chore: update GPT-5.2 references to GPT-5.4

Align runtime defaults, tests, docs, and generated artifacts with the newer GPT-5.4 baseline. Keep think-mode and prompt-routing expectations consistent after the model version bump.
This commit is contained in:
YeonGyu-Kim
2026-03-07 02:33:32 +09:00
parent d6d1f998d4
commit ea2585e01a
62 changed files with 478 additions and 479 deletions
+68 -68
View File
@@ -37,7 +37,7 @@ describe("migrateAgentNames", () => {
test("preserves current agent names unchanged", () => {
// given: Config with current agent names
const agents = {
oracle: { model: "openai/gpt-5.2" },
oracle: { model: "openai/gpt-5.4" },
librarian: { model: "google/gemini-3-flash" },
explore: { model: "opencode/gpt-5-nano" },
}
@@ -47,7 +47,7 @@ describe("migrateAgentNames", () => {
// then: Current names should remain unchanged
expect(changed).toBe(false)
expect(migrated["oracle"]).toEqual({ model: "openai/gpt-5.2" })
expect(migrated["oracle"]).toEqual({ model: "openai/gpt-5.4" })
expect(migrated["librarian"]).toEqual({ model: "google/gemini-3-flash" })
expect(migrated["explore"]).toEqual({ model: "opencode/gpt-5-nano" })
})
@@ -57,7 +57,7 @@ describe("migrateAgentNames", () => {
const agents = {
SISYPHUS: { model: "test" },
"planner-sisyphus": { prompt: "test" },
"Orchestrator-Sisyphus": { model: "openai/gpt-5.2" },
"Orchestrator-Sisyphus": { model: "openai/gpt-5.4" },
}
// when: Migrate agent names
@@ -66,7 +66,7 @@ describe("migrateAgentNames", () => {
// then: Case-insensitive lookup should migrate correctly
expect(migrated["sisyphus"]).toEqual({ model: "test" })
expect(migrated["prometheus"]).toEqual({ prompt: "test" })
expect(migrated["atlas"]).toEqual({ model: "openai/gpt-5.2" })
expect(migrated["atlas"]).toEqual({ model: "openai/gpt-5.4" })
})
test("passes through unknown agent names unchanged", () => {
@@ -441,11 +441,11 @@ describe("migrateConfigFile", () => {
expect(rawConfig.disabled_hooks).toContain("anthropic-context-window-limit-recovery")
})
test("does not migrate gpt-5.2-codex model versions in agents", () => {
test("does not migrate gpt-5.4-codex model versions in agents", () => {
// given: Config with old model version in agents
const rawConfig: Record<string, unknown> = {
agents: {
sisyphus: { model: "openai/gpt-5.2-codex", temperature: 0.1 },
sisyphus: { model: "openai/gpt-5.4-codex", temperature: 0.1 },
},
}
@@ -455,7 +455,7 @@ describe("migrateConfigFile", () => {
// then: Model version should remain unchanged
expect(needsWrite).toBe(false)
const agents = rawConfig.agents as Record<string, Record<string, unknown>>
expect(agents["sisyphus"].model).toBe("openai/gpt-5.2-codex")
expect(agents["sisyphus"].model).toBe("openai/gpt-5.4-codex")
})
test("migrates model versions in categories", () => {
@@ -479,7 +479,7 @@ describe("migrateConfigFile", () => {
// given: Config with current model versions
const rawConfig: Record<string, unknown> = {
agents: {
sisyphus: { model: "openai/gpt-5.2-codex" },
sisyphus: { model: "openai/gpt-5.4-codex" },
},
categories: {
"my-category": { model: "anthropic/claude-opus-4-6" },
@@ -514,10 +514,10 @@ describe("migration maps", () => {
})
describe("MODEL_VERSION_MAP", () => {
test("does not include openai/gpt-5.2-codex migration", () => {
test("does not include openai/gpt-5.4-codex migration", () => {
// given/when: Check MODEL_VERSION_MAP
// then: openai/gpt-5.2-codex should not be migrated
expect(MODEL_VERSION_MAP["openai/gpt-5.2-codex"]).toBeUndefined()
// then: openai/gpt-5.4-codex should not be migrated
expect(MODEL_VERSION_MAP["openai/gpt-5.4-codex"]).toBeUndefined()
})
test("maps anthropic/claude-opus-4-5 to anthropic/claude-opus-4-6", () => {
@@ -528,10 +528,10 @@ describe("MODEL_VERSION_MAP", () => {
})
describe("migrateModelVersions", () => {
test("#given a config with gpt-5.2-codex model #when migrating model versions #then does not overwrite with non-existent gpt-5.3-codex", () => {
// given: Agent config with gpt-5.2-codex model
test("#given a config with gpt-5.4-codex model #when migrating model versions #then does not overwrite with non-existent gpt-5.3-codex", () => {
// given: Agent config with gpt-5.4-codex model
const agents = {
sisyphus: { model: "openai/gpt-5.2-codex", temperature: 0.1 },
sisyphus: { model: "openai/gpt-5.4-codex", temperature: 0.1 },
}
// when: Migrate model versions
@@ -540,7 +540,7 @@ describe("migrateModelVersions", () => {
// then: Model should remain unchanged
expect(changed).toBe(false)
const sisyphus = migrated["sisyphus"] as Record<string, unknown>
expect(sisyphus.model).toBe("openai/gpt-5.2-codex")
expect(sisyphus.model).toBe("openai/gpt-5.4-codex")
expect(sisyphus.temperature).toBe(0.1)
})
@@ -562,7 +562,7 @@ describe("migrateModelVersions", () => {
test("leaves unknown model strings untouched", () => {
// given: Agent config with unknown model
const agents = {
oracle: { model: "openai/gpt-5.2", temperature: 0.5 },
oracle: { model: "openai/gpt-5.4", temperature: 0.5 },
}
// when: Migrate model versions
@@ -571,7 +571,7 @@ describe("migrateModelVersions", () => {
// then: Config should remain unchanged
expect(changed).toBe(false)
const oracle = migrated["oracle"] as Record<string, unknown>
expect(oracle.model).toBe("openai/gpt-5.2")
expect(oracle.model).toBe("openai/gpt-5.4")
})
test("handles agent config with no model field", () => {
@@ -605,9 +605,9 @@ describe("migrateModelVersions", () => {
test("migrates multiple agents in one pass", () => {
// given: Multiple agents with old models
const agents = {
sisyphus: { model: "openai/gpt-5.2-codex" },
sisyphus: { model: "openai/gpt-5.4-codex" },
prometheus: { model: "anthropic/claude-opus-4-5" },
oracle: { model: "openai/gpt-5.2" },
oracle: { model: "openai/gpt-5.4" },
}
// when: Migrate model versions
@@ -615,9 +615,9 @@ describe("migrateModelVersions", () => {
// then: Only mapped models should be updated
expect(changed).toBe(true)
expect((migrated["sisyphus"] as Record<string, unknown>).model).toBe("openai/gpt-5.2-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["oracle"] as Record<string, unknown>).model).toBe("openai/gpt-5.2")
expect((migrated["oracle"] as Record<string, unknown>).model).toBe("openai/gpt-5.4")
})
test("handles empty object", () => {
@@ -635,9 +635,9 @@ describe("migrateModelVersions", () => {
test("skips already-applied migrations", () => {
// given: Agent config with old model, but migration already applied
const agents = {
sisyphus: { model: "openai/gpt-5.2-codex", temperature: 0.1 },
sisyphus: { model: "openai/gpt-5.4-codex", temperature: 0.1 },
}
const appliedMigrations = new Set(["model-version:openai/gpt-5.2-codex->openai/gpt-5.3-codex"])
const appliedMigrations = new Set(["model-version:openai/gpt-5.4-codex->openai/gpt-5.3-codex"])
// when: Migrate with applied migrations
const { migrated, changed, newMigrations } = migrateModelVersions(agents, appliedMigrations)
@@ -646,32 +646,32 @@ describe("migrateModelVersions", () => {
expect(changed).toBe(false)
expect(newMigrations).toHaveLength(0)
const sisyphus = migrated["sisyphus"] as Record<string, unknown>
expect(sisyphus.model).toBe("openai/gpt-5.2-codex")
expect(sisyphus.model).toBe("openai/gpt-5.4-codex")
})
test("applies new migrations and records them", () => {
// given: Agent config with old model, no prior migrations
const agents = {
sisyphus: { model: "openai/gpt-5.2-codex" },
sisyphus: { model: "openai/gpt-5.4-codex" },
}
// when: Migrate without applied migrations
const { migrated, changed, newMigrations } = migrateModelVersions(agents)
// then: No migration should be applied for gpt-5.2-codex
// then: No migration should be applied for gpt-5.4-codex
expect(changed).toBe(false)
expect(newMigrations).toEqual([])
const sisyphus = migrated["sisyphus"] as Record<string, unknown>
expect(sisyphus.model).toBe("openai/gpt-5.2-codex")
expect(sisyphus.model).toBe("openai/gpt-5.4-codex")
})
test("handles mixed: some applied, some new", () => {
// given: Multiple agents, one migration already applied
const agents = {
sisyphus: { model: "openai/gpt-5.2-codex" },
sisyphus: { model: "openai/gpt-5.4-codex" },
prometheus: { model: "anthropic/claude-opus-4-5" },
}
const appliedMigrations = new Set(["model-version:openai/gpt-5.2-codex->openai/gpt-5.3-codex"])
const appliedMigrations = new Set(["model-version:openai/gpt-5.4-codex->openai/gpt-5.3-codex"])
// when: Migrate with partial history
const { migrated, changed, newMigrations } = migrateModelVersions(agents, appliedMigrations)
@@ -679,23 +679,23 @@ describe("migrateModelVersions", () => {
// then: Only prometheus should be migrated
expect(changed).toBe(true)
expect(newMigrations).toEqual(["model-version:anthropic/claude-opus-4-5->anthropic/claude-opus-4-6"])
expect((migrated["sisyphus"] as Record<string, unknown>).model).toBe("openai/gpt-5.2-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")
})
test("backward compatible without appliedMigrations param", () => {
// given: Agent config with old model, no appliedMigrations param
const agents = {
sisyphus: { model: "openai/gpt-5.2-codex" },
sisyphus: { model: "openai/gpt-5.4-codex" },
}
// when: Migrate without the param (backward compat)
const { migrated, changed, newMigrations } = migrateModelVersions(agents)
// then: Should keep gpt-5.2-codex unchanged
// then: Should keep gpt-5.4-codex unchanged
expect(changed).toBe(false)
expect(newMigrations).toHaveLength(0)
expect((migrated["sisyphus"] as Record<string, unknown>).model).toBe("openai/gpt-5.2-codex")
expect((migrated["sisyphus"] as Record<string, unknown>).model).toBe("openai/gpt-5.4-codex")
})
})
@@ -706,14 +706,14 @@ describe("migrateConfigFile _migrations tracking", () => {
const configPath = `${tmpDir}/oh-my-opencode.json`
const rawConfig: Record<string, unknown> = {
agents: {
sisyphus: { model: "openai/gpt-5.2-codex" },
sisyphus: { model: "openai/gpt-5.4-codex" },
},
}
// when: Migrate config file
const result = migrateConfigFile(configPath, rawConfig)
// then: gpt-5.2-codex should not produce migrations
// then: gpt-5.4-codex should not produce migrations
expect(result).toBe(false)
expect(rawConfig._migrations).toBeUndefined()
@@ -727,9 +727,9 @@ describe("migrateConfigFile _migrations tracking", () => {
const configPath = `${tmpDir}/oh-my-opencode.json`
const rawConfig: Record<string, unknown> = {
agents: {
sisyphus: { model: "openai/gpt-5.2-codex" },
sisyphus: { model: "openai/gpt-5.4-codex" },
},
_migrations: ["model-version:openai/gpt-5.2-codex->openai/gpt-5.3-codex"],
_migrations: ["model-version:openai/gpt-5.4-codex->openai/gpt-5.3-codex"],
}
// when: Migrate config file
@@ -738,7 +738,7 @@ describe("migrateConfigFile _migrations tracking", () => {
// then: Should NOT rewrite (model stays as user set it)
// Note: result may be true due to other migrations, but model should NOT change
const sisyphus = (rawConfig.agents as Record<string, Record<string, unknown>>).sisyphus
expect(sisyphus.model).toBe("openai/gpt-5.2-codex")
expect(sisyphus.model).toBe("openai/gpt-5.4-codex")
// cleanup
fs.rmSync(tmpDir, { recursive: true })
@@ -752,7 +752,7 @@ describe("migrateConfigFile _migrations tracking", () => {
agents: {
prometheus: { model: "anthropic/claude-opus-4-5" },
},
_migrations: ["model-version:openai/gpt-5.2-codex->openai/gpt-5.3-codex"],
_migrations: ["model-version:openai/gpt-5.4-codex->openai/gpt-5.3-codex"],
}
// when: Migrate config file
@@ -761,7 +761,7 @@ describe("migrateConfigFile _migrations tracking", () => {
// then: New migration appended, old one preserved
expect(result).toBe(true)
expect(rawConfig._migrations).toEqual([
"model-version:openai/gpt-5.2-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",
])
@@ -825,7 +825,7 @@ describe("migrateAgentConfigToCategory", () => {
const configs = [
{ model: "google/gemini-3.1-pro" },
{ model: "google/gemini-3-flash" },
{ model: "openai/gpt-5.2" },
{ model: "openai/gpt-5.4" },
{ model: "anthropic/claude-haiku-4-5" },
{ model: "anthropic/claude-opus-4-6" },
{ model: "anthropic/claude-sonnet-4-6" },
@@ -847,7 +847,7 @@ describe("migrateAgentConfigToCategory", () => {
test("preserves non-model fields during migration", () => {
// given: Config with multiple fields
const config = {
model: "openai/gpt-5.2",
model: "openai/gpt-5.4",
temperature: 0.1,
top_p: 0.95,
maxTokens: 4096,
@@ -1020,7 +1020,7 @@ describe("migrateConfigFile with backup", () => {
const rawConfig: Record<string, unknown> = {
agents: {
"multimodal-looker": { model: "anthropic/claude-haiku-4-5" },
oracle: { model: "openai/gpt-5.2" },
oracle: { model: "openai/gpt-5.4" },
"my-custom-agent": { model: "google/gemini-3.1-pro" },
},
}
@@ -1036,7 +1036,7 @@ describe("migrateConfigFile with backup", () => {
const agents = rawConfig.agents as Record<string, Record<string, unknown>>
expect(agents["multimodal-looker"].model).toBe("anthropic/claude-haiku-4-5")
expect(agents.oracle.model).toBe("openai/gpt-5.2")
expect(agents.oracle.model).toBe("openai/gpt-5.4")
expect(agents["my-custom-agent"].model).toBe("google/gemini-3.1-pro")
})
@@ -1140,9 +1140,9 @@ describe("migrateModelVersions with applied migrations", () => {
test("skips already-applied migrations", () => {
// given: Config with old model and migration already applied
const configs = {
sisyphus: { model: "openai/gpt-5.2-codex" },
sisyphus: { model: "openai/gpt-5.4-codex" },
}
const appliedMigrations = new Set(["model-version:openai/gpt-5.2-codex->openai/gpt-5.3-codex"])
const appliedMigrations = new Set(["model-version:openai/gpt-5.4-codex->openai/gpt-5.3-codex"])
// when: Migrate model versions
const { migrated, changed, newMigrations } = migrateModelVersions(configs, appliedMigrations)
@@ -1150,32 +1150,32 @@ describe("migrateModelVersions with applied migrations", () => {
// then: Migration should be skipped (user reverted)
expect(changed).toBe(false)
expect(newMigrations).toEqual([])
expect((migrated.sisyphus as Record<string, unknown>).model).toBe("openai/gpt-5.2-codex")
expect((migrated.sisyphus as Record<string, unknown>).model).toBe("openai/gpt-5.4-codex")
})
test("applies new migrations not in history", () => {
// given: Config with old model, no migration history
const configs = {
sisyphus: { model: "openai/gpt-5.2-codex" },
sisyphus: { model: "openai/gpt-5.4-codex" },
}
const appliedMigrations = new Set<string>()
// when: Migrate model versions
const { migrated, changed, newMigrations } = migrateModelVersions(configs, appliedMigrations)
// then: gpt-5.2-codex should not be migrated
// then: gpt-5.4-codex should not be migrated
expect(changed).toBe(false)
expect(newMigrations).toEqual([])
expect((migrated.sisyphus as Record<string, unknown>).model).toBe("openai/gpt-5.2-codex")
expect((migrated.sisyphus as Record<string, unknown>).model).toBe("openai/gpt-5.4-codex")
})
test("handles mixed: skip applied, apply new", () => {
// given: Config with 2 old models, 1 already migrated
const configs = {
sisyphus: { model: "openai/gpt-5.2-codex" },
sisyphus: { model: "openai/gpt-5.4-codex" },
oracle: { model: "anthropic/claude-opus-4-5" },
}
const appliedMigrations = new Set(["model-version:openai/gpt-5.2-codex->openai/gpt-5.3-codex"])
const appliedMigrations = new Set(["model-version:openai/gpt-5.4-codex->openai/gpt-5.3-codex"])
// when: Migrate model versions
const { migrated, changed, newMigrations } = migrateModelVersions(configs, appliedMigrations)
@@ -1183,29 +1183,29 @@ describe("migrateModelVersions with applied migrations", () => {
// then: Skip sisyphus (already applied), apply oracle
expect(changed).toBe(true)
expect(newMigrations).toEqual(["model-version:anthropic/claude-opus-4-5->anthropic/claude-opus-4-6"])
expect((migrated.sisyphus as Record<string, unknown>).model).toBe("openai/gpt-5.2-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")
})
test("backward compatible: no appliedMigrations param", () => {
// given: Config with old model, no appliedMigrations param (legacy call)
const configs = {
sisyphus: { model: "openai/gpt-5.2-codex" },
sisyphus: { model: "openai/gpt-5.4-codex" },
}
// when: Migrate model versions (without appliedMigrations)
const { migrated, changed, newMigrations } = migrateModelVersions(configs)
// then: gpt-5.2-codex remains unchanged
// then: gpt-5.4-codex remains unchanged
expect(changed).toBe(false)
expect(newMigrations).toEqual([])
expect((migrated.sisyphus as Record<string, unknown>).model).toBe("openai/gpt-5.2-codex")
expect((migrated.sisyphus as Record<string, unknown>).model).toBe("openai/gpt-5.4-codex")
})
test("returns empty newMigrations when no migrations applied", () => {
// given: Config with no old models
const configs = {
sisyphus: { model: "openai/gpt-5.2-codex" },
sisyphus: { model: "openai/gpt-5.4-codex" },
}
// when: Migrate model versions
@@ -1235,7 +1235,7 @@ describe("migrateConfigFile with _migrations tracking", () => {
const testConfigPath = "/tmp/test-config-migrations-1.json"
const rawConfig: Record<string, unknown> = {
agents: {
sisyphus: { model: "openai/gpt-5.2-codex" },
sisyphus: { model: "openai/gpt-5.4-codex" },
},
}
fs.writeFileSync(testConfigPath, JSON.stringify(rawConfig, null, 2))
@@ -1244,10 +1244,10 @@ describe("migrateConfigFile with _migrations tracking", () => {
// when: Migrate config file
const needsWrite = migrateConfigFile(testConfigPath, rawConfig)
// then: gpt-5.2-codex should not create migration history
// then: gpt-5.4-codex should not create migration history
expect(needsWrite).toBe(false)
expect(rawConfig._migrations).toBeUndefined()
expect((rawConfig.agents as Record<string, Record<string, unknown>>).sisyphus.model).toBe("openai/gpt-5.2-codex")
expect((rawConfig.agents as Record<string, Record<string, unknown>>).sisyphus.model).toBe("openai/gpt-5.4-codex")
})
test("skips re-applying already-recorded migrations", () => {
@@ -1255,9 +1255,9 @@ describe("migrateConfigFile with _migrations tracking", () => {
const testConfigPath = "/tmp/test-config-migrations-2.json"
const rawConfig: Record<string, unknown> = {
agents: {
sisyphus: { model: "openai/gpt-5.2-codex" },
sisyphus: { model: "openai/gpt-5.4-codex" },
},
_migrations: ["model-version:openai/gpt-5.2-codex->openai/gpt-5.3-codex"],
_migrations: ["model-version:openai/gpt-5.4-codex->openai/gpt-5.3-codex"],
}
fs.writeFileSync(testConfigPath, JSON.stringify(rawConfig, null, 2))
cleanupPaths.push(testConfigPath)
@@ -1267,8 +1267,8 @@ describe("migrateConfigFile with _migrations tracking", () => {
// then: Should not migrate (user reverted)
expect(needsWrite).toBe(false)
expect((rawConfig.agents as Record<string, Record<string, unknown>>).sisyphus.model).toBe("openai/gpt-5.2-codex")
expect(rawConfig._migrations).toEqual(["model-version:openai/gpt-5.2-codex->openai/gpt-5.3-codex"])
expect((rawConfig.agents as Record<string, Record<string, unknown>>).sisyphus.model).toBe("openai/gpt-5.4-codex")
expect(rawConfig._migrations).toEqual(["model-version:openai/gpt-5.4-codex->openai/gpt-5.3-codex"])
})
test("preserves existing _migrations and appends new ones", () => {
@@ -1276,10 +1276,10 @@ describe("migrateConfigFile with _migrations tracking", () => {
const testConfigPath = "/tmp/test-config-migrations-3.json"
const rawConfig: Record<string, unknown> = {
agents: {
sisyphus: { model: "openai/gpt-5.2-codex" },
sisyphus: { model: "openai/gpt-5.4-codex" },
oracle: { model: "anthropic/claude-opus-4-5" },
},
_migrations: ["model-version:openai/gpt-5.2-codex->openai/gpt-5.3-codex"],
_migrations: ["model-version:openai/gpt-5.4-codex->openai/gpt-5.3-codex"],
}
fs.writeFileSync(testConfigPath, JSON.stringify(rawConfig, null, 2))
cleanupPaths.push(testConfigPath)
@@ -1289,10 +1289,10 @@ describe("migrateConfigFile with _migrations tracking", () => {
// then: Should skip sisyphus, migrate oracle, append to _migrations
expect(needsWrite).toBe(true)
expect((rawConfig.agents as Record<string, Record<string, unknown>>).sisyphus.model).toBe("openai/gpt-5.2-codex")
expect((rawConfig.agents as Record<string, Record<string, unknown>>).sisyphus.model).toBe("openai/gpt-5.4-codex")
expect((rawConfig.agents as Record<string, Record<string, unknown>>).oracle.model).toBe("anthropic/claude-opus-4-6")
expect(rawConfig._migrations).toEqual([
"model-version:openai/gpt-5.2-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",
])
})