fix: send anthropic thinking blocks also when thinking text is empty (#6457)
fixes: #6376
This commit is contained in:
@@ -1081,11 +1081,13 @@ function convertMessages(
|
|||||||
});
|
});
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (block.thinking.trim().length === 0) continue;
|
const thinkingSignature = block.thinkingSignature;
|
||||||
|
const hasThinkingSignature = !!thinkingSignature && thinkingSignature.trim().length > 0;
|
||||||
|
if (block.thinking.trim().length === 0 && !hasThinkingSignature) continue;
|
||||||
// If thinking signature is missing/empty (e.g., from aborted stream),
|
// If thinking signature is missing/empty (e.g., from aborted stream),
|
||||||
// convert to plain text for Anthropic. Some compatible providers emit
|
// convert to plain text for Anthropic. Some compatible providers emit
|
||||||
// and accept empty signatures, so let marked models preserve the block.
|
// and accept empty signatures, so let marked models preserve the block.
|
||||||
if (!block.thinkingSignature || block.thinkingSignature.trim().length === 0) {
|
if (!hasThinkingSignature) {
|
||||||
blocks.push(
|
blocks.push(
|
||||||
allowEmptySignature
|
allowEmptySignature
|
||||||
? {
|
? {
|
||||||
@@ -1102,7 +1104,7 @@ function convertMessages(
|
|||||||
blocks.push({
|
blocks.push({
|
||||||
type: "thinking",
|
type: "thinking",
|
||||||
thinking: sanitizeSurrogates(block.thinking),
|
thinking: sanitizeSurrogates(block.thinking),
|
||||||
signature: block.thinkingSignature,
|
signature: thinkingSignature,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else if (block.type === "toolCall") {
|
} else if (block.type === "toolCall") {
|
||||||
|
|||||||
@@ -32,10 +32,10 @@ function makeModel(allowEmptySignature?: boolean): Model<"anthropic-messages"> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeContext(thinkingSignature: string): Context {
|
function makeContext(thinkingSignature: string, thinking = "internal reasoning"): Context {
|
||||||
const assistant: AssistantMessage = {
|
const assistant: AssistantMessage = {
|
||||||
role: "assistant",
|
role: "assistant",
|
||||||
content: [{ type: "thinking", thinking: "internal reasoning", thinkingSignature }],
|
content: [{ type: "thinking", thinking, thinkingSignature }],
|
||||||
provider: "xiaomi-token-plan-ams",
|
provider: "xiaomi-token-plan-ams",
|
||||||
api: "anthropic-messages",
|
api: "anthropic-messages",
|
||||||
model: "mimo-v2.5-pro",
|
model: "mimo-v2.5-pro",
|
||||||
@@ -80,6 +80,12 @@ describe("Anthropic empty thinking signature compat", () => {
|
|||||||
expect(assistant?.content).toEqual([{ type: "text", text: "internal reasoning" }]);
|
expect(assistant?.content).toEqual([{ type: "text", text: "internal reasoning" }]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("preserves empty thinking text when the signature is present", async () => {
|
||||||
|
const payload = await capturePayload(makeModel(), makeContext("signed-thinking", ""));
|
||||||
|
const assistant = payload.messages?.find((message) => message.role === "assistant");
|
||||||
|
expect(assistant?.content).toEqual([{ type: "thinking", thinking: "", signature: "signed-thinking" }]);
|
||||||
|
});
|
||||||
|
|
||||||
it("preserves empty-signature thinking when allowEmptySignature is enabled", async () => {
|
it("preserves empty-signature thinking when allowEmptySignature is enabled", async () => {
|
||||||
const payload = await capturePayload(makeModel(true), makeContext(" "));
|
const payload = await capturePayload(makeModel(true), makeContext(" "));
|
||||||
const assistant = payload.messages?.find((message) => message.role === "assistant");
|
const assistant = payload.messages?.find((message) => message.role === "assistant");
|
||||||
|
|||||||
Reference in New Issue
Block a user