Skip to content

feat(pi-acp): opt-in persistent sessions via PI_SESSION_DIR#1672

Open
khaled-mansour-zid wants to merge 1 commit into
rivet-dev:mainfrom
khaled-mansour-zid:zid/adapter-session-persistence
Open

feat(pi-acp): opt-in persistent sessions via PI_SESSION_DIR#1672
khaled-mansour-zid wants to merge 1 commit into
rivet-dev:mainfrom
khaled-mansour-zid:zid/adapter-session-persistence

Conversation

@khaled-mansour-zid

Copy link
Copy Markdown
Contributor

feat(pi-acp): opt-in persistent sessions via PI_SESSION_DIR

Problem

registry/agent/pi/src/adapter.ts hardcodes SessionManager.inMemory(params.cwd)
for every new session. In-memory means pi never writes the session .jsonl, so the
entire conversation is lost the moment the adapter process restarts (actor
sleep/eviction, crash, redeploy). There is no way for an embedder to get persistent,
resumable sessions short of patching the adapter.

Pi already provides the other half — SessionManager.continueRecent(cwd, sessionDir)
persists the session under sessionDir and resumes the most recent one. It just
isn't reachable from the ACP adapter.

Change

Add resolveSessionManager(SessionManager, cwd, env): if PI_SESSION_DIR is set in
the session env, use continueRecent(cwd, PI_SESSION_DIR); otherwise inMemory(cwd).
Wire the newSession call site to it.

  • Additive & non-breaking — default stays in-memory; behavior only changes when
    the embedder sets PI_SESSION_DIR.
  • Env-driven, matching the accepted SECURE_EXEC_FRAME_TIMEOUT_MS override (feat(runtime-core): env-override the native sidecar frame timeout #1641).
  • TestedresolveSessionManager is exported and unit-tested with a fake
    SessionManager (persist branch, default branch, blank-value guard); the real
    newSession path needs the Pi SDK so the selection logic is tested directly.

Verification

resolveSessionManager logic verified for all three branches; check-types + the
tests/*.test.mjs node:test suite run in CI.

The Pi ACP adapter hardcodes `SessionManager.inMemory(params.cwd)` for every new
session, so nothing is written to disk and the whole conversation is lost when the
adapter process restarts (e.g. an actor sleep/eviction). Pi already ships
`SessionManager.continueRecent(cwd, sessionDir)` — persist + resume the most
recent session — but there's no way for an embedder to select it without patching
the adapter source.

Add `resolveSessionManager()`: when the embedder provides a session directory via
the `PI_SESSION_DIR` env var, use `continueRecent` (persist under that dir and
resume); otherwise keep the current in-memory behavior. Env-driven and additive —
no behavior change unless `PI_SESSION_DIR` is set (same pattern as the
`SECURE_EXEC_FRAME_TIMEOUT_MS` override in rivet-dev#1641). The helper is exported and unit
tested with a fake SessionManager (the real newSession path needs the Pi SDK).

Co-authored-by: Khaled Mansour <khaled.mansour@zid.sa>
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.

1 participant