Merge pull request #2939 from sjawhar/fix/delegate-task-category-override

fix(delegate-task): replace mutual exclusion throw with category-wins override (#2847)
This commit is contained in:
YeonGyu-Kim
2026-03-29 18:41:48 -07:00
committed by GitHub
2 changed files with 14 additions and 13 deletions
+6 -3
View File
@@ -465,7 +465,7 @@ describe("sisyphus-task", () => {
expect(args.subagent_type).toBe("Sisyphus-Junior") expect(args.subagent_type).toBe("Sisyphus-Junior")
}, { timeout: 10000 }) }, { timeout: 10000 })
test("rejects when both category and subagent_type are provided", async () => { test("prefers category over subagent_type when both are provided", async () => {
//#given //#given
const { createDelegateTask } = require("./tools") const { createDelegateTask } = require("./tools")
@@ -516,8 +516,11 @@ describe("sisyphus-task", () => {
load_skills: [], load_skills: [],
} }
//#when + #then //#when
await expect(tool.execute(args, toolContext)).rejects.toThrow("mutually exclusive") await tool.execute(args, toolContext)
//#then - category takes precedence, subagent_type is overridden to sisyphus-junior
expect(args.subagent_type).toBe("Sisyphus-Junior")
}, { timeout: 10000 }) }, { timeout: 10000 })
test("proceeds without error when systemDefaultModel is undefined", async () => { test("proceeds without error when systemDefaultModel is undefined", async () => {
+8 -10
View File
@@ -109,14 +109,9 @@ export function createDelegateTask(options: DelegateTaskToolOptions): ToolDefini
async execute(args: DelegateTaskArgs, toolContext) { async execute(args: DelegateTaskArgs, toolContext) {
const ctx = toolContext as ToolContextWithMetadata const ctx = toolContext as ToolContextWithMetadata
let categoryOverrideNote: string | undefined
if (args.category && args.subagent_type) { if (args.category && args.subagent_type) {
throw new Error( categoryOverrideNote = `[Note: You provided both category="${args.category}" and subagent_type="${args.subagent_type}". category takes precedence \u2014 subagent_type was ignored. Next time, provide ONLY category.]`
`Invalid arguments: 'category' and 'subagent_type' are mutually exclusive. Provide EXACTLY ONE.\n` +
` - You provided: category="${args.category}", subagent_type="${args.subagent_type}"\n` +
` - Use category for task delegation (e.g., category="${categoryExamples.split(", ")[0]}")\n` +
` - Use subagent_type for direct agent invocation (e.g., subagent_type="explore")\n` +
` - subagent_type must be a callable non-primary agent name returned by app.agents()`
)
} }
if (args.category) { if (args.category) {
args.subagent_type = SISYPHUS_JUNIOR_AGENT args.subagent_type = SISYPHUS_JUNIOR_AGENT
@@ -226,7 +221,8 @@ export function createDelegateTask(options: DelegateTaskToolOptions): ToolDefini
availableCategories, availableCategories,
availableSkills, availableSkills,
}) })
return executeUnstableAgentTask(args, ctx, options, parentContext, agentToUse, categoryModel, systemContent, actualModel) const result = await executeUnstableAgentTask(args, ctx, options, parentContext, agentToUse, categoryModel, systemContent, actualModel)
return categoryOverrideNote ? `${categoryOverrideNote}\n\n${result}` : result
} }
} else { } else {
const resolution = await resolveSubagentExecution(args, options, parentContext.agent, categoryExamples) const resolution = await resolveSubagentExecution(args, options, parentContext.agent, categoryExamples)
@@ -249,11 +245,13 @@ export function createDelegateTask(options: DelegateTaskToolOptions): ToolDefini
availableSkills, availableSkills,
}) })
const prependNote = (result: string) => categoryOverrideNote ? `${categoryOverrideNote}\n\n${result}` : result
if (runInBackground) { if (runInBackground) {
return executeBackgroundTask(args, ctx, options, parentContext, agentToUse, categoryModel, systemContent, fallbackChain) return prependNote(await executeBackgroundTask(args, ctx, options, parentContext, agentToUse, categoryModel, systemContent, fallbackChain))
} }
return executeSyncTask(args, ctx, options, parentContext, agentToUse, categoryModel, systemContent, modelInfo, fallbackChain) return prependNote(await executeSyncTask(args, ctx, options, parentContext, agentToUse, categoryModel, systemContent, modelInfo, fallbackChain))
}, },
}) })
} }