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",
|
"variant": "medium",
|
||||||
},
|
},
|
||||||
"explore": {
|
"explore": {
|
||||||
"model": "opencode/gpt-5-nano",
|
"model": "openai/gpt-5.4",
|
||||||
|
"variant": "medium",
|
||||||
},
|
},
|
||||||
"hephaestus": {
|
"hephaestus": {
|
||||||
"model": "openai/gpt-5.3-codex",
|
"model": "openai/gpt-5.3-codex",
|
||||||
"variant": "medium",
|
"variant": "medium",
|
||||||
},
|
},
|
||||||
"librarian": {
|
"librarian": {
|
||||||
"model": "opencode/glm-4.7-free",
|
"model": "openai/gpt-5.4",
|
||||||
|
"variant": "medium",
|
||||||
},
|
},
|
||||||
"metis": {
|
"metis": {
|
||||||
"model": "openai/gpt-5.4",
|
"model": "openai/gpt-5.4",
|
||||||
@@ -230,12 +232,17 @@ exports[`generateModelConfig single native provider uses OpenAI models when only
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"categories": {
|
"categories": {
|
||||||
|
"artistry": {
|
||||||
|
"model": "openai/gpt-5.4",
|
||||||
|
"variant": "xhigh",
|
||||||
|
},
|
||||||
"deep": {
|
"deep": {
|
||||||
"model": "openai/gpt-5.3-codex",
|
"model": "openai/gpt-5.3-codex",
|
||||||
"variant": "medium",
|
"variant": "medium",
|
||||||
},
|
},
|
||||||
"quick": {
|
"quick": {
|
||||||
"model": "opencode/glm-4.7-free",
|
"model": "openai/gpt-5.3-codex",
|
||||||
|
"variant": "low",
|
||||||
},
|
},
|
||||||
"ultrabrain": {
|
"ultrabrain": {
|
||||||
"model": "openai/gpt-5.3-codex",
|
"model": "openai/gpt-5.3-codex",
|
||||||
@@ -250,10 +257,12 @@ exports[`generateModelConfig single native provider uses OpenAI models when only
|
|||||||
"variant": "medium",
|
"variant": "medium",
|
||||||
},
|
},
|
||||||
"visual-engineering": {
|
"visual-engineering": {
|
||||||
"model": "opencode/glm-4.7-free",
|
"model": "openai/gpt-5.4",
|
||||||
|
"variant": "high",
|
||||||
},
|
},
|
||||||
"writing": {
|
"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",
|
"variant": "medium",
|
||||||
},
|
},
|
||||||
"explore": {
|
"explore": {
|
||||||
"model": "opencode/gpt-5-nano",
|
"model": "openai/gpt-5.4",
|
||||||
|
"variant": "medium",
|
||||||
},
|
},
|
||||||
"hephaestus": {
|
"hephaestus": {
|
||||||
"model": "openai/gpt-5.3-codex",
|
"model": "openai/gpt-5.3-codex",
|
||||||
"variant": "medium",
|
"variant": "medium",
|
||||||
},
|
},
|
||||||
"librarian": {
|
"librarian": {
|
||||||
"model": "opencode/glm-4.7-free",
|
"model": "openai/gpt-5.4",
|
||||||
|
"variant": "medium",
|
||||||
},
|
},
|
||||||
"metis": {
|
"metis": {
|
||||||
"model": "openai/gpt-5.4",
|
"model": "openai/gpt-5.4",
|
||||||
@@ -303,12 +314,17 @@ exports[`generateModelConfig single native provider uses OpenAI models with isMa
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"categories": {
|
"categories": {
|
||||||
|
"artistry": {
|
||||||
|
"model": "openai/gpt-5.4",
|
||||||
|
"variant": "xhigh",
|
||||||
|
},
|
||||||
"deep": {
|
"deep": {
|
||||||
"model": "openai/gpt-5.3-codex",
|
"model": "openai/gpt-5.3-codex",
|
||||||
"variant": "medium",
|
"variant": "medium",
|
||||||
},
|
},
|
||||||
"quick": {
|
"quick": {
|
||||||
"model": "opencode/glm-4.7-free",
|
"model": "openai/gpt-5.3-codex",
|
||||||
|
"variant": "low",
|
||||||
},
|
},
|
||||||
"ultrabrain": {
|
"ultrabrain": {
|
||||||
"model": "openai/gpt-5.3-codex",
|
"model": "openai/gpt-5.3-codex",
|
||||||
@@ -323,10 +339,12 @@ exports[`generateModelConfig single native provider uses OpenAI models with isMa
|
|||||||
"variant": "medium",
|
"variant": "medium",
|
||||||
},
|
},
|
||||||
"visual-engineering": {
|
"visual-engineering": {
|
||||||
"model": "opencode/glm-4.7-free",
|
"model": "openai/gpt-5.4",
|
||||||
|
"variant": "high",
|
||||||
},
|
},
|
||||||
"writing": {
|
"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")
|
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
|
// #given only OpenAI is available
|
||||||
const config = createConfig({ hasOpenAI: true })
|
const config = createConfig({ hasOpenAI: true })
|
||||||
|
|
||||||
// #when generateModelConfig is called
|
// #when generateModelConfig is called
|
||||||
const result = generateModelConfig(config)
|
const result = generateModelConfig(config)
|
||||||
|
|
||||||
// #then explore should use gpt-5-nano (fallback)
|
// #then explore should use native OpenAI model
|
||||||
expect(result.agents?.explore?.model).toBe("opencode/gpt-5-nano")
|
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", () => {
|
test("explore uses gpt-5-mini when only Copilot available", () => {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import {
|
|||||||
import type { InstallConfig } from "./types"
|
import type { InstallConfig } from "./types"
|
||||||
|
|
||||||
import type { AgentConfig, CategoryConfig, GeneratedOmoConfig } from "./model-fallback-types"
|
import type { AgentConfig, CategoryConfig, GeneratedOmoConfig } from "./model-fallback-types"
|
||||||
|
import { applyOpenAiOnlyModelCatalog, isOpenAiOnlyAvailability } from "./openai-only-model-catalog"
|
||||||
import { toProviderAvailability } from "./provider-availability"
|
import { toProviderAvailability } from "./provider-availability"
|
||||||
import {
|
import {
|
||||||
getSisyphusFallbackChain,
|
getSisyphusFallbackChain,
|
||||||
@@ -122,11 +123,15 @@ export function generateModelConfig(config: InstallConfig): GeneratedOmoConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
const generatedConfig: GeneratedOmoConfig = {
|
||||||
$schema: SCHEMA_URL,
|
$schema: SCHEMA_URL,
|
||||||
agents,
|
agents,
|
||||||
categories,
|
categories,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return isOpenAiOnlyAvailability(avail)
|
||||||
|
? applyOpenAiOnlyModelCatalog(generatedConfig)
|
||||||
|
: generatedConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
export function shouldShowChatGPTOnlyWarning(config: InstallConfig): boolean {
|
export function shouldShowChatGPTOnlyWarning(config: InstallConfig): boolean {
|
||||||
|
|||||||
@@ -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" })
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -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