Pi SDK v2 — abilities boundary and data model
Pi SDK v2 — abilities boundary and data model
Section titled “Pi SDK v2 — abilities boundary and data model”Related: Cloud agent orchestrator · 2026-09-28 Pi SDK sessions worktrees and TS coordinator · 2026-09-28 Pi Agent SDK bash PATH and Nix flake · 2026-09-28 Worktree and PR by design orchestrators · 2026-09-28 Minimal orchestrator core Web UI plugin
Deepens (does not replace) the sessions/worktrees digest for the 0.84–0.87 surface. Skip Herdr.
What “v2” means (disambiguate)
Section titled “What “v2” means (disambiguate)”| Label | Layer | Meaning for us |
|---|---|---|
Coding-agent session file version: 3 | @earendil-works/pi-coding-agent SessionManager | Current on-disk JSONL contract (CURRENT_SESSION_VERSION = 3). v1 = linear; v2 = tree id/parentId; v3 = hookMessage → custom role. Auto-migrates on load. |
| AgentHarness v2 + SessionRepo v4 | @earendil-works/pi-agent-core (≥ 0.84.0) | Low-level harness: lane-based Session / SessionStorage / SessionRepo (JsonlSessionRepo, InMemorySessionRepo). Promoted from experimental; legacy harness JSONL APIs removed. Not what createAgentSession persists today. |
| npm scope | packages | @mariozechner/* → @earendil-works/* from 0.74.0 (2026-05). Pin Earendil scope. |
| ModelRuntime | coding-agent (≥ 0.80.8) | Replaces SDK authStorage / old modelRegistry option — async model+credential facade. |
| pi-multiagents-v2 (community package) | Extension | Codex Multi-Agent V2 behavior via in-process AgentSessions — optional; not core. |
@earendil-works/chord | Sibling package | Facets/services/replicated-state composition runtime — useful later for multi-process/UI; not required for worktree workers. |
Pinned packages (npm, 2026-09-22): pi-coding-agent, pi-agent-core, chord all 0.87.1. Docs: SDK · Session format · Sessions · Changelog.
Orchestrator default: stay on coding-agent createAgentSession / SessionManager / AgentSessionRuntime. Only dive into agent-core AgentHarness if building a custom non-coding loop.
Abilities boundary — Pi vs orchestrator-core
Section titled “Abilities boundary — Pi vs orchestrator-core”“Abilities” here = who owns which capability, not a Chord type.
| Ability | Pi owns | Orchestrator-core owns |
|---|---|---|
| LLM loop + tools | Agent via session.agent; built-ins read / bash / powershell / edit / write / grep / find / ls (ToolName); createCodingTools / createBashTool / …; tools / excludeTools / noTools / customTools / defaultTools | Tool policy (allowlists), flake PATH via bash spawnHook, e2e in Nix — not a parallel tool runner |
| One conversation | AgentSession: prompt / steer / followUp / abort / waitForIdle / subscribe / dispose | Run lifecycle: create → settle → dispose; never leave orphaned sessions |
| cwd / workspace | Tools + resource discovery bound to session cwd | git worktree add, unique branch, pin baseSha, pass cwd: worktreePath |
| Session persistence | Append-only JSONL tree (SessionManager); optional inMemory | Run record in core event store: {runId, baseSha, branch, worktreePath, prUrl, sessionId, sessionFile, leafId?} — Pi JSONL is conversation artifact, not project DB |
| Context truth | SessionManager.buildSessionContext / buildSessionProjection; system messages with sections + toolsAdded/toolsRemoved; context_edit; compaction | Do not assign session.agent.state.messages to “fix” history (0.87: Manager is canonical). Mirror selected events into core SSE |
| Extensions / skills | ResourceLoader / DefaultResourceLoader; extension events (turn_end, agent_before_settle, context_with_system, …) | Choose which extensions load per worker; re-bindExtensions after every AgentSessionRuntime session replacement; never put product orchestration only in opaque extensions |
| Auth / models | ModelRuntime (+ settings / credentials store) | Project-level model policy; worker env secrets; don’t share mutable auth files across hostile concurrent writers without care |
| Multi-agent | Core: none (by design). Packages: pi-multiagents-v2, other subagent extensions | Fleet: N workers = N sessions; coordinator is BYO MCP / core API — not Pi subagents |
| RPC / process isolation | RpcClient (--mode rpc), print/JSON modes; CLI/RPC set AI_AGENT=pi + PI_CODING_AGENT=true | Prefer in-process for same-machine workers; RpcClient for OS/crash isolation. Wire: LF-only JSONL (avoid Node readline); drain stdout; RPC message_update is delta-only (assemble until message_end) |
| Git / PR | Indirectly via bash if instructed | Always worktree + push + PR gate (2026-09-28 Worktree and PR by design orchestrators) |
| Project memory / UI | Session name / labels / custom entries inside one JSONL | Durable project files + core event log + panels (SSE) |
Security note (Pi SECURITY.md): Pi’s trust boundary is the local user account — worktrees ≠ sandbox. OS isolation (container/VM) remains orchestrator/platform if required.
Data model (ids that matter for core)
Section titled “Data model (ids that matter for core)”Runtime objects
Section titled “Runtime objects”createAgentSession(opts) → { session: AgentSession, … }AgentSession.sessionManager → SessionManager // persistence + treeAgentSession.agent → Agent // agent-core loopAgentSessionRuntime → newSession / switchSession / fork / importFromJsonl (replaces active session; rebind subscriptions + extensions)Session file layout
Section titled “Session file layout”~/.pi/agent/sessions/<encoded-cwd>/<timestamp>_<session-id>.jsonlOverrides: sessionDir / PI_CODING_AGENT_SESSION_DIR / CLI --session-dir. Header cwd groups sessions. Custom id via SDK / --session-id.
SessionHeader (first line, not in tree)
Section titled “SessionHeader (first line, not in tree)”| Field | Role |
|---|---|
type: "session" | Marker |
version | Prefer 3 |
id | Session UUID (also SessionManager.getSessionId()) |
timestamp | ISO created |
cwd | Workspace / worktree path |
parentSession? | Path to parent JSONL (fork / newSession({ parentSession })) |
Tree entries (SessionEntry)
Section titled “Tree entries (SessionEntry)”All (except header) have id, parentId, timestamp. Leaf = current append point (getLeafId()).
type | In LLM context? | Notes |
|---|---|---|
message | Yes | AgentMessage (system / user / assistant / toolResult / …). System messages carry sections + toolsAdded/toolsRemoved |
model_change | Settings | provider + modelId |
thinking_level_change | Settings | |
compaction | Summary + checkpoint | firstKeptEntryId, optional systemMessage, usage |
branch_summary | Summary | left-branch capture on /tree navigate |
context_edit | Projection only | targetId + replacement (null = omit); raw history unchanged (0.87) |
usage | No (totals yes) | e.g. kind: "cache_warm" |
custom | No | Extension state (customType) |
custom_message | Yes | Extension-injected context |
label / session_info | Meta | Bookmarks / display name |
Core should key: sessionId, sessionFile path, optional leafId at settle, plus our runId / prUrl.
Events to mirror into core SSE
Section titled “Events to mirror into core SSE”Subscribe before prompt. Completion = agent_settled (not merely agent_end — retries / queued work can follow).
Notable AgentSessionEvent types (0.87.1):
- From agent-core stream: message/tool lifecycle (via
AgentEvent, withagent_endreshaped to includewillRetry) agent_settledqueue_update(steering / followUp queues)entry_appended(persist-aware)compaction_start/compaction_endauto_retry_*,summarization_retry_*bash_execution_update(RPC/direct bash streaming)session_info_changed,thinking_level_changed
RPC message_update (0.84+): deltas only — assemble until message_end.
Env ids (bash / children)
Section titled “Env ids (bash / children)”When exposeSessionEnvironment is true: PI_SESSION_ID, PI_SESSION_FILE, PI_PROVIDER, PI_MODEL, PI_REASONING_LEVEL. CLI/RPC also set AI_AGENT=pi / PI_CODING_AGENT=true; SDK embed does not auto-set those markers.
Deltas vs our earlier Digests (0.84–0.87)
Section titled “Deltas vs our earlier Digests (0.84–0.87)”Still true from 2026-09-28 Pi SDK sessions worktrees and TS coordinator: one session per worktree cwd; wait agent_settled; no built-in worktree/PR; mid-run second prompt needs steer/followUp.
New / sharpened for core:
SessionManageris the only context authority — restore via manager entries /navigateTree/ append +refreshContext; mutatingagent.state.messagesdoes not replace future provider history.context_edit— omit/replace model-visible content without rewriting JSONL history (good for redaction / orchestrator injects that must not fork files).- Transcript-backed system + tool updates — survive resume/branch; cache-friendly dynamic tools (
toolsAddedfrom tool results). - Built-in
ToolNameset includesgrep/find/ls(not only read/bash/edit/write). ModelRuntimerequired mindset — noauthStorageoncreateAgentSession.- Extension boundaries — actionable
turn_end/agent_before_settle; deferred runs fromagent_settledhandlers until handlers finish. - agent-core harness v2/v4 — ignore for default workers unless we deliberately embed
AgentHarnessinstead of coding-agent. - Chord — optional composition later; not on the worktree hot path.
Bash PATH / flake spawnHook unchanged: 2026-09-28 Pi Agent SDK bash PATH and Nix flake.
Limits & gotchas (TS orchestrator-core)
Section titled “Limits & gotchas (TS orchestrator-core)”- One active run per
AgentSession. Parallelism = multiple sessions (or processes). SharedagentDir→ careful concurrent writers on settings/auth; prefer sharedModelRuntime+ per-runsessionManager/cwd. - After
AgentSessionRuntimereplace — oldsubscribehandles are dead; rebind toruntime.sessionand re-bindExtensions. - In-process vs RPC streams — in-process
message_updatecan carry cumulativemessage/partial; JSON/RPC (≈0.84+) emits deltas only untilmessage_end.RpcClient.promptsuccess ≠ settled (disposition: "handled"may skip wait); usepromptAndWait/waitForIdle/agent_settled. - In-memory restore —
SessionManager.inMemory(cwd?, options?, entries?)can rehydrate externally stored entries (0.85+); still keep our own run index. - Exhaustive switches on
SessionEntry/ExtensionEventmust handlecontext_editand new boundary events (0.87). - Multi-agent packages share one filesystem — disjoint write scopes or worktrees; tree not restored across process restart in
pi-multiagents-v2. - Security — Pi is not a sandbox; PR + CI remain the merge gate; optional container for untrusted code.
- Don’t treat community multiagent-v2 as product lock — coordinator stays outside Pi.
Recommendation (Cloud agent orchestrator)
Section titled “Recommendation (Cloud agent orchestrator)”Keep the locked contract:
Task → worktree+branch → createAgentSession({ cwd, sessionManager, modelRuntime, bash spawnHook }) → prompt → agent_settled → core opens PR → dispose + GC
Store in core: run metadata + pointers into Pi’s JSONL (sessionId / path / leaf). Stream agent_settled, tool/compaction failures, and PR lifecycle on SSE. Leave AgentHarness/Chord for a later “custom harness” spike, not v0 workers.
Sources
Section titled “Sources”- https://pi.dev/docs/latest/sdk · https://pi.dev/docs/latest/session-format · https://pi.dev/docs/latest/sessions · https://pi.dev/news (0.84.0–0.87.1)
- npm
@earendil-works/pi-coding-agent@0.87.1(session-manager.d.ts,agent-session.d.ts,sdk.d.ts) - https://github.com/earendil-works/pi/blob/main/packages/agent/CHANGELOG.md (AgentHarness v2 / SessionRepo v4)
- https://pi.dev/packages/pi-multiagents-v2 · https://www.npmjs.com/package/@earendil-works/chord
- Prior vault: 2026-09-28 Pi SDK sessions worktrees and TS coordinator · 2026-09-28 Pi Agent SDK bash PATH and Nix flake