Files
oh-my-opencode/src/hooks/model-fallback/fallback-state-controller.ts
T
YeonGyu-Kim 70ddc01e10 refactor: remove AI slop from refactored files
Behavior-preserving cleanup of AI-generated code smells in 5 files authored/moved by this PR:

- src/hooks/model-fallback/fallback-state-controller.ts (-47/+47 net reorganization, redundant defensiveness removed)
- src/shared/model-string-parser.ts (-4 LOC obvious-comment cleanup)
- src/shared/ripgrep-cli.ts (-13 LOC obvious comments + redundant defensive checks)
- src/tools/delegate-task/tool-description.ts (-6 LOC)
- src/tools/look-at/look-at-input-preparer.ts (-6 LOC)

Targets: obvious comments that restate code, over-defensive null checks on guaranteed values, redundant existence checks. No public API signatures changed, no type hints removed, no new abstractions introduced. Full test suite still passes.
2026-04-18 03:01:51 +09:00

135 lines
4.4 KiB
TypeScript

import type { FallbackEntry } from "../../shared/model-requirements"
import { getAgentConfigKey } from "../../shared/agent-display-names"
import { AGENT_MODEL_REQUIREMENTS } from "../../shared/model-requirements"
import { log } from "../../shared/logger"
import { getNextReachableFallback } from "./next-fallback"
type ModelFallbackStateLike = {
providerID: string
modelID: string
fallbackChain: FallbackEntry[]
attemptCount: number
pending: boolean
}
export type ModelFallbackStateController = {
lastToastKey: Map<string, string>
setSessionFallbackChain: (sessionID: string, fallbackChain: FallbackEntry[] | undefined) => void
clearSessionFallbackChain: (sessionID: string) => void
setPendingModelFallback: (
sessionID: string,
agentName: string,
currentProviderID: string,
currentModelID: string,
) => boolean
getNextFallback: (sessionID: string) => ReturnType<typeof getNextReachableFallback>
clearPendingModelFallback: (sessionID: string) => void
hasPendingModelFallback: (sessionID: string) => boolean
getFallbackState: (sessionID: string) => ModelFallbackStateLike | undefined
reset: () => void
}
export function createModelFallbackStateController(input: {
pendingModelFallbacks: Map<string, ModelFallbackStateLike>
lastToastKey: Map<string, string>
sessionFallbackChains: Map<string, FallbackEntry[]>
}): ModelFallbackStateController {
const { pendingModelFallbacks, lastToastKey, sessionFallbackChains } = input
function setSessionFallbackChain(sessionID: string, fallbackChain: FallbackEntry[] | undefined): void {
if (!sessionID) return
sessionFallbackChains.set(sessionID, fallbackChain?.length ? fallbackChain : [])
}
function clearSessionFallbackChain(sessionID: string): void {
sessionFallbackChains.delete(sessionID)
}
function setPendingModelFallback(
sessionID: string,
agentName: string,
currentProviderID: string,
currentModelID: string,
): boolean {
const agentKey = getAgentConfigKey(agentName)
const requirements = AGENT_MODEL_REQUIREMENTS[agentKey]
const fallbackChain = sessionFallbackChains.get(sessionID) ?? requirements?.fallbackChain
if (!fallbackChain?.length) {
log("[model-fallback] No fallback chain for agent: " + agentName + " (key: " + agentKey + ")")
return false
}
const existing = pendingModelFallbacks.get(sessionID)
if (!existing) {
pendingModelFallbacks.set(sessionID, {
providerID: currentProviderID,
modelID: currentModelID,
fallbackChain,
attemptCount: 0,
pending: true,
})
log("[model-fallback] Set pending fallback for session: " + sessionID + ", agent: " + agentName)
return true
}
if (existing.pending) {
log("[model-fallback] Pending fallback already armed for session: " + sessionID)
return false
}
existing.providerID = currentProviderID
existing.modelID = currentModelID
existing.pending = true
if (existing.attemptCount >= existing.fallbackChain.length) {
log("[model-fallback] Fallback chain exhausted for session: " + sessionID)
return false
}
log("[model-fallback] Re-armed pending fallback for session: " + sessionID)
return true
}
function getNextFallback(sessionID: string): ReturnType<typeof getNextReachableFallback> {
const state = pendingModelFallbacks.get(sessionID)
if (!state?.pending) return null
const fallback = getNextReachableFallback(sessionID, state)
if (fallback) return fallback
log("[model-fallback] No more fallbacks for session: " + sessionID)
pendingModelFallbacks.delete(sessionID)
return null
}
function clearPendingModelFallback(sessionID: string): void {
pendingModelFallbacks.delete(sessionID)
lastToastKey.delete(sessionID)
}
function hasPendingModelFallback(sessionID: string): boolean {
return pendingModelFallbacks.get(sessionID)?.pending === true
}
function getFallbackState(sessionID: string): ModelFallbackStateLike | undefined {
return pendingModelFallbacks.get(sessionID)
}
function reset(): void {
pendingModelFallbacks.clear()
lastToastKey.clear()
sessionFallbackChains.clear()
}
return {
lastToastKey,
setSessionFallbackChain,
clearSessionFallbackChain,
setPendingModelFallback,
getNextFallback,
clearPendingModelFallback,
hasPendingModelFallback,
getFallbackState,
reset,
}
}