Use with Tracked Changes

Separate product

Tracked Changes is a separate Tiptap product from the AI Toolkit, sold separately. It handles user edits by default and can review AI edits when integrated with the AI Toolkit.

Experimental

The Tracked Changes extension is currently in Alpha phase.

Continuation from the AI agent chatbot guide

This guide continues the AI agent chatbot guide. Read it first.

Display AI-generated changes as tracked changes, so your users can review and accept or reject them individually. This guide shows how to connect the AI Toolkit to the separately licensed Tracked Changes extension.

See the source code on GitHub.

Show tracked changes

To display AI edits as tracked changes, set reviewOptions.mode to 'trackedChanges' when executing a tool.

API endpoint

The API endpoint is the same as in the AI agent chatbot guide. No changes are needed on the server side to enable tracked changes.

// app/api/tracked-changes/route.ts
import { openai } from '@ai-sdk/openai'
import { toolDefinitions } from '@tiptap-pro/ai-toolkit-ai-sdk'
import { createAgentUIStreamResponse, ToolLoopAgent, type UIMessage } from 'ai'

export async function POST(req: Request) {
  const { messages }: { messages: UIMessage[] } = await req.json()

  const agent = new ToolLoopAgent({
    model: openai('gpt-5.4-mini'),
    instructions:
      'You are an assistant that can edit rich text documents. Use tiptapRead before tiptapEdit.',
    tools: toolDefinitions(),
  })

  return createAgentUIStreamResponse({
    agent,
    uiMessages: messages,
  })
}

Client-side setup

On the client, install and add the TrackedChanges extension, then pass reviewOptions with mode 'trackedChanges' to the executeTool method.

The TrackedChanges extension must be configured with enabled: false while the AI is making edits.

import { useChat } from '@ai-sdk/react'
import { EditorContent, useEditor } from '@tiptap/react'
import StarterKit from '@tiptap/starter-kit'
import { AiToolkit, getAiToolkit } from '@tiptap-pro/ai-toolkit'
import { TrackedChanges } from '@tiptap-pro/extension-tracked-changes'
import { DefaultChatTransport, lastAssistantMessageIsCompleteWithToolCalls } from 'ai'

export default function Page() {
  const editor = useEditor({
    immediatelyRender: false,
    extensions: [
      StarterKit,
      TrackedChanges.configure({
        enabled: false,
      }),
      AiToolkit,
    ],
    content: `<p>Ask the AI to improve this document.</p>`,
  })

  const { messages, sendMessage, addToolOutput } = useChat({
    transport: new DefaultChatTransport({ api: '/api/tracked-changes' }),
    sendAutomaticallyWhen: lastAssistantMessageIsCompleteWithToolCalls,
    async onToolCall({ toolCall }) {
      if (!editor) return

      const toolkit = getAiToolkit(editor)
      const result = toolkit.executeTool({
        toolName: toolCall.toolName,
        input: toolCall.input,
        reviewOptions: {
          mode: 'trackedChanges',
          trackedChangesOptions: {
            userId: 'ai-assistant',
            userMetadata: {
              name: 'AI',
            },
          },
        },
      })

      addToolOutput({
        tool: toolCall.toolName,
        toolCallId: toolCall.toolCallId,
        output: result.output,
      })
    },
  })

  // ... render editor and chat UI
}

After the AI edits the document, the changes appear as tracked changes. Users can accept or reject them using the acceptSuggestion, rejectSuggestion, acceptAllSuggestions, and rejectAllSuggestions commands from the Tracked Changes extension.

End result

See the source code on GitHub.

Next steps