fix(delegate-task): honor user fallback_models when category primary is unreachable#3982
Merged
code-yeongyu merged 1 commit intoMay 15, 2026
Conversation
…is unreachable
resolveModelForDelegateTask returned input.userModel immediately without
availability checking when it was set, silently ignoring the user's
configured fallback_models. Effect: a team-mode category member
(e.g. hyperplan's 'artistry' category) configured with
{ model: "opencode/gemini-3.1-pro", fallback_models: [...] }
spawned with the unreachable primary even though a listed fallback was
reachable, leading to a dropped/broken team member instead of graceful
degradation.
Now, when the provider-models cache is warm AND userFallbackModels is
non-empty, the function verifies userModel is reachable via
fuzzyMatchModel. If not, it iterates userFallbackModels and promotes the
first reachable entry. Cold-cache (first-run) behavior is preserved -
the userModel is returned as-is when availability data is unavailable,
matching the existing 'trust the user' contract covered by the
pre-cache test fixtures.
Adds three regression tests covering: (1) unreachable primary + reachable
fallback -> fallback promoted, (2) reachable primary + reachable fallback
-> primary kept (fast path), (3) unreachable primary + unreachable
fallback -> legacy trust-user behavior preserved.
There was a problem hiding this comment.
No issues found across 2 files
Confidence score: 5/5
- Automated review surfaced no issues in the provided summaries.
- No files require special attention.
Auto-approved: The change is tightly scoped with three regression tests that verify all paths—primary reachable, fallback promoted when primary is unreachable, and fallback untouched when no fallback is reachable—while preserving cold-cache behavior, so there is no risk of regression.
This was referenced May 15, 2026
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes a silent-failure path in
resolveModelForDelegateTaskwhere a user-configuredcategories.*.modelthat is not reachable on the user's connected providers was returned verbatim, bypassing the user's ownfallback_modelsarray. The team-mode category member (e.g. hyperplan'sartistry) then spawned targeting an unreachable model.The bug
src/tools/delegate-task/model-selection.ts, lines 57-64 (pre-patch):The moment
input.userModelwas set, the function returned it immediately — never checking reachability againstinput.availableModels, never iteratinginput.userFallbackModels. For a user with:… and a provider set that includes
openai+amazon-bedrockbut notopencode-hosted gemini, the team member was launched againstopencode/gemini-3.1-proand the user's carefully-authored fallbacks were silently ignored. Runtime-fallback can't intercept this either because the provider rejects the model up-front.The fix
When the provider-models cache is warm (
availableModels.size > 0) AND the user providedfallback_models, we now:fuzzyMatchModel. If yes → return it (fast path, identical to old behavior).userFallbackModelsand promote the first reachable entry, withmatchedFallback: true.userResultas-is — preserving the legacy "trust the user" behavior.Cold-cache first-run behavior is untouched (
size > 0guard). The existing pre-cache test atmodel-selection.test.ts:42-55still passes unchanged — deliberate: on first run we have no authoritative availability data and must honor user intent.Tests
Three new regression cases in
model-selection.test.ts:#when user primary model is unreachable and user fallback_models are provided→#then promotes the first reachable user fallback#then keeps the user primary when it IS reachable (fast path preserved)#then returns the user primary as-is when no user fallback is reachable either (trust-user legacy behavior)Verification
User impact
Users who observed hyperplan (or any team-mode category spawn) silently running with fewer members than requested — because one member's primary model wasn't reachable — will now see that member resolve via their configured fallbacks. No config change required on the user side; existing
fallback_modelsentries now work as documented.Need help on this PR? Tag
@codesmithwith what you need.Summary by cubic
Fixes model selection so user
fallback_modelsare used when the category’s primary model isn’t available on connected providers. This prevents team members from spawning with unreachable models and restores graceful fallback.resolveModelForDelegateTask, when availability data exists anduserFallbackModelsare set, verify the primary; if unreachable, promote the first reachable fallback and setmatchedFallback: true.Written for commit 711b753. Summary will update on new commits.