Explorar o código

tighten subtask worker prompts

alvinreal hai 2 meses
pai
achega
caa7f6b558

+ 2 - 1
src/tools/subtask/command.test.ts

@@ -21,7 +21,8 @@ describe('createSubtaskCommandManager', () => {
 
     const commands = config.command as Record<string, { template: string }>;
     expect(commands.subtask).toBeDefined();
-    expect(commands.subtask.template).toContain('subtask');
+    expect(commands.subtask.template).toContain('focused subtask worker');
+    expect(commands.subtask.template).toContain('Do not broaden it');
     expect(commands.subtask.template).toContain('$ARGUMENTS');
   });
 

+ 14 - 5
src/tools/subtask/command.ts

@@ -14,14 +14,23 @@ const COMMAND_NAME = 'subtask';
  * The subtask command template that guides the AI in generating subtask
  * prompts.
  */
-const SUBTASK_COMMAND_TEMPLATE = `Start a subtask worker session.
+const SUBTASK_COMMAND_TEMPLATE = `Start a focused subtask worker.
 
-Use the user's request below as the source of truth for what the worker should do. Keep scope and emphasis exactly aligned with the user's request.
+The user's request below is the full scope for the worker. Do not broaden it.
+Create a self-contained worker prompt that includes:
+- the exact objective
+- relevant context from this conversation
+- specific files/paths that matter
+- expected deliverables
+- validation the worker should run, if applicable
 
-USER: $ARGUMENTS
+USER REQUEST:
+$ARGUMENTS
 
-Call subtask with the worker prompt and any clearly relevant files:
-\`subtask(prompt="...", files=["src/foo.ts", "src/bar.ts", ...])\``;
+Then call the subtask tool:
+\`subtask(prompt="...", files=["src/foo.ts", "docs/bar.md"])\`
+
+Only include files that are clearly relevant. If no files are needed, omit files.`;
 
 /**
  * Creates a subtask command manager.

+ 6 - 1
src/tools/subtask/tools.test.ts

@@ -74,12 +74,17 @@ describe('subtask tool', () => {
       expect(promptCall.path.id).toBe('ses_new');
       expect(promptCall.body.agent).toBe('orchestrator');
       expect(promptCall.body.tools).toBeUndefined();
+      const workerPrompt = String(promptCall.body.parts[0]?.text);
       expect(promptCall.body.parts[0]).toMatchObject({
         type: 'text',
         text: expect.stringContaining(
-          'Work on behalf of parent session ses_old',
+          'You are a subtask worker spawned by parent session ses_old',
         ),
       });
+      expect(workerPrompt).toContain('Your job is bounded');
+      expect(workerPrompt).toContain('TASK:');
+      expect(workerPrompt).toContain('FILES PROVIDED:');
+      expect(workerPrompt).toContain('<subtask_summary>');
       expect(promptCall.body.parts).toContainEqual(
         expect.objectContaining({ synthetic: true, type: 'text' }),
       );

+ 8 - 4
src/tools/subtask/tools.ts

@@ -61,7 +61,11 @@ export function createSubtaskTool(
         return `Subtask worker blocked: max subagent depth ${depthTracker.maxDepth} would be exceeded.`;
       }
 
-      const sessionReference = `Work on behalf of parent session ${sessionID}. When you lack specific information you can use read_session to get it.`;
+      const sessionReference = `You are a subtask worker spawned by parent session ${sessionID}.
+
+Your job is bounded: complete only the task below. Do not expand scope.
+If needed context is missing, use read_session to inspect the parent session.
+Do not spawn another subtask.`;
       const files = new Set([
         ...parseFileReferences(args.prompt),
         ...(args.files ?? []).map((file) => file.replace(/^@/, '')),
@@ -69,8 +73,8 @@ export function createSubtaskTool(
       const fileRefs =
         files.size > 0 ? [...files].map((f) => `@${f}`).join(' ') : '';
       const fullPrompt = fileRefs
-        ? `${sessionReference}\n\n${fileRefs}\n\n${args.prompt}`
-        : `${sessionReference}\n\n${args.prompt}`;
+        ? `${sessionReference}\n\nTASK:\n${args.prompt}\n\nFILES PROVIDED:\n${fileRefs}`
+        : `${sessionReference}\n\nTASK:\n${args.prompt}`;
 
       let childSessionID: string | undefined;
       try {
@@ -115,7 +119,7 @@ export function createSubtaskTool(
               parts: [
                 {
                   type: 'text',
-                  text: `${fullPrompt}\n\nDo the requested work. When finished, return a concise summary of what you did, files changed, validation run, and any remaining risks or follow-up. Let the user's prompt determine scope and emphasis.`,
+                  text: `${fullPrompt}\n\nInstructions:\n1. Understand the task and relevant file context.\n2. Make only necessary changes.\n3. Run the most relevant validation checks when practical.\n4. Stop when the requested task is done.\n\nReturn your final response in this format:\n\n<subtask_summary>\nStatus: completed | blocked | partial\n\nWhat changed:\n- ...\n\nFiles touched:\n- ...\n\nValidation:\n- ...\n\nRisks / follow-up:\n- ...\n</subtask_summary>`,
                 },
                 ...(await buildSyntheticFileParts(directory, files)),
               ],