diff --git a/src/routes/messages/non-stream-translation.ts b/src/routes/messages/non-stream-translation.ts index dc41e6382..b34c1ad4c 100644 --- a/src/routes/messages/non-stream-translation.ts +++ b/src/routes/messages/non-stream-translation.ts @@ -48,7 +48,13 @@ export function translateToOpenAI( function translateModelName(model: string): string { // Subagent requests use a specific model number which Copilot doesn't support - if (model.startsWith("claude-sonnet-4-")) { + if (/^claude-opus-4-5-\d{8}$/.test(model)) { + return "claude-opus-4.5" + } else if (/^claude-sonnet-4-5-\d{8}$/.test(model)) { + return "claude-sonnet-4.5" + } else if (/^claude-haiku-4-5-\d{8}$/.test(model)) { + return "claude-haiku-4.5" + } else if (model.startsWith("claude-sonnet-4-")) { return model.replace(/^claude-sonnet-4-.*/, "claude-sonnet-4") } else if (model.startsWith("claude-opus-")) { return model.replace(/^claude-opus-4-.*/, "claude-opus-4") diff --git a/tests/anthropic-request.test.ts b/tests/anthropic-request.test.ts index 06c663778..4d467869e 100644 --- a/tests/anthropic-request.test.ts +++ b/tests/anthropic-request.test.ts @@ -197,6 +197,36 @@ describe("Anthropic to OpenAI translation logic", () => { expect(assistantMessage?.tool_calls).toHaveLength(1) expect(assistantMessage?.tool_calls?.[0].function.name).toBe("get_weather") }) + + test("should translate claude-opus-4-5-20251101 to claude-opus-4.5", () => { + const anthropicPayload: AnthropicMessagesPayload = { + model: "claude-opus-4-5-20251101", + messages: [{ role: "user", content: "Hello!" }], + max_tokens: 100, + } + const openAIPayload = translateToOpenAI(anthropicPayload) + expect(openAIPayload.model).toBe("claude-opus-4.5") + }) + + test("should translate claude-sonnet-4-5-20250929 to claude-sonnet-4.5", () => { + const anthropicPayload: AnthropicMessagesPayload = { + model: "claude-sonnet-4-5-20250929", + messages: [{ role: "user", content: "Hello!" }], + max_tokens: 100, + } + const openAIPayload = translateToOpenAI(anthropicPayload) + expect(openAIPayload.model).toBe("claude-sonnet-4.5") + }) + + test("should translate claude-haiku-4-5-20250929 to claude-haiku-4.5", () => { + const anthropicPayload: AnthropicMessagesPayload = { + model: "claude-haiku-4-5-20250929", + messages: [{ role: "user", content: "Hello!" }], + max_tokens: 100, + } + const openAIPayload = translateToOpenAI(anthropicPayload) + expect(openAIPayload.model).toBe("claude-haiku-4.5") + }) }) describe("OpenAI Chat Completion v1 Request Payload Validation with Zod", () => {