Skip to content

fix(document-api): improve AI tool definitions, add block refs, and fix formatting extraction#2511

Open
tupizz wants to merge 34 commits intomainfrom
tadeu/feat-browser-sdk-with-improvements
Open

fix(document-api): improve AI tool definitions, add block refs, and fix formatting extraction#2511
tupizz wants to merge 34 commits intomainfrom
tadeu/feat-browser-sdk-with-improvements

Conversation

@tupizz
Copy link
Copy Markdown
Contributor

@tupizz tupizz commented Mar 21, 2026

Summary

Fixes AI tool call quality by adding ref handles to API responses, fixing formatting extraction bugs, correcting tool descriptions, and rewriting the system prompt.

Problems fixed

  • Extra search steps: Creating content required create > search > format (3 calls). Editing a paragraph required search first even when blocks data was already available.
  • Wrong target format: Codegen fallback description said {kind:'text', blockId, range:{start,end}} but the correct format is {kind:'selection', start:{kind:'text', blockId, offset}, end:{kind:'text', blockId, offset}}.
  • Partial replacements: Search refs only cover matched text. "Rewrite this paragraph" replaced part of the text and left the rest because the ref didn't cover the full block.
  • Confusing flat params: blockId, start, end in edit tool schemas confused models into building targets manually instead of using refs.
  • Heading numbering: Templates with outline numbering linked to heading styles showed "1" prefix on programmatically created headings.
  • Wrong color in blocks data: extractBlockFormatting read color from all marks including highlight marks, reporting #FFFFFF as text color when paragraphs had white highlight backgrounds.
  • List creation made separate lists: Prompt said "for each paragraph" so the LLM called superdoc_list once per item, creating N independent lists instead of one.
  • Missing list conversion: set_type action for converting bullet/numbered wasn't mentioned in prompt or tool description.
  • LLMs pass limit=0 instead of omitting: "Do NOT add limit" was interpreted as "set to zero." API now normalizes limit: 0 and nodeTypes: [] to mean "all."

Changes

Block refs in blocks.list — Each non-empty block now returns a ref handle covering its full text. Agents pass this directly to superdoc_edit or superdoc_format without searching first.

Ref from superdoc_create — Create responses include a ref for the new block, enabling immediate formatting without a search step (create > format instead of create > search > format).

Fixed extractBlockFormatting — Only reads fontFamily/fontSize/color from textStyle marks and bold from bold marks. No longer picks up highlight background colors.

Fixed target descriptions — Corrected the fallback target description in codegen from wrong {kind:'text'} format to correct {kind:'selection'} format.

Tool description improvements:

  • superdoc_edit: guides toward ref usage, explains that search refs are partial while block refs cover full text
  • superdoc_create: documents the ref in the response, required format-after-create workflow with examples
  • superdoc_get_content: mentions that blocks returns ref handles and formatting data
  • superdoc_list: expanded description with key actions (create, set_type, insert, indent, outdent, detach)

List creation fix — Prompt now instructs creating all paragraphs first, then one superdoc_list call with a BlockRange target to produce a single contiguous list. Added set_type guidance for bullet/numbered conversion.

Heading numbering fixinsertHeadingAt sets numberingProperties: { numId: '0', ilvl: '0' } to suppress outline numbering from template heading styles.

Tolerant input normalizationblocks.list now normalizes limit: 0 to "all blocks" and nodeTypes: [] to "no filter" before validation.

Hidden confusing paramsblockId, start, end, offset flat params hidden from agent tool schemas (kept for CLI).

System prompt rewrite — Blocks-first workflow, concrete formatting examples for paragraphs and headings, correct list creation with BlockRange targets, list type conversion, sequential create ordering via nodeId.

Schema validator — Added description, minimum, maximum to supported keywords for contract conformance tests.

Files changed

Area Files What
Contract operation-definitions.ts, schemas.ts Tool descriptions, block ref + color schema
Types blocks.types.ts, create.types.ts ref and color fields
Codegen generate-intent-tools.mjs Fixed target fallback description
CLI params operation-params.ts Hidden flat params from agent tools
Validation blocks/blocks.ts Normalize limit=0 and nodeTypes=[]
System prompt system-prompt.md Rewritten workflow, list range targets, set_type
Editor commands insertHeadingAt.js Suppress outline numbering
Adapters blocks-wrappers.ts Block refs, color field, fixed mark reading
Adapters create-wrappers.ts Ref minting on create
Tests schema-validator.ts Support description/minimum/maximum
Evals execution.yaml List creation and conversion tests
Docs apps/docs/document-api/reference/* Generated from contract changes

Test plan

  • pnpm --filter super-editor test passes
  • Run eval suite, verify pass rate >= 96%
  • Eval: 3-item bullet list creates one contiguous list
  • Eval: bullet to numbered conversion uses set_type
  • Manual: create heading via document API, verify no "1" prefix
  • Manual: get blocks, use block ref to replace entire paragraph

tupizz added 6 commits March 21, 2026 08:32
The create response now includes a ref handle that can be passed
directly to superdoc_format or superdoc_edit without a search step.

Before: create → search → format (3 calls)
After:  create → format using ref from response (2 calls)

The ref is minted from the created block's nodeId + text range +
document revision. It's a V4 block-scoped ref that resolves to
the full text range of the created content.
- Removed "optional styleId" reference (styleId was removed)
- Changed "search after create" to "use ref from response"
- Separated heading vs paragraph formatting rules
- Added create ref to targeting section
- Removed contradictory "search before editing" for create flow
@mintlify
Copy link
Copy Markdown

mintlify bot commented Mar 21, 2026

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
SuperDoc 🟢 Ready View Preview Mar 21, 2026, 1:24 PM

@tupizz tupizz changed the title feat(sdk): browser SDK with eval improvements feat(sdk): browser SDK + AI tool quality improvements Mar 21, 2026
tupizz added 6 commits March 24, 2026 08:45
…mbering

- Apply fontFamily/fontSize/color/bold from nearby body text blocks via
  runProperties + textStyle marks + sdPreserveRunPropertiesKeys meta so the
  style engine cascade respects inline overrides on heading-styled paragraphs.
- Set numberingProperties {numId:'0'} on created headings to suppress
  outline numbering inherited from template heading styles.
- Update superdoc_create tool description: LLM MUST call superdoc_format
  after create with bold:false and body-text formatting values.
- Use editor.dispatch() instead of editor.view?.dispatch() for consistency
  with the plan engine executor dispatch path.
…minting

Remove findNearbyFormatting, applyFormattingToCreatedBlock, and mark-copying
from insertHeadingAt/insertParagraphAt. These added ~200 lines of complexity
but didn't work: the style engine cascade overrides inline marks for headings,
and the code incorrectly copied bold from title paragraphs.

The LLM handles formatting correctly via superdoc_format after create,
guided by tool descriptions. Server-side auto-formatting was a wrong turn.

Keep: numberingProperties suppression, mintBlockRef, block refs in blocks.list.
- Headings: set fontFamily, fontSize (scaled up from body), color, bold:true
- Paragraphs: set fontFamily, fontSize, color, bold:false
- Always use color #000000 (never copy from blocks — some have white text)
- Call blocks without limit/filters to get full document context
- Get fontFamily/fontSize from body text blocks, not info defaults
Restore pre-existing generated files to main versions. New browser
SDK files (package.json, dispatch.ts, validate.ts, etc.) moved to
local-only for a separate PR.
tupizz added 2 commits March 24, 2026 16:37
- Only read fontFamily/fontSize/color from textStyle marks and bold
  from bold marks. Prevents highlight mark background colors from
  being reported as text color in blocks.list.
- Remove "always use color #000000" restriction from create tool
  description and system prompt since blocks data now reports
  correct text colors.
- Revert unrelated formatting change in apps/create/src/index.ts.
- Revert orphaned findNearbyMarks defensive guard (was added for
  removed auto-formatting code).
@tupizz tupizz changed the title feat(sdk): browser SDK + AI tool quality improvements fix(document-api): improve AI tool definitions, add block refs, and fix formatting extraction Mar 24, 2026
@tupizz tupizz marked this pull request as ready for review March 24, 2026 19:52
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 390a130c19

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

tupizz added 2 commits March 25, 2026 10:40
LLMs interpret "do not add limit/filters" as "set them to zero/empty"
rather than omitting them. Normalize these values before validation:
limit=0 is treated as "all blocks", empty nodeTypes as "no filter".

Also simplify system prompt wording to "just pass action, nothing else".
…val tests

- Fix list creation prompt: use BlockRange target to create one
  contiguous list instead of calling superdoc_list per paragraph.
- Add set_type guidance for bullet/numbered conversion.
- Expand superdoc_list tool description with key actions.
- Restore neutral replace operation description for human docs
  (agent-directive language stays in INTENT_GROUP_META.edit).
- Add eval tests for multi-item list creation and list conversion.
tupizz added 7 commits March 25, 2026 11:30
…guidance

The BlockRange target converts ALL paragraphs between from and to.
If the LLM places the first item mid-document and the rest at the end,
the entire document gets converted into a numbered list.

Updated prompt to explicitly require: create all items at the same
location using documentEnd + nodeId chaining, ensure they are
consecutive before applying the range.
…g styles

- Introduced a new workflow to create an "Exhibit X" page that matches the style of an existing "Exhibit A" page, including formatting and summary.
- Enhanced assertions to validate the creation and formatting of the new page, ensuring proper tool usage and style replication.
- Added a new utility function `dispatchWithRetry` to handle automatic reference revision bumps on `REVISION_MISMATCH` errors during SDK tool dispatch.
- Updated `convertTool` and `runAgentLoop` functions to utilize `dispatchWithRetry`, enhancing resilience against transient errors.
- Modified customer workflow test to simplify task description.
- Introduced `intentGroup` and `intentAction` for the table creation operation in operation definitions.
- Updated intent dispatch logic to handle the new `table` action, allowing for seamless execution of table creation commands.
- Enhanced system prompt documentation to include guidance on avoiding overlap errors during text mutations.
…ascade

extractBlockFormatting now calls resolveRunProperties() from the
style engine instead of only reading inline textStyle marks. This
resolves the full cascade (doc defaults → Normal style → paragraph
style → inline overrides) so blocks.list always reports accurate
fontFamily, fontSize, color, bold, and underline values.

Previously, documents with style-driven formatting (no inline marks)
reported no fontFamily/fontSize for body paragraphs. The LLM then
copied the heading's 20pt size for body text, producing wrong results.
Copy link
Copy Markdown
Contributor

@andrii-harbour andrii-harbour left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nicely done! Just a few comments and UX suggestions

- Fix ref length: use computeTextContentLength instead of
  textContent.length to correctly count inline atoms (tabs, images)
  in block refs. Prevents refs from undercovering blocks with
  non-text inline nodes.
- Remove #000000 color default: let color be absent when no explicit
  color mark exists. Filter OOXML "auto" sentinel value. Prevents
  propagating black to documents with themed non-black defaults.
- Add unit tests for normalizeBlocksListInput (limit=0, nodeTypes=[]).
- Strengthen list conversion eval assertion to verify tool action.
- Add source comment for text:v4 ref prefix in eval utils.
tupizz added 2 commits March 27, 2026 12:48
Traces: abort previous SSE connection on re-call and on unmount,
add event deduplication in state updaters. Prevents React StrictMode
double-mount from producing duplicate trace entries.

Quick actions: clicking "Use sample document" or "Start blank" now
populates the form state instead of immediately creating the room.
Users can adjust model, edit mode, and display name before creating.
Selected quick action shows visual feedback (highlighted button,
status text in drop zone).
…k-with-improvements

# Conflicts:
#	pnpm-lock.yaml
tupizz added 2 commits March 27, 2026 13:15
- Introduced new operations for managing permission ranges: create, get, list, remove, and updatePrincipal.
- Added protection operations: get, setEditingRestriction, and clearEditingRestriction.
- Updated documentation to reflect these changes, including new reference pages and operation details.
- Enhanced existing API documentation with new tables for permission ranges and protection operations.
tupizz added 4 commits March 27, 2026 15:40
- Enhanced the documentation for creating paragraphs, headings, and tables in the document API.
- Clarified the required formatting steps after creation, specifying the need for two format calls: one for character styling and another for paragraph alignment.
- Improved examples for body paragraphs and headings to ensure correct usage of inline properties and alignment settings.
- Updated operation definitions to specify that paragraph actions must use a flat block target format and cannot include selection-like structures.
- Added documentation in the system prompt to emphasize that format calls must be sequential and that all created items should be formatted, addressing potential issues with parallel calls and partial failures.
…d headings

- Updated operation definitions to clarify the formatting requirements for body paragraphs, emphasizing the exclusion of underline styles and the correct inline properties.
- Enhanced documentation in the system prompt to specify the necessary attributes for body text and headings, ensuring consistent formatting practices across the API.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants