Tune OpenAI-only model catalog variants
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -195,14 +195,16 @@ exports[`generateModelConfig single native provider uses OpenAI models when only
|
||||
"variant": "medium",
|
||||
},
|
||||
"explore": {
|
||||
"model": "opencode/gpt-5-nano",
|
||||
"model": "openai/gpt-5.4",
|
||||
"variant": "medium",
|
||||
},
|
||||
"hephaestus": {
|
||||
"model": "openai/gpt-5.3-codex",
|
||||
"variant": "medium",
|
||||
},
|
||||
"librarian": {
|
||||
"model": "opencode/glm-4.7-free",
|
||||
"model": "openai/gpt-5.4",
|
||||
"variant": "medium",
|
||||
},
|
||||
"metis": {
|
||||
"model": "openai/gpt-5.4",
|
||||
@@ -230,12 +232,17 @@ exports[`generateModelConfig single native provider uses OpenAI models when only
|
||||
},
|
||||
},
|
||||
"categories": {
|
||||
"artistry": {
|
||||
"model": "openai/gpt-5.4",
|
||||
"variant": "xhigh",
|
||||
},
|
||||
"deep": {
|
||||
"model": "openai/gpt-5.3-codex",
|
||||
"variant": "medium",
|
||||
},
|
||||
"quick": {
|
||||
"model": "opencode/glm-4.7-free",
|
||||
"model": "openai/gpt-5.3-codex",
|
||||
"variant": "low",
|
||||
},
|
||||
"ultrabrain": {
|
||||
"model": "openai/gpt-5.3-codex",
|
||||
@@ -250,10 +257,12 @@ exports[`generateModelConfig single native provider uses OpenAI models when only
|
||||
"variant": "medium",
|
||||
},
|
||||
"visual-engineering": {
|
||||
"model": "opencode/glm-4.7-free",
|
||||
"model": "openai/gpt-5.4",
|
||||
"variant": "high",
|
||||
},
|
||||
"writing": {
|
||||
"model": "opencode/glm-4.7-free",
|
||||
"model": "openai/gpt-5.4",
|
||||
"variant": "medium",
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -268,14 +277,16 @@ exports[`generateModelConfig single native provider uses OpenAI models with isMa
|
||||
"variant": "medium",
|
||||
},
|
||||
"explore": {
|
||||
"model": "opencode/gpt-5-nano",
|
||||
"model": "openai/gpt-5.4",
|
||||
"variant": "medium",
|
||||
},
|
||||
"hephaestus": {
|
||||
"model": "openai/gpt-5.3-codex",
|
||||
"variant": "medium",
|
||||
},
|
||||
"librarian": {
|
||||
"model": "opencode/glm-4.7-free",
|
||||
"model": "openai/gpt-5.4",
|
||||
"variant": "medium",
|
||||
},
|
||||
"metis": {
|
||||
"model": "openai/gpt-5.4",
|
||||
@@ -303,12 +314,17 @@ exports[`generateModelConfig single native provider uses OpenAI models with isMa
|
||||
},
|
||||
},
|
||||
"categories": {
|
||||
"artistry": {
|
||||
"model": "openai/gpt-5.4",
|
||||
"variant": "xhigh",
|
||||
},
|
||||
"deep": {
|
||||
"model": "openai/gpt-5.3-codex",
|
||||
"variant": "medium",
|
||||
},
|
||||
"quick": {
|
||||
"model": "opencode/glm-4.7-free",
|
||||
"model": "openai/gpt-5.3-codex",
|
||||
"variant": "low",
|
||||
},
|
||||
"ultrabrain": {
|
||||
"model": "openai/gpt-5.3-codex",
|
||||
@@ -323,10 +339,12 @@ exports[`generateModelConfig single native provider uses OpenAI models with isMa
|
||||
"variant": "medium",
|
||||
},
|
||||
"visual-engineering": {
|
||||
"model": "opencode/glm-4.7-free",
|
||||
"model": "openai/gpt-5.4",
|
||||
"variant": "high",
|
||||
},
|
||||
"writing": {
|
||||
"model": "opencode/glm-4.7-free",
|
||||
"model": "openai/gpt-5.4",
|
||||
"variant": "medium",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -344,15 +344,16 @@ describe("generateModelConfig", () => {
|
||||
expect(result.agents?.explore?.model).toBe("anthropic/claude-haiku-4-5")
|
||||
})
|
||||
|
||||
test("explore uses gpt-5-nano when only OpenAI available", () => {
|
||||
test("explore uses OpenAI model when only OpenAI available", () => {
|
||||
// #given only OpenAI is available
|
||||
const config = createConfig({ hasOpenAI: true })
|
||||
|
||||
// #when generateModelConfig is called
|
||||
const result = generateModelConfig(config)
|
||||
|
||||
// #then explore should use gpt-5-nano (fallback)
|
||||
expect(result.agents?.explore?.model).toBe("opencode/gpt-5-nano")
|
||||
// #then explore should use native OpenAI model
|
||||
expect(result.agents?.explore?.model).toBe("openai/gpt-5.4")
|
||||
expect(result.agents?.explore?.variant).toBe("medium")
|
||||
})
|
||||
|
||||
test("explore uses gpt-5-mini when only Copilot available", () => {
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
import type { InstallConfig } from "./types"
|
||||
|
||||
import type { AgentConfig, CategoryConfig, GeneratedOmoConfig } from "./model-fallback-types"
|
||||
import { applyOpenAiOnlyModelCatalog, isOpenAiOnlyAvailability } from "./openai-only-model-catalog"
|
||||
import { toProviderAvailability } from "./provider-availability"
|
||||
import {
|
||||
getSisyphusFallbackChain,
|
||||
@@ -122,11 +123,15 @@ export function generateModelConfig(config: InstallConfig): GeneratedOmoConfig {
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
const generatedConfig: GeneratedOmoConfig = {
|
||||
$schema: SCHEMA_URL,
|
||||
agents,
|
||||
categories,
|
||||
}
|
||||
|
||||
return isOpenAiOnlyAvailability(avail)
|
||||
? applyOpenAiOnlyModelCatalog(generatedConfig)
|
||||
: generatedConfig
|
||||
}
|
||||
|
||||
export function shouldShowChatGPTOnlyWarning(config: InstallConfig): boolean {
|
||||
|
||||
46
src/cli/openai-only-model-catalog.test.ts
Normal file
46
src/cli/openai-only-model-catalog.test.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import { describe, expect, test } from "bun:test"
|
||||
|
||||
import { generateModelConfig } from "./model-fallback"
|
||||
import type { InstallConfig } from "./types"
|
||||
|
||||
function createConfig(overrides: Partial<InstallConfig> = {}): InstallConfig {
|
||||
return {
|
||||
hasClaude: false,
|
||||
isMax20: false,
|
||||
hasOpenAI: false,
|
||||
hasGemini: false,
|
||||
hasCopilot: false,
|
||||
hasOpencodeZen: false,
|
||||
hasZaiCodingPlan: false,
|
||||
hasKimiForCoding: false,
|
||||
...overrides,
|
||||
}
|
||||
}
|
||||
|
||||
describe("generateModelConfig OpenAI-only model catalog", () => {
|
||||
test("fills remaining OpenAI-only agent gaps with OpenAI models", () => {
|
||||
// #given
|
||||
const config = createConfig({ hasOpenAI: true })
|
||||
|
||||
// #when
|
||||
const result = generateModelConfig(config)
|
||||
|
||||
// #then
|
||||
expect(result.agents?.explore).toEqual({ model: "openai/gpt-5.4", variant: "medium" })
|
||||
expect(result.agents?.librarian).toEqual({ model: "openai/gpt-5.4", variant: "medium" })
|
||||
})
|
||||
|
||||
test("fills remaining OpenAI-only category gaps with OpenAI models", () => {
|
||||
// #given
|
||||
const config = createConfig({ hasOpenAI: true })
|
||||
|
||||
// #when
|
||||
const result = generateModelConfig(config)
|
||||
|
||||
// #then
|
||||
expect(result.categories?.artistry).toEqual({ model: "openai/gpt-5.4", variant: "xhigh" })
|
||||
expect(result.categories?.quick).toEqual({ model: "openai/gpt-5.3-codex", variant: "low" })
|
||||
expect(result.categories?.["visual-engineering"]).toEqual({ model: "openai/gpt-5.4", variant: "high" })
|
||||
expect(result.categories?.writing).toEqual({ model: "openai/gpt-5.4", variant: "medium" })
|
||||
})
|
||||
})
|
||||
39
src/cli/openai-only-model-catalog.ts
Normal file
39
src/cli/openai-only-model-catalog.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import type { AgentConfig, CategoryConfig, GeneratedOmoConfig, ProviderAvailability } from "./model-fallback-types"
|
||||
|
||||
const OPENAI_ONLY_AGENT_OVERRIDES: Record<string, AgentConfig> = {
|
||||
explore: { model: "openai/gpt-5.4", variant: "medium" },
|
||||
librarian: { model: "openai/gpt-5.4", variant: "medium" },
|
||||
}
|
||||
|
||||
const OPENAI_ONLY_CATEGORY_OVERRIDES: Record<string, CategoryConfig> = {
|
||||
artistry: { model: "openai/gpt-5.4", variant: "xhigh" },
|
||||
quick: { model: "openai/gpt-5.3-codex", variant: "low" },
|
||||
"visual-engineering": { model: "openai/gpt-5.4", variant: "high" },
|
||||
writing: { model: "openai/gpt-5.4", variant: "medium" },
|
||||
}
|
||||
|
||||
export function isOpenAiOnlyAvailability(availability: ProviderAvailability): boolean {
|
||||
return (
|
||||
availability.native.openai &&
|
||||
!availability.native.claude &&
|
||||
!availability.native.gemini &&
|
||||
!availability.opencodeZen &&
|
||||
!availability.copilot &&
|
||||
!availability.zai &&
|
||||
!availability.kimiForCoding
|
||||
)
|
||||
}
|
||||
|
||||
export function applyOpenAiOnlyModelCatalog(config: GeneratedOmoConfig): GeneratedOmoConfig {
|
||||
return {
|
||||
...config,
|
||||
agents: {
|
||||
...config.agents,
|
||||
...OPENAI_ONLY_AGENT_OVERRIDES,
|
||||
},
|
||||
categories: {
|
||||
...config.categories,
|
||||
...OPENAI_ONLY_CATEGORY_OVERRIDES,
|
||||
},
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user