# Agents

> Give a model Revise's editing tools, or teach a coding agent the CLI.

## Your own agent loop

`agentTools(doc, { provider })` returns the editing tools in the shape a model
API expects, and a `handle` function that runs one tool call and returns the
tool-result message to send back. No model SDK is a dependency: plain objects
in, plain objects out.

```ts
import Anthropic from "@anthropic-ai/sdk";
import { ReviseDocument, agentTools } from "revise";

const anthropic = new Anthropic();
const doc = await ReviseDocument.open("contract.docx", { author: "Contract bot" });
const agent = agentTools(doc, { provider: "anthropic" });

const messages: Anthropic.MessageParam[] = [
  { role: "user", content: "Change the governing law to New York." },
];
for (;;) {
  const reply = await anthropic.messages.create({
    model: "claude-sonnet-5-5",
    max_tokens: 4096,
    tools: agent.tools,
    messages,
  });
  messages.push({ role: "assistant", content: reply.content });
  const calls = reply.content.filter((block) => block.type === "tool_use");
  if (calls.length === 0) break;
  messages.push({
    role: "user",
    content: await Promise.all(calls.map(agent.handle)),
  });
}

const { bytes } = await doc.export({ format: "docx" });
doc.dispose();
```

| Provider | `tools` | `handle(call)` takes | and returns |
| --- | --- | --- | --- |
| `"anthropic"` | Messages API tools | a `tool_use` content block | a `tool_result` block |
| `"openai"` | Chat Completions function tools | an entry of `message.tool_calls` | a `role: "tool"` message |
| `"openai-responses"` | Responses API function tools | a `function_call` output item | a `function_call_output` item |

With the OpenAI Responses API, append every output item the model returned
(reasoning and `function_call` items included) to your input, then the
`function_call_output` items `handle` returns, and call again until the model
stops calling tools.

Options:

| Option | |
| --- | --- |
| `include`, `exclude` | Only these tools, or every tool except these |
| `maxResultChars` | Cap on one result's text (default 100,000). Longer results end with a note telling the model how to page. |

`handle` never throws for a bad call: the model gets the error and can
correct itself. Calls run on the document's one tool session, so reads,
searches, and edits share context across turns, and parallel tool calls queue.
The session remembers what the model has read: when you compact or drop the
transcript, call `agent.reset()`. `agent.version()` changes whenever the
document does, so you can tell whether a turn edited it.

Edits are tracked changes unless you open the document with
`mode: "editing"`. Review them with [`doc.changes()`](https://revise.io/developer/docs/revise/library#review),
or let a person review them in [`@reviseio/editor`](https://revise.io/developer/docs/editor-sdk/introduction):
pass the document as Y.js state (`Y.encodeStateAsUpdate(doc.ydoc)`), or
export a .docx with tracked changes and open that.

## Coding agents

Coding agents (Claude Code, Codex, and others) can drive the CLI directly. The
agent skill teaches them how. To install it as a plugin for your agent, or
with one pasted line, see [Build with AI](https://revise.io/developer/docs/build-with-ai). From the CLI:

```bash
revise skill install            # .claude/skills/ for Claude Code, else .agents/skills/
revise skill install --dir ./skills
revise skill                    # print it
```

It covers reading by block id, editing with tools, reviewing, the `xml`
escape hatch, and the exit codes.
