fix(model-fallback): respect user model override for sisyphus-junior category sessions (#2941)

When users configure agents.sisyphus-junior.model, category sessions
should use that model without falling back to hardcoded
AGENT_MODEL_REQUIREMENTS. Two leaks existed:

1. Launch-time: category-resolver.ts did not check overrideModel when
   deciding whether to use the hardcoded fallbackChain. Fixed by adding
   overrideModel to the suppression condition.

2. Runtime retry: model-fallback hook.ts treated undefined fallbackChain
   (from setSessionFallbackChain(id, undefined)) as 'no override' and
   fell through to AGENT_MODEL_REQUIREMENTS on session.error/status
   retry. Fixed by storing explicit empty array and checking .has()
   instead of truthiness.

Tests added:
- hook.test.ts: explicit empty session fallback suppresses agent chain
- event.model-fallback-2941.test.ts: session.error does not arm retry
- category-resolver.test.ts: overrideModel suppresses fallbackChain
- tools.test.ts: sisyphusJuniorModel override assertion
This commit is contained in:
YeonGyu-Kim
2026-04-07 11:20:42 +09:00
parent 12106ffccc
commit 889294a5fd
6 changed files with 222 additions and 4 deletions
+19
View File
@@ -332,6 +332,25 @@ describe("model fallback hook", () => {
clearPendingModelFallback(sessionID)
})
test("does not fall back to hardcoded agent chain when session explicitly stores no fallback chain [regression #2941]", () => {
//#given
const sessionID = "ses_model_fallback_explicit_none"
clearPendingModelFallback(sessionID)
setSessionFallbackChain(sessionID, undefined)
//#when
const set = setPendingModelFallback(
sessionID,
"Sisyphus - Junior",
"anthropic",
"claude-sonnet-4-6",
)
//#then
expect(set).toBe(false)
clearPendingModelFallback(sessionID)
})
test("shows toast when fallback is applied", async () => {
//#given
const toastCalls: Array<{ title: string; message: string }> = []