refactor(migration): auto-upgrade claude-opus-4-5 and 4-6 to claude-opus-4-7

MODEL_VERSION_MAP now chains the legacy claude-opus-4-5 entry straight
to claude-opus-4-7 and adds an explicit claude-opus-4-6 to 4-7 bump
path, letting existing user configs upgrade on next load without an
intermediate 4-6 stop.

MODEL_TO_CATEGORY_MAP picks up claude-opus-4-7 as the canonical
unspecified-high model (prior 4-6 entry is covered by the chained
version map above, so legacy hardcoded configs still resolve).

Migration tests rewritten to reflect the chained 4-5 to 4-7 behavior
and the new 4-6 to 4-7 bump path, including the sidecar-union
scenario.
This commit is contained in:
YeonGyu-Kim
2026-04-17 14:52:02 +09:00
parent def44338ff
commit 4ca4c06698
6 changed files with 40 additions and 39 deletions
+27 -27
View File
@@ -19,7 +19,7 @@ describe("migrateAgentNames", () => {
test("migrates legacy OmO names to lowercase", () => { test("migrates legacy OmO names to lowercase", () => {
// given: Config with legacy OmO agent names // given: Config with legacy OmO agent names
const agents = { const agents = {
omo: { model: "anthropic/claude-opus-4-6" }, omo: { model: "anthropic/claude-opus-4-7" },
OmO: { temperature: 0.5 }, OmO: { temperature: 0.5 },
"OmO-Plan": { prompt: "custom prompt" }, "OmO-Plan": { prompt: "custom prompt" },
} }
@@ -88,7 +88,7 @@ describe("migrateAgentNames", () => {
test("migrates orchestrator-sisyphus to atlas", () => { test("migrates orchestrator-sisyphus to atlas", () => {
// given: Config with legacy orchestrator-sisyphus agent name // given: Config with legacy orchestrator-sisyphus agent name
const agents = { const agents = {
"orchestrator-sisyphus": { model: "anthropic/claude-opus-4-6" }, "orchestrator-sisyphus": { model: "anthropic/claude-opus-4-7" },
} }
// when: Migrate agent names // when: Migrate agent names
@@ -96,14 +96,14 @@ describe("migrateAgentNames", () => {
// then: orchestrator-sisyphus should be migrated to atlas // then: orchestrator-sisyphus should be migrated to atlas
expect(changed).toBe(true) expect(changed).toBe(true)
expect(migrated["atlas"]).toEqual({ model: "anthropic/claude-opus-4-6" }) expect(migrated["atlas"]).toEqual({ model: "anthropic/claude-opus-4-7" })
expect(migrated["orchestrator-sisyphus"]).toBeUndefined() expect(migrated["orchestrator-sisyphus"]).toBeUndefined()
}) })
test("migrates lowercase atlas to atlas", () => { test("migrates lowercase atlas to atlas", () => {
// given: Config with lowercase atlas agent name // given: Config with lowercase atlas agent name
const agents = { const agents = {
atlas: { model: "anthropic/claude-opus-4-6" }, atlas: { model: "anthropic/claude-opus-4-7" },
} }
// when: Migrate agent names // when: Migrate agent names
@@ -111,7 +111,7 @@ describe("migrateAgentNames", () => {
// then: lowercase atlas should remain atlas (no change needed) // then: lowercase atlas should remain atlas (no change needed)
expect(changed).toBe(false) expect(changed).toBe(false)
expect(migrated["atlas"]).toEqual({ model: "anthropic/claude-opus-4-6" }) expect(migrated["atlas"]).toEqual({ model: "anthropic/claude-opus-4-7" })
}) })
test("migrates Sisyphus variants to lowercase", () => { test("migrates Sisyphus variants to lowercase", () => {
@@ -524,7 +524,7 @@ describe("migrateConfigFile", () => {
// then: Model version should be migrated // then: Model version should be migrated
expect(needsWrite).toBe(true) expect(needsWrite).toBe(true)
const categories = rawConfig.categories as Record<string, Record<string, unknown>> const categories = rawConfig.categories as Record<string, Record<string, unknown>>
expect(categories["my-category"].model).toBe("anthropic/claude-opus-4-6") expect(categories["my-category"].model).toBe("anthropic/claude-opus-4-7")
}) })
test("does not set needsWrite when no model versions need migration", () => { test("does not set needsWrite when no model versions need migration", () => {
@@ -534,7 +534,7 @@ describe("migrateConfigFile", () => {
sisyphus: { model: "openai/gpt-5.4-codex" }, sisyphus: { model: "openai/gpt-5.4-codex" },
}, },
categories: { categories: {
"my-category": { model: "anthropic/claude-opus-4-6" }, "my-category": { model: "anthropic/claude-opus-4-7" },
}, },
} }
@@ -572,10 +572,10 @@ describe("MODEL_VERSION_MAP", () => {
expect(MODEL_VERSION_MAP["openai/gpt-5.4-codex"]).toBeUndefined() expect(MODEL_VERSION_MAP["openai/gpt-5.4-codex"]).toBeUndefined()
}) })
test("maps anthropic/claude-opus-4-5 to anthropic/claude-opus-4-6", () => { test("maps anthropic/claude-opus-4-5 to anthropic/claude-opus-4-7", () => {
// given/when: Check MODEL_VERSION_MAP // given/when: Check MODEL_VERSION_MAP
// then: Should contain correct mapping // then: Should contain correct mapping
expect(MODEL_VERSION_MAP["anthropic/claude-opus-4-5"]).toBe("anthropic/claude-opus-4-6") expect(MODEL_VERSION_MAP["anthropic/claude-opus-4-5"]).toBe("anthropic/claude-opus-4-7")
}) })
test("maps openai/gpt-5.3-codex to openai/gpt-5.4 for deep category migration", () => { test("maps openai/gpt-5.3-codex to openai/gpt-5.4 for deep category migration", () => {
@@ -614,7 +614,7 @@ describe("migrateModelVersions", () => {
// then: Model should be updated // then: Model should be updated
expect(changed).toBe(true) expect(changed).toBe(true)
const prometheus = migrated["prometheus"] as Record<string, unknown> const prometheus = migrated["prometheus"] as Record<string, unknown>
expect(prometheus.model).toBe("anthropic/claude-opus-4-6") expect(prometheus.model).toBe("anthropic/claude-opus-4-7")
}) })
test("leaves unknown model strings untouched", () => { test("leaves unknown model strings untouched", () => {
@@ -674,7 +674,7 @@ describe("migrateModelVersions", () => {
// then: Only mapped models should be updated // then: Only mapped models should be updated
expect(changed).toBe(true) expect(changed).toBe(true)
expect((migrated["sisyphus"] as Record<string, unknown>).model).toBe("openai/gpt-5.4-codex") expect((migrated["sisyphus"] as Record<string, unknown>).model).toBe("openai/gpt-5.4-codex")
expect((migrated["prometheus"] as Record<string, unknown>).model).toBe("anthropic/claude-opus-4-6") expect((migrated["prometheus"] as Record<string, unknown>).model).toBe("anthropic/claude-opus-4-7")
expect((migrated["oracle"] as Record<string, unknown>).model).toBe("openai/gpt-5.4") expect((migrated["oracle"] as Record<string, unknown>).model).toBe("openai/gpt-5.4")
}) })
@@ -736,9 +736,9 @@ describe("migrateModelVersions", () => {
// then: Only prometheus should be migrated // then: Only prometheus should be migrated
expect(changed).toBe(true) expect(changed).toBe(true)
expect(newMigrations).toEqual(["model-version:anthropic/claude-opus-4-5->anthropic/claude-opus-4-6"]) expect(newMigrations).toEqual(["model-version:anthropic/claude-opus-4-5->anthropic/claude-opus-4-7"])
expect((migrated["sisyphus"] as Record<string, unknown>).model).toBe("openai/gpt-5.4-codex") expect((migrated["sisyphus"] as Record<string, unknown>).model).toBe("openai/gpt-5.4-codex")
expect((migrated["prometheus"] as Record<string, unknown>).model).toBe("anthropic/claude-opus-4-6") expect((migrated["prometheus"] as Record<string, unknown>).model).toBe("anthropic/claude-opus-4-7")
}) })
test("backward compatible without appliedMigrations param", () => { test("backward compatible without appliedMigrations param", () => {
@@ -820,12 +820,12 @@ describe("migrateConfigFile _migrations tracking", () => {
// (legacy + new) is written to the sidecar file exactly once. // (legacy + new) is written to the sidecar file exactly once.
expect(result).toBe(true) expect(result).toBe(true)
expect(rawConfig._migrations).toBeUndefined() expect(rawConfig._migrations).toBeUndefined()
expect((rawConfig.agents as Record<string, Record<string, unknown>>).prometheus.model).toBe("anthropic/claude-opus-4-6") expect((rawConfig.agents as Record<string, Record<string, unknown>>).prometheus.model).toBe("anthropic/claude-opus-4-7")
const sidecar = JSON.parse(fs.readFileSync(`${configPath}.migrations.json`, "utf-8")) const sidecar = JSON.parse(fs.readFileSync(`${configPath}.migrations.json`, "utf-8"))
expect(new Set(sidecar.appliedMigrations)).toEqual(new Set([ expect(new Set(sidecar.appliedMigrations)).toEqual(new Set([
"model-version:openai/gpt-5.4-codex->openai/gpt-5.3-codex", "model-version:openai/gpt-5.4-codex->openai/gpt-5.3-codex",
"model-version:anthropic/claude-opus-4-5->anthropic/claude-opus-4-6", "model-version:anthropic/claude-opus-4-5->anthropic/claude-opus-4-7",
])) ]))
// cleanup // cleanup
@@ -890,7 +890,7 @@ describe("migrateAgentConfigToCategory", () => {
{ model: "google/gemini-3-flash" }, { model: "google/gemini-3-flash" },
{ model: "openai/gpt-5.4" }, { model: "openai/gpt-5.4" },
{ model: "anthropic/claude-haiku-4-5" }, { model: "anthropic/claude-haiku-4-5" },
{ model: "anthropic/claude-opus-4-6" }, { model: "anthropic/claude-opus-4-7" },
{ model: "anthropic/claude-sonnet-4-6" }, { model: "anthropic/claude-sonnet-4-6" },
] ]
@@ -970,7 +970,7 @@ describe("shouldDeleteAgentConfig", () => {
// given: Config with custom model override // given: Config with custom model override
const config = { const config = {
category: "visual-engineering", category: "visual-engineering",
model: "anthropic/claude-opus-4-6", model: "anthropic/claude-opus-4-7",
} }
// when: Check if config should be deleted // when: Check if config should be deleted
@@ -1245,9 +1245,9 @@ describe("migrateModelVersions with applied migrations", () => {
// then: Skip sisyphus (already applied), apply oracle // then: Skip sisyphus (already applied), apply oracle
expect(changed).toBe(true) expect(changed).toBe(true)
expect(newMigrations).toEqual(["model-version:anthropic/claude-opus-4-5->anthropic/claude-opus-4-6"]) expect(newMigrations).toEqual(["model-version:anthropic/claude-opus-4-5->anthropic/claude-opus-4-7"])
expect((migrated.sisyphus as Record<string, unknown>).model).toBe("openai/gpt-5.4-codex") expect((migrated.sisyphus as Record<string, unknown>).model).toBe("openai/gpt-5.4-codex")
expect((migrated.oracle as Record<string, unknown>).model).toBe("anthropic/claude-opus-4-6") expect((migrated.oracle as Record<string, unknown>).model).toBe("anthropic/claude-opus-4-7")
}) })
test("backward compatible: no appliedMigrations param", () => { test("backward compatible: no appliedMigrations param", () => {
@@ -1334,12 +1334,12 @@ describe("migrateConfigFile with migration tracking via sidecar (#3263)", () =>
const needsWrite = migrateConfigFile(testConfigPath, rawConfig) const needsWrite = migrateConfigFile(testConfigPath, rawConfig)
expect(needsWrite).toBe(true) expect(needsWrite).toBe(true)
expect((rawConfig.agents as Record<string, Record<string, unknown>>).oracle.model).toBe("anthropic/claude-opus-4-6") expect((rawConfig.agents as Record<string, Record<string, unknown>>).oracle.model).toBe("anthropic/claude-opus-4-7")
expect(rawConfig._migrations).toBeUndefined() expect(rawConfig._migrations).toBeUndefined()
const sidecar = JSON.parse(fs.readFileSync(sidecarPath(testConfigPath), "utf-8")) const sidecar = JSON.parse(fs.readFileSync(sidecarPath(testConfigPath), "utf-8"))
expect(sidecar.appliedMigrations).toEqual([ expect(sidecar.appliedMigrations).toEqual([
"model-version:anthropic/claude-opus-4-5->anthropic/claude-opus-4-6", "model-version:anthropic/claude-opus-4-5->anthropic/claude-opus-4-7",
]) ])
}) })
@@ -1408,7 +1408,7 @@ describe("migrateConfigFile with migration tracking via sidecar (#3263)", () =>
JSON.stringify({ JSON.stringify({
appliedMigrations: [ appliedMigrations: [
"model-version:openai/gpt-5.3-codex->openai/gpt-5.4", "model-version:openai/gpt-5.3-codex->openai/gpt-5.4",
"model-version:anthropic/claude-opus-4-5->anthropic/claude-opus-4-6", "model-version:anthropic/claude-opus-4-5->anthropic/claude-opus-4-7",
], ],
}), }),
) )
@@ -1416,7 +1416,7 @@ describe("migrateConfigFile with migration tracking via sidecar (#3263)", () =>
agents: { agents: {
oracle: { model: "anthropic/claude-opus-4-5" }, oracle: { model: "anthropic/claude-opus-4-5" },
}, },
_migrations: ["model-version:anthropic/claude-opus-4-5->anthropic/claude-opus-4-6"], _migrations: ["model-version:anthropic/claude-opus-4-5->anthropic/claude-opus-4-7"],
} }
fs.writeFileSync(testConfigPath, JSON.stringify(rawConfig, null, 2)) fs.writeFileSync(testConfigPath, JSON.stringify(rawConfig, null, 2))
@@ -1430,7 +1430,7 @@ describe("migrateConfigFile with migration tracking via sidecar (#3263)", () =>
const sidecar = JSON.parse(fs.readFileSync(sidecarPath(testConfigPath), "utf-8")) const sidecar = JSON.parse(fs.readFileSync(sidecarPath(testConfigPath), "utf-8"))
expect(sidecar.appliedMigrations).toEqual([ expect(sidecar.appliedMigrations).toEqual([
"model-version:anthropic/claude-opus-4-5->anthropic/claude-opus-4-6", "model-version:anthropic/claude-opus-4-5->anthropic/claude-opus-4-7",
"model-version:openai/gpt-5.3-codex->openai/gpt-5.4", "model-version:openai/gpt-5.3-codex->openai/gpt-5.4",
]) ])
}) })
@@ -1460,13 +1460,13 @@ describe("migrateConfigFile with migration tracking via sidecar (#3263)", () =>
// codex was reverted, must stay // codex was reverted, must stay
expect((rawConfig.agents as Record<string, Record<string, unknown>>).codex.model).toBe("openai/gpt-5.3-codex") expect((rawConfig.agents as Record<string, Record<string, unknown>>).codex.model).toBe("openai/gpt-5.3-codex")
// claude migrates // claude migrates
expect((rawConfig.agents as Record<string, Record<string, unknown>>).claude.model).toBe("anthropic/claude-opus-4-6") expect((rawConfig.agents as Record<string, Record<string, unknown>>).claude.model).toBe("anthropic/claude-opus-4-7")
expect(rawConfig._migrations).toBeUndefined() expect(rawConfig._migrations).toBeUndefined()
const sidecar = JSON.parse(fs.readFileSync(sidecarPath(testConfigPath), "utf-8")) const sidecar = JSON.parse(fs.readFileSync(sidecarPath(testConfigPath), "utf-8"))
expect(new Set(sidecar.appliedMigrations)).toEqual(new Set([ expect(new Set(sidecar.appliedMigrations)).toEqual(new Set([
"model-version:openai/gpt-5.3-codex->openai/gpt-5.4", "model-version:openai/gpt-5.3-codex->openai/gpt-5.4",
"model-version:anthropic/claude-opus-4-5->anthropic/claude-opus-4-6", "model-version:anthropic/claude-opus-4-5->anthropic/claude-opus-4-7",
])) ]))
}) })
@@ -1494,7 +1494,7 @@ describe("migrateConfigFile with migration tracking via sidecar (#3263)", () =>
expect(Array.isArray(migrations)).toBe(true) expect(Array.isArray(migrations)).toBe(true)
expect(migrations).toContain("model-version:openai/gpt-5.3-codex->openai/gpt-5.4") expect(migrations).toContain("model-version:openai/gpt-5.3-codex->openai/gpt-5.4")
expect(migrations.length).toBeGreaterThanOrEqual(1) expect(migrations.length).toBeGreaterThanOrEqual(1)
expect((rawConfig.agents as Record<string, Record<string, unknown>>).oracle.model).toBe("anthropic/claude-opus-4-6") expect((rawConfig.agents as Record<string, Record<string, unknown>>).oracle.model).toBe("anthropic/claude-opus-4-7")
// Sidecar should not exist because write failed // Sidecar should not exist because write failed
expect(fs.existsSync(sidecarPath(testConfigPath))).toBe(false) expect(fs.existsSync(sidecarPath(testConfigPath))).toBe(false)
+1 -1
View File
@@ -16,7 +16,7 @@ export const MODEL_TO_CATEGORY_MAP: Record<string, string> = {
"google/gemini-3-flash": "writing", "google/gemini-3-flash": "writing",
"openai/gpt-5.4": "ultrabrain", "openai/gpt-5.4": "ultrabrain",
"anthropic/claude-haiku-4-5": "quick", "anthropic/claude-haiku-4-5": "quick",
"anthropic/claude-opus-4-6": "unspecified-high", "anthropic/claude-opus-4-7": "unspecified-high",
"anthropic/claude-sonnet-4-6": "unspecified-low", "anthropic/claude-sonnet-4-6": "unspecified-low",
} }
@@ -8,7 +8,7 @@ import { migrateConfigFile } from "./config-migration"
import { getSidecarPath } from "./migrations-sidecar" import { getSidecarPath } from "./migrations-sidecar"
const createdDirectories: string[] = [] const createdDirectories: string[] = []
const MIGRATION_KEY = "model-version:anthropic/claude-opus-4-5->anthropic/claude-opus-4-6" const MIGRATION_KEY = "model-version:anthropic/claude-opus-4-5->anthropic/claude-opus-4-7"
function createWorkdir(): string { function createWorkdir(): string {
const workdir = mkdtempSync(join(tmpdir(), "omo-config-migration-")) const workdir = mkdtempSync(join(tmpdir(), "omo-config-migration-"))
@@ -46,13 +46,13 @@ describe("migrateConfigFile sidecar write ordering", () => {
expect(needsWrite).toBe(true) expect(needsWrite).toBe(true)
expect(rawConfig._migrations).toBeUndefined() expect(rawConfig._migrations).toBeUndefined()
expect((rawConfig.agents as Record<string, Record<string, unknown>>).prometheus.model).toBe( expect((rawConfig.agents as Record<string, Record<string, unknown>>).prometheus.model).toBe(
"anthropic/claude-opus-4-6", "anthropic/claude-opus-4-7",
) )
const persistedConfig = JSON.parse(readFileSync(configPath, "utf-8")) as Record<string, unknown> const persistedConfig = JSON.parse(readFileSync(configPath, "utf-8")) as Record<string, unknown>
expect(persistedConfig._migrations).toBeUndefined() expect(persistedConfig._migrations).toBeUndefined()
expect((persistedConfig.agents as Record<string, Record<string, unknown>>).prometheus.model).toBe( expect((persistedConfig.agents as Record<string, Record<string, unknown>>).prometheus.model).toBe(
"anthropic/claude-opus-4-6", "anthropic/claude-opus-4-7",
) )
const sidecar = JSON.parse(readFileSync(getSidecarPath(configPath), "utf-8")) as { const sidecar = JSON.parse(readFileSync(getSidecarPath(configPath), "utf-8")) as {
@@ -87,7 +87,7 @@ describe("migrateConfigFile sidecar write ordering", () => {
expect(retriedNeedsWrite).toBe(true) expect(retriedNeedsWrite).toBe(true)
expect(retriedConfig._migrations).toBeUndefined() expect(retriedConfig._migrations).toBeUndefined()
expect((retriedConfig.agents as Record<string, Record<string, unknown>>).prometheus.model).toBe( expect((retriedConfig.agents as Record<string, Record<string, unknown>>).prometheus.model).toBe(
"anthropic/claude-opus-4-6", "anthropic/claude-opus-4-7",
) )
expect(existsSync(getSidecarPath(configPath))).toBe(true) expect(existsSync(getSidecarPath(configPath))).toBe(true)
}) })
@@ -108,13 +108,13 @@ describe("migrateConfigFile sidecar write ordering", () => {
expect(needsWrite).toBe(true) expect(needsWrite).toBe(true)
expect(rawConfig._migrations).toEqual([MIGRATION_KEY]) expect(rawConfig._migrations).toEqual([MIGRATION_KEY])
expect((rawConfig.agents as Record<string, Record<string, unknown>>).prometheus.model).toBe( expect((rawConfig.agents as Record<string, Record<string, unknown>>).prometheus.model).toBe(
"anthropic/claude-opus-4-6", "anthropic/claude-opus-4-7",
) )
const persistedConfig = JSON.parse(readFileSync(configPath, "utf-8")) as Record<string, unknown> const persistedConfig = JSON.parse(readFileSync(configPath, "utf-8")) as Record<string, unknown>
expect(persistedConfig._migrations).toEqual([MIGRATION_KEY]) expect(persistedConfig._migrations).toEqual([MIGRATION_KEY])
expect((persistedConfig.agents as Record<string, Record<string, unknown>>).prometheus.model).toBe( expect((persistedConfig.agents as Record<string, Record<string, unknown>>).prometheus.model).toBe(
"anthropic/claude-opus-4-6", "anthropic/claude-opus-4-7",
) )
expect(statSync(getSidecarPath(configPath)).isDirectory()).toBe(true) expect(statSync(getSidecarPath(configPath)).isDirectory()).toBe(true)
}) })
@@ -42,7 +42,7 @@ describe("migrations sidecar", () => {
JSON.stringify({ JSON.stringify({
appliedMigrations: [ appliedMigrations: [
"model-version:openai/gpt-5.3-codex->openai/gpt-5.4", "model-version:openai/gpt-5.3-codex->openai/gpt-5.4",
"model-version:anthropic/claude-opus-4-5->anthropic/claude-opus-4-6", "model-version:anthropic/claude-opus-4-5->anthropic/claude-opus-4-7",
], ],
}), }),
) )
@@ -51,7 +51,7 @@ describe("migrations sidecar", () => {
expect(applied.size).toBe(2) expect(applied.size).toBe(2)
expect(applied.has("model-version:openai/gpt-5.3-codex->openai/gpt-5.4")).toBe(true) expect(applied.has("model-version:openai/gpt-5.3-codex->openai/gpt-5.4")).toBe(true)
expect(applied.has("model-version:anthropic/claude-opus-4-5->anthropic/claude-opus-4-6")).toBe(true) expect(applied.has("model-version:anthropic/claude-opus-4-5->anthropic/claude-opus-4-7")).toBe(true)
}) })
test("returns an empty set on malformed JSON instead of throwing", () => { test("returns an empty set on malformed JSON instead of throwing", () => {
@@ -134,7 +134,7 @@ describe("migrations sidecar", () => {
const configPath = join(workdir, "oh-my-openagent.jsonc") const configPath = join(workdir, "oh-my-openagent.jsonc")
const original = new Set([ const original = new Set([
"model-version:openai/gpt-5.3-codex->openai/gpt-5.4", "model-version:openai/gpt-5.3-codex->openai/gpt-5.4",
"model-version:anthropic/claude-opus-4-5->anthropic/claude-opus-4-6", "model-version:anthropic/claude-opus-4-5->anthropic/claude-opus-4-7",
]) ])
writeAppliedMigrations(configPath, original) writeAppliedMigrations(configPath, original)
+1 -1
View File
@@ -22,7 +22,7 @@ import { writeFileAtomically } from "../write-file-atomically"
* { * {
* "appliedMigrations": [ * "appliedMigrations": [
* "model-version:openai/gpt-5.3-codex->openai/gpt-5.4", * "model-version:openai/gpt-5.3-codex->openai/gpt-5.4",
* "model-version:anthropic/claude-opus-4-5->anthropic/claude-opus-4-6" * "model-version:anthropic/claude-opus-4-5->anthropic/claude-opus-4-7"
* ] * ]
* } * }
*/ */
+2 -1
View File
@@ -6,7 +6,8 @@
* Keys are full "provider/model" strings. Only openai and anthropic entries needed. * Keys are full "provider/model" strings. Only openai and anthropic entries needed.
*/ */
export const MODEL_VERSION_MAP: Record<string, string> = { export const MODEL_VERSION_MAP: Record<string, string> = {
"anthropic/claude-opus-4-5": "anthropic/claude-opus-4-6", "anthropic/claude-opus-4-5": "anthropic/claude-opus-4-7",
"anthropic/claude-opus-4-6": "anthropic/claude-opus-4-7",
"anthropic/claude-sonnet-4-5": "anthropic/claude-sonnet-4-6", "anthropic/claude-sonnet-4-5": "anthropic/claude-sonnet-4-6",
"openai/gpt-5.3-codex": "openai/gpt-5.4", "openai/gpt-5.3-codex": "openai/gpt-5.4",
} }