Skip to content
AI Primer
release

Pi releases version 1.0 with durable sessions backed by SQLite

Pi 1.0 introduces Pi Durable, with SQLite storage and concurrent sessions shared across multiple clients. Published examples describe replay-safe tasks and background subagents.

6 min read
Pi releases version 1.0 with durable sessions backed by SQLite
Pi releases version 1.0 with durable sessions backed by SQLite

TL;DR

A single process owns each storage backend, even when many clients attach. Codemode keeps its JavaScript state in the session transcript. The sharpest little detail sits in the background-subagent example: replaying stop could kill newer work.

Pi 1.0

Earendil's October 1 release post lists seven additions to the coding agent:

  • Codemode, including native MCP support and access to non-LLM models such as Jev and image models.
  • Extension support for virtual models.
  • Deferred tool loading.
  • Cache warming for Anthropic models.
  • Mid-conversation system messages for transcript-aware prompt and tool changes.
  • A new TUI theme.
  • Full-screen mode by default.

The terminal coding agent retains its one-person workflow. Pi Durable supplies a separate framework for applications with automatic recovery and shared conversations; both projects are MIT-licensed.

The announced Pi Durable installation includes three packages:

Codemode and MCP

Pi's native MCP support followed a September 29 reversal documented in Earendil's technical explanation. Codemode runs a JavaScript sandbox on the harness side, where scripts orchestrate and combine tool calls.

The new tool metadata distinguishes three exposure patterns:

  • Tools available directly to the LLM.
  • Tools loaded on demand.
  • Tools available only through Codemode.

Earendil says composition still suffers when MCP servers return prose instead of structured data. badlogicgames joked about having “this massive cake on my face” in a follow-up to the change.

SQLite storage

A harness opens over a pluggable storage backend, as described in badlogicgames's walkthrough:

  • Backends: memory, SQLite, and JSONL ship with the package, alongside a conformance suite and benchmarks for custom implementations.
  • Ownership: one process owns the storage; other clients attach to that process.
  • Working set: SQLite keeps active transcripts, live tasks, and pending submissions in memory. Older data stays on disk; compaction bounds the active transcript by the model's context window.
  • Execution: the harness and its tools can run on different machines. An env function selects an execution environment using each conversation's working directory.

The SQLite and JSONL storage code uses no Node APIs. Earendil describes small adapters for Bun or Cloudflare Durable Objects; the included local execution environment uses Node.

In a separate discussion, thdxr listed three constraints on his own agent project:

  • It can be open source.
  • It provides a decent experience without a cloud service.
  • Everything is pluggable.

He contrasted those requirements with Codex's logged-in, cloud-powered experience.

Replay-safe tasks

Pi Durable's README describes tasks as durable state machines. Tool-call intent is committed before execution, and each task saves checkpoints as it advances.

Recovery has four distinct behaviors:

  • Interrupted model request: send it again; preserve the partial answer in the transcript, marked as aborted.
  • Interrupted tool call: rerun only when declared replay: "safe". Otherwise, return an interrupted error to the model with the output committed so far.
  • Retried submission: reuse the original submission when its requestId matches. Exactly-once admission applies to submissions.
  • Custom task: resume from its persisted phase. External effects still use their own idempotency mechanism, such as the payment example's task-derived charge key.

badlogicgames praised Effect for in-process structured concurrency but argued that effect/workflow uses a Temporal-style replay model that creates problems when code changes.

Multiplayer

Everything a client needs is committed state. A late joiner or reconnecting client receives the current conversation view, then subsequent changes.

The watching documentation adds two operational limits:

  • Partial answers and tool output are committed at most every 100 ms; the documented crash-loss window is at most that interval.
  • A slow watcher retains at most 100 undelivered frames. Beyond that, pending frames are replaced by a single frame containing the newest full view.

Foreground subagents

Pi Durable has no built-in subagents. The foreground implementation supplies a delegation tool as an extension:

  • The tool-call task owns the child conversation, so aborting the call aborts the child.
  • A replay searches for an existing child by ownerTaskId instead of creating another.
  • A task-derived requestId reuses the child's original submission.
  • Removing the subagent extension from the child prevents recursive delegation through that tool.

The example uses OpenAI when an API key is present and a scripted faux provider otherwise.

Background subagents

The background example opens a SQLite database, closes the harness while a child is working, and reopens the same database to recover the work.

Its management tool exposes four actions:

  • spawn: create a named child and start work.
  • send: steer it, or queue a message after its current answer with followUp: true.
  • stop: abort its current work and drop queued messages while leaving the conversation usable.
  • status: report whether one child, or all children, are working or idle.

An anchor background task owns each child. Normal Esc and idle waits stop at that background boundary; abort({ background: true }) reaches through it.

A separate reporter task delivers answers to the main conversation using deduplicated submissions. The management tool itself is replay: "unsafe", because repeating a stop after recovery could interrupt a newer task.

Context and telemetry

Every asynchronous call takes a Chord Context. Cancelling a wait cancels only that wait, leaving the durable work running, according to the API documentation.

Explicit contexts carry cancellation signals and telemetry-parent information, badlogicgames explained. Using AsyncLocalStorage for telemetry parents would exclude some JavaScript runtimes; submitting in one stack frame and waiting in another requires a different context, he added.

Telemetry was still unwired at launch. The README also warns that Pi Durable's experimental API can change without notice between releases.

Further reading

Discussion across the web

Where this story is being discussed, in original context.

On X· 7 threads
TL;DR2 posts
Pi 1.01 post
Codemode and MCP1 post
SQLite storage3 posts
Replay-safe tasks1 post
Multiplayer1 post
Context and telemetry2 posts
Share on X