map Claude Code model strings to OpenCode format with proper object structure

This commit is contained in:
YeonGyu-Kim
2026-03-11 17:07:23 +09:00
parent 96b5811dc1
commit c6ea3f4aff
6 changed files with 58 additions and 46 deletions

View File

@@ -1,3 +1,5 @@
/// <reference types="bun-types" />
import { describe, it, expect } from "bun:test"
import { mapClaudeModelToOpenCode } from "./claude-model-mapper"
@@ -17,20 +19,20 @@ describe("mapClaudeModelToOpenCode", () => {
})
describe("#given Claude Code alias", () => {
it("#when called with sonnet #then maps to anthropic/claude-sonnet-4-6", () => {
expect(mapClaudeModelToOpenCode("sonnet")).toBe("anthropic/claude-sonnet-4-6")
it("#when called with sonnet #then maps to anthropic claude-sonnet-4-6 object", () => {
expect(mapClaudeModelToOpenCode("sonnet")).toEqual({ providerID: "anthropic", modelID: "claude-sonnet-4-6" })
})
it("#when called with opus #then maps to anthropic/claude-opus-4-6", () => {
expect(mapClaudeModelToOpenCode("opus")).toBe("anthropic/claude-opus-4-6")
it("#when called with opus #then maps to anthropic claude-opus-4-6 object", () => {
expect(mapClaudeModelToOpenCode("opus")).toEqual({ providerID: "anthropic", modelID: "claude-opus-4-6" })
})
it("#when called with haiku #then maps to anthropic/claude-haiku-4-5", () => {
expect(mapClaudeModelToOpenCode("haiku")).toBe("anthropic/claude-haiku-4-5")
it("#when called with haiku #then maps to anthropic claude-haiku-4-5 object", () => {
expect(mapClaudeModelToOpenCode("haiku")).toEqual({ providerID: "anthropic", modelID: "claude-haiku-4-5" })
})
it("#when called with Sonnet (capitalized) #then maps case-insensitively", () => {
expect(mapClaudeModelToOpenCode("Sonnet")).toBe("anthropic/claude-sonnet-4-6")
it("#when called with Sonnet (capitalized) #then maps case-insensitively to object", () => {
expect(mapClaudeModelToOpenCode("Sonnet")).toEqual({ providerID: "anthropic", modelID: "claude-sonnet-4-6" })
})
})
@@ -41,40 +43,40 @@ describe("mapClaudeModelToOpenCode", () => {
})
describe("#given bare Claude model name", () => {
it("#when called with claude-sonnet-4-5-20250514 #then adds anthropic prefix", () => {
expect(mapClaudeModelToOpenCode("claude-sonnet-4-5-20250514")).toBe("anthropic/claude-sonnet-4-5-20250514")
it("#when called with claude-sonnet-4-5-20250514 #then adds anthropic object format", () => {
expect(mapClaudeModelToOpenCode("claude-sonnet-4-5-20250514")).toEqual({ providerID: "anthropic", modelID: "claude-sonnet-4-5-20250514" })
})
it("#when called with claude-opus-4-6 #then adds anthropic prefix", () => {
expect(mapClaudeModelToOpenCode("claude-opus-4-6")).toBe("anthropic/claude-opus-4-6")
it("#when called with claude-opus-4-6 #then adds anthropic object format", () => {
expect(mapClaudeModelToOpenCode("claude-opus-4-6")).toEqual({ providerID: "anthropic", modelID: "claude-opus-4-6" })
})
it("#when called with claude-haiku-4-5-20251001 #then adds anthropic prefix", () => {
expect(mapClaudeModelToOpenCode("claude-haiku-4-5-20251001")).toBe("anthropic/claude-haiku-4-5-20251001")
it("#when called with claude-haiku-4-5-20251001 #then adds anthropic object format", () => {
expect(mapClaudeModelToOpenCode("claude-haiku-4-5-20251001")).toEqual({ providerID: "anthropic", modelID: "claude-haiku-4-5-20251001" })
})
it("#when called with claude-3-5-sonnet-20241022 #then adds anthropic prefix", () => {
expect(mapClaudeModelToOpenCode("claude-3-5-sonnet-20241022")).toBe("anthropic/claude-3-5-sonnet-20241022")
it("#when called with claude-3-5-sonnet-20241022 #then adds anthropic object format", () => {
expect(mapClaudeModelToOpenCode("claude-3-5-sonnet-20241022")).toEqual({ providerID: "anthropic", modelID: "claude-3-5-sonnet-20241022" })
})
})
describe("#given model with dot version numbers", () => {
it("#when called with claude-3.5-sonnet #then normalizes dots and adds prefix", () => {
expect(mapClaudeModelToOpenCode("claude-3.5-sonnet")).toBe("anthropic/claude-3-5-sonnet")
it("#when called with claude-3.5-sonnet #then normalizes dots and returns object format", () => {
expect(mapClaudeModelToOpenCode("claude-3.5-sonnet")).toEqual({ providerID: "anthropic", modelID: "claude-3-5-sonnet" })
})
it("#when called with claude-3.5-sonnet-20241022 #then normalizes dots and adds prefix", () => {
expect(mapClaudeModelToOpenCode("claude-3.5-sonnet-20241022")).toBe("anthropic/claude-3-5-sonnet-20241022")
it("#when called with claude-3.5-sonnet-20241022 #then normalizes dots and returns object format", () => {
expect(mapClaudeModelToOpenCode("claude-3.5-sonnet-20241022")).toEqual({ providerID: "anthropic", modelID: "claude-3-5-sonnet-20241022" })
})
})
describe("#given model already in provider/model format", () => {
it("#when called with anthropic/claude-sonnet-4-6 #then passes through unchanged", () => {
expect(mapClaudeModelToOpenCode("anthropic/claude-sonnet-4-6")).toBe("anthropic/claude-sonnet-4-6")
it("#when called with anthropic/claude-sonnet-4-6 #then splits into object format", () => {
expect(mapClaudeModelToOpenCode("anthropic/claude-sonnet-4-6")).toEqual({ providerID: "anthropic", modelID: "claude-sonnet-4-6" })
})
it("#when called with openai/gpt-5.2 #then passes through unchanged", () => {
expect(mapClaudeModelToOpenCode("openai/gpt-5.2")).toBe("openai/gpt-5.2")
it("#when called with openai/gpt-5.2 #then splits into object format", () => {
expect(mapClaudeModelToOpenCode("openai/gpt-5.2")).toEqual({ providerID: "openai", modelID: "gpt-5.2" })
})
})
@@ -99,8 +101,8 @@ describe("mapClaudeModelToOpenCode", () => {
})
describe("#given model with leading/trailing whitespace", () => {
it("#when called with padded string #then trims before mapping", () => {
expect(mapClaudeModelToOpenCode(" claude-sonnet-4-6 ")).toBe("anthropic/claude-sonnet-4-6")
it("#when called with padded string #then trims before returning object format", () => {
expect(mapClaudeModelToOpenCode(" claude-sonnet-4-6 ")).toEqual({ providerID: "anthropic", modelID: "claude-sonnet-4-6" })
})
})
})