// Core types for PlayContext. import type { PlayCellReadRef, PlayCellDecision, PlayDatasetBornFrom, PlayRowMeta, } from './cell-provenance'; import type { PlayBundleArtifact } from '../plays/artifact-types'; import type { PlayRunContractSnapshot } from '../plays/contracts'; import type { PlayStructuredDefinition } from '../plays/definition'; import type { PlayStaticPipeline } from '../plays/static-pipeline'; import type { DurableCallStaleAfterSeconds, PlayAuthoringCallOptions, PlayAuthoringCsvOptions, PlayAuthoringFetchOptions, PlayAuthoringRuntimeStepOptions, PlayAuthoringContractEdition, PlayToolCallOptions, PlayToolExecutionRequest, PlayReceiptWaitMs, PlayRuntimeTimeoutMs, } from '../plays/authoring-contract'; import type { PlayDataset, PlayDatasetInput, PlayDatasetRow, } from '../plays/dataset'; import type { PlayQueueHint, RateStateBackend, } from './governor/rate-state-backend'; import type { GovernanceSnapshot, PlayExecutionGovernor, } from './governor/governor'; import type { BudgetStateBackend } from './governor/budget-state-backend'; import type { DocflowObservationUpsert } from './docflow-observation'; import type { RuntimeMapMemoryLimits } from './map-memory-limits'; import type { AnyBatchOperationStrategy } from './batching-types'; import type { ToolResultMetadataInput } from './tool-result'; import type { PreviousCell } from './cell-staleness'; import type { MapRowOutcome } from './durability-store'; import type { WorkReceiptFailureKind } from './work-receipts'; import type { RunExecutionScope } from './run-execution-scope'; import type { PlayCallExecution } from './play-call-execution'; import type { PlayDocflowNodeIoPreviewMap } from './docflow-node-io'; import type { PlayActivityEvent } from './activity-observation'; import type { ToolExecutionErrorSchemaVersion, ToolExecutionFailureV1, } from '../tool-execution-error'; import type { FixtureBehavior } from './fixture-behavior'; import type { ToolResponseContract } from './tool-response-contract'; export interface RowState { results: Map; } export interface ToolCallRequest { callId: string; cacheKey: string; /** Stable external-operation identity, independent of receipt serialization. */ providerIdempotencyKeyBase?: string | null; cacheable?: boolean; receiptKey?: string | null; executionAuthScopeDigest?: string | null; receiptLeaseId?: string | null; receiptLeaseExpiresAt?: string | null; force?: boolean; forceFailedRefresh?: boolean; requiresExecutionFence?: boolean; rowId: number; fieldName?: string; /** The author-supplied `ctx.tools.execute(, ...)` key (ADR 0018). */ contextKey?: string; toolId: string; input: Record; timeoutMs?: number; receiptWaitMs?: number; tableNamespace?: string; rowKey?: string | null; description?: string; } export interface ToolBatchResult { done: true; result: unknown | null; } export interface RuntimeStepReceipt { key: string; status: 'queued' | 'pending' | 'running' | 'completed' | 'failed' | 'skipped'; output?: unknown; error?: string; errorPayload?: ToolExecutionFailureV1 | null; failureKind?: WorkReceiptFailureKind | null; runId?: string | null; leaseId?: string | null; leaseOwnerRunId?: string | null; leaseOwnerAttempt?: number | null; leaseExpiresAt?: string | null; claimState?: 'claimed' | 'existing'; } export type AcquireRuntimeReceiptExecutionLockInput = { key: string; runId: string; ownerExecutionId: string; ttlMs: number; }; export type ReleaseRuntimeReceiptExecutionLockInput = { key: string; runId: string; ownerExecutionId: string; }; export interface GetRuntimeStepReceiptInput { key: string; } export interface ClaimRuntimeStepReceiptInput { key: string; leaseId?: string; runId: string; runAttempt?: number | null; leaseAware?: boolean; reclaimRunning?: boolean; forceRefresh?: boolean; forceFailedRefresh?: boolean; } export interface MarkRuntimeStepReceiptRunningInput { key: string; runId: string; runAttempt?: number | null; leaseId?: string | null; } export interface CompleteRuntimeStepReceiptInput { key: string; runId: string; runAttempt?: number | null; leaseId?: string | null; output: unknown | null; } export interface ReleaseRuntimeStepReceiptInput { key: string; runId: string; runAttempt?: number | null; leaseId?: string | null; } export interface FailRuntimeStepReceiptInput { key: string; runId: string; runAttempt?: number | null; leaseId?: string | null; error: string; errorPayload?: ToolExecutionFailureV1 | null; failureKind?: WorkReceiptFailureKind | null; } export interface SkipRuntimeStepReceiptInput { key: string; runId: string; runAttempt?: number | null; leaseId?: string | null; output?: unknown | null; } export interface GetRuntimeStepReceiptsInput { keys: string[]; } export interface ClaimRuntimeStepReceiptsInput { keys: string[]; leaseIds?: string[]; runId: string; runAttempt?: number | null; leaseAware?: boolean; reclaimRunning?: boolean; forceRefresh?: boolean; forceFailedRefresh?: boolean; } export interface MarkRuntimeStepReceiptsRunningInput { receipts: Array<{ key: string; runId: string; runAttempt?: number | null; leaseId?: string | null; }>; } export interface MarkRuntimeStepReceiptsQueuedInput { receipts: Array<{ key: string; runId: string; runAttempt?: number | null; leaseId?: string | null; }>; } export interface CompleteRuntimeStepReceiptsInput { receipts: Array<{ key: string; runId: string; runAttempt?: number | null; leaseId?: string | null; output: unknown | null; }>; } export interface FailRuntimeStepReceiptsInput { receipts: Array<{ key: string; runId: string; runAttempt?: number | null; leaseId?: string | null; error: string; errorPayload?: ToolExecutionFailureV1 | null; failureKind?: WorkReceiptFailureKind | null; }>; } export interface HeartbeatRuntimeStepReceiptsInput { keys: string[]; runId: string; runAttempt?: number | null; leaseId?: string; leaseIds?: string[]; } export type CsvOptions = PlayAuthoringCsvOptions; export interface RuntimeDatasetOptions> { description?: string; /** * Optional relative cache window for intentional reruns. * * By default, ctx.dataset is durable by play + dataset key + row identity forever. * Set staleAfterSeconds to rerun after that many seconds while retries/replays * inside the same window still hit the cache. Daily refreshes use 86400. */ staleAfterSeconds?: number; /** * Optional stable key per row. When provided, row identity is derived from * the selected input field(s) or returned value instead of hashing the full * row. Use this to pin identity to primary columns (e.g. `{ key: "email" }` * or `{ key: ["first_name", "last_name", "domain"] }`) so harmless * mutations to other columns don't invalidate the cache. * * Must return a non-empty string (numbers are coerced). Empty keys throw * loudly before any provider work runs. Rows whose keys duplicate an earlier * row are silently deduped (first occurrence wins) and logged, never failing * the run. The key function should reference *input* * columns only — values produced by this dataset's field resolvers are stripped * before identity is computed. */ key?: | (keyof TItem & string) | readonly (keyof TItem & string)[] | ((row: TItem, index: number) => string | number | readonly unknown[]); /** * Row failure policy for this dataset run. * * Default 'isolate': a row whose column resolver or tool call throws is * recorded as a failed row (its error is persisted on the row and the * failing cell), sibling rows continue, and the run completes with a * partial-failure summary (N succeeded / M failed). Failed rows re-execute * on the next run; succeeded rows replay free from receipts. If every * executed row fails, the run still fails loudly. * * 'fail' opts into fail-fast: the first row error aborts the dataset run * and fails the play run. Rows persisted before the error stay recoverable * and are reused on re-run. */ onRowError?: 'isolate' | 'fail'; /** * Controls how a persisted dataset admits rows whose key already exists. * * `upsert` (the default) preserves the row-preserving enrichment contract: * existing rows are reused and returned with the current input. `net_new` * atomically inserts only previously unseen keys and returns/processes only * those inserted rows. Use `net_new` for a durable sourcing table, not for * ordinary CSV enrichment reruns. */ mode?: 'upsert' | 'net_new'; /** * Columns this dataset computes that the authored `@mermaid` diagram * deliberately does not draw. * * A Play that authors a diagram must account for every column it computes: * draw the column inside the dataset's `subgraph` loop region, or name it * here. `plays check` fails otherwise, and it echoes these names back so an * opt-out is always visible. Purely a documentation contract — it changes no * execution behavior. */ undrawnColumns?: readonly string[]; } export type RuntimeDatasetDefinitionOptions> = Omit, 'description'>; export type RuntimeDatasetRunOptions> = Pick< RuntimeDatasetOptions, 'description' | 'key' | 'onRowError' | 'mode' | 'undrawnColumns' >; export type ToolCallOptions = PlayToolCallOptions; export type ToolExecutionRequest = PlayToolExecutionRequest; export type PlayCallOptions = Omit< PlayAuthoringCallOptions, 'execution' | 'timeoutMs' > & { /** Legacy invalid spelling retained only for the stable migration error. */ execution?: PlayCallExecution | 'child-workflow'; /** Legacy invalid option retained only for the stable migration error. */ timeoutMs?: number; }; export type RuntimeStepOptions = PlayAuthoringRuntimeStepOptions; export type FetchOptions = PlayAuthoringFetchOptions; export interface ResolvedPlayExecution { playId: string; code?: string | null; sourceCode?: string | null; codeFormat?: 'function' | 'cjs_module' | 'esm_module'; artifact?: PlayBundleArtifact | null; compressedArtifact?: string | null; definition?: PlayStructuredDefinition | null; staticPipeline?: PlayStaticPipeline | null; contractSnapshot?: PlayRunContractSnapshot | null; } export interface BatchRequest { provider: string; toolName: string; inputs: Record[]; rowIds: number[]; } export interface MapStartResult { /** Rows that need processing for this run. Previous values may be included for context. */ pendingRows: Record[]; /** Rows already terminal for this run and safe to count as completed. */ completedRows?: Record[]; /** Rows leased by another active attempt and not executable by this attempt. */ blockedRows?: Record[]; /** Resolved table namespace. */ tableNamespace: string; } export interface MapExecutionFrame { mapInvocationId: string; mapNodeId?: string | null; logicalNamespace: string; artifactTableNamespace: string; status: 'running' | 'suspended' | 'completed' | 'failed'; totalRows: number; completedRowKeys: string[]; pendingRowKeys: string[]; completedRowsCount?: number; pendingRowsCount?: number; failedRowsCount?: number; activeBoundaryId?: string | null; startedAt: number; updatedAt: number; } export interface MapExecutionScope { mapInvocationId: string; mapNodeId?: string | null; logicalNamespace: string; artifactTableNamespace: string; rowIdentity: (row: Record, index?: number) => string; } export type PlayExecutionEvent = | PlayActivityEvent | { type: 'docflow.node.hit'; nodeId: string; at: number; } | { type: 'docflow.node.started'; nodeId: string; attempt: number; invocationId: string; inputs: PlayDocflowNodeIoPreviewMap; inputsTruncated?: boolean; at: number; } | { type: 'docflow.node.completed'; nodeId: string; attempt: number; invocationId: string; inputs: PlayDocflowNodeIoPreviewMap; inputsTruncated?: boolean; outputs: PlayDocflowNodeIoPreviewMap; outputsTruncated?: boolean; at: number; } | { type: 'docflow.node.failed'; nodeId: string; attempt: number; invocationId: string; inputs: PlayDocflowNodeIoPreviewMap; inputsTruncated?: boolean; error: string; at: number; } /** * Explicit tool-node lifecycle (ADR 0018). Emitted only for tool calls that * are NOT row-scoped, i.e. the same call sites that used to be inferred by * matching `Calling tool: ` against runner stdout. Row-scoped calls stay * out of the ledger on purpose (ADR 0001 forbids row-heavy Run Events); their * attribution is the Runtime Sheet `_cell_meta.producers` trace plus the * node-scoped usage events. */ | { type: 'tool.call.started'; toolId: string; callKey?: string | null; at: number; } | { type: 'tool.call.settled'; toolId: string; callKey?: string | null; outcome: 'completed' | 'no_result' | 'failed' | 'cached'; durationMs?: number | null; error?: string | null; at: number; } | { type: 'dataset.lifecycle'; datasetId: string; path: string; tableNamespace: string; phase: 'registered' | 'available' | 'failed'; persistedRows?: number; succeededRows?: number; failedRows?: number; complete?: boolean; /** * Dataset-grain row birth (ADR 0019). Rows entered this dataset from * play-body code, so the runtime witnessed how many rows arrived at which * step but no per-row source mapping. Stated once per dataset here rather * than repeated — or invented — per row. */ bornFrom?: PlayDatasetBornFrom; at: number; } | { type: 'map.preparing'; mapInvocationId: string; mapNodeId?: string | null; logicalNamespace: string; artifactTableNamespace: string; totalRows: number; completedRows: number; pendingRows: number; at: number; } | { type: 'map.started'; mapInvocationId: string; mapNodeId?: string | null; logicalNamespace: string; artifactTableNamespace: string; totalRows: number; completedRows: number; pendingRows: number; at: number; } | { type: 'map.progress'; mapInvocationId: string; mapNodeId?: string | null; logicalNamespace: string; artifactTableNamespace: string; completedRows: number; failedRows: number; totalRows?: number; /** * Inline child-play composition aggregates for this run. Maintained by the * single-writer progress path (never per child), so fan-out cannot contend. * See ADR 0013. */ childrenTotal?: number; childrenOk?: number; childrenFailed?: number; at: number; } | { type: 'map.row.updated'; mapInvocationId: string; mapNodeId?: string | null; logicalNamespace: string; artifactTableNamespace: string; rowKey: string; rowStatus?: PlayRowUpdate['status']; fieldName?: string | null; stage?: string | null; provider?: string | null; at: number; } | { type: 'map.completed' | 'map.suspended' | 'map.resumed' | 'map.failed'; mapInvocationId: string; mapNodeId?: string | null; logicalNamespace: string; artifactTableNamespace: string; completedRows: number; failedRows: number; totalRows?: number; /** * Inline child-play composition aggregates for this run. Maintained by the * single-writer progress path (never per child). See ADR 0013. */ childrenTotal?: number; childrenOk?: number; childrenFailed?: number; at: number; }; export type IntegrationEventWaitRuntimeContext = { playId?: string; runId?: string; workflowId?: string; orgId?: string; executorToken?: string; }; export type IntegrationEventWaitBoundary = { boundaryId: string; eventKey: string; timeoutMs: number; provider: string; toolId: string; messageRef?: { channel: string; ts: string; }; }; export type IntegrationEventWaitHandler = { provider: string; toolId: string; prepare: (input: { payload: Record; context: IntegrationEventWaitRuntimeContext; }) => IntegrationEventWaitBoundary | Promise; arm: (input: { payload: Record; context: IntegrationEventWaitRuntimeContext; boundary: IntegrationEventWaitBoundary; }) => Promise; }; export interface ContextOptions { /** Immutable logical and physical execution identity for this context. */ executionScope?: RunExecutionScope; /** Authoring semantics pinned by the immutable artifact. */ authoringContractEdition?: PlayAuthoringContractEdition; /** Error shape pinned by the immutable play artifact; missing preserves legacy schema 0. */ toolErrorSchemaVersion?: ToolExecutionErrorSchemaVersion; /** Execute-result contract pinned by the immutable Play artifact. */ toolResponseContract?: ToolResponseContract; /** Explicit response-transform revision used for durable receipt identity. */ toolResponseReceiptRevision?: string; /** Short-lived HMAC-signed internal token for tool callbacks. Required for cloud execution. */ executorToken?: string; baseUrl?: string; /** * Optional long-lived integration transport. Runtime control, receipts, and * runner terminals continue to use baseUrl; only provider execute requests * use this origin. This lets production rotate the receipt gateway without * terminating an in-flight provider request. */ executionGatewayBaseUrl?: string | null; /** * The integration base URL persists each keyed execute response before * exposing it. Only runtime adapters that route through that gateway may * enable ambiguous transport replay. */ durableInvocationFence?: boolean; requestDurableInvocationFence?: boolean; verifyDurableInvocationFence?: (signal?: AbortSignal) => Promise; runtimeTestFaultHeader?: string | null; /** * Runtime-sheet transport selected by the runner. Daytona sandboxes use the * execution gateway and must never fall back to minting direct DB sessions. */ dbSessionStrategy?: 'preloaded' | 'gateway_only' | 'trusted_dynamic'; vercelProtectionBypassToken?: string | null; /** Optional per-run integration execution mode for provider calls. */ integrationMode?: 'live' | 'eval_stub' | 'fixture'; /** * Docflow rollout answer for this run, decided at admission (see * `RuntimeAuthorityDescriptor.docflowEnabled`). Absent means OFF, so a run * whose launch predates the field captures exactly what it captured before. */ docflowEnabled?: boolean; /** Internal fixture-only simulation of provider response residence. */ fixtureBehavior?: FixtureBehavior | null; /** Preview/dev test seam that applies provider pacing to fixture responses. */ enforceFixtureProviderPacing?: boolean; /** * Server-validated per-run ceiling for concurrently resident provider-tool * executions and direct ctx.fetch calls. Omitted uses the platform default. */ maxConcurrentExternalCalls?: number | null; maxConcurrentRows?: number | null; orgId?: string; userEmail?: string; playName?: string; graphHash?: string | null; artifactHash?: string | null; convexUrl?: string; runtimeSchedulerSchema?: string | null; staticPipeline?: PlayStaticPipeline | null; workflowId?: string; sessionId?: string; verbose?: boolean; /** Checkpoint from a previous scheduler attempt. */ checkpoint?: PlayCheckpoint; /** Enables durable boundary replay such as ctx.sleep() resumptions. */ durableBoundaries?: boolean; /** * Run-level cache policy. * forceStepRefresh bypasses completed ctx.step receipts while preserving * completed provider-call receipts. * forceToolRefresh bypasses all ctx.tools.execute receipts. * forceFailedToolRefresh reclaims only failed receipts, preserving completed * provider-call idempotency while allowing forced repair runs to make progress. */ cachePolicy?: { forceStepRefresh?: boolean; forceToolRefresh?: boolean; forceFailedToolRefresh?: boolean; }; /** Called after each durable batch completes for scheduler checkpointing. */ onBatchComplete?: (checkpoint: PlayCheckpoint) => void; /** Called when the runtime emits a new execution log line. */ onLog?: (line: string) => void; /** * Runtime-provided HTTP transport for ctx.fetch. Node runtimes should provide * a transport that validates resolved IP addresses at connect time. */ fetchImpl?: (input: string | URL, init?: RequestInit) => Promise; /** * Internal runtime-policy override used by focused tests and controlled * harnesses. Play authors cannot set these values; ctx.fetch always has a * bounded platform deadline. */ ctxFetchTimeouts?: { headersMs?: number; bodyMs?: number; totalMs?: number; }; /** Internal low-cardinality map-stall diagnostic interval override. */ runtimeMapStallLogIntervalMs?: number; /** Called when a row gains new partial data or stage info. */ onRowUpdate?: (update: PlayRowUpdate) => void | Promise; /** Structured execution events emitted from explicit dataset scopes. */ onExecutionEvent?: (event: PlayExecutionEvent) => void | Promise; /** * Durable docflow observation sink (ADR 0016 rule 2). Present ONLY for * instrumented (diagrammed) plays: the compiler injects the observation * wrapper only when an `@mermaid` block exists, and the runtime wires this * sink to the receipt gateway's `observe` action. The wrapper posts to it * fire-and-forget alongside the live event emission — it must NEVER fail or * slow the play body. Absent means observations are not persisted (the live * `onExecutionEvent` stream is unchanged either way). */ onDocflowObservation?: ( observation: DocflowObservationUpsert, ) => void | Promise; /** * Called when ctx.dataset() starts — inserts items into the sheet and returns * the pending/completed split. If not provided, all items are processed. */ onMapStart?: ( items: Record[], tableNamespace: string, context: { playName?: string; playId?: string; runId?: string; executorToken?: string; staticPipeline?: PlayStaticPipeline | null; forceRefresh?: boolean; inputOffset?: number; mode?: RuntimeDatasetRunOptions['mode']; }, ) => Promise; /** * Called as ctx.dataset() rows complete — persists executed rows (data + * cell meta) into the tenant runtime sheet so the sheet, not an in-memory * preview, is the source of truth. Invoked in bounded chunks; rows carry * deterministic keys, so the write is idempotent across retries and runs. */ onMapRowsCompleted?: (input: { playName?: string; playId?: string; runId?: string; executorToken?: string; tableNamespace: string; rows: MapRowOutcome[]; outputFields: string[]; staticPipeline?: PlayStaticPipeline | null; }) => Promise; /** * Persists coalesced, non-terminal row patches before a map suspends. * Terminal rows use onMapRowsCompleted; this narrow seam only preserves * cells that completed before an integration-event boundary. */ onMapRowsCheckpoint?: (input: { playName?: string; playId?: string; runId: string; executorToken?: string; tableNamespace: string; updates: PlayRowUpdate[]; staticPipeline?: PlayStaticPipeline | null; }) => Promise; playId?: string; runId?: string; /** Physical executor run that owns leases for an inline child context. */ runtimeReceiptOwnerRunId?: string; /** Logical invocation scope for receipts created inside an inline child. */ runtimeReceiptScope?: string; runAttempt?: number | null; /** * Optional shared provider-rate state for fleet substrates. Local/test * contexts omit this and use the in-process backend. */ rateState?: RateStateBackend; /** Shared root-run budget reservations. Production schedulers must provide * the same durable backend to every child sandbox. */ budgetState?: BudgetStateBackend; /** * Loud guard for production Node substrates: when true, constructing a * context without a shared rate-state backend is a configuration error. */ requireSharedRateState?: boolean; /** * Node/Daytona map memory guard. Production adapters should normally omit * this and use the runtime constants; tests and explicit resource profiles may * pass a smaller/larger budget to make the OOM boundary deterministic. */ runtimeMapMemoryLimits?: Partial; /** * Return map PlayDataset handles backed by Runtime Sheet reads after a map * has persisted. Runtime adapters with real sheet APIs should enable this; * in-memory callback tests can omit it and keep local result resolvers. */ runtimeSheetBackedMapDatasets?: boolean; resolvePlay?: (playRef: string) => Promise; getToolQueueHints?: (toolId: string) => Promise; getToolProvider?: (toolId: string) => Promise; getToolOperation?: (toolId: string) => Promise; getToolRetryPolicy?: ( toolId: string, input: Record, ) => Promise<{ retrySafeTransientHttp?: boolean; requiresExecutionFence?: boolean; } | null>; getToolActionCacheVersion?: (toolId: string) => Promise | string; getToolAuthScopeDigest?: (toolId: string) => Promise | string; getToolRateScope?: ( toolId: string, provider: string, ) => | Promise<{ bucketId: string; token: string } | null> | { bucketId: string; token: string } | null; invalidateToolAuthScopeDigest?: (toolId: string) => void; getToolTargetGetters?: ( toolId: string, output: string, ) => Promise; resolveSecret?: (input: { name: string; playName?: string; orgId?: string; workflowId?: string; runId?: string; executorToken?: string; }) => Promise; getToolResultMetadata?: ( toolId: string, ) => Promise | ToolResultMetadataInput | null; getIntegrationEventWaitHandler?: ( toolId: string, ) => | IntegrationEventWaitHandler | null | Promise; getBatchOperationStrategy?: ( operation: string, ) => AnyBatchOperationStrategy | null; /** * Internal deterministic clock for fixed-window dispatcher tests. Runtime * adapters omit this and use the system clock. */ toolBatchDispatcherClock?: { nowMs: () => number; schedule: (delayMs: number, wake: () => void) => () => void; }; // How long provider-native batch calls wait for same-key row continuations // before dispatching, measured from the first queued item. toolBatchCoalesceWindowMs?: number; // Scalar calls remain separate physical requests, but wait in one scheduling // lane for this fixed window so pipelined replacement rows launch together. toolScalarCoalesceWindowMs?: number; /** Deterministic test override for the runner-local scheduling-group cap. */ toolDispatcherMaxInFlightGroups?: number; /** Deterministic test override for the active-group cap per scheduling lane. */ toolDispatcherMaxInFlightGroupsPerLane?: number; executeStructuredPlayDefinition?: (input: { definition: PlayStructuredDefinition; ctx: unknown; rows: Record[]; playInput: Record; }) => Promise; getRuntimeStepReceipt?: ( input: GetRuntimeStepReceiptInput, ) => Promise | RuntimeStepReceipt | null; acquireRuntimeReceiptExecutionLock?: ( input: AcquireRuntimeReceiptExecutionLockInput, ) => Promise<{ ownerExecutionId: string; expiresAt: string } | null>; releaseRuntimeReceiptExecutionLock?: ( input: ReleaseRuntimeReceiptExecutionLockInput, ) => Promise; getRuntimeStepReceipts?: ( input: GetRuntimeStepReceiptsInput, ) => | Promise> | Array; claimRuntimeStepReceipt?: ( input: ClaimRuntimeStepReceiptInput, ) => Promise | RuntimeStepReceipt | null; claimRuntimeStepReceipts?: ( input: ClaimRuntimeStepReceiptsInput, ) => | Promise> | Array; /** Internal backend capability: a claimed running receipt is the execution fence. */ runtimeReceiptClaimsEstablishExecutionFence?: boolean; markRuntimeStepReceiptRunning?: ( input: MarkRuntimeStepReceiptRunningInput, ) => Promise | RuntimeStepReceipt | null; markRuntimeStepReceiptsRunning?: ( input: MarkRuntimeStepReceiptsRunningInput, ) => | Promise> | Array; markRuntimeStepReceiptsQueued?: ( input: MarkRuntimeStepReceiptsQueuedInput, ) => | Promise> | Array; completeRuntimeStepReceipt?: ( input: CompleteRuntimeStepReceiptInput, ) => Promise | RuntimeStepReceipt | null; releaseRuntimeStepReceipt?: ( input: ReleaseRuntimeStepReceiptInput, ) => Promise | RuntimeStepReceipt | null; completeRuntimeStepReceipts?: ( input: CompleteRuntimeStepReceiptsInput, ) => | Promise> | Array; failRuntimeStepReceipt?: ( input: FailRuntimeStepReceiptInput, ) => Promise | RuntimeStepReceipt | null; failRuntimeStepReceipts?: ( input: FailRuntimeStepReceiptsInput, ) => | Promise> | Array; heartbeatRuntimeStepReceipts?: ( input: HeartbeatRuntimeStepReceiptsInput, ) => | Promise> | Array; skipRuntimeStepReceipt?: ( input: SkipRuntimeStepReceiptInput, ) => Promise | RuntimeStepReceipt | null; /** Inline composition scope used for recursion and shared-resource governance. */ governance?: GovernanceSnapshot; /** Internal in-process child view sharing the root run's resource governor. */ executionGovernor?: PlayExecutionGovernor; } export interface PlayCheckpoint { /** * Clock captured when this logical run first creates its context. All * staleAfterSeconds receipt buckets use this value across durable resumes. */ durableCallCacheEpochMs?: number; /** Waterfall batches that have completed: key = `${toolName}:${provider}`, value = results array. */ completedBatches: Record; /** Tool call batches that have completed: key = toolId, value = sparse row-cache-key -> result map. */ completedToolBatches: Record>; /** Row states resolved from completed batches. */ resolvedWaterfalls: Record>; /** Durable boundary completions keyed by boundary id. */ resolvedBoundaries?: Record< string, | { kind: 'sleep'; delayMs: number; completedAt?: number; scope?: { type: 'workflow' | 'map_row'; tableNamespace?: string; rowKey?: string; rowIndex?: number; fieldName?: string; }; } | { kind: 'integration_event'; eventKey: string; timeoutMs: number; provider?: string; toolId?: string; messageRef?: { channel: string; ts: string; }; output?: unknown; completedAt?: number; } | { kind: 'fetch'; url: string; method: string; output?: unknown; completedAt?: number; } | { kind: 'step'; stepId: string; output?: unknown; completedAt?: number; } >; /** Per-map execution frames keyed by invocation id. */ mapFrames?: Record; } export type PlayFetchResponse = { ok: boolean; status: number; statusText: string; url: string; headers: Record; bodyText: string; json: unknown | null; }; export interface BatchResult { rowId: number; rowKey?: string | null; result: unknown | null; } export interface ToolDefinition { toolId: string; provider: string; providers?: string[]; supportsBatch?: boolean; } type AwaitedMapValue = T extends Promise ? AwaitedMapValue : T; export type MapResolvedFields> = { [K in keyof TColumns]: AwaitedMapValue; }; export type MapAvailableFields< TItem, TColumns extends Record, > = TItem & Partial>>; export type MapFieldResolver< TItem, TFields = Record, TValue = unknown, > = | TValue | (( row: TItem, ctx: unknown, fields: TFields, index: number, previousCell?: PreviousCell, ) => TValue | Promise); export type MapFieldDefinition< TItem, TColumns extends Record = Record, > = { [K in keyof TColumns]: MapFieldResolver< TItem, MapAvailableFields, TColumns[K] >; }; export type RuntimeStepResolver< Row = Record, Value = unknown, > = ( row: Row, ctx: unknown, index: number, previousCell?: PreviousCell, ) => Value | Promise; export type RuntimeConditionalStepResolver< Row = Record, Value = unknown, > = { kind: 'conditional'; when: (row: Row, index: number) => boolean | Promise; run: RuntimeStepResolver; elseValue?: unknown; }; export type RuntimeStepProgramStep = { name: string; /** Copied from a `withColumns()` waterfall program for per-leg fallback. */ continueOnProviderUnavailable?: boolean; recompute?: boolean; recomputeOnError?: boolean; staleAfterSeconds?: number; resolver: | RuntimeStepResolver | RuntimeConditionalStepResolver | RuntimeStepProgram; }; export type RuntimeStepProgram = { kind: 'steps'; steps: readonly RuntimeStepProgramStep[]; returnResolver?: RuntimeStepResolver; /** Opt in to treating provider unavailability as a miss and advancing. */ continueOnProviderUnavailable?: boolean; }; export type { PlayDataset, PlayDatasetInput, PlayDatasetRow }; // Structured step data for UI visualization // csv_load is NOT a step — it's part of the run metadata, not the pipeline export type PlayStep = | { type: 'start'; trigger?: string; description?: string } | { type: 'csv_load'; arg?: string; rows?: number; description?: string } | { type: 'dataset'; items: number; fields?: string[]; substeps: PlayDatasetSubstep[]; description?: string; } | { type: 'waterfall'; tool?: string; providers?: string[]; id?: string; output?: string; minResults?: number; steps?: Array<{ id: string; kind?: 'tool' | 'code'; toolId?: string; results: PlayStepRowResult[]; }>; results: PlayStepRowResult[]; description?: string; } | { type: 'tool'; toolId: string; results: PlayStepRowResult[]; description?: string; } | { type: 'play_call'; playId: string; execution?: PlayCallExecution; results?: PlayStepRowResult[]; nestedSteps: PlayStep[]; description?: string; } | { type: 'run_javascript'; alias: string; results: PlayStepRowResult[]; description?: string; } | { type: 'return'; outputRows: number; description?: string }; /** Steps that happen inside ctx.dataset() — tool/waterfall calls from column resolvers. */ export type PlayDatasetSubstep = | { type: 'waterfall'; tool?: string; providers?: string[]; id?: string; output?: string; minResults?: number; steps?: Array<{ id: string; kind?: 'tool' | 'code'; toolId?: string; results: PlayStepRowResult[]; }>; results: PlayStepRowResult[]; description?: string; } | { type: 'tool'; toolId: string; results: PlayStepRowResult[]; description?: string; } | { type: 'play_call'; playId: string; execution?: PlayCallExecution; results?: PlayStepRowResult[]; nestedSteps: PlayStep[]; description?: string; } | { type: 'run_javascript'; alias: string; results: PlayStepRowResult[]; description?: string; }; type PlayStepRowResultFields = { rowId: number; provider?: string; value?: unknown; error?: string | null; }; export type PlayStepRowResult = PlayStepRowResultFields & ( | { status: 'completed'; success: true } | { status: 'failed' | 'missed' | 'skipped'; success: false } ); /** The producer credited with a cell's kept value. */ export interface PlaySheetCellProducer { kind: 'play' | 'tool' | 'code'; id?: string | null; displayName?: string | null; playId?: string | null; toolId?: string | null; runId?: string | null; } /** * One attempted producer for a runtime sheet cell (ADR 0018). * * `durationMs` is the wall time of the logical invocation as observed by the * runtime: it includes batching/queue wait, so summing it across a node is an * upper bound on provider time, not a wall-clock span for the node. */ export interface PlayCellProducerAttempt { kind: 'play' | 'tool' | 'code'; id?: string | null; toolId?: string | null; displayName?: string | null; /** Attempt start, epoch ms. */ at: number; outcome: 'running' | 'completed' | 'no_result' | 'failed' | 'cached'; durationMs?: number | null; } /** Cell-level provenance shapes (ADR 0019). Defined in `cell-provenance`. */ export type { PlayCellReadRef, PlayCellDecision, PlayRowBornFrom, PlayRowBornFromRow, PlayDatasetBornFrom, PlayRowReadOrder, PlayRowMeta, } from './cell-provenance'; export interface PlayRowUpdate { key: string; rowId: number; tableNamespace?: string | null; attemptId?: string | null; attemptOwnerRunId?: string | null; attemptSeq?: number | null; attemptExpiresAt?: string | null; writeVersion?: number | null; status?: 'running' | 'completed' | 'failed'; stage?: string | null; provider?: string | null; error?: string | null; dataPatch?: Record; /** * Row-grain provenance (ADR 0019), stored under the reserved `_cell_meta._row` * key. It is a separate field rather than a `cellMetaPatch` entry because it * is not a cell: it has no status, no producer, and no lifecycle. */ rowMetaPatch?: PlayRowMeta; cellMetaPatch?: Record< string, { status: | 'queued' | 'running' | 'completed' | 'failed' | 'cached' | 'missed' | 'skipped'; /** * Run that produced this cell. Stamped at the emit site so a run-scoped * read never has to infer ownership from the row's current `_run_id`, * which a later run overwrites (ADR 0018). */ runId?: string; stage?: string | null; provider?: string | null; error?: string | null; producer?: PlaySheetCellProducer | null; /** * Every producer attempted for this cell during the run, oldest first. * `producer` is patch-merged and therefore only ever holds the last leg; * a waterfall's losing legs exist nowhere else (a failed tool call writes * no durable receipt). See ADR 0018. */ producers?: PlayCellProducerAttempt[] | null; /** * Attempts the per-cell cap dropped (ADR 0018/0019). Present only when * the trace is a floor, so a capped cell cannot read as a complete count. */ attemptsDropped?: number; /** * Explicit per-cell read trace (ADR 0019). Only nested step-program cells * carry one, because their read-set includes sibling steps that the row's * column order does not describe. Dataset columns resolve their reads * through `_cell_meta._row.reads` instead of repeating a list per cell. */ reads?: PlayCellReadRef[] | null; /** Branch selected by a per-row conditional for this cell (ADR 0019). */ decide?: PlayCellDecision | null; reused?: boolean; completedAt?: number; staleAt?: number | null; staleAfterSeconds?: number | null; } >; }