Skip to content

Commit 62bf497

Browse files
author
Kuo, Joseph
committed
fix(provider): preserve Bedrock Claude reasoning replay
1 parent 9730008 commit 62bf497

2 files changed

Lines changed: 74 additions & 2 deletions

File tree

packages/opencode/src/provider/transform.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,11 @@ function normalizeMessages(
175175
return result
176176
}
177177

178-
if (typeof model.capabilities.interleaved === "object" && model.capabilities.interleaved.field) {
178+
if (
179+
model.api.npm === "@ai-sdk/openai-compatible" &&
180+
typeof model.capabilities.interleaved === "object" &&
181+
model.capabilities.interleaved.field
182+
) {
179183
const field = model.capabilities.interleaved.field
180184
return msgs.map((msg) => {
181185
if (msg.role === "assistant" && Array.isArray(msg.content)) {
@@ -185,7 +189,8 @@ function normalizeMessages(
185189
// Filter out reasoning parts from content
186190
const filteredContent = msg.content.filter((part: any) => part.type !== "reasoning")
187191

188-
// Include reasoning_content | reasoning_details directly on the message for all assistant messages
192+
// Include reasoning_content | reasoning_details directly on the message for
193+
// OpenAI-compatible assistant messages.
189194
if (reasoningText) {
190195
return {
191196
...msg,

packages/opencode/test/provider/transform.test.ts

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -977,6 +977,73 @@ describe("ProviderTransform.message - DeepSeek reasoning content", () => {
977977
])
978978
expect(result[0].providerOptions?.openaiCompatible?.reasoning_content).toBeUndefined()
979979
})
980+
981+
test("Bedrock providers keep reasoning metadata even if interleaved is configured", () => {
982+
const msgs = [
983+
{
984+
role: "assistant",
985+
content: [
986+
{
987+
type: "reasoning",
988+
text: "Thinking...",
989+
providerMetadata: {
990+
bedrock: { signature: "sig-123" },
991+
},
992+
},
993+
{ type: "text", text: "Answer" },
994+
],
995+
},
996+
] as any[]
997+
998+
const result = ProviderTransform.message(
999+
msgs,
1000+
{
1001+
id: ModelID.make("bedrock/anthropic-claude-opus-4-7"),
1002+
providerID: ProviderID.make("bedrock"),
1003+
api: {
1004+
id: "anthropic.claude-opus-4-7",
1005+
url: "https://bedrock.amazonaws.com",
1006+
npm: "@ai-sdk/amazon-bedrock",
1007+
},
1008+
name: "Claude Opus 4.7",
1009+
capabilities: {
1010+
temperature: true,
1011+
reasoning: true,
1012+
attachment: true,
1013+
toolcall: true,
1014+
input: { text: true, audio: false, image: true, video: false, pdf: true },
1015+
output: { text: true, audio: false, image: false, video: false, pdf: false },
1016+
interleaved: {
1017+
field: "reasoning_content",
1018+
},
1019+
},
1020+
cost: {
1021+
input: 0.001,
1022+
output: 0.002,
1023+
cache: { read: 0.0001, write: 0.0002 },
1024+
},
1025+
limit: {
1026+
context: 200_000,
1027+
output: 64_000,
1028+
},
1029+
status: "active",
1030+
options: {},
1031+
headers: {},
1032+
release_date: "2024-01-01",
1033+
},
1034+
{},
1035+
)
1036+
1037+
expect(result[0].content[0]).toMatchObject({
1038+
type: "reasoning",
1039+
text: "Thinking...",
1040+
providerMetadata: {
1041+
bedrock: { signature: "sig-123" },
1042+
},
1043+
})
1044+
expect(result[0].content[1]).toEqual({ type: "text", text: "Answer" })
1045+
expect(result[0].providerOptions?.openaiCompatible?.reasoning_content).toBeUndefined()
1046+
})
9801047
})
9811048

9821049
describe("ProviderTransform.message - empty image handling", () => {

0 commit comments

Comments
 (0)