chore: update gpt-5.2-codex references to gpt-5.3-codex

This commit is contained in:
YeonGyu-Kim 2026-02-06 14:20:05 +09:00
parent d3999d79df
commit 4c7215404e
15 changed files with 73 additions and 73 deletions

View File

@ -204,8 +204,8 @@ oh-my-opencode/
| Agent | Model | Purpose | | Agent | Model | Purpose |
|-------|-------|---------| |-------|-------|---------|
| Sisyphus | anthropic/claude-opus-4-5 | Primary orchestrator (fallback: kimi-k2.5 → glm-4.7 → gpt-5.2-codex → gemini-3-pro) | | Sisyphus | anthropic/claude-opus-4-5 | Primary orchestrator (fallback: kimi-k2.5 → glm-4.7 → gpt-5.3-codex → gemini-3-pro) |
| Hephaestus | openai/gpt-5.2-codex | Autonomous deep worker, "The Legitimate Craftsman" (requires gpt-5.2-codex, no fallback) | | Hephaestus | openai/gpt-5.3-codex | Autonomous deep worker, "The Legitimate Craftsman" (requires gpt-5.3-codex, no fallback) |
| Atlas | anthropic/claude-sonnet-4-5 | Master orchestrator (fallback: kimi-k2.5 → gpt-5.2) | | Atlas | anthropic/claude-sonnet-4-5 | Master orchestrator (fallback: kimi-k2.5 → gpt-5.2) |
| oracle | openai/gpt-5.2 | Consultation, debugging | | oracle | openai/gpt-5.2 | Consultation, debugging |
| librarian | zai-coding-plan/glm-4.7 | Docs, GitHub search (fallback: glm-4.7-free) | | librarian | zai-coding-plan/glm-4.7 | Docs, GitHub search (fallback: glm-4.7-free) |

View File

@ -22,8 +22,8 @@ A Category is an agent configuration preset optimized for specific domains.
| Category | Default Model | Use Cases | | Category | Default Model | Use Cases |
|----------|---------------|-----------| |----------|---------------|-----------|
| `visual-engineering` | `google/gemini-3-pro` | Frontend, UI/UX, design, styling, animation | | `visual-engineering` | `google/gemini-3-pro` | Frontend, UI/UX, design, styling, animation |
| `ultrabrain` | `openai/gpt-5.2-codex` (xhigh) | Deep logical reasoning, complex architecture decisions requiring extensive analysis | | `ultrabrain` | `openai/gpt-5.3-codex` (xhigh) | Deep logical reasoning, complex architecture decisions requiring extensive analysis |
| `deep` | `openai/gpt-5.2-codex` (medium) | Goal-oriented autonomous problem-solving. Thorough research before action. For hairy problems requiring deep understanding. | | `deep` | `openai/gpt-5.3-codex` (medium) | Goal-oriented autonomous problem-solving. Thorough research before action. For hairy problems requiring deep understanding. |
| `artistry` | `google/gemini-3-pro` (max) | Highly creative/artistic tasks, novel ideas | | `artistry` | `google/gemini-3-pro` (max) | Highly creative/artistic tasks, novel ideas |
| `quick` | `anthropic/claude-haiku-4-5` | Trivial tasks - single file changes, typo fixes, simple modifications | | `quick` | `anthropic/claude-haiku-4-5` | Trivial tasks - single file changes, typo fixes, simple modifications |
| `unspecified-low` | `anthropic/claude-sonnet-4-5` | Tasks that don't fit other categories, low effort required | | `unspecified-low` | `anthropic/claude-sonnet-4-5` | Tasks that don't fit other categories, low effort required |

View File

@ -725,7 +725,7 @@ All 7 categories come with optimal model defaults, but **you must configure them
| Category | Built-in Default Model | Description | | Category | Built-in Default Model | Description |
| -------------------- | ---------------------------------- | -------------------------------------------------------------------- | | -------------------- | ---------------------------------- | -------------------------------------------------------------------- |
| `visual-engineering` | `google/gemini-3-pro-preview` | Frontend, UI/UX, design, styling, animation | | `visual-engineering` | `google/gemini-3-pro-preview` | Frontend, UI/UX, design, styling, animation |
| `ultrabrain` | `openai/gpt-5.2-codex` (xhigh) | Deep logical reasoning, complex architecture decisions | | `ultrabrain` | `openai/gpt-5.3-codex` (xhigh) | Deep logical reasoning, complex architecture decisions |
| `artistry` | `google/gemini-3-pro-preview` (max)| Highly creative/artistic tasks, novel ideas | | `artistry` | `google/gemini-3-pro-preview` (max)| Highly creative/artistic tasks, novel ideas |
| `quick` | `anthropic/claude-haiku-4-5` | Trivial tasks - single file changes, typo fixes, simple modifications| | `quick` | `anthropic/claude-haiku-4-5` | Trivial tasks - single file changes, typo fixes, simple modifications|
| `unspecified-low` | `anthropic/claude-sonnet-4-5` | Tasks that don't fit other categories, low effort required | | `unspecified-low` | `anthropic/claude-sonnet-4-5` | Tasks that don't fit other categories, low effort required |
@ -768,7 +768,7 @@ All 7 categories come with optimal model defaults, but **you must configure them
"model": "google/gemini-3-pro-preview" "model": "google/gemini-3-pro-preview"
}, },
"ultrabrain": { "ultrabrain": {
"model": "openai/gpt-5.2-codex", "model": "openai/gpt-5.3-codex",
"variant": "xhigh" "variant": "xhigh"
}, },
"artistry": { "artistry": {
@ -911,8 +911,8 @@ Categories follow the same resolution logic:
| Category | Model (no prefix) | Provider Priority Chain | | Category | Model (no prefix) | Provider Priority Chain |
|----------|-------------------|-------------------------| |----------|-------------------|-------------------------|
| **visual-engineering** | `gemini-3-pro` | google → anthropic → zai-coding-plan | | **visual-engineering** | `gemini-3-pro` | google → anthropic → zai-coding-plan |
| **ultrabrain** | `gpt-5.2-codex` | openai → google → anthropic | | **ultrabrain** | `gpt-5.3-codex` | openai → google → anthropic |
| **deep** | `gpt-5.2-codex` | openai → anthropic → google | | **deep** | `gpt-5.3-codex` | openai → anthropic → google |
| **artistry** | `gemini-3-pro` | google → anthropic → openai | | **artistry** | `gemini-3-pro` | google → anthropic → openai |
| **quick** | `claude-haiku-4-5` | anthropic → google → opencode | | **quick** | `claude-haiku-4-5` | anthropic → google → opencode |
| **unspecified-low** | `claude-sonnet-4-5` | anthropic → openai → google | | **unspecified-low** | `claude-sonnet-4-5` | anthropic → openai → google |

View File

@ -10,8 +10,8 @@ Oh-My-OpenCode provides 11 specialized AI agents. Each has distinct expertise, o
| Agent | Model | Purpose | | Agent | Model | Purpose |
|-------|-------|---------| |-------|-------|---------|
| **Sisyphus** | `anthropic/claude-opus-4-5` | **The default orchestrator.** Plans, delegates, and executes complex tasks using specialized subagents with aggressive parallel execution. Todo-driven workflow with extended thinking (32k budget). Fallback: kimi-k2.5 → glm-4.7 → gpt-5.2-codex → gemini-3-pro. | | **Sisyphus** | `anthropic/claude-opus-4-5` | **The default orchestrator.** Plans, delegates, and executes complex tasks using specialized subagents with aggressive parallel execution. Todo-driven workflow with extended thinking (32k budget). Fallback: kimi-k2.5 → glm-4.7 → gpt-5.3-codex → gemini-3-pro. |
| **Hephaestus** | `openai/gpt-5.2-codex` | **The Legitimate Craftsman.** Autonomous deep worker inspired by AmpCode's deep mode. Goal-oriented execution with thorough research before action. Explores codebase patterns, completes tasks end-to-end without premature stopping. Named after the Greek god of forge and craftsmanship. Requires gpt-5.2-codex (no fallback - only activates when this model is available). | | **Hephaestus** | `openai/gpt-5.3-codex` | **The Legitimate Craftsman.** Autonomous deep worker inspired by AmpCode's deep mode. Goal-oriented execution with thorough research before action. Explores codebase patterns, completes tasks end-to-end without premature stopping. Named after the Greek god of forge and craftsmanship. Requires gpt-5.3-codex (no fallback - only activates when this model is available). |
| **oracle** | `openai/gpt-5.2` | Architecture decisions, code review, debugging. Read-only consultation - stellar logical reasoning and deep analysis. Inspired by AmpCode. | | **oracle** | `openai/gpt-5.2` | Architecture decisions, code review, debugging. Read-only consultation - stellar logical reasoning and deep analysis. Inspired by AmpCode. |
| **librarian** | `zai-coding-plan/glm-4.7` | Multi-repo analysis, documentation lookup, OSS implementation examples. Deep codebase understanding with evidence-based answers. Fallback: glm-4.7-free → claude-sonnet-4-5. | | **librarian** | `zai-coding-plan/glm-4.7` | Multi-repo analysis, documentation lookup, OSS implementation examples. Deep codebase understanding with evidence-based answers. Fallback: glm-4.7-free → claude-sonnet-4-5. |
| **explore** | `anthropic/claude-haiku-4-5` | Fast codebase exploration and contextual grep. Fallback: gpt-5-mini → gpt-5-nano. | | **explore** | `anthropic/claude-haiku-4-5` | Fast codebase exploration and contextual grep. Fallback: gpt-5-mini → gpt-5-nano. |

View File

@ -33,8 +33,8 @@ agents/
## AGENT MODELS ## AGENT MODELS
| Agent | Model | Temp | Purpose | | Agent | Model | Temp | Purpose |
|-------|-------|------|---------| |-------|-------|------|---------|
| Sisyphus | anthropic/claude-opus-4-5 | 0.1 | Primary orchestrator (fallback: kimi-k2.5 → glm-4.7 → gpt-5.2-codex → gemini-3-pro) | | Sisyphus | anthropic/claude-opus-4-5 | 0.1 | Primary orchestrator (fallback: kimi-k2.5 → glm-4.7 → gpt-5.3-codex → gemini-3-pro) |
| Hephaestus | openai/gpt-5.2-codex | 0.1 | Autonomous deep worker, "The Legitimate Craftsman" (requires gpt-5.2-codex, no fallback) | | Hephaestus | openai/gpt-5.3-codex | 0.1 | Autonomous deep worker, "The Legitimate Craftsman" (requires gpt-5.3-codex, no fallback) |
| Atlas | anthropic/claude-sonnet-4-5 | 0.1 | Master orchestrator (fallback: kimi-k2.5 → gpt-5.2) | | Atlas | anthropic/claude-sonnet-4-5 | 0.1 | Master orchestrator (fallback: kimi-k2.5 → gpt-5.2) |
| oracle | openai/gpt-5.2 | 0.1 | Consultation, debugging | | oracle | openai/gpt-5.2 | 0.1 | Consultation, debugging |
| librarian | zai-coding-plan/glm-4.7 | 0.1 | Docs, GitHub search (fallback: glm-4.7-free) | | librarian | zai-coding-plan/glm-4.7 | 0.1 | Docs, GitHub search (fallback: glm-4.7-free) |

View File

@ -263,7 +263,7 @@ describe("createBuiltinAgents with requiresProvider gating (hephaestus)", () =>
test("hephaestus is created when openai provider is connected", async () => { test("hephaestus is created when openai provider is connected", async () => {
// #given - openai provider has models available // #given - openai provider has models available
const fetchSpy = spyOn(shared, "fetchAvailableModels").mockResolvedValue( const fetchSpy = spyOn(shared, "fetchAvailableModels").mockResolvedValue(
new Set(["openai/gpt-5.2-codex"]) new Set(["openai/gpt-5.3-codex"])
) )
try { try {
@ -280,7 +280,7 @@ describe("createBuiltinAgents with requiresProvider gating (hephaestus)", () =>
test("hephaestus is created when github-copilot provider is connected", async () => { test("hephaestus is created when github-copilot provider is connected", async () => {
// #given - github-copilot provider has models available // #given - github-copilot provider has models available
const fetchSpy = spyOn(shared, "fetchAvailableModels").mockResolvedValue( const fetchSpy = spyOn(shared, "fetchAvailableModels").mockResolvedValue(
new Set(["github-copilot/gpt-5.2-codex"]) new Set(["github-copilot/gpt-5.3-codex"])
) )
try { try {
@ -297,7 +297,7 @@ describe("createBuiltinAgents with requiresProvider gating (hephaestus)", () =>
test("hephaestus is created when opencode provider is connected", async () => { test("hephaestus is created when opencode provider is connected", async () => {
// #given - opencode provider has models available // #given - opencode provider has models available
const fetchSpy = spyOn(shared, "fetchAvailableModels").mockResolvedValue( const fetchSpy = spyOn(shared, "fetchAvailableModels").mockResolvedValue(
new Set(["opencode/gpt-5.2-codex"]) new Set(["opencode/gpt-5.3-codex"])
) )
try { try {
@ -322,7 +322,7 @@ describe("createBuiltinAgents with requiresProvider gating (hephaestus)", () =>
// #then // #then
expect(agents.hephaestus).toBeDefined() expect(agents.hephaestus).toBeDefined()
expect(agents.hephaestus.model).toBe("openai/gpt-5.2-codex") expect(agents.hephaestus.model).toBe("openai/gpt-5.3-codex")
} finally { } finally {
cacheSpy.mockRestore() cacheSpy.mockRestore()
fetchSpy.mockRestore() fetchSpy.mockRestore()
@ -572,7 +572,7 @@ describe("buildAgent with category and skills", () => {
const agent = buildAgent(source["test-agent"], TEST_MODEL) const agent = buildAgent(source["test-agent"], TEST_MODEL)
// #then - category's built-in model and skills are applied // #then - category's built-in model and skills are applied
expect(agent.model).toBe("openai/gpt-5.2-codex") expect(agent.model).toBe("openai/gpt-5.3-codex")
expect(agent.variant).toBe("xhigh") expect(agent.variant).toBe("xhigh")
expect(agent.prompt).toContain("Role: Designer-Turned-Developer") expect(agent.prompt).toContain("Role: Designer-Turned-Developer")
expect(agent.prompt).toContain("Task description") expect(agent.prompt).toContain("Task description")
@ -685,9 +685,9 @@ describe("override.category expansion in createBuiltinAgents", () => {
// #when // #when
const agents = await createBuiltinAgents([], overrides, undefined, TEST_DEFAULT_MODEL) const agents = await createBuiltinAgents([], overrides, undefined, TEST_DEFAULT_MODEL)
// #then - ultrabrain category: model=openai/gpt-5.2-codex, variant=xhigh // #then - ultrabrain category: model=openai/gpt-5.3-codex, variant=xhigh
expect(agents.oracle).toBeDefined() expect(agents.oracle).toBeDefined()
expect(agents.oracle.model).toBe("openai/gpt-5.2-codex") expect(agents.oracle.model).toBe("openai/gpt-5.3-codex")
expect(agents.oracle.variant).toBe("xhigh") expect(agents.oracle.variant).toBe("xhigh")
}) })
@ -754,9 +754,9 @@ describe("override.category expansion in createBuiltinAgents", () => {
// #when // #when
const agents = await createBuiltinAgents([], overrides, undefined, TEST_DEFAULT_MODEL) const agents = await createBuiltinAgents([], overrides, undefined, TEST_DEFAULT_MODEL)
// #then - ultrabrain category: model=openai/gpt-5.2-codex, variant=xhigh // #then - ultrabrain category: model=openai/gpt-5.3-codex, variant=xhigh
expect(agents.sisyphus).toBeDefined() expect(agents.sisyphus).toBeDefined()
expect(agents.sisyphus.model).toBe("openai/gpt-5.2-codex") expect(agents.sisyphus.model).toBe("openai/gpt-5.3-codex")
expect(agents.sisyphus.variant).toBe("xhigh") expect(agents.sisyphus.variant).toBe("xhigh")
}) })
@ -769,9 +769,9 @@ describe("override.category expansion in createBuiltinAgents", () => {
// #when // #when
const agents = await createBuiltinAgents([], overrides, undefined, TEST_DEFAULT_MODEL) const agents = await createBuiltinAgents([], overrides, undefined, TEST_DEFAULT_MODEL)
// #then - ultrabrain category: model=openai/gpt-5.2-codex, variant=xhigh // #then - ultrabrain category: model=openai/gpt-5.3-codex, variant=xhigh
expect(agents.atlas).toBeDefined() expect(agents.atlas).toBeDefined()
expect(agents.atlas.model).toBe("openai/gpt-5.2-codex") expect(agents.atlas.model).toBe("openai/gpt-5.3-codex")
expect(agents.atlas.variant).toBe("xhigh") expect(agents.atlas.variant).toBe("xhigh")
}) })

View File

@ -417,7 +417,7 @@ describe("generateModelConfig", () => {
const result = generateModelConfig(config) const result = generateModelConfig(config)
// #then // #then
expect(result.agents?.hephaestus?.model).toBe("openai/gpt-5.2-codex") expect(result.agents?.hephaestus?.model).toBe("openai/gpt-5.3-codex")
expect(result.agents?.hephaestus?.variant).toBe("medium") expect(result.agents?.hephaestus?.variant).toBe("medium")
}) })
@ -429,7 +429,7 @@ describe("generateModelConfig", () => {
const result = generateModelConfig(config) const result = generateModelConfig(config)
// #then // #then
expect(result.agents?.hephaestus?.model).toBe("github-copilot/gpt-5.2-codex") expect(result.agents?.hephaestus?.model).toBe("github-copilot/gpt-5.3-codex")
expect(result.agents?.hephaestus?.variant).toBe("medium") expect(result.agents?.hephaestus?.variant).toBe("medium")
}) })
@ -441,7 +441,7 @@ describe("generateModelConfig", () => {
const result = generateModelConfig(config) const result = generateModelConfig(config)
// #then // #then
expect(result.agents?.hephaestus?.model).toBe("opencode/gpt-5.2-codex") expect(result.agents?.hephaestus?.model).toBe("opencode/gpt-5.3-codex")
expect(result.agents?.hephaestus?.variant).toBe("medium") expect(result.agents?.hephaestus?.variant).toBe("medium")
}) })

View File

@ -295,7 +295,7 @@ describe("Prometheus category config resolution", () => {
// then // then
expect(config).toBeDefined() expect(config).toBeDefined()
expect(config?.model).toBe("openai/gpt-5.2-codex") expect(config?.model).toBe("openai/gpt-5.3-codex")
expect(config?.variant).toBe("xhigh") expect(config?.variant).toBe("xhigh")
}) })
@ -355,7 +355,7 @@ describe("Prometheus category config resolution", () => {
// then - falls back to DEFAULT_CATEGORIES // then - falls back to DEFAULT_CATEGORIES
expect(config).toBeDefined() expect(config).toBeDefined()
expect(config?.model).toBe("openai/gpt-5.2-codex") expect(config?.model).toBe("openai/gpt-5.3-codex")
expect(config?.variant).toBe("xhigh") expect(config?.variant).toBe("xhigh")
}) })

View File

@ -113,9 +113,9 @@ describe("resolveVariantForModel", () => {
}) })
test("returns correct variant for openai provider (hephaestus agent)", () => { test("returns correct variant for openai provider (hephaestus agent)", () => {
// #given hephaestus has openai/gpt-5.2-codex with variant "medium" in its chain // #given hephaestus has openai/gpt-5.3-codex with variant "medium" in its chain
const config = {} as OhMyOpenCodeConfig const config = {} as OhMyOpenCodeConfig
const model = { providerID: "openai", modelID: "gpt-5.2-codex" } const model = { providerID: "openai", modelID: "gpt-5.3-codex" }
// #when // #when
const variant = resolveVariantForModel(config, "hephaestus", model) const variant = resolveVariantForModel(config, "hephaestus", model)
@ -179,7 +179,7 @@ describe("resolveVariantForModel", () => {
"custom-agent": { category: "ultrabrain" }, "custom-agent": { category: "ultrabrain" },
}, },
} as OhMyOpenCodeConfig } as OhMyOpenCodeConfig
const model = { providerID: "openai", modelID: "gpt-5.2-codex" } const model = { providerID: "openai", modelID: "gpt-5.3-codex" }
// when // when
const variant = resolveVariantForModel(config, "custom-agent", model) const variant = resolveVariantForModel(config, "custom-agent", model)

View File

@ -67,7 +67,7 @@ describe("fetchAvailableModels", () => {
model: { model: {
list: async () => ({ list: async () => ({
data: [ data: [
{ id: "gpt-5.2-codex", provider: "openai" }, { id: "gpt-5.3-codex", provider: "openai" },
{ id: "gemini-3-pro", provider: "google" }, { id: "gemini-3-pro", provider: "google" },
], ],
}), }),
@ -77,7 +77,7 @@ describe("fetchAvailableModels", () => {
const result = await fetchAvailableModels(client) const result = await fetchAvailableModels(client)
expect(result).toBeInstanceOf(Set) expect(result).toBeInstanceOf(Set)
expect(result.has("openai/gpt-5.2-codex")).toBe(true) expect(result.has("openai/gpt-5.3-codex")).toBe(true)
expect(result.has("google/gemini-3-pro")).toBe(false) expect(result.has("google/gemini-3-pro")).toBe(false)
}) })
@ -96,7 +96,7 @@ describe("fetchAvailableModels", () => {
model: { model: {
list: async () => ({ list: async () => ({
data: [ data: [
{ id: "gpt-5.2-codex", provider: "openai" }, { id: "gpt-5.3-codex", provider: "openai" },
{ id: "gemini-3-pro", provider: "google" }, { id: "gemini-3-pro", provider: "google" },
], ],
}), }),
@ -106,7 +106,7 @@ describe("fetchAvailableModels", () => {
const result = await fetchAvailableModels(client, { connectedProviders: ["openai", "google"] }) const result = await fetchAvailableModels(client, { connectedProviders: ["openai", "google"] })
expect(result).toBeInstanceOf(Set) expect(result).toBeInstanceOf(Set)
expect(result.has("openai/gpt-5.2-codex")).toBe(true) expect(result.has("openai/gpt-5.3-codex")).toBe(true)
expect(result.has("google/gemini-3-pro")).toBe(true) expect(result.has("google/gemini-3-pro")).toBe(true)
}) })
@ -134,7 +134,7 @@ describe("fetchAvailableModels", () => {
it("#given cache file with various providers #when fetchAvailableModels called with all providers #then extracts all IDs correctly", async () => { it("#given cache file with various providers #when fetchAvailableModels called with all providers #then extracts all IDs correctly", async () => {
writeModelsCache({ writeModelsCache({
openai: { id: "openai", models: { "gpt-5.2-codex": { id: "gpt-5.2-codex" } } }, openai: { id: "openai", models: { "gpt-5.3-codex": { id: "gpt-5.3-codex" } } },
anthropic: { id: "anthropic", models: { "claude-sonnet-4-5": { id: "claude-sonnet-4-5" } } }, anthropic: { id: "anthropic", models: { "claude-sonnet-4-5": { id: "claude-sonnet-4-5" } } },
google: { id: "google", models: { "gemini-3-flash": { id: "gemini-3-flash" } } }, google: { id: "google", models: { "gemini-3-flash": { id: "gemini-3-flash" } } },
opencode: { id: "opencode", models: { "gpt-5-nano": { id: "gpt-5-nano" } } }, opencode: { id: "opencode", models: { "gpt-5-nano": { id: "gpt-5-nano" } } },
@ -145,7 +145,7 @@ describe("fetchAvailableModels", () => {
}) })
expect(result.size).toBe(4) expect(result.size).toBe(4)
expect(result.has("openai/gpt-5.2-codex")).toBe(true) expect(result.has("openai/gpt-5.3-codex")).toBe(true)
expect(result.has("anthropic/claude-sonnet-4-5")).toBe(true) expect(result.has("anthropic/claude-sonnet-4-5")).toBe(true)
expect(result.has("google/gemini-3-flash")).toBe(true) expect(result.has("google/gemini-3-flash")).toBe(true)
expect(result.has("opencode/gpt-5-nano")).toBe(true) expect(result.has("opencode/gpt-5-nano")).toBe(true)
@ -159,7 +159,7 @@ describe("fuzzyMatchModel", () => {
it("should match substring in model name", () => { it("should match substring in model name", () => {
const available = new Set([ const available = new Set([
"openai/gpt-5.2", "openai/gpt-5.2",
"openai/gpt-5.2-codex", "openai/gpt-5.3-codex",
"anthropic/claude-opus-4-5", "anthropic/claude-opus-4-5",
]) ])
const result = fuzzyMatchModel("gpt-5.2", available) const result = fuzzyMatchModel("gpt-5.2", available)
@ -185,7 +185,7 @@ describe("fuzzyMatchModel", () => {
it("should prefer exact match over substring match", () => { it("should prefer exact match over substring match", () => {
const available = new Set([ const available = new Set([
"openai/gpt-5.2", "openai/gpt-5.2",
"openai/gpt-5.2-codex", "openai/gpt-5.3-codex",
"openai/gpt-5.2-ultra", "openai/gpt-5.2-ultra",
]) ])
const result = fuzzyMatchModel("gpt-5.2", available) const result = fuzzyMatchModel("gpt-5.2", available)
@ -794,10 +794,10 @@ describe("fetchAvailableModels with provider-models cache (whitelist-filtered)",
describe("isModelAvailable", () => { describe("isModelAvailable", () => {
it("returns true when model exists via fuzzy match", () => { it("returns true when model exists via fuzzy match", () => {
// given // given
const available = new Set(["openai/gpt-5.2-codex", "anthropic/claude-opus-4-5"]) const available = new Set(["openai/gpt-5.3-codex", "anthropic/claude-opus-4-5"])
// when // when
const result = isModelAvailable("gpt-5.2-codex", available) const result = isModelAvailable("gpt-5.3-codex", available)
// then // then
expect(result).toBe(true) expect(result).toBe(true)
@ -808,7 +808,7 @@ describe("isModelAvailable", () => {
const available = new Set(["anthropic/claude-opus-4-5"]) const available = new Set(["anthropic/claude-opus-4-5"])
// when // when
const result = isModelAvailable("gpt-5.2-codex", available) const result = isModelAvailable("gpt-5.3-codex", available)
// then // then
expect(result).toBe(false) expect(result).toBe(false)
@ -819,7 +819,7 @@ describe("isModelAvailable", () => {
const available = new Set<string>() const available = new Set<string>()
// when // when
const result = isModelAvailable("gpt-5.2-codex", available) const result = isModelAvailable("gpt-5.3-codex", available)
// then // then
expect(result).toBe(false) expect(result).toBe(false)

View File

@ -20,7 +20,7 @@ import { readProviderModelsCache, hasProviderModelsCache, readConnectedProviders
* If providers array is given, only models starting with "provider/" are considered. * If providers array is given, only models starting with "provider/" are considered.
* *
* @example * @example
* const available = new Set(["openai/gpt-5.2", "openai/gpt-5.2-codex", "anthropic/claude-opus-4-5"]) * const available = new Set(["openai/gpt-5.2", "openai/gpt-5.3-codex", "anthropic/claude-opus-4-5"])
* fuzzyMatchModel("gpt-5.2", available) // → "openai/gpt-5.2" * fuzzyMatchModel("gpt-5.2", available) // → "openai/gpt-5.2"
* fuzzyMatchModel("claude", available, ["openai"]) // → null (provider filter excludes anthropic) * fuzzyMatchModel("claude", available, ["openai"]) // → null (provider filter excludes anthropic)
*/ */
@ -105,7 +105,7 @@ export function fuzzyMatchModel(
/** /**
* Check if a target model is available (fuzzy match by model name, no provider filtering) * Check if a target model is available (fuzzy match by model name, no provider filtering)
* *
* @param targetModel - Model name to check (e.g., "gpt-5.2-codex") * @param targetModel - Model name to check (e.g., "gpt-5.3-codex")
* @param availableModels - Set of available models in "provider/model" format * @param availableModels - Set of available models in "provider/model" format
* @returns true if model is available, false otherwise * @returns true if model is available, false otherwise
*/ */

View File

@ -224,35 +224,35 @@ describe("AGENT_MODEL_REQUIREMENTS", () => {
}) })
describe("CATEGORY_MODEL_REQUIREMENTS", () => { describe("CATEGORY_MODEL_REQUIREMENTS", () => {
test("ultrabrain has valid fallbackChain with gpt-5.2-codex as primary", () => { test("ultrabrain has valid fallbackChain with gpt-5.3-codex as primary", () => {
// given - ultrabrain category requirement // given - ultrabrain category requirement
const ultrabrain = CATEGORY_MODEL_REQUIREMENTS["ultrabrain"] const ultrabrain = CATEGORY_MODEL_REQUIREMENTS["ultrabrain"]
// when - accessing ultrabrain requirement // when - accessing ultrabrain requirement
// then - fallbackChain exists with gpt-5.2-codex as first entry // then - fallbackChain exists with gpt-5.3-codex as first entry
expect(ultrabrain).toBeDefined() expect(ultrabrain).toBeDefined()
expect(ultrabrain.fallbackChain).toBeArray() expect(ultrabrain.fallbackChain).toBeArray()
expect(ultrabrain.fallbackChain.length).toBeGreaterThan(0) expect(ultrabrain.fallbackChain.length).toBeGreaterThan(0)
const primary = ultrabrain.fallbackChain[0] const primary = ultrabrain.fallbackChain[0]
expect(primary.variant).toBe("xhigh") expect(primary.variant).toBe("xhigh")
expect(primary.model).toBe("gpt-5.2-codex") expect(primary.model).toBe("gpt-5.3-codex")
expect(primary.providers[0]).toBe("openai") expect(primary.providers[0]).toBe("openai")
}) })
test("deep has valid fallbackChain with gpt-5.2-codex as primary", () => { test("deep has valid fallbackChain with gpt-5.3-codex as primary", () => {
// given - deep category requirement // given - deep category requirement
const deep = CATEGORY_MODEL_REQUIREMENTS["deep"] const deep = CATEGORY_MODEL_REQUIREMENTS["deep"]
// when - accessing deep requirement // when - accessing deep requirement
// then - fallbackChain exists with gpt-5.2-codex as first entry, medium variant // then - fallbackChain exists with gpt-5.3-codex as first entry, medium variant
expect(deep).toBeDefined() expect(deep).toBeDefined()
expect(deep.fallbackChain).toBeArray() expect(deep.fallbackChain).toBeArray()
expect(deep.fallbackChain.length).toBeGreaterThan(0) expect(deep.fallbackChain.length).toBeGreaterThan(0)
const primary = deep.fallbackChain[0] const primary = deep.fallbackChain[0]
expect(primary.variant).toBe("medium") expect(primary.variant).toBe("medium")
expect(primary.model).toBe("gpt-5.2-codex") expect(primary.model).toBe("gpt-5.3-codex")
expect(primary.providers[0]).toBe("openai") expect(primary.providers[0]).toBe("openai")
}) })
@ -480,12 +480,12 @@ describe("ModelRequirement type", () => {
}) })
describe("requiresModel field in categories", () => { describe("requiresModel field in categories", () => {
test("deep category has requiresModel set to gpt-5.2-codex", () => { test("deep category has requiresModel set to gpt-5.3-codex", () => {
// given // given
const deep = CATEGORY_MODEL_REQUIREMENTS["deep"] const deep = CATEGORY_MODEL_REQUIREMENTS["deep"]
// when / #then // when / #then
expect(deep.requiresModel).toBe("gpt-5.2-codex") expect(deep.requiresModel).toBe("gpt-5.3-codex")
}) })
test("artistry category has requiresModel set to gemini-3-pro", () => { test("artistry category has requiresModel set to gemini-3-pro", () => {

View File

@ -26,7 +26,7 @@ export const AGENT_MODEL_REQUIREMENTS: Record<string, ModelRequirement> = {
}, },
hephaestus: { hephaestus: {
fallbackChain: [ fallbackChain: [
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2-codex", variant: "medium" }, { providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.3-codex", variant: "medium" },
], ],
requiresProvider: ["openai", "github-copilot", "opencode"], requiresProvider: ["openai", "github-copilot", "opencode"],
}, },
@ -113,7 +113,7 @@ export const CATEGORY_MODEL_REQUIREMENTS: Record<string, ModelRequirement> = {
}, },
ultrabrain: { ultrabrain: {
fallbackChain: [ fallbackChain: [
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2-codex", variant: "xhigh" }, { providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.3-codex", variant: "xhigh" },
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro", variant: "high" }, { providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro", variant: "high" },
{ providers: ["anthropic"], model: "claude-opus-4-6", variant: "max" }, { providers: ["anthropic"], model: "claude-opus-4-6", variant: "max" },
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" }, { providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" },
@ -121,12 +121,12 @@ export const CATEGORY_MODEL_REQUIREMENTS: Record<string, ModelRequirement> = {
}, },
deep: { deep: {
fallbackChain: [ fallbackChain: [
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2-codex", variant: "medium" }, { providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.3-codex", variant: "medium" },
{ providers: ["anthropic"], model: "claude-opus-4-6", variant: "max" }, { providers: ["anthropic"], model: "claude-opus-4-6", variant: "max" },
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" }, { providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" },
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro", variant: "high" }, { providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro", variant: "high" },
], ],
requiresModel: "gpt-5.2-codex", requiresModel: "gpt-5.3-codex",
}, },
artistry: { artistry: {
fallbackChain: [ fallbackChain: [
@ -147,7 +147,7 @@ export const CATEGORY_MODEL_REQUIREMENTS: Record<string, ModelRequirement> = {
"unspecified-low": { "unspecified-low": {
fallbackChain: [ fallbackChain: [
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-sonnet-4-5" }, { providers: ["anthropic", "github-copilot", "opencode"], model: "claude-sonnet-4-5" },
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2-codex", variant: "medium" }, { providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.3-codex", variant: "medium" },
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-flash" }, { providers: ["google", "github-copilot", "opencode"], model: "gemini-3-flash" },
], ],
}, },

View File

@ -194,8 +194,8 @@ You are NOT an interactive assistant. You are an autonomous problem-solver.
export const DEFAULT_CATEGORIES: Record<string, CategoryConfig> = { export const DEFAULT_CATEGORIES: Record<string, CategoryConfig> = {
"visual-engineering": { model: "google/gemini-3-pro" }, "visual-engineering": { model: "google/gemini-3-pro" },
ultrabrain: { model: "openai/gpt-5.2-codex", variant: "xhigh" }, ultrabrain: { model: "openai/gpt-5.3-codex", variant: "xhigh" },
deep: { model: "openai/gpt-5.2-codex", variant: "medium" }, deep: { model: "openai/gpt-5.3-codex", variant: "medium" },
artistry: { model: "google/gemini-3-pro", variant: "high" }, artistry: { model: "google/gemini-3-pro", variant: "high" },
quick: { model: "anthropic/claude-haiku-4-5" }, quick: { model: "anthropic/claude-haiku-4-5" },
"unspecified-low": { model: "anthropic/claude-sonnet-4-5" }, "unspecified-low": { model: "anthropic/claude-sonnet-4-5" },
@ -343,7 +343,7 @@ FOR EVERY TASK, YOU MUST RECOMMEND:
| Category | Best For | Model | | Category | Best For | Model |
|----------|----------|-------| |----------|----------|-------|
| \`visual-engineering\` | Frontend, UI/UX, design, styling, animation | google/gemini-3-pro | | \`visual-engineering\` | Frontend, UI/UX, design, styling, animation | google/gemini-3-pro |
| \`ultrabrain\` | Complex architecture, deep logical reasoning | openai/gpt-5.2-codex | | \`ultrabrain\` | Complex architecture, deep logical reasoning | openai/gpt-5.3-codex |
| \`artistry\` | Highly creative/artistic tasks, novel ideas | google/gemini-3-pro | | \`artistry\` | Highly creative/artistic tasks, novel ideas | google/gemini-3-pro |
| \`quick\` | Trivial tasks - single file, typo fixes | anthropic/claude-haiku-4-5 | | \`quick\` | Trivial tasks - single file, typo fixes | anthropic/claude-haiku-4-5 |
| \`unspecified-low\` | Moderate effort, doesn't fit other categories | anthropic/claude-sonnet-4-5 | | \`unspecified-low\` | Moderate effort, doesn't fit other categories | anthropic/claude-sonnet-4-5 |

View File

@ -30,7 +30,7 @@ describe("sisyphus-task", () => {
models: { models: {
anthropic: ["claude-opus-4-5", "claude-sonnet-4-5", "claude-haiku-4-5"], anthropic: ["claude-opus-4-5", "claude-sonnet-4-5", "claude-haiku-4-5"],
google: ["gemini-3-pro", "gemini-3-flash"], google: ["gemini-3-pro", "gemini-3-flash"],
openai: ["gpt-5.2", "gpt-5.2-codex"], openai: ["gpt-5.2", "gpt-5.3-codex"],
}, },
connected: ["anthropic", "google", "openai"], connected: ["anthropic", "google", "openai"],
updatedAt: "2026-01-01T00:00:00.000Z", updatedAt: "2026-01-01T00:00:00.000Z",
@ -59,7 +59,7 @@ describe("sisyphus-task", () => {
// when / #then // when / #then
expect(category).toBeDefined() expect(category).toBeDefined()
expect(category.model).toBe("openai/gpt-5.2-codex") expect(category.model).toBe("openai/gpt-5.3-codex")
expect(category.variant).toBe("xhigh") expect(category.variant).toBe("xhigh")
}) })
@ -69,7 +69,7 @@ describe("sisyphus-task", () => {
// when / #then // when / #then
expect(category).toBeDefined() expect(category).toBeDefined()
expect(category.model).toBe("openai/gpt-5.2-codex") expect(category.model).toBe("openai/gpt-5.3-codex")
expect(category.variant).toBe("medium") expect(category.variant).toBe("medium")
}) })
}) })
@ -216,7 +216,7 @@ describe("sisyphus-task", () => {
app: { agents: async () => ({ data: [] }) }, app: { agents: async () => ({ data: [] }) },
config: { get: async () => ({}) }, // No model configured config: { get: async () => ({}) }, // No model configured
provider: { list: async () => ({ data: { connected: ["openai"] } }) }, provider: { list: async () => ({ data: { connected: ["openai"] } }) },
model: { list: async () => ({ data: [{ provider: "openai", id: "gpt-5.2-codex" }] }) }, model: { list: async () => ({ data: [{ provider: "openai", id: "gpt-5.3-codex" }] }) },
session: { session: {
create: async () => ({ data: { id: "test-session" } }), create: async () => ({ data: { id: "test-session" } }),
prompt: async () => ({ data: {} }), prompt: async () => ({ data: {} }),
@ -1754,7 +1754,7 @@ describe("sisyphus-task", () => {
abort: new AbortController().signal, abort: new AbortController().signal,
} }
// when - using ultrabrain category (default model is openai/gpt-5.2-codex) // when - using ultrabrain category (default model is openai/gpt-5.3-codex)
await tool.execute( await tool.execute(
{ {
description: "Override precedence test", description: "Override precedence test",
@ -1805,7 +1805,7 @@ describe("sisyphus-task", () => {
client: mockClient, client: mockClient,
sisyphusJuniorModel: "anthropic/claude-sonnet-4-5", sisyphusJuniorModel: "anthropic/claude-sonnet-4-5",
userCategories: { userCategories: {
ultrabrain: { model: "openai/gpt-5.2-codex" }, ultrabrain: { model: "openai/gpt-5.3-codex" },
}, },
}) })
@ -1830,7 +1830,7 @@ describe("sisyphus-task", () => {
// then - explicit category model should win // then - explicit category model should win
expect(launchInput.model.providerID).toBe("openai") expect(launchInput.model.providerID).toBe("openai")
expect(launchInput.model.modelID).toBe("gpt-5.2-codex") expect(launchInput.model.modelID).toBe("gpt-5.3-codex")
}) })
}) })
@ -2083,7 +2083,7 @@ describe("sisyphus-task", () => {
// then - catalog model is used // then - catalog model is used
expect(resolved).not.toBeNull() expect(resolved).not.toBeNull()
expect(resolved!.config.model).toBe("openai/gpt-5.2-codex") expect(resolved!.config.model).toBe("openai/gpt-5.3-codex")
expect(resolved!.config.variant).toBe("xhigh") expect(resolved!.config.variant).toBe("xhigh")
}) })
@ -2107,10 +2107,10 @@ describe("sisyphus-task", () => {
// when // when
const resolved = resolveCategoryConfig(categoryName, { inheritedModel, systemDefaultModel: SYSTEM_DEFAULT_MODEL }) const resolved = resolveCategoryConfig(categoryName, { inheritedModel, systemDefaultModel: SYSTEM_DEFAULT_MODEL })
// then - category's built-in model wins (ultrabrain uses gpt-5.2-codex) // then - category's built-in model wins (ultrabrain uses gpt-5.3-codex)
expect(resolved).not.toBeNull() expect(resolved).not.toBeNull()
const actualModel = resolved!.config.model const actualModel = resolved!.config.model
expect(actualModel).toBe("openai/gpt-5.2-codex") expect(actualModel).toBe("openai/gpt-5.3-codex")
}) })
test("when user defines model - modelInfo should report user-defined regardless of inheritedModel", () => { test("when user defines model - modelInfo should report user-defined regardless of inheritedModel", () => {
@ -2164,12 +2164,12 @@ describe("sisyphus-task", () => {
const categoryName = "ultrabrain" const categoryName = "ultrabrain"
const inheritedModel = "anthropic/claude-opus-4-5" const inheritedModel = "anthropic/claude-opus-4-5"
// when category has a built-in model (gpt-5.2-codex for ultrabrain) // when category has a built-in model (gpt-5.3-codex for ultrabrain)
const resolved = resolveCategoryConfig(categoryName, { inheritedModel, systemDefaultModel: SYSTEM_DEFAULT_MODEL }) const resolved = resolveCategoryConfig(categoryName, { inheritedModel, systemDefaultModel: SYSTEM_DEFAULT_MODEL })
// then category's built-in model should be used, NOT inheritedModel // then category's built-in model should be used, NOT inheritedModel
expect(resolved).not.toBeNull() expect(resolved).not.toBeNull()
expect(resolved!.model).toBe("openai/gpt-5.2-codex") expect(resolved!.model).toBe("openai/gpt-5.3-codex")
}) })
test("FIXED: systemDefaultModel is used when no userConfig.model and no inheritedModel", () => { test("FIXED: systemDefaultModel is used when no userConfig.model and no inheritedModel", () => {