Document Authoring AI lets you add an AI assistant to the Document Authoring editor. The server talks to the model; the browser owns the document. The model requests reads and writes through tool calls, and the browser validates and executes each one against the live editor before sending the results back. The real boundary is this: Your app controls which messages and tool results reach the model. Document content reaches it only when a read tool returns that content, so what the model sees depends on which tools you expose and how your app routes the results.
This page walks you through the minimum agentic loop: Install the package, expose tool definitions on your server, and execute tool calls in the browser editor. By the end, you’ll have a working assistant that can read and edit the open document.
Prerequisites
- A Document Authoring editor is running in the browser with a live
DocAuthEditorinstance available aseditor. - Your server can reach a model provider. The examples use OpenAI through Vercel AI SDK(opens in a new tab).
- Node.js ≥ 18 and access to the Nutrient SDK npm registry.
1. Install
npm install @nutrient-sdk/document-authoring-aiThe package ships two entry points: @nutrient-sdk/document-authoring-ai for the server and @nutrient-sdk/document-authoring-ai/editor for the browser. There’s no separate install for the browser entry: It’s part of the same package.
2. Set up the server route
Your server route registers the document tool definitions with the AI framework and streams the model response back to the browser with streamText(opens in a new tab). The route exposes the tools but runs none of them; the browser does.
import { openai } from "@ai-sdk/openai";import { convertToModelMessages, stepCountIs, streamText,} from "ai";import { getAiPromptGuide, getAiToolDefinitions,} from "@nutrient-sdk/document-authoring-ai";import { toVercelAiTools } from "@nutrient-sdk/document-authoring-ai/vercel";
const tools = toVercelAiTools(getAiToolDefinitions());const system = getAiPromptGuide();
export async function POST(req: Request) { const body = await req.json();
const result = streamText({ model: openai("gpt-4o-mini"), system, messages: await convertToModelMessages(body.messages), stopWhen: stepCountIs(20), temperature: 0.1, tools, });
return result.toUIMessageStreamResponse();}getAiToolDefinitions returns the full document tool set. toVercelAiTools converts them into the shape Vercel AI SDK expects. getAiPromptGuide is the system prompt designed for these tools; it tells the model how element IDs, read-before-write ordering, and schema validation work.
3. Create the toolkit in the browser
Bind the toolkit to the live editor. Call this once per editor session, after the editor has mounted:
import { getAiToolkit } from "@nutrient-sdk/document-authoring-ai/editor";
const toolkit = getAiToolkit(editor);The toolkit stays bound to that DocAuthEditor instance. It’s what gives executeTool access to the document.
4. Wire the chat loop
Inside the Vercel AI SDK useChat(opens in a new tab) hook, intercept each tool call, run it through the toolkit, and send the result back to the model. The edit and mode checks happen here.
import { useChat } from "@ai-sdk/react";import { DefaultChatTransport, lastAssistantMessageIsCompleteWithToolCalls,} from "ai";import { isAiWriteToolName } from "@nutrient-sdk/document-authoring-ai";
const { addToolOutput } = useChat({ transport: new DefaultChatTransport({ api: "/api/chat" }), sendAutomaticallyWhen: lastAssistantMessageIsCompleteWithToolCalls, async onToolCall({ toolCall }) { const editorMode = editor.getEditorMode(); const isWriteTool = isAiWriteToolName(toolCall.toolName);
if (isWriteTool && editorMode === "view") { addToolOutput({ tool: toolCall.toolName, toolCallId: toolCall.toolCallId, state: "output-error", errorText: "The document is in View mode. Switch to Edit or Review mode before editing.", }); return; }
const executed = await toolkit.executeTool( { id: toolCall.toolCallId, name: toolCall.toolName, args: toolCall.input, }, { writeMode: isWriteTool && editorMode === "review" ? "track_changes" : "apply", }, );
addToolOutput({ tool: toolCall.toolName, toolCallId: toolCall.toolCallId, output: executed, }); },});isAiWriteToolName tells you whether the model’s tool call mutates the document. Write tools are blocked in View mode and routed through tracked changes in Review mode. Read tools always run regardless of mode.
Success checkpoint
Open the editor in Edit mode and type: “Make the title bold.”
The model issues one or more tool calls to read the document and apply the formatting. Watch the editor: The title heading should become bold within a few seconds. You’ll see the tool calls and their results in the chat/tool log.
If the document doesn’t change:
- Confirm the server route returns
result.toUIMessageStreamResponse. - Check that
getAiToolkitwas called after the editor mounted, not before. - Verify
editor.getEditorModereturns"edit", not"view".
What’s next
- Agentic tools — Full tool reference, element ID rules, and review comment configuration.
- Workflows — Proofreading, translation, and other bounded tasks that skip the tool loop.
- Review and approval — How Edit, Review, and View mode should map to write behavior.
- Vercel AI SDK integration — Tool definitions, the chat loop, and edge cases.