Client-side tools
Client-side tools are tools that run in the browser. Use them to interact with the editor's content. For example:
- Count the number of words in the document
- Replace all instances of a word in the document
- Format the document.
All built-in tools are client-side tools.
This guide shows how to implement a tool that replaces all occurrences of a word in the document with another word. It assumes you have already set up the AI Agent extension with your custom backend.
Code demo available
This guide includes a code demo to help you get started. See the GitHub repository.
Client-side setup
Declare a tool call handler for your tool. Tool handlers are functions that apply the tool call in the editor. They must implement the AiAgentToolHandler
interface.
import { z } from 'zod'
import type { AiAgentToolHandler } from '@tiptap-pro/extension-ai-agent'
import { ToolCallError, invalidArgumentsResponseFormatter } from '@tiptap-pro/extension-ai-agent'
// Schema for validating tool arguments
const replaceAllToolSchema = z.object({
find: z.string().min(1, 'Find text cannot be empty'),
replace: z.string(),
})
export const replaceAllToolHandler = (): AiAgentToolHandler => ({
// Unique identifier for the tool
name: 'replace_all',
modifiesEditor: true,
handleToolCall: ({ editor, state, toolCall }) => {
// Validate the arguments
const result = replaceAllToolSchema.safeParse(toolCall.arguments)
if (!result.success) {
// Return an error message to the AI
throw new ToolCallError(invalidArgumentsResponseFormatter(result.error))
}
const args = result.data
try {
// Get the current HTML content
const html = editor.getHTML()
// Replace all occurrences of the find text with the replace text
const replacedHtml = html.replaceAll(args.find, args.replace)
// Set the new content in the editor
editor.commands.setContent(replacedHtml)
// Return a success message
return `Successfully replaced all occurrences of "${args.find}" with "${args.replace}".`
} catch (error) {
console.error(error)
throw new ToolCallError(`Failed to replace text: ${error.message}`)
}
},
})
Then, add the tool to your AI Agent provider:
import { AiAgentProvider, toolHandlersStarterKit } from '@tiptap-pro/extension-ai-agent'
const provider = new AiAgentProvider({
toolHandlers: [...toolHandlersStarterKit(), replaceAllToolHandler()],
})
The toolHandlersStarterKit
contains the tool handlers for all the built-in tools. You can add your custom tool handlers to the array.
Server-side setup
On the server-side, define the tool. The tool definition contains the tool's name, description, and JSON schema. This data is sent to the LLM to generate the tool calls. It must implement the AiAgentTool
interface.
import type { AiAgentTool } from '@tiptap-pro/extension-ai-agent-server'
export const replaceAllTool = (): AiAgentTool => ({
// Unique identifier for the tool. Must match the one in the tool handler
name: 'replace_all',
description: 'Replaces all occurrences of a word in the document with another word',
parameters: {
type: 'object',
properties: {
find: {
type: 'string',
},
replace: {
type: 'string',
},
},
required: ['find', 'replace'],
},
})
Then, add the tool to your AI Agent toolkit:
import { AiAgentToolkit, toolsStarterKit } from '@tiptap-pro/extension-ai-agent-server'
const toolkit = new AiAgentToolkit({
tools: [...toolsStarterKit(), replaceAllTool()],
})
The toolsStarterKit
contains the tool definitions for all the built-in tools. You can add your custom tool definitions to the array.