@tangle-network/agent-runtime / durable
Durable, append-only third-person history for one concrete Runtime execution. It consumes Runtime's existing hook stream and does not participate in execution decisions. A broken observer therefore cannot change what an agent is allowed to do.
The write discipline deliberately matches FileSpawnJournal: serialized appends,
torn-tail recovery, short-write handling, and fsync before acknowledgement. One
execution owns one journal file; higher-level pursuit aggregation joins isolated
journals by pursuitId instead of making independent processes share a write head.
new FileObserverJournal(
path,pursuitId):FileObserverJournal
string
string
readonlypath:string
readonlypursuitId:string
hooks():
RuntimeHooks
appendEvent(
event):Promise<ObserverRecord>
Promise<ObserverRecord>
appendDecision(
point):Promise<ObserverRecord>
Promise<ObserverRecord>
ObserverJournal.appendDecision
read():
Promise<readonlyObserverRecord[]>
Promise<readonly ObserverRecord[]>
A failed Runtime execution whose complete third-person projection was retained.
Error
new SupervisePursuitError(
cause,pursuit,observerPath):SupervisePursuitError
unknown
string
Error.constructor
readonlypursuit:PursuitProjection
readonlyobserverPath:string
The NDJSON line protocol every product chat client already speaks.
type:
string
optionaldata?:Record<string,unknown>
Identity of a chat turn. tenantId is the workspace id for workspace-
scoped products and the user id for session-scoped products.
tenantId:
string
sessionId:
string
Thread / session id.
userId:
string
turnIndex:
number
Monotonic 0-based turn index within the session.
The live side of a turn returned by the product's produce hook.
TEvent extends ChatStreamEvent = ChatStreamEvent
stream:
AsyncGenerator<TEvent,void,unknown>
The turn's event stream. Forwarded verbatim to the caller.
finalText():
string
The turn's final assistant text. Read once, after stream drains.
string
Product callbacks invoked while one chat turn runs.
produce():
ChatTurnProducer
Build the backend stream. The engine forwards events verbatim and
reads finalText() once the stream drains.
persistAssistantMessage(
input):Promise<void>
Persist the assistant message to the product's own store. Called once, after drain, with the assembled (transform-applied) text.
string
Promise<void>
optionalonTurnComplete(input):Promise<void>
Optional post-processing for proposals, citations, or credit metering. Errors are logged without failing a turn that already streamed.
string
Promise<void>
optionalonEvent(event):void|Promise<void>
Optional per-event side channel, such as a Durable Object broadcast. Runs for every emitted event, including the lifecycle envelope. Errors are logged without breaking the chat stream.
void | Promise<void>
optionaltransformFinalText(text):string|Promise<string>
Optional pre-persist transform of the final text (e.g. PII redaction). Affects only what is persisted; the live stream is never altered.
string
string | Promise<string>
optionaltraceFlush():Promise<void>
Optional trace flush. Handed to waitUntil so the worker stays alive
until export completes.
Promise<void>
Inputs for one streamed product chat turn.
identity:
ChatTurnIdentity
hooks:
ChatTurnHooks
optionalwaitUntil?: (p) =>void
Worker liveness hook. When omitted, trace flush is awaited inline before the stream closes.
Promise<unknown>
void
optionallog?: (message,meta?) =>void
Structured logger for swallowed hook errors. Defaults to
console.error so failures surface without product wiring.
string
Record<string, unknown>
void
HTTP response values returned for one chat turn.
body:
ReadableStream<Uint8Array<ArrayBufferLike>>
NDJSON body to return as the platform Response body.
contentType:
"application/x-ndjson"
Content type for the response.
One immutable record in the observer plane. sequence is journal order, not
execution order; causal/runtime order remains available on the underlying event.
previousDigest + digest make deletion, reordering, or mutation detectable.
readonlyschemaVersion:1
readonlypursuitId:string
readonlysequence:number
readonlykind:ObserverRecordKind
readonlyobservedAt:number
readonlyoptionalpreviousDigest?:string
readonlyoptionalevent?:RuntimeHookEvent<unknown>
readonlyoptionaldecision?:RuntimeDecisionPoint
readonlydigest:string
appendEvent(
event):Promise<ObserverRecord>
Promise<ObserverRecord>
appendDecision(
point):Promise<ObserverRecord>
Promise<ObserverRecord>
read():
Promise<readonlyObserverRecord[]>
Promise<readonly ObserverRecord[]>
hooks():
RuntimeHooks
One node's token usage by class. Cache and reasoning classes are absent when the provider did
not report them — absence is not zero. tokensKnown is false when work happened whose token
count no provider reported, which makes input/output a floor.
readonlyinput:number
readonlyoutput:number
readonlyoptionalcacheRead?:number
readonlyoptionalcacheWrite?:number
readonlyoptionalreasoning?:number
readonlytokensKnown:boolean
One node's dollar cost with the provenance that decides whether it may be compared or summed.
readonlyusd:number
readonlyusdKnown:boolean
readonlyoptionalusdEstimated?:number
The part of usd a model catalog priced because no provider receipt covered it.
readonlyprovenance:PursuitCostProvenance
One node's clock. wallMs is settledAt - startedAt and is deliberately distinct from the
executor-reported spent.ms sums, which under-report and overlap across parallel children.
firstTokenAt stays absent unless a provider reports that instant; it is never inferred from
firstOutputAt, which is when the node first reported usage for a turn.
readonlystartedAt:number
readonlyoptionalfirstOutputAt?:number
readonlyoptionalfirstTokenAt?:number
readonlyoptionalsettledAt?:number
readonlyoptionalwallMs?:number
One run's spend counted once, and each node's own share of it. inclusive and the entries of
exclusiveByNode are the two views a client needs to show a tree without double counting.
readonlyinclusive:Spend
The whole run counted once. A node's settled spent already contains the child work its own
nested tree reported, so summing only the run's top-level nodes plus every node's own
inference counts each model call exactly once.
readonlyexclusiveByNode:Readonly<Record<string,Spend>>
Each node's own share: its reported spend and own inference minus what its direct children
reported. Keyed by node id, plus the run root when the root itself metered inference. The
entries sum to inclusive by construction.
readonlyrunId:string
readonlystatus:PursuitStatus
readonlyoptionalsettledAt?:number
readonlyoptionalerror?:string
readonlyfirstSequence:number
readonlylastSequence:number
readonlyfirstObservedAt:number
readonlylastObservedAt:number
readonlyeventCount:number
readonlydecisionCount:number
readonlytargets:Readonly<Record<string,number>>
readonlydecisions:Readonly<Record<string,number>>
readonlytotals:PursuitRunTotals
readonlyoptionalspendGaps?: readonlySpendGap[]
The nodes whose accounting is incomplete. Present exactly when non-empty.
readonlyid:string
readonlyoptionalparentId?:string
readonlyrunId:string
Node ids are scoped to this concrete Runtime tree; (runId,id) is identity.
readonlyoptionallabel?:string
readonlyoptionalruntime?:string
The runner that executed this node — the executor's own name, not a harness guess.
readonlyoptionaldepth?:number
readonlyoptionalassignmentId?:string
readonlyoptionalidentity?:unknown
readonlyoptionalbudget?:unknown
readonlystatus:PursuitStatus
readonlyoptionalsettledAt?:number
readonlyoptionalspent?:Spend
The child work this node reported at settlement. Absent until a terminal record lands.
readonlyoptionalownInference?:Spend
This node's OWN inference, re-homed from its nested tree. Absent when it drove no turns.
readonlyoptionalusage?:PursuitNodeUsage
Absent until a spend record lands; the run's spendGaps then names the node.
readonlyoptionalcost?:PursuitNodeCost
Absent until a spend record lands; the run's spendGaps then names the node.
readonlyoptionaltiming?:PursuitNodeTiming
readonlyoptionalattemptId?:string
The kernel-minted attempt this node's execution binding is keyed on.
readonlyoptionalexecution?:object
The runner-native execution the node bound to: a request, session, run, process, or tree.
readonlykind:string
readonlyid:string
readonlyoptionalmodel?:string
The model the materialization receipt names, when the runner reported one.
readonlyoptionalbackend?:string
The concrete backend the profile materialized onto.
readonlyoptionalplacement?:Readonly<Record<string,string|number|boolean|null>>
readonlyoptionalmodelCalls?: readonlystring[]
Model-call identifiers this node's own turns reported, in order, deduplicated.
readonlyoptionalmaterialization?:ProfileMaterializationReceipt
readonlyoptionalexecutionBindings?: readonlyExecutionBindingReceipt[]
readonlyoptionalproviderModel?:ProviderModelExecutionEvidence
What the provider itself reported serving, and why it is unknown when it is.
readonlyoptionaltrace?:WorkerTraceEvidence
Content-addressed pointer to this node's persisted tool trace, or why there is none.
readonlyoptionaloutRef?:string
readonlyoptionalscore?:number
readonlyoptionalvalid?:boolean
readonlyoptionalreason?:string
readonlyoptionalinfra?:boolean
readonlyoptionalwait?:unknown
readonlyfirstSequence:number
readonlylastSequence:number
readonlyfirstObservedAt:number
readonlylastObservedAt:number
readonlyeventCount:number
readonlyturnCount:number
readonlypursuitId:string
readonlysequence:number
Number of records in this concrete execution journal.
readonlychainTip:string
Digest-chain tip for this concrete execution journal.
readonlyfirstObservedAt:number
readonlylastObservedAt:number
readonlyruns: readonlyPursuitRunProjection[]
readonlynodes: readonlyPursuitNodeProjection[]
readonlyeventCount:number
readonlydecisionCount:number
readonlypursuitId:string
Stable objective identity spanning concrete Runtime runs.
readonlyrunDir:string
One concrete Runtime execution owns one durable directory and observer journal.
A pursuit spanning several runs reuses pursuitId across distinct runDirs;
Intelligence joins those isolated projections without a shared write head.
readonlybudget:Budget
The conserved compute pool for the whole run.
readonlyoptionalrootHandle?:RootHandle<unknown>
Caller-created live handle for observing, steering, or cancelling this root manager. Runtime attaches it before execution and detaches it after the join barrier.
readonlyoptionalsignal?:AbortSignal
Caller-owned cancellation for the complete recursive run. Aborting it cascades through the root scope and every live child, including acquisition and backend execution.
readonlyoptionalexecution?:AgentExecutionRef
Trusted candidate and pursuit attribution for the root. The runtime derives profile/task digests itself from the exact detached values it executes.
readonlyoptionalbackend?:ExecutorConfig
WHERE workers run — derives the worker seam. Provide this OR an explicit makeWorkerAgent.
readonlyoptionaldeliverable?:string|DeliverableSpec<unknown>
The independent completion check for backend-derived workers and direct supervisor
submissions. Strongly recommended: without it the supervisor cannot submit its own work and
backend-derived workers fall back to their own validity signal. A string names an entry in
registry.deliverables.
readonlyoptionalresolveDeliverable?: (input) =>DeliverableSpec<unknown> |undefined
Resolve the completion check for one exact authorized backend-derived leaf. The callback runs
after spawn authorization and driver classification, receives a detached immutable context,
and may return undefined to use the run-wide deliverable. Driver profiles never call it.
DeliverableSpec<unknown> | undefined
SuperviseOptions.resolveDeliverable
readonlyoptionalregistry?:SuperviseRegistry
Name→value tables for the four code-valued options, so a recorded run configuration can name them instead of carrying closures. See SuperviseRegistry.
readonlyoptionalcoordination?:CoordinationBinding
Where the coordination MCP binds when the supervisor is harness-driven. Omit = an ephemeral
port on 127.0.0.1, which an off-host root cannot reach. A non-loopback host is refused
unless allowUnauthenticatedRemote acknowledges that the verbs are unauthenticated.
readonlyoptionalpeerMail?:boolean| {limits?:Partial<PeerMailLimits>; }
OPT-IN peer mail for the run's workers: sibling-to-sibling send_mail / read_mail, bounded
and audited (CoordinationToolsOptions.peerMail). The runtime mints one capability URL per
spawn, serves the mail listener beside the coordination MCP, and hands each worker its
endpoint on WorkerSpawnContext.peerMailUrl. Mounting that URL into the worker is the
makeWorkerAgent owner's job today: the runtime never writes it into a worker profile, since
the fresh random URL would move the canonical profile digest, and bridge workers cannot mount
it out of band until the bridge carries runtime attachments (#774). Requires a harness-brained
supervisor; a router-brained supervisor is refused rather than silently unmailed.
readonlyoptionalmakeWorkerAgent?:MakeWorkerAgent
Override the worker seam directly (tests / advanced) instead of deriving it from backend.
This is caller-owned execution: profile security, spawn authorization, and recursive-driver
selection below apply only to the backend-derived worker path. authorizeMessage still
governs continuations sent through Runtime's coordination tools.
SuperviseOptions.makeWorkerAgent
readonlyoptionalmakeLeafAgent?:MakeWorkerAgent
Override ONLY how an authorized LEAF executes, keeping the whole backend-derived path —
profile security, spawn authorization, recursive-driver selection, nested supervisors — in
force. Unlike makeWorkerAgent, which replaces that path, this slots inside it: the kernel
authorizes and classifies every spawn, and a child that is NOT a driver runs through this
factory instead of backend. A child that IS a driver still becomes a nested supervisor, whose
own leaves use this same factory. Composes with authorizeSpawn; backend is then optional.
This is the seam an offline test or a pinning layer (an agent graph) should use.
SuperviseOptions.makeLeafAgent
readonlyoptionaldriverBackend?:ExecutorConfig
Run harness-brained supervisors here. Automatic execution supports a local bridge; a remote
sandbox requires an explicit driveHarness with a reachable coordination relay or tunnel.
Defaults to backend; separate it when managers and workers use different services.
SuperviseOptions.driverBackend
readonlyoptionalprofileSecurity?:AgentProfileSecurityPolicy
Security policy applied to every manager-authored child profile before budget reservation. The default blocks local and remote MCP, hooks, and connection grants. Pass an explicit allowlist to grant remote MCP hosts or other author-controlled capabilities.
SuperviseOptions.profileSecurity
readonlyoptionalauthorizeSpawn?: (input) =>AuthorizedSpawn
Product authority over one complete manager-authored spawn. The callback sees the detached, immutable profile, task, budget, label, and key together, so approving a profile cannot authorize a different task. Return the exact allowed profile (which may be narrowed) plus trusted candidate/pursuit attribution, or throw to refuse the whole spawn before reservation.
AgentProfile
AgentProfile
Trusted identity of the manager authorizing this exact child.
string
Concrete manager node; never accepted from model-authored tool arguments.
string
Stable manager-scoped assignment, including deterministic unkeyed siblings.
unknown
string
string
number
string
Present (as the analyst id) only when the runtime's analyst-on-settle hook initiated this spawn — authored by the runtime, never accepted from a driver's tool arguments. A node-pinning authority reads it to admit the analyst node it would refuse as a driver-authored spawn.
The EFFECTIVE continuity of this spawn, resolved by the coordination layer.
SuperviseOptions.authorizeSpawn
readonlyoptionalauthorizeMessage?: (input) =>AuthorizedDownMessage
Product authority over every continuation sent to a live child. When spawn authorization is enabled, omitting this refuses steer/answer instructions instead of silently extending the authorized task. The exact worker identity and detached bytes are recorded before delivery.
DownMessageAuthorizationInput & object
SuperviseOptions.authorizeMessage
readonlyoptionalisDriverProfile?: (input) =>boolean
Decide whether an authorized child becomes another supervisor. By default only
metadata.role === 'driver' does. Products receive the same frozen post-authorization
context as resolveDeliverable, so trusted execution/assignment authority can override
model-authored metadata without a side channel.
boolean
SuperviseOptions.isDriverProfile
readonlyoptionalrouter?:RouterTransportConfig
The supervisor's router substrate (profile.harness omitted or cli-base). The profile's
model wins.
readonlyoptionalrootDriverFromBackend?:boolean
When driverBackend is absent, whether an external-harness ROOT may default to running on
backend (where workers run). true (default) keeps the convenience every direct caller has.
A layer that gives backend a narrower meaning — runGraph, where it places WORKER nodes only
— sets false, so an external root without an explicit driverBackend is refused before any
compute rather than silently driven from the worker placement.
SuperviseOptions.rootDriverFromBackend
readonlyoptionalresolveSpawnProfile?: (profile) =>AgentProfile
Pre-journal profile resolution for the spawn pre-flight: the profile a driver authored →
the profile that will run (CoordinationToolsOptions.resolveSpawnProfile). A pinning layer
sets this alongside authorizeSpawn so the backend gate and the authorization see the same
canonical profile. Identity-free and synchronous; throw to refuse.
AgentProfile
AgentProfile
SuperviseOptions.resolveSpawnProfile
readonlyoptionaldriveHarness?:DriveHarness
Run an external-harness supervisor explicitly. Required for a remote sandbox; optional as a caller-owned override for a local bridge.
readonlyoptionaldriverRetry?:DriverRetryPolicy
How hard a transiently-failed EXTERNAL driver is re-entered before the run ends
driver-failed. A harness process SIGKILLed at a bridge timeout, a stream cut mid-turn, or an
upstream 5xx used to end a run of arbitrary length while its budget and deadline sat almost
untouched (#741). A retry re-enters the driver over the SAME scope, coordination server, and
live children; the bridge backend reattaches the harness session by its durable execution id.
Runtime's own refusals (a validation guard, an exhausted budget, an abort, a client-side transport status) are never retried — they were decisions. Retries stop at the budget, the deadline, an abort, or a run of attempts that changed nothing at all.
Omit = retry under the defaults. { enabled: false } = the historical behavior where the first
driver failure ends the run. Applies to the root manager and every recursive manager under it.
readonlyoptionalonDriverAttempt?: (record) =>void|Promise<void>
Per-attempt record for every external driver in the tree — what makes "failed after N attempts, last cause X" visible instead of one backend's last words.
void | Promise<void>
SuperviseOptions.onDriverAttempt
readonlyoptionalchildSettleGraceMs?:number
How long live children may keep running after the ROOT DRIVER FAILED, before the join barrier
cascades the abort into them. A root that died did not make its children unhealthy: a child
mid-unit holds work already paid for, and an immediate cascade discards everything it has not
yet written. Bounded by the run's own deadline. Omit/0 = immediate teardown.
SuperviseOptions.childSettleGraceMs
readonlyoptionalresolveDriveHarness?:ResolveDriveHarness
Resolve one custom external-harness session per trusted manager identity. Use this instead of
driveHarness when recursive managers must be independently steerable.
SuperviseOptions.resolveDriveHarness
readonlyoptionaldriveHarnessMaterialization?:ProfileMaterializationContract
Required with a custom driveHarness or resolveDriveHarness: declares which complete
AgentProfile axes that path really applies. Built-in bridge driving supplies its own
full-profile contract.
SuperviseOptions.driveHarnessMaterialization
readonlyoptionalresolveSupervisorTools?:ResolveSupervisorTools
Resolve product-owned tools from the exact trusted manager context. The same descriptors and
handlers are bound to router and external-harness managers; resolution happens once per node.
Each handler receives that manager scope's live cancellation signal in its trusted invocation
context, including recursive parent and root cascades, plus context.verbs — that manager's
own coordination verbs, callable in code so a product tool can COMPOSE its children (fan out,
chain, join, retry) in one tool call instead of one model turn per verb. Every verb crosses
the same authorizeSpawn / security / allowedModels gate, pool reservation, maxLiveWorkers
cap, journal, and bus the MCP verb crosses, at every depth and on both arms.
SuperviseOptions.resolveSupervisorTools
readonlyoptionalonCoordinationEvent?: (context,eventId,record) =>void|Promise<void>
Awaited product transaction hook for every coordination record. eventId is stable across a
lost acknowledgement and durable restart; the record is not pull-visible until this commits.
`sha256:${string}`
void | Promise<void>
SuperviseOptions.onCoordinationEvent
readonlyoptionalextraTools?: readonlyobject[]
WORK tools the supervisor may call DIRECTLY — so a recursive atom can ACT (do simple work
itself) OR SPAWN (delegate when it needs parallelism), not be a pure manager. Pair with
executeExtraTool. Router arm only (profile.harness omitted or cli-base).
readonlyoptionalexecuteExtraTool?: (name,args) =>Promise<string|null|undefined>
Runs an extraTools call; null/undefined falls through to the coordination dispatch.
string
Record<string, unknown>
Promise<string | null | undefined>
SuperviseOptions.executeExtraTool
readonlyoptionalperWorker?:Budget
Per-child budget reserved on each spawn. Defaults to a quarter of the pool's tokens.
readonlyoptionalmaxLiveWorkers?:number
Hard cap on simultaneously executing spawned workers across the WHOLE recursive tree. The
root is excluded; nested drivers and leaves share one allocation, so recursion cannot multiply
the cap. Omit/<= 0 = no cap (the conserved pool stays the only bound).
SuperviseOptions.maxLiveWorkers
readonlyoptionalanalysts?:string|AnalystRegistry
Analyst lenses available to the driver. Required for analyzeOnSettle. Unset → status quo
(the driver receives settled worker outputs, no analyst findings). A string names an entry in
registry.analysts.
readonlyoptionalanalyzeOnSettle?: readonly (string|AnalyzeOnSettleRoute)[]
Analyst kind ids run AUTOMATICALLY when a worker settles done — each re-enters as a finding
the driver pulls (await_event) and composes its next steer from. The self-improving UP-leg,
threaded to the driver at this level (propagate to sub-drivers via a recursive makeWorkerAgent).
Omit/empty = status quo (no analyst feed). Requires analysts.
SuperviseOptions.analyzeOnSettle
readonlyoptionalwatchWorkers?:WorkerWatchOptions
Watch every worker's LIVE tool trace with the online detector panel and raise a finding the
moment one loops or error-storms — so the supervisor learns it mid-run (via await_event)
instead of at settle. Pairs with a steerable worker: the finding is the evidence, steer_agent
is the correction. Requires a backend whose executor exposes a trace source (the steerable
sandbox worker and the pi wrapper do); other runtimes are simply not watched.
Omit = off (status quo — no online watching, no extra events).
readonlyoptionalstallAfterMs?:number
Idle time after which observe_agent reports a running worker as stalled. A derived read
at observation time — nothing is killed or retried. Omit = the runtime default.
readonlyoptionalcontinuityByProfile?:Readonly<Record<string,ContinuityMode>>
Default continuity per worker PROFILE NAME: 'resume' makes each spawn of that name after
the first re-attach to the node's most recent SETTLED worker — a NEW live worker whose spawn
context carries the prior worker's identity (WorkerSpawnContext.resume), which the executor
seam re-attaches with. spawn_agent's per-call continuity argument overrides in either
direction; runGraph derives this from delegates-edge continuity. Omit = every spawn is
'fresh' (status quo). See CoordinationToolsOptions.continuityByProfile for the
refusal semantics (no-prior / while-live / with-key) and the process-local resume boundary.
SuperviseOptions.continuityByProfile
readonlyoptionalblobs?:ResultBlobStore
Worker output store. Defaults to in-memory.
readonlyoptionaljournal?:SpawnJournal
Override the spawn journal directly (advanced; runDir is the ordinary durable path). Pair
with blobs — a journal whose result payloads live in a different store cannot replay.
readonlyoptionalprobes?:string|WaitProbeRegistry
Predicate registry for poll wait-states (Scope.wait). A poll names its predicate so the
wait survives a restart; this is what the name resolves against. Unset ⇒ poll waits are
refused unknown-probe and timer waits still work. A string names an entry in
registry.probes.
readonlyoptionalstopRule?:StopRule
PROGRESS-derived stop rule (BOTH arms). Ends a run that has stopped LEARNING before it exhausts a ceiling — the answer to "a run should end because it is done or stuck, not because it ran out". It composes with the budget guards and can never override one.
The evaluation boundary differs by arm because the loop does: a router-brained supervisor is evaluated before each of its own inference turns; a harness-brained supervisor is evaluated on each worker settle, and a stop aborts its stop signal so the harness ends at its next turn boundary. Both arms fold the same settled ledger through the same evaluator.
Build it from supervise/stop-rules: plateau({window, minDelta}),
noProgressFor({ms, settles}), allWorkersStalled({...}), combined with anyOf/allOf. The
thresholds are policy and stay with you; the enforcement lives in the runtime. Omit = ceilings
only (unchanged behavior).
readonlyoptionalonProgressStop?: (reason) =>void
One-shot notification of WHY a stopRule ended the run (BOTH arms) — so a caller records the
reason instead of inferring an early stop from an unexhausted budget.
string
void
SuperviseOptions.onProgressStop
readonlyoptionalmaxDepth?:number
readonlyoptionalmaxTurns?:number
Turn cap for the supervisor's OWN loop (BOTH arms). Router arm: inference turns of the
driver's tool loop. Harness arm: turns the harness reports, counted off its iteration
stream — reaching the cap aborts the stop signal, so the harness ends at its next turn
boundary rather than mid-request. 0 lifts the cap on both arms and leaves the conserved
pool, the deadline, and abort as the bounds; a negative value is refused. Omit = the router
arm's default cap, and no turn cap on the harness arm.
readonlyoptionalcompaction?:ToolLoopCompactionOptions
Give the supervisor brain a chapter-lifecycle on its OWN context window (ROUTER ARM ONLY —
a harness owns its own context window and its own compaction, so this is refused for a
harness-brained supervisor rather than silently ignored): once its coordination transcript
exceeds thresholdTokens it distills to a compact progress note and continues, instead of
re-billing the whole transcript every turn (the cost that makes the LLM-brain front door lose
to a dumb-Ralph respawn). The live Scope roster is the durable state across chapters.
Default off. distill defaults to a brain self-summary + the settled-worker roster.
readonlyoptionalrunId?:string
readonlyoptionalnow?: () =>number
number
readonlyoptionalallowedModels?: readonlystring[]
Restrict the run to this subset of models. When set, every configured model — the
supervisor router model, the profile's model, and the backend's model — must be a member,
or supervise() throws a ConfigError before any compute is spent. Unset = unrestricted.
This is a MODEL-ID filter, not a route filter. The compared values are the bare ids a profile
declares — model.default, model.small, subagents[].model, modes[].model. The composed
wire id (harness/provider/model) is never built here and never compared, so an entry written
in qualified form matches nothing, and a child that names an allowed id is admitted whatever
harness and provider its own profile declares. Pin the route with authorizeSpawn: it reads
the authored child profile and may refuse the spawn before any reservation.
SuperviseOptions.allowedModels
readonlyoptionalfinalizer?:string|SupervisorFinalizer
How the settled-worker ledger becomes the run's output. Default bestDelivered — the single
highest-scoring DELIVERED child (the exact behavior every existing caller had). Alternatives:
collectDelivered (every verified distinct output with provenance — a Pareto set / recorded
disagreement) or a custom SupervisorFinalizer. Whatever the finalizer, it operates on
structurally DELIVERED outputs only — an undelivered or invalid child stays ineligible. A
string names an entry in registry.finalizers.
readonlyoptionalhooks?:RuntimeHooks
Lifecycle observers for the whole recursive tree (Scope re-seeds them into every nested
scope). Composed with the otel recorder below when both are set. Omit = no observers, which
is the behavior every existing caller has.
readonlyoptionalotel?:Omit<SupervisorSpanOptions,"runId"|"now">
OPT-IN OTLP tracing: emit one span per supervised node (opened at spawn, closed at settle,
parented to its parent node's span) plus an LLM child span per metered driver turn, so the
tree is readable by any trace viewer instead of only by a journal parser. See otel-spans.ts.
Omit and the run emits nothing, allocates no recorder, and installs no hook — telemetry is
never a default. Present with no reachable endpoint (no exportConfig.endpoint and no
OTEL_EXPORTER_OTLP_ENDPOINT) is also a no-op. The spawn journal is untouched either way:
spans are telemetry, never the replay/resume record.
Result
readonlyresult:Result
readonlypursuit:PursuitProjection
readonlyobserverPath:string
readonlyrunId:string
readonlyownerIds: readonlystring[]
Exact owner ids present in the side-log, sorted for deterministic display.
readonlyunscopedRecords:number
Records written before owner-scoped coordination identities were introduced.
readonlyrecordCount:number
Identities discoverable from one supervise({ runDir }) directory without
already knowing the root node or coordination run id stored inside it.
readonlyrunDir:string
readonlyspawnJournalPath:string
readonlycoordinationLogPath:string
readonlyroots: readonlystring[]
readonlycoordinationStreams: readonlyDurableCoordinationStreamIdentity[]
ObserverRecordKind =
"event"|"decision"
PursuitStatus =
"running"|"done"|"down"
One settled projection status, shared by runs and nodes. down is the journal's own word for a
failure (a settlement is journaled as kind: 'down', cancellation included), so a consumer can
join run rows to node rows on status and read one failure population instead of two.
PursuitCostProvenance =
"reported"|"estimated"|"partial"|"unknown"
Where a node's dollar figure came from. reported = a provider billed all of it; estimated =
a model catalog priced all of it; partial = a provider billed part and a catalog priced the
rest; unknown = nothing priced it, so usd is a floor and never the cost.
PursuitNodePlacement =
Readonly<Record<string,string|number|boolean|null>>
Where and how a node's execution was placed, read off its execution-binding receipt.
handleChatTurn(
input):ChatTurnResult
Run one chat turn. Returns immediately with a ReadableStream body;
execution starts while the stream is constructed. Backend
failures surface as error + session.run.failed events.
deriveExecutionId(
input):string
Derive a stable execution id from the run identity.
The same (projectId, sessionId, turnIndex) tuple yields the same id.
Use the result as both PromptOptions.executionId and
PromptOptions.turnId on the first dispatch.
The execution id addresses the server-side execution for reconnect and
replay; the turn id makes a repeated dispatch idempotent.
An execution id alone does not make a repeated POST idempotent.
Format is readable, not hashed: operators grepping orchestrator logs
for gtm-agent:thread-abc:3 find the run without translating an
opaque id. Components are URL-encoded so delimiters inside caller ids
cannot collapse distinct tuples. The final id is limited to the
orchestrator replay route's 256-byte maximum. Execution ids are not a
secrecy boundary.
Wire integration:
- Initial dispatch: pass the result as
executionIdandturnId. - Stream replay: pass it as
executionIdwithlastEventId.
string
string
number
string
TypeError when either string id is blank.
RangeError when turnIndex is invalid or the result exceeds 256 bytes.
verifyObserverRecords(
records,pursuitId?): readonlyObserverRecord[]
Verify identity, monotonic sequence, payload shape, and the complete digest chain.
readonly ObserverRecord[]
string
readonly ObserverRecord[]
observerRecordDigest(
record):string
Compute the canonical SHA-256 digest for an unsigned observer record.
Omit<ObserverRecord, "digest">
string
createFileObserverHooks(
path,pursuitId):object
Build the canonical durable observer hook in one call.
string
string
object
readonlyjournal:FileObserverJournal
readonlyhooks:RuntimeHooks
projectPursuit(
records):PursuitProjection
Fold one append-only execution journal into a deterministic operator projection.
This is intentionally a READ model, not another state machine: it does not own execution, cannot steer agents, and can be rebuilt from the journal at any time. Projection verifies the complete hash chain first, so an operator view can never silently render a mutated or reordered observer history as trustworthy state.
Topology comes only from Runtime's canonical agent.spawn facts. Terminal node
state comes only from agent.child; concrete run state comes only from the root
agent.run lifecycle emitted by supervisePursuit. Node identity is scoped to the
concrete Runtime run so independent trees may both contain root:s0 without aliasing.
Usage, cost and timing are reported at the class the runtime measured them at. A missing
class stays ABSENT and the run names the node in spendGaps; nothing here converts an
unmeasured channel into a zero, because a fabricated zero is indistinguishable from free work.
readonly ObserverRecord[]
supervisePursuit(
profile,task,opts):Promise<SupervisedPursuitResult<{rootProviderModel:ProviderModelExecutionEvidence;kind:"no-winner";reason:"budget-exhausted"|"all-children-down"|"aborted";tree:TreeView;downCount:number;spentTotal:Spend;providerModel?:ProviderModelExecutionEvidence;teardownUnconfirmed?: readonlyUnconfirmedTeardown[];spendGaps?: readonlySpendGap[];error?:undefined; } | {rootProviderModel:ProviderModelExecutionEvidence;kind:"no-winner";reason:"driver-failed";tree:TreeView;downCount:number;spentTotal:Spend;providerModel?:ProviderModelExecutionEvidence;teardownUnconfirmed?: readonlyUnconfirmedTeardown[];spendGaps?: readonlySpendGap[];error:NoWinnerError; } | {rootProviderModel:ProviderModelExecutionEvidence;kind:"winner";out:unknown;outRef:string;verdict?:DefaultVerdict;tree:TreeView;spentTotal:Spend;providerModel?:ProviderModelExecutionEvidence;teardownUnconfirmed?: readonlyUnconfirmedTeardown[];spendGaps?: readonlySpendGap[];spentBreakdown?: {driverInference:Spend;childWork:Spend; }; }>>
One-call durable pursuit execution over the canonical supervise() kernel.
This is an adapter, not a second executor: it composes a durable third-person
observer into Runtime's existing recursive hook stream and then rebuilds the
operator projection after the same supervise() call settles. Agents never
receive the observer path or projection and their behavior does not depend on it.
Every concrete execution writes only inside its own runDir. Cross-run pursuit
aggregation is therefore lock-free at the observer layer: reuse pursuitId across
run directories and let Intelligence join the independently verified projections.
AgentProfile
unknown
Promise<SupervisedPursuitResult<{ rootProviderModel: ProviderModelExecutionEvidence; kind: "no-winner"; reason: "budget-exhausted" | "all-children-down" | "aborted"; tree: TreeView; downCount: number; spentTotal: Spend; providerModel?: ProviderModelExecutionEvidence; teardownUnconfirmed?: readonly UnconfirmedTeardown[]; spendGaps?: readonly SpendGap[]; error?: undefined; } | { rootProviderModel: ProviderModelExecutionEvidence; kind: "no-winner"; reason: "driver-failed"; tree: TreeView; downCount: number; spentTotal: Spend; providerModel?: ProviderModelExecutionEvidence; teardownUnconfirmed?: readonly UnconfirmedTeardown[]; spendGaps?: readonly SpendGap[]; error: NoWinnerError; } | { rootProviderModel: ProviderModelExecutionEvidence; kind: "winner"; out: unknown; outRef: string; verdict?: DefaultVerdict; tree: TreeView; spentTotal: Spend; providerModel?: ProviderModelExecutionEvidence; teardownUnconfirmed?: readonly UnconfirmedTeardown[]; spendGaps?: readonly SpendGap[]; spentBreakdown?: { driverInference: Spend; childWork: Spend; }; }>>
discoverDurableSupervisionRun(
runDir):Promise<DurableSupervisionDiscovery>
Discover the stable identities recorded by Runtime's durable supervision
files. This is the developer-facing first step before calling
FileSpawnJournal.loadTree(root), loadSpawnForest(journal, root), or
FileCoordinationLog.load(runId, ownerId).
Missing files produce empty collections. A malformed committed JSONL record still fails loud through the same parser used by the runtime; a torn final append is ignored because it was never acknowledged as committed.
string
Promise<DurableSupervisionDiscovery>