Skip to content

Commit 889cb6c

Browse files
authored
properly convert custom / mcp tools to anthropic cua format (#1103)
Why Custom AI SDK tools and MCP integrations weren't working properly with Anthropic CUA - parameters were empty {} and tools weren't tracked. What Changed - Convert Zod schemas to JSON Schema before sending to Anthropic (using zodToJsonSchema) - Track custom tool calls in the actions array - Silence "Unknown tool name" warnings for custom tools Test Plan Tested with examples file. Parameters passed correctly ({"city":"San Francisco"} instead of {}) Custom tools execute and appear in actions array No warnings
1 parent e0e6b30 commit 889cb6c

File tree

2 files changed

+24
-11
lines changed

2 files changed

+24
-11
lines changed

.changeset/short-mirrors-switch.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@browserbasehq/stagehand": patch
3+
---
4+
5+
patch custom tool support in anthropic cua client

lib/agent/AnthropicCUAClient.ts

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { LogLine } from "@/types/log";
1313
import { AgentScreenshotProviderError } from "@/types/stagehandErrors";
1414
import Anthropic from "@anthropic-ai/sdk";
1515
import { ToolSet } from "ai";
16+
import { zodToJsonSchema } from "zod-to-json-schema";
1617
import { AgentClient } from "./AgentClient";
1718
import { mapKeyToPlaywright } from "./utils/cuaKeyMapping";
1819
import { compressConversationImages } from "./utils/imageCompression";
@@ -275,6 +276,12 @@ export class AnthropicCUAClient extends AgentClient {
275276
level: 2,
276277
});
277278
stepActions.push(action);
279+
} else if (this.tools && toolUseItem.name in this.tools) {
280+
stepActions.push({
281+
type: "custom_tool",
282+
tool: toolUseItem.name,
283+
input: toolUseItem.input,
284+
} as AgentAction);
278285
}
279286
} else if (block.type === "text") {
280287
// Safe to cast here since we've verified it's a text block
@@ -436,17 +443,16 @@ export class AnthropicCUAClient extends AgentClient {
436443
if (this.tools && Object.keys(this.tools).length > 0) {
437444
const customTools = Object.entries(this.tools).map(([name, tool]) => {
438445
// Convert Zod schema to proper JSON schema format for Anthropic
439-
let inputSchema = tool.parameters;
440-
441-
// Ensure the schema has the required 'type' field at root level
442-
if (typeof inputSchema === "object" && inputSchema !== null) {
443-
if (!("type" in inputSchema)) {
444-
inputSchema = {
445-
type: "object",
446-
...inputSchema,
447-
};
448-
}
449-
}
446+
const jsonSchema = zodToJsonSchema(tool.parameters) as {
447+
properties?: Record<string, unknown>;
448+
required?: string[];
449+
};
450+
451+
const inputSchema = {
452+
type: "object",
453+
properties: jsonSchema.properties || {},
454+
required: jsonSchema.required || [],
455+
};
450456

451457
return {
452458
name,
@@ -890,6 +896,8 @@ export class AnthropicCUAClient extends AgentClient {
890896
type: name,
891897
params: input,
892898
};
899+
} else if (this.tools && name in this.tools) {
900+
return null;
893901
}
894902

895903
console.warn(`Unknown tool name: ${name}`);

0 commit comments

Comments
 (0)