fix(shared): normalize claude model IDs for anthropic provider (#3290)
Anthropic API accepts claude-opus-4.6 (dot format) but not claude-opus-4-6 (dash format). Added anthropic case to transformModelForProvider to normalize dash-format model IDs before they reach the provider. Updated model config snapshots and test expectations to match the new dot-format output. 🤖 Generated with OhMyOpenCode assistance https://github.com/code-yeongyu/oh-my-opencode
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
declare const require: (name: string) => any
|
||||
const { afterEach, beforeEach, describe, expect, mock, spyOn, test } = require("bun:test")
|
||||
/// <reference types="bun-types" />
|
||||
|
||||
import { afterEach, beforeEach, describe, expect, mock, spyOn, test } from "bun:test"
|
||||
import { resolveModelForDelegateTask } from "./model-selection"
|
||||
import * as connectedProvidersCache from "../../shared/connected-providers-cache"
|
||||
|
||||
@@ -25,12 +26,12 @@ describe("resolveModelForDelegateTask", () => {
|
||||
describe("#when availableModels is empty and no user model override", () => {
|
||||
test("#then returns skipped sentinel to leave model unpinned", () => {
|
||||
const result = resolveModelForDelegateTask({
|
||||
categoryDefaultModel: "anthropic/claude-sonnet-4-6",
|
||||
categoryDefaultModel: "anthropic/claude-sonnet-4.6",
|
||||
fallbackChain: [
|
||||
{ providers: ["anthropic"], model: "claude-sonnet-4-6" },
|
||||
],
|
||||
availableModels: new Set(),
|
||||
systemDefaultModel: "anthropic/claude-sonnet-4-6",
|
||||
systemDefaultModel: "anthropic/claude-sonnet-4.6",
|
||||
})
|
||||
|
||||
expect(result).toEqual({ skipped: true })
|
||||
@@ -41,12 +42,12 @@ describe("resolveModelForDelegateTask", () => {
|
||||
test("#then returns the user model regardless of cache state", () => {
|
||||
const result = resolveModelForDelegateTask({
|
||||
userModel: "openai/gpt-5.4",
|
||||
categoryDefaultModel: "anthropic/claude-sonnet-4-6",
|
||||
categoryDefaultModel: "anthropic/claude-sonnet-4.6",
|
||||
fallbackChain: [
|
||||
{ providers: ["anthropic"], model: "claude-sonnet-4-6" },
|
||||
],
|
||||
availableModels: new Set(),
|
||||
systemDefaultModel: "anthropic/claude-sonnet-4-6",
|
||||
systemDefaultModel: "anthropic/claude-sonnet-4.6",
|
||||
})
|
||||
|
||||
expect(result).toEqual({ model: "openai/gpt-5.4" })
|
||||
@@ -57,7 +58,7 @@ describe("resolveModelForDelegateTask", () => {
|
||||
test("#then returns skipped sentinel (skip fallback resolution without cache)", () => {
|
||||
const result = resolveModelForDelegateTask({
|
||||
userFallbackModels: ["openai/gpt-5.4", "google/gemini-3.1-pro"],
|
||||
categoryDefaultModel: "anthropic/claude-sonnet-4-6",
|
||||
categoryDefaultModel: "anthropic/claude-sonnet-4.6",
|
||||
fallbackChain: [
|
||||
{ providers: ["anthropic"], model: "claude-sonnet-4-6" },
|
||||
],
|
||||
@@ -80,15 +81,15 @@ describe("resolveModelForDelegateTask", () => {
|
||||
const readConnectedProvidersSpy = spyOn(connectedProvidersCache, "readConnectedProvidersCache").mockReturnValue(["anthropic"])
|
||||
|
||||
const result = resolveModelForDelegateTask({
|
||||
categoryDefaultModel: "anthropic/claude-sonnet-4-6",
|
||||
categoryDefaultModel: "anthropic/claude-sonnet-4.6",
|
||||
fallbackChain: [
|
||||
{ providers: ["anthropic"], model: "claude-sonnet-4-6" },
|
||||
],
|
||||
availableModels: new Set(),
|
||||
systemDefaultModel: "anthropic/claude-sonnet-4-6",
|
||||
systemDefaultModel: "anthropic/claude-sonnet-4.6",
|
||||
})
|
||||
|
||||
expect(result).toEqual({ model: "anthropic/claude-sonnet-4-6" })
|
||||
expect(result).toEqual({ model: "anthropic/claude-sonnet-4.6" })
|
||||
readConnectedProvidersSpy.mockRestore()
|
||||
})
|
||||
|
||||
@@ -96,12 +97,12 @@ describe("resolveModelForDelegateTask", () => {
|
||||
const readConnectedProvidersSpy = spyOn(connectedProvidersCache, "readConnectedProvidersCache").mockReturnValue(["openai"])
|
||||
|
||||
const result = resolveModelForDelegateTask({
|
||||
categoryDefaultModel: "anthropic/claude-sonnet-4-6",
|
||||
categoryDefaultModel: "anthropic/claude-sonnet-4.6",
|
||||
fallbackChain: [
|
||||
{ providers: ["openai"], model: "gpt-5.4", variant: "high" },
|
||||
],
|
||||
availableModels: new Set(),
|
||||
systemDefaultModel: "anthropic/claude-sonnet-4-6",
|
||||
systemDefaultModel: "anthropic/claude-sonnet-4.6",
|
||||
})
|
||||
|
||||
expect(result).toEqual({
|
||||
@@ -117,7 +118,7 @@ describe("resolveModelForDelegateTask", () => {
|
||||
const readConnectedProvidersSpy = spyOn(connectedProvidersCache, "readConnectedProvidersCache").mockReturnValue(["openai"])
|
||||
|
||||
const result = resolveModelForDelegateTask({
|
||||
userFallbackModels: ["anthropic/claude-sonnet-4-6", "openai/gpt-5.4"],
|
||||
userFallbackModels: ["anthropic/claude-sonnet-4.6", "openai/gpt-5.4"],
|
||||
availableModels: new Set(),
|
||||
})
|
||||
|
||||
@@ -129,14 +130,14 @@ describe("resolveModelForDelegateTask", () => {
|
||||
describe("#when availableModels has entries and category default matches", () => {
|
||||
test("#then resolves via fuzzy match (existing behavior)", () => {
|
||||
const result = resolveModelForDelegateTask({
|
||||
categoryDefaultModel: "anthropic/claude-sonnet-4-6",
|
||||
categoryDefaultModel: "anthropic/claude-sonnet-4.6",
|
||||
fallbackChain: [
|
||||
{ providers: ["anthropic"], model: "claude-sonnet-4-6" },
|
||||
],
|
||||
availableModels: new Set(["anthropic/claude-sonnet-4-6"]),
|
||||
availableModels: new Set(["anthropic/claude-sonnet-4.6"]),
|
||||
})
|
||||
|
||||
expect(result).toEqual({ model: "anthropic/claude-sonnet-4-6" })
|
||||
expect(result).toEqual({ model: "anthropic/claude-sonnet-4.6" })
|
||||
})
|
||||
|
||||
test("#then trusts user-configured category model without fuzzy validation", () => {
|
||||
@@ -200,7 +201,7 @@ describe("resolveModelForDelegateTask", () => {
|
||||
expect(result).toBeDefined()
|
||||
expect(result).not.toHaveProperty("skipped")
|
||||
const resolved = result as { model: string; variant?: string }
|
||||
expect(resolved.model).toBe("anthropic/claude-haiku-4-5")
|
||||
expect(resolved.model).toBe("anthropic/claude-haiku-4.5")
|
||||
})
|
||||
|
||||
test("#then resolves first provider in entry that is connected", () => {
|
||||
@@ -229,10 +230,10 @@ describe("resolveModelForDelegateTask", () => {
|
||||
{ providers: ["opencode-go"], model: "minimax-m2.7" },
|
||||
],
|
||||
availableModels: new Set(),
|
||||
systemDefaultModel: "anthropic/claude-sonnet-4-6",
|
||||
systemDefaultModel: "anthropic/claude-sonnet-4.6",
|
||||
})
|
||||
|
||||
expect(result).toEqual({ model: "anthropic/claude-sonnet-4-6" })
|
||||
expect(result).toEqual({ model: "anthropic/claude-sonnet-4.6" })
|
||||
})
|
||||
})
|
||||
|
||||
@@ -259,7 +260,7 @@ describe("resolveModelForDelegateTask", () => {
|
||||
test("#then extracts the variant and returns the base model separately", () => {
|
||||
const result = resolveModelForDelegateTask({
|
||||
userModel: "openai/gpt-5.4 high",
|
||||
categoryDefaultModel: "anthropic/claude-sonnet-4-6",
|
||||
categoryDefaultModel: "anthropic/claude-sonnet-4.6",
|
||||
fallbackChain: [
|
||||
{ providers: ["anthropic"], model: "claude-sonnet-4-6" },
|
||||
],
|
||||
@@ -274,7 +275,7 @@ describe("resolveModelForDelegateTask", () => {
|
||||
test("#then extracts the variant and returns the base model separately", () => {
|
||||
const result = resolveModelForDelegateTask({
|
||||
userModel: "openai/gpt-5.4(max)",
|
||||
categoryDefaultModel: "anthropic/claude-sonnet-4-6",
|
||||
categoryDefaultModel: "anthropic/claude-sonnet-4.6",
|
||||
availableModels: new Set(),
|
||||
})
|
||||
|
||||
@@ -359,7 +360,7 @@ describe("resolveModelForDelegateTask", () => {
|
||||
const readConnectedProvidersSpy = spyOn(connectedProvidersCache, "readConnectedProvidersCache").mockReturnValue(["openai"])
|
||||
|
||||
const result = resolveModelForDelegateTask({
|
||||
categoryDefaultModel: "anthropic/claude-sonnet-4-6",
|
||||
categoryDefaultModel: "anthropic/claude-sonnet-4.6",
|
||||
fallbackChain: [
|
||||
{ providers: ["openai"], model: "gpt-5.4" },
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user