mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-07 08:26:51 +00:00
fix: apply reasoning stripping to anthropic-vertex, add cache control test
- Apply the same reasoning_details/reasoning_content stripping to anthropic-vertex.ts that was already applied to anthropic.ts and openrouter.ts (identical no-op cast bug) - Pass aiSdkMessages (mapped copy) to applyCacheControlToAiSdkMessages in anthropic-vertex.ts so cache control mutations target the copies sent to streamText - Add test verifying cache control providerOptions are applied to the mapped message copies (not the originals) when messages contain extra legacy fields
This commit is contained in:
parent
7375a59931
commit
8b9ae4bb58
2 changed files with 48 additions and 3 deletions
|
|
@ -438,6 +438,47 @@ describe("AnthropicHandler", () => {
|
|||
expect(callArgs.messages[1].content).toEqual([{ type: "text", text: "Hi" }])
|
||||
})
|
||||
|
||||
it("should apply cache control providerOptions to mapped message copies (not originals)", async () => {
|
||||
setupStreamTextMock([{ type: "text-delta", text: "test" }])
|
||||
|
||||
// Messages with extra legacy fields — .map() creates new objects to strip them
|
||||
const messagesWithExtraFields = [
|
||||
{
|
||||
role: "user",
|
||||
content: [{ type: "text" as const, text: "Hello" }],
|
||||
},
|
||||
{
|
||||
role: "assistant",
|
||||
content: [{ type: "text" as const, text: "Hi" }],
|
||||
reasoning_details: [{ type: "thinking", thinking: "deep thoughts" }],
|
||||
},
|
||||
{
|
||||
role: "user",
|
||||
content: [{ type: "text" as const, text: "Follow up" }],
|
||||
},
|
||||
] as any
|
||||
|
||||
const stream = handler.createMessage(systemPrompt, messagesWithExtraFields)
|
||||
|
||||
for await (const _chunk of stream) {
|
||||
// Consume stream
|
||||
}
|
||||
|
||||
expect(mockStreamText).toHaveBeenCalledTimes(1)
|
||||
const callArgs = mockStreamText.mock.calls[0]![0]
|
||||
|
||||
// The last user message (index 2) should have cache control applied
|
||||
const lastUserMsg = callArgs.messages[2]
|
||||
expect(lastUserMsg.role).toBe("user")
|
||||
expect(lastUserMsg.providerOptions).toBeDefined()
|
||||
expect(lastUserMsg.providerOptions.anthropic).toEqual({
|
||||
cacheControl: { type: "ephemeral" },
|
||||
})
|
||||
|
||||
// And it should still NOT have reasoning_details (stripped by .map())
|
||||
expect(lastUserMsg).not.toHaveProperty("reasoning_details")
|
||||
})
|
||||
|
||||
it("should pass system prompt via system param with systemProviderOptions for cache control", async () => {
|
||||
setupStreamTextMock([{ type: "text-delta", text: "test" }])
|
||||
|
||||
|
|
|
|||
|
|
@ -90,8 +90,12 @@ export class AnthropicVertexHandler extends BaseProvider implements SingleComple
|
|||
): ApiStream {
|
||||
const modelConfig = this.getModel()
|
||||
|
||||
// Convert messages to AI SDK format
|
||||
const aiSdkMessages = messages as ModelMessage[]
|
||||
// Convert messages to AI SDK format, stripping extra fields from legacy
|
||||
// ApiMessage objects that survive JSON deserialization (e.g. reasoning_details
|
||||
// causes Anthropic 400: "Extra inputs are not permitted").
|
||||
const aiSdkMessages = messages.map(
|
||||
({ reasoning_details, reasoning_content, ...rest }: any) => rest,
|
||||
) as ModelMessage[]
|
||||
|
||||
// Convert tools to AI SDK format
|
||||
const openAiTools = this.convertToolsForOpenAI(metadata?.tools)
|
||||
|
|
@ -147,7 +151,7 @@ export class AnthropicVertexHandler extends BaseProvider implements SingleComple
|
|||
if (secondLastUserMsgIndex >= 0) targetIndices.add(secondLastUserMsgIndex)
|
||||
|
||||
if (targetIndices.size > 0) {
|
||||
this.applyCacheControlToAiSdkMessages(messages as ModelMessage[], targetIndices, cacheProviderOption)
|
||||
this.applyCacheControlToAiSdkMessages(aiSdkMessages, targetIndices, cacheProviderOption)
|
||||
}
|
||||
|
||||
// Build streamText request
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue