Repository navigation
Fix Claude native tool names for Claude Code - #663
diegosouzapw merged 2 commits into
Conversation
Code Review SummaryStatus: No Issues Found | Recommendation: Merge OverviewThe PR implements proper restoration of original tool names for Claude native (Claude-to-Claude) passthrough requests. Instead of forwarding requests completely untouched, it now performs a CLAUDE→OPENAI→CLAUDE round-trip translation to apply structural normalization while preserving original tool names. Changes Summary
Verification
Files Reviewed (3 files)
Note: The PR description mentions the unit test currently fails in the checkout due to missing |
There was a problem hiding this comment.
Code Review
This pull request updates the Claude passthrough logic to perform a round-trip translation (Claude-to-OpenAI-to-Claude), allowing the service to reuse existing normalization logic while preserving original tool names. It introduces mechanisms to map tool names from the request and restore them in both non-streaming and streaming responses. Feedback was provided to simplify the tool name extraction logic in buildClaudePassthroughToolNameMap, as the current implementation handles multiple formats unnecessarily when only the native Claude format is expected in that context.
| const toolData = | ||
| toolRecord?.type === "function" && | ||
| toolRecord.function && | ||
| typeof toolRecord.function === "object" | ||
| ? (toolRecord.function as Record<string, unknown>) | ||
| : toolRecord; | ||
| const originalName = typeof toolData?.name === "string" ? toolData.name.trim() : ""; |
There was a problem hiding this comment.
This logic for extracting toolData seems overly complex for its context. The function buildClaudePassthroughToolNameMap is invoked when isClaudePassthrough is true, which means the sourceFormat is claude. Consequently, body.tools should conform to the native Claude format, where each tool object has a name property directly.
The current implementation is robustly designed to handle both Claude and OpenAI tool formats. However, this generality is unnecessary here and adds complexity. Simplifying the code to handle only the expected Claude format would improve clarity and align it more closely with the function's specific purpose.
| const toolData = | |
| toolRecord?.type === "function" && | |
| toolRecord.function && | |
| typeof toolRecord.function === "object" | |
| ? (toolRecord.function as Record<string, unknown>) | |
| : toolRecord; | |
| const originalName = typeof toolData?.name === "string" ? toolData.name.trim() : ""; | |
| const originalName = typeof toolRecord?.name === "string" ? toolRecord.name.trim() : ""; |
There was a problem hiding this comment.
Pull request overview
This PR addresses Claude Code compatibility by ensuring Claude-native tool names are preserved when proxying Claude /v1/messages requests/responses, including both non-streaming and SSE passthrough flows.
Changes:
- Restores original Claude tool names in Claude→Claude passthrough responses (non-streaming) and in Claude SSE
content_block_starttool_use chunks. - Routes Claude→Claude “passthrough” requests through a Claude→OpenAI→Claude normalization round-trip (instead of forwarding raw payloads).
- Adds a unit test intended to cover native Claude passthrough tool-name behavior.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| tests/unit/claude-native-passthrough-tools.test.mjs | Adds a unit test for Claude-native passthrough tool-name preservation (currently incomplete/broken). |
| open-sse/utils/stream.ts | Restores tool_use content_block.name during Claude SSE passthrough using a tool-name map. |
| open-sse/handlers/chatCore.ts | Builds tool-name maps for Claude passthrough and restores tool_use names in non-streaming Claude responses; changes Claude→Claude request handling to normalize via OpenAI. |
Comments suppressed due to low confidence (1)
tests/unit/claude-native-passthrough-tools.test.mjs:42
- This new unit test file is syntactically incomplete (it ends mid-
translateRequest(...)call), which will cause the entire test suite to fail to parse/run. Finish the call(s), close the test block, and add an assertion that verifies the translated Claude body/tool definitions (and/or tool_use blocks) keep the original tool name (e.g.,TodoWrite) rather thanproxy_TodoWrite.
const openaiBody = translateRequest(
FORMATS.CLAUDE,
FORMATS.OPENAI,
body.model,
structuredClone(body),
false,
null,
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Thanks @coobabm for this excellent fix! 🎉 The Claude native tool name restoration is exactly what was needed — keeps the passthrough path clean for Claude Code. The unit test is a great addition too. Merged and shipping with v3.1.6! 🚀 |
Changes: - fix: restore native Claude tool names in passthrough responses (PR #663 by @coobabm) - fix: Clear All Models button now also removes aliases (PR #664 by @rdself) - fix: completed truncated test from PR #663, added Claude-to-Claude passthrough test - docs: update CHANGELOG and OpenAPI spec
…tive-tool-fix-push Fix Claude native tool names for Claude Code
Changes: - fix: restore native Claude tool names in passthrough responses (PR cheaper-inference#663 by @coobabm) - fix: Clear All Models button now also removes aliases (PR cheaper-inference#664 by @rdself) - fix: completed truncated test from PR cheaper-inference#663, added Claude-to-Claude passthrough test - docs: update CHANGELOG and OpenAPI spec
…tive-tool-fix-push Fix Claude native tool names for Claude Code
Changes: - fix: restore native Claude tool names in passthrough responses (PR cheaper-inference#663 by @coobabm) - fix: Clear All Models button now also removes aliases (PR cheaper-inference#664 by @rdself) - fix: completed truncated test from PR cheaper-inference#663, added Claude-to-Claude passthrough test - docs: update CHANGELOG and OpenAPI spec
Summary\n- restore native Claude tool names before returning non-stream and SSE passthrough responses\n- keep Claude OAuth native messages requests on the normalized Claude path\n- add a unit test covering native Claude passthrough tool names\n\n## Verification\n- verified /v1/messages non-stream returns TodoWrite instead of proxy_TodoWrite\n- verified /v1/messages SSE content_block_start returns TodoWrite\n- node --import tsx/esm --test tests/unit/claude-native-passthrough-tools.test.mjs currently fails in this server checkout because tsx is not installed