2026-02-17 21:15:38 +09:00
|
|
|
import { describe, expect, test } from "bun:test"
|
|
|
|
|
|
|
|
|
|
import { transformModelForProvider } from "./provider-model-id-transform"
|
|
|
|
|
|
|
|
|
|
describe("transformModelForProvider", () => {
|
|
|
|
|
describe("github-copilot provider", () => {
|
|
|
|
|
test("transforms claude-opus-4-6 to claude-opus-4.6", () => {
|
|
|
|
|
// #given github-copilot provider and claude-opus-4-6 model
|
|
|
|
|
const provider = "github-copilot"
|
|
|
|
|
const model = "claude-opus-4-6"
|
|
|
|
|
|
|
|
|
|
// #when transformModelForProvider is called
|
|
|
|
|
const result = transformModelForProvider(provider, model)
|
|
|
|
|
|
|
|
|
|
// #then should transform to claude-opus-4.6
|
|
|
|
|
expect(result).toBe("claude-opus-4.6")
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test("transforms claude-sonnet-4-5 to claude-sonnet-4.5", () => {
|
|
|
|
|
// #given github-copilot provider and claude-sonnet-4-5 model
|
|
|
|
|
const provider = "github-copilot"
|
|
|
|
|
const model = "claude-sonnet-4-5"
|
|
|
|
|
|
|
|
|
|
// #when transformModelForProvider is called
|
|
|
|
|
const result = transformModelForProvider(provider, model)
|
|
|
|
|
|
|
|
|
|
// #then should transform to claude-sonnet-4.5
|
|
|
|
|
expect(result).toBe("claude-sonnet-4.5")
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test("transforms claude-haiku-4-5 to claude-haiku-4.5", () => {
|
|
|
|
|
// #given github-copilot provider and claude-haiku-4-5 model
|
|
|
|
|
const provider = "github-copilot"
|
|
|
|
|
const model = "claude-haiku-4-5"
|
|
|
|
|
|
|
|
|
|
// #when transformModelForProvider is called
|
|
|
|
|
const result = transformModelForProvider(provider, model)
|
|
|
|
|
|
|
|
|
|
// #then should transform to claude-haiku-4.5
|
|
|
|
|
expect(result).toBe("claude-haiku-4.5")
|
|
|
|
|
})
|
|
|
|
|
|
2026-02-26 21:01:05 +09:00
|
|
|
test("transforms gemini-3.1-pro to gemini-3.1-pro-preview", () => {
|
|
|
|
|
// #given github-copilot provider and gemini-3.1-pro model
|
2026-02-17 21:15:38 +09:00
|
|
|
const provider = "github-copilot"
|
2026-02-26 21:01:05 +09:00
|
|
|
const model = "gemini-3.1-pro"
|
2026-02-17 21:15:38 +09:00
|
|
|
|
|
|
|
|
// #when transformModelForProvider is called
|
|
|
|
|
const result = transformModelForProvider(provider, model)
|
|
|
|
|
|
2026-02-26 21:01:05 +09:00
|
|
|
// #then should transform to gemini-3.1-pro-preview
|
|
|
|
|
expect(result).toBe("gemini-3.1-pro-preview")
|
2026-02-17 21:15:38 +09:00
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test("transforms gemini-3-flash to gemini-3-flash-preview", () => {
|
|
|
|
|
// #given github-copilot provider and gemini-3-flash model
|
|
|
|
|
const provider = "github-copilot"
|
|
|
|
|
const model = "gemini-3-flash"
|
|
|
|
|
|
|
|
|
|
// #when transformModelForProvider is called
|
|
|
|
|
const result = transformModelForProvider(provider, model)
|
|
|
|
|
|
|
|
|
|
// #then should transform to gemini-3-flash-preview
|
|
|
|
|
expect(result).toBe("gemini-3-flash-preview")
|
|
|
|
|
})
|
2026-02-17 22:18:56 +09:00
|
|
|
|
2026-02-26 21:01:05 +09:00
|
|
|
test("prevents double transformation of gemini-3.1-pro-preview", () => {
|
|
|
|
|
// #given github-copilot provider and gemini-3.1-pro-preview model (already transformed)
|
2026-02-17 22:18:56 +09:00
|
|
|
const provider = "github-copilot"
|
2026-02-26 21:01:05 +09:00
|
|
|
const model = "gemini-3.1-pro-preview"
|
2026-02-17 22:18:56 +09:00
|
|
|
|
|
|
|
|
// #when transformModelForProvider is called
|
|
|
|
|
const result = transformModelForProvider(provider, model)
|
|
|
|
|
|
2026-02-26 21:01:05 +09:00
|
|
|
// #then should NOT become gemini-3.1-pro-preview-preview
|
|
|
|
|
expect(result).toBe("gemini-3.1-pro-preview")
|
2026-02-17 22:18:56 +09:00
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test("prevents double transformation of gemini-3-flash-preview", () => {
|
|
|
|
|
// #given github-copilot provider and gemini-3-flash-preview model (already transformed)
|
|
|
|
|
const provider = "github-copilot"
|
|
|
|
|
const model = "gemini-3-flash-preview"
|
|
|
|
|
|
|
|
|
|
// #when transformModelForProvider is called
|
|
|
|
|
const result = transformModelForProvider(provider, model)
|
|
|
|
|
|
|
|
|
|
// #then should NOT become gemini-3-flash-preview-preview
|
|
|
|
|
expect(result).toBe("gemini-3-flash-preview")
|
|
|
|
|
})
|
2026-02-17 21:15:38 +09:00
|
|
|
})
|
|
|
|
|
|
|
|
|
|
describe("google provider", () => {
|
|
|
|
|
test("transforms gemini-3-flash to gemini-3-flash-preview", () => {
|
|
|
|
|
// #given google provider and gemini-3-flash model
|
|
|
|
|
const provider = "google"
|
|
|
|
|
const model = "gemini-3-flash"
|
|
|
|
|
|
|
|
|
|
// #when transformModelForProvider is called
|
|
|
|
|
const result = transformModelForProvider(provider, model)
|
|
|
|
|
|
|
|
|
|
// #then should transform to gemini-3-flash-preview
|
|
|
|
|
expect(result).toBe("gemini-3-flash-preview")
|
|
|
|
|
})
|
|
|
|
|
|
2026-02-26 21:01:05 +09:00
|
|
|
test("transforms gemini-3.1-pro to gemini-3.1-pro-preview", () => {
|
|
|
|
|
// #given google provider and gemini-3.1-pro model
|
2026-02-17 21:15:38 +09:00
|
|
|
const provider = "google"
|
2026-02-26 21:01:05 +09:00
|
|
|
const model = "gemini-3.1-pro"
|
2026-02-17 21:15:38 +09:00
|
|
|
|
|
|
|
|
// #when transformModelForProvider is called
|
|
|
|
|
const result = transformModelForProvider(provider, model)
|
|
|
|
|
|
2026-02-26 21:01:05 +09:00
|
|
|
// #then should transform to gemini-3.1-pro-preview
|
|
|
|
|
expect(result).toBe("gemini-3.1-pro-preview")
|
2026-02-17 21:15:38 +09:00
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test("passes through other gemini models unchanged", () => {
|
|
|
|
|
// #given google provider and gemini-2.5-flash model
|
|
|
|
|
const provider = "google"
|
|
|
|
|
const model = "gemini-2.5-flash"
|
|
|
|
|
|
|
|
|
|
// #when transformModelForProvider is called
|
|
|
|
|
const result = transformModelForProvider(provider, model)
|
|
|
|
|
|
|
|
|
|
// #then should pass through unchanged
|
|
|
|
|
expect(result).toBe("gemini-2.5-flash")
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test("prevents double transformation of gemini-3-flash-preview", () => {
|
|
|
|
|
// #given google provider and gemini-3-flash-preview model (already transformed)
|
|
|
|
|
const provider = "google"
|
|
|
|
|
const model = "gemini-3-flash-preview"
|
|
|
|
|
|
|
|
|
|
// #when transformModelForProvider is called
|
|
|
|
|
const result = transformModelForProvider(provider, model)
|
|
|
|
|
|
|
|
|
|
// #then should NOT become gemini-3-flash-preview-preview
|
|
|
|
|
expect(result).toBe("gemini-3-flash-preview")
|
|
|
|
|
})
|
|
|
|
|
|
2026-02-26 21:01:05 +09:00
|
|
|
test("prevents double transformation of gemini-3.1-pro-preview", () => {
|
|
|
|
|
// #given google provider and gemini-3.1-pro-preview model (already transformed)
|
2026-02-17 21:15:38 +09:00
|
|
|
const provider = "google"
|
2026-02-26 21:01:05 +09:00
|
|
|
const model = "gemini-3.1-pro-preview"
|
2026-02-17 21:15:38 +09:00
|
|
|
|
|
|
|
|
// #when transformModelForProvider is called
|
|
|
|
|
const result = transformModelForProvider(provider, model)
|
|
|
|
|
|
2026-02-26 21:01:05 +09:00
|
|
|
// #then should NOT become gemini-3.1-pro-preview-preview
|
|
|
|
|
expect(result).toBe("gemini-3.1-pro-preview")
|
2026-02-17 21:15:38 +09:00
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test("does not transform claude models for google provider", () => {
|
|
|
|
|
// #given google provider and claude-opus-4-6 model
|
|
|
|
|
const provider = "google"
|
|
|
|
|
const model = "claude-opus-4-6"
|
|
|
|
|
|
|
|
|
|
// #when transformModelForProvider is called
|
|
|
|
|
const result = transformModelForProvider(provider, model)
|
|
|
|
|
|
|
|
|
|
// #then should pass through unchanged (google doesn't use claude)
|
|
|
|
|
expect(result).toBe("claude-opus-4-6")
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
2026-04-12 02:28:27 +09:00
|
|
|
describe("anthropic provider", () => {
|
|
|
|
|
test("transforms claude-opus-4-6 to claude-opus-4.6", () => {
|
|
|
|
|
// #given anthropic provider and claude-opus-4-6 model
|
|
|
|
|
const provider = "anthropic"
|
|
|
|
|
const model = "claude-opus-4-6"
|
|
|
|
|
|
|
|
|
|
// #when transformModelForProvider is called
|
|
|
|
|
const result = transformModelForProvider(provider, model)
|
|
|
|
|
|
|
|
|
|
// #then should transform to claude-opus-4.6
|
|
|
|
|
expect(result).toBe("claude-opus-4.6")
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test("transforms claude-sonnet-4-6 to claude-sonnet-4.6", () => {
|
|
|
|
|
// #given anthropic provider and claude-sonnet-4-6 model
|
|
|
|
|
const provider = "anthropic"
|
|
|
|
|
const model = "claude-sonnet-4-6"
|
|
|
|
|
|
|
|
|
|
// #when transformModelForProvider is called
|
|
|
|
|
const result = transformModelForProvider(provider, model)
|
|
|
|
|
|
|
|
|
|
// #then should transform to claude-sonnet-4.6
|
|
|
|
|
expect(result).toBe("claude-sonnet-4.6")
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test("transforms claude-haiku-4-5 to claude-haiku-4.5", () => {
|
|
|
|
|
// #given anthropic provider and claude-haiku-4-5 model
|
|
|
|
|
const provider = "anthropic"
|
|
|
|
|
const model = "claude-haiku-4-5"
|
|
|
|
|
|
|
|
|
|
// #when transformModelForProvider is called
|
|
|
|
|
const result = transformModelForProvider(provider, model)
|
|
|
|
|
|
|
|
|
|
// #then should transform to claude-haiku-4.5
|
|
|
|
|
expect(result).toBe("claude-haiku-4.5")
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
2026-04-13 11:23:11 +09:00
|
|
|
describe("vercel provider", () => {
|
|
|
|
|
test("prepends anthropic/ and applies anthropic transform for claude models", () => {
|
|
|
|
|
// #given vercel provider and claude-opus-4-6 model
|
|
|
|
|
// #when transformModelForProvider is called
|
|
|
|
|
const result = transformModelForProvider("vercel", "claude-opus-4-6")
|
|
|
|
|
|
|
|
|
|
// #then should produce anthropic/claude-opus-4.6
|
|
|
|
|
expect(result).toBe("anthropic/claude-opus-4.6")
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test("prepends anthropic/ and applies anthropic transform for claude-sonnet", () => {
|
|
|
|
|
// #given vercel provider and claude-sonnet-4-6 model
|
|
|
|
|
// #when transformModelForProvider is called
|
|
|
|
|
const result = transformModelForProvider("vercel", "claude-sonnet-4-6")
|
|
|
|
|
|
|
|
|
|
// #then should produce anthropic/claude-sonnet-4.6
|
|
|
|
|
expect(result).toBe("anthropic/claude-sonnet-4.6")
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test("prepends anthropic/ and applies anthropic transform for claude-haiku", () => {
|
|
|
|
|
// #given vercel provider and claude-haiku-4-5 model
|
|
|
|
|
// #when transformModelForProvider is called
|
|
|
|
|
const result = transformModelForProvider("vercel", "claude-haiku-4-5")
|
|
|
|
|
|
|
|
|
|
// #then should produce anthropic/claude-haiku-4.5
|
|
|
|
|
expect(result).toBe("anthropic/claude-haiku-4.5")
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test("prepends openai/ for gpt models", () => {
|
|
|
|
|
// #given vercel provider and gpt-5.4 model
|
|
|
|
|
// #when transformModelForProvider is called
|
|
|
|
|
const result = transformModelForProvider("vercel", "gpt-5.4")
|
|
|
|
|
|
|
|
|
|
// #then should produce openai/gpt-5.4
|
|
|
|
|
expect(result).toBe("openai/gpt-5.4")
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test("prepends google/ and applies google transform for gemini models", () => {
|
|
|
|
|
// #given vercel provider and gemini-3.1-pro model
|
|
|
|
|
// #when transformModelForProvider is called
|
|
|
|
|
const result = transformModelForProvider("vercel", "gemini-3.1-pro")
|
|
|
|
|
|
|
|
|
|
// #then should produce google/gemini-3.1-pro-preview
|
|
|
|
|
expect(result).toBe("google/gemini-3.1-pro-preview")
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test("prepends google/ and applies google transform for gemini-3-flash", () => {
|
|
|
|
|
// #given vercel provider and gemini-3-flash model
|
|
|
|
|
// #when transformModelForProvider is called
|
|
|
|
|
const result = transformModelForProvider("vercel", "gemini-3-flash")
|
|
|
|
|
|
|
|
|
|
// #then should produce google/gemini-3-flash-preview
|
|
|
|
|
expect(result).toBe("google/gemini-3-flash-preview")
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test("prepends xai/ for grok models", () => {
|
|
|
|
|
// #given vercel provider and grok-code-fast-1 model
|
|
|
|
|
// #when transformModelForProvider is called
|
|
|
|
|
const result = transformModelForProvider("vercel", "grok-code-fast-1")
|
|
|
|
|
|
|
|
|
|
// #then should produce xai/grok-code-fast-1
|
|
|
|
|
expect(result).toBe("xai/grok-code-fast-1")
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test("delegates to sub-provider when model already has sub-provider prefix", () => {
|
|
|
|
|
// #given vercel provider and anthropic/claude-opus-4-6 (already prefixed)
|
|
|
|
|
// #when transformModelForProvider is called
|
|
|
|
|
const result = transformModelForProvider("vercel", "anthropic/claude-opus-4-6")
|
|
|
|
|
|
|
|
|
|
// #then should apply anthropic transform within the prefix
|
|
|
|
|
expect(result).toBe("anthropic/claude-opus-4.6")
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test("passes through unknown models without sub-provider prefix", () => {
|
|
|
|
|
// #given vercel provider and an unknown model name
|
|
|
|
|
// #when transformModelForProvider is called
|
|
|
|
|
const result = transformModelForProvider("vercel", "big-pickle")
|
|
|
|
|
|
|
|
|
|
// #then should pass through unchanged
|
|
|
|
|
expect(result).toBe("big-pickle")
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
2026-02-17 21:15:38 +09:00
|
|
|
describe("unknown provider", () => {
|
|
|
|
|
test("passes model through unchanged for unknown provider", () => {
|
|
|
|
|
// #given unknown provider and any model
|
|
|
|
|
const provider = "unknown-provider"
|
|
|
|
|
const model = "some-model"
|
|
|
|
|
|
|
|
|
|
// #when transformModelForProvider is called
|
|
|
|
|
const result = transformModelForProvider(provider, model)
|
|
|
|
|
|
|
|
|
|
// #then should pass through unchanged
|
|
|
|
|
expect(result).toBe("some-model")
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test("passes gemini-3-flash through unchanged for unknown provider", () => {
|
|
|
|
|
// #given unknown provider and gemini-3-flash model
|
|
|
|
|
const provider = "unknown-provider"
|
|
|
|
|
const model = "gemini-3-flash"
|
|
|
|
|
|
|
|
|
|
// #when transformModelForProvider is called
|
|
|
|
|
const result = transformModelForProvider(provider, model)
|
|
|
|
|
|
|
|
|
|
// #then should pass through unchanged (no transformation for unknown provider)
|
|
|
|
|
expect(result).toBe("gemini-3-flash")
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
})
|