refactor(models): bump claude-opus-4-6 to claude-opus-4-7 across fallback chains, categories, and hooks
Updates the canonical Anthropic Opus model in every fallback chain (sisyphus, oracle, prometheus, metis, momus, visual-engineering, ultrabrain, deep, artistry, unspecified-high), the unspecified-high category default, the think-mode HIGH_VARIANT_MAP, the Claude Code alias map, the claude-thinking legacy alias, the context-limit GA regex, and event.ts fallback strings. Widens supportsCachedAnthropicLimit to accept both claude-*-4-6 and claude-*-4-7 so the 1M context cache still applies across the bump. Regenerates the bundled model-capabilities snapshot from models.dev and the model-fallback snapshot to match the new source output.
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -46,7 +46,7 @@ Model Providers (Priority: Native > Copilot > OpenCode Zen > Z.ai > Kimi > Verce
|
||||
OpenAI Native openai/ models (GPT-5.4 for Oracle)
|
||||
Gemini Native google/ models (Gemini 3.1 Pro, Flash)
|
||||
Copilot github-copilot/ models (fallback)
|
||||
OpenCode Zen opencode/ models (opencode/claude-opus-4-6, etc.)
|
||||
OpenCode Zen opencode/ models (opencode/claude-opus-4-7, etc.)
|
||||
Z.ai zai-coding-plan/glm-5 (visual-engineering fallback)
|
||||
Kimi kimi-for-coding/k2p5 (Sisyphus/Prometheus fallback)
|
||||
Vercel vercel/ models (universal proxy, always last fallback)
|
||||
|
||||
@@ -26,8 +26,8 @@ describe("generateOmoConfig - model fallback system", () => {
|
||||
|
||||
//#then
|
||||
expect([
|
||||
"github-copilot/claude-opus-4.6",
|
||||
"github-copilot/claude-opus-4-6",
|
||||
"github-copilot/claude-opus-4.7",
|
||||
"github-copilot/claude-opus-4-7",
|
||||
]).toContain((result.agents as Record<string, { model: string }>).sisyphus.model)
|
||||
})
|
||||
|
||||
@@ -74,7 +74,7 @@ describe("generateOmoConfig - model fallback system", () => {
|
||||
|
||||
//#then
|
||||
expect((result.agents as Record<string, { model: string }>).librarian.model).toBe("zai-coding-plan/glm-4.7")
|
||||
expect((result.agents as Record<string, { model: string }>).sisyphus.model).toBe("anthropic/claude-opus-4-6")
|
||||
expect((result.agents as Record<string, { model: string }>).sisyphus.model).toBe("anthropic/claude-opus-4-7")
|
||||
})
|
||||
|
||||
test("uses native OpenAI models when only ChatGPT available", () => {
|
||||
@@ -131,7 +131,7 @@ describe("generateOmoConfig - model fallback system", () => {
|
||||
}>
|
||||
|
||||
//#then
|
||||
expect(agents.sisyphus.model).toBe("anthropic/claude-opus-4-6")
|
||||
expect(agents.sisyphus.model).toBe("anthropic/claude-opus-4-7")
|
||||
expect(agents.sisyphus.fallback_models).toEqual([
|
||||
{
|
||||
model: "openai/gpt-5.4",
|
||||
@@ -141,7 +141,7 @@ describe("generateOmoConfig - model fallback system", () => {
|
||||
expect(categories.deep.model).toBe("openai/gpt-5.4")
|
||||
expect(categories.deep.fallback_models).toEqual([
|
||||
{
|
||||
model: "anthropic/claude-opus-4-6",
|
||||
model: "anthropic/claude-opus-4-7",
|
||||
variant: "max",
|
||||
},
|
||||
])
|
||||
|
||||
@@ -34,7 +34,7 @@ describe("loadAvailableModelsFromCache", () => {
|
||||
join(tempDir, "cache", "opencode", "models.json"),
|
||||
JSON.stringify({
|
||||
openai: { models: { "gpt-5.4": {} } },
|
||||
anthropic: { models: { "claude-opus-4-6": {}, "claude-sonnet-4-6": {} } },
|
||||
anthropic: { models: { "claude-opus-4-7": {}, "claude-sonnet-4-6": {} } },
|
||||
})
|
||||
)
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ describe("model-resolution check", () => {
|
||||
// then: Should have agent entries
|
||||
const sisyphus = info.agents.find((a) => a.name === "sisyphus")
|
||||
expect(sisyphus).toBeDefined()
|
||||
expect(sisyphus!.requirement.fallbackChain[0]?.model).toBe("claude-opus-4-6")
|
||||
expect(sisyphus!.requirement.fallbackChain[0]?.model).toBe("claude-opus-4-7")
|
||||
expect(sisyphus!.requirement.fallbackChain[0]?.providers).toContain("anthropic")
|
||||
})
|
||||
|
||||
@@ -42,7 +42,7 @@ describe("model-resolution check", () => {
|
||||
// given: User has override for oracle agent
|
||||
const mockConfig = {
|
||||
agents: {
|
||||
oracle: { model: "anthropic/claude-opus-4-6" },
|
||||
oracle: { model: "anthropic/claude-opus-4-7" },
|
||||
},
|
||||
}
|
||||
|
||||
@@ -51,8 +51,8 @@ describe("model-resolution check", () => {
|
||||
// then: Oracle should show the override
|
||||
const oracle = info.agents.find((a) => a.name === "oracle")
|
||||
expect(oracle).toBeDefined()
|
||||
expect(oracle!.userOverride).toBe("anthropic/claude-opus-4-6")
|
||||
expect(oracle!.effectiveResolution).toBe("User override: anthropic/claude-opus-4-6")
|
||||
expect(oracle!.userOverride).toBe("anthropic/claude-opus-4-7")
|
||||
expect(oracle!.effectiveResolution).toBe("User override: anthropic/claude-opus-4-7")
|
||||
})
|
||||
|
||||
it("shows user override for category when configured", async () => {
|
||||
@@ -169,13 +169,13 @@ describe("model-resolution check", () => {
|
||||
|
||||
const info = getModelResolutionInfoWithOverrides({
|
||||
agents: {
|
||||
oracle: { model: "anthropic/claude-opus-4-6-thinking" },
|
||||
oracle: { model: "anthropic/claude-opus-4-7-thinking" },
|
||||
},
|
||||
})
|
||||
|
||||
const oracle = info.agents.find((agent) => agent.name === "oracle")
|
||||
expect(oracle).toBeDefined()
|
||||
expect(oracle!.effectiveModel).toBe("anthropic/claude-opus-4-6-thinking")
|
||||
expect(oracle!.effectiveModel).toBe("anthropic/claude-opus-4-7-thinking")
|
||||
expect(oracle!.capabilityDiagnostics).toMatchObject({
|
||||
resolutionMode: "alias-backed",
|
||||
canonicalization: {
|
||||
|
||||
@@ -381,7 +381,7 @@ describe("generateModelConfig", () => {
|
||||
const result = generateModelConfig(config)
|
||||
|
||||
// #then
|
||||
expect(result.agents?.sisyphus?.model).toBe("anthropic/claude-opus-4-6")
|
||||
expect(result.agents?.sisyphus?.model).toBe("anthropic/claude-opus-4-7")
|
||||
})
|
||||
|
||||
test("Sisyphus is created when multiple fallback providers are available", () => {
|
||||
@@ -398,7 +398,7 @@ describe("generateModelConfig", () => {
|
||||
const result = generateModelConfig(config)
|
||||
|
||||
// #then
|
||||
expect(result.agents?.sisyphus?.model).toBe("anthropic/claude-opus-4-6")
|
||||
expect(result.agents?.sisyphus?.model).toBe("anthropic/claude-opus-4-7")
|
||||
})
|
||||
|
||||
test("Sisyphus resolves to gpt-5.4 medium when only OpenAI is available", () => {
|
||||
@@ -668,7 +668,7 @@ describe("generateModelConfig", () => {
|
||||
const result = generateModelConfig(config)
|
||||
|
||||
// #then should prefer native anthropic over gateway
|
||||
expect(result.agents?.sisyphus?.model).toBe("anthropic/claude-opus-4-6")
|
||||
expect(result.agents?.sisyphus?.model).toBe("anthropic/claude-opus-4-7")
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -5,16 +5,16 @@ import { transformModelForProvider as transformSharedModelForProvider } from "..
|
||||
|
||||
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
|
||||
test("transforms claude-opus-4-7 to claude-opus-4.7", () => {
|
||||
// #given github-copilot provider and claude-opus-4-7 model
|
||||
const provider = "github-copilot"
|
||||
const model = "claude-opus-4-6"
|
||||
const model = "claude-opus-4-7"
|
||||
|
||||
// #when transformModelForProvider is called
|
||||
const result = transformModelForProvider(provider, model)
|
||||
|
||||
// #then should transform to claude-opus-4.6
|
||||
expect(result).toBe("claude-opus-4.6")
|
||||
// #then should transform to claude-opus-4.7
|
||||
expect(result).toBe("claude-opus-4.7")
|
||||
})
|
||||
|
||||
test("transforms claude-sonnet-4-5 to claude-sonnet-4.5", () => {
|
||||
@@ -152,29 +152,29 @@ describe("transformModelForProvider", () => {
|
||||
})
|
||||
|
||||
test("does not transform claude models for google provider", () => {
|
||||
// #given google provider and claude-opus-4-6 model
|
||||
// #given google provider and claude-opus-4-7 model
|
||||
const provider = "google"
|
||||
const model = "claude-opus-4-6"
|
||||
const model = "claude-opus-4-7"
|
||||
|
||||
// #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")
|
||||
expect(result).toBe("claude-opus-4-7")
|
||||
})
|
||||
})
|
||||
|
||||
describe("anthropic provider", () => {
|
||||
test("preserves hyphenated claude-opus-4-6 for config output (regression: installer must not write dotted IDs)", () => {
|
||||
// #given anthropic provider and claude-opus-4-6 model
|
||||
test("preserves hyphenated claude-opus-4-7 for config output (regression: installer must not write dotted IDs)", () => {
|
||||
// #given anthropic provider and claude-opus-4-7 model
|
||||
const provider = "anthropic"
|
||||
const model = "claude-opus-4-6"
|
||||
const model = "claude-opus-4-7"
|
||||
|
||||
// #when transformModelForProvider is called
|
||||
const result = transformModelForProvider(provider, model)
|
||||
|
||||
// #then should keep hyphenated form so Anthropic provider resolution succeeds on fresh installs
|
||||
expect(result).toBe("claude-opus-4-6")
|
||||
expect(result).toBe("claude-opus-4-7")
|
||||
})
|
||||
|
||||
test("preserves hyphenated claude-sonnet-4-6 for config output", () => {
|
||||
@@ -204,12 +204,12 @@ describe("transformModelForProvider", () => {
|
||||
|
||||
describe("vercel provider", () => {
|
||||
test("prepends anthropic/ and applies anthropic transform for claude models", () => {
|
||||
// #given vercel provider and claude-opus-4-6 model
|
||||
// #given vercel provider and claude-opus-4-7 model
|
||||
// #when transformModelForProvider is called
|
||||
const result = transformModelForProvider("vercel", "claude-opus-4-6")
|
||||
const result = transformModelForProvider("vercel", "claude-opus-4-7")
|
||||
|
||||
// #then should produce anthropic/claude-opus-4.6
|
||||
expect(result).toBe("anthropic/claude-opus-4.6")
|
||||
// #then should produce anthropic/claude-opus-4.7
|
||||
expect(result).toBe("anthropic/claude-opus-4.7")
|
||||
})
|
||||
|
||||
test("prepends anthropic/ and applies anthropic transform for claude-sonnet", () => {
|
||||
@@ -267,12 +267,12 @@ describe("transformModelForProvider", () => {
|
||||
})
|
||||
|
||||
test("delegates to sub-provider when model already has sub-provider prefix", () => {
|
||||
// #given vercel provider and anthropic/claude-opus-4-6 (already prefixed)
|
||||
// #given vercel provider and anthropic/claude-opus-4-7 (already prefixed)
|
||||
// #when transformModelForProvider is called
|
||||
const result = transformModelForProvider("vercel", "anthropic/claude-opus-4-6")
|
||||
const result = transformModelForProvider("vercel", "anthropic/claude-opus-4-7")
|
||||
|
||||
// #then should apply anthropic transform within the prefix
|
||||
expect(result).toBe("anthropic/claude-opus-4.6")
|
||||
expect(result).toBe("anthropic/claude-opus-4.7")
|
||||
})
|
||||
|
||||
test("prepends minimax/ for minimax models", () => {
|
||||
@@ -340,14 +340,14 @@ describe("transformModelForProvider", () => {
|
||||
|
||||
test("uses a CLI-local transform implementation distinct from the shared runtime transform", () => {
|
||||
// #given the CLI transform (used by the installer) and the shared runtime transform
|
||||
const cliResult = transformModelForProvider("anthropic", "claude-opus-4-6")
|
||||
const sharedResult = transformSharedModelForProvider("anthropic", "claude-opus-4-6")
|
||||
const cliResult = transformModelForProvider("anthropic", "claude-opus-4-7")
|
||||
const sharedResult = transformSharedModelForProvider("anthropic", "claude-opus-4-7")
|
||||
|
||||
// #when both are called with the same anthropic claude input
|
||||
// #then the CLI preserves hyphenated form for config output,
|
||||
// the shared runtime transform converts dash→dot for API calls
|
||||
expect(transformModelForProvider).not.toBe(transformSharedModelForProvider)
|
||||
expect(cliResult).toBe("claude-opus-4-6")
|
||||
expect(sharedResult).toBe("claude-opus-4.6")
|
||||
expect(cliResult).toBe("claude-opus-4-7")
|
||||
expect(sharedResult).toBe("claude-opus-4.7")
|
||||
})
|
||||
})
|
||||
|
||||
@@ -54,7 +54,7 @@ export function transformModelForProvider(provider: string, model: string): stri
|
||||
}
|
||||
|
||||
if (provider === "anthropic") {
|
||||
// Installer writes hyphenated IDs (claude-opus-4-6) to the config. The
|
||||
// Installer writes hyphenated IDs (claude-opus-4-7) to the config. The
|
||||
// runtime provider-model-id-transform converts dash→dot when calling the
|
||||
// Anthropic API. Keeping the dotted form in the config breaks fresh
|
||||
// installs with ProviderModelNotFoundError because Anthropic's provider
|
||||
|
||||
@@ -49,7 +49,7 @@ describe("refreshModelCapabilities", () => {
|
||||
sourceUrl: "https://override.example/api.json",
|
||||
models: {
|
||||
"gpt-5.4": { id: "gpt-5.4" },
|
||||
"claude-opus-4-6": { id: "claude-opus-4-6" },
|
||||
"claude-opus-4-7": { id: "claude-opus-4-7" },
|
||||
},
|
||||
}))
|
||||
let stdout = ""
|
||||
|
||||
@@ -98,7 +98,7 @@ describe("message.part.delta handling", () => {
|
||||
sessionID: "ses_main",
|
||||
role: "assistant",
|
||||
agent: "Sisyphus - Ultraworker",
|
||||
modelID: "claude-opus-4-6",
|
||||
modelID: "claude-opus-4-7",
|
||||
variant: "max",
|
||||
},
|
||||
},
|
||||
@@ -113,7 +113,7 @@ describe("message.part.delta handling", () => {
|
||||
//#then
|
||||
const rendered = stdoutSpy.mock.calls.map((call) => String(call[0] ?? "")).join("")
|
||||
expect(rendered).toContain("\u001b[38;2;0;206;209m")
|
||||
expect(rendered).toContain("claude-opus-4-6 (max)")
|
||||
expect(rendered).toContain("claude-opus-4-7 (max)")
|
||||
expect(rendered).toContain("└─")
|
||||
expect(rendered).toContain("Sisyphus - Ultraworker")
|
||||
stdoutSpy.mockRestore()
|
||||
@@ -128,7 +128,7 @@ describe("message.part.delta handling", () => {
|
||||
{
|
||||
type: "message.updated",
|
||||
properties: {
|
||||
info: { sessionID: "ses_main", role: "assistant", agent: "Sisyphus - Ultraworker", modelID: "claude-opus-4-6" },
|
||||
info: { sessionID: "ses_main", role: "assistant", agent: "Sisyphus - Ultraworker", modelID: "claude-opus-4-7" },
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -187,7 +187,7 @@ describe("message.part.delta handling", () => {
|
||||
{
|
||||
type: "message.updated",
|
||||
properties: {
|
||||
info: { sessionID: "ses_main", role: "assistant", agent: "Sisyphus - Ultraworker", modelID: "claude-opus-4-6" },
|
||||
info: { sessionID: "ses_main", role: "assistant", agent: "Sisyphus - Ultraworker", modelID: "claude-opus-4-7" },
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -242,7 +242,7 @@ describe("message.part.delta handling", () => {
|
||||
{
|
||||
type: "message.updated",
|
||||
properties: {
|
||||
info: { id: "msg_assistant", sessionID: "ses_main", role: "assistant", agent: "Sisyphus - Ultraworker", modelID: "claude-opus-4-6" },
|
||||
info: { id: "msg_assistant", sessionID: "ses_main", role: "assistant", agent: "Sisyphus - Ultraworker", modelID: "claude-opus-4-7" },
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -309,7 +309,7 @@ describe("message.part.delta handling", () => {
|
||||
{
|
||||
type: "message.updated",
|
||||
properties: {
|
||||
info: { id: "msg_assistant", sessionID: "ses_main", role: "assistant", agent: "Sisyphus - Ultraworker", modelID: "claude-opus-4-6" },
|
||||
info: { id: "msg_assistant", sessionID: "ses_main", role: "assistant", agent: "Sisyphus - Ultraworker", modelID: "claude-opus-4-7" },
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -353,7 +353,7 @@ describe("message.part.delta handling", () => {
|
||||
{
|
||||
type: "message.updated",
|
||||
properties: {
|
||||
info: { id: "msg_assistant", sessionID: "ses_main", role: "assistant", agent: "Sisyphus - Ultraworker", modelID: "claude-opus-4-6", variant: "max" },
|
||||
info: { id: "msg_assistant", sessionID: "ses_main", role: "assistant", agent: "Sisyphus - Ultraworker", modelID: "claude-opus-4-7", variant: "max" },
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -388,7 +388,7 @@ describe("message.part.delta handling", () => {
|
||||
{
|
||||
type: "message.updated",
|
||||
properties: {
|
||||
info: { id: "msg_user", sessionID: "ses_main", role: "user", agent: "Sisyphus - Ultraworker", modelID: "claude-opus-4-6" },
|
||||
info: { id: "msg_user", sessionID: "ses_main", role: "user", agent: "Sisyphus - Ultraworker", modelID: "claude-opus-4-7" },
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -410,7 +410,7 @@ describe("message.part.delta handling", () => {
|
||||
{
|
||||
type: "message.updated",
|
||||
properties: {
|
||||
info: { id: "msg_assistant", sessionID: "ses_main", role: "assistant", agent: "Sisyphus - Ultraworker", modelID: "claude-opus-4-6" },
|
||||
info: { id: "msg_assistant", sessionID: "ses_main", role: "assistant", agent: "Sisyphus - Ultraworker", modelID: "claude-opus-4-7" },
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -619,7 +619,7 @@ describe("message.part.delta handling", () => {
|
||||
{
|
||||
type: "message.updated",
|
||||
properties: {
|
||||
info: { id: "msg_1", sessionID: "ses_main", role: "assistant", agent: "Sisyphus", modelID: "claude-opus-4-6" },
|
||||
info: { id: "msg_1", sessionID: "ses_main", role: "assistant", agent: "Sisyphus", modelID: "claude-opus-4-7" },
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -634,7 +634,7 @@ describe("message.part.delta handling", () => {
|
||||
{
|
||||
type: "message.updated",
|
||||
properties: {
|
||||
info: { id: "msg_1", sessionID: "ses_main", role: "assistant", agent: "Sisyphus", modelID: "claude-opus-4-6" },
|
||||
info: { id: "msg_1", sessionID: "ses_main", role: "assistant", agent: "Sisyphus", modelID: "claude-opus-4-7" },
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -74,7 +74,7 @@ export async function promptInstallConfig(detected: DetectedConfig): Promise<Ins
|
||||
message: "Do you have access to OpenCode Zen (opencode/ models)?",
|
||||
options: [
|
||||
{ value: "no", label: "No", hint: "Will use other configured providers" },
|
||||
{ value: "yes", label: "Yes", hint: "opencode/claude-opus-4-6, opencode/gpt-5.4, etc." },
|
||||
{ value: "yes", label: "Yes", hint: "opencode/claude-opus-4-7, opencode/gpt-5.4, etc." },
|
||||
],
|
||||
initialValue: initial.opencodeZen,
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user