Skip to content

Commit 140f8b7

Browse files
committed
pi-agenticoding/03: restore post-handoff proceed
1 parent 15afdb0 commit 140f8b7

5 files changed

Lines changed: 18 additions & 13 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Changed
1111

12-
- **Breaking:** handoff no longer auto-sends `Proceed.` after compaction and no longer supports configurable auto-resume. The superseded `handoff.resumeBehavior` (`"wait"`/`"proceed"`) setting is ignored.
12+
- Handoff keeps auto-sending `Proceed.` after successful compaction, matching core Pi behavior, while the superseded `handoff.resumeBehavior` (`"wait"`/`"proceed"`) setting is ignored and no longer configures continuation.
1313
- Added `handoff.automaticEnabled` raw settings support with JSON boolean values. Missing settings default to automatic handoff enabled; `false` removes the agent-facing handoff tool and handoff-call guidance during normal turns while preserving explicit `/handoff <direction>`.
1414
- Added the extension-owned `/agenticoding-settings` TUI panel for automatic handoff availability. TUI saves are global-only to `~/.pi/agent/settings.json`, preserve unrelated settings keys, persist real booleans, and visibly warn when a project override masks the global value.
1515
- Manual `/handoff <direction>` now waits behind the scenes when the assistant is streaming, then enables the `handoff` tool and starts a fresh handoff turn once idle. Visible stale-cleanup diagnostics have been removed from this flow, including TUI warnings and `agenticoding-handoff-diagnostic` conversation messages.

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ That's it. Your agent now has `spawn`, `notebook_write`, `notebook_read`, `noteb
5252
|---------|-------------------|
5353
| **Context usage %** | `ctx 65%` in status bar — green < 30%, yellow < 50%, orange < 70%, red ≥ 70% |
5454
| **Notebook count** | 📒 `3` when pages exist, dim `📒 0` when empty |
55-
| **`/handoff` command** | Explicit manual pivot — agent drafts brief, compacts context, then waits for your next input |
55+
| **`/handoff` command** | Explicit manual pivot — agent drafts brief, compacts context, then Pi sends `Proceed.` in the fresh context |
5656
| **`/agenticoding-settings` command** | TUI panel for global `handoff.automaticEnabled`, with project override warnings |
5757
| **`/notebook` command** | Overlay showing all notebook pages with previews |
5858
| **Auto-rehydration** | Notebook pages survive session restarts |
@@ -117,7 +117,7 @@ A sparse pocket notebook the agent curates while working. After discovering some
117117

118118
When context degrades or the job changes, the agent saves reusable state to the notebook, writes a focused brief preserving what's still missing, and restarts clean. The new context starts with the brief front-and-center, all notebook pages accessible, and zero noise.
119119

120-
By default, automatic handoff is enabled: the agent can see the `handoff` tool and may use it at context/job boundaries. Handoff completion always waits for your next explicit input; there is no configurable auto-`Proceed.` behavior.
120+
By default, automatic handoff is enabled: the agent can see the `handoff` tool and may use it at context/job boundaries. After successful handoff compaction, Pi auto-sends `Proceed.` so the fresh context continues immediately; this continuation is fixed, not configurable.
121121

122122
To make handoff human-driven only, set `handoff.automaticEnabled` to `false` in raw Pi settings JSON. Supported persisted values are JSON booleans `true` and `false`; missing settings default to `true`.
123123

@@ -127,11 +127,11 @@ To make handoff human-driven only, set `handoff.automaticEnabled` to `false` in
127127
}
128128
```
129129

130-
Settings are read from `~/.pi/agent/settings.json` and `<project>/.pi/settings.json`, with project settings overriding global settings. When automatic handoff is disabled, the agent-facing `handoff` tool and handoff-call guidance are removed from normal turns. The explicit operator command `/handoff <direction>` still works from idle or busy prompts: if the assistant is streaming, it waits behind the scenes until the current run is idle, temporarily enables the tool for a fresh requested handoff turn, compacts, restores the disabled state, and then waits for your next input.
130+
Settings are read from `~/.pi/agent/settings.json` and `<project>/.pi/settings.json`, with project settings overriding global settings. When automatic handoff is disabled, the agent-facing `handoff` tool and handoff-call guidance are removed from normal turns. The explicit operator command `/handoff <direction>` still works from idle or busy prompts: if the assistant is streaming, it waits behind the scenes until the current run is idle, temporarily enables the tool for a fresh requested handoff turn, compacts, restores the disabled state, and auto-sends `Proceed.` after successful compaction.
131131

132132
Run `/agenticoding-settings` to change the global value from the TUI. It saves global-only to `~/.pi/agent/settings.json`, preserves unrelated JSON keys, shows the effective runtime value separately, and warns when a project override masks the global value. Setting changes affect future fresh agent turns; manual `/handoff` uses that same rule by waiting for idle before enabling the tool and starting its own fresh turn. Edit or remove project overrides manually.
133133

134-
Migration note: the superseded PR-only `handoff.resumeBehavior` (`"wait"`/`"proceed"`) setting is ignored and cannot trigger automatic continuation. Remove it when convenient.
134+
Migration note: the superseded PR-only `handoff.resumeBehavior` (`"wait"`/`"proceed"`) setting is ignored and cannot change the fixed post-compaction `Proceed.` continuation. Remove it when convenient.
135135

136136
**Rule of thumb:** The notebook holds reusable learned knowledge. Handoff carries the remaining situational context.
137137

agenticoding.test.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,7 @@ test("/handoff requires a direction", async () => {
408408
assert.deepEqual(pi.sentUserMessages, []);
409409
});
410410

411-
test("handoff automatic setting defaults to enabled without automatic continuation", async () => {
411+
test("handoff automatic setting defaults to enabled with post-compaction Proceed", async () => {
412412
const pi = new MockPi();
413413
const state = createState();
414414
state.notebookPages.set("auth-refresh", "sensitive notebook body");
@@ -441,19 +441,19 @@ test("handoff automatic setting defaults to enabled without automatic continuati
441441
assert.equal(result.terminate, true);
442442

443443
compactOptions.onComplete({});
444-
assert.deepEqual(pi.sentUserMessages, []);
444+
assert.deepEqual(pi.sentUserMessages, [{ content: "Proceed.", options: undefined }]);
445445
assert.ok(pi.activeTools.includes("handoff"));
446446
});
447447

448-
test("handoff automatic setting true keeps handoff active without automatic continuation", async () => {
448+
test("handoff automatic setting true keeps handoff active and proceeds after compaction", async () => {
449449
const result = await runHandoffResumeScenario({
450450
globalSettings: { handoff: { automaticEnabled: false } },
451451
projectSettings: { handoff: { automaticEnabled: true } },
452452
});
453453

454454
assert.ok(result.compactOptions);
455455
result.compactOptions.onComplete({});
456-
assert.deepEqual(result.sentUserMessages, []);
456+
assert.deepEqual(result.sentUserMessages, [{ content: "Proceed.", options: undefined }]);
457457
assert.deepEqual(result.notifications, []);
458458
assert.ok(result.activeTools.includes("handoff"));
459459
});
@@ -558,14 +558,14 @@ test("handoff automatic setting non-ENOENT read errors are treated as invalid so
558558
});
559559
});
560560

561-
test("handoff resumeBehavior is ignored and cannot trigger automatic continuation", async () => {
561+
test("handoff resumeBehavior is ignored and completion still uses fixed Proceed", async () => {
562562
const result = await runHandoffResumeScenario({
563563
globalSettings: { handoff: { resumeBehavior: "proceed" } },
564564
});
565565

566566
assert.ok(result.compactOptions);
567567
result.compactOptions.onComplete({});
568-
assert.deepEqual(result.sentUserMessages, []);
568+
assert.deepEqual(result.sentUserMessages, [{ content: "Proceed.", options: undefined }]);
569569
assert.deepEqual(result.notifications, []);
570570
});
571571

@@ -593,6 +593,9 @@ test("manual slash handoff temporarily activates handoff when automatic handoff
593593
});
594594
assert.ok(compactOptions);
595595
assert.equal(state.pendingRequestedHandoff?.toolCalled, true);
596+
597+
compactOptions.onComplete({});
598+
assert.equal(pi.sentUserMessages.at(-1)?.content, "Proceed.");
596599
});
597600
});
598601

handoff/tool.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,9 @@ export function registerHandoffTool(
9898
manualRequest.toolCalled = true;
9999
}
100100
ctx.compact({
101-
onComplete: () => {},
101+
onComplete: () => {
102+
pi.sendUserMessage("Proceed.");
103+
},
102104
onError: () => {
103105
state.pendingHandoff = null;
104106
state.pendingRequestedHandoff = null;

settings.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ export function getAgenticodingSettingsDisplayLines(model: AgenticodingSettingsM
316316
`Supported values: true, false. Default: true (automatic handoff enabled).`,
317317
`When false, the agent-facing handoff tool is inactive for normal turns; manual /handoff <direction> still works from an idle prompt.`,
318318
`Setting changes affect future fresh agent turns; in-flight queued follow-ups keep their existing tool schema.`,
319-
`Handoff completion waits for your next explicit input; handoff.resumeBehavior is ignored and no automatic Proceed. message is sent.`,
319+
`After successful handoff compaction, Pi auto-sends Proceed.; handoff.resumeBehavior is ignored and cannot change that behavior.`,
320320
`Global settings: ${model.state.global.path} (${model.state.global.invalid ? "invalid JSON" : describeValue(model.state.global.automaticEnabled)})`,
321321
`Project settings: ${model.state.project.path} (${model.state.project.invalid ? "invalid JSON" : describeValue(model.state.project.automaticEnabled)})`,
322322
`TUI saves are global-only; project settings override global settings at runtime.`,

0 commit comments

Comments
 (0)