chore: update gpt-5.2-codex references to gpt-5.3-codex
This commit is contained in:
@@ -204,8 +204,8 @@ oh-my-opencode/
|
||||
|
||||
| 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) |
|
||||
| Hephaestus | openai/gpt-5.2-codex | Autonomous deep worker, "The Legitimate Craftsman" (requires gpt-5.2-codex, no fallback) |
|
||||
| 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.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) |
|
||||
| oracle | openai/gpt-5.2 | Consultation, debugging |
|
||||
| librarian | zai-coding-plan/glm-4.7 | Docs, GitHub search (fallback: glm-4.7-free) |
|
||||
|
||||
@@ -22,8 +22,8 @@ A Category is an agent configuration preset optimized for specific domains.
|
||||
| Category | Default Model | Use Cases |
|
||||
|----------|---------------|-----------|
|
||||
| `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 |
|
||||
| `deep` | `openai/gpt-5.2-codex` (medium) | Goal-oriented autonomous problem-solving. Thorough research before action. For hairy problems requiring deep understanding. |
|
||||
| `ultrabrain` | `openai/gpt-5.3-codex` (xhigh) | Deep logical reasoning, complex architecture decisions requiring extensive analysis |
|
||||
| `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 |
|
||||
| `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 |
|
||||
|
||||
@@ -725,7 +725,7 @@ All 7 categories come with optimal model defaults, but **you must configure them
|
||||
| Category | Built-in Default Model | Description |
|
||||
| -------------------- | ---------------------------------- | -------------------------------------------------------------------- |
|
||||
| `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 |
|
||||
| `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 |
|
||||
@@ -768,7 +768,7 @@ All 7 categories come with optimal model defaults, but **you must configure them
|
||||
"model": "google/gemini-3-pro-preview"
|
||||
},
|
||||
"ultrabrain": {
|
||||
"model": "openai/gpt-5.2-codex",
|
||||
"model": "openai/gpt-5.3-codex",
|
||||
"variant": "xhigh"
|
||||
},
|
||||
"artistry": {
|
||||
@@ -911,8 +911,8 @@ Categories follow the same resolution logic:
|
||||
| Category | Model (no prefix) | Provider Priority Chain |
|
||||
|----------|-------------------|-------------------------|
|
||||
| **visual-engineering** | `gemini-3-pro` | google → anthropic → zai-coding-plan |
|
||||
| **ultrabrain** | `gpt-5.2-codex` | openai → google → anthropic |
|
||||
| **deep** | `gpt-5.2-codex` | openai → anthropic → google |
|
||||
| **ultrabrain** | `gpt-5.3-codex` | openai → google → anthropic |
|
||||
| **deep** | `gpt-5.3-codex` | openai → anthropic → google |
|
||||
| **artistry** | `gemini-3-pro` | google → anthropic → openai |
|
||||
| **quick** | `claude-haiku-4-5` | anthropic → google → opencode |
|
||||
| **unspecified-low** | `claude-sonnet-4-5` | anthropic → openai → google |
|
||||
|
||||
@@ -10,8 +10,8 @@ Oh-My-OpenCode provides 11 specialized AI agents. Each has distinct expertise, o
|
||||
|
||||
| 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. |
|
||||
| **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). |
|
||||
| **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.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. |
|
||||
| **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. |
|
||||
|
||||
@@ -33,8 +33,8 @@ agents/
|
||||
## AGENT MODELS
|
||||
| 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) |
|
||||
| Hephaestus | openai/gpt-5.2-codex | 0.1 | Autonomous deep worker, "The Legitimate Craftsman" (requires gpt-5.2-codex, no fallback) |
|
||||
| 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.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) |
|
||||
| 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) |
|
||||
|
||||
@@ -263,7 +263,7 @@ describe("createBuiltinAgents with requiresProvider gating (hephaestus)", () =>
|
||||
test("hephaestus is created when openai provider is connected", async () => {
|
||||
// #given - openai provider has models available
|
||||
const fetchSpy = spyOn(shared, "fetchAvailableModels").mockResolvedValue(
|
||||
new Set(["openai/gpt-5.2-codex"])
|
||||
new Set(["openai/gpt-5.3-codex"])
|
||||
)
|
||||
|
||||
try {
|
||||
@@ -280,7 +280,7 @@ describe("createBuiltinAgents with requiresProvider gating (hephaestus)", () =>
|
||||
test("hephaestus is created when github-copilot provider is connected", async () => {
|
||||
// #given - github-copilot provider has models available
|
||||
const fetchSpy = spyOn(shared, "fetchAvailableModels").mockResolvedValue(
|
||||
new Set(["github-copilot/gpt-5.2-codex"])
|
||||
new Set(["github-copilot/gpt-5.3-codex"])
|
||||
)
|
||||
|
||||
try {
|
||||
@@ -297,7 +297,7 @@ describe("createBuiltinAgents with requiresProvider gating (hephaestus)", () =>
|
||||
test("hephaestus is created when opencode provider is connected", async () => {
|
||||
// #given - opencode provider has models available
|
||||
const fetchSpy = spyOn(shared, "fetchAvailableModels").mockResolvedValue(
|
||||
new Set(["opencode/gpt-5.2-codex"])
|
||||
new Set(["opencode/gpt-5.3-codex"])
|
||||
)
|
||||
|
||||
try {
|
||||
@@ -322,7 +322,7 @@ describe("createBuiltinAgents with requiresProvider gating (hephaestus)", () =>
|
||||
|
||||
// #then
|
||||
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 {
|
||||
cacheSpy.mockRestore()
|
||||
fetchSpy.mockRestore()
|
||||
@@ -572,7 +572,7 @@ describe("buildAgent with category and skills", () => {
|
||||
const agent = buildAgent(source["test-agent"], TEST_MODEL)
|
||||
|
||||
// #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.prompt).toContain("Role: Designer-Turned-Developer")
|
||||
expect(agent.prompt).toContain("Task description")
|
||||
@@ -685,9 +685,9 @@ describe("override.category expansion in createBuiltinAgents", () => {
|
||||
// #when
|
||||
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.model).toBe("openai/gpt-5.2-codex")
|
||||
expect(agents.oracle.model).toBe("openai/gpt-5.3-codex")
|
||||
expect(agents.oracle.variant).toBe("xhigh")
|
||||
})
|
||||
|
||||
@@ -754,9 +754,9 @@ describe("override.category expansion in createBuiltinAgents", () => {
|
||||
// #when
|
||||
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.model).toBe("openai/gpt-5.2-codex")
|
||||
expect(agents.sisyphus.model).toBe("openai/gpt-5.3-codex")
|
||||
expect(agents.sisyphus.variant).toBe("xhigh")
|
||||
})
|
||||
|
||||
@@ -769,9 +769,9 @@ describe("override.category expansion in createBuiltinAgents", () => {
|
||||
// #when
|
||||
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.model).toBe("openai/gpt-5.2-codex")
|
||||
expect(agents.atlas.model).toBe("openai/gpt-5.3-codex")
|
||||
expect(agents.atlas.variant).toBe("xhigh")
|
||||
})
|
||||
|
||||
|
||||
@@ -417,7 +417,7 @@ describe("generateModelConfig", () => {
|
||||
const result = generateModelConfig(config)
|
||||
|
||||
// #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")
|
||||
})
|
||||
|
||||
@@ -429,7 +429,7 @@ describe("generateModelConfig", () => {
|
||||
const result = generateModelConfig(config)
|
||||
|
||||
// #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")
|
||||
})
|
||||
|
||||
@@ -441,7 +441,7 @@ describe("generateModelConfig", () => {
|
||||
const result = generateModelConfig(config)
|
||||
|
||||
// #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")
|
||||
})
|
||||
|
||||
|
||||
@@ -295,7 +295,7 @@ describe("Prometheus category config resolution", () => {
|
||||
|
||||
// then
|
||||
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")
|
||||
})
|
||||
|
||||
@@ -355,7 +355,7 @@ describe("Prometheus category config resolution", () => {
|
||||
|
||||
// then - falls back to DEFAULT_CATEGORIES
|
||||
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")
|
||||
})
|
||||
|
||||
|
||||
@@ -113,9 +113,9 @@ describe("resolveVariantForModel", () => {
|
||||
})
|
||||
|
||||
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 model = { providerID: "openai", modelID: "gpt-5.2-codex" }
|
||||
const model = { providerID: "openai", modelID: "gpt-5.3-codex" }
|
||||
|
||||
// #when
|
||||
const variant = resolveVariantForModel(config, "hephaestus", model)
|
||||
@@ -179,7 +179,7 @@ describe("resolveVariantForModel", () => {
|
||||
"custom-agent": { category: "ultrabrain" },
|
||||
},
|
||||
} as OhMyOpenCodeConfig
|
||||
const model = { providerID: "openai", modelID: "gpt-5.2-codex" }
|
||||
const model = { providerID: "openai", modelID: "gpt-5.3-codex" }
|
||||
|
||||
// when
|
||||
const variant = resolveVariantForModel(config, "custom-agent", model)
|
||||
|
||||
@@ -67,7 +67,7 @@ describe("fetchAvailableModels", () => {
|
||||
model: {
|
||||
list: async () => ({
|
||||
data: [
|
||||
{ id: "gpt-5.2-codex", provider: "openai" },
|
||||
{ id: "gpt-5.3-codex", provider: "openai" },
|
||||
{ id: "gemini-3-pro", provider: "google" },
|
||||
],
|
||||
}),
|
||||
@@ -77,7 +77,7 @@ describe("fetchAvailableModels", () => {
|
||||
const result = await fetchAvailableModels(client)
|
||||
|
||||
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)
|
||||
})
|
||||
|
||||
@@ -96,7 +96,7 @@ describe("fetchAvailableModels", () => {
|
||||
model: {
|
||||
list: async () => ({
|
||||
data: [
|
||||
{ id: "gpt-5.2-codex", provider: "openai" },
|
||||
{ id: "gpt-5.3-codex", provider: "openai" },
|
||||
{ id: "gemini-3-pro", provider: "google" },
|
||||
],
|
||||
}),
|
||||
@@ -106,7 +106,7 @@ describe("fetchAvailableModels", () => {
|
||||
const result = await fetchAvailableModels(client, { connectedProviders: ["openai", "google"] })
|
||||
|
||||
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)
|
||||
})
|
||||
|
||||
@@ -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 () => {
|
||||
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" } } },
|
||||
google: { id: "google", models: { "gemini-3-flash": { id: "gemini-3-flash" } } },
|
||||
opencode: { id: "opencode", models: { "gpt-5-nano": { id: "gpt-5-nano" } } },
|
||||
@@ -145,7 +145,7 @@ describe("fetchAvailableModels", () => {
|
||||
})
|
||||
|
||||
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("google/gemini-3-flash")).toBe(true)
|
||||
expect(result.has("opencode/gpt-5-nano")).toBe(true)
|
||||
@@ -159,7 +159,7 @@ describe("fuzzyMatchModel", () => {
|
||||
it("should match substring in model name", () => {
|
||||
const available = new Set([
|
||||
"openai/gpt-5.2",
|
||||
"openai/gpt-5.2-codex",
|
||||
"openai/gpt-5.3-codex",
|
||||
"anthropic/claude-opus-4-5",
|
||||
])
|
||||
const result = fuzzyMatchModel("gpt-5.2", available)
|
||||
@@ -185,7 +185,7 @@ describe("fuzzyMatchModel", () => {
|
||||
it("should prefer exact match over substring match", () => {
|
||||
const available = new Set([
|
||||
"openai/gpt-5.2",
|
||||
"openai/gpt-5.2-codex",
|
||||
"openai/gpt-5.3-codex",
|
||||
"openai/gpt-5.2-ultra",
|
||||
])
|
||||
const result = fuzzyMatchModel("gpt-5.2", available)
|
||||
@@ -794,10 +794,10 @@ describe("fetchAvailableModels with provider-models cache (whitelist-filtered)",
|
||||
describe("isModelAvailable", () => {
|
||||
it("returns true when model exists via fuzzy match", () => {
|
||||
// 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
|
||||
const result = isModelAvailable("gpt-5.2-codex", available)
|
||||
const result = isModelAvailable("gpt-5.3-codex", available)
|
||||
|
||||
// then
|
||||
expect(result).toBe(true)
|
||||
@@ -808,7 +808,7 @@ describe("isModelAvailable", () => {
|
||||
const available = new Set(["anthropic/claude-opus-4-5"])
|
||||
|
||||
// when
|
||||
const result = isModelAvailable("gpt-5.2-codex", available)
|
||||
const result = isModelAvailable("gpt-5.3-codex", available)
|
||||
|
||||
// then
|
||||
expect(result).toBe(false)
|
||||
@@ -819,7 +819,7 @@ describe("isModelAvailable", () => {
|
||||
const available = new Set<string>()
|
||||
|
||||
// when
|
||||
const result = isModelAvailable("gpt-5.2-codex", available)
|
||||
const result = isModelAvailable("gpt-5.3-codex", available)
|
||||
|
||||
// then
|
||||
expect(result).toBe(false)
|
||||
|
||||
@@ -20,7 +20,7 @@ import { readProviderModelsCache, hasProviderModelsCache, readConnectedProviders
|
||||
* If providers array is given, only models starting with "provider/" are considered.
|
||||
*
|
||||
* @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("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)
|
||||
*
|
||||
* @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
|
||||
* @returns true if model is available, false otherwise
|
||||
*/
|
||||
|
||||
@@ -224,35 +224,35 @@ describe("AGENT_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
|
||||
const ultrabrain = CATEGORY_MODEL_REQUIREMENTS["ultrabrain"]
|
||||
|
||||
// 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.fallbackChain).toBeArray()
|
||||
expect(ultrabrain.fallbackChain.length).toBeGreaterThan(0)
|
||||
|
||||
const primary = ultrabrain.fallbackChain[0]
|
||||
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")
|
||||
})
|
||||
|
||||
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
|
||||
const deep = CATEGORY_MODEL_REQUIREMENTS["deep"]
|
||||
|
||||
// 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.fallbackChain).toBeArray()
|
||||
expect(deep.fallbackChain.length).toBeGreaterThan(0)
|
||||
|
||||
const primary = deep.fallbackChain[0]
|
||||
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")
|
||||
})
|
||||
|
||||
@@ -480,12 +480,12 @@ describe("ModelRequirement type", () => {
|
||||
})
|
||||
|
||||
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
|
||||
const deep = CATEGORY_MODEL_REQUIREMENTS["deep"]
|
||||
|
||||
// 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", () => {
|
||||
|
||||
@@ -26,7 +26,7 @@ export const AGENT_MODEL_REQUIREMENTS: Record<string, ModelRequirement> = {
|
||||
},
|
||||
hephaestus: {
|
||||
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"],
|
||||
},
|
||||
@@ -113,7 +113,7 @@ export const CATEGORY_MODEL_REQUIREMENTS: Record<string, ModelRequirement> = {
|
||||
},
|
||||
ultrabrain: {
|
||||
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: ["anthropic"], model: "claude-opus-4-6", 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: {
|
||||
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", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" },
|
||||
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro", variant: "high" },
|
||||
],
|
||||
requiresModel: "gpt-5.2-codex",
|
||||
requiresModel: "gpt-5.3-codex",
|
||||
},
|
||||
artistry: {
|
||||
fallbackChain: [
|
||||
@@ -147,7 +147,7 @@ export const CATEGORY_MODEL_REQUIREMENTS: Record<string, ModelRequirement> = {
|
||||
"unspecified-low": {
|
||||
fallbackChain: [
|
||||
{ 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" },
|
||||
],
|
||||
},
|
||||
|
||||
@@ -194,8 +194,8 @@ You are NOT an interactive assistant. You are an autonomous problem-solver.
|
||||
|
||||
export const DEFAULT_CATEGORIES: Record<string, CategoryConfig> = {
|
||||
"visual-engineering": { model: "google/gemini-3-pro" },
|
||||
ultrabrain: { model: "openai/gpt-5.2-codex", variant: "xhigh" },
|
||||
deep: { model: "openai/gpt-5.2-codex", variant: "medium" },
|
||||
ultrabrain: { model: "openai/gpt-5.3-codex", variant: "xhigh" },
|
||||
deep: { model: "openai/gpt-5.3-codex", variant: "medium" },
|
||||
artistry: { model: "google/gemini-3-pro", variant: "high" },
|
||||
quick: { model: "anthropic/claude-haiku-4-5" },
|
||||
"unspecified-low": { model: "anthropic/claude-sonnet-4-5" },
|
||||
@@ -343,7 +343,7 @@ FOR EVERY TASK, YOU MUST RECOMMEND:
|
||||
| Category | Best For | Model |
|
||||
|----------|----------|-------|
|
||||
| \`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 |
|
||||
| \`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 |
|
||||
|
||||
@@ -30,7 +30,7 @@ describe("sisyphus-task", () => {
|
||||
models: {
|
||||
anthropic: ["claude-opus-4-5", "claude-sonnet-4-5", "claude-haiku-4-5"],
|
||||
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"],
|
||||
updatedAt: "2026-01-01T00:00:00.000Z",
|
||||
@@ -59,7 +59,7 @@ describe("sisyphus-task", () => {
|
||||
|
||||
// when / #then
|
||||
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")
|
||||
})
|
||||
|
||||
@@ -69,7 +69,7 @@ describe("sisyphus-task", () => {
|
||||
|
||||
// when / #then
|
||||
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")
|
||||
})
|
||||
})
|
||||
@@ -216,7 +216,7 @@ describe("sisyphus-task", () => {
|
||||
app: { agents: async () => ({ data: [] }) },
|
||||
config: { get: async () => ({}) }, // No model configured
|
||||
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: {
|
||||
create: async () => ({ data: { id: "test-session" } }),
|
||||
prompt: async () => ({ data: {} }),
|
||||
@@ -1754,7 +1754,7 @@ describe("sisyphus-task", () => {
|
||||
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(
|
||||
{
|
||||
description: "Override precedence test",
|
||||
@@ -1805,7 +1805,7 @@ describe("sisyphus-task", () => {
|
||||
client: mockClient,
|
||||
sisyphusJuniorModel: "anthropic/claude-sonnet-4-5",
|
||||
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
|
||||
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
|
||||
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")
|
||||
})
|
||||
|
||||
@@ -2107,10 +2107,10 @@ describe("sisyphus-task", () => {
|
||||
// when
|
||||
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()
|
||||
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", () => {
|
||||
@@ -2164,12 +2164,12 @@ describe("sisyphus-task", () => {
|
||||
const categoryName = "ultrabrain"
|
||||
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 })
|
||||
|
||||
// then category's built-in model should be used, NOT inheritedModel
|
||||
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", () => {
|
||||
|
||||
Reference in New Issue
Block a user