fix(model-resolution): honor user config overrides on cold cache
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
This commit is contained in:
@@ -78,12 +78,16 @@ export function collectPendingBuiltinAgents(input: {
|
|||||||
})
|
})
|
||||||
if (!resolution) {
|
if (!resolution) {
|
||||||
if (override?.model) {
|
if (override?.model) {
|
||||||
log("[agent-registration] User-configured model could not be resolved, falling back", {
|
// User explicitly configured a model but resolution failed (e.g., cold cache).
|
||||||
|
// Honor the user's choice directly instead of falling back to hardcoded chain.
|
||||||
|
log("[agent-registration] User-configured model not resolved, using as-is", {
|
||||||
agent: agentName,
|
agent: agentName,
|
||||||
configuredModel: override.model,
|
configuredModel: override.model,
|
||||||
})
|
})
|
||||||
|
resolution = { model: override.model, provenance: "override" as const }
|
||||||
|
} else {
|
||||||
|
resolution = getFirstFallbackModel(requirement)
|
||||||
}
|
}
|
||||||
resolution = getFirstFallbackModel(requirement)
|
|
||||||
}
|
}
|
||||||
if (!resolution) continue
|
if (!resolution) continue
|
||||||
const { model, variant: resolvedVariant } = resolution
|
const { model, variant: resolvedVariant } = resolution
|
||||||
|
|||||||
@@ -239,6 +239,7 @@ Available categories: ${categoryNames.join(", ")}`,
|
|||||||
modelInfo,
|
modelInfo,
|
||||||
actualModel,
|
actualModel,
|
||||||
isUnstableAgent,
|
isUnstableAgent,
|
||||||
fallbackChain: configuredFallbackChain ?? requirement?.fallbackChain,
|
// Don't use hardcoded fallback chain when resolution was skipped (cold cache)
|
||||||
|
fallbackChain: configuredFallbackChain ?? (isModelResolutionSkipped ? undefined : requirement?.fallbackChain),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -125,12 +125,26 @@ Create the work plan directly - that's your job as the planning agent.`,
|
|||||||
systemDefaultModel: undefined,
|
systemDefaultModel: undefined,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (resolution && !('skipped' in resolution)) {
|
const resolutionSkipped = resolution && 'skipped' in resolution
|
||||||
|
|
||||||
|
if (resolution && !resolutionSkipped) {
|
||||||
const normalized = normalizeModelFormat(resolution.model)
|
const normalized = normalizeModelFormat(resolution.model)
|
||||||
if (normalized) {
|
if (normalized) {
|
||||||
const variantToUse = agentOverride?.variant ?? resolution.variant
|
const variantToUse = agentOverride?.variant ?? resolution.variant
|
||||||
categoryModel = variantToUse ? { ...normalized, variant: variantToUse } : normalized
|
categoryModel = variantToUse ? { ...normalized, variant: variantToUse } : normalized
|
||||||
}
|
}
|
||||||
|
} else if (resolutionSkipped && agentOverride?.model) {
|
||||||
|
// Cold cache: resolution was skipped but user explicitly configured a model.
|
||||||
|
// Honor the user override directly — don't fall through to hardcoded fallback chain.
|
||||||
|
const normalized = normalizeModelFormat(agentOverride.model)
|
||||||
|
if (normalized) {
|
||||||
|
const variantToUse = agentOverride?.variant
|
||||||
|
categoryModel = variantToUse ? { ...normalized, variant: variantToUse } : normalized
|
||||||
|
log("[delegate-task] Cold cache: using explicit user override for subagent", {
|
||||||
|
agent: agentToUse,
|
||||||
|
model: agentOverride.model,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultProviderID = categoryModel?.providerID
|
const defaultProviderID = categoryModel?.providerID
|
||||||
@@ -140,7 +154,9 @@ Create the work plan directly - that's your job as the planning agent.`,
|
|||||||
normalizedAgentFallbackModels,
|
normalizedAgentFallbackModels,
|
||||||
defaultProviderID,
|
defaultProviderID,
|
||||||
)
|
)
|
||||||
fallbackChain = configuredFallbackChain ?? agentRequirement?.fallbackChain
|
// Don't assign hardcoded fallback chain when resolution was skipped (cold cache)
|
||||||
|
// — the chain may contain model IDs that don't exist in the provider yet.
|
||||||
|
fallbackChain = configuredFallbackChain ?? (resolutionSkipped ? undefined : agentRequirement?.fallbackChain)
|
||||||
|
|
||||||
// Only promote fallback-only settings when resolution actually selected a fallback model.
|
// Only promote fallback-only settings when resolution actually selected a fallback model.
|
||||||
const resolvedFallbackEntry = (resolution && !('skipped' in resolution)) ? resolution.fallbackEntry : undefined
|
const resolvedFallbackEntry = (resolution && !('skipped' in resolution)) ? resolution.fallbackEntry : undefined
|
||||||
|
|||||||
Reference in New Issue
Block a user