2026-02-17 16:29:52 -05:00
|
|
|
import type { OhMyOpenCodeConfig } from "../../config"
|
2026-03-18 14:21:27 +01:00
|
|
|
import type { FallbackModelObject } from "../../config/schema/fallback-models"
|
2026-03-04 20:25:25 +01:00
|
|
|
import { agentPattern } from "./agent-resolver"
|
2026-02-17 16:29:52 -05:00
|
|
|
import { HOOK_NAME } from "./constants"
|
|
|
|
|
import { log } from "../../shared/logger"
|
|
|
|
|
import { SessionCategoryRegistry } from "../../shared/session-category-registry"
|
2026-03-18 14:21:27 +01:00
|
|
|
import { normalizeFallbackModels, flattenToFallbackModelStrings } from "../../shared/model-resolver"
|
2026-02-17 16:29:52 -05:00
|
|
|
|
2026-03-18 14:21:27 +01:00
|
|
|
/**
|
|
|
|
|
* Returns fallback model strings for the runtime-fallback system.
|
|
|
|
|
* Object entries are flattened to "provider/model(variant)" strings so the
|
|
|
|
|
* string-based fallback state machine can work with them unchanged.
|
|
|
|
|
*/
|
2026-02-17 16:29:52 -05:00
|
|
|
export function getFallbackModelsForSession(
|
|
|
|
|
sessionID: string,
|
|
|
|
|
agent: string | undefined,
|
|
|
|
|
pluginConfig: OhMyOpenCodeConfig | undefined
|
|
|
|
|
): string[] {
|
|
|
|
|
if (!pluginConfig) return []
|
|
|
|
|
|
2026-03-18 14:21:27 +01:00
|
|
|
const raw = getRawFallbackModelsForSession(sessionID, agent, pluginConfig)
|
|
|
|
|
return flattenToFallbackModelStrings(raw) ?? []
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns the raw fallback model entries (strings and objects) for a session.
|
|
|
|
|
* Use this when per-model settings (temperature, reasoningEffort, etc.) must be
|
|
|
|
|
* preserved — e.g. before passing to buildFallbackChainFromModels.
|
|
|
|
|
*/
|
|
|
|
|
export function getRawFallbackModels(
|
|
|
|
|
sessionID: string,
|
|
|
|
|
agent: string | undefined,
|
|
|
|
|
pluginConfig: OhMyOpenCodeConfig | undefined,
|
|
|
|
|
): (string | FallbackModelObject)[] | undefined {
|
|
|
|
|
if (!pluginConfig) return undefined
|
|
|
|
|
return getRawFallbackModelsForSession(sessionID, agent, pluginConfig)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getRawFallbackModelsForSession(
|
|
|
|
|
sessionID: string,
|
|
|
|
|
agent: string | undefined,
|
|
|
|
|
pluginConfig: OhMyOpenCodeConfig,
|
|
|
|
|
): (string | FallbackModelObject)[] | undefined {
|
2026-02-17 16:29:52 -05:00
|
|
|
const sessionCategory = SessionCategoryRegistry.get(sessionID)
|
|
|
|
|
if (sessionCategory && pluginConfig.categories?.[sessionCategory]) {
|
|
|
|
|
const categoryConfig = pluginConfig.categories[sessionCategory]
|
|
|
|
|
if (categoryConfig?.fallback_models) {
|
2026-03-18 14:21:27 +01:00
|
|
|
return normalizeFallbackModels(categoryConfig.fallback_models)
|
2026-02-17 16:29:52 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-18 14:21:27 +01:00
|
|
|
const tryGetFallbackFromAgent = (agentName: string): (string | FallbackModelObject)[] | undefined => {
|
2026-02-17 16:29:52 -05:00
|
|
|
const agentConfig = pluginConfig.agents?.[agentName as keyof typeof pluginConfig.agents]
|
|
|
|
|
if (!agentConfig) return undefined
|
2026-03-18 14:21:27 +01:00
|
|
|
|
2026-02-17 16:29:52 -05:00
|
|
|
if (agentConfig?.fallback_models) {
|
|
|
|
|
return normalizeFallbackModels(agentConfig.fallback_models)
|
|
|
|
|
}
|
2026-03-18 14:21:27 +01:00
|
|
|
|
2026-02-17 16:29:52 -05:00
|
|
|
const agentCategory = agentConfig?.category
|
|
|
|
|
if (agentCategory && pluginConfig.categories?.[agentCategory]) {
|
|
|
|
|
const categoryConfig = pluginConfig.categories[agentCategory]
|
|
|
|
|
if (categoryConfig?.fallback_models) {
|
|
|
|
|
return normalizeFallbackModels(categoryConfig.fallback_models)
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-03-18 14:21:27 +01:00
|
|
|
|
2026-02-17 16:29:52 -05:00
|
|
|
return undefined
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (agent) {
|
|
|
|
|
const result = tryGetFallbackFromAgent(agent)
|
|
|
|
|
if (result) return result
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const sessionAgentMatch = sessionID.match(agentPattern)
|
|
|
|
|
if (sessionAgentMatch) {
|
|
|
|
|
const detectedAgent = sessionAgentMatch[1].toLowerCase()
|
|
|
|
|
const result = tryGetFallbackFromAgent(detectedAgent)
|
|
|
|
|
if (result) return result
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-04 20:25:25 +01:00
|
|
|
log(`[${HOOK_NAME}] No category/agent fallback models resolved for session`, { sessionID, agent })
|
2026-02-17 16:29:52 -05:00
|
|
|
|
2026-03-18 14:21:27 +01:00
|
|
|
return undefined
|
2026-02-17 16:29:52 -05:00
|
|
|
}
|