mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-13 23:11:10 +00:00
Prevent xAI replay from exposing persisted Anthropic reasoning
The xAI Responses path reuses convertToResponsesApiInput() when replaying persisted conversation history. Anthropic thinking blocks were being flattened into ordinary assistant-visible output_text entries, which changes conversation semantics and leaks hidden reasoning into later prompt context. This keeps the fix intentionally narrow: persisted Anthropic thinking blocks are now skipped for Responses replay, and a regression test covers the behavior. Constraint: Keep the change scoped to the replay transform without changing provider selection or task persistence Rejected: Preserve thinking by converting it to [Thinking] output_text | turns hidden reasoning into visible assistant content Confidence: medium Scope-risk: narrow Reversibility: clean Directive: If a provider-specific hidden reasoning replay format is added later, prefer that over flattening Anthropic thinking into visible text Tested: pnpm --dir src exec vitest run api/transform/__tests__/responses-api-input.spec.ts api/providers/__tests__/xai.spec.ts Not-tested: Full end-to-end provider-switch replay with live xAI credentials
This commit is contained in:
parent
cb83656718
commit
f8a2873be9
2 changed files with 27 additions and 8 deletions
|
|
@ -280,6 +280,28 @@ describe("convertToResponsesApiInput", () => {
|
|||
}),
|
||||
)
|
||||
})
|
||||
|
||||
it("should not replay Anthropic thinking blocks as assistant-visible text", () => {
|
||||
const messages: Anthropic.Messages.MessageParam[] = [
|
||||
{
|
||||
role: "assistant",
|
||||
content: [
|
||||
{ type: "thinking", thinking: "SECRET_CHAIN_OF_THOUGHT", signature: "sig-1" } as any,
|
||||
{ type: "text", text: "visible answer" },
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
const result = convertToResponsesApiInput(messages)
|
||||
|
||||
expect(result).toEqual([
|
||||
{
|
||||
type: "message",
|
||||
role: "assistant",
|
||||
content: [{ type: "output_text", text: "visible answer" }],
|
||||
},
|
||||
])
|
||||
})
|
||||
})
|
||||
|
||||
describe("multi-turn conversations", () => {
|
||||
|
|
|
|||
|
|
@ -53,14 +53,11 @@ export function convertToResponsesApiInput(messages: Anthropic.Messages.MessageP
|
|||
})
|
||||
break
|
||||
case "thinking":
|
||||
// Include reasoning if it has content
|
||||
if ((part as any).thinking && (part as any).thinking.trim().length > 0) {
|
||||
input.push({
|
||||
type: "message",
|
||||
role: "assistant",
|
||||
content: [{ type: "output_text", text: `[Thinking] ${(part as any).thinking}` }],
|
||||
})
|
||||
}
|
||||
// Anthropic thinking blocks represent hidden reasoning. The
|
||||
// Responses API input format does not have a compatible hidden
|
||||
// reasoning representation for these persisted blocks, so replaying
|
||||
// them as normal assistant-visible text changes conversation
|
||||
// semantics. Skip them instead of flattening them into output_text.
|
||||
break
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue