diff --git a/packages/durable/CHANGELOG.md b/packages/durable/CHANGELOG.md index 4e4fedde9..141c91b4a 100644 --- a/packages/durable/CHANGELOG.md +++ b/packages/durable/CHANGELOG.md @@ -2,6 +2,39 @@ ## [Unreleased] +### Breaking Changes + +- `TaskRuntime` now requires `env`, `hooks`, `getTask()`, `waitForTask()`, and `entry()`; `ToolExecutionApi` requires `env` and `diagnostic()` and no longer declares `conversation()` until owned-conversation handles land. +- `createRegistry()` also pre-registers the built-in `pi.tool` and `pi.post-tools` tasks. +- `ToolResultEntry` now carries `data: { diagnostics }`. +- `Tx` now requires `placeSubmission()` and `latestHeadMarker()`. +- Busy submissions no longer reject with `ConversationBusy`: they queue in the conversation's `pi.inbox`, except input with `whenBusy: "reject"`. +- The built-in `pi` setup now also creates `pi.inbox` and `pi.usage` in every Harness conversation. +- The environment shell no longer keeps a bounded, throttled output view: `ShellExecOptions.capture` and `onUpdate` are replaced by raw `onOutput` chunks and `spill: { afterBytes, afterLines }`, `ShellExecResult` is `{ exitCode, spillPath? }`, and `ExecutionError.spillPath` reports 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 hands the run to parallel or sequential `pi.tool` tasks and a `pi.post-tools` task that applies `addTools` and `terminate` and continues with the next generation. +- Added the `pi.tool` task: argument validation before and after `beforeTool`, durable intent with the replay policy, recovery that reruns only replay-safe tools, bounded `output()` and `details()` progress in `pi.live.tools` slots with adaptive throttling, output and details fallback, `afterTool`, and results with a rendered `` 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`, and `onYield` continuations on generation, `beforeTool` and `afterTool` on tools, and `afterTools` on post-tools, with `HookApi` memos. +- Added `HarnessOptions.env`, `ToolRegistration.executionMode`, and the `toolExecution` configuration with `get/setToolExecution()`. +- Added `read`, `bash`, `edit`, and `write` tools in `@earendil-works/pi-durable/tools`; they use `api.env`. Bash streams raw output into `api.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 for `edits` sent as a JSON string or a single object and for top-level `oldText`/`newText`. +- Tool output retained by `api.output()` is an exact slice of whole lines, sanitized of control characters. +- Added the `bench:tool-output` benchmark 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.inbox` document (`InboxDoc`) and are placed at post-tools and final boundaries, writes before user items, by the new `steeringMode` and `followUpMode` configuration with `get/set` accessors. Withdrawal removes the item; stale head writes settle `unanswered`; queued items survive a failed run until the next submission. +- Added `Conversation.reset(handoff)` and the post-tools `handoff` control, which write the headed `pi.reset` entry (`ResetEntry`); a reset queued during a tool round ends the run. +- `onYield` continuations 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.usage` ledger (`UsageDoc`) of assistant usage per model and tool usage per tool, `ToolExecutionResult.usage`, and `Harness.usage()` for the Session total. +- Added the structural `ConversationView` with `Conversation.viewState()` and `Conversation.watch()`. +- Added the experimental `watchEvents()` agent event adapter with snapshot events, translated message and tool deltas, and overflow to a snapshot. + +### 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 @@ -24,13 +57,6 @@ - `createRegistry()` now pre-registers the built-in `pi.generation` task and `pi` conversation setup, which cannot be disposed or replaced, and `Harness.open()` rejects a registry whose snapshot lacks either. - `RegistrySnapshot` now requires `conversationSetups()`. - `Tx` now requires `settleSubmission()`. -- `TaskRuntime` now requires `env`, `hooks`, `getTask()`, `waitForTask()`, and `entry()`; `ToolExecutionApi` requires `env` and `diagnostic()` and no longer declares `conversation()` until owned-conversation handles land. -- `createRegistry()` also pre-registers the built-in `pi.tool` and `pi.post-tools` tasks. -- `ToolResultEntry` now carries `data: { diagnostics }`. -- `Tx` now requires `placeSubmission()` and `latestHeadMarker()`. -- Busy submissions no longer reject with `ConversationBusy`: they queue in the conversation's `pi.inbox`, except input with `whenBusy: "reject"`. -- The built-in `pi` setup now also creates `pi.inbox` and `pi.usage` in every Harness conversation. -- The environment shell no longer keeps a bounded, throttled output view: `ShellExecOptions.capture` and `onUpdate` are replaced by raw `onOutput` chunks and `spill: { afterBytes, afterLines }`, `ShellExecResult` is `{ exitCode, spillPath? }`, and `ExecutionError.spillPath` reports the spill of a timed-out or aborted command. ### Added @@ -58,27 +84,10 @@ - Added `registry.conversations.setup()`: setups run in every Harness commit that creates or forks a conversation, including raw `Tx.createConversation()` and `Tx.forkConversation()`, before host `init`. The built-in `pi` setup runs first and stages the default configuration with every registered tool active (forks keep their copied configuration) and an empty `pi.live`. - `Conversation.submit()`, `Submission.wait()`, `waitForTask()`, and `waitForIdle()` now enable task scheduling, so they never wait on a Harness whose `resume()` was not called. - Scheduler-written `faulted` and `orphaned` outcomes of a run task now settle the run's input submissions `unanswered` and clear its run control in the same commit. -- 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 hands the run to parallel or sequential `pi.tool` tasks and a `pi.post-tools` task that applies `addTools` and `terminate` and continues with the next generation. -- Added the `pi.tool` task: argument validation before and after `beforeTool`, durable intent with the replay policy, recovery that reruns only replay-safe tools, bounded `output()` and `details()` progress in `pi.live.tools` slots with adaptive throttling, output and details fallback, `afterTool`, and results with a rendered `` 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`, and `onYield` continuations on generation, `beforeTool` and `afterTool` on tools, and `afterTools` on post-tools, with `HookApi` memos. -- Added `HarnessOptions.env`, `ToolRegistration.executionMode`, and the `toolExecution` configuration with `get/setToolExecution()`. -- Added `read`, `bash`, `edit`, and `write` tools in `@earendil-works/pi-durable/tools`; they use `api.env`. Bash streams raw output into `api.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 for `edits` sent as a JSON string or a single object and for top-level `oldText`/`newText`. -- Tool output retained by `api.output()` is an exact slice of whole lines, sanitized of control characters. -- Added the `bench:tool-output` benchmark 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.inbox` document (`InboxDoc`) and are placed at post-tools and final boundaries, writes before user items, by the new `steeringMode` and `followUpMode` configuration with `get/set` accessors. Withdrawal removes the item; stale head writes settle `unanswered`; queued items survive a failed run until the next submission. -- Added `Conversation.reset(handoff)` and the post-tools `handoff` control, which write the headed `pi.reset` entry (`ResetEntry`); a reset queued during a tool round ends the run. -- `onYield` continuations 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.usage` ledger (`UsageDoc`) of assistant usage per model and tool usage per tool, `ToolExecutionResult.usage`, and `Harness.usage()` for the Session total. -- Added the structural `ConversationView` with `Conversation.viewState()` and `Conversation.watch()`. -- Added the experimental `watchEvents()` agent event adapter with snapshot events, translated message and tool deltas, and overflow to a snapshot. ### 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. -- Avoided loading TypeBox through the package root's generation retry helpers and switched examples to narrow pi-ai model and faux-provider imports. ## [0.87.1] - 2026-09-22