fix(cli): preserve installer fallback chains in generated config (#3144)

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
YeonGyu-Kim
2026-04-06 13:17:38 +09:00
parent abda3c52f0
commit 57b152994f
3 changed files with 87 additions and 4 deletions
+48 -4
View File
@@ -2,11 +2,13 @@ import {
CLI_AGENT_MODEL_REQUIREMENTS,
CLI_CATEGORY_MODEL_REQUIREMENTS,
} from "./model-fallback-requirements"
import type { FallbackModelObject } from "../config/schema/fallback-models"
import type { FallbackEntry } from "../shared/model-requirements"
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 { isProviderAvailable, toProviderAvailability } from "./provider-availability"
import {
getSisyphusFallbackChain,
isAnyFallbackEntryAvailable,
@@ -14,6 +16,7 @@ import {
isRequiredProviderAvailable,
resolveModelFromChain,
} from "./fallback-chain-resolution"
import { transformModelForProvider } from "./provider-model-id-transform"
export type { GeneratedOmoConfig } from "./model-fallback-types"
@@ -22,6 +25,44 @@ const ZAI_MODEL = "zai-coding-plan/glm-4.7"
const ULTIMATE_FALLBACK = "opencode/gpt-5-nano"
const SCHEMA_URL = "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-opencode.schema.json"
function toFallbackModelObject(entry: FallbackEntry, provider: string): FallbackModelObject {
return {
model: `${provider}/${transformModelForProvider(provider, entry.model)}`,
...(entry.variant ? { variant: entry.variant } : {}),
...(entry.reasoningEffort ? { reasoningEffort: entry.reasoningEffort as FallbackModelObject["reasoningEffort"] } : {}),
...(entry.temperature !== undefined ? { temperature: entry.temperature } : {}),
...(entry.top_p !== undefined ? { top_p: entry.top_p } : {}),
...(entry.maxTokens !== undefined ? { maxTokens: entry.maxTokens } : {}),
...(entry.thinking ? { thinking: entry.thinking } : {}),
}
}
function attachFallbackModels<T extends AgentConfig | CategoryConfig>(
config: T,
fallbackChain: FallbackEntry[],
availability: ReturnType<typeof toProviderAvailability>,
): T {
const expandedFallbacks = fallbackChain.flatMap((entry) =>
entry.providers
.filter((provider) => isProviderAvailable(provider, availability))
.map((provider) => toFallbackModelObject(entry, provider))
)
const primaryIndex = expandedFallbacks.findIndex((entry) => entry.model === config.model)
if (primaryIndex === -1) {
return config
}
const fallbackModels = expandedFallbacks.slice(primaryIndex + 1)
if (fallbackModels.length === 0) {
return config
}
return {
...config,
fallback_models: fallbackModels,
}
}
export function generateModelConfig(config: InstallConfig): GeneratedOmoConfig {
@@ -85,7 +126,8 @@ export function generateModelConfig(config: InstallConfig): GeneratedOmoConfig {
const resolved = resolveModelFromChain(fallbackChain, avail)
if (resolved) {
const variant = resolved.variant ?? req.variant
agents[role] = variant ? { model: resolved.model, variant } : { model: resolved.model }
const agentConfig = variant ? { model: resolved.model, variant } : { model: resolved.model }
agents[role] = attachFallbackModels(agentConfig, fallbackChain, avail)
}
continue
}
@@ -100,7 +142,8 @@ export function generateModelConfig(config: InstallConfig): GeneratedOmoConfig {
const resolved = resolveModelFromChain(req.fallbackChain, avail)
if (resolved) {
const variant = resolved.variant ?? req.variant
agents[role] = variant ? { model: resolved.model, variant } : { model: resolved.model }
const agentConfig = variant ? { model: resolved.model, variant } : { model: resolved.model }
agents[role] = attachFallbackModels(agentConfig, req.fallbackChain, avail)
} else {
agents[role] = { model: ULTIMATE_FALLBACK }
}
@@ -123,7 +166,8 @@ export function generateModelConfig(config: InstallConfig): GeneratedOmoConfig {
const resolved = resolveModelFromChain(fallbackChain, avail)
if (resolved) {
const variant = resolved.variant ?? req.variant
categories[cat] = variant ? { model: resolved.model, variant } : { model: resolved.model }
const categoryConfig = variant ? { model: resolved.model, variant } : { model: resolved.model }
categories[cat] = attachFallbackModels(categoryConfig, fallbackChain, avail)
} else {
categories[cat] = { model: ULTIMATE_FALLBACK }
}