fix(cli): prefer mini-fast for install fallback

Default the install-time fallback chain to gpt-5.4-mini-fast for librarian and explore when OpenAI is available.\nKeep the snapshot and catalog tests aligned with the new resolution path.

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
YeonGyu-Kim
2026-04-21 13:30:02 +09:00
parent d2e5ddd73d
commit ceadf4bdbc
4 changed files with 103 additions and 85 deletions
@@ -519,12 +519,31 @@ exports[`generateModelConfig all native providers uses preferred models from fal
"model": "anthropic/claude-sonnet-4-6",
},
"explore": {
"model": "anthropic/claude-haiku-4-5",
"fallback_models": [
{
"model": "anthropic/claude-haiku-4-5",
},
{
"model": "openai/gpt-5.4-nano",
},
],
"model": "openai/gpt-5.4-mini-fast",
},
"hephaestus": {
"model": "openai/gpt-5.4",
"variant": "medium",
},
"librarian": {
"fallback_models": [
{
"model": "anthropic/claude-haiku-4-5",
},
{
"model": "openai/gpt-5.4-nano",
},
],
"model": "openai/gpt-5.4-mini-fast",
},
"metis": {
"fallback_models": [
{
@@ -718,12 +737,31 @@ exports[`generateModelConfig all native providers uses preferred models with isM
"model": "anthropic/claude-sonnet-4-6",
},
"explore": {
"model": "anthropic/claude-haiku-4-5",
"fallback_models": [
{
"model": "anthropic/claude-haiku-4-5",
},
{
"model": "openai/gpt-5.4-nano",
},
],
"model": "openai/gpt-5.4-mini-fast",
},
"hephaestus": {
"model": "openai/gpt-5.4",
"variant": "medium",
},
"librarian": {
"fallback_models": [
{
"model": "anthropic/claude-haiku-4-5",
},
{
"model": "openai/gpt-5.4-nano",
},
],
"model": "openai/gpt-5.4-mini-fast",
},
"metis": {
"fallback_models": [
{
@@ -917,10 +955,7 @@ exports[`generateModelConfig fallback providers uses OpenCode Zen models when on
"explore": {
"fallback_models": [
{
"model": "opencode/minimax-m2.7",
},
{
"model": "opencode/gpt-5-nano",
"model": "opencode/gpt-5.4-nano",
},
],
"model": "opencode/claude-haiku-4-5",
@@ -1142,10 +1177,7 @@ exports[`generateModelConfig fallback providers uses OpenCode Zen models with is
"explore": {
"fallback_models": [
{
"model": "opencode/minimax-m2.7",
},
{
"model": "opencode/gpt-5-nano",
"model": "opencode/gpt-5.4-nano",
},
],
"model": "opencode/claude-haiku-4-5",
@@ -1369,11 +1401,6 @@ exports[`generateModelConfig fallback providers uses GitHub Copilot models when
"model": "github-copilot/claude-sonnet-4.6",
},
"explore": {
"fallback_models": [
{
"model": "github-copilot/grok-code-fast-1",
},
],
"model": "github-copilot/gpt-5-mini",
},
"hephaestus": {
@@ -1555,11 +1582,6 @@ exports[`generateModelConfig fallback providers uses GitHub Copilot models with
"model": "github-copilot/claude-sonnet-4.6",
},
"explore": {
"fallback_models": [
{
"model": "github-copilot/grok-code-fast-1",
},
],
"model": "github-copilot/gpt-5-mini",
},
"hephaestus": {
@@ -1869,14 +1891,11 @@ exports[`generateModelConfig mixed provider scenarios uses Claude + OpenCode Zen
},
"explore": {
"fallback_models": [
{
"model": "opencode/minimax-m2.7",
},
{
"model": "opencode/claude-haiku-4-5",
},
{
"model": "opencode/gpt-5-nano",
"model": "opencode/gpt-5.4-nano",
},
],
"model": "anthropic/claude-haiku-4-5",
@@ -2153,10 +2172,10 @@ exports[`generateModelConfig mixed provider scenarios uses OpenAI + Copilot comb
"explore": {
"fallback_models": [
{
"model": "github-copilot/grok-code-fast-1",
"model": "openai/gpt-5.4-nano",
},
],
"model": "github-copilot/gpt-5-mini",
"model": "openai/gpt-5.4-mini-fast",
},
"hephaestus": {
"fallback_models": [
@@ -2168,6 +2187,14 @@ exports[`generateModelConfig mixed provider scenarios uses OpenAI + Copilot comb
"model": "openai/gpt-5.4",
"variant": "medium",
},
"librarian": {
"fallback_models": [
{
"model": "openai/gpt-5.4-nano",
},
],
"model": "openai/gpt-5.4-mini-fast",
},
"metis": {
"fallback_models": [
{
@@ -2622,13 +2649,7 @@ exports[`generateModelConfig mixed provider scenarios uses all fallback provider
"explore": {
"fallback_models": [
{
"model": "github-copilot/grok-code-fast-1",
},
{
"model": "opencode/minimax-m2.7",
},
{
"model": "opencode/gpt-5-nano",
"model": "opencode/gpt-5.4-nano",
},
],
"model": "opencode/claude-haiku-4-5",
@@ -2645,14 +2666,11 @@ exports[`generateModelConfig mixed provider scenarios uses all fallback provider
},
"librarian": {
"fallback_models": [
{
"model": "opencode/minimax-m2.7-highspeed",
},
{
"model": "opencode/claude-haiku-4-5",
},
{
"model": "opencode/gpt-5-nano",
"model": "opencode/gpt-5.4-nano",
},
],
"model": "zai-coding-plan/glm-4.7",
@@ -3020,19 +3038,19 @@ exports[`generateModelConfig mixed provider scenarios uses all providers togethe
"explore": {
"fallback_models": [
{
"model": "github-copilot/grok-code-fast-1",
},
{
"model": "opencode/minimax-m2.7",
"model": "anthropic/claude-haiku-4-5",
},
{
"model": "opencode/claude-haiku-4-5",
},
{
"model": "opencode/gpt-5-nano",
"model": "openai/gpt-5.4-nano",
},
{
"model": "opencode/gpt-5.4-nano",
},
],
"model": "anthropic/claude-haiku-4-5",
"model": "openai/gpt-5.4-mini-fast",
},
"hephaestus": {
"fallback_models": [
@@ -3050,9 +3068,6 @@ exports[`generateModelConfig mixed provider scenarios uses all providers togethe
},
"librarian": {
"fallback_models": [
{
"model": "opencode/minimax-m2.7-highspeed",
},
{
"model": "anthropic/claude-haiku-4-5",
},
@@ -3060,10 +3075,13 @@ exports[`generateModelConfig mixed provider scenarios uses all providers togethe
"model": "opencode/claude-haiku-4-5",
},
{
"model": "opencode/gpt-5-nano",
"model": "openai/gpt-5.4-nano",
},
{
"model": "opencode/gpt-5.4-nano",
},
],
"model": "zai-coding-plan/glm-4.7",
"model": "openai/gpt-5.4-mini-fast",
},
"metis": {
"fallback_models": [
@@ -3571,19 +3589,19 @@ exports[`generateModelConfig mixed provider scenarios uses all providers with is
"explore": {
"fallback_models": [
{
"model": "github-copilot/grok-code-fast-1",
},
{
"model": "opencode/minimax-m2.7",
"model": "anthropic/claude-haiku-4-5",
},
{
"model": "opencode/claude-haiku-4-5",
},
{
"model": "opencode/gpt-5-nano",
"model": "openai/gpt-5.4-nano",
},
{
"model": "opencode/gpt-5.4-nano",
},
],
"model": "anthropic/claude-haiku-4-5",
"model": "openai/gpt-5.4-mini-fast",
},
"hephaestus": {
"fallback_models": [
@@ -3601,9 +3619,6 @@ exports[`generateModelConfig mixed provider scenarios uses all providers with is
},
"librarian": {
"fallback_models": [
{
"model": "opencode/minimax-m2.7-highspeed",
},
{
"model": "anthropic/claude-haiku-4-5",
},
@@ -3611,10 +3626,13 @@ exports[`generateModelConfig mixed provider scenarios uses all providers with is
"model": "opencode/claude-haiku-4-5",
},
{
"model": "opencode/gpt-5-nano",
"model": "openai/gpt-5.4-nano",
},
{
"model": "opencode/gpt-5.4-nano",
},
],
"model": "zai-coding-plan/glm-4.7",
"model": "openai/gpt-5.4-mini-fast",
},
"metis": {
"fallback_models": [
@@ -4120,9 +4138,6 @@ exports[`generateModelConfig Vercel AI Gateway provider uses vercel/ model strin
},
"explore": {
"fallback_models": [
{
"model": "vercel/xai/grok-code-fast-1",
},
{
"model": "vercel/minimax/minimax-m2.7",
},
@@ -4130,7 +4145,7 @@ exports[`generateModelConfig Vercel AI Gateway provider uses vercel/ model strin
"model": "vercel/anthropic/claude-haiku-4.5",
},
{
"model": "vercel/openai/gpt-5-nano",
"model": "vercel/openai/gpt-5.4-nano",
},
],
"model": "vercel/minimax/minimax-m2.7-highspeed",
@@ -4148,7 +4163,7 @@ exports[`generateModelConfig Vercel AI Gateway provider uses vercel/ model strin
"model": "vercel/anthropic/claude-haiku-4.5",
},
{
"model": "vercel/openai/gpt-5-nano",
"model": "vercel/openai/gpt-5.4-nano",
},
],
"model": "vercel/minimax/minimax-m2.7",
@@ -4413,9 +4428,6 @@ exports[`generateModelConfig Vercel AI Gateway provider uses vercel/ model strin
},
"explore": {
"fallback_models": [
{
"model": "vercel/xai/grok-code-fast-1",
},
{
"model": "vercel/minimax/minimax-m2.7",
},
@@ -4423,7 +4435,7 @@ exports[`generateModelConfig Vercel AI Gateway provider uses vercel/ model strin
"model": "vercel/anthropic/claude-haiku-4.5",
},
{
"model": "vercel/openai/gpt-5-nano",
"model": "vercel/openai/gpt-5.4-nano",
},
],
"model": "vercel/minimax/minimax-m2.7-highspeed",
@@ -4441,7 +4453,7 @@ exports[`generateModelConfig Vercel AI Gateway provider uses vercel/ model strin
"model": "vercel/anthropic/claude-haiku-4.5",
},
{
"model": "vercel/openai/gpt-5-nano",
"model": "vercel/openai/gpt-5.4-nano",
},
],
"model": "vercel/minimax/minimax-m2.7",
+12 -12
View File
@@ -553,15 +553,15 @@ describe("generateModelConfig", () => {
})
describe("special-case agents include fallback_models", () => {
test("explore includes fallback_models when Copilot and Claude are both available", () => {
// #given both Copilot and Claude are available
const config = createConfig({ hasCopilot: true, hasClaude: true })
test("explore includes fallback_models when OpenAI and Claude are both available", () => {
// #given both OpenAI and Claude are available
const config = createConfig({ hasOpenAI: true, hasClaude: true })
// #when generateModelConfig is called
const result = generateModelConfig(config)
// #then explore should have fallback_models from the remaining chain entries
expect(result.agents?.explore?.model).toBe("anthropic/claude-haiku-4-5")
expect(result.agents?.explore?.model).toBe("openai/gpt-5.4-mini-fast")
expect(result.agents?.explore?.fallback_models).toBeDefined()
expect(result.agents?.explore?.fallback_models?.length).toBeGreaterThan(0)
})
@@ -578,28 +578,28 @@ describe("generateModelConfig", () => {
expect(result.agents?.explore?.fallback_models).toBeUndefined()
})
test("librarian includes fallback_models when opencode-go and Claude are both available", () => {
// #given opencode-go and Claude are available
const config = createConfig({ hasOpencodeGo: true, hasClaude: true })
test("librarian includes fallback_models when OpenAI and opencode-go are both available", () => {
// #given OpenAI and opencode-go are available
const config = createConfig({ hasOpenAI: true, hasOpencodeGo: true })
// #when generateModelConfig is called
const result = generateModelConfig(config)
// #then librarian should have fallback_models
expect(result.agents?.librarian?.model).toBe("opencode-go/minimax-m2.7")
expect(result.agents?.librarian?.model).toBe("openai/gpt-5.4-mini-fast")
expect(result.agents?.librarian?.fallback_models).toBeDefined()
expect(result.agents?.librarian?.fallback_models?.length).toBeGreaterThan(0)
})
test("librarian omits fallback_models when only one provider matches", () => {
// #given only opencode-go is available
const config = createConfig({ hasOpencodeGo: true })
test("librarian omits fallback_models when only ZAI is available", () => {
// #given only ZAI is available
const config = createConfig({ hasZaiCodingPlan: true })
// #when generateModelConfig is called
const result = generateModelConfig(config)
// #then librarian should not have fallback_models
expect(result.agents?.librarian?.model).toBe("opencode-go/minimax-m2.7")
expect(result.agents?.librarian?.model).toBe("zai-coding-plan/glm-4.7")
expect(result.agents?.librarian?.fallback_models).toBeUndefined()
})
})
+6 -2
View File
@@ -127,7 +127,9 @@ export function generateModelConfig(config: InstallConfig): GeneratedOmoConfig {
for (const [role, req] of Object.entries(CLI_AGENT_MODEL_REQUIREMENTS)) {
if (role === "librarian") {
let agentConfig: AgentConfig | undefined
if (avail.opencodeGo) {
if (avail.native.openai) {
agentConfig = { model: "openai/gpt-5.4-mini-fast" }
} else if (avail.opencodeGo) {
agentConfig = { model: "opencode-go/minimax-m2.7" }
} else if (avail.zai) {
agentConfig = { model: ZAI_MODEL }
@@ -142,7 +144,9 @@ export function generateModelConfig(config: InstallConfig): GeneratedOmoConfig {
if (role === "explore") {
let agentConfig: AgentConfig
if (avail.native.claude) {
if (avail.native.openai) {
agentConfig = { model: "openai/gpt-5.4-mini-fast" }
} else if (avail.native.claude) {
agentConfig = { model: "anthropic/claude-haiku-4-5" }
} else if (avail.opencodeZen) {
agentConfig = { model: "opencode/claude-haiku-4-5" }
+4 -2
View File
@@ -54,8 +54,10 @@ describe("generateModelConfig OpenAI-only model catalog", () => {
const result = generateModelConfig(config)
// #then
expect(result.agents?.explore).toMatchObject({ model: "opencode-go/minimax-m2.7" })
expect(result.agents?.librarian).toMatchObject({ model: "opencode-go/minimax-m2.7" })
expect(result.agents?.explore).toMatchObject({ model: "openai/gpt-5.4-mini-fast" })
expect(result.agents?.librarian).toMatchObject({ model: "openai/gpt-5.4-mini-fast" })
expect(result.agents?.explore).not.toMatchObject({ variant: "medium" })
expect(result.agents?.librarian).not.toMatchObject({ variant: "medium" })
expect(result.categories?.quick).toMatchObject({ model: "openai/gpt-5.4-mini" })
})
})