mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-05 14:52:09 +03:00
Fix empty tool name 400 errors from Claude API and missing @swc/helpers in Docker (#288)
* Initial plan * fix: filter empty tool names and missing tool_use_id; add @swc/helpers to Docker Co-authored-by: ngleichner1 <263653359+ngleichner1@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: ngleichner1 <263653359+ngleichner1@users.noreply.github.com>
This commit is contained in:
@@ -29,6 +29,8 @@ RUN mkdir -p /app/data
|
||||
COPY --from=builder /app/public ./public
|
||||
COPY --from=builder /app/.next/static ./.next/static
|
||||
COPY --from=builder /app/.next/standalone ./
|
||||
# Explicitly copy @swc/helpers — not always traced by standalone output but needed at runtime
|
||||
COPY --from=builder /app/node_modules/@swc/helpers ./node_modules/@swc/helpers
|
||||
COPY --from=builder /app/scripts/run-standalone.mjs ./run-standalone.mjs
|
||||
COPY --from=builder /app/scripts/runtime-env.mjs ./runtime-env.mjs
|
||||
COPY --from=builder /app/scripts/healthcheck.mjs ./healthcheck.mjs
|
||||
|
||||
@@ -127,14 +127,24 @@ export function prepareClaudeRequest(body, provider = null) {
|
||||
}
|
||||
|
||||
// Pass 1.4: Filter out tool_use blocks with empty names (causes Claude 400 error)
|
||||
// Apply to ALL roles (assistant tool_use + any user messages that may carry tool_use)
|
||||
// Also filter tool_result blocks with missing tool_use_id
|
||||
for (const msg of filtered) {
|
||||
if (msg.role === "assistant" && Array.isArray(msg.content)) {
|
||||
if (Array.isArray(msg.content)) {
|
||||
msg.content = msg.content.filter(
|
||||
(block) => block.type !== "tool_use" || (block.name && block.name.trim())
|
||||
(block) => block.type !== "tool_use" || (block.name && block.name?.trim())
|
||||
);
|
||||
msg.content = msg.content.filter(
|
||||
(block) => block.type !== "tool_result" || block.tool_use_id
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Also filter top-level tool declarations with empty names
|
||||
if (body.tools && Array.isArray(body.tools)) {
|
||||
body.tools = body.tools.filter((tool) => tool.name && tool.name?.trim());
|
||||
}
|
||||
|
||||
// Pass 1.5: Fix tool_use/tool_result ordering
|
||||
// Each tool_use must have tool_result in the NEXT message (not same message with other content)
|
||||
filtered = fixToolUseOrdering(filtered);
|
||||
|
||||
@@ -175,6 +175,9 @@ export function openaiToClaudeRequest(model, body, stream) {
|
||||
};
|
||||
});
|
||||
|
||||
// Filter out tools with empty names (would cause Claude 400 error)
|
||||
result.tools = result.tools.filter((tool) => tool.name && tool.name?.trim());
|
||||
|
||||
// Add cache_control to last tool that doesn't have defer_loading
|
||||
// Tools with defer_loading=true cannot have cache_control (API rejects it)
|
||||
for (let i = result.tools.length - 1; i >= 0; i--) {
|
||||
@@ -227,6 +230,8 @@ function getContentBlocksFromMessage(msg, toolNameMap = new Map(), disableToolPr
|
||||
if (part.type === "text" && part.text) {
|
||||
blocks.push({ type: "text", text: part.text });
|
||||
} else if (part.type === "tool_result") {
|
||||
// Skip tool_result with no tool_use_id (would be useless and may cause errors)
|
||||
if (!part.tool_use_id) continue;
|
||||
blocks.push({
|
||||
type: "tool_result",
|
||||
tool_use_id: part.tool_use_id,
|
||||
|
||||
Reference in New Issue
Block a user