> ## Documentation Index
> Fetch the complete documentation index at: https://docs.superdoc.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Legacy preset — grouped intent tools

> The original 10-tool surface: grouped intent tools with search-then-edit targeting. Maintained for existing integrations; new integrations should use the core preset.

<Warning>
  **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](/ai/agents/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.
</Warning>

The legacy preset gives the model 10 grouped **intent tools** that map closely to [Document API](/document-api/overview) operations. The model works low-level: search for text to obtain handles/addresses, then edit by address.

## Quick start

<Tabs>
  <Tab title="Node.js">
    ```typescript theme={null}
    import { createAgentToolkit } from '@superdoc-dev/sdk';

    // 'legacy' is also what you get if you omit `preset`.
    const { tools, systemPrompt, dispatch } = await createAgentToolkit({
      provider: 'openai',
      preset: 'legacy',
    });
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    from superdoc import create_agent_toolkit

    kit = create_agent_toolkit({"provider": "openai", "preset": "legacy"})
    tools, system_prompt = kit["tools"], kit["system_prompt"]
    ```
  </Tab>
</Tabs>

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`.

| Tool                     | Actions                                                                                                                                                                                                                                                         | What it does                                                                                                               |
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| `superdoc_get_content`   | `text`, `markdown`, `html`, `blocks`, `extract`, `info`                                                                                                                                                                                                         | Read document content in different formats                                                                                 |
| `superdoc_search`        | *(single action)*                                                                                                                                                                                                                                               | Find text or nodes and return handles or addresses for later edits                                                         |
| `superdoc_edit`          | `insert`, `replace`, `delete`, `undo`, `redo`                                                                                                                                                                                                                   | Perform text edits and history actions                                                                                     |
| `superdoc_format`        | `inline`, `set_style`, `set_alignment`, `set_indentation`, `set_spacing`, `set_direction`, `set_flow_options`                                                                                                                                                   | Apply inline or paragraph formatting                                                                                       |
| `superdoc_create`        | `paragraph`, `heading`, `table`                                                                                                                                                                                                                                 | Create structural block elements                                                                                           |
| `superdoc_list`          | `insert`, `create`, `attach`, `detach`, `delete`, `merge`, `split`, `indent`, `outdent`, `set_level`, `set_type`, `set_value`, `continue_previous`                                                                                                              | Create and manipulate lists                                                                                                |
| `superdoc_comment`       | `create`, `update`, `delete`, `get`, `list`                                                                                                                                                                                                                     | Manage comment threads                                                                                                     |
| `superdoc_track_changes` | `list`, `decide`                                                                                                                                                                                                                                                | Review and resolve tracked changes                                                                                         |
| `superdoc_mutations`     | `preview`, `apply`                                                                                                                                                                                                                                              | Execute multi-step atomic edits as a batch                                                                                 |
| `superdoc_table`         | `delete`, `delete_column`, `delete_row`, `insert_column`, `insert_row`, `merge_cells`, `set_borders`, `set_cell`, `set_cell_text`, `set_column`, `set_layout`, `set_options`, `set_row`, `set_row_options`, `set_shading`, `set_style_options`, `unmerge_cells` | Modify table structure, content, and styling (find table/row/cell nodeIds via `superdoc_get_content` or `superdoc_search`) |

## Behaviors you must know

**`superdoc_search` `require` values** — `first` 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                  | What you do                                        |
| --------------------- | -------------------------------------------------- |
| 1. Pick operations    | Browse `doc.*` to find the methods you need        |
| 2. Define the schema  | Write a function tool definition for your provider |
| 3. Write a dispatcher | Map tool actions to `doc.*` calls                  |
| 4. Merge and use      | Combine with SDK tools in your agentic loop        |

### Step 1: Pick your operations

Every `doc.*` namespace maps to a group of [Document API](/document-api/overview) operations:

```text theme={null}
doc.hyperlinks   → list, get, wrap, insert, patch, remove
doc.tables       → get, insertRow, deleteRow, mergeCells, ...
doc.images       → list, get, setSize, rotate, crop, ...
doc.footnotes    → list, get, create, delete, update, ...
doc.bookmarks    → list, get, create, delete, ...
```

### 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.

```typescript theme={null}
import type { ChatCompletionTool } from 'openai/resources/chat/completions';

const hyperlinkTool: ChatCompletionTool = {
  type: 'function',
  function: {
    name: 'superdoc_hyperlink',
    description:
      'Create, read, update, or remove hyperlinks in the document.',
    parameters: {
      type: 'object',
      properties: {
        action: {
          type: 'string',
          enum: ['list', 'get', 'wrap', 'insert', 'patch', 'remove'],
        },
        target: {
          description: 'Target address from superdoc_search results.',
        },
        text: { type: 'string', description: 'Display text (insert only).' },
        href: { type: 'string', description: 'URL destination.' },
        tooltip: { type: 'string', description: 'Hover tooltip text.' },
      },
      required: ['action'],
      additionalProperties: false,
    },
  },
};
```

<Note>
  * 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.
</Note>

### Step 3: Write a dispatcher

Map each action to the corresponding `doc.*` call:

```typescript theme={null}
import { dispatchSuperDocTool } from '@superdoc-dev/sdk';

async function dispatchToolCall(doc, toolName, args) {
  // Built-in tools: delegate to the SDK
  if (toolName !== 'superdoc_hyperlink') {
    return dispatchSuperDocTool(doc, toolName, args);
  }

  // Custom tool: call doc.* directly
  const { action, target, text, href, tooltip } = args;

  switch (action) {
    case 'list':
      return doc.hyperlinks.list({});
    case 'get':
      return doc.hyperlinks.get({ target });
    case 'wrap':
      return doc.hyperlinks.wrap({
        target,
        link: { destination: { href }, ...(tooltip && { tooltip }) },
      });
    case 'insert':
      return doc.hyperlinks.insert({
        text,
        link: { destination: { href }, ...(tooltip && { tooltip }) },
        ...(target && { target }),
      });
    case 'patch':
      return doc.hyperlinks.patch({
        target,
        patch: { ...(href && { href }), ...(tooltip && { tooltip }) },
      });
    case 'remove':
      return doc.hyperlinks.remove({ target });
    default:
      throw new Error(`Unknown action: "${action}"`);
  }
}
```

### Step 4: Merge and use

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

```typescript theme={null}
const { tools: sdkTools } = await chooseTools({ provider: 'openai' });
const allTools = [...sdkTools, hyperlinkTool];

// In your agentic loop, use your dispatcher instead of dispatchSuperDocTool:
// OpenAI chat completions store the tool name on function.name.
const toolName = toolCall.function.name;
const result = await dispatchToolCall(doc, toolName, args);
```

### Extending the system prompt

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

```typescript theme={null}
const systemPrompt = await getSystemPrompt();

const customInstructions = `
## superdoc_hyperlink

Use this tool to manage hyperlinks. First use superdoc_search to find
text you want to link, then pass the handle as target to the wrap action.
`;

const fullPrompt = systemPrompt + '\n' + customInstructions;
```

## Migrating to core

The mapping is conceptual, not mechanical — core actions absorb multi-call legacy patterns into single verbs:

| Legacy pattern                                               | Core equivalent                                                                          |
| ------------------------------------------------------------ | ---------------------------------------------------------------------------------------- |
| `superdoc_search` → `superdoc_edit` (replace by ref)         | `replace_text` (finds and edits in one call)                                             |
| `superdoc_search` → `superdoc_mutations` (multi-block batch) | one action call — each action resolves its own targets atomically                        |
| `superdoc_create` + `superdoc_format` chains                 | `insert_paragraphs` / `insert_heading` / `create_table` with `placement`                 |
| `superdoc_track_changes {action:"decide"}`                   | `accept_tracked_changes` / `reject_tracked_changes` (with `author`/`changeType` filters) |
| `superdoc_comment`                                           | `add_comments` / `reply_to_comment` / `resolve_comments`                                 |

Switching is a one-line change per call site (`preset: 'core'` on the toolkit) plus adopting the receipt contract — see the [core preset reference](/ai/agents/core-preset).

## Related

* [Core preset reference](/ai/agents/core-preset) — the recommended surface
* [How it works](/ai/agents/architecture) — SDK ↔ CLI ↔ LLM mechanics
* [Overview](/ai/agents/llm-tools) — providers, token budget, errors, troubleshooting
