mirror of
https://github.com/badlogic/pi-mono.git
synced 2026-11-05 23:37:25 +00:00
13 KiB
13 KiB
Changelog
[Unreleased]
[0.99.2] - 2026-09-30
Breaking Changes
TaskRuntimenow requiresenv,hooks,getTask(),waitForTask(),outcomes(),entry(), andconversation();ToolExecutionApirequiresenv,diagnostic(), andconversation().createRegistry()also pre-registers the built-inpi.tooltask.tx.createTask()requiresoptions.ownership:{ kind: "conversation" }or{ kind: "task", taskId }.TaskOptions.afterandTaskRecord.afterare removed; a task waits on other tasks by committing awaitingstate.TaskRecordgainsowner, andTaskStategainswaitingandcompleting; the SQLite task schema changed.ToolResultEntrynow carriesdata: { diagnostics }.Txnow requiresplaceSubmission()andlatestHeadMarker().- Busy submissions no longer reject with
ConversationBusy: they queue in the conversation'spi.inbox, except input withwhenBusy: "reject". - The built-in
pisetup now also createspi.inboxandpi.usagein every Harness conversation. - The environment shell no longer keeps a bounded, throttled output view:
ShellExecOptions.captureandonUpdateare replaced by rawonOutputchunks andspill: { afterBytes, afterLines },ShellExecResultis{ exitCode, spillPath? }, andExecutionError.spillPathreports the spill of a timed-out or aborted command.
Added
- Added the tool chain: generation offers active registered tools through positional system entries, answers calls to tools it did not offer with
tool_unavailable, and runs parallel or sequentialpi.tooltasks that it owns and waits for in itstoolsphase, which appliesaddToolsandterminateand continues with the next generation. - Added the
pi.tooltask: argument validation before and afterbeforeTool, durable intent with the replay policy, recovery that reruns only replay-safe tools, boundedoutput()anddetails()progress inpi.live.toolsslots with adaptive throttling, output and details fallback,afterTool, and results with a rendered<harness>diagnostics block. - Added tool diagnostics:
api.diagnostic(),ToolExecutionResult.diagnostics, and Harness diagnostics for truncation and error results. - Added hook dispatch with conversation and owned-subtree scopes:
beforeRequest,afterResponse, andonYieldcontinuations on generation,afterToolson generation,beforeToolandafterToolon tools, withHookApimemos. - Added
HarnessOptions.env,ToolRegistration.executionMode, and thetoolExecutionconfiguration withget/setToolExecution(). - Added
read,bash,edit, andwritetools in@earendil-works/pi-durable/tools; they useapi.env. Bash streams raw output intoapi.output(), reports its spill file as a diagnostic, and throws on a nonzero exit or timeout. Reading images is not supported yet. - Added
ToolRegistration.prepareArguments()to repair malformed arguments before validation; the edit tool uses it foreditssent as a JSON string or a single object and for top-leveloldText/newText. - Tool output retained by
api.output()is an exact slice of whole lines, sanitized of control characters. - Added the
bench:tool-outputbenchmark of tool output rates, retention, backends, replay, and 1 GiB throughput. - Added the inbox: busy steer and follow-up inputs and passive writes queue in the
pi.inboxdocument (InboxDoc) and are placed atpostToolsand final boundaries, writes before user items, by the newsteeringModeandfollowUpModeconfiguration withget/setaccessors. Withdrawal removes the item; stale head writes settleunanswered; queued items survive a failed run until the next submission. - Added
Conversation.reset(handoff)and thehandofftool control, which write the headedpi.resetentry (ResetEntry); a reset queued during a tool round ends the run. onYieldcontinuations now apply only when the final boundary places no queued user input and no reset.- A generation that faults or is orphaned now converts its committed partial into an aborted assistant entry, which counts in
pi.usage, instead of discarding it. - Added the
pi.usageledger (UsageDoc) of assistant usage per model and tool usage per tool,ToolExecutionResult.usage, andHarness.usage()for the Session total. - Added the structural
ConversationViewwithConversation.viewState()andConversation.watch(). - Added the experimental
watchEvents()agent event adapter with snapshot events, translated message and tool deltas, and overflow to a snapshot. - Added
Conversation.abort(), which withdraws queued inputs, aborts the conversation's ordinary ownership scope, and resolves once it is idle. - Abort marks now cascade to work owned by the aborted task, or by a task holding a failed, faulted, or orphaned outcome: live foreground tasks below it are aborted and the queued inputs of their conversations withdrawn. Background tasks are boundaries; finished owners never cascade.
- Added structured concurrency: tasks own child tasks (
ownership: { kind: "task", taskId }) and wait for any tasks with awaitingstate (on,policy: "failFast" | "allSettled") andruntime.outcomes(). A task that finishes while work it owns is live holds its outcome ascompletinguntil that work drains; abort handlers run bottom-up, after the aborted task's owned work ended. - Added
Conversation.abort(context, { background: true }), which also aborts background work and waits for it. - Conversation and Harness idle waits now include work in owned conversations and stop at background tasks.
- A tool task whose
execute()throws, or that is interrupted by a restart without a safe rerun, now endsfailed(still with its error result entry), which aborts the conversations the call owns. - Added compaction: the
pi.compactiontask (CompactionTask) summarizes an older prefix of the model context and places api.compactionentry (CompactionEntry) that heads the first kept entry.Conversation.compact()starts one manually; generation starts one in the background above a soft threshold, waits for one abovecontextWindow - reserveTokens, and compacts and retries once after a context overflow. Configure it withget/setCompaction();beforeCompacthooks can decline or supply the summary;pi.live.compactions,compaction_start/compaction_endevents, andpi.usagereport it. ContextViewnow includescontributions, each active entry's model messages after edits.- Added
TaskRuntime.conversation()andToolExecutionApi.conversation(): invocation-boundConversationHandles for submitting to, aborting, and waiting on existing conversations, such as the ones a task owns.
Fixed
- Avoided loading TypeBox through the package root's generation retry helpers and switched examples to narrow pi-ai model and faux-provider imports.
[0.99.1] - 2026-09-29
[0.99.0] - 2026-09-29
Breaking Changes
- Reordered Storage scan arguments so the limit precedes the cursor.
- Added the required conversation-visible
Storage.entry(conversationId, id, context)overload. - Split
Tx.createConversation()fromTx.forkConversation(), replaced raw conversation-record input, and require explicit ownerless or task ownership. - Replaced untyped numeric record IDs and the
TaskRefwrapper with erased branded numeric ID types, including result-typedTaskId<R>, separately branded commit sequences, and genericStorage.mintId(). - Made task conversation membership immutable after task creation.
- Added
ConversationQueryto Storage and transaction conversation scans. - Added required
StoredDocument.deltasSinceBaseto Storage document reads. - Task definitions now require an exhaustive
phasesmap and anaborthandler; define them withdefineTask(). RegistryReadernow requiressubscribe().- Removed
Tx.setTask(); a task changes its own state by returning the next state from itsruntime.commit()callback. Session.subscribeClose()listeners now run synchronously when close begins, after admission is sealed.defineEntry<D>()now takes the entry'sdatatype instead of a record type;Entry<D>.is()narrows toTypedEntry<D>.- Added the required
Storage.scanSubmissions()scan of submissions by conversation and status. createRegistry()now pre-registers the built-inpi.generationtask andpiconversation setup, which cannot be disposed or replaced, andHarness.open()rejects a registry whose snapshot lacks either.RegistrySnapshotnow requiresconversationSetups().Txnow requiressettleSubmission().
Added
- Added transactional Sessions with typed durable documents, task creation, snapshots, retirement, and commit publications.
- Added document checkpoint selection, lazy version migration, and
Session.snapshotAsOf()for rewindable conversation documents. - Added policy-driven backend-side conversation document copying when creating forks.
- Added indexed conversation ownership queries and guaranteed no-effect Storage rejection handling.
- Added the JSONL storage backend (
@earendil-works/pi-durable/storage/jsonl, andopenNodeJsonlStorage()from@earendil-works/pi-durable/storage/jsonl/node), including sidecar reclamation. - Added the execution environment (
@earendil-works/pi-durable/env, andNodeExecutionEnvfrom@earendil-works/pi-durable/env/node) for file access and shell execution with bounded output capture and truncation. - Added the
@earendil-works/pi-durable/testingexport with the scoped storage conformance suite (createStorageConformance(),registerStorageConformance()) and storage benchmark workloads (#9977 by @christianklotz). - Added incarnation-bound read-only Chord document states and serialized asynchronous document watches with bounded exact-frame buffering.
- Added
deltasSinceBasecheckpoint predicate information so definitions can bound replay without value counters. - Added
Harness.open()with lazy root creation, atomic conversation creation and forks withinit, conversation-bound commits, fork-aware entry pagination, model context derivation, and the built-inConversationConfigdocument with model, thinking level, and active tool accessors. - Added
createRegistry()for tools, tool wrappers, hooks, tasks, and system prompt sections with batched publication and stable keyed ordering. - Added
defineEntry()typed entry kinds. - Added the durable task runtime:
defineTask(), registry-resolved phase handlers with checkpoint progress rules decided on the Session line, migration at reservation, typed runtime commits, memos,sleep(), and invocation-owned watches, plusHarness.resume(),getTask(),waitForTask(),abortTask(), and task-awarewaitForIdle()on the Harness and conversations. Open reconciles running tasks to pending; tasks without a fitting definition stay blocked until registration, and aborting them settles them asorphaned. - Added the first runnable chat turn:
Conversation.submit()with request-ID deduplication,Submissionhandles (status(),wait(),abort()),Harness.submission(),Harness.abortSubmission(), andConversationBusyfor submissions to a busy conversation. - Added the built-in
pi.generationtask: positional system prompt preparation from registered sections (tags, wrappers, failures, minimal patches, order rewrites, and head-cut rebaselines), model requests throughModels, durable throttled partials in thepi.livedocument (LiveDoc), retries with backoff, deferred-response polling and cancellation, and aborted-partial conversion. - Added
Tx.settleSubmission(), which run tasks use to settle the inputs they answer. - Added built-in entry tokens
UserEntry,AssistantEntry,SystemEntry, andToolResultEntry, and token-firsttx.entry()andtx.appendEntry()overloads. - Added
streamOptionsandretrytoConversationConfigwithget/setStreamOptions()andget/setRetryPolicy()on conversations. - Added
snapshot(),snapshotAsOf(),context(),now(), andreport()toTaskRuntime. - Added
Harness.inspect(): live tasks with their derived scheduler state (running, ready, waiting, or blocked with its reason), queued and placed submissions, and registry wrapper failures. - Entries appended by a task's runtime commits now record the task as
byTaskId. - Added
registry.conversations.setup(): setups run in every Harness commit that creates or forks a conversation, including rawTx.createConversation()andTx.forkConversation(), before hostinit. The built-inpisetup runs first and stages the default configuration with every registered tool active (forks keep their copied configuration) and an emptypi.live. Conversation.submit(),Submission.wait(),waitForTask(), andwaitForIdle()now enable task scheduling, so they never wait on a Harness whoseresume()was not called.- Scheduler-written
faultedandorphanedoutcomes of a run task now settle the run's input submissionsunansweredand clear its run control in the same commit.
Fixed
- Fixed cached documents skipping migration when accessed with a newer definition version, and older definitions reading values migrated only in memory. Document states and watches hydrated under another definition version receive the new value as a root replacement.
[0.87.1] - 2026-09-22
[0.87.0] - 2026-09-21
[0.86.1] - 2026-09-20
[0.86.0] - 2026-09-19
Added
- Added the initial Pico durable record contracts and detached in-memory storage implementation.