Split 1021-line index.ts into 10 focused modules per project conventions. New structure: - error-classifier.ts: error analysis with dynamic status code extraction - agent-resolver.ts: agent detection utilities - fallback-state.ts: state management and cooldown logic - fallback-models.ts: model resolution from config - auto-retry.ts: retry helpers with mutual recursion support - event-handler.ts: session lifecycle events - message-update-handler.ts: message.updated event handling - chat-message-handler.ts: chat message interception - hook.ts: main factory with proper cleanup - types.ts: updated with HookDeps interface - index.ts: 2-line barrel re-export Embedded fixes: - Fix setInterval leak with .unref() - Replace require() with ESM import - Add log warning on invalid model format - Update sessionLastAccess on normal traffic - Make extractStatusCode dynamic from config - Remove unused SessionErrorInfo type All 61 tests pass without modification. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
70 lines
2.3 KiB
TypeScript
70 lines
2.3 KiB
TypeScript
import type { OhMyOpenCodeConfig } from "../../config"
|
|
import { AGENT_NAMES, agentPattern } from "./agent-resolver"
|
|
import { HOOK_NAME } from "./constants"
|
|
import { log } from "../../shared/logger"
|
|
import { SessionCategoryRegistry } from "../../shared/session-category-registry"
|
|
import { normalizeFallbackModels } from "../../shared/model-resolver"
|
|
|
|
export function getFallbackModelsForSession(
|
|
sessionID: string,
|
|
agent: string | undefined,
|
|
pluginConfig: OhMyOpenCodeConfig | undefined
|
|
): string[] {
|
|
if (!pluginConfig) return []
|
|
|
|
const sessionCategory = SessionCategoryRegistry.get(sessionID)
|
|
if (sessionCategory && pluginConfig.categories?.[sessionCategory]) {
|
|
const categoryConfig = pluginConfig.categories[sessionCategory]
|
|
if (categoryConfig?.fallback_models) {
|
|
return normalizeFallbackModels(categoryConfig.fallback_models) ?? []
|
|
}
|
|
}
|
|
|
|
const tryGetFallbackFromAgent = (agentName: string): string[] | undefined => {
|
|
const agentConfig = pluginConfig.agents?.[agentName as keyof typeof pluginConfig.agents]
|
|
if (!agentConfig) return undefined
|
|
|
|
if (agentConfig?.fallback_models) {
|
|
return normalizeFallbackModels(agentConfig.fallback_models)
|
|
}
|
|
|
|
const agentCategory = agentConfig?.category
|
|
if (agentCategory && pluginConfig.categories?.[agentCategory]) {
|
|
const categoryConfig = pluginConfig.categories[agentCategory]
|
|
if (categoryConfig?.fallback_models) {
|
|
return normalizeFallbackModels(categoryConfig.fallback_models)
|
|
}
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
const sisyphusFallback = tryGetFallbackFromAgent("sisyphus")
|
|
if (sisyphusFallback) {
|
|
log(`[${HOOK_NAME}] Using sisyphus fallback models (no agent detected)`, { sessionID })
|
|
return sisyphusFallback
|
|
}
|
|
|
|
for (const agentName of AGENT_NAMES) {
|
|
const result = tryGetFallbackFromAgent(agentName)
|
|
if (result) {
|
|
log(`[${HOOK_NAME}] Using ${agentName} fallback models (no agent detected)`, { sessionID })
|
|
return result
|
|
}
|
|
}
|
|
|
|
return []
|
|
}
|