Selection awareness
Build a server-side AI agent that reads the current selection before it decides how to edit the document.
See the source code on GitHub.
Continuation from the AI agent chatbot guide
This guide extends the AI agent chatbot guide. Reuse the same authentication setup from that guide.
1. Track the active selection
Add the Selection extension and store the current range whenever the selection changes.
import { Selection } from '@tiptap/extensions'
import { EditorContent, useEditor } from '@tiptap/react'
import { ServerAiToolkit } from '@tiptap-pro/server-ai-toolkit'
import { useRef } from 'react'
const selectionRangeRef = useRef({ from: 0, to: 0 })
const editor = useEditor({
immediatelyRender: false,
extensions: [StarterKit, Collaboration.configure({ document: doc }), ServerAiToolkit, Selection],
onSelectionUpdate: ({ editor: currentEditor }) => {
selectionRangeRef.current = {
from: currentEditor.state.selection.from,
to: currentEditor.state.selection.to,
}
},
})2. Send the selection with the user message
When the user sends a message, include the schema awareness data, document ID, and captured selection range in the request body.
const { messages, sendMessage, status } = useChat({
transport: new DefaultChatTransport({
api: '/api/server-selection-awareness',
}),
})
sendMessage(
{ text: input },
{
body: {
schemaAwarenessData: getSchemaAwarenessData(editor),
documentId,
selectionRange: selectionRangeRef.current,
},
},
)3. Read the selection from the AI Server
In your backend route, call the Server AI Toolkit selection-read endpoint before the agent starts its tool loop:
POST /v3/ai/toolkit/read/read-selection
const response = await fetch(`${apiBaseUrl}/toolkit/read/read-selection`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${jwtToken}`,
'X-App-Id': appId,
},
body: JSON.stringify({
schemaAwarenessData,
range: selectionRange,
sessionId,
reviewOptions: {
mode: 'disabled',
},
format: 'json',
experimental_documentOptions: {
documentId,
userId: 'ai-assistant',
},
}),
})
const selectionResult = await response.json()
const selectionPrompt = !selectionResult.output.isEmpty
? selectionResult.output.prompt
: 'There is currently no active selection.'The returned prompt contains a model-friendly description of the selected content and its
position in the document.
4. Add the selection context to the agent instructions
Inject the selection prompt into the agent instructions so the model knows what part of the document it should focus on.
const agent = new ToolLoopAgent({
model,
instructions: `You are an assistant that can edit rich text documents.
Use the selection context before making changes.
<selection-context>
${selectionPrompt}
</selection-context>
${schemaAwarenessPrompt}`,
tools,
})The agent can then use the regular Server AI Toolkit tools to read more context and edit the document, while staying grounded on the active selection.
End result
The result is a server-side AI chat experience that only rewrites the content the user selected:
See the source code on GitHub.
Next steps
- Review the REST API reference
- Learn about schema awareness