Skip to content

fix(pi): persist the active session id for agent resume - #665

Open
HaningZS wants to merge 1 commit into
HarnessMD:mainfrom
HaningZS:fix/pi-session-resume-299
Open

HaningZS wants to merge 1 commit into
HarnessMD:mainfrom
HaningZS:fix/pi-session-resume-299

Conversation

@HaningZS

@HaningZS HaningZS commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

What & why

The generated Pi bridge reports tool/Stop events without a session id and never reports session startup. The harness therefore has no durable Pi conversation identity to pass to --session when an agent restarts.

This reads ctx.sessionManager.getSessionId() on each callback, forwards it with existing tool/Stop payloads, and emits SessionStart on Pi's session_start. It uses the current context rather than a cached id or an event-provided field, so new, resumed, reloaded and forked sessions do not retain the previous identity. Missing/broken context leaves the existing fail-open reporting behavior intact.

Closes #299

Type of change

  • Bug fix
  • New feature
  • Refactor / cleanup
  • Docs
  • Build / CI

Evidence

These images render actual node:test output, not live CLI screenshots. The same tests execute the installed/generated extension with simulated Pi callbacks/transport, then use the real HookServer/HiveManager to persist the id and the production provider-aware resume branch to form --session argv.

Before

Unchanged upstream f44b986a with the final regression suite: 1 passed / 6 failed.

Before: Pi session identity is absent

After

All 7 pass: startup before any tool call, persistence across hive restart, resume/new/fork/reload identity changes, current context on tool/Stop events, and missing/broken context fallback.

After: Pi identity persists and forms resume argv

Real CLI experiment

Also ran official Pi 1.0.0 in offline RPC mode with the generated bridge and a real hook socket. A SessionManager-created transcript containing one fixture user message was loaded without sending a prompt. The experiment confirmed:

PASS: real Pi session_start persisted its UUID through the real hook socket
PASS: --session <persisted UUID> reopened the same Pi transcript (1 fixture message)
PASS: real Pi new_session updated the saved resume identity
PASS: real Pi switch_session restored the selected conversation identity
No prompt or model API request sent. Pi version: 1.0.0

The optional reproducer is test/pi-session-resume.manual.cjs. Pi is installed into a separate npm prefix; it is not added to the app's dependencies:

taskRuntime=$(mktemp -d)
npm install --prefix "$taskRuntime" --no-audit --no-fund @earendil-works/pi-coding-agent@1.0.0
PI_RUNTIME_DIR="$taskRuntime" node test/pi-session-resume.manual.cjs

The script retains its printed temporary hive for inspection and stops the child CLI processes. It canonicalizes the working directory because macOS /var and /private/var aliases otherwise trigger Pi's different-project fork prompt.

How I tested it

  • macOS 26.4.1, Apple Silicon, Node.js v24.13.0.
  • New tests: 7 passed; new plus existing Pi bridge/models tests: 21 passed.
  • Real Pi offline RPC experiment above passed.
  • npm run typecheck, npm run build, git diff --check: passed.
  • npm run test:focused: 970 passed, 1 failed, 1 skipped. Clean upstream at the same revision: 963 passed, the same 1 failure, 1 skipped. The failure is test/model-catalog-remote.test.cjs:60, catalog drift tracked by CI never runs the test suite; model-catalog-remote is failing on main #652; the full-suite checkbox is intentionally unchecked.

Agent review and limits

Reviewed event registration, current-versus-cached identity, missing/throwing context, transport errors, provider scope, and paths with spaces. The production behavior change is confined to the Pi extension. Existing tool payload fields and approval behavior remain covered by the bridge tests. No filesystem operation is added to the tool callback; the existing HookServer session recorder skips unchanged ids.

The API contract was checked in Pi's official extension types and SessionManager, plus the installed 1.0.0 package. Actual CLI startup/UUID restore/new/switch were exercised; fork/reload and tool-event cases are regression tests. Live model/tool execution, a packaged GUI restart, older Pi releases and native Windows/Linux CLI smoke tests were not run. The separate worktree restore issues (#297/#298) are outside this change.

Checklist

  • Before and after evidence is attached under both headings.
  • npm run typecheck passes.
  • npm run test:focused passes — the reproduced upstream failure is detailed above.
  • npm run build succeeds.
  • This PR is one change.
  • I read the diff for debug output and unrelated changes.
  • No new UI or art; design-token and artwork requirements are not applicable.

Why:
- Pi lifecycle payloads omit the active conversation id, so the harness cannot resume the previous session (HarnessMD#299).

What:
- Read the active session id from the Pi extension context on lifecycle callbacks.
- Emit SessionStart on session_start and attach the current id to tool/Stop events.
- Keep existing tool reporting and approval behavior when session context is absent or broken.
- Add persistence/resume-path regression tests and an optional offline real-Pi CLI experiment.

Risk:
- Live model/tool execution and native Windows/Linux CLI smoke tests were not run.
- This fixes session identity forwarding; unrelated worktree restore problems remain separate.

Tests:
- New suite: 7 passed; unchanged upstream: 1 passed, 6 failed.
- Related Pi tests: 21 passed.
- Pi 1.0.0 offline RPC: session recorded via actual hook socket, same transcript resumed by UUID, new/switch identities updated; no model request.
- npm run typecheck; npm run build; git diff --check passed.
- Full suite: 970 passed, 1 failed, 1 skipped; baseline: 963 passed, same model-catalog failure (HarnessMD#652), 1 skipped.

Live Docs:
- Required Before/After evidence under docs/pr-evidence; manual experiment instructions in test/pi-session-resume.manual.cjs.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

pi session_id is never forwarded by hive-bridge.js, so a restored pi agent always starts a fresh conversation

1 participant