fix: plan tasks after initial exploration

This commit is contained in:
lesetong
2026-08-24 09:58:33 +08:00
parent 7783e7166a
commit ff497e23b3
3 changed files with 12 additions and 10 deletions
+1 -1
View File
@@ -47,7 +47,7 @@ pi remove npm:pi-todo-herdr
## Usage ## Usage
For large, multi-stage work, the extension instructs Pi to call `set_tasks` before exploration as the only tool in the first batch. Smaller work remains untracked. Pi then updates task states at each real transition instead of reconstructing progress at the end. For work with three or more distinct steps, the extension instructs Pi to explore enough to understand the scope, then call `set_tasks` before implementation. Smaller work remains untracked. Pi then updates task states at each real transition instead of reconstructing progress at the end.
After automatic or manual context compaction, the extension sends one short hidden reminder only when unfinished tasks exist. Pi calls `list_task` to recover the authoritative current IDs and statuses; the full tree is not injected on every model call. After automatic or manual context compaction, the extension sends one short hidden reminder only when unfinished tasks exist. Pi calls `list_task` to recover the authoritative current IDs and statuses; the full tree is not injected on every model call.
+2 -2
View File
@@ -6,8 +6,8 @@ export const COMPACTION_REMINDER =
"Active tasks exist. Call list_task now; treat its result as authoritative."; "Active tasks exist. Call list_task now; treat its result as authoritative.";
export const TASK_PROMPT_GUIDELINES = [ export const TASK_PROMPT_GUIDELINES = [
"For large, multi-stage work, call set_tasks before exploration as the only first-batch tool. Use append with force false by default; use replace with force true only for explicitly abandoned unfinished work. Start one task in-progress; skip smaller work.", "For work with 3+ distinct steps, explore enough to understand the scope, then call set_tasks before implementation; otherwise skip tracking. Start one task in-progress.",
"Use update_task when tracked work starts, blocks, or finishes; reconcile the tree before the final response.", "Use update_task when tasks start, block, or finish; keep statuses accurate before the final response.",
]; ];
export function formatCompactTaskTree(tasks: Task[]): string { export function formatCompactTaskTree(tasks: Task[]): string {
+9 -7
View File
@@ -10,15 +10,17 @@ import {
} from "../src/prompt.ts"; } from "../src/prompt.ts";
import { TaskState } from "../src/state.ts"; import { TaskState } from "../src/state.ts";
test("keeps task guidance short while requiring planning before large work", () => { test("keeps task guidance short with planning after exploration", () => {
assert.equal(TASK_PROMPT_GUIDELINES.length, 2); assert.equal(TASK_PROMPT_GUIDELINES.length, 2);
const prompt = TASK_PROMPT_GUIDELINES.join("\n"); const prompt = TASK_PROMPT_GUIDELINES.join("\n");
assert.match(prompt, /large, multi-stage work/); assert.match(prompt, /work with 3\+ distinct steps/);
assert.match(prompt, /set_tasks before exploration as the only first-batch tool/); assert.match(prompt, /explore enough to understand the scope/);
assert.match(prompt, /append with force false by default/); assert.match(prompt, /then call set_tasks before implementation/);
assert.match(prompt, /Start one task in-progress; skip smaller work/); assert.match(prompt, /otherwise skip tracking/);
assert.match(prompt, /Use update_task when tracked work starts, blocks, or finishes/); assert.match(prompt, /Start one task in-progress/);
assert.ok(prompt.split(/\s+/).length < 60); assert.match(prompt, /update_task when tasks start, block, or finish/);
assert.match(prompt, /keep statuses accurate before the final response/);
assert.ok(prompt.split(/\s+/).length < 40);
}); });
test("uses a compact one-shot recovery reminder without embedding task data", () => { test("uses a compact one-shot recovery reminder without embedding task data", () => {