When provider-models cache is cold (first run / cache miss),
resolveModelForDelegateTask returns {skipped: true}. Previously this
caused the subagent resolver to:
1. Ignore the user's explicit model override (e.g. explore.model)
2. Fall through to the hardcoded fallback chain which may contain
model IDs that don't exist in the provider catalog
Now:
- subagent-resolver: if resolution is skipped but user explicitly
configured a model, use it directly
- subagent-resolver: don't assign hardcoded fallback chain on skip
- category-resolver: same — don't leak hardcoded chain on skip
- general-agents: if user model fails resolution, use it as-is
instead of falling back to hardcoded chain first entry
Closes#2820
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
When a category has no CATEGORY_MODEL_REQUIREMENTS entry (e.g.
user-defined categories like solana-re), the !requirement branch
set actualModel but never built categoryModel with variant from
the user config. The bottom fallback then created categoryModel
via parseModelString alone, silently dropping the variant.
Mirror the requirement branch logic: read variant from
userCategories and resolved.config, and build categoryModel
with it.
Fixes#2538
Allow individual categories to be disabled via `disable: true` in
config. Introduce shared `mergeCategories()` utility to centralize
category merging and disabled filtering across all 7 consumption sites.
OpenCode SDK does not expose client.model.list API. This caused the
provider-models cache to always be empty (models: {}), which in turn
caused delegate-task categories with requiresModel (e.g., 'deep',
'artistry') to fail with misleading 'Unknown category' errors.
Changes:
- connected-providers-cache.ts: Extract models from provider.list()
response's .all array instead of calling non-existent client.model.list
- category-resolver.ts: Distinguish between 'unknown category' and
'model not available' errors with clearer error messages
- Add comprehensive tests for both fixes
Bug chain:
client.model?.list is undefined -> empty cache -> isModelAvailable
returns false for requiresModel categories -> null returned from
resolveCategoryConfig -> 'Unknown category' error (wrong message)
- Create available-models.ts for model availability checking
- Create model-selection.ts for category-to-model resolution logic
- Update category-resolver, subagent-resolver, and sync modules to import
from new focused modules instead of monolithic sources