From 7269671c23a8edc94f22f6189a87f998d144ebbb Mon Sep 17 00:00:00 2001 From: hannesrudolph Date: Wed, 6 Aug 2025 16:11:51 -0700 Subject: [PATCH] fix: make new_task tool definition dynamic based on experimental setting - Tool description now changes based on newTaskRequireTodos setting - When disabled: shows todos as (optional) - When enabled: shows todos as (required) with no mention of configuration - Added tests to verify dynamic behavior - Ensures AI models get unambiguous instructions based on current settings --- .../prompts/tools/__tests__/new-task.spec.ts | 98 +++++++++++++++++++ src/core/prompts/tools/new-task.ts | 10 +- 2 files changed, 104 insertions(+), 4 deletions(-) create mode 100644 src/core/prompts/tools/__tests__/new-task.spec.ts diff --git a/src/core/prompts/tools/__tests__/new-task.spec.ts b/src/core/prompts/tools/__tests__/new-task.spec.ts new file mode 100644 index 0000000000..1d70d809a7 --- /dev/null +++ b/src/core/prompts/tools/__tests__/new-task.spec.ts @@ -0,0 +1,98 @@ +import { describe, it, expect } from "vitest" +import { getNewTaskDescription } from "../new-task" +import { ToolArgs } from "../types" + +describe("getNewTaskDescription", () => { + it("should show todos as optional when experiment is disabled", () => { + const args: ToolArgs = { + cwd: "/test", + supportsComputerUse: false, + experiments: { + newTaskRequireTodos: false, + }, + } + + const description = getNewTaskDescription(args) + + // Check that todos is marked as optional + expect(description).toContain("todos: (optional)") + expect(description).toContain("optional initial todo list") + + // Should not contain any mention of required + expect(description).not.toContain("todos: (required)") + }) + + it("should show todos as required when experiment is enabled", () => { + const args: ToolArgs = { + cwd: "/test", + supportsComputerUse: false, + experiments: { + newTaskRequireTodos: true, + }, + } + + const description = getNewTaskDescription(args) + + // Check that todos is marked as required + expect(description).toContain("todos: (required)") + expect(description).toContain("and initial todo list") + + // Should not contain any mention of optional for todos + expect(description).not.toContain("todos: (optional)") + expect(description).not.toContain("optional initial todo list") + }) + + it("should default to optional when experiments is undefined", () => { + const args: ToolArgs = { + cwd: "/test", + supportsComputerUse: false, + experiments: undefined, + } + + const description = getNewTaskDescription(args) + + // Check that todos is marked as optional by default + expect(description).toContain("todos: (optional)") + expect(description).toContain("optional initial todo list") + }) + + it("should default to optional when newTaskRequireTodos is undefined", () => { + const args: ToolArgs = { + cwd: "/test", + supportsComputerUse: false, + experiments: {}, + } + + const description = getNewTaskDescription(args) + + // Check that todos is marked as optional by default + expect(description).toContain("todos: (optional)") + expect(description).toContain("optional initial todo list") + }) + + it("should always include the example with todos", () => { + const argsWithExperimentOff: ToolArgs = { + cwd: "/test", + supportsComputerUse: false, + experiments: { + newTaskRequireTodos: false, + }, + } + + const argsWithExperimentOn: ToolArgs = { + cwd: "/test", + supportsComputerUse: false, + experiments: { + newTaskRequireTodos: true, + }, + } + + const descriptionOff = getNewTaskDescription(argsWithExperimentOff) + const descriptionOn = getNewTaskDescription(argsWithExperimentOn) + + // Both should include the example with todos + const examplePattern = /\s*\[\s*\]\s*Set up auth middleware/s + expect(descriptionOff).toMatch(examplePattern) + expect(descriptionOn).toMatch(examplePattern) + }) +}) diff --git a/src/core/prompts/tools/new-task.ts b/src/core/prompts/tools/new-task.ts index 37a0a7783e..f1806bb4e0 100644 --- a/src/core/prompts/tools/new-task.ts +++ b/src/core/prompts/tools/new-task.ts @@ -1,14 +1,16 @@ import { ToolArgs } from "./types" -export function getNewTaskDescription(_args: ToolArgs): string { +export function getNewTaskDescription(args: ToolArgs): string { + const todosRequired = args.experiments?.newTaskRequireTodos === true + const todosStatus = todosRequired ? "(required)" : "(optional)" + return `## new_task -Description: This will let you create a new task instance in the chosen mode using your provided message and optional initial todo list. +Description: This will let you create a new task instance in the chosen mode using your provided message${todosRequired ? " and initial todo list" : " and optional initial todo list"}. Parameters: - mode: (required) The slug of the mode to start the new task in (e.g., "code", "debug", "architect"). - message: (required) The initial user message or instructions for this new task. -- todos: (optional by default, can be required via experimental setting) The initial todo list in markdown checklist format for the new task. - Note: The 'todos' parameter can be configured to be required through the experimental setting 'newTaskRequireTodos'. +- todos: ${todosStatus} The initial todo list in markdown checklist format for the new task. Usage: