diff --git a/.changeset/prevent-subagent-questions.md b/.changeset/prevent-subagent-questions.md new file mode 100644 index 00000000000..e953140748f --- /dev/null +++ b/.changeset/prevent-subagent-questions.md @@ -0,0 +1,6 @@ +--- +"@kilocode/cli": patch +"kilo-code": patch +--- + +Prevent task subagents from asking questions that users cannot answer from the parent session. diff --git a/packages/opencode/src/kilocode/tool/task.ts b/packages/opencode/src/kilocode/tool/task.ts index 5f2be34b315..ea61421eb72 100644 --- a/packages/opencode/src/kilocode/tool/task.ts +++ b/packages/opencode/src/kilocode/tool/task.ts @@ -61,7 +61,11 @@ export namespace KiloTask { /** Extra permission rules appended to subagent sessions */ export function permissions(rules: Permission.Ruleset): Permission.Ruleset { - return [{ permission: "task", pattern: "*", action: "deny" }, ...rules] + return [ + { permission: "task", pattern: "*", action: "deny" }, + { permission: "question", pattern: "*", action: "deny" }, + ...rules, + ] } export function merge(...rulesets: Permission.Ruleset[]): Permission.Ruleset { diff --git a/packages/opencode/src/tool/task.ts b/packages/opencode/src/tool/task.ts index aa074dea264..7d948bd858a 100644 --- a/packages/opencode/src/tool/task.ts +++ b/packages/opencode/src/tool/task.ts @@ -247,6 +247,7 @@ export const TaskTool = Tool.define( variant, // kilocode_change agent: next.name, tools: { + question: false, // kilocode_change - subagents cannot prompt the user directly ...(canTodo ? {} : { todowrite: false }), ...(canTask ? {} : { task: false }), ...Object.fromEntries((cfg.experimental?.primary_tools ?? []).map((item) => [item, false])), diff --git a/packages/opencode/test/kilocode/task-nesting.test.ts b/packages/opencode/test/kilocode/task-nesting.test.ts index 912e4b554e3..2a8751e16f5 100644 --- a/packages/opencode/test/kilocode/task-nesting.test.ts +++ b/packages/opencode/test/kilocode/task-nesting.test.ts @@ -155,7 +155,7 @@ describe("Kilo task nesting", () => { ), ) - it.live("disables nested task tool even when global task permission allows it", () => + it.live("disables nested task and question tools even when global permissions allow them", () => provideTmpdirInstance( () => Effect.gen(function* () { @@ -186,6 +186,7 @@ describe("Kilo task nesting", () => { const child = yield* sessions.get(result.metadata.sessionId) expect(seen?.tools?.task).toBe(false) + expect(seen?.tools?.question).toBe(false) expect(child.permission).toEqual( expect.arrayContaining([ { @@ -193,6 +194,11 @@ describe("Kilo task nesting", () => { pattern: "*", action: "deny", }, + { + permission: "question", + pattern: "*", + action: "deny", + }, ]), ) }), @@ -200,6 +206,7 @@ describe("Kilo task nesting", () => { config: { permission: { task: "allow", + question: "allow", }, }, }, diff --git a/packages/opencode/test/tool/task.test.ts b/packages/opencode/test/tool/task.test.ts index 32e9d18d623..21eca940144 100644 --- a/packages/opencode/test/tool/task.test.ts +++ b/packages/opencode/test/tool/task.test.ts @@ -484,6 +484,7 @@ describe("tool.task", () => { ) // kilocode_change end expect(seen?.tools).toEqual({ + question: false, // kilocode_change - subagents cannot prompt the user directly todowrite: false, task: false, // kilocode_change - Kilo disallows nested subagents bash: false,