Pi SDK sessions, worktrees, and TypeScript coordinator
Pi SDK sessions, worktrees, and TypeScript coordinator
Section titled “Pi SDK sessions, worktrees, and TypeScript coordinator”Related: Cloud agent orchestrator · 2026-09-28 Pi SDK v2 abilities boundary and data model · 2026-09-28 Pi Agent SDK bash PATH and Nix flake · 2026-09-26 Cloud agent orchestrators in the wild
Verdict
Section titled “Verdict”Strong fit for Noa’s TypeScript control plane. Pi owns conversation + tools + bash spawn; the orchestrator owns isolation lifecycle: git worktree add → session with cwd=worktree → prompt → commit/push → gh pr create → cleanup.
Packages: @earendil-works/pi-coding-agent (sessions/tools/SDK), @earendil-works/pi-agent-core (LLM loop at session.agent). Repo: earendil-works/pi / badlogic/pi-mono. Docs: SDK.
Session / run model
Section titled “Session / run model”| Surface | Role |
|---|---|
createAgentSession(options) | Factory → { session, extensionsResult, … } |
AgentSession | One conversation: model, tools, queues, compaction, extensions |
SessionManager | Entry tree + active leaf; persistence |
createAgentSessionRuntime / AgentSessionRuntime | newSession, switchSession, fork, importFromJsonl — replaces active session, recreates cwd-bound services |
Agent (agent-core) | Low-level loop via session.agent |
Important options: cwd, agentDir, model / modelRuntime / thinkingLevel, tools / customTools / noTools / excludeTools, resourceLoader, sessionManager, settingsManager.
SessionManager factories:
inMemory(cwd?)— ephemeralcreate(cwd, sessionDir?)— new JSONLopen(path)— resumecontinueRecent(cwd, sessionDir?)list(cwd, sessionDir?)forkFrom(sourcePath, targetCwd, sessionDir?)— new file; headercwd: targetCwd,parentSession: sourcePath
Persistence: default ~/.pi/agent/sessions/<encoded-cwd>/<timestamp>_<id>.jsonl (v3 tree). Header stores cwd. Override with sessionDir, PI_CODING_AGENT_SESSION_DIR, or CLI --session-dir.
Lifecycle: prompt / steer / followUp / abort / waitForIdle / subscribe / dispose. Wait on agent_settled (not only agent_end). After runtime session replacement, rebind subscriptions to runtime.session.
cwd ↔ tools (per-worktree)
Section titled “cwd ↔ tools (per-worktree)”Yes — each session can use a different worktree path. Pass cwd: worktreePath into createAgentSession and SessionManager.create|inMemory(worktreePath). Built-ins (read, bash, edit, write, …) are built for that cwd.
createBashTool(cwd, options?) executes with ctx?.cwd || cwd. Use spawnHook to replace PATH with flake print-dev-env (2026-09-28 Pi Agent SDK bash PATH and Nix flake). Session PI_* env is injected before the hook when exposeSessionEnvironment is true.
Worktree + PR recipe (who owns what)
Section titled “Worktree + PR recipe (who owns what)”| Step | Owner |
|---|---|
git worktree add <path> -b <branch> | Coordinator |
createAgentSession({ cwd: worktreePath, sessionManager: … }) | SDK |
Prompt / stream / agent_settled / dispose() | SDK |
git add / commit / push | Coordinator (or agent via bash if instructed) |
Open PR (gh pr create / API) | Coordinator |
| Remove worktree | Coordinator |
Optional: SessionManager.forkFrom(parentSessionFile, worktreePath) to carry transcript into the new cwd. Community pi-pr-agents (docs package) implements worktree+PR outside core — pattern reference, not a dependency lock.
Limits (orchestrator must design around)
Section titled “Limits (orchestrator must design around)”- No built-in worktree / branch / PR APIs in the coding-agent SDK.
- One active run per session. Mid-run second
prompt()needssteer/followUpor it rejects. Parallel jobs → separate sessions (or processes). Concurrent background spawns can collide (#5775). - Shared
agentDir: fine for credentials/settings; avoid concurrent writers on the same JSONL. Prefer sharedModelRuntime+ per-runcwd/sessionManager, or per-runagentDirfor hard isolation. - SDK embed does not auto-set
AI_AGENT/PI_CODING_AGENT(CLI/RPC do). - Overlapping trees without worktrees → file races; worktrees are the isolation story.
TypeScript control plane surfaces
Section titled “TypeScript control plane surfaces”In-process (preferred for Noa’s core): createAgentSession, createAgentSessionRuntime, SessionManager, ModelRuntime, tool factories, session.subscribe.
Process boundary: RpcClient from @earendil-works/pi-coding-agent — spawns node <cli> --mode rpc with { cliPath, cwd, env, provider, model, args }. Methods: prompt, promptAndWait, steer, followUp, abort, newSession, switchSession, fork, clone, bash, getState, waitForIdle, onEvent. Wire = JSONL stdin/stdout; completion = agent_settled.
Also: pi --print, pi --mode json for one-shot streams.
Recommendation for Cloud agent orchestrator
Section titled “Recommendation for Cloud agent orchestrator”Lock run create as: allocate worktree → open Pi session with that cwd (+ flake PATH spawnHook) → prompt to settled → coordinator opens PR → dispose + worktree GC. Persist run metadata (worktree path, branch, session file, PR URL) in the orchestrator store — Pi’s JSONL is the conversation artifact, not the project DB.
Sources
Section titled “Sources”- pi.dev SDK · sessions · session format · CLI integration · env vars
packages/coding-agent/src/core/sdk.ts,session-manager.ts,agent-session-runtime.ts,tools/bash.ts,modes/rpc/rpc-client.ts- Examples:
examples/sdk/05-tools.ts,11-sessions.ts,12-full-control.ts,13-session-runtime.ts