From c99d4b5b9915527ad899adfa3295132c9d93329b Mon Sep 17 00:00:00 2001 From: Drew Stone Date: Tue, 4 Aug 2026 19:22:16 -0600 Subject: [PATCH] chore(stability): define the stability contract and graduate the proven core docs/STABILITY.md defines what @stable/@experimental promise consumers, the graduation bar (tests + curated doc + real consumer + 30-day quiet API + CHANGELOG entry), and the demotion/removal policy; linked from README and the docs index. Graduated to @stable (per-symbol and module-level), with evidence recorded in the 0.130.0 CHANGELOG entry: the runAgentRounds kernel and its contract types, supervise/Scope/Supervisor, the personify combinators, the spawn journal family, the /mcp delegation queue+stores+status tools, /intelligence, the improvement generators, and streamAgentTurn/collectAgentTurn. Kept @experimental with reasons: restart-recovery and event-bus durability surfaces (not implemented per docs/agent-managed-compute), the detached and worktree delegation leaves (unfinished resume path), the coordination MCP, and the kernel lineage/extension points. Newly tagged @experimental: define-agent (act not wired), strategy-evolution, /candidate-execution. Module-level maturity now renders: tsdoc.json extends TypeDoc's base tag set and each subpath barrel carries @module, so docs/api subpath pages show the Stable/Experimental badge under the title. --- CHANGELOG.md | 33 ++ README.md | 1 + docs/README.md | 1 + docs/STABILITY.md | 40 ++ docs/api/candidate-execution.md | 5 + docs/api/index.md | 41 +- docs/api/intelligence.md | 18 + docs/api/mcp.md | 281 +++--------- docs/api/primitive-catalog.md | 5 +- docs/api/profiles.md | 56 +++ docs/api/runtime.md | 405 ++++-------------- docs/api/tui.md | 258 +++++++++++ docs/canonical-api.md | 2 +- package.json | 2 +- src/agent/define-agent.ts | 4 + src/candidate-execution/index.ts | 8 + src/durable/spawn-journal.ts | 12 +- src/improvement/agentic-generator.ts | 2 +- src/improvement/improve.ts | 2 +- src/improvement/improvement-driver.ts | 2 +- src/improvement/raw-trace-distiller.ts | 2 +- src/improvement/reflective-generator.ts | 2 +- src/intelligence/capability.ts | 2 +- src/intelligence/delivery.ts | 2 +- src/intelligence/effort.ts | 2 +- src/intelligence/index.ts | 3 +- src/intelligence/resolver.ts | 2 +- src/intelligence/with-intelligence.ts | 2 +- src/mcp/delegation-store.ts | 14 +- src/mcp/feedback-store.ts | 10 +- src/mcp/index.ts | 2 +- src/mcp/task-queue.ts | 24 +- src/mcp/tools/delegate-feedback.ts | 14 +- src/mcp/tools/delegate.ts | 12 +- src/mcp/tools/delegation-history.ts | 14 +- src/mcp/tools/delegation-status.ts | 14 +- src/profiles/index.ts | 1 + src/runtime/index.ts | 2 +- src/runtime/personify/combinators.ts | 14 +- src/runtime/personify/persona.ts | 6 +- src/runtime/run-loop.ts | 6 +- src/runtime/strategy-evolution.ts | 2 + src/runtime/stream-agent-turn.ts | 14 +- src/runtime/supervise/event-bus.ts | 6 +- src/runtime/supervise/scope.ts | 2 +- src/runtime/supervise/supervise.ts | 4 +- src/runtime/supervise/supervisor.ts | 2 +- src/runtime/supervise/types.ts | 10 + src/runtime/types.ts | 54 +-- .../fixtures/agent-improvement-proposal.json | 10 +- .../agent-profile-improvement-proposal.json | 6 +- src/tui/index.ts | 1 + tsdoc.json | 3 + 53 files changed, 754 insertions(+), 688 deletions(-) create mode 100644 docs/STABILITY.md diff --git a/CHANGELOG.md b/CHANGELOG.md index a5505988..cbd5242a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,38 @@ # Changelog +## 0.130.0 + +### Stability contract + first graduation + +[docs/STABILITY.md](./docs/STABILITY.md) defines what `@stable` / `@experimental` promise consumers, the graduation bar (substantive tests + a curated-doc section + at least one real consumer + a 30-day quiet API + a CHANGELOG graduation entry), and the demotion/removal policy. A symbol tag wins over its module tag; an untagged symbol in an untagged module is experimental by default. This entry is the initial graduation: each family below is promoted at its current post-0.129.0 exact-profile shape with the evidence that passed the bar, and the 30-day breaking-change clock applies to every `@stable` symbol from this release forward. + +Promoted `@experimental` → `@stable` (per-symbol and module-level): + +- `runAgentRounds` + the kernel contract (`Driver`, `Validator`, `OutputAdapter`, `Iteration`, `LoopResult`, `AgentRunSpec`, `SandboxClient`, `ExecCtx`, `LoopTraceEmitter`, `RunAgentRoundsOptions`, and the trace-event/provenance closure in `src/runtime/types.ts`) — tests: `tests/kernel/` (`run-loop-harden`, `loop-dispatch` + the kernel suite); doc: `docs/canonical-api.md`; consumers: `bench/src/research-shot.ts`, `bench/src/corpus.ts`. +- `supervise` / `Scope` / `Supervisor` (+ `createScope` / `createSupervisor` via their module tags) — tests: `tests/kernel/supervise.test.ts` (1,878 lines) + `coordination-driver` / `coordination-mcp`; docs: `docs/execution-model.md`, `docs/canonical-api.md`; consumers: `bench/src/gate.ts`, `examples/supervise`, `examples/supervisor-loop`. +- personify combinators `pipeline` / `fanout` / `loopUntil` / `panel` / `verify` / `widen` + `definePersona` / `runPersonified` — tests: `tests/kernel/personify.test.ts` (797 lines); doc: `docs/canonical-api.md`; consumers: `examples/graphs`, `bench/src/gate.ts`. +- the spawn journal family (`InMemorySpawnJournal`, `FileSpawnJournal`, `InMemoryResultBlobStore`, `FileResultBlobStore`, `replaySpawnTree`, the `SpawnForest*` views) — tests: `tests/runtime/spawn-journal-replay-identity.test.ts` + the kernel suite's journal assertions; doc: `docs/canonical-api.md`; consumers: `bench/src/gate.ts`, `examples/recursive-supervisor`. +- the `/mcp` delegation queue + stores + status tools (`DelegationTaskQueue`, the delegation store, the feedback store, `delegate`, `delegation_status`, `delegation_history`, `delegate_feedback`) — tests: `tests/mcp/` (`task-queue`, `task-queue-durable`, `delegation-store`, `delegation-status`, `delegation-history`, `delegate`, `delegate-feedback`); doc: `docs/agent-managed-compute/current-state.md`; consumers: the shipped `agent-runtime-mcp` server (`src/mcp/server.ts`) + `examples/supervisor-loop/run-supervisor-mcp.ts`. +- `/intelligence` (all six module-tagged modules: the barrel, `capability`, `delivery`, `effort`, `resolver`, `with-intelligence`) — tests: in-package (`capability` / `delivery` / `intelligence` / `with-intelligence`, ~1,969 lines); doc: `docs/intelligence-sdk.md`, whose status has been "shipped" since it landed; consumers: `examples/intelligence-recommend`, `examples/intelligence-webcode`, `examples/intelligence-drop-in`, `examples/self-improving-loop`. +- the improvement generators (`improve`, the agentic generator, the improvement driver, the raw-trace distiller, the reflective generator) — tests: `src/improvement/improve.test.ts` (919 lines) + the in-package suite; doc: `docs/canonical-api.md`; consumers: `bench/src/swe-bench-env.ts`, `examples/improve`. +- `streamAgentTurn` / `collectAgentTurn` + the turn types (`AgentTurnBackend`, `AgentTurnInput`, `AgentTurnUsage`, `CollectedAgentTurn`, `StreamAgentTurnOptions`) — tests: `src/runtime/stream-agent-turn.test.ts` (690 lines); doc: `docs/canonical-api.md`; consumers: `bench/src/router-turn.ts`, `bench/src/benchmarks/appworld.ts`, `examples/chat-handler`, `examples/runtime-run`. + +Kept `@experimental`, each with the failing check: + +- `Scope.resume` / `SupervisorOpts.resume` and `EventBus` / `createEventBus`: same-process replay only — live supervised-tree recovery after a coordinator restart and the durable cross-process mailbox are listed Not implemented in `docs/agent-managed-compute/README.md`. +- The detached/worktree delegation leaves (`src/mcp/delegates.ts`, `detached-coder`, `detached-turn`, the worktree harnesses, `local-harness`): the module doc records the unfinished `driveTurn`-over-a-detached-session resume path. +- The coordination MCP (`src/mcp/tools/coordination.ts`, `src/runtime/supervise/coordination-mcp.ts`): authenticated remote coordination is Not implemented. +- `LoopLineageOptions` / `RunAgentRoundsOptions.lineage` and the member-level extension points `Driver.selectWinner`, `SandboxClient.criuStatus`, `ExecCtx.onSandboxEvent`: opt-in surfaces whose platform contracts (session continuity, CRIU fork) are still being proven. + +Newly tagged `@experimental` (previously untagged, unfinished): + +- `src/agent/define-agent.ts` — manifests validate and load, but `runtime.act` is not wired end-to-end into the eval path (`unimplementedAgentRun` is the shipped default). +- `src/runtime/strategy-evolution.ts` — the multi-generation strategy search, a research surface. +- the `/candidate-execution` subpath barrel. +- the supervisor restart-recovery and event-bus durability members listed under "kept" above, now tagged explicitly at the symbol level. + +Maturity now renders in the generated reference: `tsdoc.json` extends TypeDoc's base tag definitions, and each subpath barrel carries `@module`, so `docs/api/.md` shows the module-level `Stable` / `Experimental` badge directly under the page title. Module-level tags previously rendered nowhere in `docs/api`. + ## 0.129.0 - Require Agent Eval 0.144.4, Agent Interface 0.43.1, Agent Knowledge 7.0.11, and Sandbox 0.19.1 as one dependency set, and route the official-optimizer callback through Runtime's exact `AgentProfile` execution path. diff --git a/README.md b/README.md index e191a72d..6240c92f 100644 --- a/README.md +++ b/README.md @@ -529,6 +529,7 @@ All 29 live in [`examples/`](./examples). - New here? [`docs/concepts.md`](./docs/concepts.md), the mental model in plain terms. - [`docs/canonical-api.md`](./docs/canonical-api.md), find the primitive: "I want to ___ → use ___". - [`docs/api/primitive-catalog.md`](./docs/api/primitive-catalog.md), every export in one generated, never-stale list with its import path. Check it before building anything new. +- [`docs/STABILITY.md`](./docs/STABILITY.md), what `@stable` / `@experimental` promise you, and how a symbol graduates. - [`docs/design.md`](./docs/design.md), the design philosophy and the internal research docs behind it: background reading, not required to use the package. - [`bench/HARNESS.md`](./bench/HARNESS.md), the experiment harness and how to run a benchmark. diff --git a/docs/README.md b/docs/README.md index ae23fe75..2c23f257 100644 --- a/docs/README.md +++ b/docs/README.md @@ -32,6 +32,7 @@ These are internal working documents: design theses, research narrative, and roa |---|---|---| | [../README.md](../README.md) | API entry point | Install, the loop API, the plain-language framing, the exported subpaths. Start HERE. | | [canonical-api.md](./canonical-api.md) | API spine + decision table | The conceptual spine + the "I want to ___ → use ___" anti-reinvention matrix of LOCAL symbols. Per-symbol signatures are generated into [api/](./api/). | +| [STABILITY.md](./STABILITY.md) | stability contract | What `@stable` / `@experimental` promise consumers, the graduation bar, and the demotion/removal policy. | | [concepts.md](./concepts.md) | mental model | The product-API layer cake (chat turns, tasks, runs) — the onramp before the loop/strategy docs. | | [glossary.md](./glossary.md) | canonical vocabulary | One definition per term, grounded to `file:line`; drifted synonyms flagged. | | [execution-model.md](./execution-model.md) | the picture | The unified `Executor` port (router/bridge/cli/sandbox/BYO) + two engines, driver vs worker, spawn mechanics. | diff --git a/docs/STABILITY.md b/docs/STABILITY.md new file mode 100644 index 00000000..b15fa581 --- /dev/null +++ b/docs/STABILITY.md @@ -0,0 +1,40 @@ +# API stability — what `@stable` and `@experimental` mean + +Every exported symbol in this package carries a maturity level, declared with the TSDoc modifier tags `@stable` and `@experimental` (`@stable` is defined in [`tsdoc.json`](../tsdoc.json); `@experimental` is a TSDoc built-in). +This doc defines what those tags promise, how a symbol graduates, and how one is demoted or removed. + +## What the tags mean for consumers + +**`@stable`** — the symbol's shape and documented behavior are a contract. +You can build a product on it. +A breaking change to a stable symbol goes through the demotion/removal process below: it is never silent, never same-release, and always ships with a named migration path in the CHANGELOG. + +**`@experimental`** — the symbol may change shape, change behavior, or disappear in any release, with only a CHANGELOG line. +Use it to build, not to depend on: pin an exact version if an experimental symbol is load-bearing for you, and expect to follow the CHANGELOG when you bump. + +**Where a tag lives.** +A tag on the symbol itself always wins. +An untagged symbol inherits the module-level tag of the file that declares it. +An untagged symbol in an untagged module is **experimental by default** — stability is opt-in and explicit, never assumed. +A member-level `@experimental` inside a `@stable` interface marks that one member (an extension point) as still movable while the rest of the interface is contractual. + +**Where you see it.** +The generated reference ([`docs/api/`](./api/)) renders **`Stable`** / **`Experimental`** badges on tagged symbols, and each subpath page (e.g. [`api/intelligence.md`](./api/intelligence.md)) renders its module-level badge directly under the page title. +Module-level tags on non-entry source files are authoritative for inheritance but only render through the subpath page and per-symbol badges. + +## Graduation bar — experimental → stable + +A symbol (or a whole subpath) is promoted only when **all** of the following hold: + +1. **Substantive test coverage** — tests that exercise the documented behavior, not just imports that compile. +2. **A curated-doc section** — the symbol appears in a hand-maintained doc ([`canonical-api.md`](./canonical-api.md), a dedicated doc such as [`intelligence-sdk.md`](./intelligence-sdk.md), or a subpath guide); a generated `api/` page alone does not count. +3. **At least one real consumer** — `bench/`, `examples/`, or an external package actually calls it on a real path. +4. **No breaking change to its API in the last 30 days** — the shape has stopped moving before the promise is made. +5. **A CHANGELOG graduation entry** — the release notes name every promoted symbol and record the evidence for 1–3. + +Promotion is a normal PR: flip the tags (per-symbol and module-level), add the CHANGELOG entry, regenerate `docs/api`. + +## Demotion and removal + +A `@stable` symbol is demoted back to `@experimental`, or removed, only through a deprecation cycle: the release that announces it adds `@deprecated` (naming the replacement or the reason) while the symbol keeps working, the CHANGELOG entry names the symbol and the migration path, and removal lands no earlier than the next minor release after the announcement. +An `@experimental` symbol needs none of that — it can be reshaped or removed in any release with a CHANGELOG line — which is exactly why the default is experimental and the stable set is enumerated, not implied. diff --git a/docs/api/candidate-execution.md b/docs/api/candidate-execution.md index 69203b88..960c73f5 100644 --- a/docs/api/candidate-execution.md +++ b/docs/api/candidate-execution.md @@ -6,6 +6,11 @@ # candidate-execution +**`Experimental`** + +`@tangle-network/agent-runtime/candidate-execution` — sealed candidate bundles +plus the isolated prepare/execute/finalize/recover lifecycle around them. + ## References ### AgentCandidateCodeSource diff --git a/docs/api/index.md b/docs/api/index.md index 6f6b0065..57050634 100644 --- a/docs/api/index.md +++ b/docs/api/index.md @@ -7923,6 +7923,8 @@ Dollar accounting is known unless explicitly false. A false value must not be tr ### Scope +**`Stable`** + The budget-conserving reactive scope an `Agent.act` runs inside. `spawn` reserves budget atomically from the shared pool and fails closed when the pool cannot cover it. `next()` waits for one settlement from this scope's live set; `view` reads live state, @@ -7949,6 +7951,8 @@ This scope's abort signal — aborted when the run is cancelled, a breaker trips > `readonly` `optional` **resume?**: [`ResumedWork`](runtime.md#resumedwork)\<`Out`\> +**`Experimental`** + Prior committed work, present ONLY on a resumed run (`undefined` on a fresh run, which is every run that did not pass `SupervisorOpts.resume`). The supervisor `loadTree`s the journal first; when a non-empty tree exists it rehydrates the already-settled children (via @@ -7957,6 +7961,9 @@ re-spawning committed work. A resume-blind driver simply ignores it and re-spawn but redundant. The scope's spawn ordinal + cursor seq are already advanced past the recorded maxima, so any NEW spawn appends without colliding with a journaled event. + Same-process replay only — live supervised-tree recovery after a +coordinator restart is not implemented (docs/agent-managed-compute/README.md). + ##### view > `readonly` **view**: [`TreeView`](runtime.md#treeview) @@ -8183,6 +8190,8 @@ metered event is cost-critical, so it lands before the join-barrier roll-up). ### Supervisor +**`Stable`** + Owns the conserved pool, the spawn log, the abort cascade, the OTP intensity breaker, and the root handle. `run` executes the root `Agent` to completion; `attach` wires a live `RootHandle` (the Q2 substrate the chat/pi-viz client later consumes). @@ -8239,7 +8248,7 @@ live `RootHandle` (the Q2 substrate the chat/pi-viz client later consumes). ### Driver -**`Experimental`** +**`Stable`** #### Type Parameters @@ -8261,8 +8270,6 @@ live `RootHandle` (the Q2 substrate the chat/pi-viz client later consumes). > `readonly` `optional` **name?**: `string` -**`Experimental`** - Stable identifier surfaced in trace events. Default `'driver'`. #### Methods @@ -8271,8 +8278,6 @@ Stable identifier surfaced in trace events. Default `'driver'`. > **plan**(`task`, `history`): `Promise`\<`Task`[]\> -**`Experimental`** - Tasks to issue this iteration. `[task]` → refine; N copies → fanout; `[]` → no more work this round (kernel proceeds to `decide`). @@ -8294,8 +8299,6 @@ readonly [`Iteration`](runtime.md#iteration-1)\<`Task`, `Output`\>[] > **decide**(`history`): `Decision` \| `Promise`\<`Decision`\> -**`Experimental`** - Inspect history and return the next state. The kernel terminates the loop when `decide` returns a value listed in `isTerminalDecision` (`'stop' | 'pick-winner' | 'fail' | 'done'`), when `maxIterations` @@ -8315,8 +8318,6 @@ readonly [`Iteration`](runtime.md#iteration-1)\<`Task`, `Output`\>[] > `optional` **describePlan**(): [`LoopPlanDescription`](runtime.md#loopplandescription) \| `undefined` -**`Experimental`** - Optional: describe the move `plan()` just produced, for trace emission. The kernel calls this immediately after `plan()` and emits the result in the `loop.plan` event so a topology viewer can render the agent's chosen @@ -8356,7 +8357,7 @@ readonly [`Iteration`](runtime.md#iteration-1)\<`Task`, `Output`\>[] ### LoopResult -**`Experimental`** +**`Stable`** #### Type Parameters @@ -8378,64 +8379,46 @@ readonly [`Iteration`](runtime.md#iteration-1)\<`Task`, `Output`\>[] > **decision**: `Decision` -**`Experimental`** - ##### iterations > **iterations**: [`Iteration`](runtime.md#iteration-1)\<`Task`, `Output`\>[] -**`Experimental`** - ##### winner? > `optional` **winner?**: [`LoopWinner`](runtime.md#loopwinner)\<`Task`, `Output`\> -**`Experimental`** - ##### durationMs > **durationMs**: `number` -**`Experimental`** - ##### costUsd > **costUsd**: `number` -**`Experimental`** - Sum of every iteration's `costUsd`. ##### costUsdKnown? > `optional` **costUsdKnown?**: `false` -**`Experimental`** - False when `costUsd` is only the observed subtotal, not a complete bill. ##### estimatedCostUsd? > `optional` **estimatedCostUsd?**: `number` -**`Experimental`** - Sum of separately-labelled local/catalog estimates. ##### promptCache? > `optional` **promptCache?**: `Record`\<`string`, `string` \| `number`\> -**`Experimental`** - Aggregated provider-reported prompt-cache fields. ##### tokenUsage > **tokenUsage**: [`LoopTokenUsage`](runtime.md#looptokenusage) -**`Experimental`** - Sum of every iteration's token usage. `loopDispatch` commits it through the campaign's paid-call receipt. @@ -8443,8 +8426,6 @@ Sum of every iteration's token usage. `loopDispatch` commits it through > **provenance**: [`RunProvenance`](runtime.md#runprovenance) -**`Experimental`** - Domain-free run provenance for auditability: the mount manifest recorded during `prepareBox` and the selection receipts for how the winner was chosen. Always present; empty arrays when nothing was recorded. diff --git a/docs/api/intelligence.md b/docs/api/intelligence.md index 6340f213..29f46248 100644 --- a/docs/api/intelligence.md +++ b/docs/api/intelligence.md @@ -6,6 +6,24 @@ # intelligence +**`Stable`** + +Tangle Intelligence SDK — trace capture plus reviewable improvement. + +The client keeps live-agent trace delivery best-effort. The separate +improvement-cycle exports analyze completed traces, run a signed baseline +versus candidate experiment, bind review to its result, and activate only +the exact measured candidate. + + 1. OBSERVE — wrap a generic agent and export one trace span per call to + Tangle Intelligence, swallowing every export failure so a live agent + never fails because Intelligence is down. + 2. MODE 0 / OFF — at `effort: 'off'`, run the agent as PURE PASSTHROUGH + (zero intelligence spawns) with best-effort telemetry still on. The + exported trace tags usage by class `{ inferenceUsd, intelligenceUsd }`, + and at OFF `intelligenceUsd` is provably `0` — the mechanism that proves + an OFF customer paid inference-only. + ## Classes ### CapabilityNotAdmittedError diff --git a/docs/api/mcp.md b/docs/api/mcp.md index d5f90814..47c11914 100644 --- a/docs/api/mcp.md +++ b/docs/api/mcp.md @@ -6,6 +6,17 @@ # mcp +`@tangle-network/agent-runtime/mcp` — Stdio MCP server exposing the +delegation tools to sandbox coding-harness agents: the generic `delegate` +(one intent → a supervisor that authors + drives its own worker, returns the +delivered output with its cost), plus the queue-bound `delegate_feedback`, +`delegation_status`, and `delegation_history`. `delegate_ui_audit` is served +when a `uiAuditorDelegate` is wired. + +Mount the server inside a product agent's sandbox via +`agent-runtime-mcp` (the bin) or wire it into a custom Node entry +point with `createMcpServer({ ... })`. + ## Classes ### CodexExecutionDiagnosticError @@ -62,7 +73,7 @@ Thrown when reproducible Codex exits without one valid terminal usage event. ### DelegationStateCorruptError -**`Experimental`** +**`Stable`** The persisted delegation state exists but cannot be parsed into records. Fail loud: silently starting empty over a corrupt journal @@ -81,8 +92,6 @@ which archives the corrupt file and starts fresh. > **new DelegationStateCorruptError**(`message`, `options?`): [`DelegationStateCorruptError`](#delegationstatecorrupterror) -**`Experimental`** - ###### Parameters ###### message @@ -107,7 +116,7 @@ which archives the corrupt file and starts fresh. ### DelegationPersistenceError -**`Experimental`** +**`Stable`** A delegation-store read or write failed (filesystem error, store called before `loadAll`, ...). Once the queue observes one, it stops @@ -124,8 +133,6 @@ silently demote durable mode to in-memory mode. > **new DelegationPersistenceError**(`message`, `options?`): [`DelegationPersistenceError`](#delegationpersistenceerror) -**`Experimental`** - ###### Parameters ###### message @@ -150,7 +157,7 @@ silently demote durable mode to in-memory mode. ### InMemoryDelegationStore -**`Experimental`** +**`Stable`** In-memory `DelegationStore` — suitable for single-process use and tests. @@ -164,8 +171,6 @@ In-memory `DelegationStore` — suitable for single-process use and tests. > **new InMemoryDelegationStore**(): [`InMemoryDelegationStore`](#inmemorydelegationstore) -**`Experimental`** - ###### Returns [`InMemoryDelegationStore`](#inmemorydelegationstore) @@ -176,8 +181,6 @@ In-memory `DelegationStore` — suitable for single-process use and tests. > **loadAll**(): `Promise`\<[`DelegationRecord`](#delegationrecord)[]\> -**`Experimental`** - Read every persisted record. Called once, by `DelegationTaskQueue.restore`, before any write. A missing backing file is an empty store; an unparseable one throws @@ -195,8 +198,6 @@ file is an empty store; an unparseable one throws > **upsert**(`record`): `Promise`\<`void`\> -**`Experimental`** - Insert or replace the record keyed by `record.taskId`. ###### Parameters @@ -217,8 +218,6 @@ Insert or replace the record keyed by `record.taskId`. > **lookupIdempotencyKey**(`key`): `Promise`\<`string` \| `undefined`\> -**`Experimental`** - Resolve an idempotency key to the taskId that claimed it, if any. The queue serves submit-time dedupe from its rehydrated in-memory index; this read exists for consumers that share a store across @@ -242,8 +241,6 @@ processes without holding the full record set. > **remove**(`taskIds`): `Promise`\<`void`\> -**`Experimental`** - Delete the named records — the retention-cap eviction path. ###### Parameters @@ -264,7 +261,7 @@ readonly `string`[] ### FileDelegationStore -**`Experimental`** +**`Stable`** JSON-file persistence for the delegation queue. Each write serializes the full record set and lands it atomically (write to a sibling tmp @@ -286,8 +283,6 @@ and corruption-detectable without a database dependency. > **new FileDelegationStore**(`options`): [`FileDelegationStore`](#filedelegationstore) -**`Experimental`** - ###### Parameters ###### options @@ -304,8 +299,6 @@ and corruption-detectable without a database dependency. > **loadAll**(): `Promise`\<[`DelegationRecord`](#delegationrecord)[]\> -**`Experimental`** - Read every persisted record. Called once, by `DelegationTaskQueue.restore`, before any write. A missing backing file is an empty store; an unparseable one throws @@ -323,8 +316,6 @@ file is an empty store; an unparseable one throws > **upsert**(`record`): `Promise`\<`void`\> -**`Experimental`** - Insert or replace the record keyed by `record.taskId`. ###### Parameters @@ -345,8 +336,6 @@ Insert or replace the record keyed by `record.taskId`. > **lookupIdempotencyKey**(`key`): `Promise`\<`string` \| `undefined`\> -**`Experimental`** - Resolve an idempotency key to the taskId that claimed it, if any. The queue serves submit-time dedupe from its rehydrated in-memory index; this read exists for consumers that share a store across @@ -370,8 +359,6 @@ processes without holding the full record set. > **remove**(`taskIds`): `Promise`\<`void`\> -**`Experimental`** - Delete the named records — the retention-cap eviction path. ###### Parameters @@ -392,7 +379,7 @@ readonly `string`[] ### InMemoryFeedbackStore -**`Experimental`** +**`Stable`** In-memory `FeedbackStore` — suitable for single-process use and tests. @@ -406,8 +393,6 @@ In-memory `FeedbackStore` — suitable for single-process use and tests. > **new InMemoryFeedbackStore**(): [`InMemoryFeedbackStore`](#inmemoryfeedbackstore) -**`Experimental`** - ###### Returns [`InMemoryFeedbackStore`](#inmemoryfeedbackstore) @@ -418,8 +403,6 @@ In-memory `FeedbackStore` — suitable for single-process use and tests. > **put**(`event`): `Promise`\<`void`\> -**`Experimental`** - Append a new event. Never dedupes — every rating is its own event. ###### Parameters @@ -440,8 +423,6 @@ Append a new event. Never dedupes — every rating is its own event. > **list**(`filter?`): `Promise`\<[`FeedbackEvent`](#feedbackevent)[]\> -**`Experimental`** - List events filtered by `namespace`. When `namespace` is omitted, list across all namespaces. Returns events in insertion order. @@ -469,7 +450,7 @@ across all namespaces. Returns events in insertion order. ### DelegationTaskQueue -**`Experimental`** +**`Stable`** In-process queue for async delegation tasks — submit, cancel, poll status, and read history. @@ -479,8 +460,6 @@ In-process queue for async delegation tasks — submit, cancel, poll status, and > **new DelegationTaskQueue**(`options?`): [`DelegationTaskQueue`](#delegationtaskqueue) -**`Experimental`** - ###### Parameters ###### options? @@ -497,8 +476,6 @@ In-process queue for async delegation tasks — submit, cancel, poll status, and > `static` **restore**(`options?`): `Promise`\<[`DelegationTaskQueue`](#delegationtaskqueue)\> -**`Experimental`** - Construct a queue from previously-persisted state. Loads every record from `options.store`, rebuilds the idempotency index (so a re-submitted identical task returns the prior taskId and its terminal state), then: @@ -525,8 +502,6 @@ The retention cap applies to the loaded set as well. > **submit**\<`Args`\>(`input`): [`SubmitOutput`](#submitoutput) -**`Experimental`** - Kick off a delegation in the background. Returns immediately. The `taskId` is queryable via `status` once this method returns. Throws the recorded `DelegationPersistenceError` once the store has failed — @@ -552,8 +527,6 @@ the queue does not accept work it cannot journal. > **status**(`taskId`, `opts?`): [`DelegationStatusResult`](#delegationstatusresult) \| `undefined` -**`Experimental`** - Snapshot the current state of a delegation. Returns `undefined` for unknown ids so callers can distinguish missing from terminal. `includeTrace` attaches the journaled loop-trace span tree — off by @@ -579,8 +552,6 @@ default so status polls stay light. > **cancel**(`taskId`): `boolean` -**`Experimental`** - Abort an in-flight delegation. Returns `false` if the task is unknown or already terminal. The underlying `run` function MUST honor the abort signal for the cancel to take effect; the queue marks the @@ -601,8 +572,6 @@ UI on `running` forever. > **attachFeedback**(`taskId`, `snapshot`): `boolean` -**`Experimental`** - Append a feedback event to the matching delegation. Returns `false` when `ref` does not name a known taskId — the caller should still record the feedback through a different surface (artifact/outcome @@ -626,8 +595,6 @@ kinds are not queue-bound). > **history**(`args?`): [`DelegationHistoryEntry`](#delegationhistoryentry)[] -**`Experimental`** - Query the recorded delegations. Returns entries newest-first (by `startedAt`), truncated to `limit`. @@ -645,8 +612,6 @@ Query the recorded delegations. Returns entries newest-first (by > **flush**(): `Promise`\<`void`\> -**`Experimental`** - Await every journal write issued so far. Rejects with the recorded `DelegationPersistenceError` when any of them failed. Call before handing the store's backing file to another process. @@ -659,8 +624,6 @@ handing the store's backing file to another process. > **inflightCount**(): `number` -**`Experimental`** - Test-only — number of in-flight (non-terminal) records. ###### Returns @@ -1015,7 +978,7 @@ Same gate as the streaming path: an unapproved candidate cannot win. ### DelegationStore -**`Experimental`** +**`Stable`** #### Methods @@ -1023,8 +986,6 @@ Same gate as the streaming path: an unapproved candidate cannot win. > **loadAll**(): `Promise`\<[`DelegationRecord`](#delegationrecord)[]\> -**`Experimental`** - Read every persisted record. Called once, by `DelegationTaskQueue.restore`, before any write. A missing backing file is an empty store; an unparseable one throws @@ -1038,8 +999,6 @@ file is an empty store; an unparseable one throws > **upsert**(`record`): `Promise`\<`void`\> -**`Experimental`** - Insert or replace the record keyed by `record.taskId`. ###### Parameters @@ -1056,8 +1015,6 @@ Insert or replace the record keyed by `record.taskId`. > **lookupIdempotencyKey**(`key`): `Promise`\<`string` \| `undefined`\> -**`Experimental`** - Resolve an idempotency key to the taskId that claimed it, if any. The queue serves submit-time dedupe from its rehydrated in-memory index; this read exists for consumers that share a store across @@ -1077,8 +1034,6 @@ processes without holding the full record set. > **remove**(`taskIds`): `Promise`\<`void`\> -**`Experimental`** - Delete the named records — the retention-cap eviction path. ###### Parameters @@ -1095,7 +1050,7 @@ readonly `string`[] ### FileDelegationStoreOptions -**`Experimental`** +**`Stable`** #### Properties @@ -1103,16 +1058,12 @@ readonly `string`[] > **filePath**: `string` -**`Experimental`** - Absolute path of the JSON state file. Parent directories are created on first write. ##### recoverCorrupt? > `optional` **recoverCorrupt?**: `boolean` -**`Experimental`** - When the state file exists but cannot be parsed, archive it to `.corrupt-` and start empty instead of throwing `DelegationStateCorruptError`. Default false. @@ -1827,7 +1778,7 @@ machineId so workers don't compete with the orchestrator on the same VM. ### FeedbackEvent -**`Experimental`** +**`Stable`** #### Properties @@ -1835,43 +1786,31 @@ machineId so workers don't compete with the orchestrator on the same VM. > **id**: `string` -**`Experimental`** - ##### refersTo > **refersTo**: [`FeedbackRefersTo`](#feedbackrefersto) -**`Experimental`** - ##### rating > **rating**: [`FeedbackRating`](#feedbackrating) -**`Experimental`** - ##### by > **by**: `"agent"` \| `"user"` \| `"downstream-judge"` -**`Experimental`** - ##### capturedAt > **capturedAt**: `string` -**`Experimental`** - ##### namespace? > `optional` **namespace?**: `string` -**`Experimental`** - *** ### FeedbackStore -**`Experimental`** +**`Stable`** #### Methods @@ -1879,8 +1818,6 @@ machineId so workers don't compete with the orchestrator on the same VM. > **put**(`event`): `Promise`\<`void`\> -**`Experimental`** - Append a new event. Never dedupes — every rating is its own event. ###### Parameters @@ -1897,8 +1834,6 @@ Append a new event. Never dedupes — every rating is its own event. > **list**(`filter?`): `Promise`\<[`FeedbackEvent`](#feedbackevent)[]\> -**`Experimental`** - List events filtered by `namespace`. When `namespace` is omitted, list across all namespaces. Returns events in insertion order. @@ -3166,7 +3101,7 @@ Stop a `serve` call. Subsequent requests are rejected. ### DelegationRecord -**`Experimental`** +**`Stable`** Must be JSON-safe end to end (`args`, `result`, `error`, `feedback`) — persistent stores round-trip records through `JSON.stringify`. @@ -3177,82 +3112,56 @@ persistent stores round-trip records through `JSON.stringify`. > **taskId**: `string` -**`Experimental`** - ##### profile > **profile**: [`DelegationProfile`](#delegationprofile) -**`Experimental`** - ##### namespace? > `optional` **namespace?**: `string` -**`Experimental`** - ##### args > **args**: [`DelegationArgs`](#delegationargs) -**`Experimental`** - ##### status > **status**: [`DelegationStatus`](#delegationstatus) -**`Experimental`** - ##### progress? > `optional` **progress?**: [`DelegationProgress`](#delegationprogress) -**`Experimental`** - ##### result? > `optional` **result?**: [`DelegationResultPayload`](#delegationresultpayload) -**`Experimental`** - ##### error? > `optional` **error?**: [`DelegationError`](#delegationerror) -**`Experimental`** - ##### costUsd? > `optional` **costUsd?**: `number` -**`Experimental`** - ##### startedAt > **startedAt**: `string` -**`Experimental`** - ##### completedAt? > `optional` **completedAt?**: `string` -**`Experimental`** - ##### idempotencyKey? > `optional` **idempotencyKey?**: `string` -**`Experimental`** - Sha-prefix hash of the canonical input — used for idempotency lookup. ##### detachedSessionRef? > `optional` **detachedSessionRef?**: `string` -**`Experimental`** - Caller-generated deterministic id of a detached run (e.g. the sandbox session id a single-tick driver resumes by). Presence is what makes a restored in-flight record resumable via `resumeDelegate`; without it a @@ -3262,16 +3171,12 @@ restart settles the record as failed. > **feedback**: [`DelegationFeedbackSnapshot`](#delegationfeedbacksnapshot)[] -**`Experimental`** - Feedback events keyed by this delegation's taskId. ##### trace? > `optional` **trace?**: [`DelegationTraceSpan`](#delegationtracespan)[] -**`Experimental`** - Compact loop-trace span tree teed from the delegation's run, oldest spans first. Appended when a delegated loop reaches `loop.ended` and settled (partial buffers included) at the terminal transition. Capped @@ -3281,16 +3186,12 @@ via `capDelegationTrace` — see `traceTruncated`. > `optional` **traceTruncated?**: `true` -**`Experimental`** - Present when oldest trace spans were dropped to honor the trace caps. ##### traceId? > `optional` **traceId?**: `string` -**`Experimental`** - Inherited trace identity (the queue's `traceContext` at submit time — typically `readTraceContextFromEnv()`), distinct from the span payload: a journal consumer joins records into the parent trace by these ids @@ -3300,15 +3201,13 @@ without parsing spans. Restored records keep their persisted identity. > `optional` **parentSpanId?**: `string` -**`Experimental`** - Caller span that dispatched the delegation, when one was inherited. *** ### SubmitInput -**`Experimental`** +**`Stable`** #### Type Parameters @@ -3322,32 +3221,22 @@ Caller span that dispatched the delegation, when one was inherited. > **profile**: [`DelegationProfile`](#delegationprofile) -**`Experimental`** - ##### args > **args**: `Args` -**`Experimental`** - ##### namespace? > `optional` **namespace?**: `string` -**`Experimental`** - ##### idempotencyKey? > `optional` **idempotencyKey?**: `string` -**`Experimental`** - ##### detachedSessionRef? > `optional` **detachedSessionRef?**: `string` -**`Experimental`** - Records the detached-run resume key on the new record. The submitted `run` function still executes in-process exactly as without it — the ref only matters after a restart, when `DelegationTaskQueue.restore` @@ -3357,8 +3246,6 @@ hands it to the `resumeDelegate` seam instead of failing the record. > **run**: (`ctx`) => `Promise`\<[`CoderOutput`](#coderoutput) \| [`UiAuditorDelegationOutput`](#uiauditordelegationoutput) \| [`ResearchOutputShape`](#researchoutputshape)\> -**`Experimental`** - Runs the underlying delegation. The queue passes a fresh `AbortSignal` and a `report` channel for incremental progress updates. The function MUST resolve with the typed `DelegationResultPayload['output']`; the @@ -3378,7 +3265,7 @@ queue wraps it with the profile tag. ### DelegationRunContext -**`Experimental`** +**`Stable`** Context handed to a `SubmitInput.run` function. @@ -3388,22 +3275,16 @@ Context handed to a `SubmitInput.run` function. > **signal**: `AbortSignal` -**`Experimental`** - ##### detachedSessionRef? > `optional` **detachedSessionRef?**: `string` -**`Experimental`** - The `detachedSessionRef` recorded at submit, when one was supplied. ##### traceEmitter? > `optional` **traceEmitter?**: [`LoopTraceEmitter`](runtime.md#looptraceemitter) -**`Experimental`** - Per-delegation loop-trace sink, always provided by the queue. Events emitted here are journaled onto the record as a compact span tree (`record.trace`) when each loop run ends and at the delegation's @@ -3418,8 +3299,6 @@ contexts stay source-compatible. > **report**(`progress`): `void` -**`Experimental`** - ###### Parameters ###### progress @@ -3434,8 +3313,6 @@ contexts stay source-compatible. > **updateDetachedSessionRef**(`ref`): `void` -**`Experimental`** - Replace the record's detached-run resume key — the detached dispatch path calls this once the sandbox id is known so the persisted ref names a resolvable box. Ignored after the record settles (a cancel racing the @@ -3456,7 +3333,7 @@ ref — erasing the resume key would silently make the record unresumable. ### SubmitOutput -**`Experimental`** +**`Stable`** #### Properties @@ -3464,21 +3341,17 @@ ref — erasing the resume key would silently make the record unresumable. > **taskId**: `string` -**`Experimental`** - ##### reused > **reused**: `boolean` -**`Experimental`** - True when a prior matching `idempotencyKey` returned an existing record. *** ### DelegationResumeContext -**`Experimental`** +**`Stable`** #### Properties @@ -3486,8 +3359,6 @@ True when a prior matching `idempotencyKey` returned an existing record. > **signal**: `AbortSignal` -**`Experimental`** - Fired by `cancel(taskId)`; the driver should stop the remote run when it can. #### Methods @@ -3496,8 +3367,6 @@ Fired by `cancel(taskId)`; the driver should stop the remote run when it can. > **report**(`progress`): `void` -**`Experimental`** - ###### Parameters ###### progress @@ -3512,7 +3381,7 @@ Fired by `cancel(taskId)`; the driver should stop the remote run when it can. ### DelegationResumeDriver -**`Experimental`** +**`Stable`** Re-attaches restored in-flight records to their detached runs. The queue calls `tick` repeatedly — it never awaits a whole run — so the driver can @@ -3527,8 +3396,6 @@ terminal and are not retried. > `optional` **intervalMs?**: `number` -**`Experimental`** - Delay between `running` ticks, in milliseconds. Default 5000. #### Methods @@ -3537,8 +3404,6 @@ Delay between `running` ticks, in milliseconds. Default 5000. > **tick**(`task`, `ctx`): `Promise`\<[`DelegationResumeTick`](#delegationresumetick)\> -**`Experimental`** - ###### Parameters ###### task @@ -3563,7 +3428,7 @@ Delay between `running` ticks, in milliseconds. Default 5000. ### DelegationTaskQueueOptions -**`Experimental`** +**`Stable`** #### Properties @@ -3571,8 +3436,6 @@ Delay between `running` ticks, in milliseconds. Default 5000. > `optional` **generateId?**: () => `string` -**`Experimental`** - ID generator override; default `randomTaskId`. ###### Returns @@ -3583,8 +3446,6 @@ ID generator override; default `randomTaskId`. > `optional` **now?**: () => `string` -**`Experimental`** - Clock override; default `() => new Date().toISOString()`. ###### Returns @@ -3595,8 +3456,6 @@ Clock override; default `() => new Date().toISOString()`. > `optional` **store?**: [`DelegationStore`](#delegationstore) -**`Experimental`** - Journal for record mutations and the `restore()` load source. Default `InMemoryDelegationStore` — observably identical to an unjournaled queue. Pass a `FileDelegationStore` through @@ -3607,16 +3466,12 @@ constructing with `new` never loads prior state. > `optional` **resumeDelegate?**: [`DelegationResumeDriver`](#delegationresumedriver) -**`Experimental`** - Resume seam for restored in-flight records that carry a `detachedSessionRef`. ##### maxTerminalRecords? > `optional` **maxTerminalRecords?**: `number` -**`Experimental`** - Maximum number of terminal (completed | failed | cancelled) records retained; the oldest (by `completedAt`) are evicted from memory and store once the cap is exceeded. Default unbounded. @@ -3625,8 +3480,6 @@ store once the cap is exceeded. Default unbounded. > `optional` **onPersistError?**: (`error`) => `void` -**`Experimental`** - Observes the first store failure. After it fires, the queue refuses new submissions and `flush()` rejects with the same error. Default: rethrow on a microtask — an unhandled crash — because silently @@ -3646,8 +3499,6 @@ degrading durable mode to memory-only would lie to the caller. > `optional` **traceContext?**: [`TraceContext`](#tracecontext-2) -**`Experimental`** - Inherited trace identity stamped on every submitted record (`traceId` / `parentSpanId`). The bin passes `readTraceContextFromEnv()` so journal consumers can join delegation @@ -4250,7 +4101,7 @@ nobody is left to read a finding, and analysts spend real compute). Returns the ### DelegateFeedbackHandlerOptions -**`Experimental`** +**`Stable`** #### Properties @@ -4258,20 +4109,14 @@ nobody is left to read a finding, and analysts spend real compute). Returns the > **queue**: [`DelegationTaskQueue`](#delegationtaskqueue) -**`Experimental`** - ##### store > **store**: [`FeedbackStore`](#feedbackstore) -**`Experimental`** - ##### generateId? > `optional` **generateId?**: () => `string` -**`Experimental`** - ###### Returns `string` @@ -4280,8 +4125,6 @@ nobody is left to read a finding, and analysts spend real compute). Returns the > `optional` **now?**: () => `string` -**`Experimental`** - ###### Returns `string` @@ -4360,7 +4203,7 @@ What killed a delegation, projected for the calling agent: the rejection's name ### DelegateHandlerOptions -**`Experimental`** +**`Stable`** #### Properties @@ -4368,47 +4211,37 @@ What killed a delegation, projected for the calling agent: the rejection's name > **router**: [`RouterTransportConfig`](runtime.md#routertransportconfig) -**`Experimental`** - The supervisor brain's router substrate (REQUIRED — the default supervisor is router-brained). ##### supervisorProfile > **supervisorProfile**: `AgentProfile` -**`Experimental`** - Exact executable supervisor identity selected by the trusted composition root. ##### backend > **backend**: [`ExecutorConfig`](runtime.md#executorconfig) -**`Experimental`** - WHERE the authored workers run. Required for `supervise()` to spawn anything. ##### deliverable? > `optional` **deliverable?**: [`DeliverableSpec`](runtime.md#deliverablespec)\<`unknown`\> -**`Experimental`** - The completion oracle the authored workers settle against (settled ⟺ delivered). ##### allowedModels? > `optional` **allowedModels?**: readonly `string`[] -**`Experimental`** - Restrict the run to this subset of models. *** ### DelegationHistoryHandlerOptions -**`Experimental`** +**`Stable`** #### Properties @@ -4416,13 +4249,11 @@ Restrict the run to this subset of models. > **queue**: [`DelegationTaskQueue`](#delegationtaskqueue) -**`Experimental`** - *** ### DelegationStatusHandlerOptions -**`Experimental`** +**`Stable`** #### Properties @@ -4430,8 +4261,6 @@ Restrict the run to this subset of models. > **queue**: [`DelegationTaskQueue`](#delegationtaskqueue) -**`Experimental`** - *** ### TraceContext @@ -5659,7 +5488,7 @@ with no translation step. > **DelegationArgs** = [`DelegateCodeArgs`](#delegatecodeargs) \| [`DelegateResearchArgs`](#delegateresearchargs) \| [`DelegateUiAuditArgs`](#delegateuiauditargs) -**`Experimental`** +**`Stable`** Arguments accepted by the durable delegation queue. @@ -5669,7 +5498,7 @@ Arguments accepted by the durable delegation queue. > **DelegationResumeTick** = \{ `state`: `"running"`; \} \| \{ `state`: `"completed"`; `output`: [`DelegationResultPayload`](#delegationresultpayload)\[`"output"`\]; `costUsd?`: `number`; \} \| \{ `state`: `"failed"`; `error`: [`DelegationError`](#delegationerror); \} -**`Experimental`** +**`Stable`** One observation of a detached run, mapped 1:1 from a single-tick driver (e.g. the sandbox SDK's `driveTurn`, which reports @@ -5866,7 +5695,7 @@ Env var overriding the served display name (default 'agent-memory'). > `const` **DELEGATE\_FEEDBACK\_TOOL\_NAME**: `"delegate_feedback"` = `'delegate_feedback'` -**`Experimental`** +**`Stable`** MCP tool name for the `delegate_feedback` feedback-recording tool. @@ -5876,7 +5705,7 @@ MCP tool name for the `delegate_feedback` feedback-recording tool. > `const` **DELEGATE\_FEEDBACK\_DESCRIPTION**: `string` -**`Experimental`** +**`Stable`** Human-readable description of the `delegate_feedback` MCP tool, injected into the tool manifest. @@ -5886,7 +5715,7 @@ Human-readable description of the `delegate_feedback` MCP tool, injected into th > `const` **DELEGATE\_FEEDBACK\_INPUT\_SCHEMA**: `object` -**`Experimental`** +**`Stable`** JSON Schema for `delegate_feedback` tool arguments (`refersTo`, `rating`, `by`, optional fields). @@ -6314,7 +6143,7 @@ JSON Schema for `delegate_ui_audit` tool arguments (`workspaceDir`, `routes`, op > `const` **DELEGATE\_TOOL\_NAME**: `"delegate"` = `'delegate'` -**`Experimental`** +**`Stable`** MCP tool name for the `delegate` generic-delegation tool. @@ -6324,7 +6153,7 @@ MCP tool name for the `delegate` generic-delegation tool. > `const` **DELEGATE\_DESCRIPTION**: `string` -**`Experimental`** +**`Stable`** Human-readable description of the `delegate` MCP tool, injected into the tool manifest. @@ -6334,7 +6163,7 @@ Human-readable description of the `delegate` MCP tool, injected into the tool ma > `const` **DELEGATE\_INPUT\_SCHEMA**: `object` -**`Experimental`** +**`Stable`** JSON Schema for `delegate` tool arguments (`intent` + optional trace id). @@ -6386,7 +6215,7 @@ JSON Schema for `delegate` tool arguments (`intent` + optional trace id). > `const` **DELEGATION\_HISTORY\_TOOL\_NAME**: `"delegation_history"` = `'delegation_history'` -**`Experimental`** +**`Stable`** MCP tool name for the `delegation_history` read-past-delegations tool. @@ -6396,7 +6225,7 @@ MCP tool name for the `delegation_history` read-past-delegations tool. > `const` **DELEGATION\_HISTORY\_DESCRIPTION**: `string` -**`Experimental`** +**`Stable`** Human-readable description of the `delegation_history` MCP tool, injected into the tool manifest. @@ -6406,7 +6235,7 @@ Human-readable description of the `delegation_history` MCP tool, injected into t > `const` **DELEGATION\_HISTORY\_INPUT\_SCHEMA**: `object` -**`Experimental`** +**`Stable`** JSON Schema for `delegation_history` tool arguments (optional `namespace`, `profile`, `since`, `limit`). @@ -6478,7 +6307,7 @@ JSON Schema for `delegation_history` tool arguments (optional `namespace`, `prof > `const` **DELEGATION\_STATUS\_TOOL\_NAME**: `"delegation_status"` = `'delegation_status'` -**`Experimental`** +**`Stable`** MCP tool name for the `delegation_status` synchronous-poll tool. @@ -6488,7 +6317,7 @@ MCP tool name for the `delegation_status` synchronous-poll tool. > `const` **DELEGATION\_STATUS\_DESCRIPTION**: `string` -**`Experimental`** +**`Stable`** Human-readable description of the `delegation_status` MCP tool, injected into the tool manifest. @@ -6498,7 +6327,7 @@ Human-readable description of the `delegation_status` MCP tool, injected into th > `const` **DELEGATION\_STATUS\_INPUT\_SCHEMA**: `object` -**`Experimental`** +**`Stable`** JSON Schema for `delegation_status` tool arguments (`taskId` + optional `includeTrace`). @@ -6938,7 +6767,7 @@ cross-sandbox copy step. > **eventToSnapshot**(`event`): [`DelegationFeedbackSnapshot`](#delegationfeedbacksnapshot) -**`Experimental`** +**`Stable`** Project a `FeedbackEvent` down to the snapshot shape carried on `delegation_history` entries. @@ -7216,7 +7045,7 @@ client writes to it) and the server-side stream (the test reads from it). > **hashIdempotencyInput**(`value`): `string` -**`Experimental`** +**`Stable`** Best-effort stable hash for use as `idempotencyKey`. Not cryptographic; collisions only affect dedupe, never correctness. @@ -7273,7 +7102,7 @@ Build the driver's MCP tools over a live scope. > **validateDelegateFeedbackArgs**(`raw`): [`DelegateFeedbackArgs`](#delegatefeedbackargs) -**`Experimental`** +**`Stable`** Parse and validate raw MCP tool input into typed `DelegateFeedbackArgs`; throws `TypeError` on bad input. @@ -7293,7 +7122,7 @@ Parse and validate raw MCP tool input into typed `DelegateFeedbackArgs`; throws > **createDelegateFeedbackHandler**(`options`): (`raw`) => `Promise`\<[`DelegateFeedbackResult`](#delegatefeedbackresult)\> -**`Experimental`** +**`Stable`** Build the MCP tool handler that persists feedback events and attaches them to delegation records. @@ -7353,7 +7182,7 @@ Build the MCP tool handler that validates input, deduplicates via idempotency ke > **validateDelegateArgs**(`raw`): [`DelegateArgs`](#delegateargs) -**`Experimental`** +**`Stable`** Parse and validate raw MCP tool input into typed `DelegateArgs`; throws `TypeError` on bad input. @@ -7393,7 +7222,7 @@ delivered output with its conserved cost. > **validateDelegationHistoryArgs**(`raw`): [`DelegationHistoryArgs`](#delegationhistoryargs) -**`Experimental`** +**`Stable`** Parse and validate raw MCP tool input into typed `DelegationHistoryArgs`; throws `TypeError` on bad input. @@ -7413,7 +7242,7 @@ Parse and validate raw MCP tool input into typed `DelegationHistoryArgs`; throws > **createDelegationHistoryHandler**(`options`): (`raw`) => `Promise`\<[`DelegationHistoryResult`](#delegationhistoryresult)\> -**`Experimental`** +**`Stable`** Build the MCP tool handler that reads filtered past delegations from a `DelegationTaskQueue`. @@ -7433,7 +7262,7 @@ Build the MCP tool handler that reads filtered past delegations from a `Delegati > **validateDelegationStatusArgs**(`raw`): [`DelegationStatusArgs`](#delegationstatusargs) -**`Experimental`** +**`Stable`** Parse and validate raw MCP tool input into typed `DelegationStatusArgs`; throws `TypeError` on bad input. @@ -7453,7 +7282,7 @@ Parse and validate raw MCP tool input into typed `DelegationStatusArgs`; throws > **createDelegationStatusHandler**(`options`): (`raw`) => `Promise`\<[`DelegationStatusResult`](#delegationstatusresult)\> -**`Experimental`** +**`Stable`** Build the MCP tool handler that polls a `DelegationTaskQueue` for task status. diff --git a/docs/api/primitive-catalog.md b/docs/api/primitive-catalog.md index 1e043e88..f5b979af 100644 --- a/docs/api/primitive-catalog.md +++ b/docs/api/primitive-catalog.md @@ -7,7 +7,7 @@ # Primitive catalog — the never-stale anti-reinvention inventory -> **GENERATED** from `@tangle-network/agent-runtime@0.129.0` and `@tangle-network/agent-eval@0.144.4` by `scripts/gen-primitive-catalog.mjs`. Do NOT hand-edit — run `pnpm run docs:api`. This is the mechanical companion to the JUDGMENT in `canonical-api.md` (§2 decision table + §1.5 AgentProfile law): that doc says WHICH primitive to reach for and what NOT to build; this catalog proves WHAT exists. Per-symbol signatures + `file:line` live in the per-module pages under `docs/api/`. +> **GENERATED** from `@tangle-network/agent-runtime@0.130.0` and `@tangle-network/agent-eval@0.144.4` by `scripts/gen-primitive-catalog.mjs`. Do NOT hand-edit — run `pnpm run docs:api`. This is the mechanical companion to the JUDGMENT in `canonical-api.md` (§2 decision table + §1.5 AgentProfile law): that doc says WHICH primitive to reach for and what NOT to build; this catalog proves WHAT exists. Per-symbol signatures + `file:line` live in the per-module pages under `docs/api/`. ## 1. agent-runtime — own public surface @@ -823,6 +823,7 @@ Import from `@tangle-network/agent-runtime/kernel` — 709 exports. | `EqualKArm` | interface | One arm of an equal-k comparison — a labeled trajectory (a `TrajectoryReport` is one arm's whole | | `EqualKOnCostOptions` | interface | `equalKOnCost(arms, { tolerance? })` — assert arms are comparable at EQUAL conserved COST | | `EqualKVerdict` | interface | The equal-k-on-cost verdict: whether every arm spent within `tolerance` of the others on the | +| `EventBus` | interface | The child→parent coordination bus surface: publish, priority-ordered pull, pass-through subscribe, history, and stats. | | `ExecCtx` | interface | Execution context for `runAgentRounds`: the sandbox client the kernel creates boxes through, plus optional runtime hooks. | | `Executor` | interface | The leaf runtime — ONE open interface, not a closed union. `execute` returns a | | `ExecutorAccounting` | interface | Split used by a recursive executor when journaled child work differs from the full amount | @@ -1069,7 +1070,7 @@ Import from `@tangle-network/agent-runtime/kernel` — 709 exports. | `WorktreeCheckRunner` | type | The single shell-command-in-worktree runner seam (replaces the per-executor copies). | | `WorktreePatchArtifact` | type | Terminal artifact of one worktree-CLI run — the canonical worktree-harness result (the captured | -**Undocumented supporting types** (add a TSDoc line at the declaration to earn a table row): `AcquireOptions`, `AgentEnvironment`, `AgentEnvironmentCapabilities`, `AgentEnvironmentEvent`, `AgentEnvironmentProvider`, `AgentEnvironmentQuery`, `AgentEnvironmentSummary`, `AgentGraph`, `AgenticOptions`, `AgenticRunResult`, `AgenticTask`, `AgenticTool`, `AgentSession`, `AgentSessionRef`, `AgentTurnResult`, `AllWorkersStalledOptions`, `AnalystRegistry`, `AnytimeReport`, `AnytimeStrategySummary`, `AnytimeTaskCurve`, `ArtifactHandle`, `AuditIntentInput`, `AuditIntentOptions`, `AuthoredHarness`, `AuthoredStrategy`, `AuthorStrategyOptions`, `BenchmarkConfig`, `BenchmarkLift`, `BenchmarkStrategySummary`, `BenchmarkTaskRow`, `BudgetPool`, `BusStats`, `ChampionPick`, `CheckpointRef`, `CheckpointRequest`, `CheckRunContext`, `CliWorktreeBridgeSeam`, `CoordinationMcpHandle`, `CopyOptions`, `CorpusReadbackOptions`, `CreateAgentEnvironmentInput`, `CreateTangleSandboxExactProcessProviderOptions`, `DefinedLeaderboard`, `DispatchReport`, `Driver`, `EventBus`, `EvolutionArchiveNode`, `EvolutionAuthor`, `EvolutionBandInfo`, `EvolutionCandidate`, `EvolutionGeneration`, `EvolutionReport`, `ExecRequest`, `ExecResult`, `ExecutorResultMapping`, `ForkRequest`, `GitWorkspaceOptions`, `GraphResult`, `HarvestCorpusOptions`, `HarvestFailure`, `HarvestReport`, `Inbox`, `InProcessSandboxClientOptions`, `IntentAudit`, `Iteration`, `Leaderboard`, `LeaderboardOptions`, `LocalSandboxClientOptions`, `LoopDecisionPayload`, `LoopDispatchOptions`, `LoopEndedPayload`, `LoopIterationEndedPayload`, `LoopIterationStartedPayload`, `LoopPlanDescription`, `LoopResult`, `LoopSandboxPlacement`, `LoopStartedPayload`, `LoopTraceEmitter`, `LoopWinner`, `MaterializeLocalMcpOptions`, `McpEnvironmentOptions`, `McpToolDescriptor`, `NodeSnapshot`, `NoProgressForOptions`, `Observation`, `ObserveInput`, `ObserveOptions`, `OpenSandboxRunOptions`, `PairwiseOptions`, `PatchDeliverableOptions`, `PlacementInfo`, `PlateauOptions`, `ProgressTrackerOptions`, `PromotionGateOptions`, `PromotionVerdict`, `PublishOptions`, `ReproductionCheck`, `ResolveSandboxClientOptions`, `ResourceRequest`, `RollingDispatchOptions`, `RunAgenticOptions`, `RunAgentRoundsOptions`, `RunGraphOptions`, `SandboxRun`, `ShotSpec`, `SpawnOpts`, `StdioMcpConnection`, `StdioMcpServerSpec`, `SteerableSandboxArgs`, `Strategy`, `StrategyEvolutionConfig`, `StrategyResult`, `StreamAgentTurnOptions`, `StructuralRolloutConfig`, `SuperviseOptions`, `SuperviseSurfaceOptions`, `SupervisorAgentDeps`, `SupervisorOpts`, `SupervisorSpanOptions`, `SupervisorSpanRecorder`, `SurfaceScore`, `ToolSpec`, `ToolStepInput`, `TraceSource`, `TrajectoryAnalysis`, `UntrackedCopyStats`, `ValidationCtx`, `Validator`, `VerifierEnvironmentOptions`, `WatchTraceOptions`, `WaterfallCollector`, `WaterfallReport`, `WaterfallSpan`, `WorkerEvidenceInput`, `Workspace`, `WorkspaceRequest`, `WorkspaceRun`, `WorktreeCliExecutorOptions`, `WorktreeFanoutOptions`, `AgentEnvironmentStatus`, `AgentSessionStatus`, `ChampionPolicy`, `EdgeDeliveryOutcome`, `GraphEdge`, `LoopTraceEvent`, `MakeWorkerAgent`, `RepairStop`, `SandboxControlClient`, `WorkspaceCommit`. +**Undocumented supporting types** (add a TSDoc line at the declaration to earn a table row): `AcquireOptions`, `AgentEnvironment`, `AgentEnvironmentCapabilities`, `AgentEnvironmentEvent`, `AgentEnvironmentProvider`, `AgentEnvironmentQuery`, `AgentEnvironmentSummary`, `AgentGraph`, `AgenticOptions`, `AgenticRunResult`, `AgenticTask`, `AgenticTool`, `AgentSession`, `AgentSessionRef`, `AgentTurnResult`, `AllWorkersStalledOptions`, `AnalystRegistry`, `AnytimeReport`, `AnytimeStrategySummary`, `AnytimeTaskCurve`, `ArtifactHandle`, `AuditIntentInput`, `AuditIntentOptions`, `AuthoredHarness`, `AuthoredStrategy`, `AuthorStrategyOptions`, `BenchmarkConfig`, `BenchmarkLift`, `BenchmarkStrategySummary`, `BenchmarkTaskRow`, `BudgetPool`, `BusStats`, `ChampionPick`, `CheckpointRef`, `CheckpointRequest`, `CheckRunContext`, `CliWorktreeBridgeSeam`, `CoordinationMcpHandle`, `CopyOptions`, `CorpusReadbackOptions`, `CreateAgentEnvironmentInput`, `CreateTangleSandboxExactProcessProviderOptions`, `DefinedLeaderboard`, `DispatchReport`, `Driver`, `EvolutionArchiveNode`, `EvolutionAuthor`, `EvolutionBandInfo`, `EvolutionCandidate`, `EvolutionGeneration`, `EvolutionReport`, `ExecRequest`, `ExecResult`, `ExecutorResultMapping`, `ForkRequest`, `GitWorkspaceOptions`, `GraphResult`, `HarvestCorpusOptions`, `HarvestFailure`, `HarvestReport`, `Inbox`, `InProcessSandboxClientOptions`, `IntentAudit`, `Iteration`, `Leaderboard`, `LeaderboardOptions`, `LocalSandboxClientOptions`, `LoopDecisionPayload`, `LoopDispatchOptions`, `LoopEndedPayload`, `LoopIterationEndedPayload`, `LoopIterationStartedPayload`, `LoopPlanDescription`, `LoopResult`, `LoopSandboxPlacement`, `LoopStartedPayload`, `LoopTraceEmitter`, `LoopWinner`, `MaterializeLocalMcpOptions`, `McpEnvironmentOptions`, `McpToolDescriptor`, `NodeSnapshot`, `NoProgressForOptions`, `Observation`, `ObserveInput`, `ObserveOptions`, `OpenSandboxRunOptions`, `PairwiseOptions`, `PatchDeliverableOptions`, `PlacementInfo`, `PlateauOptions`, `ProgressTrackerOptions`, `PromotionGateOptions`, `PromotionVerdict`, `PublishOptions`, `ReproductionCheck`, `ResolveSandboxClientOptions`, `ResourceRequest`, `RollingDispatchOptions`, `RunAgenticOptions`, `RunAgentRoundsOptions`, `RunGraphOptions`, `SandboxRun`, `ShotSpec`, `SpawnOpts`, `StdioMcpConnection`, `StdioMcpServerSpec`, `SteerableSandboxArgs`, `Strategy`, `StrategyEvolutionConfig`, `StrategyResult`, `StreamAgentTurnOptions`, `StructuralRolloutConfig`, `SuperviseOptions`, `SuperviseSurfaceOptions`, `SupervisorAgentDeps`, `SupervisorOpts`, `SupervisorSpanOptions`, `SupervisorSpanRecorder`, `SurfaceScore`, `ToolSpec`, `ToolStepInput`, `TraceSource`, `TrajectoryAnalysis`, `UntrackedCopyStats`, `ValidationCtx`, `Validator`, `VerifierEnvironmentOptions`, `WatchTraceOptions`, `WaterfallCollector`, `WaterfallReport`, `WaterfallSpan`, `WorkerEvidenceInput`, `Workspace`, `WorkspaceRequest`, `WorkspaceRun`, `WorktreeCliExecutorOptions`, `WorktreeFanoutOptions`, `AgentEnvironmentStatus`, `AgentSessionStatus`, `ChampionPolicy`, `EdgeDeliveryOutcome`, `GraphEdge`, `LoopTraceEvent`, `MakeWorkerAgent`, `RepairStop`, `SandboxControlClient`, `WorkspaceCommit`. ### Environment provider adapters — generic sandbox/compute bridge diff --git a/docs/api/profiles.md b/docs/api/profiles.md index a2ca2ec4..6267fa1f 100644 --- a/docs/api/profiles.md +++ b/docs/api/profiles.md @@ -6,6 +6,12 @@ # profiles +**`Experimental`** + +Authored `AgentProfile` presets (the §1.5 author-the-profile DATA) for common agent roles, each +with a pure task-to-prompt formatter. The substrate materializes a profile into a harness +invocation; "is it delivered" is a `DeliverableSpec`, not a bundled validator. + ## Interfaces ### AuditRegistry @@ -537,6 +543,8 @@ Optional task — narrows the validator's namespace check. ### UiFindingScreenshot +**`Experimental`** + Pointer to a screenshot referenced by a finding (workspace-relative path). #### Properties @@ -545,18 +553,26 @@ Pointer to a screenshot referenced by a finding (workspace-relative path). > **path**: `string` +**`Experimental`** + ##### viewport? > `optional` **viewport?**: `string` +**`Experimental`** + ##### label? > `optional` **label?**: `string` +**`Experimental`** + *** ### UiFinding +**`Experimental`** + A single UI audit finding — the unit of work a contributor can act on. Every field except the documented optionals is required. The auditor @@ -569,90 +585,122 @@ lens, missing title, etc. > `optional` **id?**: `number` +**`Experimental`** + Monotonic id assigned by the writer when persisting. Optional in-transit. ##### title > **title**: `string` +**`Experimental`** + ##### lens > **lens**: [`UiLens`](#uilens) +**`Experimental`** + ##### severity > **severity**: [`UiFindingSeverity`](#uifindingseverity) +**`Experimental`** + ##### route > **route**: `string` +**`Experimental`** + Logical route the finding was observed on (e.g. `home`, `checkout-step-2`). ##### url? > `optional` **url?**: `string` +**`Experimental`** + Fully qualified URL the finding was observed at. ##### viewport? > `optional` **viewport?**: `string` +**`Experimental`** + Viewport string the offending capture was taken at (e.g. `1280x800`). ##### selector? > `optional` **selector?**: `string` +**`Experimental`** + CSS selector pinning the offending element, when one can be identified. ##### observation > **observation**: `string` +**`Experimental`** + 1–3 sentences describing what the screenshot shows that is wrong. ##### impact > **impact**: `string` +**`Experimental`** + Who is affected and how. ##### suggestedFix > **suggestedFix**: `string` +**`Experimental`** + A specific change a contributor could apply without asking back. ##### reproSteps? > `optional` **reproSteps?**: `string` +**`Experimental`** + Optional explicit reproduction steps. Writer synthesizes from route/url/selector when omitted. ##### tags? > `optional` **tags?**: readonly `string`[] +**`Experimental`** + Free-form tags. ##### screenshots > **screenshots**: readonly [`UiFindingScreenshot`](#uifindingscreenshot)[] +**`Experimental`** + Screenshot references — must be non-empty for actionable findings. ##### similarTo? > `optional` **similarTo?**: readonly `number`[] +**`Experimental`** + Cross-references to similar findings already on file, by id. ##### createdAt? > `optional` **createdAt?**: `string` +**`Experimental`** + ISO-8601 creation timestamp set by the writer when persisted. *** @@ -923,6 +971,8 @@ these — the caller decides. > **UiLens** = `"consistency"` \| `"hierarchy"` \| `"layout"` \| `"ux-flow"` \| `"duplication"` \| `"accessibility"` \| `"responsive"` \| `"states"` \| `"content"` \| `"interaction"` \| `"performance-perceived"` \| `"other"` +**`Experimental`** + Canonical audit lenses. Each lens scopes a finding to a single class of problem so a single audit pass can iterate them without pile-on findings under a generic label. @@ -933,6 +983,8 @@ under a generic label. > **UiFindingSeverity** = `"low"` \| `"med"` \| `"high"` \| `"critical"` +**`Experimental`** + Severity scale. - `critical` — blocks a core task or is an accessibility blocker. - `high` — confusing, broken-looking, or noticeable friction. @@ -965,6 +1017,8 @@ Per-lens auditor briefs: concrete signals to look for and cross-lens distinction > `const` **UI\_LENSES**: readonly [`UiLens`](#uilens)[] +**`Experimental`** + Frozen tuple of lenses for validation + iteration. *** @@ -973,6 +1027,8 @@ Frozen tuple of lenses for validation + iteration. > `const` **UI\_FINDING\_SEVERITIES**: readonly [`UiFindingSeverity`](#uifindingseverity)[] +**`Experimental`** + Frozen severity tuple, ordered worst → least bad for sort/report. ## Functions diff --git a/docs/api/runtime.md b/docs/api/runtime.md index a6149872..afde9792 100644 --- a/docs/api/runtime.md +++ b/docs/api/runtime.md @@ -6,10 +6,19 @@ # runtime +Driven-loop substrate. `runAgentRounds` orchestrates around the sandbox SDK; it +does not invent its own notion of "what an agent is". Each iteration is +a `sandboxClient.create({ backend: { profile } })` + `box.streamPrompt` +call. The driver owns topology; the validator owns scoring; the output +adapter owns event-stream decode; the kernel owns iteration accounting, +concurrency, abort, cost aggregation, and trace emission. + ## Classes ### InMemoryResultBlobStore +**`Stable`** + In-memory `ResultBlobStore`. Content-addressed: `put` verifies the supplied `outRef` matches the artifact's hash so a stale/forged ref fails loud rather than silently rehydrating the wrong payload. Idempotent on an identical re-put. @@ -74,6 +83,8 @@ silently rehydrating the wrong payload. Idempotent on an identical re-put. ### FileResultBlobStore +**`Stable`** + FS `ResultBlobStore`. One JSON file per artifact under `dir`, named by a filesystem-safe encoding of the `outRef` (`sha256:` → `sha256-.json`). `put` fsyncs so a crash between writes never loses an acknowledged blob. @@ -144,6 +155,8 @@ filesystem-safe encoding of the `outRef` (`sha256:` → `sha256-.json` ### InMemorySpawnJournal +**`Stable`** + In-memory `SpawnJournal`. Appends are observed-committed only; the impl enforces the corruption guards a durable replay rests on: - an event before `beginTree` is a corrupted tree (fail loud), @@ -232,6 +245,8 @@ the corruption guards a durable replay rests on: ### FileSpawnJournal +**`Stable`** + JSONL on disk. One line per record: the first record is `begin`, subsequent records are `event` envelopes wrapping a `SpawnEvent`. `loadTree` replays the whole file, filtering by `root`, and applies the same begin-precedes-events + unique-seq @@ -6076,7 +6091,7 @@ The headline when both `refine` and `sample` ran: paired-bootstrap lift of refin ### RunAgentRoundsOptions -**`Experimental`** +**`Stable`** #### Type Parameters @@ -6098,14 +6113,10 @@ The headline when both `refine` and `sample` ran: paired-bootstrap lift of refin > **driver**: [`Driver`](index.md#driver)\<`Task`, `Output`, `Decision`\> -**`Experimental`** - ##### agentRun? > `optional` **agentRun?**: [`AgentRunSpec`](#agentrunspec)\<`Task`\> -**`Experimental`** - Single agent spec — every iteration uses this profile. Mutually exclusive with `agentRuns`. @@ -6113,8 +6124,6 @@ exclusive with `agentRuns`. > `optional` **agentRuns?**: [`AgentRunSpec`](#agentrunspec)\<`Task`\>[] -**`Experimental`** - Multiple specs for heterogeneous fanout. The kernel round-robins through them when the driver plans N tasks. Mutually exclusive with `agentRun`. @@ -6123,48 +6132,34 @@ through them when the driver plans N tasks. Mutually exclusive with > **output**: [`OutputAdapter`](#outputadapter)\<`Output`\> -**`Experimental`** - ##### validator? > `optional` **validator?**: [`Validator`](#validator-1)\<`Output`, `DefaultVerdict`\> -**`Experimental`** - ##### task > **task**: `Task` -**`Experimental`** - ##### ctx > **ctx**: [`ExecCtx`](#execctx) -**`Experimental`** - ##### maxIterations? > `optional` **maxIterations?**: `number` -**`Experimental`** - Default 10. Hard cap on total iterations across all `plan()` rounds. ##### maxConcurrency? > `optional` **maxConcurrency?**: `number` -**`Experimental`** - Default 4. In-flight worker cap within a single `plan()` batch. ##### runId? > `optional` **runId?**: `string` -**`Experimental`** - Pre-allocated id for trace correlation. Default = `loop-${random}`. Surfaces as `runId` on every emitted `LoopTraceEvent`. @@ -6172,8 +6167,6 @@ Surfaces as `runId` on every emitted `LoopTraceEvent`. > `optional` **now?**: () => `number` -**`Experimental`** - Clock override; default `Date.now`. Deterministic tests pass a monotonic counter to stabilize iteration timing fields. @@ -6185,8 +6178,6 @@ monotonic counter to stabilize iteration timing fields. > `optional` **selectWinner?**: (`iterations`) => [`LoopWinner`](#loopwinner)\<`Task`, `Output`\> \| `undefined` -**`Experimental`** - Override the default winner selector (highest-valid-score, ties broken by earliest iteration). @@ -6204,8 +6195,6 @@ by earliest iteration). > `optional` **onWorkerBox?**: (`box`) => `void` -**`Experimental`** - Same-sandbox driver mode — a kernel→caller out-channel, not a value handed in. When set, the kernel keeps each finished worker box alive across the `plan()` boundary and hands it here, so a same-sandbox planner @@ -8567,7 +8556,7 @@ budget: refine→max shots; sample→rollout width. ### StreamAgentTurnOptions -**`Experimental`** +**`Stable`** #### Properties @@ -8575,16 +8564,12 @@ budget: refine→max shots; sample→rollout width. > `optional` **signal?**: `AbortSignal` -**`Experimental`** - Caller-initiated cancellation. Terminates the stream with `final.status: 'aborted'`. ##### timeoutMs? > `optional` **timeoutMs?**: `number` -**`Experimental`** - Wall-clock deadline for the whole turn in ms. An expired deadline aborts the backend and terminates the stream with `final.status: 'failed'` (a blown deadline is a turn failure, not a caller cancellation). @@ -8593,24 +8578,18 @@ the backend and terminates the stream with `final.status: 'failed'` > `optional` **callId?**: `string` -**`Experimental`** - Stable logical paid-call id, forwarded as the provider idempotency key and retained in evidence. ##### correlationId? > `optional` **correlationId?**: `string` -**`Experimental`** - Caller trace tag retained in evidence and forwarded when the transport supports it. ##### preserveToolParts? > `optional` **preserveToolParts?**: `boolean` -**`Experimental`** - Opt-in tool-part projection for box and executor backends: sandbox tool parts additionally surface in-stream as `tool_call` / `tool_result` events (`mapSandboxToolEvent`), so a consumer @@ -8623,8 +8602,6 @@ tool events included when the backend produces them). > `optional` **onRawEvent?**: (`event`) => `void` \| `Promise`\<`void`\> -**`Experimental`** - Raw-event tap for box-kind backends: called (and awaited) with every unmapped `SandboxEvent` BEFORE it is projected, so a consumer can read parts the chat-UX projection drops (part ids, step markers, custom @@ -8646,7 +8623,7 @@ has no sandbox events. ### AgentTurnUsage -**`Experimental`** +**`Stable`** Metered usage of one turn, summed over every cost-bearing event the backend emitted. `input`/`output` are token counts and are accompanied by @@ -8659,71 +8636,53 @@ are present only when the backend actually reported them. > **input**: `number` -**`Experimental`** - ##### output > **output**: `number` -**`Experimental`** - ##### tokensKnown? > `optional` **tokensKnown?**: `false` -**`Experimental`** - Present when a real turn ran but the provider did not report token usage. ##### costUsd? > `optional` **costUsd?**: `number` -**`Experimental`** - ##### usdKnown? > `optional` **usdKnown?**: `false` -**`Experimental`** - Present when Runtime could not prove the full dollar amount. ##### estimatedCostUsd? > `optional` **estimatedCostUsd?**: `number` -**`Experimental`** - Separately-labelled local/catalog estimate; never billed spend. ##### promptCache? > `optional` **promptCache?**: `Readonly`\<`Record`\<`string`, `string` \| `number`\>\> -**`Experimental`** - Provider-reported prompt-cache fields; absent fields remain unknown. ##### reasoningTokens? > `optional` **reasoningTokens?**: `number` -**`Experimental`** - Provider-reported reasoning-token subset of output, when available. ##### model? > `optional` **model?**: `string` -**`Experimental`** - *** ### CollectedAgentTurn -**`Experimental`** +**`Stable`** A drained turn: the terminal summary plus every event the stream yielded. `status`/`error` mirror the terminal `final` event so a failed or aborted @@ -8735,36 +8694,26 @@ turn stays inspectable without re-scanning `events`. > **finalText**: `string` -**`Experimental`** - ##### output? > `optional` **output?**: `unknown` -**`Experimental`** - Exact terminal artifact output from a Runtime-owned executor. ##### usage > **usage**: [`AgentTurnUsage`](#agentturnusage) -**`Experimental`** - ##### transportAttempts? > `optional` **transportAttempts?**: `number` -**`Experimental`** - Exact underlying transport calls when the Runtime-owned executor reports them. ##### toolCalls > **toolCalls**: `object`[] -**`Experimental`** - ###### id? > `optional` **id?**: `string` @@ -8781,20 +8730,14 @@ Exact underlying transport calls when the Runtime-owned executor reports them. > **events**: [`RuntimeStreamEvent`](index.md#runtimestreamevent)[] -**`Experimental`** - ##### status > **status**: [`AgentTaskStatus`](index.md#agenttaskstatus) -**`Experimental`** - ##### error? > `optional` **error?**: [`BackendErrorDetail`](index.md#backenderrordetail) -**`Experimental`** - *** ### StructuralRolloutPolicy @@ -10379,6 +10322,12 @@ Count published per event `type`. ### EventBus +**`Experimental`** + +The child→parent coordination bus surface: publish, priority-ordered pull, pass-through subscribe, history, and stats. + In-process only — the durable cross-process mailbox this interface is designed +to admit is not implemented (docs/agent-managed-compute/README.md). + #### Type Parameters ##### E @@ -10391,6 +10340,8 @@ Count published per event `type`. > **publish**(`event`, `opts?`): `Promise`\<[`BusRecord`](#busrecord)\<`E`\>\> +**`Experimental`** + Stamp the event, await every subscriber in order, then make it pull-visible. A subscriber failure leaves the event invisible and retrying the SAME event object reuses the exact stamp. This lets an awaited product observer commit its record before a supervisor can consume it. @@ -10413,6 +10364,8 @@ Stamp the event, await every subscriber in order, then make it pull-visible. A s > **pull**(`kinds?`): `E` \| `undefined` +**`Experimental`** + Remove and return the highest-priority QUEUED event whose type is in `kinds` (any if omitted), ties broken FIFO by `seq`; `undefined` when nothing matches. @@ -10430,6 +10383,8 @@ readonly `E`\[`"type"`\][] > **subscribe**(`handler`): () => `void` +**`Experimental`** + Register a pass-through handler; it receives the stamped record of every event published after registration. Returns an unsubscribe fn. @@ -10447,6 +10402,8 @@ Register a pass-through handler; it receives the stamped record of every event p > **pending**(`kinds?`): `number` +**`Experimental`** + Count of queued, not-yet-pulled events (filtered by `kinds` when given). ###### Parameters @@ -10463,6 +10420,8 @@ readonly `E`\[`"type"`\][] > **history**(): readonly [`BusRecord`](#busrecord)\<`E`\>[] +**`Experimental`** + The full ordered log of every event published in this process (audit evidence, not replay). ###### Returns @@ -10473,6 +10432,8 @@ readonly [`BusRecord`](#busrecord)\<`E`\>[] > **stats**(): [`BusStats`](#busstats) +**`Experimental`** + Throughput counters for observability dashboards. ###### Returns @@ -15116,6 +15077,8 @@ trips the supervisor to `no-winner` rather than restarting forever. > `readonly` `optional` **resume?**: `boolean` +**`Experimental`** + Opt into RESUME-FIRST: read any prior journal tree for this `runId` BEFORE beginning a fresh one, and when a non-empty tree exists rehydrate its committed work onto `Scope.resume` (`replaySpawnTree` + `materializeTreeView`) instead of starting over. Requires a journal + @@ -15125,6 +15088,9 @@ stores there is never a prior tree, so it is a no-op. Default `false` — a run always begins a fresh tree, which is the behavior every existing consumer has. Resume is a durability contract the caller opts into, never a silent default. + Rehydrates committed settlements only; live supervised-tree recovery after a +coordinator restart is not implemented (docs/agent-managed-compute/README.md). + ##### now? > `readonly` `optional` **now?**: () => `number` @@ -16181,7 +16147,7 @@ Notified each time a compaction fires — for observability/metering. ### ValidationCtx -**`Experimental`** +**`Stable`** #### Properties @@ -16189,16 +16155,12 @@ Notified each time a compaction fires — for observability/metering. > **iteration**: `number` -**`Experimental`** - Iteration index this output came from (0-based). ##### box? > `optional` **box?**: `SandboxInstance` -**`Experimental`** - Live sandbox for this iteration. Validators that need execution-grounded evidence can inspect files or run commands here instead of forcing callers to bypass the loop kernel with raw Sandbox SDK orchestration. @@ -16207,16 +16169,12 @@ to bypass the loop kernel with raw Sandbox SDK orchestration. > **signal**: `AbortSignal` -**`Experimental`** - Cooperative cancellation channel. ##### traceEmitter? > `optional` **traceEmitter?**: [`LoopTraceEmitter`](#looptraceemitter) -**`Experimental`** - Optional trace emitter. When set, validator implementations that make LLM calls (e.g. an LLM-judge reviewer) emit spans into it. The kernel passes `ctx.traceEmitter` from `ExecCtx` when available. @@ -16225,7 +16183,7 @@ The kernel passes `ctx.traceEmitter` from `ExecCtx` when available. ### Validator -**`Experimental`** +**`Stable`** #### Type Parameters @@ -16243,8 +16201,6 @@ The kernel passes `ctx.traceEmitter` from `ExecCtx` when available. > **validate**(`output`, `ctx`): `Promise`\<`Verdict`\> -**`Experimental`** - ###### Parameters ###### output @@ -16263,7 +16219,7 @@ The kernel passes `ctx.traceEmitter` from `ExecCtx` when available. ### AgentRunSpec -**`Experimental`** +**`Stable`** Sandbox-SDK-shaped agent specification. @@ -16285,16 +16241,12 @@ through them when the driver plans N tasks. > **profile**: `AgentProfile` -**`Experimental`** - Sandbox SDK profile — what kind of agent runs the task. ##### taskToPrompt > **taskToPrompt**: (`task`) => `string` -**`Experimental`** - Task → prompt formatter. Pure and deterministic. ###### Parameters @@ -16311,8 +16263,6 @@ Task → prompt formatter. Pure and deterministic. > `optional` **prepareBox?**: (`box`, `ctx`) => `void` \| `Promise`\<`void`\> -**`Experimental`** - Optional pre-prompt sandbox provisioner. Runs after the sandbox is acquired and before the first prompt is streamed into that box. Use this for domain-agnostic setup such as repo snapshots, benchmark fixtures, policy @@ -16349,8 +16299,6 @@ meaning to the entries; not calling it simply leaves the manifest empty. > `optional` **name?**: `string` -**`Experimental`** - Per-spec stable name. Surfaced in trace events and the default winner selector tiebreak. Falls back to `profile.name ?? 'agent'`. @@ -16358,8 +16306,6 @@ selector tiebreak. Falls back to `profile.name ?? 'agent'`. > `optional` **sandboxOverrides?**: `Partial`\<`Omit`\<`CreateSandboxOptions`, `"backend"`\>\> & `object` -**`Experimental`** - Optional sandbox-SDK `CreateSandboxOptions` overrides merged on top of the kernel's defaults. `backend.profile` is set to `profile` by the kernel and cannot be overridden here — use `profile` itself for that. @@ -16374,7 +16320,7 @@ kernel and cannot be overridden here — use `profile` itself for that. ### OutputAdapter -**`Experimental`** +**`Stable`** Stream of `SandboxEvent`s → typed `Output`. @@ -16394,8 +16340,6 @@ persisted streams during tests / replays. > **parse**(`events`): `Output` -**`Experimental`** - ###### Parameters ###### events @@ -16433,7 +16377,7 @@ False when the subtotal is incomplete. ### MountManifestEntry -**`Experimental`** +**`Stable`** One mounted resource recorded during box preparation — a pure provenance record of what the caller placed into a box before the agent saw it. The @@ -16449,16 +16393,12 @@ auditable after the fact ("what exactly was this agent given?"). > **path**: `string` -**`Experimental`** - Destination path inside the box where the resource was placed. ##### sha256 > **sha256**: `string` -**`Experimental`** - Hex SHA-256 of the mounted bytes. The caller computes it from the bytes it wrote — the kernel does not hash box contents. @@ -16466,16 +16406,12 @@ Hex SHA-256 of the mounted bytes. The caller computes it from the bytes > **bytes**: `number` -**`Experimental`** - Size of the mounted resource in bytes. ##### source > **source**: `string` -**`Experimental`** - Free-form origin of the resource (e.g. a repo ref, a corpus id, a local path, a URL). Provenance only — the kernel attaches no meaning to it. @@ -16483,7 +16419,7 @@ Free-form origin of the resource (e.g. a repo ref, a corpus id, a local ### SelectionReceipt -**`Experimental`** +**`Stable`** A record of one candidate-selection decision: which iteration the selector picked (or rejected) and why. Pure audit trail of the SELECTOR role — it @@ -16497,40 +16433,30 @@ per scored candidate at finalize so a run answers "why did THIS one win?". > **candidateIndex**: `number` -**`Experimental`** - Iteration index this receipt is about. ##### selected > **selected**: `boolean` -**`Experimental`** - True for the iteration the selector chose as winner; false otherwise. ##### score? > `optional` **score?**: `number` -**`Experimental`** - The candidate's verdict score, when it has one. ##### reason? > `optional` **reason?**: `string` -**`Experimental`** - Why this candidate was (or was not) selected, when the selector states it. ##### selector > **selector**: `"default"` \| `"driver"` \| `"caller"` -**`Experimental`** - Identity of the selector that produced this receipt — `'caller'` (an explicit `selectWinner`), `'driver'` (a driver-authored winner), or `'default'` (the kernel's best-valid-score argmax). @@ -16539,7 +16465,7 @@ Identity of the selector that produced this receipt — `'caller'` (an ### RunProvenance -**`Experimental`** +**`Stable`** Domain-free run provenance: a manifest of what was mounted into the run's boxes and the receipts for how the winner was selected. Surfaced on @@ -16553,23 +16479,19 @@ candidate to select. > **mounts**: [`MountManifestEntry`](#mountmanifestentry)[] -**`Experimental`** - Every resource recorded via `prepareBox`'s `recordMount`, in record order. ##### selectionReceipts > **selectionReceipts**: [`SelectionReceipt`](#selectionreceipt)[] -**`Experimental`** - One receipt per scored candidate at finalize, in iteration order. *** ### Iteration -**`Experimental`** +**`Stable`** #### Type Parameters @@ -16587,105 +16509,77 @@ One receipt per scored candidate at finalize, in iteration order. > **index**: `number` -**`Experimental`** - 0-based iteration index assigned by the kernel. ##### task > **task**: `Task` -**`Experimental`** - ##### agentRunName > **agentRunName**: `string` -**`Experimental`** - Stable name of the `AgentRunSpec` that produced this iteration. ##### output? > `optional` **output?**: `Output` -**`Experimental`** - ##### verdict? > `optional` **verdict?**: `DefaultVerdict` -**`Experimental`** - ##### error? > `optional` **error?**: `Error` -**`Experimental`** - ##### events > **events**: `SandboxEvent`[] -**`Experimental`** - Raw sandbox event stream collected for this iteration. ##### startedAt > **startedAt**: `number` -**`Experimental`** - ##### endedAt > **endedAt**: `number` -**`Experimental`** - ##### costUsd > **costUsd**: `number` -**`Experimental`** - ##### costUsdKnown? > `optional` **costUsdKnown?**: `false` -**`Experimental`** - False when `costUsd` is only the observed subtotal, not a complete bill. ##### estimatedCostUsd? > `optional` **estimatedCostUsd?**: `number` -**`Experimental`** - Local/catalog estimates remain separate from billed spend. ##### promptCache? > `optional` **promptCache?**: `Record`\<`string`, `string` \| `number`\> -**`Experimental`** - Provider-reported prompt-cache fields; absent fields remain unknown. ##### tokenUsage > **tokenUsage**: [`LoopTokenUsage`](#looptokenusage) -**`Experimental`** - Summed LLM token usage across every `llm_call` event in this iteration. *** ### LoopPlanDescription -**`Experimental`** +**`Stable`** Driver-supplied description of the just-planned move. @@ -16695,24 +16589,18 @@ Driver-supplied description of the just-planned move. > **kind**: `string` -**`Experimental`** - Topology move this round — e.g. `'refine' | 'fanout' | 'verify' | 'stop'`. ##### rationale? > `optional` **rationale?**: `string` -**`Experimental`** - Why the driver chose this move (the agent's rationale), when available. ##### parentIndex? > `optional` **parentIndex?**: `number` -**`Experimental`** - Iteration index this round branches FROM, when the driver declares it. Overrides the kernel's inferred branch point — lets a planner that branches off a specific (non-winner) iteration emit faithful edge lineage. @@ -16722,7 +16610,7 @@ Omit to keep the inferred (best-valid / latest) branch point. ### LoopWinner -**`Experimental`** +**`Stable`** #### Type Parameters @@ -16740,37 +16628,27 @@ Omit to keep the inferred (best-valid / latest) branch point. > **task**: `Task` -**`Experimental`** - ##### output > **output**: `Output` -**`Experimental`** - ##### verdict? > `optional` **verdict?**: `DefaultVerdict` -**`Experimental`** - ##### iterationIndex > **iterationIndex**: `number` -**`Experimental`** - ##### agentRunName > **agentRunName**: `string` -**`Experimental`** - *** ### SandboxClient -**`Experimental`** +**`Stable`** Minimal sandbox client surface the kernel calls. Satisfied structurally by `new Sandbox({ apiKey, baseUrl })` — declared as a structural type so @@ -16788,8 +16666,6 @@ the kernel falls back to `{ placement: 'sibling', sandboxId: box.id }`. > **create**(`options?`): `Promise`\<`SandboxInstance`\> -**`Experimental`** - ###### Parameters ###### options? @@ -16804,8 +16680,6 @@ the kernel falls back to `{ placement: 'sibling', sandboxId: box.id }`. > `optional` **describePlacement**(`box`): [`LoopSandboxPlacement`](#loopsandboxplacement) -**`Experimental`** - ###### Parameters ###### box @@ -16918,7 +16792,7 @@ idle-drop. Applies to the default fresh-box path too, not only when ### LoopSandboxPlacement -**`Experimental`** +**`Stable`** #### Extended by @@ -16930,31 +16804,23 @@ idle-drop. Applies to the default fresh-box path too, not only when > **kind**: `"sibling"` \| `"fleet"` -**`Experimental`** - ##### sandboxId? > `optional` **sandboxId?**: `string` -**`Experimental`** - ##### fleetId? > `optional` **fleetId?**: `string` -**`Experimental`** - ##### machineId? > `optional` **machineId?**: `string` -**`Experimental`** - *** ### LoopTraceEmitter -**`Experimental`** +**`Stable`** #### Methods @@ -16962,8 +16828,6 @@ idle-drop. Applies to the default fresh-box path too, not only when > **emit**(`event`): `void` \| `Promise`\<`void`\> -**`Experimental`** - ###### Parameters ###### event @@ -16978,7 +16842,7 @@ idle-drop. Applies to the default fresh-box path too, not only when ### LoopStartedPayload -**`Experimental`** +**`Stable`** #### Properties @@ -16986,31 +16850,23 @@ idle-drop. Applies to the default fresh-box path too, not only when > **driver**: `string` -**`Experimental`** - ##### agentRunNames > **agentRunNames**: `string`[] -**`Experimental`** - ##### maxIterations > **maxIterations**: `number` -**`Experimental`** - ##### maxConcurrency > **maxConcurrency**: `number` -**`Experimental`** - *** ### LoopPlanPayload -**`Experimental`** +**`Stable`** Emitted once per `plan()` round, immediately after the driver plans. Carries the topology move so a viewer renders WHAT the agent decided + WHY, not just @@ -17023,40 +16879,30 @@ provided, else inferred from `plannedCount` (0→stop, 1→refine, N→fanout). > **roundIndex**: `number` -**`Experimental`** - 0-based plan round (one per `plan()` call). ##### plannedCount > **plannedCount**: `number` -**`Experimental`** - Tasks the driver issued this round. ##### moveKind > **moveKind**: `string` -**`Experimental`** - Topology move — `'refine' | 'fanout' | 'verify' | 'stop'` etc. ##### rationale? > `optional` **rationale?**: `string` -**`Experimental`** - Driver rationale for the move, when available. ##### parentIndex? > `optional` **parentIndex?**: `number` -**`Experimental`** - Iteration index this round branched FROM (the edge source). `undefined` for round 0 (root). Kernel-inferred branch point — the best-valid (else latest) iteration so far — unless a driver later declares it explicitly. @@ -17065,15 +16911,13 @@ latest) iteration so far — unless a driver later declares it explicitly. > **childIndices**: `number`[] -**`Experimental`** - Iteration indices this round dispatched (the edge targets). *** ### LoopIterationStartedPayload -**`Experimental`** +**`Stable`** #### Properties @@ -17081,41 +16925,31 @@ Iteration indices this round dispatched (the edge targets). > **iterationIndex**: `number` -**`Experimental`** - ##### agentRunName > **agentRunName**: `string` -**`Experimental`** - ##### taskHash > **taskHash**: `string` -**`Experimental`** - ##### groupId? > `optional` **groupId?**: `number` -**`Experimental`** - Plan round (== `LoopPlanPayload.roundIndex`) this iteration belongs to. ##### parentIndex? > `optional` **parentIndex?**: `number` -**`Experimental`** - Iteration this one was planned from; `undefined` ⇒ root. *** ### LoopIterationDispatchPayload -**`Experimental`** +**`Stable`** Where the iteration's worker was placed. `sibling` = a fresh sandbox the kernel created via `sandboxClient.create`. `fleet` = an existing machine in @@ -17128,65 +16962,49 @@ they write lands on it directly. > **iterationIndex**: `number` -**`Experimental`** - ##### agentRunName > **agentRunName**: `string` -**`Experimental`** - ##### placement > **placement**: `"sibling"` \| `"fleet"` -**`Experimental`** - ##### sandboxId? > `optional` **sandboxId?**: `string` -**`Experimental`** - Set on every placement. Lets analyst loops correlate per-iteration logs. ##### fleetId? > `optional` **fleetId?**: `string` -**`Experimental`** - Set only when `placement === 'fleet'`. ##### machineId? > `optional` **machineId?**: `string` -**`Experimental`** - Set only when `placement === 'fleet'`. ##### groupId? > `optional` **groupId?**: `number` -**`Experimental`** - Plan round this iteration belongs to. ##### parentIndex? > `optional` **parentIndex?**: `number` -**`Experimental`** - Iteration this one was planned from; `undefined` ⇒ root. *** ### LoopIterationEndedPayload -**`Experimental`** +**`Stable`** #### Properties @@ -17194,62 +17012,42 @@ Iteration this one was planned from; `undefined` ⇒ root. > **iterationIndex**: `number` -**`Experimental`** - ##### agentRunName > **agentRunName**: `string` -**`Experimental`** - ##### outputHash? > `optional` **outputHash?**: `string` -**`Experimental`** - ##### verdict? > `optional` **verdict?**: `DefaultVerdict` -**`Experimental`** - ##### error? > `optional` **error?**: `string` -**`Experimental`** - ##### costUsd > **costUsd**: `number` -**`Experimental`** - ##### costUsdKnown? > `optional` **costUsdKnown?**: `false` -**`Experimental`** - ##### estimatedCostUsd? > `optional` **estimatedCostUsd?**: `number` -**`Experimental`** - ##### durationMs > **durationMs**: `number` -**`Experimental`** - ##### tokenUsage? > `optional` **tokenUsage?**: [`LoopTokenUsage`](#looptokenusage) -**`Experimental`** - Summed LLM token usage for this iteration — maps to gen_ai.usage.* on the branch span. Omitted when no `llm_call` events carried token counts. @@ -17257,24 +17055,18 @@ Summed LLM token usage for this iteration — maps to gen_ai.usage.* on the > `optional` **groupId?**: `number` -**`Experimental`** - Plan round this iteration belongs to. ##### parentIndex? > `optional` **parentIndex?**: `number` -**`Experimental`** - Iteration this one was planned from; `undefined` ⇒ root. ##### outputPreview? > `optional` **outputPreview?**: `string` -**`Experimental`** - Truncated string preview of the parsed output — for a viewer's drawer. Bounded to ~280 chars; never the full payload. @@ -17282,7 +17074,7 @@ Truncated string preview of the parsed output — for a viewer's drawer. ### LoopDecisionPayload -**`Experimental`** +**`Stable`** #### Properties @@ -17290,19 +17082,15 @@ Truncated string preview of the parsed output — for a viewer's drawer. > **decision**: `string` -**`Experimental`** - ##### historyLength > **historyLength**: `number` -**`Experimental`** - *** ### LoopEndedPayload -**`Experimental`** +**`Stable`** #### Properties @@ -17310,43 +17098,31 @@ Truncated string preview of the parsed output — for a viewer's drawer. > `optional` **winnerIterationIndex?**: `number` -**`Experimental`** - ##### totalCostUsd > **totalCostUsd**: `number` -**`Experimental`** - ##### costUsdKnown? > `optional` **costUsdKnown?**: `false` -**`Experimental`** - ##### estimatedCostUsd? > `optional` **estimatedCostUsd?**: `number` -**`Experimental`** - ##### durationMs > **durationMs**: `number` -**`Experimental`** - ##### iterations > **iterations**: `number` -**`Experimental`** - *** ### LoopTeardownFailedPayload -**`Experimental`** +**`Stable`** Emitted when a box's `delete()` throws or times out during teardown — the loop swallows the failure (platform reaps on expiry) but surfaces it here so @@ -17358,21 +17134,17 @@ Emitted when a box's `delete()` throws or times out during teardown — the > `optional` **sandboxId?**: `string` -**`Experimental`** - ##### reason > **reason**: `string` -**`Experimental`** - `'timeout'` or the delete error message. *** ### ExecCtx -**`Experimental`** +**`Stable`** Execution context for `runAgentRounds`: the sandbox client the kernel creates boxes through, plus optional runtime hooks. @@ -17382,24 +17154,18 @@ Execution context for `runAgentRounds`: the sandbox client the kernel creates bo > **sandboxClient**: [`SandboxClient`](#sandboxclient-5) -**`Experimental`** - Sandbox SDK client — the kernel calls `.create()` per iteration. ##### hooks? > `optional` **hooks?**: [`RuntimeHooks`](index.md#runtimehooks) -**`Experimental`** - Optional runtime hooks. Execution-scoped; never part of `AgentProfile`. ##### traceEmitter? > `optional` **traceEmitter?**: [`LoopTraceEmitter`](#looptraceemitter) -**`Experimental`** - Optional trace emitter. When set, the kernel emits `loop.*` events. ##### onSandboxEvent? @@ -17446,8 +17212,6 @@ on that. > `optional` **runHandle?**: [`RuntimeRunHandle`](index.md#runtimerunhandle) -**`Experimental`** - Optional production-run handle. When set, every synthesized `llm_call` the kernel infers from a sandbox event stream is forwarded via `runHandle.observe` so per-run cost aggregates pick up loop spend. @@ -17456,16 +17220,12 @@ the kernel infers from a sandbox event stream is forwarded via > `optional` **signal?**: `AbortSignal` -**`Experimental`** - Cooperative cancellation signal. ##### traceId? > `optional` **traceId?**: `string` -**`Experimental`** - Trace id for OTEL correlation. When set alongside `traceEmitter`, the exporter uses this as the parent trace for all emitted spans. Typically inherited from TRACE_ID env var in MCP subprocess mode. @@ -17474,8 +17234,6 @@ inherited from TRACE_ID env var in MCP subprocess mode. > `optional` **parentSpanId?**: `string` -**`Experimental`** - Parent span id for OTEL correlation. Loop events become children of this span. Typically inherited from PARENT_SPAN_ID env var. @@ -18516,7 +18274,7 @@ One provider-neutral conversation record carried between strategy shots. > **AgentTurnBackend** = `object` -**`Experimental`** +**`Stable`** The execution substrate one turn runs on — a closed discriminated union over the three stream surfaces the runtime already owns. @@ -19755,7 +19513,7 @@ Public supervisor-facing compaction config: same knobs as the primitive, but `di > **MountRecorder** = (`entry`) => `void` -**`Experimental`** +**`Stable`** Records a mounted resource into the run's provenance manifest. Passed to `prepareBox` so the caller — which owns the bytes it writes into the box — @@ -19777,7 +19535,7 @@ declares what it mounted without the kernel having to inspect box contents. > **LoopTraceEvent** = \{ `kind`: `"loop.started"`; `runId`: `string`; `timestamp`: `number`; `payload`: [`LoopStartedPayload`](#loopstartedpayload); \} \| \{ `kind`: `"loop.plan"`; `runId`: `string`; `timestamp`: `number`; `payload`: [`LoopPlanPayload`](#loopplanpayload); \} \| \{ `kind`: `"loop.iteration.started"`; `runId`: `string`; `timestamp`: `number`; `payload`: [`LoopIterationStartedPayload`](#loopiterationstartedpayload); \} \| \{ `kind`: `"loop.iteration.dispatch"`; `runId`: `string`; `timestamp`: `number`; `payload`: [`LoopIterationDispatchPayload`](#loopiterationdispatchpayload); \} \| \{ `kind`: `"loop.iteration.ended"`; `runId`: `string`; `timestamp`: `number`; `payload`: [`LoopIterationEndedPayload`](#loopiterationendedpayload); \} \| \{ `kind`: `"loop.decision"`; `runId`: `string`; `timestamp`: `number`; `payload`: [`LoopDecisionPayload`](#loopdecisionpayload); \} \| \{ `kind`: `"loop.ended"`; `runId`: `string`; `timestamp`: `number`; `payload`: [`LoopEndedPayload`](#loopendedpayload); \} \| \{ `kind`: `"loop.teardown.failed"`; `runId`: `string`; `timestamp`: `number`; `payload`: [`LoopTeardownFailedPayload`](#loopteardownfailedpayload); \} -**`Experimental`** +**`Stable`** *** @@ -20166,6 +19924,8 @@ change the result already observed. > **replaySpawnTree**(`journal`, `blobs`, `root`): `Promise`\<[`Settled`](index.md#settled)\<`unknown`\>[]\> +**`Stable`** + Re-feed a journaled spawn tree in strict `seq` order, rehydrating each settled child's `out` from the blob store by `outRef`, and return the `Settled[]` exactly as `scope.next()` originally delivered them. @@ -21189,6 +20949,8 @@ the selection logic previously copied per role. > **pipeline**\<`Task`, `D`\>(`stages`): [`CombinatorShape`](#combinatorshape)\<`Task`, `D`\> +**`Stable`** + `pipeline(stages)` — run the stages in order, feeding each stage's `done` deliverable into the next stage's task. The first stage that ends `blocked` (a child that went down, a child the pool would not admit, or a stage whose `collect` chose to block) short-circuits — its blockers @@ -21221,6 +20983,8 @@ readonly [`PipelineStage`](#pipelinestage)\<`Task`, `unknown`, `unknown`\>[] > **fanout**\<`Task`, `Item`, `D`\>(`items`, `opts`): [`CombinatorShape`](#combinatorshape)\<`Task`, `D`\> +**`Stable`** + `fanout(items, opts)` — spawn one child per item in a single round (bounded by the conserved pool's fail-closed admission), drain via `scope.next()`, then either synthesize over the gathered settlements (one SEPARATE synthesis child) or return the best-valid child via the @@ -21265,6 +21029,8 @@ readonly `Item`[] > **loopUntil**\<`Task`, `State`, `D`\>(`seed`, `spec`): [`CombinatorShape`](#combinatorshape)\<`Task`, `D`\> +**`Stable`** + `loopUntil(seed, spec)` — one `step` child per round; `fold` accumulates each settlement into the running state; `until` (reading the round's trace findings, NOT a fresh raw verdict) is the deployable stop. The conserved pool IS the loop bound: once `spawn` fails closed the loop @@ -21309,6 +21075,8 @@ argument is the empty array — never a fabricated finding (fail-loud honesty ov > **panel**\<`Task`, `Artifact`, `D`\>(`spec`): [`CombinatorShape`](#combinatorshape)\<`Task`, `D`\> +**`Stable`** + `panel(spec)` — spawn the M judge children over the SAME artifact, drain their settlements, and fold them into a panel verdict via the pure WRITE-ONLY `merge` (a judge's output never reaches another judge's task; the merge never spawns or re-ranks). A `down` judge carries no @@ -21345,6 +21113,8 @@ concrete blocker before `merge` is consulted. > **verify**\<`Task`, `Candidate`, `D`\>(`spec`): [`CombinatorShape`](#combinatorshape)\<`Task`, `D`\> +**`Stable`** + `verify(spec)` — an IMPLEMENT child produces a candidate, then a SEPARATE VERIFIER child grades it; only a `valid` verifier verdict ships. Any other outcome (implement down, verifier down, verifier verdict absent or not `valid`) is a concrete blocker carrying the failure verbatim — @@ -21380,6 +21150,8 @@ never a coerced "done". The implement child does not grade itself. > **widen**\<`Task`, `Seed`, `D`\>(`spec`): [`CombinatorShape`](#combinatorshape)\<`Task`, `D`\> +**`Stable`** + `widen(spec)` — the streaming spawn-on-completion driver. Spawns the seed lineages, then REACTS to each `scope.next()`: on every settled child it consults `spec.gate.decide` and, when the gate returns `widen`, spawns AT MOST ONE more child toward the chosen lineage under the remaining @@ -21472,6 +21244,8 @@ An empty query result returns a fresh COPY of the profile with no instruction ch > **definePersona**\<`D`\>(`input`): [`Persona`](#persona)\<`D`\> +**`Stable`** + Build a frozen `Persona`. Fails loud on the executors-supplied invariant: a persona with neither a pre-built registry nor a seam bag cannot resolve its built-in runtimes, so it is unrunnable — refuse it at definition time, not at the first spawn. Pure; no I/O. @@ -21498,6 +21272,8 @@ unrunnable — refuse it at definition time, not at the first spawn. Pure; no I/ > **runPersonified**\<`Task`, `D`\>(`options`): `Promise`\<[`SupervisedResult`](index.md#supervisedresult)\<[`Outcome`](#outcome-2)\<`D`\>\>\> +**`Stable`** + Compose the persona + chosen shape onto a fresh keystone `Supervisor`. Resolves the shape (a factory verbatim, or a registered name through `builtinShapes`), applies it to a `ShapeContext`, and runs the resulting root `Agent` to a typed `SupervisedResult`. @@ -21776,7 +21552,7 @@ Pretty-print a report — the "free optimization" verdict, with the cost vector. > **runAgentRounds**\<`Task`, `Output`, `Decision`\>(`options`): `Promise`\<[`LoopResult`](index.md#loopresult)\<`Task`, `Output`, `Decision`\>\> -**`Experimental`** +**`Stable`** The round-synchronous MULTI-AGENT kernel: each round `driver.plan()` fans N tasks out to N sandboxes (bounded concurrency), parses + validates each output, and folds @@ -22482,7 +22258,7 @@ Run a Strategy through the keystone Supervisor — `Agent.act` over a conserved- > **streamAgentTurn**(`backend`, `input`, `opts?`): `AsyncGenerator`\<[`RuntimeStreamEvent`](index.md#runtimestreamevent)\> -**`Experimental`** +**`Stable`** Run ONE agent turn on any backend kind and stream its events. Yields the `RuntimeStreamEvent` vocabulary incrementally and always ends with a `final` @@ -22515,7 +22291,7 @@ timeout alike. The generator never throws; failures surface in-band as > **collectAgentTurn**(`stream`): `Promise`\<[`CollectedAgentTurn`](#collectedagentturn)\> -**`Experimental`** +**`Stable`** Drain a `streamAgentTurn` stream (or any `RuntimeStreamEvent` stream that honors its terminal contract) into the turn summary plus the full event @@ -23479,7 +23255,10 @@ readonly `object`[] > **createEventBus**\<`E`\>(`now?`): [`EventBus`](#eventbus)\<`E`\> +**`Experimental`** + Create the child→parent coordination bus: one typed pipe for settled outputs, questions, and analyst findings, with a priority-ordered pull queue and a pass-through subscribe lane. + In-process queue; durability is a transport swap that does not exist yet. #### Type Parameters @@ -24450,6 +24229,8 @@ ahead of the worker seam. > **supervise**(`profile`, `task`, `opts`): `Promise`\<[`SupervisedResult`](index.md#supervisedresult)\<`unknown`\>\> +**`Stable`** + One-call supervisor: build + run a supervisor from its exact profile. #### Parameters diff --git a/docs/api/tui.md b/docs/api/tui.md index a5b7b62e..bbb9f4a5 100644 --- a/docs/api/tui.md +++ b/docs/api/tui.md @@ -6,6 +6,26 @@ # tui +**`Experimental`** + +`@tangle-network/agent-runtime/tui` — the terminal view over live supervisor runs. + +A read-only renderer plus two write-back controls, over the same `/.agent/supervisor/` +layout `../runtime/supervise/run-layout` defines. It ships here rather than as its own package +because the runtime is what WRITES the state it renders: a separately-versioned viewer would +drift from the layout it reads, which is the exact failure a client and server versioning +independently produces. + +Zero third-party dependencies — raw ANSI and `node:readline` keypresses, nothing else. + +```ts +import { loadTopSnapshot, renderTopFrame } from '@tangle-network/agent-runtime/tui' + +process.stdout.write(renderTopFrame(loadTopSnapshot(process.cwd()), { width: 132 })) +``` + +The runnable form is the `agent-runtime-top` bin: `agent-runtime-top [--once] [--no-color]`. + ## Interfaces ### TopAppOptions @@ -32,24 +52,34 @@ How the app was invoked. Defaults read `process.argv` / `process.cwd()`. ### TopSnapshot +**`Experimental`** + #### Properties ##### root > `readonly` **root**: `string` +**`Experimental`** + ##### generatedAt > `readonly` **generatedAt**: `number` +**`Experimental`** + ##### supervisors > `readonly` **supervisors**: [`SupervisorView`](#supervisorview)[] +**`Experimental`** + *** ### SupervisorBase +**`Experimental`** + #### Extended by - [`SupervisorView`](#supervisorview) @@ -60,74 +90,110 @@ How the app was invoked. Defaults read `process.argv` / `process.cwd()`. > `readonly` **id**: `string` +**`Experimental`** + ##### status > `readonly` **status**: `string` +**`Experimental`** + ##### task > `readonly` **task**: `string` +**`Experimental`** + ##### workspaceDir > `readonly` **workspaceDir**: `string` +**`Experimental`** + ##### budget > `readonly` **budget**: `number` +**`Experimental`** + ##### verifyCmd? > `readonly` `optional` **verifyCmd?**: `string` +**`Experimental`** + ##### workerModel? > `readonly` `optional` **workerModel?**: `string` +**`Experimental`** + ##### driverModel? > `readonly` `optional` **driverModel?**: `string` +**`Experimental`** + ##### verdict? > `readonly` `optional` **verdict?**: `string` +**`Experimental`** + ##### progress? > `readonly` `optional` **progress?**: `string` +**`Experimental`** + ##### startedAt? > `readonly` `optional` **startedAt?**: `string` +**`Experimental`** + ##### completedAt? > `readonly` `optional` **completedAt?**: `string` +**`Experimental`** + ##### maxSandboxes? > `readonly` `optional` **maxSandboxes?**: `number` +**`Experimental`** + ##### maxLifetimeSeconds? > `readonly` `optional` **maxLifetimeSeconds?**: `number` +**`Experimental`** + ##### idleTimeoutSeconds? > `readonly` `optional` **idleTimeoutSeconds?**: `number` +**`Experimental`** + ##### maxUsd? > `readonly` `optional` **maxUsd?**: `number` +**`Experimental`** + ##### maxDepth? > `readonly` `optional` **maxDepth?**: `number` +**`Experimental`** + *** ### SupervisorView +**`Experimental`** + #### Extends - [`SupervisorBase`](#supervisorbase) @@ -138,6 +204,8 @@ How the app was invoked. Defaults read `process.argv` / `process.cwd()`. > `readonly` **id**: `string` +**`Experimental`** + ###### Inherited from [`SupervisorBase`](#supervisorbase).[`id`](#id) @@ -146,6 +214,8 @@ How the app was invoked. Defaults read `process.argv` / `process.cwd()`. > `readonly` **status**: `string` +**`Experimental`** + ###### Inherited from [`SupervisorBase`](#supervisorbase).[`status`](#status) @@ -154,6 +224,8 @@ How the app was invoked. Defaults read `process.argv` / `process.cwd()`. > `readonly` **task**: `string` +**`Experimental`** + ###### Inherited from [`SupervisorBase`](#supervisorbase).[`task`](#task) @@ -162,6 +234,8 @@ How the app was invoked. Defaults read `process.argv` / `process.cwd()`. > `readonly` **workspaceDir**: `string` +**`Experimental`** + ###### Inherited from [`SupervisorBase`](#supervisorbase).[`workspaceDir`](#workspacedir) @@ -170,6 +244,8 @@ How the app was invoked. Defaults read `process.argv` / `process.cwd()`. > `readonly` **budget**: `number` +**`Experimental`** + ###### Inherited from [`SupervisorBase`](#supervisorbase).[`budget`](#budget) @@ -178,6 +254,8 @@ How the app was invoked. Defaults read `process.argv` / `process.cwd()`. > `readonly` `optional` **verifyCmd?**: `string` +**`Experimental`** + ###### Inherited from [`SupervisorBase`](#supervisorbase).[`verifyCmd`](#verifycmd) @@ -186,6 +264,8 @@ How the app was invoked. Defaults read `process.argv` / `process.cwd()`. > `readonly` `optional` **workerModel?**: `string` +**`Experimental`** + ###### Inherited from [`SupervisorBase`](#supervisorbase).[`workerModel`](#workermodel) @@ -194,6 +274,8 @@ How the app was invoked. Defaults read `process.argv` / `process.cwd()`. > `readonly` `optional` **driverModel?**: `string` +**`Experimental`** + ###### Inherited from [`SupervisorBase`](#supervisorbase).[`driverModel`](#drivermodel) @@ -202,6 +284,8 @@ How the app was invoked. Defaults read `process.argv` / `process.cwd()`. > `readonly` `optional` **verdict?**: `string` +**`Experimental`** + ###### Inherited from [`SupervisorBase`](#supervisorbase).[`verdict`](#verdict) @@ -210,6 +294,8 @@ How the app was invoked. Defaults read `process.argv` / `process.cwd()`. > `readonly` `optional` **progress?**: `string` +**`Experimental`** + ###### Inherited from [`SupervisorBase`](#supervisorbase).[`progress`](#progress) @@ -218,6 +304,8 @@ How the app was invoked. Defaults read `process.argv` / `process.cwd()`. > `readonly` `optional` **startedAt?**: `string` +**`Experimental`** + ###### Inherited from [`SupervisorBase`](#supervisorbase).[`startedAt`](#startedat) @@ -226,6 +314,8 @@ How the app was invoked. Defaults read `process.argv` / `process.cwd()`. > `readonly` `optional` **completedAt?**: `string` +**`Experimental`** + ###### Inherited from [`SupervisorBase`](#supervisorbase).[`completedAt`](#completedat) @@ -234,6 +324,8 @@ How the app was invoked. Defaults read `process.argv` / `process.cwd()`. > `readonly` `optional` **maxSandboxes?**: `number` +**`Experimental`** + ###### Inherited from [`SupervisorBase`](#supervisorbase).[`maxSandboxes`](#maxsandboxes) @@ -242,6 +334,8 @@ How the app was invoked. Defaults read `process.argv` / `process.cwd()`. > `readonly` `optional` **maxLifetimeSeconds?**: `number` +**`Experimental`** + ###### Inherited from [`SupervisorBase`](#supervisorbase).[`maxLifetimeSeconds`](#maxlifetimeseconds) @@ -250,6 +344,8 @@ How the app was invoked. Defaults read `process.argv` / `process.cwd()`. > `readonly` `optional` **idleTimeoutSeconds?**: `number` +**`Experimental`** + ###### Inherited from [`SupervisorBase`](#supervisorbase).[`idleTimeoutSeconds`](#idletimeoutseconds) @@ -258,6 +354,8 @@ How the app was invoked. Defaults read `process.argv` / `process.cwd()`. > `readonly` `optional` **maxUsd?**: `number` +**`Experimental`** + ###### Inherited from [`SupervisorBase`](#supervisorbase).[`maxUsd`](#maxusd) @@ -266,6 +364,8 @@ How the app was invoked. Defaults read `process.argv` / `process.cwd()`. > `readonly` `optional` **maxDepth?**: `number` +**`Experimental`** + ###### Inherited from [`SupervisorBase`](#supervisorbase).[`maxDepth`](#maxdepth) @@ -274,282 +374,416 @@ How the app was invoked. Defaults read `process.argv` / `process.cwd()`. > `readonly` **stateDir**: `string` +**`Experimental`** + ##### resultSpentUsd? > `readonly` `optional` **resultSpentUsd?**: `number` +**`Experimental`** + ##### resultSpentTokens? > `readonly` `optional` **resultSpentTokens?**: `number` +**`Experimental`** + ##### workers > `readonly` **workers**: [`WorkerView`](#workerview)[] +**`Experimental`** + ##### progressTail > `readonly` **progressTail**: `string`[] +**`Experimental`** + ##### journalTail > `readonly` **journalTail**: [`TopJournalEvent`](#topjournalevent)[] +**`Experimental`** + ##### driverSpend > `readonly` **driverSpend**: [`SpendStats`](#spendstats) +**`Experimental`** + ##### totals > `readonly` **totals**: [`SupervisorTotals`](#supervisortotals) +**`Experimental`** + *** ### WorkerView +**`Experimental`** + #### Properties ##### id > `readonly` **id**: `string` +**`Experimental`** + ##### label > `readonly` **label**: `string` +**`Experimental`** + ##### cwd? > `readonly` `optional` **cwd?**: `string` +**`Experimental`** + ##### eventFile? > `readonly` `optional` **eventFile?**: `string` +**`Experimental`** + ##### parent? > `readonly` `optional` **parent?**: `string` +**`Experimental`** + ##### runtime? > `readonly` `optional` **runtime?**: `string` +**`Experimental`** + ##### status > `readonly` **status**: `"done"` \| `"down"` \| `"running"` \| `"cancelled"` +**`Experimental`** + ##### verdict? > `readonly` `optional` **verdict?**: `string` +**`Experimental`** + ##### infra? > `readonly` `optional` **infra?**: `boolean` +**`Experimental`** + ##### startedAt? > `readonly` `optional` **startedAt?**: `string` +**`Experimental`** + ##### endedAt? > `readonly` `optional` **endedAt?**: `string` +**`Experimental`** + ##### latencyMs > `readonly` **latencyMs**: `number` +**`Experimental`** + ##### budget? > `readonly` `optional` **budget?**: [`BudgetStats`](#budgetstats) +**`Experimental`** + ##### spend > `readonly` **spend**: [`SpendStats`](#spendstats) +**`Experimental`** + ##### metered > `readonly` **metered**: [`SpendStats`](#spendstats) +**`Experimental`** + ##### liveTail > `readonly` **liveTail**: `string`[] +**`Experimental`** + ##### outRef? > `readonly` `optional` **outRef?**: `string` +**`Experimental`** + ##### reason? > `readonly` `optional` **reason?**: `string` +**`Experimental`** + *** ### SupervisorTotals +**`Experimental`** + #### Properties ##### workers > `readonly` **workers**: `number` +**`Experimental`** + ##### running > `readonly` **running**: `number` +**`Experimental`** + ##### done > `readonly` **done**: `number` +**`Experimental`** + ##### down > `readonly` **down**: `number` +**`Experimental`** + ##### cancelled > `readonly` **cancelled**: `number` +**`Experimental`** + ##### inFlight > `readonly` **inFlight**: `number` +**`Experimental`** + ##### settled > `readonly` **settled**: `number` +**`Experimental`** + ##### tokensInput > `readonly` **tokensInput**: `number` +**`Experimental`** + ##### tokensOutput > `readonly` **tokensOutput**: `number` +**`Experimental`** + ##### tokensTotal > `readonly` **tokensTotal**: `number` +**`Experimental`** + ##### usd > `readonly` **usd**: `number` +**`Experimental`** + ##### latencyMs > `readonly` **latencyMs**: `number` +**`Experimental`** + ##### workerLatency > `readonly` **workerLatency**: [`Distribution`](#distribution) +**`Experimental`** + *** ### Distribution +**`Experimental`** + #### Properties ##### n > `readonly` **n**: `number` +**`Experimental`** + ##### min > `readonly` **min**: `number` +**`Experimental`** + ##### median > `readonly` **median**: `number` +**`Experimental`** + ##### p90 > `readonly` **p90**: `number` +**`Experimental`** + ##### max > `readonly` **max**: `number` +**`Experimental`** + *** ### BudgetStats +**`Experimental`** + #### Properties ##### maxIterations? > `readonly` `optional` **maxIterations?**: `number` +**`Experimental`** + ##### maxTokens? > `readonly` `optional` **maxTokens?**: `number` +**`Experimental`** + ##### maxUsd? > `readonly` `optional` **maxUsd?**: `number` +**`Experimental`** + *** ### SpendStats +**`Experimental`** + #### Properties ##### iterations > `readonly` **iterations**: `number` +**`Experimental`** + ##### tokensInput > `readonly` **tokensInput**: `number` +**`Experimental`** + ##### tokensOutput > `readonly` **tokensOutput**: `number` +**`Experimental`** + ##### usd > `readonly` **usd**: `number` +**`Experimental`** + ##### ms > `readonly` **ms**: `number` +**`Experimental`** + *** ### RenderOptions +**`Experimental`** + #### Properties ##### width? > `readonly` `optional` **width?**: `number` +**`Experimental`** + ##### height? > `readonly` `optional` **height?**: `number` +**`Experimental`** + ##### color? > `readonly` `optional` **color?**: `boolean` +**`Experimental`** + ##### selectedSupervisorId? > `readonly` `optional` **selectedSupervisorId?**: `string` +**`Experimental`** + ##### selectedWorkerId? > `readonly` `optional` **selectedWorkerId?**: `string` +**`Experimental`** + ##### focus? > `readonly` `optional` **focus?**: `"supervisors"` \| `"workers"` +**`Experimental`** + ##### mode? > `readonly` `optional` **mode?**: `"log"` \| `"overview"` \| `"detail"` +**`Experimental`** + ##### notice? > `readonly` `optional` **notice?**: `string` +**`Experimental`** + ##### steerInput? > `readonly` `optional` **steerInput?**: `object` +**`Experimental`** + ###### active > `readonly` **active**: `boolean` @@ -566,44 +800,62 @@ How the app was invoked. Defaults read `process.argv` / `process.cwd()`. ### RenderTarget +**`Experimental`** + #### Properties ##### row > `readonly` **row**: `number` +**`Experimental`** + ##### kind > `readonly` **kind**: `"worker"` \| `"supervisor"` +**`Experimental`** + ##### id > `readonly` **id**: `string` +**`Experimental`** + ##### supervisorId? > `readonly` `optional` **supervisorId?**: `string` +**`Experimental`** + *** ### RenderedTopFrame +**`Experimental`** + #### Properties ##### frame > `readonly` **frame**: `string` +**`Experimental`** + ##### targets > `readonly` **targets**: [`RenderTarget`](#rendertarget)[] +**`Experimental`** + ## Type Aliases ### TopJournalEvent > **TopJournalEvent** = \{ `kind`: `"spawned"`; `id`: `string`; `parent?`: `string`; `label?`: `string`; `budget?`: `unknown`; `runtime?`: `string`; `seq?`: `number`; `at?`: `string`; \} \| \{ `kind`: `"settled"`; `id`: `string`; `status?`: `string`; `outRef?`: `string`; `verdict?`: `unknown`; `spent?`: `unknown`; `infra?`: `boolean`; `seq?`: `number`; `at?`: `string`; \} \| \{ `kind`: `"cancelled"`; `id`: `string`; `reason?`: `string`; `seq?`: `number`; `at?`: `string`; \} \| \{ `kind`: `"metered"`; `id`: `string`; `spend?`: `unknown`; `seq?`: `number`; `at?`: `string`; \} +**`Experimental`** + ## Functions ### renderTopOnce() @@ -652,6 +904,8 @@ otherwise it writes a single frame to stdout and returns. > **loadTopSnapshot**(`rootDir`, `now?`): [`TopSnapshot`](#topsnapshot) +**`Experimental`** + Read every supervisor run under one workspace into a single point-in-time snapshot. Pure with respect to the process: it only reads, and every unreadable or half-written file is @@ -678,6 +932,8 @@ injectable so elapsed time is deterministic under test. > **renderTopFrame**(`snapshot`, `options?`): `string` +**`Experimental`** + Render one snapshot to an ANSI frame. Use this when nothing needs to be clickable. #### Parameters @@ -700,6 +956,8 @@ Render one snapshot to an ANSI frame. Use this when nothing needs to be clickabl > **renderTopFrameWithLayout**(`snapshot`, `options?`): [`RenderedTopFrame`](#renderedtopframe) +**`Experimental`** + Render one snapshot, returning the frame together with the row→entity map a mouse click resolves against. The layout is the only thing that knows which row is which run or worker, so emitting it alongside the text is what keeps click handling out of the renderer. diff --git a/docs/canonical-api.md b/docs/canonical-api.md index 01a7f2c3..fb640e0b 100644 --- a/docs/canonical-api.md +++ b/docs/canonical-api.md @@ -4,7 +4,7 @@ Generated signatures and the complete export list live in docs/api/. Run pnpm docs:freshness after editing this file. --> -> **Version 0.129.0.** +> **Version 0.130.0.** > [`docs/api/primitive-catalog.md`](./api/primitive-catalog.md) lists every export and import path. > `agent-eval` must satisfy `>=0.144.4 <0.145.0`. > `sandbox` must satisfy `>=0.19.1 <0.20.0`. diff --git a/package.json b/package.json index e1ffc3bc..7b872a3b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@tangle-network/agent-runtime", - "version": "0.129.0", + "version": "0.130.0", "description": "Shared task-lifecycle skeleton for agents: a recursive loop kernel for chat turns, one-shot tasks, and multi-attempt loops, with trace capture and eval-gated self-improvement. Domain behavior lives in adapters; scoring and ship-gates in @tangle-network/agent-eval.", "homepage": "https://github.com/tangle-network/agent-runtime#readme", "repository": { diff --git a/src/agent/define-agent.ts b/src/agent/define-agent.ts index f443285b..cd73e0ca 100644 --- a/src/agent/define-agent.ts +++ b/src/agent/define-agent.ts @@ -13,6 +13,10 @@ * throws a structured error if any required surface is missing on * disk. The cost is one filesystem stat per surface (cheap); the * benefit is a manifest that can't ship broken. + * + * @experimental Manifests validate and load, but `runtime.act` is not yet wired + * end-to-end into the substrate's eval path (`unimplementedAgentRun` is the + * shipped default). */ import type { TraceAnalystDefinition } from '@tangle-network/agent-eval' diff --git a/src/candidate-execution/index.ts b/src/candidate-execution/index.ts index 3a5461eb..b6f4d4ee 100644 --- a/src/candidate-execution/index.ts +++ b/src/candidate-execution/index.ts @@ -1,3 +1,11 @@ +/** + * `@tangle-network/agent-runtime/candidate-execution` — sealed candidate bundles + * plus the isolated prepare/execute/finalize/recover lifecycle around them. + * + * @module + * @experimental + */ + export { type AgentCandidateCodeSource, type AgentCandidateCodeSurfaceSource, diff --git a/src/durable/spawn-journal.ts b/src/durable/spawn-journal.ts index 6a2b2c37..381f5510 100644 --- a/src/durable/spawn-journal.ts +++ b/src/durable/spawn-journal.ts @@ -17,7 +17,7 @@ * touching the blob store, so the order in which rehydration `get`s resolve can never * reorder the replayed `Settled[]`; the result is identical regardless of blob latency. * - * @experimental + * @stable */ import { detachedSnapshot } from '../runtime/supervise/snapshot' @@ -108,6 +108,8 @@ export interface SpawnForest { * In-memory `ResultBlobStore`. Content-addressed: `put` verifies the supplied * `outRef` matches the artifact's hash so a stale/forged ref fails loud rather than * silently rehydrating the wrong payload. Idempotent on an identical re-put. + * + * @stable */ export class InMemoryResultBlobStore implements ResultBlobStore { private readonly blobs = new Map() @@ -126,6 +128,8 @@ export class InMemoryResultBlobStore implements ResultBlobStore { * FS `ResultBlobStore`. One JSON file per artifact under `dir`, named by a * filesystem-safe encoding of the `outRef` (`sha256:` → `sha256-.json`). * `put` fsyncs so a crash between writes never loses an acknowledged blob. + * + * @stable */ export class FileResultBlobStore implements ResultBlobStore { constructor(private readonly dir: string) {} @@ -178,6 +182,8 @@ function assertContentAddress(outRef: string, artifact: unknown): void { * - an event before `beginTree` is a corrupted tree (fail loud), * - a duplicate `seq` within a tree is a corrupted cursor (fail loud) — two * settlements cannot share the cursor position replay orders by. + * + * @stable */ export class InMemorySpawnJournal implements SpawnJournal { private readonly trees = new Map() @@ -217,6 +223,8 @@ export class InMemorySpawnJournal implements SpawnJournal { * filtering by `root`, and applies the same begin-precedes-events + unique-seq * corruption guards as the in-memory impl. Each append fsyncs so a crash between * writes never loses an acknowledged event. + * + * @stable */ export class FileSpawnJournal implements SpawnJournal { private appendTail: Promise = Promise.resolve() @@ -502,6 +510,8 @@ function outsideCursorNamespace(ev: SpawnEvent): boolean { * resolves. `at` (wall-clock) is never a replay input. Fail loud on a tree that was * never begun, a settled-done event missing its `outRef`, or a blob the store can't * rehydrate — a silent gap would let `act` branch on the wrong evidence. + * + * @stable */ export async function replaySpawnTree( journal: SpawnJournal, diff --git a/src/improvement/agentic-generator.ts b/src/improvement/agentic-generator.ts index 5f7f754f..be6aa1ed 100644 --- a/src/improvement/agentic-generator.ts +++ b/src/improvement/agentic-generator.ts @@ -24,7 +24,7 @@ * false`), never shipped — if you configured a verifier, a non-passing tree is * not a candidate. With no verifier, the first dirty shot is the candidate. * - * @experimental + * @stable */ import { spawnSync } from 'node:child_process' diff --git a/src/improvement/improve.ts b/src/improvement/improve.ts index f9226902..6d887932 100644 --- a/src/improvement/improve.ts +++ b/src/improvement/improve.ts @@ -6,7 +6,7 @@ * Code is the sole exception. It uses Runtime's isolated git worktrees because * checkout ownership and cleanup cannot cross a generic optimizer boundary. * - * @experimental + * @stable */ import type { Scenario } from '@tangle-network/agent-eval/contract' diff --git a/src/improvement/improvement-driver.ts b/src/improvement/improvement-driver.ts index 324a7734..56e3ec6f 100644 --- a/src/improvement/improvement-driver.ts +++ b/src/improvement/improvement-driver.ts @@ -4,7 +4,7 @@ * A `CandidateGenerator` edits an isolated checkout. This driver finalizes each * accepted edit as a `CodeSurface` and disposes rejected worktrees. * - * @experimental + * @stable */ import { spawnSync } from 'node:child_process' diff --git a/src/improvement/raw-trace-distiller.ts b/src/improvement/raw-trace-distiller.ts index f3b67257..f3dbc2e8 100644 --- a/src/improvement/raw-trace-distiller.ts +++ b/src/improvement/raw-trace-distiller.ts @@ -28,7 +28,7 @@ * cached-result.json ← the cell's score + artifact ref * ← whatever the dispatch wrote * - * @experimental + * @stable */ import { type Dirent, existsSync, readdirSync } from 'node:fs' diff --git a/src/improvement/reflective-generator.ts b/src/improvement/reflective-generator.ts index 7e98bc57..f42c9fd5 100644 --- a/src/improvement/reflective-generator.ts +++ b/src/improvement/reflective-generator.ts @@ -9,7 +9,7 @@ * This is the `shots=1, sandbox=off` code-candidate setting. * `agenticGenerator` supplies the multi-shot verify-in-session setting. * - * @experimental + * @stable */ import { spawnSync } from 'node:child_process' diff --git a/src/intelligence/capability.ts b/src/intelligence/capability.ts index d5f51791..50084fae 100644 --- a/src/intelligence/capability.ts +++ b/src/intelligence/capability.ts @@ -23,7 +23,7 @@ * `AgentProfileMcpServer` shape the mcp binding lowers to) and on the runtime's * own `ToolSpec`. It never imports agent-eval and never reaches upward. * - * @experimental + * @stable */ import type { AgentProfileMcpServer } from '@tangle-network/agent-interface' diff --git a/src/intelligence/delivery.ts b/src/intelligence/delivery.ts index 6319e408..f6b690c4 100644 --- a/src/intelligence/delivery.ts +++ b/src/intelligence/delivery.ts @@ -23,7 +23,7 @@ * Auth: Bearer (the one TANGLE_API_KEY shared by router + sandbox + * intelligence), resolved to a tenant by platform-api's key-verify S2S contract. * - * @experimental + * @stable */ import type { diff --git a/src/intelligence/effort.ts b/src/intelligence/effort.ts index 2197f792..f0f116e8 100644 --- a/src/intelligence/effort.ts +++ b/src/intelligence/effort.ts @@ -12,7 +12,7 @@ * agent as pure passthrough and only intelligence-class usage can prove to be * zero — there is nothing to spawn. * - * @experimental + * @stable */ /** The named effort tiers, lowest to highest. `'off'` is the honest floor diff --git a/src/intelligence/index.ts b/src/intelligence/index.ts index 60573386..187df128 100644 --- a/src/intelligence/index.ts +++ b/src/intelligence/index.ts @@ -16,7 +16,8 @@ * and at OFF `intelligenceUsd` is provably `0` — the mechanism that proves * an OFF customer paid inference-only. * - * @experimental + * @module + * @stable */ import { contentHash } from '@tangle-network/agent-eval' diff --git a/src/intelligence/resolver.ts b/src/intelligence/resolver.ts index 0c1015c2..8614c46c 100644 --- a/src/intelligence/resolver.ts +++ b/src/intelligence/resolver.ts @@ -23,7 +23,7 @@ * capability (never a half-wired tool); a post-resolve drift check drops any tool * whose live names diverge from the certified interface. * - * @experimental + * @stable */ import { diff --git a/src/intelligence/with-intelligence.ts b/src/intelligence/with-intelligence.ts index 56c458bd..328fb42a 100644 --- a/src/intelligence/with-intelligence.ts +++ b/src/intelligence/with-intelligence.ts @@ -28,7 +28,7 @@ * { project: 'support-agent', target: 'support-agent' }, * ) * - * @experimental + * @stable */ import type { AgentProfile } from '@tangle-network/agent-interface' diff --git a/src/mcp/delegation-store.ts b/src/mcp/delegation-store.ts index f1e624cf..df594ae5 100644 --- a/src/mcp/delegation-store.ts +++ b/src/mcp/delegation-store.ts @@ -12,7 +12,7 @@ * through `JSON.stringify`/`JSON.parse`, so a `Date`, `Map`, or function * smuggled into `args`/`result` would corrupt the journal. * - * @experimental + * @stable */ import { mkdir, readFile, rename, writeFile } from 'node:fs/promises' @@ -20,7 +20,7 @@ import { dirname } from 'node:path' import { AgentEvalError } from '../errors' import type { DelegationRecord } from './task-queue' -/** @experimental */ +/** @stable */ export interface DelegationStore { /** * Read every persisted record. Called once, by @@ -50,7 +50,7 @@ export interface DelegationStore { * (the bin maps `AGENT_RUNTIME_DELEGATION_STATE_RECOVER=1` onto it), * which archives the corrupt file and starts fresh. * - * @experimental + * @stable */ export class DelegationStateCorruptError extends AgentEvalError { constructor(message: string, options?: { cause?: unknown }) { @@ -64,7 +64,7 @@ export class DelegationStateCorruptError extends AgentEvalError { * accepting new submissions — accepting work it cannot journal would * silently demote durable mode to in-memory mode. * - * @experimental + * @stable */ export class DelegationPersistenceError extends AgentEvalError { constructor(message: string, options?: { cause?: unknown }) { @@ -72,7 +72,7 @@ export class DelegationPersistenceError extends AgentEvalError { } } -/** In-memory `DelegationStore` — suitable for single-process use and tests. @experimental */ +/** In-memory `DelegationStore` — suitable for single-process use and tests. @stable */ export class InMemoryDelegationStore implements DelegationStore { private readonly records = new Map() @@ -96,7 +96,7 @@ export class InMemoryDelegationStore implements DelegationStore { } } -/** @experimental */ +/** @stable */ export interface FileDelegationStoreOptions { /** Absolute path of the JSON state file. Parent directories are created on first write. */ filePath: string @@ -126,7 +126,7 @@ const STATE_FORMAT_VERSION = 1 * records): full-snapshot writes keep the format trivially inspectable * and corruption-detectable without a database dependency. * - * @experimental + * @stable */ export class FileDelegationStore implements DelegationStore { private readonly filePath: string diff --git a/src/mcp/feedback-store.ts b/src/mcp/feedback-store.ts index 50f6124a..0d653102 100644 --- a/src/mcp/feedback-store.ts +++ b/src/mcp/feedback-store.ts @@ -11,12 +11,12 @@ * fresh id, even when the same delegation is rated multiple times. The * caller decides how to roll up scores downstream. * - * @experimental + * @stable */ import type { DelegateFeedbackArgs, DelegationFeedbackSnapshot } from './types' -/** @experimental */ +/** @stable */ export interface FeedbackEvent { id: string refersTo: DelegateFeedbackArgs['refersTo'] @@ -26,7 +26,7 @@ export interface FeedbackEvent { namespace?: string } -/** @experimental */ +/** @stable */ export interface FeedbackStore { /** Append a new event. Never dedupes — every rating is its own event. */ put(event: FeedbackEvent): Promise @@ -37,7 +37,7 @@ export interface FeedbackStore { list(filter?: { namespace?: string; refersToRef?: string }): Promise } -/** In-memory `FeedbackStore` — suitable for single-process use and tests. @experimental */ +/** In-memory `FeedbackStore` — suitable for single-process use and tests. @stable */ export class InMemoryFeedbackStore implements FeedbackStore { private readonly events: FeedbackEvent[] = [] @@ -61,7 +61,7 @@ export class InMemoryFeedbackStore implements FeedbackStore { * Project a `FeedbackEvent` down to the snapshot shape carried on * `delegation_history` entries. * - * @experimental + * @stable */ export function eventToSnapshot(event: FeedbackEvent): DelegationFeedbackSnapshot { const snap: DelegationFeedbackSnapshot = { diff --git a/src/mcp/index.ts b/src/mcp/index.ts index fa160c18..9a6f1808 100644 --- a/src/mcp/index.ts +++ b/src/mcp/index.ts @@ -11,7 +11,7 @@ * `agent-runtime-mcp` (the bin) or wire it into a custom Node entry * point with `createMcpServer({ ... })`. * - * @experimental + * @module */ export type { DetectExecutorArgs } from './bin-helpers' diff --git a/src/mcp/task-queue.ts b/src/mcp/task-queue.ts index 68bb0046..3fda6d0e 100644 --- a/src/mcp/task-queue.ts +++ b/src/mcp/task-queue.ts @@ -23,7 +23,7 @@ * `resumeDelegate` seam (when they carry a `detachedSessionRef`) or fail * loud with a driver-restart error so `delegation_status` tells the truth. * - * @experimental + * @stable */ import { ValidationError } from '../errors' @@ -55,14 +55,14 @@ import type { DelegationStatusResult, } from './types' -/** Arguments accepted by the durable delegation queue. @experimental */ +/** Arguments accepted by the durable delegation queue. @stable */ export type DelegationArgs = DelegateCodeArgs | DelegateResearchArgs | DelegateUiAuditArgs /** * Must be JSON-safe end to end (`args`, `result`, `error`, `feedback`) — * persistent stores round-trip records through `JSON.stringify`. * - * @experimental + * @stable */ export interface DelegationRecord { taskId: string @@ -107,7 +107,7 @@ export interface DelegationRecord { parentSpanId?: string } -/** @experimental */ +/** @stable */ export interface SubmitInput { profile: DelegationProfile args: Args @@ -129,7 +129,7 @@ export interface SubmitInput { run: (ctx: DelegationRunContext) => Promise } -/** @experimental Context handed to a `SubmitInput.run` function. */ +/** @stable Context handed to a `SubmitInput.run` function. */ export interface DelegationRunContext { signal: AbortSignal report(progress: DelegationProgress): void @@ -155,7 +155,7 @@ export interface DelegationRunContext { traceEmitter?: LoopTraceEmitter } -/** @experimental */ +/** @stable */ export interface SubmitOutput { taskId: string /** True when a prior matching `idempotencyKey` returned an existing record. */ @@ -168,14 +168,14 @@ export interface SubmitOutput { * completed | running | failed per pass). `running` schedules another tick * after `intervalMs`; `completed` / `failed` settle the record. * - * @experimental + * @stable */ export type DelegationResumeTick = | { state: 'running' } | { state: 'completed'; output: DelegationResultPayload['output']; costUsd?: number } | { state: 'failed'; error: DelegationError } -/** @experimental */ +/** @stable */ export interface DelegationResumeContext { /** Fired by `cancel(taskId)`; the driver should stop the remote run when it can. */ signal: AbortSignal @@ -190,7 +190,7 @@ export interface DelegationResumeContext { * thrown error settles the record as failed; `failed` ticks are treated as * terminal and are not retried. * - * @experimental + * @stable */ export interface DelegationResumeDriver { tick( @@ -201,7 +201,7 @@ export interface DelegationResumeDriver { intervalMs?: number } -/** @experimental */ +/** @stable */ export interface DelegationTaskQueueOptions { /** ID generator override; default `randomTaskId`. */ generateId?: () => string @@ -240,7 +240,7 @@ export interface DelegationTaskQueueOptions { traceContext?: TraceContext } -/** In-process queue for async delegation tasks — submit, cancel, poll status, and read history. @experimental */ +/** In-process queue for async delegation tasks — submit, cancel, poll status, and read history. @stable */ export class DelegationTaskQueue { private readonly records = new Map() private readonly controllers = new Map() @@ -802,7 +802,7 @@ function randomTaskId(): string { * Best-effort stable hash for use as `idempotencyKey`. Not cryptographic; * collisions only affect dedupe, never correctness. * - * @experimental + * @stable */ export function hashIdempotencyInput(value: unknown): string { let str: string diff --git a/src/mcp/tools/delegate-feedback.ts b/src/mcp/tools/delegate-feedback.ts index b4af5182..fa6463f8 100644 --- a/src/mcp/tools/delegate-feedback.ts +++ b/src/mcp/tools/delegate-feedback.ts @@ -8,7 +8,7 @@ * to the matching queue record so `delegation_history` surfaces it * inline without a join. * - * @experimental + * @stable */ import type { FeedbackStore } from '../feedback-store' @@ -21,10 +21,10 @@ import type { FeedbackRefersTo, } from '../types' -/** MCP tool name for the `delegate_feedback` feedback-recording tool. @experimental */ +/** MCP tool name for the `delegate_feedback` feedback-recording tool. @stable */ export const DELEGATE_FEEDBACK_TOOL_NAME = 'delegate_feedback' -/** Human-readable description of the `delegate_feedback` MCP tool, injected into the tool manifest. @experimental */ +/** Human-readable description of the `delegate_feedback` MCP tool, injected into the tool manifest. @stable */ export const DELEGATE_FEEDBACK_DESCRIPTION = [ 'Record feedback on a delegation, artifact, or outcome. Synchronous — the', 'event is durably stored when this call returns.', @@ -48,7 +48,7 @@ export const DELEGATE_FEEDBACK_DESCRIPTION = [ 'delegation record so delegation_history surfaces it inline.', ].join('\n') -/** JSON Schema for `delegate_feedback` tool arguments (`refersTo`, `rating`, `by`, optional fields). @experimental */ +/** JSON Schema for `delegate_feedback` tool arguments (`refersTo`, `rating`, `by`, optional fields). @stable */ export const DELEGATE_FEEDBACK_INPUT_SCHEMA = { type: 'object', properties: { @@ -79,7 +79,7 @@ export const DELEGATE_FEEDBACK_INPUT_SCHEMA = { additionalProperties: false, } as const -/** Parse and validate raw MCP tool input into typed `DelegateFeedbackArgs`; throws `TypeError` on bad input. @experimental */ +/** Parse and validate raw MCP tool input into typed `DelegateFeedbackArgs`; throws `TypeError` on bad input. @stable */ export function validateDelegateFeedbackArgs(raw: unknown): DelegateFeedbackArgs { if (raw === null || typeof raw !== 'object') { throw new TypeError('delegate_feedback: arguments must be an object') @@ -148,7 +148,7 @@ function validateRating(raw: unknown): FeedbackRating { return rating } -/** @experimental */ +/** @stable */ export interface DelegateFeedbackHandlerOptions { queue: DelegationTaskQueue store: FeedbackStore @@ -156,7 +156,7 @@ export interface DelegateFeedbackHandlerOptions { now?: () => string } -/** Build the MCP tool handler that persists feedback events and attaches them to delegation records. @experimental */ +/** Build the MCP tool handler that persists feedback events and attaches them to delegation records. @stable */ export function createDelegateFeedbackHandler( options: DelegateFeedbackHandlerOptions, ): (raw: unknown) => Promise { diff --git a/src/mcp/tools/delegate.ts b/src/mcp/tools/delegate.ts index 4f859616..08ede1ac 100644 --- a/src/mcp/tools/delegate.ts +++ b/src/mcp/tools/delegate.ts @@ -13,7 +13,7 @@ * is INJECTED at server construction — never an agent-supplied arg. The agent supplies only the * intent (+ an optional per-call `model` / `runId`). * - * @experimental + * @stable */ import type { AgentProfile } from '@tangle-network/agent-interface' @@ -23,10 +23,10 @@ import { type DelegateOptions, delegate } from '../../runtime/supervise/delegate import type { ExecutorConfig } from '../../runtime/supervise/runtime' import type { Spend, SupervisedResult } from '../../runtime/supervise/types' -/** MCP tool name for the `delegate` generic-delegation tool. @experimental */ +/** MCP tool name for the `delegate` generic-delegation tool. @stable */ export const DELEGATE_TOOL_NAME = 'delegate' -/** Human-readable description of the `delegate` MCP tool, injected into the tool manifest. @experimental */ +/** Human-readable description of the `delegate` MCP tool, injected into the tool manifest. @stable */ export const DELEGATE_DESCRIPTION = [ 'Delegate an INTENT to a supervisor that AUTHORS and drives whatever worker the intent needs.', '', @@ -44,7 +44,7 @@ export const DELEGATE_DESCRIPTION = [ 'a success.', ].join('\n') -/** JSON Schema for `delegate` tool arguments (`intent` + optional trace id). @experimental */ +/** JSON Schema for `delegate` tool arguments (`intent` + optional trace id). @stable */ export const DELEGATE_INPUT_SCHEMA = { type: 'object', properties: { @@ -67,7 +67,7 @@ export interface DelegateArgs { runId?: string } -/** Parse and validate raw MCP tool input into typed `DelegateArgs`; throws `TypeError` on bad input. @experimental */ +/** Parse and validate raw MCP tool input into typed `DelegateArgs`; throws `TypeError` on bad input. @stable */ export function validateDelegateArgs(raw: unknown): DelegateArgs { if (raw === null || typeof raw !== 'object') { throw new TypeError('delegate: arguments must be an object') @@ -103,7 +103,7 @@ export interface DelegateError { message: string } -/** @experimental */ +/** @stable */ export interface DelegateHandlerOptions { /** The supervisor brain's router substrate (REQUIRED — the default supervisor is router-brained). */ router: RouterTransportConfig diff --git a/src/mcp/tools/delegation-history.ts b/src/mcp/tools/delegation-history.ts index fec9e4a1..24a90ca0 100644 --- a/src/mcp/tools/delegation-history.ts +++ b/src/mcp/tools/delegation-history.ts @@ -4,7 +4,7 @@ * The agent uses this for self-introspection — "have I delegated this * kind of task before? did it work?" — and calibration. * - * @experimental + * @stable */ import type { @@ -14,10 +14,10 @@ import type { DelegationTaskQueue, } from '../task-queue' -/** MCP tool name for the `delegation_history` read-past-delegations tool. @experimental */ +/** MCP tool name for the `delegation_history` read-past-delegations tool. @stable */ export const DELEGATION_HISTORY_TOOL_NAME = 'delegation_history' -/** Human-readable description of the `delegation_history` MCP tool, injected into the tool manifest. @experimental */ +/** Human-readable description of the `delegation_history` MCP tool, injected into the tool manifest. @stable */ export const DELEGATION_HISTORY_DESCRIPTION = [ 'Read past delegations newest-first. Each entry carries the original', 'arguments, current status, cost, and any feedback attached via', @@ -38,7 +38,7 @@ export const DELEGATION_HISTORY_DESCRIPTION = [ 'to 50, capped at 500.', ].join('\n') -/** JSON Schema for `delegation_history` tool arguments (optional `namespace`, `profile`, `since`, `limit`). @experimental */ +/** JSON Schema for `delegation_history` tool arguments (optional `namespace`, `profile`, `since`, `limit`). @stable */ export const DELEGATION_HISTORY_INPUT_SCHEMA = { type: 'object', properties: { @@ -50,7 +50,7 @@ export const DELEGATION_HISTORY_INPUT_SCHEMA = { additionalProperties: false, } as const -/** Parse and validate raw MCP tool input into typed `DelegationHistoryArgs`; throws `TypeError` on bad input. @experimental */ +/** Parse and validate raw MCP tool input into typed `DelegationHistoryArgs`; throws `TypeError` on bad input. @stable */ export function validateDelegationHistoryArgs(raw: unknown): DelegationHistoryArgs { if (raw === undefined || raw === null) return {} if (typeof raw !== 'object') { @@ -86,12 +86,12 @@ export function validateDelegationHistoryArgs(raw: unknown): DelegationHistoryAr return out } -/** @experimental */ +/** @stable */ export interface DelegationHistoryHandlerOptions { queue: DelegationTaskQueue } -/** Build the MCP tool handler that reads filtered past delegations from a `DelegationTaskQueue`. @experimental */ +/** Build the MCP tool handler that reads filtered past delegations from a `DelegationTaskQueue`. @stable */ export function createDelegationHistoryHandler( options: DelegationHistoryHandlerOptions, ): (raw: unknown) => Promise { diff --git a/src/mcp/tools/delegation-status.ts b/src/mcp/tools/delegation-status.ts index ae989a4a..84512047 100644 --- a/src/mcp/tools/delegation-status.ts +++ b/src/mcp/tools/delegation-status.ts @@ -3,7 +3,7 @@ * `delegation_status` MCP tool — synchronous poll. Returns the current * state machine + optional progress + final result (when terminal). * - * @experimental + * @stable */ import { NotFoundError } from '../../errors' @@ -13,10 +13,10 @@ import type { DelegationTaskQueue, } from '../task-queue' -/** MCP tool name for the `delegation_status` synchronous-poll tool. @experimental */ +/** MCP tool name for the `delegation_status` synchronous-poll tool. @stable */ export const DELEGATION_STATUS_TOOL_NAME = 'delegation_status' -/** Human-readable description of the `delegation_status` MCP tool, injected into the tool manifest. @experimental */ +/** Human-readable description of the `delegation_status` MCP tool, injected into the tool manifest. @stable */ export const DELEGATION_STATUS_DESCRIPTION = [ 'Poll the status of an async delegation. Returns the current state', '(pending | running | completed | failed | cancelled), optional progress,', @@ -38,7 +38,7 @@ export const DELEGATION_STATUS_DESCRIPTION = [ '`pending` for a typo.', ].join('\n') -/** JSON Schema for `delegation_status` tool arguments (`taskId` + optional `includeTrace`). @experimental */ +/** JSON Schema for `delegation_status` tool arguments (`taskId` + optional `includeTrace`). @stable */ export const DELEGATION_STATUS_INPUT_SCHEMA = { type: 'object', properties: { @@ -53,7 +53,7 @@ export const DELEGATION_STATUS_INPUT_SCHEMA = { additionalProperties: false, } as const -/** Parse and validate raw MCP tool input into typed `DelegationStatusArgs`; throws `TypeError` on bad input. @experimental */ +/** Parse and validate raw MCP tool input into typed `DelegationStatusArgs`; throws `TypeError` on bad input. @stable */ export function validateDelegationStatusArgs(raw: unknown): DelegationStatusArgs { if (raw === null || typeof raw !== 'object') { throw new TypeError('delegation_status: arguments must be an object') @@ -73,12 +73,12 @@ export function validateDelegationStatusArgs(raw: unknown): DelegationStatusArgs return out } -/** @experimental */ +/** @stable */ export interface DelegationStatusHandlerOptions { queue: DelegationTaskQueue } -/** Build the MCP tool handler that polls a `DelegationTaskQueue` for task status. @experimental */ +/** Build the MCP tool handler that polls a `DelegationTaskQueue` for task status. @stable */ export function createDelegationStatusHandler( options: DelegationStatusHandlerOptions, ): (raw: unknown) => Promise { diff --git a/src/profiles/index.ts b/src/profiles/index.ts index 329a9d01..951260c9 100644 --- a/src/profiles/index.ts +++ b/src/profiles/index.ts @@ -4,6 +4,7 @@ * with a pure task-to-prompt formatter. The substrate materializes a profile into a harness * invocation; "is it delivered" is a `DeliverableSpec`, not a bundled validator. * + * @module * @experimental */ diff --git a/src/runtime/index.ts b/src/runtime/index.ts index 018f4f94..bfde2e72 100644 --- a/src/runtime/index.ts +++ b/src/runtime/index.ts @@ -7,7 +7,7 @@ * adapter owns event-stream decode; the kernel owns iteration accounting, * concurrency, abort, cost aggregation, and trace emission. * - * @experimental + * @module */ // The analyst-finding factory + id helper from the substrate, re-surfaced here so a host that builds diff --git a/src/runtime/personify/combinators.ts b/src/runtime/personify/combinators.ts index ddcea22f..57e87b35 100644 --- a/src/runtime/personify/combinators.ts +++ b/src/runtime/personify/combinators.ts @@ -19,7 +19,7 @@ * CONCRETE blocker (never an eager over-fan, never a silent drop), and a `blocked` outcome always * names at least one blocker (a shape that cannot finish MUST say why — `blocked([])` throws). * - * @experimental + * @stable */ import { ValidationError } from '../../errors' @@ -98,6 +98,8 @@ export function selectValidWinner(opts?: { * pool would not admit, or a stage whose `collect` chose to block) short-circuits — its blockers * ARE the pipeline's blockers, never coerced past a failed stage. The terminal stage's `done` * deliverable is the pipeline's deliverable. + * + * @stable */ export function pipeline( stages: ReadonlyArray>, @@ -140,6 +142,8 @@ export function pipeline( * `opts.width` swaps the single round for `rollingDispatch`: at most `width` items live at once, * refilled the instant one settles. Selection, blockers, and the conserved pool are unchanged — * the refill behavior lives in the existing combinator rather than in a rival primitive. + * + * @stable */ export function fanout( items: ReadonlyArray, @@ -255,6 +259,8 @@ export function fanout( * `until` on the resulting trace-derived findings (the analyst spawns into THIS scope, so its * compute is conserved-pooled — equal-k holds by construction). Absent an analyst the findings * argument is the empty array — never a fabricated finding (fail-loud honesty over a silent default). + * + * @stable */ export function loopUntil( seed: State, @@ -307,6 +313,8 @@ export function loopUntil( * reaches another judge's task; the merge never spawns or re-ranks). A `down` judge carries no * verdict and is excluded from the merge denominator. A panel that admitted no judge is a * concrete blocker before `merge` is consulted. + * + * @stable */ export function panel(spec: PanelSpec): CombinatorShape { if (spec.judges.length === 0) { @@ -367,6 +375,8 @@ export function panel(spec: PanelSpec): Combinat * it; only a `valid` verifier verdict ships. Any other outcome (implement down, verifier down, * verifier verdict absent or not `valid`) is a concrete blocker carrying the failure verbatim — * never a coerced "done". The implement child does not grade itself. + * + * @stable */ export function verify( spec: VerifySpec, @@ -421,6 +431,8 @@ export function verify( * the widen loop sees it. The shipped default (`flatWidenGate`) never widens, so no widen child is * ever live when the analyst runs and the wire is exact; a non-flat gate must drive the analyst on * a scope whose siblings are quiesced, or read findings without the shared-cursor drain. + * + * @stable */ export function widen(spec: WidenSpec): CombinatorShape { return (ctx: ShapeContext): Agent> => ({ diff --git a/src/runtime/personify/persona.ts b/src/runtime/personify/persona.ts index 16c3f70d..ee49a096 100644 --- a/src/runtime/personify/persona.ts +++ b/src/runtime/personify/persona.ts @@ -16,7 +16,7 @@ * receive a ctx with the persona seams merged in — so a persona never has to pre-close its * factories by hand. A persona may instead supply a fully-built `registry` and skip the wrap. * - * @experimental + * @stable */ import { InMemoryResultBlobStore, InMemorySpawnJournal } from '../../durable/spawn-journal' @@ -54,6 +54,8 @@ import type { ScopeAnalyst } from './wave-types' * Build a frozen `Persona`. Fails loud on the executors-supplied invariant: a persona with * neither a pre-built registry nor a seam bag cannot resolve its built-in runtimes, so it is * unrunnable — refuse it at definition time, not at the first spawn. Pure; no I/O. + * + * @stable */ export function definePersona(input: DefinePersonaInput): Persona { if (!input.executors.registry && !input.executors.seams) { @@ -130,6 +132,8 @@ export function createShapeContext( * `ShapeContext`, and runs the resulting root `Agent` to a typed `SupervisedResult`. * Fail loud on an unknown shape name or an unresolvable persona registry — never a silent * default-shape fallback. + * + * @stable */ export async function runPersonified( options: RunPersonifiedOptions, diff --git a/src/runtime/run-loop.ts b/src/runtime/run-loop.ts index b6ea8b18..75e82382 100644 --- a/src/runtime/run-loop.ts +++ b/src/runtime/run-loop.ts @@ -21,7 +21,7 @@ * profile), how outputs are decoded (output adapter), how outputs are * scored (validator), or topology (driver). * - * @experimental + * @stable */ import type { SandboxEvent, SandboxInstance } from '@tangle-network/sandbox' @@ -70,7 +70,7 @@ import { const DEFAULT_MAX_ITERATIONS = 10 const DEFAULT_MAX_CONCURRENCY = 4 -/** @experimental */ +/** @stable */ export interface RunAgentRoundsOptions { driver: Driver /** @@ -147,7 +147,7 @@ export interface RunAgentRoundsOptions { * folding the results back in until the model stops calling tools. No sandboxes, no * rounds, no winner selection. * - * @experimental + * @stable */ export async function runAgentRounds( options: RunAgentRoundsOptions, diff --git a/src/runtime/strategy-evolution.ts b/src/runtime/strategy-evolution.ts index 8585c683..34c38be2 100644 --- a/src/runtime/strategy-evolution.ts +++ b/src/runtime/strategy-evolution.ts @@ -20,6 +20,8 @@ * Lineage fields (`parent`, `generation`) are recorded on every archive node so a * descendant-productivity parent-selection policy can be added without changing the * report schema; the v1 search authors from the latest tournament's losses. + * + * @experimental */ import { existsSync, readFileSync, writeFileSync } from 'node:fs' diff --git a/src/runtime/stream-agent-turn.ts b/src/runtime/stream-agent-turn.ts index 1643b745..efc32fa8 100644 --- a/src/runtime/stream-agent-turn.ts +++ b/src/runtime/stream-agent-turn.ts @@ -44,7 +44,7 @@ * (and locked by test): nothing is produced past the event the caller is * holding. * - * @experimental + * @stable */ import { scoreKnowledgeReadiness } from '@tangle-network/agent-eval' @@ -93,7 +93,7 @@ import type { * The execution substrate one turn runs on — a closed discriminated union over * the three stream surfaces the runtime already owns. * - * @experimental + * @stable */ export type AgentTurnBackend = { /** A Runtime-owned executor factory materialized from this exact canonical profile. */ @@ -137,7 +137,7 @@ export type AgentTurnInput = | string | { readonly messages: ReadonlyArray>> } -/** @experimental */ +/** @stable */ export interface StreamAgentTurnOptions { /** Caller-initiated cancellation. Terminates the stream with `final.status: 'aborted'`. */ signal?: AbortSignal @@ -355,7 +355,7 @@ function turnProvenance( * `tokensKnown: false` when the backend did not report them. `costUsd`/`model` * are present only when the backend actually reported them. * - * @experimental + * @stable */ export interface AgentTurnUsage { input: number @@ -379,7 +379,7 @@ export interface AgentTurnUsage { * `status`/`error` mirror the terminal `final` event so a failed or aborted * turn stays inspectable without re-scanning `events`. * - * @experimental + * @stable */ export interface CollectedAgentTurn { finalText: string @@ -426,7 +426,7 @@ interface TurnAccumulator { * timeout alike. The generator never throws; failures surface in-band as * `backend_error` + `final` with a typed `error` detail. * - * @experimental + * @stable */ export async function* streamAgentTurn( backend: AgentTurnBackend, @@ -713,7 +713,7 @@ function assertExactExecutorEvidence( * list. Fail-loud: throws when the stream ends without a terminal `final` * event — a stream that violates the contract must not read as an empty turn. * - * @experimental + * @stable */ export async function collectAgentTurn( stream: AsyncIterable, diff --git a/src/runtime/supervise/event-bus.ts b/src/runtime/supervise/event-bus.ts index cc81c620..a7b2e9a0 100644 --- a/src/runtime/supervise/event-bus.ts +++ b/src/runtime/supervise/event-bus.ts @@ -54,6 +54,9 @@ export interface BusStats { readonly byKind: Readonly> } +/** The child→parent coordination bus surface: publish, priority-ordered pull, pass-through subscribe, history, and stats. + * @experimental In-process only — the durable cross-process mailbox this interface is designed + * to admit is not implemented (docs/agent-managed-compute/README.md). */ export interface EventBus { /** Stamp the event, await every subscriber in order, then make it pull-visible. A subscriber * failure leaves the event invisible and retrying the SAME event object reuses the exact stamp. @@ -73,7 +76,8 @@ export interface EventBus { stats(): BusStats } -/** Create the child→parent coordination bus: one typed pipe for settled outputs, questions, and analyst findings, with a priority-ordered pull queue and a pass-through subscribe lane. */ +/** Create the child→parent coordination bus: one typed pipe for settled outputs, questions, and analyst findings, with a priority-ordered pull queue and a pass-through subscribe lane. + * @experimental In-process queue; durability is a transport swap that does not exist yet. */ export function createEventBus(now: () => number = Date.now): EventBus { const queue: BusRecord[] = [] const log: BusRecord[] = [] diff --git a/src/runtime/supervise/scope.ts b/src/runtime/supervise/scope.ts index 01814153..76cf72dd 100644 --- a/src/runtime/supervise/scope.ts +++ b/src/runtime/supervise/scope.ts @@ -22,7 +22,7 @@ * writer of `spawned` events. The result blob is `put` BEFORE the journal `settled` record * references its `outRef`, so a crash can never leave a journaled ref with no blob. * - * @experimental + * @stable */ import { diff --git a/src/runtime/supervise/supervise.ts b/src/runtime/supervise/supervise.ts index bb03be21..e1198d31 100644 --- a/src/runtime/supervise/supervise.ts +++ b/src/runtime/supervise/supervise.ts @@ -6,6 +6,8 @@ * * `workerFromBackend` derives the worker seam (`makeWorkerAgent`) from a backend config + an optional * completion oracle — so "where the workers run" is one data choice, not a hand-rolled factory. + * + * @stable */ import { randomUUID } from 'node:crypto' import { resolve } from 'node:path' @@ -1178,7 +1180,7 @@ export interface SuperviseTestOptions extends SuperviseOptions { readonly brain: ToolLoopChat } -/** One-call supervisor: build + run a supervisor from its exact profile. */ +/** One-call supervisor: build + run a supervisor from its exact profile. @stable */ export function supervise(profile: SupervisorProfile, task: unknown, opts: SuperviseOptions) { if ('brain' in opts) { throw new ValidationError( diff --git a/src/runtime/supervise/supervisor.ts b/src/runtime/supervise/supervisor.ts index 4b76a8a0..9fd53230 100644 --- a/src/runtime/supervise/supervisor.ts +++ b/src/runtime/supervise/supervisor.ts @@ -31,7 +31,7 @@ * `spentTotal` off the journal (`settled` child work + `metered` driver inference), and wraps * it as a typed `winner` — it does not re-rank children behind the driver's back. * - * @experimental + * @stable */ import { sha256DigestSchema } from '@tangle-network/agent-interface' diff --git a/src/runtime/supervise/types.ts b/src/runtime/supervise/types.ts index da30a495..036e1e32 100644 --- a/src/runtime/supervise/types.ts +++ b/src/runtime/supervise/types.ts @@ -609,6 +609,8 @@ export type Settled = * budget atomically from the shared pool and fails closed when the pool cannot cover it. * `next()` waits for one settlement from this scope's live set; `view` reads live state, * not the replay log. + * + * @stable */ export interface Scope { /** @@ -711,6 +713,9 @@ export interface Scope { * re-spawning committed work. A resume-blind driver simply ignores it and re-spawns — correct * but redundant. The scope's spawn ordinal + cursor seq are already advanced past the recorded * maxima, so any NEW spawn appends without colliding with a journaled event. + * + * @experimental Same-process replay only — live supervised-tree recovery after a + * coordinator restart is not implemented (docs/agent-managed-compute/README.md). */ readonly resume?: ResumedWork /** The live tree — reads the in-memory nursery, not the journal. */ @@ -996,6 +1001,8 @@ export interface ResultBlobStore { * Owns the conserved pool, the spawn log, the abort cascade, the OTP intensity breaker, * and the root handle. `run` executes the root `Agent` to completion; `attach` wires a * live `RootHandle` (the Q2 substrate the chat/pi-viz client later consumes). + * + * @stable */ export interface Supervisor { run(root: Agent, task: Task, opts: SupervisorOpts): Promise> @@ -1042,6 +1049,9 @@ export interface SupervisorOpts { * * Default `false` — a run always begins a fresh tree, which is the behavior every existing * consumer has. Resume is a durability contract the caller opts into, never a silent default. + * + * @experimental Rehydrates committed settlements only; live supervised-tree recovery after a + * coordinator restart is not implemented (docs/agent-managed-compute/README.md). */ readonly resume?: boolean readonly now?: () => number diff --git a/src/runtime/types.ts b/src/runtime/types.ts index bbeee3db..cf4d0f88 100644 --- a/src/runtime/types.ts +++ b/src/runtime/types.ts @@ -9,7 +9,7 @@ * emission; the driver owns topology (plan + decide); the validator owns * output scoring; the output adapter owns event-stream → typed-output decode. * - * @experimental + * @stable */ import type { DefaultVerdict } from '@tangle-network/agent-eval' @@ -25,7 +25,7 @@ import type { RuntimeRunHandle } from '../runtime-run' // concerns (ValidationCtx with iteration + signal + traceEmitter). export type { DefaultVerdict } -/** @experimental */ +/** @stable */ export interface ValidationCtx { /** Iteration index this output came from (0-based). */ iteration: number @@ -45,7 +45,7 @@ export interface ValidationCtx { traceEmitter?: LoopTraceEmitter } -/** @experimental */ +/** @stable */ export interface Validator { validate(output: Output, ctx: ValidationCtx): Promise } @@ -59,7 +59,7 @@ export interface Validator { * fanout supplies multiple `AgentRunSpec`s and the kernel round-robins * through them when the driver plans N tasks. * - * @experimental + * @stable */ export interface AgentRunSpec { /** Sandbox SDK profile — what kind of agent runs the task. */ @@ -105,7 +105,7 @@ export interface AgentRunSpec { * do not receive the live AsyncIterable so they can be replayed against * persisted streams during tests / replays. * - * @experimental + * @stable */ export interface OutputAdapter { parse(events: SandboxEvent[]): Output @@ -129,7 +129,7 @@ export interface LoopTokenUsage { * its content fingerprint, its size, and where it came from — so a run is * auditable after the fact ("what exactly was this agent given?"). * - * @experimental + * @stable */ export interface MountManifestEntry { /** Destination path inside the box where the resource was placed. */ @@ -151,7 +151,7 @@ export interface MountManifestEntry { * human-readable reason, with no domain semantics. The kernel emits one receipt * per scored candidate at finalize so a run answers "why did THIS one win?". * - * @experimental + * @stable */ export interface SelectionReceipt { /** Iteration index this receipt is about. */ @@ -175,7 +175,7 @@ export interface SelectionReceipt { * it. Empty arrays when the caller recorded no mounts and there was no * candidate to select. * - * @experimental + * @stable */ export interface RunProvenance { /** Every resource recorded via `prepareBox`'s `recordMount`, in record order. */ @@ -189,11 +189,11 @@ export interface RunProvenance { * `prepareBox` so the caller — which owns the bytes it writes into the box — * declares what it mounted without the kernel having to inspect box contents. * - * @experimental + * @stable */ export type MountRecorder = (entry: MountManifestEntry) => void -/** @experimental */ +/** @stable */ export interface Iteration { /** 0-based iteration index assigned by the kernel. */ index: number @@ -218,7 +218,7 @@ export interface Iteration { tokenUsage: LoopTokenUsage } -/** @experimental */ +/** @stable */ export interface Driver { /** * Stable identifier surfaced in trace events. Default `'driver'`. @@ -260,7 +260,7 @@ export interface Driver { ): LoopWinner | undefined } -/** @experimental Driver-supplied description of the just-planned move. */ +/** @stable Driver-supplied description of the just-planned move. */ export interface LoopPlanDescription { /** Topology move this round — e.g. `'refine' | 'fanout' | 'verify' | 'stop'`. */ kind: string @@ -275,7 +275,7 @@ export interface LoopPlanDescription { parentIndex?: number } -/** @experimental */ +/** @stable */ export interface LoopWinner { task: Task output: Output @@ -284,7 +284,7 @@ export interface LoopWinner { agentRunName: string } -/** @experimental */ +/** @stable */ export interface LoopResult { decision: Decision iterations: Iteration[] @@ -318,7 +318,7 @@ export interface LoopResult { * Fleet-aware adapters set this; the raw `Sandbox` SDK class does not, and * the kernel falls back to `{ placement: 'sibling', sandboxId: box.id }`. * - * @experimental + * @stable */ export interface SandboxClient { create(options?: CreateSandboxOptions): Promise @@ -402,7 +402,7 @@ export interface LoopLineageOptions { streaming?: 'sse' | 'poll' } -/** @experimental */ +/** @stable */ export interface LoopSandboxPlacement { kind: 'sibling' | 'fleet' sandboxId?: string @@ -410,12 +410,12 @@ export interface LoopSandboxPlacement { machineId?: string } -/** @experimental */ +/** @stable */ export interface LoopTraceEmitter { emit(event: LoopTraceEvent): void | Promise } -/** @experimental */ +/** @stable */ export type LoopTraceEvent = | { kind: 'loop.started'; runId: string; timestamp: number; payload: LoopStartedPayload } | { kind: 'loop.plan'; runId: string; timestamp: number; payload: LoopPlanPayload } @@ -446,7 +446,7 @@ export type LoopTraceEvent = payload: LoopTeardownFailedPayload } -/** @experimental */ +/** @stable */ export interface LoopStartedPayload { driver: string agentRunNames: string[] @@ -460,7 +460,7 @@ export interface LoopStartedPayload { * the inferred fan-width. `moveKind` is the driver's `describePlan().kind` when * provided, else inferred from `plannedCount` (0→stop, 1→refine, N→fanout). * - * @experimental + * @stable */ export interface LoopPlanPayload { /** 0-based plan round (one per `plan()` call). */ @@ -481,7 +481,7 @@ export interface LoopPlanPayload { childIndices: number[] } -/** @experimental */ +/** @stable */ export interface LoopIterationStartedPayload { iterationIndex: number agentRunName: string @@ -498,7 +498,7 @@ export interface LoopIterationStartedPayload { * a shared-workspace fleet — workers see the caller's filesystem and any diff * they write lands on it directly. * - * @experimental + * @stable */ export interface LoopIterationDispatchPayload { iterationIndex: number @@ -516,7 +516,7 @@ export interface LoopIterationDispatchPayload { parentIndex?: number } -/** @experimental */ +/** @stable */ export interface LoopIterationEndedPayload { iterationIndex: number agentRunName: string @@ -539,13 +539,13 @@ export interface LoopIterationEndedPayload { outputPreview?: string } -/** @experimental */ +/** @stable */ export interface LoopDecisionPayload { decision: string historyLength: number } -/** @experimental */ +/** @stable */ export interface LoopEndedPayload { winnerIterationIndex?: number totalCostUsd: number @@ -557,7 +557,7 @@ export interface LoopEndedPayload { /** Emitted when a box's `delete()` throws or times out during teardown — the * loop swallows the failure (platform reaps on expiry) but surfaces it here so - * a real leak (e.g. mid-loop auth expiry) is observable. @experimental */ + * a real leak (e.g. mid-loop auth expiry) is observable. @stable */ export interface LoopTeardownFailedPayload { sandboxId?: string /** `'timeout'` or the delete error message. */ @@ -567,7 +567,7 @@ export interface LoopTeardownFailedPayload { /** * Execution context for `runAgentRounds`: the sandbox client the kernel creates boxes through, plus optional runtime hooks. * - * @experimental + * @stable */ export interface ExecCtx { /** Sandbox SDK client — the kernel calls `.create()` per iteration. */ diff --git a/src/testing/fixtures/agent-improvement-proposal.json b/src/testing/fixtures/agent-improvement-proposal.json index 6733d57b..656c1411 100644 --- a/src/testing/fixtures/agent-improvement-proposal.json +++ b/src/testing/fixtures/agent-improvement-proposal.json @@ -1,6 +1,6 @@ { "changedSurfaces": ["prompt"], - "digest": "sha256:51691ad716939f633997479cb6a54458806eeb9d693a520e64b4400c035cc187", + "digest": "sha256:6eb44a120bafca53e7744cfb4f6b2973591d91744da28a8493c5265332535bf2", "evaluation": { "decision": { "contributingChecks": [ @@ -4810,7 +4810,7 @@ ], "metadata": { "fixture": "agent-improvement-proposal", - "runtimeVersion": "0.129.0" + "runtimeVersion": "0.130.0" }, "objectives": [ { @@ -4921,8 +4921,8 @@ "baselineContentHash": "sha256:5c21ee53e513fc604cb09754e21c392b24a424da0ef37dbf8f1ee4a8a0b08f09", "candidateContentHash": "sha256:60fcbb1c728194bd51d7d19cb732d1c3f1881dce7e0a6266b41c8b98cfd65693", "kind": "agent-eval-loop", - "recordDigest": "sha256:aa49f5a490a6cab44580a20bf8f454862eff990823e576d7d063ad3c59c951f2", - "runId": "agent-runtime-0.129.0-proposal-fixture", + "recordDigest": "sha256:1cb73229028fbc76a369bc38c0676de924bfce2c74603e9fc288e8409eb5d317", + "runId": "agent-runtime-0.130.0-proposal-fixture", "schema": "agent-candidate-experiment" } }, @@ -4949,5 +4949,5 @@ ], "kind": "agent-improvement-proposal", "proposedAt": "2026-07-10T01:00:00.000Z", - "runId": "agent-runtime-0.129.0-proposal-fixture" + "runId": "agent-runtime-0.130.0-proposal-fixture" } diff --git a/src/testing/fixtures/agent-profile-improvement-proposal.json b/src/testing/fixtures/agent-profile-improvement-proposal.json index 988f9d8f..0025cac3 100644 --- a/src/testing/fixtures/agent-profile-improvement-proposal.json +++ b/src/testing/fixtures/agent-profile-improvement-proposal.json @@ -1,6 +1,6 @@ { "changedSurfaces": ["prompt", "skills"], - "digest": "sha256:ac0b55438c591e740c19eb7b39e119f99f1d0e220c3cb3f785a7d1a3f49bfb48", + "digest": "sha256:dff67627a77309e9c0abe5173e4ff4c581e289049be4c8ccb9999bf429430482", "evaluation": { "decision": { "contributingChecks": [ @@ -1715,7 +1715,7 @@ ], "metadata": { "fixture": "agent-profile-improvement-proposal", - "runtimeVersion": "0.129.0" + "runtimeVersion": "0.130.0" }, "objectives": [ { @@ -1826,7 +1826,7 @@ "baselineContentHash": "sha256:21c495a37c418c10bde64fbaa188beddeed31f1f051ea60a6a6582a9ee0db704", "candidateContentHash": "sha256:103f77bc8481601eef1ad5fe6ba84a40dffabc3a44f421f8c8559121edab84e9", "kind": "agent-eval-loop", - "recordDigest": "sha256:c9bb01de88046bd5c02d32f323f02651614a2870a8af3ffe9a9f0bceb4a0aa63", + "recordDigest": "sha256:732444d0214da643c8acb3ac9c76823b0ab5c9751f4497638d4c8db016a2bf86", "runId": "profile-improvement-1", "schema": "agent-profile-improvement-experiment" } diff --git a/src/tui/index.ts b/src/tui/index.ts index a1d0f5bf..979e06eb 100644 --- a/src/tui/index.ts +++ b/src/tui/index.ts @@ -17,6 +17,7 @@ * * The runnable form is the `agent-runtime-top` bin: `agent-runtime-top [--once] [--no-color]`. * + * @module * @experimental */ diff --git a/tsdoc.json b/tsdoc.json index 8c6e1544..cee17674 100644 --- a/tsdoc.json +++ b/tsdoc.json @@ -1,5 +1,8 @@ { "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", + "extends": [ + "typedoc/tsdoc.json" + ], "tagDefinitions": [ { "tagName": "@stable",