fix(translator): strict Anthropic content block compliance (#2225)
Filter empty text blocks from thoughtSignature-only parts, preserve tool_calls when functionResponse and functionCall coexist in the same content, and skip empty regular text parts before they reach Claude. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
committed by
decolua
parent
7afaecd617
commit
ce6120ce7b
@@ -138,12 +138,14 @@ function convertContent(content) {
|
||||
|
||||
// Text with thoughtSignature = regular text after thinking
|
||||
if (part.thoughtSignature && part.text !== undefined) {
|
||||
textParts.push({ type: OPENAI_BLOCK.TEXT, text: part.text });
|
||||
if (part.text) {
|
||||
textParts.push({ type: OPENAI_BLOCK.TEXT, text: part.text });
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// Regular text
|
||||
if (part.text !== undefined) {
|
||||
if (part.text !== undefined && part.text !== "") {
|
||||
textParts.push({ type: OPENAI_BLOCK.TEXT, text: part.text });
|
||||
}
|
||||
|
||||
@@ -180,8 +182,22 @@ function convertContent(content) {
|
||||
}
|
||||
}
|
||||
|
||||
// Content with only functionResponses → return array of tool messages
|
||||
// Content with functionResponses — return array of tool result messages,
|
||||
// plus an assistant message for any co-located tool calls / text.
|
||||
if (toolResults.length > 0) {
|
||||
if (toolCalls.length > 0 || textParts.length > 0 || reasoningContent) {
|
||||
const assistantMsg = { role: ROLE.ASSISTANT };
|
||||
if (textParts.length > 0) {
|
||||
assistantMsg.content = collapseTextParts(textParts);
|
||||
}
|
||||
if (reasoningContent) {
|
||||
assistantMsg.reasoning_content = reasoningContent;
|
||||
}
|
||||
if (toolCalls.length > 0) {
|
||||
assistantMsg.tool_calls = toolCalls;
|
||||
}
|
||||
return [...toolResults, assistantMsg];
|
||||
}
|
||||
return toolResults;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,10 +9,9 @@ const AG2O = (req) =>
|
||||
translateRequest(FORMATS.ANTIGRAVITY, FORMATS.OPENAI, "m", { request: req }, true, null, null);
|
||||
|
||||
describe("Antigravity → OpenAI", () => {
|
||||
// antigravity-to-openai.js:177-189 — content with BOTH functionResponse and functionCall/text
|
||||
// returns toolResults early → drops the tool calls / text.
|
||||
// KNOWN BUG
|
||||
it.fails("functionResponse + functionCall in same content keeps both", () => {
|
||||
// antigravity-to-openai.js — content with BOTH functionResponse and functionCall/text
|
||||
// previously returned toolResults early → dropped tool calls / text (fixed in #2225)
|
||||
it("functionResponse + functionCall in same content keeps both", () => {
|
||||
const out = AG2O({
|
||||
contents: [{
|
||||
role: "model",
|
||||
|
||||
Reference in New Issue
Block a user