Skip to main content
Not recommended for new integrations. The legacy preset remains the default (omitting preset selects it) purely for backwards compatibility — existing integrations keep working unchanged. For new work, use the core preset: it scores measurably higher on our revision-fidelity evals, returns verifiable receipts instead of raw operation results, and treats tracked-changes redlining as a first-class workflow.
The legacy preset gives the model 10 grouped intent tools that map closely to Document API operations. The model works low-level: search for text to obtain handles/addresses, then edit by address.

Quick start

The legacy preset ignores excludeActions everywhere (it has no action surface to narrow) — passing it is a harmless no-op.

Tool catalog

Most tools use an action argument to select the underlying operation. Single-action tools like superdoc_search do not require action.

Behaviors you must know

superdoc_search require valuesfirst returns the first match (error on zero), all returns every match, any returns matches without failing on zero, exactlyOne errors unless exactly one matched (AMBIGUOUS_MATCH on several, MATCH_NOT_FOUND on none). Refs expire on mutation. Every successful edit bumps the document revision and invalidates previously fetched refs — using a stale ref raises REVISION_MISMATCH. This is the sharpest edge of the legacy surface: pre-fetching refs for two blocks and editing them sequentially always fails on the second edit. For multi-block edits use superdoc_mutations (which resolves all targets before any step executes and applies everything in one revision bump), or re-search between edits. get_content action:"text" returns the whole document with no pagination — in an agent loop that result lives in conversation history forever and amplifies every later turn’s token cost. Prefer scoped reads.

System prompt

getSystemPrompt() / getSystemPrompt('legacy') returns the prompt this surface was designed with: the search-before-edit workflow, targeting rules, and batching guidance. Use it as-is or extend it — and pair prompt and tools from the same preset.

Creating custom tools

The built-in intent tools cover core editing operations. For anything else, create custom tools that call doc.* methods directly and merge them with the SDK tools.

Step 1: Pick your operations

Every doc.* namespace maps to a group of Document API operations:

Step 2: Define the tool schema

Group related operations under a single tool using an action enum. This matches the pattern the built-in tools use.
  • Keep descriptions short. The model reads every tool definition on each turn.
  • Use additionalProperties: false to prevent hallucinated parameters.
  • Reference superdoc_search in descriptions so the model knows how to get targets.

Step 3: Write a dispatcher

Map each action to the corresponding doc.* call:

Step 4: Merge and use

Combine your custom tool with the SDK tools and use your dispatcher in the agentic loop:

Extending the system prompt

For custom tools, append usage instructions to the SDK system prompt so the model knows how to use them:

Migrating to core

The mapping is conceptual, not mechanical — core actions absorb multi-call legacy patterns into single verbs: Switching is a one-line change per call site (preset: 'core' on the toolkit) plus adopting the receipt contract — see the core preset reference.