npm / @earendil-works/pi-durable
@earendil-works/pi-durable
What changed in @earendil-works/pi-durable 1, from its official release notes, upgrade guides and advisories. Sources checked 2026-11-01.
22 breaking38 new APIs and options1 performance7 behavior and defaults3 fixes and other
See which of these apply to your code, ranked, in your agent:
npx @unstale/cli init@earendil-works/pi-durable 171 changes
Breaking changes 22
Every defineDoc definition now requires an explicit checkpointWhen predicate; there is no default.
Every defineDocFamily definition now requires an explicit checkpointWhen predicate; there is no default.
Tasks now have a sleeping status; code handling every TaskState, TaskGraphState, or TaskInspection state needs a case for it.
Opening SQLite storage automatically migrates it to schema version 2 and rebuilds its task table. Migrated databases cannot be opened by 1.3.0 or earlier, preventing rollback past this release.
The exemption is limited to reads: errors thrown by commit() or mintId() fail the Harness like any other storage error.
Removed because waiting inside a phase holds an invocation and can restart the wait after a restart. Use sleepUntil() or return sleeping from commit(), and move post-wait work into the next phase.
Its type is now boolean instead of true; false does not end the run.
Adds access to the Harness clock; hand-built TaskRuntime and ToolExecutionApi objects must include the new methods.
After compaction, or when a first baseline follows earlier answers, the baseline leads model context when kept history includes an assistant message; other system messages after an assistant message stay in place.
A nonzero exit now returns an error result with an exit_code diagnostic instead of throwing tool_error.
A generation now fails with model_error if its blocking threshold compaction failed, faulted, was orphaned, or was directly aborted, rather than sending a request anyway.
A submission containing only kind and data is appended and settled immediately, even while busy or queued; it does not change what the model sees.
pi.tool is version 2 and migrates live version 1 tasks.
A nonzero exit now returns an error result with an exit_code diagnostic instead of throwing tool_error.
Rejects waits that form a cycle through waits and held owners, naming the cycle, rather than leaving tasks waiting forever.
Any Storage method error, including a read, fails and closes the Session; later calls and pending waits reject with SessionFailed, and nothing is retried.
StorageRejected is removed; StorageRequestError represents invalid requests and fails only that call.
Storage throws StorageRequestError for an invalid request, which fails only that call.
Throwing or rejected listener callbacks are reported through onReport instead of failing the operation that ran them.
Throwing or rejected listener callbacks are reported through onReport instead of failing the operation that ran them.
The content field is replaced by output, alongside the new structuredOutput field.
ToolTaskInput and ToolTaskResult are tagged unions: model-issued calls use kind: "model" and nested calls use kind: "nested".
New APIs and options 38
SQLite drivers, portable interfaces, and the generic migration runner now come from this package; existing Durable SQLite entry points continue re-exporting their public names.
Runs a task again after the crash-loop guard parks it.
Reports whether work can run or the earliest sleep time, allowing hosts to schedule process wakeups.
Sets a pi-ai ClientIdentity for User-Agent and provider attribution on every model request through the Harness, including hooks and tools.
Notifies a host when the Session needs a process; when configured, the Harness keeps no timer for sleeps so hosts can hibernate and resume on an alarm.
Arms Session, scheduler, and task timers, including for createSession(); with now, timers use a host or fake clock.
Enables content-free telemetry for submissions, task phases, committed events, checkpoints, tool replay, reports, and optional metrics and trace propagation.
Adds browser storage backed by IndexedDB.
The callback now receives a second argument, info, describing the report; callbacks written for one argument continue to work.
Controls whether inputs queued behind a run failing with model_error or no_model are kept, run next, or settled unanswered with reason run_failed.
Sets compaction thresholds per exact provider/modelId, so one Harness can serve models with different context-window sizes.
Sets how many consecutive cutoffs without a committed state are allowed before a task is parked; set it to Infinity to retain the old behavior.
Shows why a task cannot run, including missing_task, task_too_old, migration_failed, and restart_limit.
Tracks task restarts caused by a crash, eviction, or reset; a newly committed state starts the count over.
Accepts an optional from argument for reports.
Adds a way to pace work inside a phase without waiting for it.
Adds durable sleeping that ends a task phase; the task resumes at its checkpoint once the Harness clock reaches until.
Forwards the prefix option so Durable Object SQLite storage can namespace tables and indexes in a shared database.
Forwards the prefix option so Node SQLite storage can namespace tables and indexes in a shared database.
Accepts a prefix to namespace every table and index, allowing the database to be shared with host tables.
Reads the bounded output the model will see.
Bounds the Session document cache by use; unobserved documents are released after the retention period, which defaults to ten minutes and can be set to 0.
Adds a codemode tool whose scripts call conversation tools as nested calls and replay deterministically from a journal across restarts.
Provides a Photon WebAssembly image processor with Node and Cloudflare loaders.
Provides the coding agent's tool_search tool, which searches deferred tools with BM25 and loads matches.
ExecutionEnv optionally supports bounded, gitignore-aware tree listings, with ListFilesOptions, FileListing, and FileListEntry types.
Input submissions can place content in an entry of a specified kind and data instead of pi.user; the kind must not start with pi.
pi.agent modelTools controls which tools a conversation offers the model; addTools also extends it.
Keeps the newest compaction failure until a compaction produces a summary; agent snapshots carry it as compactionFailure.
Session.closed settles after closure with either a closed reason or a failed reason and error.
Tools can declare a structured output schema; the Harness validates structuredOutput and provides it to programs calling the tool.
Aborts an in-memory-awaited task and its owned work when a later Harness starts scheduling, before any work runs again.
Aborts a task owned by this task and waits until it is terminal.
Returns copies of the live tasks directly owned by a task, regardless of which invocation created them.
Tools can call another tool as a nested call, with validation, hooks, output limits, replay policy, and a NestedToolExecutionResult returned to the caller.
Controls whether a tool may be called by the model, nested tools, or both; both is the default.
Keeps a tool from the model until modelTools names it; deferred tools can be loaded through the new add mechanism.
WatchEnd gains a session_failed variant carrying the error.
Performance 1
Encodes a 3 MiB image without using about 140 MB of heap, avoiding the Cloudflare Durable Object 128 MB memory limit.
Behavior and default changes 7
Generation retry backoffs, deferred-response polls, and compaction retry backoffs now sleep instead of waiting in a running phase, allowing a process to stop or hibernate during them.
Now accepts a function returning the current model value, evaluated at each use so hosts can replace model configuration without reopening the Harness.
Code mode now measures script deadlines and wall time using the Harness clock instead of Date.now().
Now accepts a function returning the current settings value, evaluated at each use so hosts can replace settings without reopening the Harness.
A task phase that faults is now reported through onReport as task_faulted, rather than only being recorded in its outcome.
Adapters created for the same storage object now coordinate operations, allowing multiple Pi storages to safely share one Durable Object database.
Returns supported PNG, JPEG, GIF, and WebP images as image blocks within model limits instead of an unsupported_image error.
Fixes and other changes 3
Idle document and context eviction timers are declined in Workers with nodejs_compat, allowing Durable Objects to hibernate; memory is freed at later commits.
The Node environment now detects the legacy WSL bash.exe launcher from %SystemRoot% instead of assuming C:\Windows.
Thinking is no longer included in the summarization request, avoiding requests that exceed the context being summarized.