Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 15 additions & 9 deletions src/api/providers/__tests__/openrouter.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ describe("OpenRouterHandler", () => {
top_p: undefined,
transforms: ["middle-out"],
}),
{ headers: { "x-anthropic-beta": "fine-grained-tool-streaming-2025-05-14" } },
)
})

Expand All @@ -218,7 +219,9 @@ describe("OpenRouterHandler", () => {

await handler.createMessage("test", []).next()

expect(mockCreate).toHaveBeenCalledWith(expect.objectContaining({ transforms: ["middle-out"] }))
expect(mockCreate).toHaveBeenCalledWith(expect.objectContaining({ transforms: ["middle-out"] }), {
headers: { "x-anthropic-beta": "fine-grained-tool-streaming-2025-05-14" },
})
})

it("adds cache control for supported models", async () => {
Expand Down Expand Up @@ -260,6 +263,7 @@ describe("OpenRouterHandler", () => {
}),
]),
}),
{ headers: { "x-anthropic-beta": "fine-grained-tool-streaming-2025-05-14" } },
)
})

Expand Down Expand Up @@ -295,14 +299,16 @@ describe("OpenRouterHandler", () => {

expect(result).toBe("test completion")

expect(mockCreate).toHaveBeenCalledWith({
model: mockOptions.openRouterModelId,
max_tokens: 8192,
thinking: undefined,
temperature: 0,
messages: [{ role: "user", content: "test prompt" }],
stream: false,
})
expect(mockCreate).toHaveBeenCalledWith(
{
model: mockOptions.openRouterModelId,
max_tokens: 8192,
temperature: 0,
messages: [{ role: "user", content: "test prompt" }],
stream: false,
},
{ headers: { "x-anthropic-beta": "fine-grained-tool-streaming-2025-05-14" } },
)
})

it("handles API errors", async () => {
Expand Down
14 changes: 12 additions & 2 deletions src/api/providers/openrouter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,9 +213,14 @@ export class OpenRouterHandler extends BaseProvider implements SingleCompletionH
...(metadata?.tool_choice && { tool_choice: metadata.tool_choice }),
}

// Add Anthropic beta header for fine-grained tool streaming when using Anthropic models
const requestOptions = modelId.startsWith("anthropic/")
? { headers: { "x-anthropic-beta": "fine-grained-tool-streaming-2025-05-14" } }
: undefined

let stream
try {
stream = await this.client.chat.completions.create(completionParams)
stream = await this.client.chat.completions.create(completionParams, requestOptions)
} catch (error) {
throw handleOpenAIError(error, this.providerName)
}
Expand Down Expand Up @@ -417,9 +422,14 @@ export class OpenRouterHandler extends BaseProvider implements SingleCompletionH
...(reasoning && { reasoning }),
}

// Add Anthropic beta header for fine-grained tool streaming when using Anthropic models
const requestOptions = modelId.startsWith("anthropic/")
? { headers: { "x-anthropic-beta": "fine-grained-tool-streaming-2025-05-14" } }
: undefined

let response
try {
response = await this.client.chat.completions.create(completionParams)
response = await this.client.chat.completions.create(completionParams, requestOptions)
} catch (error) {
throw handleOpenAIError(error, this.providerName)
}
Expand Down
Loading