Skip to content

zidane/durable

The durable runtime seam, so an agent run continues after its process crashes.

import { … } from 'zidane/durable'src/durable/index.ts

Use this entry point to type or build a durable runtime. Pass one to createAgent({ durable, sessionId }) and the loop records each model call and tool call as a step, so a run continues after a crash instead of starting over: onInterrupted: 'resume' makes run() continue it first, or call agent.resume(), which resolves null when there is nothing to continue. agent.suspend() stops a run so the next process resumes it. createMemoryRuntime() keeps its steps in memory, for tests. For a file on disk use zidane/durable/sqlite, and for a Restate handler zidane/restate. See crash recovery.

TypeScript
import { createAgent } from 'zidane'
import { createMemoryRuntime } from 'zidane/durable'
import { anthropic } from 'zidane/providers/anthropic'

const runtime = createMemoryRuntime()
const agent = createAgent({ provider: anthropic(), durable: { runtime, onInterrupted: 'resume' }, sessionId: 'job-42' })
await agent.run({ prompt: 'Summarize the README.' })
console.log(runtime.mode)

Functions#

createMemoryDurableStateFunction#

An empty state for memoryRuntime.

TypeScript
function createMemoryDurableState(): MemoryDurableState

src/durable/memory.ts:117

createMemoryRuntimeFunction#

A memory runtime over a fresh state: what an agent uses when it is given no runtime.

TypeScript
function createMemoryRuntime(): DurableRuntime

src/durable/memory.ts:129

memoryRuntimeFunction#

A memory runtime over state. Several runtimes may share one state (two "processes" on one database); the state itself is the durable part.

TypeScript
function memoryRuntime(options: { state: MemoryDurableState }): DurableRuntime
Parameters
NameTypeDescription
options{ state: MemoryDurableState }

Runtime options.

src/durable/memory.ts:139

nestedCallFunction#

call of the nth call (from 1) made inside parentCall: a codemode script's inner calls, in the order the script makes them. Same as the nested call ids the loop already mints (cm1/1, cm1/2).

TypeScript
function nestedCall(parentCall: string, n: number): string
Parameters
NameTypeDescription
parentCallstring

call of the call that makes the nested ones (cm1).

nnumber

Position of the nested call, from 1.

string

<parentCall>/<n>.

src/durable/keys.ts:77

parseStepKeyFunction#

Split a key built by stepKey. Throws on anything else.

TypeScript
function parseStepKey(key: string): StepKeyParts
Parameters
NameTypeDescription
keystring

The key to split.

StepKeyParts

Its parts, unescaped.

src/durable/keys.ts:58

stepKeyFunction#

Build the key of a step. Throws on an empty run or call, or a negative or fractional turn or attempt.

TypeScript
function stepKey(parts: StepKeyParts): `${string}:${number}:${string}:${number}`
Parameters
NameTypeDescription
partsStepKeyParts

The key's parts. See StepKeyParts.

`${string}:${number}:${string}:${number}`

The escaped run:turn:call:attempt key.

src/durable/keys.ts:45

Classes#

RunLeaseHeldErrorClass#

A run could not start: another live process holds its session's lease (claimRunLease). owner: that process, when the lease names it.

TypeScript
class RunLeaseHeldError extends Error
TypeScript
new RunLeaseHeldError(sessionId: string, owner?: RunOwner)
Parameters
NameTypeDescription
sessionIdstring

The session whose lease is held.

owner?RunOwner

The process holding it, when the lease names it.

RunLeaseHeldError properties
NameTypeDescription
owner?readonlyRunOwner

The process holding it, when the lease names it.

sessionIdreadonlystring

The session whose lease is held.

src/durable/errors.ts:49

RunSuspendedErrorClass#

Agent.suspend stopped the run (a host draining before it exits). A control error: no step records it as failed, the run keeps its resumable mark, and Agent.resume continues it from its last committed step.

TypeScript
class RunSuspendedError extends Error
TypeScript
new RunSuspendedError()

src/durable/errors.ts:33

StaleEpochErrorClass#

A write guarded by a lease epoch matched no row: another process claimed the run since. The run stops at once, with no final save.

TypeScript
class StaleEpochError extends Error
TypeScript
new StaleEpochError(sessionId: string, epoch: number)
Parameters
NameTypeDescription
sessionIdstring

The session whose run moved to another process.

epochnumber

The epoch the refused write was guarded by.

StaleEpochError properties
NameTypeDescription
epochreadonlynumber

The epoch the refused write was guarded by.

sessionIdreadonlystring

The session whose run moved to another process.

src/durable/errors.ts:17

Constants#

MODEL_CALLConstant#

call of the model request of a turn.

TypeScript
const MODEL_CALL = 'model'

src/durable/keys.ts:33

RUN_TAKEN_OVER_MESSAGEConstant#

Shown when a run's lease moved to another process and its writes were refused.

TypeScript
const RUN_TAKEN_OVER_MESSAGE = 'this run continued in another process'

src/durable/errors.ts:8

Interfaces#

AwakeableOptionsInterface#

Options of RunScope.awakeable.

TypeScript
interface AwakeableOptions
AwakeableOptions properties
NameTypeDescription
key`${string}:${number}:${string}:${number}`

Step key of the wait. A run resumed after a restart asks again with the same key and gets the same awakeable back, with any resolution that arrived while no process was running it.

timeoutMs?number

Deadline, stored as an absolute time when the awakeable is created. Unset or non-positive: no deadline. Ignored when the key already has an awakeable: the deadline stays the stored one.

src/durable/types.ts:238

AwakeableRecordInterface#

A stored awakeable (the awakeables table of the SQLite adapter). id is unique; (sessionId, key) finds it again on resume.

TypeScript
interface AwakeableRecord
AwakeableRecord properties
NameTypeDescription
deadline?number

Absolute deadline (epoch ms), when the awakeable has one.

idstring

The id a resumer resolves it with.

key`${string}:${number}:${string}:${number}`

See AwakeableOptions.key.

resolvedboolean

A resumer resolved it.

sessionIdstring

Session of the run that waits.

value?JsonValue

What the resumer sent, once resolved.

src/durable/types.ts:268

DurableAwakeableInterface#

A wait a resumer ends: its id, and the promise that settles with the outcome.

TypeScript
interface DurableAwakeable<T>
DurableAwakeable type parameters
NameDescription
T
DurableAwakeable properties
NameTypeDescription
idstring

Hand this to the resumer (resolveAwakeable(id, value)).

promisePromise<AwakeableOutcome<T>>

Settles when a resumer resolves the awakeable or its deadline passes.

settled?{ value: T }

The resolution, when the key's awakeable was already resolved as it was asked for (a resumed run whose answer arrived meanwhile): the caller can skip announcing the wait. Unset where the runtime cannot tell (a journal).

src/durable/types.ts:254

DurableInspectorInterface#

Read access to what a runtime stored, for tests and diagnostics.

TypeScript
interface DurableInspector
DurableInspector properties
NameTypeDescription
awakeables() => Promise<AwakeableRecord[]>

Every stored awakeable.

partials(runId?: string) => Promise<StreamPartialRecord[]>

Stream partials, in write order.

steps(runId?: string) => Promise<StepRecord[]>

Step records, of one run or of all. Pruned records are gone.

src/durable/types.ts:284

DurableLeaseInterface#

Who runs a session's run, fenced by an epoch. The agent claims the lease when a run starts (run or resume) and passes the epoch to DurableRuntime.openRun. Every claim bumps the epoch; every turn, step and queue write of the holder is guarded by it, so the writes of an owner that lost the lease (a laptop waking from sleep) are rejected (StaleEpochError) instead of interleaving with the new owner's. Absent on runtimes whose platform already guarantees a single writer.

TypeScript
interface DurableLease
DurableLease properties
NameTypeDescription
claim(sessionId: string, options: { onStale?: (error: StaleEpochError) => void; owner?: RunOwner; staleAt: number }) => Promise<LeaseClaim>

Take the session's run. Succeeds when no live owner holds it: no lease, one released, one held by an owner known dead (isRunOwnerDead), one last renewed at or before staleAt by an owner that no longer holds it (isRunOwnerHolding: a quiet owner on this host that still runs keeps it for up to RUN_OWNER_HOLD_MS), or one held under this process's own owner token. A successful claim fences the session on this runtime until release: its writes are guarded by the new epoch, and onStale is told when one is refused (the run stops at once).

epoch(sessionId: string) => Promise<number | null>

Current epoch of the session, null when it was never claimed.

release(sessionId: string, epoch: number) => Promise<void>

Give the lease up and lift this runtime's fence. A stale epoch leaves the stored lease alone.

renew(sessionId: string, epoch: number) => Promise<boolean>

Keep the lease alive. false: epoch is no longer the current one.

resumable(options: { sessionId?: string; staleAt: number }) => Promise<ResumableRun[]>

Top-level runs to resume: still marked resumable (SessionRun.resumable, set while a checkpoint run is in progress), of a session whose lease lapsed (leaseLapsed: released, held by a dead owner, or not renewed since staleAt by an owner that no longer holds it), and not parked on an awakeable (the run or a child its spawn call waits on). Sessions never leased and runs never marked (written before durability existed) are never listed: they are healed. A child run resumes with its parent's spawn call, so it is not listed on its own. sessionId: that session's run only.

src/durable/types.ts:360

DurableOptionsInterface#

AgentOptions.durable in full: the runtime, and what run() does with a run a process death left unfinished in the session.

TypeScript
interface DurableOptions
DurableOptions properties
NameTypeDescription
onInterrupted?'resume' | 'heal'

'heal' (default): run() reports the interrupted run's open tool calls as interrupted and starts the new run; resume() still continues the interrupted run when called first. 'resume': run() first continues it (Agent.resume) when the lease lists it (DurableLease.resumable: its process is gone and it waits on no unanswered awakeable), then runs the prompt, unless the resumed run was aborted or suspended. A run the lease does not list is healed as with 'heal'. A host that asks the user first keeps 'heal' and calls resume() on a yes.

runtimeDurableRuntime

The runtime every run of the agent goes through.

src/durable/types.ts:396

DurableQueueEntryInterface#

Minimum shape of a queued prompt; the chat host's QueuedEntry fits it.

TypeScript
interface DurableQueueEntry
DurableQueueEntry properties
NameTypeDescription
idstring

The entry's id.

textstring

The prompt text.

src/durable/types.ts:294

DurableQueueStoreInterface#

The type-ahead queue of a session, kept across a crash. Wraps the session-metadata copy the chat host already keeps (zidane.queue).

TypeScript
interface DurableQueueStore<E extends DurableQueueEntry = DurableQueueEntry>
DurableQueueStore type parameters
NameTypeDefaultDescription
Eextends DurableQueueEntryDurableQueueEntry
DurableQueueStore properties
NameTypeDescription
read(sessionId: string) => Promise<E[]>

The stored queue, oldest first; empty when none.

write(sessionId: string, entries: readonly E[]) => Promise<void>

Replace the stored queue. An empty list clears it.

src/durable/types.ts:305

DurableResumeOptionsInterface#

Options of Agent.resume.

TypeScript
interface DurableResumeOptions
DurableResumeOptions properties
NameTypeDescription
run?Omit<AgentRunOptions, 'prompt' | 'signal' | 'resumeRunId'>

Per-run options of the resumed run, as its run() had them (a spawned child's system prompt, depth and parent). They apply over the options the run's record kept (SessionRun.options); what neither sets is the agent's own.

runId?string

Run to resume. Default: the session's last run that did not finish.

signal?AbortSignal

Aborts the resumed run, as AgentRunOptions.signal does.

src/durable/types.ts:414

DurableRuntimeInterface#

What the agent loop needs from a durable runtime. See the module docs.

TypeScript
interface DurableRuntime
DurableRuntime properties
NameTypeDescription
findAwakeable?(sessionId: string, key: `${string}:${number}:${string}:${number}`) => Promise<AwakeableRecord | undefined>

The stored awakeable of (sessionId, key), for a resumer that knows what a run waits on but not the id (a prompt rehydrated from the session's turns). undefined: none. Absent on runtimes without an awakeable table.

isControlError(error: unknown) => boolean

Errors the runtime uses to stop or suspend a run: the loop rethrows them untouched instead of reporting a failed call.

lease?readonlyDurableLease

Who runs each session's run. Absent where the platform guarantees one writer.

modereadonlyDurableMode

How the runtime recovers a run, see DurableMode.

openRun(options: OpenRunOptions) => Promise<RunScope>

Open a run's scope. Handlers are per scope, never shared with another run.

resolveAwakeable(id: string, value: JsonValue) => Promise<boolean>

Resolve an awakeable, also while no process runs its run (the run gets the value when it resumes). Call it from the resumer's side: another process or an ingress client, never the run that waits. In replay mode, resolving from the waiter's own journal shifts every later entry.

false: no awakeable has that id, e.g. a prompt left open by a build without awakeables, and the caller falls back to its own handling. Only runtimes that keep an awakeable table can tell; the others answer true.

storesreadonlyDurableStores

Where a run persists its session, tool state, queue and submissions.

src/durable/types.ts:529

DurableStoresInterface#

Everything a run persists, behind one runtime so it commits consistently.

TypeScript
interface DurableStores
DurableStores properties
NameTypeDescription
queueDurableQueueStore

The session's type-ahead queue.

sessionSessionStore

The session store the runtime commits turns to.

submissions?DurableSubmissionStore

Absent where the platform dedupes requests itself (an ingress idempotency key).

toolState(sessionId: string) => ToolStateStore

Tool state of one session.

src/durable/types.ts:325

DurableSubmissionStoreInterface#

Client request ids of sends (requestId), so a retried send gets the first one's outcome. Wraps the session store's send-request book (claimSendRequest / settleSendRequest).

TypeScript
interface DurableSubmissionStore
DurableSubmissionStore properties
NameTypeDescription
claim(sessionId: string, requestId: string, fingerprint: string) => Promise<SendRequestClaim>

Claim requestId for a send with this input fingerprint. claimed: false returns the record of the earlier send with that id.

settle(sessionId: string, requestId: string, result: JsonValue) => Promise<void>

Store the send's result; null drops the claim so a retry runs again.

src/durable/types.ts:317

MemoryDurableStateInterface#

What the memory runtime stores: sessions, steps, awakeables, partials, queue, submissions and tool state.

TypeScript
interface MemoryDurableState
MemoryDurableState properties
NameTypeDescription
clone() => MemoryDurableState

A copy of the state as it is now. Later writes to either copy never reach the other.

inspectreadonlyDurableInspector

Read access to the stored steps, partials and awakeables.

src/durable/memory.ts:89

OpenRunOptionsInterface#

Options of DurableRuntime.openRun.

TypeScript
interface OpenRunOptions
OpenRunOptions properties
NameTypeDescription
epoch?number

Lease epoch every write of the scope is guarded by. Default: the epoch this runtime's lease claimed for the session (a spawned child runs under its parent's claim), or none when the session is not claimed here.

handlersStepHandlers

The run's handlers. They close over its options (model, tools), so they live and die with the scope.

runIdstring

The run's id, unique within its session.

sessionIdstring

Session of the run.

src/durable/types.ts:429

ResumableRunInterface#

A top-level run another process held and stopped renewing, still marked resumable.

TypeScript
interface ResumableRun
ResumableRun properties
NameTypeDescription
epochnumber

The session's lease epoch when the run was listed.

runIdstring

The run to resume.

sessionIdstring

The run's session.

src/durable/types.ts:342

RunScopeInterface#

One run's view of the runtime: its steps, clock and awakeables. Opened by the agent when a run starts or resumes, closed when it ends.

TypeScript
interface RunScope
RunScope properties
NameTypeDescription
all<T extends readonly unknown[]>(values: T) => Promise<{ -readonly [K in string | number | symbol]: Awaited<T[K]> }>

Promise.all over the scope's own promises (durable combinator in replay mode).

allSettled<T>(values: readonly Promise<T>[]) => Promise<PromiseSettledResult<T>[]>

Promise.allSettled over the scope's own promises: how the loop joins a batch of concurrent steps, each settling on its own.

awakeable<T = JsonValue>(options: AwakeableOptions) => Promise<DurableAwakeable<T>>

Park until a resumer resolves the awakeable or its deadline passes. Resolves once the awakeable is stored.

close() => Promise<void>

End the scope: its handlers are dropped, later step() calls reject, and its awakeable waits stop (SQLite). Other scopes are untouched. Idempotent.

now() => number | Promise<number>

Wall-clock ms. Journaled in replay mode.

race<T>(values: readonly Promise<T>[]) => Promise<T>

Promise.race over the scope's own promises.

runIdreadonlystring

The run's id.

sessionIdreadonlystring

Session of the run.

sleep(ms: number, signal?: AbortSignal) => Promise<void>

Wait ms; a durable timer where the runtime has one. signal ends a plain timer early (the promise resolves); a durable timer is left to the runtime.

step<T = JsonValue>(req: StepRequest, live?: StepLive<unknown>) => Promise<StepOutcome<T>>

Run req through handlers[req.kind] once, or answer from its record.

Timing (the crash cases depend on it):

  • Before the handler of an unsafe step starts, its pending record is durable. A safe step writes none (it runs again either way, so a missing record answers the same), unless live.markStarted asks for it. In replay mode an unsafe step journals an intent entry and waits for it to be acknowledged; a safe step needs none.
  • step() settles only once the done or failed record is durable, with the tool state the handler staged.
  • A handler error for which DurableRuntime.isControlError holds is not recorded: the step stays pending (a suspension or a process death, not a failure), and the error propagates untouched.

In checkpoint mode a live step (replayed: false) resolves with the handler's own value and rejects with its own error; only a replayed step gets the forms rebuilt from the record. The runtime logs a result whose JSON form loses something (a class instance, a Date) and stores that form. In replay mode a live step gets the recorded form too, so its replay takes the same branches.

What a record found after a restart answers:

  • done: completed, replayed: true, the handler does not run.
  • failed: rejects with the error rebuilt from the record.
  • pending, safe: the handler runs again, under the same key.
  • pending, unsafe: interrupted, the handler does not run. In replay mode that answer is journaled as the step's value.
  • Another fingerprint than the request's: interrupted.
  • No record (the step never started, or a safe step never finished): runs as a new step, even unsafe.
storedPartials?() => Promise<StreamPartialRecord[]>

Checkpoint runtimes that keep stream partials: this run's partials, in write order. Agent.resume joins them into an aborted assistant turn.

storedSteps?() => Promise<StepRecord[]>

Checkpoint runtimes: this run's stored step records, in write order. A resumed run reads them to tell the calls of a batch already done (tool-batch:resumed) from those still to settle. Absent in replay mode.

storedTurns?() => Promise<number[]>

Checkpoint runtimes: the loop turns this run's stored step records cover, ascending (the turn of their keys). Only the unfinished turn has records, so Agent.resume checks it against the turn it resumes at before asking for any key. Absent in replay mode.

uuid() => string

RFC-4122 v4 UUID. Journaled in replay mode.

src/durable/types.ts:448

StepCompletedInterface#

A step that has a value: it ran now, or its done record answered.

TypeScript
interface StepCompleted<T>
StepCompleted type parameters
NameDescription
T
StepCompleted properties
NameTypeDescription
replayedboolean

Answered from a record, the handler did not run.

status'completed'

Discriminant of StepOutcome.

toolState?readonly ToolStateOp[]

Tool-state ops the step staged, live or from its record. The runtime already committed them with the record; the loop applies them to its hydrated view and never commits them again.

valueT

The handler's result, or the form rebuilt from the record when replayed.

src/durable/types.ts:136

StepErrorRecordInterface#

A step's error as stored. A replayed failure rejects with an Error rebuilt from it: name, message, and the other fields as own properties, so the loop classifies it (retryable, context exceeded, retry-after) the way it classified the live error.

TypeScript
interface StepErrorRecord
StepErrorRecord properties
NameTypeDescription
code?string

Provider or system code (context_length_exceeded, ENOENT).

data?JsonValue

Anything else the loop classifies on (a retry-after, a limit), as JSON.

decision?JsonValue

The loop's verdict on this failure (retry, fall back, give up), stored with it in checkpoint mode: the rebuilt error has neither the provider's error class nor the stream's progress, so a resumed run takes this verdict instead of judging the rebuilt error again.

messagestring

The error's message.

namestring

The error's name.

retryable?boolean

The error's own retry verdict.

status?number

HTTP status of the response that failed.

src/durable/types.ts:166

StepHandlerContextInterface#

What the runtime hands a running handler besides the caller's StepLive.

TypeScript
interface StepHandlerContext extends StepLive
StepHandlerContext properties
NameTypeDescription
callbacks?from StepLiveunknown

Callbacks the handler drives (a model step's stream callbacks).

markStarted?from StepLiveboolean

Write the pending record of a safe step too, so a resumed run sees that the step started: its call passed an approval that must not be asked again. An unsafe step always writes it.

onProgress?from StepLive(progress: StepProgress) => void

Receives the output the handler streams. The runtime may keep it as stream partials.

signal?from StepLiveAbortSignal

Aborts the handler's work (the run's abort, a cancelled call).

stageToolState(ops: readonly ToolStateOp[]) => void

Stage tool-state ops to commit with this step's done record, in call order. A failed step commits none of them. A step answered from its record never runs its handler, so this is how its tool state survives: the ops come back in StepOutcome.

src/durable/types.ts:108

StepInterruptedInterface#

An unsafe step that started before a restart and never finished, or a step whose record has another fingerprint.

TypeScript
interface StepInterrupted
StepInterrupted properties
NameTypeDescription
status'interrupted'

Discriminant of StepOutcome.

src/durable/types.ts:152

StepKeyPartsInterface#

The four parts of a StepKey, unescaped.

TypeScript
interface StepKeyParts
StepKeyParts properties
NameTypeDescription
attemptnumber

The loop's own retry index for the step.

callstring

What the step is within the turn: MODEL_CALL, a tool call id, a nested call or a decision name.

runstring

The run id, unique within its session.

turnnumber

The loop's turn index within the run.

src/durable/keys.ts:21

StepLiveInterface#

The live half of a step. The object itself is never stored or replayed; a replayed step gets a fresh one from the resumed loop. What a handler reports through onProgress may be kept by the runtime as stream partials (see StreamPartialRecord).

TypeScript
interface StepLive<C = unknown>
StepLive type parameters
NameDefaultDescription
Cunknown
StepLive properties
NameTypeDescription
callbacks?C

Callbacks the handler drives (a model step's stream callbacks).

markStarted?boolean

Write the pending record of a safe step too, so a resumed run sees that the step started: its call passed an approval that must not be asked again. An unsafe step always writes it.

onProgress?(progress: StepProgress) => void

Receives the output the handler streams. The runtime may keep it as stream partials.

signal?AbortSignal

Aborts the handler's work (the run's abort, a cancelled call).

src/durable/types.ts:92

StepRecordInterface#

One stored step (the steps table of the SQLite adapter). Keyed by (sessionId, key): run ids are only unique within their session.

TypeScript
interface StepRecord
StepRecord properties
NameTypeDescription
error?StepErrorRecord

What the handler threw, once failed.

fingerprint?string

See StepRequest.fingerprint.

key`${string}:${number}:${string}:${number}`

See StepRequest.key.

kindStepKind

See StepRequest.kind.

replayStepReplayPolicy

See StepRequest.replay.

result?JsonValue

The handler's result in its JSON form, once done.

runIdstring

Run the step belongs to.

sessionIdstring

Session the step belongs to.

statusStepStatus

Where the step is in its lifecycle.

toolState?ToolStateOp[]

Tool-state ops committed with the done record.

src/durable/types.ts:192

StepRequestInterface#

What a runtime keeps of a step besides its outcome: its key, policy and a description. Not enough to run it again.

TypeScript
interface StepRequest<P extends JsonValue = JsonValue>
StepRequest type parameters
NameTypeDefaultDescription
Pextends JsonValueJsonValue
StepRequest properties
NameTypeDescription
fingerprint?string

What the step does beyond its key: a codemode inner call's tool name and input hash, since those calls are keyed by their order in the script. A record whose fingerprint differs means the code took another path since the record was written: the step answers interrupted and the handler does not run. Unset: not checked.

key`${string}:${number}:${string}:${number}`

run:turn:call:attempt, see StepKey. Stable across a restart.

kindStepKind

Which of the run's handlers runs it.

payloadP

A description of the step (a model name, a tool name and call id), stored with it. The work itself is the live closure in StepLive.

replayStepReplayPolicy

What a restart does with the step when it started and never finished.

src/durable/types.ts:62

StreamPartialRecordInterface#

One stored slice of model output streamed by a step that has not finished (stream_partials), keyed by (sessionId, stepKey, seq).

TypeScript
interface StreamPartialRecord
StreamPartialRecord properties
NameTypeDescription
runIdstring

Run of the step.

seqnumber

Write order within the step, from 0.

sessionIdstring

Session of the step.

stepKey`${string}:${number}:${string}:${number}`

Key of the model step that streamed it.

textstring

Text streamed since the previous slice, never the whole answer so far.

thinking?string

Thinking streamed since the previous slice.

src/durable/types.ts:216

Types#

AwakeableOutcomeType#

Settlement of an awakeable: the deadline passed, or a resumer resolved it with value (which may be null).

TypeScript
type AwakeableOutcome<T> = { timedOut: true } | { timedOut: false; value: T }
AwakeableOutcome type parameters
NameDescription
T

src/durable/types.ts:235

DurableBodyType#

See DurableToolDef.durableBody.

TypeScript
type DurableBody = 'composite' | 'promise'

src/tools/types.ts:418

DurableModeType#

How a runtime survives a restart. See the module docs.

TypeScript
type DurableMode = 'checkpoint' | 'replay'

src/durable/types.ts:42

LeaseClaimType#

Answer of DurableLease.claim: the new epoch, or who still holds the lease. previous: the session's status as the claim found it.

TypeScript
type LeaseClaim =
  | { claimed: true; epoch: number; previous?: SessionData['status'] }
  | { claimed: false; owner?: RunOwner; previous?: SessionData['status'] }

src/durable/types.ts:337

MemoryDurableInspectorType#

Read access to the stored state, for tests and the conformance suite.

TypeScript
type MemoryDurableInspector = DurableInspector

src/durable/memory.ts:86

StepHandlerType#

Runs one step of a kind: the loop's handlers run the closure handed in StepLive.callbacks. A replay gets the result's JSON form (it is stored or journaled as JSON); in checkpoint mode a live call gets the value itself, and a value the JSON form loses is logged.

TypeScript
type StepHandler<P extends JsonValue = JsonValue, R = JsonValue> = (payload: P, context: StepHandlerContext) => Promise<R>
StepHandler type parameters
NameTypeDefaultDescription
Pextends JsonValueJsonValue
RJsonValue

src/durable/types.ts:124

StepHandlersType#

A run's handlers by kind.

TypeScript
type StepHandlers = Readonly<Partial<Record<StepKind, StepHandler<any, unknown>>>>

src/durable/types.ts:127

StepKeyType#

A step key as built by stepKey.

TypeScript
type StepKey = `${string}:${number}:${string}:${number}`

src/durable/keys.ts:18

StepKindType#

Handler family of a step (the loop's are LOOP_STEP_KINDS). A run passes one handler per kind to DurableRuntime.openRun. The open string lets an adapter add its own.

TypeScript
type StepKind =
  | 'model'
  | 'tool'
  | 'gate'
  | 'decision'
  | 'compact'
  | 'reconcile'
  | (string & {})

src/durable/types.ts:59

StepOutcomeType#

Result of RunScope.step. A step whose handler failed rejects with that error instead (rebuilt from its record when replayed).

TypeScript
type StepOutcome<T> = StepCompleted<T> | StepInterrupted
StepOutcome type parameters
NameDescription
T

src/durable/types.ts:133

StepProgressType#

Incremental output a handler reports while it runs. Streamed model text is what an adapter keeps as a partial.

TypeScript
type StepProgress =
  | { delta: string; type: 'text' }
  | { delta: string; type: 'thinking' }

src/durable/types.ts:82

StepReplayPolicyType#

What a resumed run does with a step that started but never finished.

  • safe: run it again (reads, pure computations, model calls).
  • unsafe: never run it again; the loop reports it as interrupted (TOOL_USE_INTERRUPTED_MARKER), saying the effect may or may not have happened.
TypeScript
type StepReplayPolicy = 'safe' | 'unsafe'

src/durable/types.ts:52

StepStatusType#

Lifecycle of a step record: written pending before the handler runs (an unsafe step, or one marked started), then done or failed.

TypeScript
type StepStatus = 'pending' | 'done' | 'failed'

src/durable/types.ts:158

ToolPreflightType#

What a DurableToolDef.preflight decided: run the body with input, or answer the call with output.

TypeScript
type ToolPreflight =
  | { input: Record<string, unknown> }
  | { output: string | ToolResultContent[] }

src/tools/types.ts:415