After the 4.2.0 unified-dispatch refactor (a42f894f / df198d8b / fee515c5 / 989ab717 / dd3fecaf / 1bbe065c / 12bd6580), at least one caller in the new prompt-async-gate path forwards a FallbackModelObject (or some other non-string shape) into parsers that statically claim 'model: string'. The downstream .trim() call then throws 'model.trim is not a function', which rejects the session.processor promise and surfaces as 'Aborted process' + UI 'interrupted'. The issue (#4145) reports this aborts 90% of subagent dispatches across every provider on 4.2.0 + opencode 1.15.4.
This patch adds a 'typeof x !== "string"' runtime guard at the four parser entrypoints called from the dispatch path:
- src/shared/fallback-chain-from-models.ts :: parseVariantFromModel, parseFallbackModelEntry
- src/tools/delegate-task/model-string-parser.ts :: parseVariantFromModelID, parseModelString
- src/shared/model-string-parser.ts (duplicate file with same API) :: parseVariantFromModelID, parseModelString
- src/features/claude-code-agent-loader/claude-model-mapper.ts :: mapClaudeModelString
Each parser now returns undefined / { modelID: "" } for non-string input instead of throwing. This unblocks subagent dispatch and leaves the underlying caller bug for a follow-up.
Regression coverage: three new tests in src/shared/fallback-chain-from-models.test.ts pin the non-string behavior (object, null/undefined, number). Existing 38 tests still pass. Total: 41/41 green, typecheck clean.
The previous commit (2dfa6336f) used 'git add -A' which swept up files that
prior commits had intentionally deleted but were still present untracked in
the local workspace. This commit re-deletes them to match the upstream intent.
Files removed (each was previously deleted in the cited commit):
- drafts/gpt-5-5/{README,deep,hephaestus,oracle,sisyphus-junior,sisyphus}.md
(deleted in 40ded422c chore(drafts): remove stale gpt-5.5 prompt drafts)
- src/plugin-dispose.{ts,test.ts}
(deleted in e2f5c0d36 refactor(plugin): remove orphaned createPluginDispose)
- src/features/tmux-subagent/{cleanup,session-created-handler,session-deleted-handler}.ts
(deleted in 7a7926f22 chore(tmux-subagent): remove dead event-handler modules)
- src/tools/delegate-task/{model-string-parser,resolve-call-id,resolve-call-id.test}.ts
(model-string-parser deleted in db056346d; resolve-call-id was scratch)
- src/__debug-test.test.ts (debug scratch never intended for git)
Typecheck + model-requirements tests still pass. The legitimate metis +
AGENTS.md edits from the previous commit remain on dev.
Source code change:
- src/shared/model-requirements.ts: prepend claude-sonnet-4-6 to metis fallback
chain so Sonnet becomes the default. Opus 4.7 max remains as the immediate
fallback for callers who want extra reasoning.
- src/shared/model-requirements.test.ts: update assertion to expect Sonnet
primary + Opus secondary.
AGENTS.md accuracy fixes (verified against source):
- Agent modes: Sisyphus/Hephaestus are 'primary' (not 'all'); Sisyphus-Junior
is 'subagent' (not 'all'). Confirmed via 'const MODE: AgentMode = ...' in
each agent file. Also clarified Prometheus has no agentSources factory and
is built via buildPrometheusAgentConfig.
- Sisyphus fallback chain: corrected order to kimi-k2.6 → k2p5 → kimi-k2.5
→ gpt-5.5 medium → glm-5 → big-pickle (was missing kimi-k2.5).
- Librarian/Explore: added missing minimax-m2.7 step between -highspeed and
claude-haiku-4-5.
- Metis chain: removed fictitious gemini-3.1-pro entry.
- Sisyphus-Junior chain: spelled out the actual fallback (was 'user-configurable').
- Temperatures: Sisyphus/Hephaestus do not set explicit temperature (model
default); Sisyphus-Junior is 0.1 via SISYPHUS_JUNIOR_DEFAULTS.
- Quick category default: gpt-5.4-mini (not gpt-5.4-mini-fast).
Team-mode corrections:
- Eligibility registry has 3 verdicts: eligible (sisyphus, atlas, sisyphus-junior),
conditional (hephaestus — needs D-36 teammate permission), hard-reject
(oracle, librarian, explore, multimodal-looker, metis, momus, prometheus).
- Schema has 11 fields, not 4: added max_messages_per_run, max_wall_clock_minutes,
max_member_turns, base_dir, message_payload_max_bytes, recipient_unread_max_bytes,
mailbox_poll_interval_ms.
- Hooks: 'team-session-events' is 4 sub-handlers in src/plugin/event.ts
(team-idle-wake-hint, team-lead-orphan-handler, team-member-error-handler,
team-member-status-handler), not a single Continuation-tier hook.
- Tier counts now show base + team-mode: ToolGuard 14/15, Transform 5/7.
- Total: 52 base hooks, 59 with team-mode.
Doc cascade for the Metis change:
- docs/guide/orchestration.md, agent-model-matching.md, installation.md
- docs/reference/configuration.md, features.md
Move parseModelString into src/shared so callers can depend on a neutral module instead of reaching into delegate-task internals.
Cross-tool coupling violates module boundaries, and this keeps call-omo-agent plus runtime-fallback from importing through a sibling tool.
Add support for object-style entries in fallback_models arrays, enabling
per-model configuration of variant, reasoningEffort, temperature, top_p,
maxTokens, and thinking settings.
- Zod schema for FallbackModelObject with full validation
- normalizeFallbackModels() and flattenToFallbackModelStrings() utilities
- Provider-agnostic model resolution pipeline with fallback chain
- Session prompt params state management
- Fallback chain construction with prefix-match lookup
- Integration across delegate-task, background-agent, and plugin layers