From 6274adce3aa257a63bf7fe31ac6ec1b22a42a0d1 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 10 Jan 2026 04:18:00 +0100 Subject: [PATCH] fix(tools): keep canonical tool names for oauth --- src/agents/pi-tools.test.ts | 16 +++++----------- src/agents/pi-tools.ts | 33 ++++----------------------------- 2 files changed, 9 insertions(+), 40 deletions(-) diff --git a/src/agents/pi-tools.test.ts b/src/agents/pi-tools.test.ts index 07e98b292..59ad6f7d0 100644 --- a/src/agents/pi-tools.test.ts +++ b/src/agents/pi-tools.test.ts @@ -158,22 +158,16 @@ describe("createClawdbotCodingTools", () => { expect(tools.some((tool) => tool.name === "process")).toBe(true); }); - it("renames blocked tool names only for Anthropic OAuth", () => { + it("keeps canonical tool names for Anthropic OAuth (pi-ai remaps on the wire)", () => { const tools = createClawdbotCodingTools({ modelProvider: "anthropic", modelAuthMode: "oauth", }); const names = new Set(tools.map((tool) => tool.name)); - expect(names.has("Bash")).toBe(true); - expect(names.has("Read")).toBe(true); - expect(names.has("Write")).toBe(true); - expect(names.has("Edit")).toBe(true); - - // Ensure the blocked lowercase variants are not present in the schema. - expect(names.has("bash")).toBe(false); - expect(names.has("read")).toBe(false); - expect(names.has("write")).toBe(false); - expect(names.has("edit")).toBe(false); + expect(names.has("bash")).toBe(true); + expect(names.has("read")).toBe(true); + expect(names.has("write")).toBe(true); + expect(names.has("edit")).toBe(true); }); it("provides top-level object schemas for all tools", () => { diff --git a/src/agents/pi-tools.ts b/src/agents/pi-tools.ts index 1fa265f21..ad3925b86 100644 --- a/src/agents/pi-tools.ts +++ b/src/agents/pi-tools.ts @@ -284,28 +284,6 @@ function normalizeToolNames(list?: string[]) { return list.map((entry) => entry.trim().toLowerCase()).filter(Boolean); } -/** - * Anthropic blocks specific lowercase tool names (bash, read, write, edit) with OAuth tokens. - * Renaming to capitalized versions bypasses the block while maintaining compatibility - * with Anthropic API keys and other providers. - */ -const OAUTH_BLOCKED_TOOL_NAMES: Record = { - bash: "Bash", - read: "Read", - write: "Write", - edit: "Edit", -}; - -function renameBlockedToolsForOAuth(tools: AnyAgentTool[]): AnyAgentTool[] { - return tools.map((tool) => { - const newName = OAUTH_BLOCKED_TOOL_NAMES[tool.name]; - if (newName) { - return { ...tool, name: newName }; - } - return tool; - }); -} - const DEFAULT_SUBAGENT_TOOL_DENY = [ "sessions_list", "sessions_history", @@ -667,11 +645,8 @@ export function createClawdbotCodingTools(options?: { ) : normalized; - // Anthropic blocks specific lowercase tool names (bash, read, write, edit) with OAuth tokens. - // Only apply the rename when we are actually using (or likely using) Anthropic OAuth. - const provider = options?.modelProvider?.trim(); - const authMode = options?.modelAuthMode; - const isAnthropicOAuth = - provider === "anthropic" && (authMode === "oauth" || authMode === "mixed"); - return isAnthropicOAuth ? renameBlockedToolsForOAuth(withAbort) : withAbort; + // NOTE: Keep canonical (lowercase) tool names here. + // pi-ai's Anthropic OAuth transport remaps tool names to Claude Code-style names + // on the wire and maps them back for tool dispatch. + return withAbort; }