add client-defined tools and prepareSendMessagesRequest options#729
Conversation
🦋 Changeset detectedLatest commit: 2f2edf6 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
commit: |
Claude Code ReviewSummaryThis PR adds client-side tool execution with automatic/manual modes and fixes duplicate message issues. The implementation is generally solid with comprehensive tests. Issues Found1. Race condition in The retry loop uses a hardcoded 10-attempt limit with 100ms delays (1 second total). If the message is not persisted within 1 second, the tool result is lost silently: for (let attempt = 0; attempt < 10; attempt++) {
message = this._findMessageByToolCallId(toolCallId);
if (message) break;
await new Promise((resolve) => setTimeout(resolve, 100));
}This is fragile - under load or with slow database operations, tool results can be dropped. Consider:
2. Potential memory leak in const [clientToolResults, setClientToolResults] = useState<
Map<string, unknown>
>(new Map());This Map grows indefinitely - every tool execution adds an entry but nothing ever removes old ones. In long conversations with many tool calls, this could accumulate significant memory. The state appears to be used for tracking but never cleaned up. 3. Missing validation in The function warns about duplicate tool names but still processes them: if (seenNames.has(t.name)) {
console.warn(`Duplicate tool name "${t.name}" found...`);
}The later definition silently overwrites the earlier one. Consider either:
4. The 5. Test timeout values inconsistency
These magic numbers should be constants with documented rationale. TestingExcellent test coverage including:
Tests are thorough but would benefit from testing the race condition edge cases in |
This update documents two new features added in PR #729: 1. **clientTools option**: Allows clients to dynamically register tools that are sent to the Agent with each request. This enables embeddable chat widgets and multi-tenant applications where different clients need different tool capabilities. 2. **prepareSendMessagesRequest callback**: Provides advanced control over request customization, allowing developers to add dynamic context, custom headers, and other request modifications before sending messages to the Agent. Key additions: - Updated UseAgentChatOptions type signature to include new options - Added comprehensive examples showing clientTools usage with tool execution handlers - Added example demonstrating prepareSendMessagesRequest for dynamic context - Documented TypeScript types: ClientTool, JSONSchemaType, PrepareSendMessagesRequestOptions, PrepareSendMessagesRequestResult - Explained use cases for client-defined tools (embeddable widgets, multi-tenant apps, dynamic tool registration) - Clarified that both options can be combined for hybrid client/server tool capabilities Synced from: cloudflare/agents PR #729 cloudflare/agents#729 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Document new client-defined tools feature from cloudflare/agents#729: - Add comprehensive guide for client-defined tools - Update API reference with new types and functions - Document useAgentChat tools parameter - Document prepareSendMessagesRequest callback - Document createToolsFromClientSchemas function Related to: cloudflare/agents#729 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
| /** Human-readable description of what the tool does */ | ||
| description?: string; | ||
| /** JSON Schema defining the tool's input parameters */ | ||
| parameters?: Record<string, unknown>; |
There was a problem hiding this comment.
nit: naming here. Can we not build this type from ai sdk tools omitting execute
| * Supports common JSON Schema properties with an index signature | ||
| * for extension properties like $ref, format, minimum, maximum, etc. | ||
| */ | ||
| export type JSONSchemaType = { |
There was a problem hiding this comment.
there are so many different specs for json schema. MCP standardise on 2020-12. you can use https://www.npmjs.com/package/json-schema-typed as a type lib for this.
| /** | ||
| * @deprecated Use `parameters` instead. Will be removed in a future version. | ||
| */ | ||
| inputSchema?: unknown; |
There was a problem hiding this comment.
intereste on this change and why we are vendoring this type ourselves not using ai sdk.
| export type ClientToolSchema = { | ||
| /** Unique name for the tool */ | ||
| name: string; | ||
| /** Human-readable description of what the tool does */ | ||
| description?: string; | ||
| /** JSON Schema defining the tool's input parameters */ | ||
| parameters?: Record<string, unknown>; | ||
| }; |
There was a problem hiding this comment.
looks like a type not a schema? and same as above...
There was a problem hiding this comment.
yes yes, fixing this, my oversight
| function toParametersRecord( | ||
| params: JSONSchemaType | unknown | undefined | ||
| ): Record<string, unknown> | undefined { | ||
| if (params === undefined || params === null) { | ||
| return undefined; | ||
| } | ||
| // JSONSchemaType and plain objects are compatible with Record<string, unknown> | ||
| if (typeof params === "object") { | ||
| return params as Record<string, unknown>; | ||
| } | ||
| // Primitive values shouldn't be used as parameters, but handle gracefully | ||
| return undefined; | ||
| } |
There was a problem hiding this comment.
technically a boolean is a valid json schema. You want to use the Interface object on the JSONSchema type here to restrict the type to something which will go over wire. this shouldnt be necessary.
mattzcarey
left a comment
There was a problem hiding this comment.
tentative approval. I think there is a bit of cleaning that can be done with types.
This PR adds comprehensive documentation for the new client-defined tools feature introduced in cloudflare/agents#729. Key additions: - New API reference page for client-defined tools - Detailed explanation of client-side tool registration - Examples of browser-specific tool actions (alerts, DOM manipulation) - Server-side integration using createToolsFromClientSchemas() - Advanced usage patterns with custom request data - API reference for AITool, ClientToolSchema, and OnChatMessageOptions types - Best practices for security, error handling, and TypeScript usage The documentation follows the Diátaxis framework, providing both reference material and practical examples for implementing dynamic tool registration in embeddable chat widgets and multi-tenant applications. Related to: cloudflare/agents#729 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Adds comprehensive documentation for the new client-defined tools feature introduced in PR #729, which allows clients to dynamically register tools that execute in the browser. Changes: - Added Client-Defined Tools section to agents-api.mdx - Documented AITool type with execute functions - Added client-side tool definition examples - Documented createToolsFromClientSchemas() server-side utility - Added prepareSendMessagesRequest option documentation - Updated useAgentChat type definition with new options This documentation covers: - How to define tools on the client with execute functions - Automatic schema extraction and transmission to server - Server-side handling of client tool schemas - Advanced custom request data patterns Related to cloudflare/agents#729
…uest Sync documentation from cloudflare/agents PR #729: - Add comprehensive client-defined tools guide - Update AIChatAgent API to document options parameter - Add createToolsFromClientSchemas helper documentation - Update human-in-the-loop guide with new tool format - Document prepareSendMessagesRequest option - Add useAgentChat tools and customization examples Related PR: cloudflare/agents#729
d09d42a to
8585098
Compare
ada8304 to
dc0736b
Compare
This update documents the new client-defined tools feature that enables dynamic tool registration from browser clients, essential for embeddable chat widgets and multi-tenant applications. Changes: - Add client-defined tools guide with comprehensive examples - Update useAgentChat API reference with new options: - tools: Client-side tool definitions with execute functions - toolsRequiringConfirmation: Human-in-the-loop tool approval - prepareSendMessagesRequest: Custom request data/headers - Document AIChatAgent server-side API updates: - OnChatMessageOptions type with clientTools parameter - createToolsFromClientSchemas() helper function - ClientToolSchema and AITool type definitions The new guide covers: - Client-side tool definition with JSON Schema and execute functions - Server-side tool handling with createToolsFromClientSchemas() - Human-in-the-loop workflows with toolsRequiringConfirmation - Custom request data with prepareSendMessagesRequest - Server-only tools without client execute functions - Best practices for security and performance Related to cloudflare/agents#729 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
… update message handling to merge tool results into existing assistant messages
…tions This documentation update corresponds to PR #729 in cloudflare/agents. Key changes: - Updated human-in-the-loop guide with new client-side tool definitions using JSON Schema - Added documentation for autoContinueAfterToolResult option in useAgentChat - Updated server-side tool processing to properly handle tool results - Added comprehensive examples for client-side tools with human-in-the-loop workflows - Updated agents-api documentation with new useAgentChat options: - tools: Client-side tools with optional execute functions - toolsRequiringConfirmation: List of tools requiring human approval - autoContinueAfterToolResult: Automatic continuation after tool execution Related PR: cloudflare/agents#729
Add client-defined tools and options for message requests.
Document new features from cloudflare/agents PR #729: - Add client-side tools support via useAgentChat - Add toolsRequiringConfirmation option for human-in-the-loop - Add autoContinueAfterToolResult for seamless tool execution - Update human-in-the-loop guide with new patterns - Update API reference with detailed tool configuration examples Synced from: cloudflare/agents#729 Generated with Claude Code https://claude.com/claude-code Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Fix client-side tool execution and message duplication