fix(#2735): check model availability before using custom subagent default model

subagent-resolver: when falling back to matchedAgent.model for custom
subagents, verify the model is actually available via fuzzyMatchModel
before setting it as categoryModel. Prevents delegate_task from using
an unavailable model when the user's custom agent config references
a model they don't have access to.

Test updated to include the target model in available models mock.
This commit is contained in:
YeonGyu-Kim
2026-03-27 15:50:16 +09:00
parent 3be26cb97f
commit 3b4420bc23
2 changed files with 63 additions and 3 deletions
+12 -2
View File
@@ -13,6 +13,7 @@ import { log } from "../../shared/logger"
import { getAvailableModelsForDelegateTask } from "./available-models"
import type { FallbackEntry } from "../../shared/model-requirements"
import { resolveModelForDelegateTask } from "./model-selection"
import { fuzzyMatchModel } from "../../shared/model-availability"
export async function resolveSubagentExecution(
args: DelegateTaskArgs,
@@ -109,8 +110,9 @@ Create the work plan directly - that's your job as the planning agent.`,
?? (agentOverride?.category ? userCategories?.[agentOverride.category]?.fallback_models : undefined)
)
const availableModels = await getAvailableModelsForDelegateTask(client)
if (agentOverride?.model || agentCategoryModel || agentRequirement || matchedAgent.model) {
const availableModels = await getAvailableModelsForDelegateTask(client)
const normalizedMatchedModel = matchedAgent.model
? normalizeModelFormat(matchedAgent.model)
@@ -192,7 +194,15 @@ Create the work plan directly - that's your job as the planning agent.`,
if (!categoryModel && matchedAgent.model) {
const normalizedMatchedModel = normalizeModelFormat(matchedAgent.model)
if (normalizedMatchedModel) {
categoryModel = normalizedMatchedModel
const fullModel = `${normalizedMatchedModel.providerID}/${normalizedMatchedModel.modelID}`
if (availableModels.size === 0 || fuzzyMatchModel(fullModel, availableModels, [normalizedMatchedModel.providerID])) {
categoryModel = normalizedMatchedModel
} else {
log("[delegate-task] Skipping unavailable agent default model", {
agent: agentToUse,
model: fullModel,
})
}
}
}
} catch (error) {