fix(opencode): preserve signed thinking during anthropic reorder (#30182)

This commit is contained in:
Aiden Cline 2026-06-02 23:33:48 -05:00 committed by GitHub
parent 0294342f77
commit 42173bca4b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 59 additions and 0 deletions

View File

@ -230,6 +230,18 @@ function normalizeMessages(
const parts = msg.content
const first = parts.findIndex((part) => part.type === "tool-call")
if (first === -1) return [msg]
// Anthropic signs thinking blocks, so moving them during replay invalidates the request.
if (
parts
.slice(first)
.some(
(part) =>
part.type === "reasoning" &&
(part.providerOptions?.anthropic?.signature != null ||
part.providerOptions?.anthropic?.redactedData != null),
)
)
return [msg]
if (!parts.slice(first).some((part) => part.type !== "tool-call")) return [msg]
return [
{ ...msg, content: parts.filter((part) => part.type !== "tool-call") },

View File

@ -1680,6 +1680,25 @@ describe("ProviderTransform.message - anthropic empty content filtering", () =>
])
})
test("leaves signed anthropic reasoning after tool calls unchanged", () => {
const msgs = [
{
role: "assistant",
content: [
{ type: "reasoning", text: "First thought", providerOptions: { anthropic: { signature: "sig-1" } } },
{ type: "tool-call", toolCallId: "toolu_1", toolName: "read", input: { filePath: "/root" } },
{ type: "reasoning", text: "Second thought", providerOptions: { anthropic: { signature: "sig-2" } } },
{ type: "tool-call", toolCallId: "toolu_2", toolName: "glob", input: { pattern: "**/*.pdf" } },
],
},
] as any[]
const result = ProviderTransform.message(msgs, anthropicModel, {}) as any[]
expect(result).toHaveLength(1)
expect(result[0].content).toMatchObject(msgs[0].content)
})
test("splits vertex anthropic assistant messages when text trails tool calls", () => {
const model = {
...anthropicModel,
@ -1717,6 +1736,34 @@ describe("ProviderTransform.message - anthropic empty content filtering", () =>
],
})
})
test("leaves redacted vertex anthropic reasoning after tool calls unchanged", () => {
const model = {
...anthropicModel,
providerID: "google-vertex-anthropic",
api: {
id: "claude-sonnet-4@20250514",
url: "https://us-central1-aiplatform.googleapis.com",
npm: "@ai-sdk/google-vertex/anthropic",
},
}
const msgs = [
{
role: "assistant",
content: [
{ type: "tool-call", toolCallId: "toolu_1", toolName: "read", input: { filePath: "/root" } },
{ type: "reasoning", text: "", providerOptions: { anthropic: { redactedData: "redacted-1" } } },
{ type: "tool-call", toolCallId: "toolu_2", toolName: "glob", input: { pattern: "**/*.pdf" } },
],
},
] as any[]
const result = ProviderTransform.message(msgs, model, {}) as any[]
expect(result).toHaveLength(1)
expect(result[0].content).toMatchObject(msgs[0].content)
})
})
describe("ProviderTransform.message - strip openai metadata when store=false", () => {