@axlsdk/axl 0.19.1 → 0.20.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -112,6 +112,8 @@ type StreamChunk = {
112
112
  total_tokens: number;
113
113
  reasoning_tokens?: number;
114
114
  cached_tokens?: number;
115
+ /** Tokens written to a provider prompt cache during this call, when reported. */
116
+ cache_write_tokens?: number;
115
117
  };
116
118
  /** Estimated cost in USD for this call, computed the same way as ProviderResponse.cost. */
117
119
  cost?: number;
@@ -354,9 +356,13 @@ type ExecutionStatus = 'running' | 'completed' | 'failed' | 'waiting';
354
356
  * derive `AxlEventType` from this tuple and use it to validate stream filters,
355
357
  * redaction tables, and exhaustiveness assertions.
356
358
  */
357
- declare const AXL_EVENT_TYPES: readonly ["workflow_start", "workflow_end", "ask_start", "ask_end", "agent_call_start", "agent_call_end", "token", "tool_call_start", "tool_call_end", "tool_approval", "tool_denied", "delegate", "handoff_start", "handoff_return", "pipeline", "partial_object", "string_delta", "verify", "schema_diagnostic", "log", "memory_remember", "memory_recall", "memory_forget", "checkpoint_save", "checkpoint_replay", "await_human", "await_human_resolved", "guardrail", "schema_check", "validate", "done", "error"];
359
+ declare const AXL_EVENT_TYPES: readonly ["workflow_start", "workflow_end", "ask_start", "ask_end", "agent_call_start", "agent_call_end", "token", "tool_call_start", "tool_call_end", "tool_call_rejected", "tool_approval", "delegate", "handoff_start", "handoff_return", "pipeline", "partial_object", "string_delta", "verify", "schema_diagnostic", "log", "memory_remember", "memory_recall", "memory_forget", "checkpoint_save", "checkpoint_replay", "await_human", "await_human_resolved", "guardrail", "schema_check", "validate", "done", "error"];
358
360
  /** Discriminator union derived from `AXL_EVENT_TYPES`. */
359
361
  type AxlEventType = (typeof AXL_EVENT_TYPES)[number];
362
+ /** Backward-compatible name for the canonical v2 writer discriminator list. */
363
+ declare const AXL_EVENT_TYPES_V2: readonly ["workflow_start", "workflow_end", "ask_start", "ask_end", "agent_call_start", "agent_call_end", "token", "tool_call_start", "tool_call_end", "tool_call_rejected", "tool_approval", "delegate", "handoff_start", "handoff_return", "pipeline", "partial_object", "string_delta", "verify", "schema_diagnostic", "log", "memory_remember", "memory_recall", "memory_forget", "checkpoint_save", "checkpoint_replay", "await_human", "await_human_resolved", "guardrail", "schema_check", "validate", "done", "error"];
364
+ /** Accepted/rejected tool lifecycle discriminators in event schema v2. */
365
+ declare const AXL_TOOL_LIFECYCLE_TYPES_V2: readonly ["tool_call_start", "tool_call_end", "tool_call_rejected"];
360
366
  /** Resolved model parameters sent to the provider for an LLM call. */
361
367
  type AgentCallParams = {
362
368
  temperature?: number;
@@ -431,18 +437,142 @@ type ToolCallData = {
431
437
  type ToolCallStartData = {
432
438
  args: unknown;
433
439
  };
440
+ /** Data shape for a v2 tool start. The event's `tool` is canonical; this field
441
+ * retains the provider-visible request name only when it differs. */
442
+ type ToolCallStartDataV2 = {
443
+ args: unknown;
444
+ requestedTool?: string;
445
+ };
434
446
  /** Data shape for `tool_approval` events. Emitted by the approval gate on both outcomes. */
435
447
  type ToolApprovalData = {
436
448
  approved: boolean;
437
449
  args: unknown;
438
450
  reason?: string;
439
451
  };
440
- /** Data shape for `tool_denied` events. Emitted when the LLM names a tool the agent doesn't expose. */
452
+ /** Historical v1 data shape for `tool_denied` events. V2 writers emit
453
+ * `tool_call_rejected` for unavailable provider requests instead. */
441
454
  type ToolDeniedData = {
442
455
  args?: unknown;
443
456
  reason?: string;
444
457
  callId?: string;
445
458
  };
459
+ /** A validation issue for a provider-issued tool invocation.
460
+ *
461
+ * Values are deliberately omitted: paths and validator codes are sufficient
462
+ * for correction without copying application data into diagnostic channels.
463
+ */
464
+ type ToolArgumentIssue = {
465
+ path: readonly (string | number)[];
466
+ code: string;
467
+ message?: string;
468
+ };
469
+ /** Data shape for a v2 tool request rejected before execution starts. */
470
+ type ToolCallRejectedData = {
471
+ reason: 'unavailable';
472
+ requestedTool: string;
473
+ availableTools: string[];
474
+ } | {
475
+ reason: 'invalid_json';
476
+ requestedTool: string;
477
+ message: string;
478
+ } | {
479
+ reason: 'invalid_arguments';
480
+ requestedTool: string;
481
+ args: unknown;
482
+ issues: readonly ToolArgumentIssue[];
483
+ };
484
+ /** Host-observable error details for a terminal tool outcome. */
485
+ type ToolEventError = {
486
+ name: string;
487
+ message: string;
488
+ code?: string;
489
+ /** Optional host-only diagnostic cause. Redaction removes this at every
490
+ * untrusted observation boundary. */
491
+ cause?: unknown;
492
+ };
493
+ /** Constructor input for the next-major model-safe thrown tool failure. */
494
+ type ToolFailureOptions = {
495
+ message: string;
496
+ modelMessage: string;
497
+ code?: string;
498
+ cause?: unknown;
499
+ };
500
+ /** Failure details for an accepted v2 tool invocation. */
501
+ type ToolCallFailure = {
502
+ phase: 'approval';
503
+ kind: 'infrastructure';
504
+ disposition: 'abort';
505
+ error: ToolEventError;
506
+ } | {
507
+ phase: 'before_hook';
508
+ kind: 'tool_failure';
509
+ disposition: 'continue';
510
+ error: ToolEventError;
511
+ } | {
512
+ phase: 'before_hook';
513
+ kind: 'unexpected';
514
+ disposition: 'abort';
515
+ error: ToolEventError;
516
+ } | {
517
+ phase: 'handler';
518
+ kind: 'tool_failure' | 'mcp_error';
519
+ disposition: 'continue';
520
+ error: ToolEventError;
521
+ attempts: number;
522
+ } | {
523
+ phase: 'handler';
524
+ kind: 'unexpected';
525
+ disposition: 'abort';
526
+ error: ToolEventError;
527
+ attempts: number;
528
+ } | {
529
+ phase: 'after_hook';
530
+ kind: 'tool_failure';
531
+ disposition: 'continue';
532
+ error: ToolEventError;
533
+ result: unknown;
534
+ } | {
535
+ phase: 'after_hook';
536
+ kind: 'unexpected';
537
+ disposition: 'abort';
538
+ error: ToolEventError;
539
+ result: unknown;
540
+ } | {
541
+ phase: 'projection' | 'serialization';
542
+ kind: 'output';
543
+ disposition: 'abort';
544
+ error: ToolEventError;
545
+ result: unknown;
546
+ };
547
+ /** Cancellation details for an accepted v2 tool invocation. */
548
+ type ToolCallCancellation = {
549
+ phase: 'approval' | 'before_hook' | 'handler';
550
+ reason?: string;
551
+ } | {
552
+ phase: 'after_handler' | 'after_hook' | 'projection' | 'serialization';
553
+ result: unknown;
554
+ reason?: string;
555
+ };
556
+ /** Terminal state of an accepted v2 tool invocation. */
557
+ type ToolCallOutcome = {
558
+ status: 'succeeded';
559
+ result: unknown;
560
+ } | {
561
+ status: 'failed';
562
+ failure: ToolCallFailure;
563
+ } | {
564
+ status: 'denied';
565
+ reason?: string;
566
+ } | {
567
+ status: 'cancelled';
568
+ cancellation: ToolCallCancellation;
569
+ };
570
+ /** Data shape for a v2 `tool_call_end` event. */
571
+ type ToolCallEndData = {
572
+ args: unknown;
573
+ requestedTool?: string;
574
+ outcome: ToolCallOutcome;
575
+ };
446
576
  /** Data shape for `handoff_start` events (always emitted, pre-transition). */
447
577
  type HandoffStartData = {
448
578
  source: string;
@@ -586,6 +716,26 @@ type WorkflowStartData = {
586
716
  /** The validated input passed to the workflow handler. */
587
717
  input: unknown;
588
718
  };
719
+ /** Machine-readable completeness of an observation surface or execution trace. */
720
+ type ObservationStatus = {
721
+ complete: true;
722
+ } | {
723
+ complete: false;
724
+ reason: 'queue_overflow';
725
+ droppedEvents: number;
726
+ } | {
727
+ complete: false;
728
+ reason: 'branch_drain_timeout';
729
+ pendingContinuations: number;
730
+ timeoutMs: number;
731
+ } | {
732
+ complete: false;
733
+ reason: 'persistence_truncated';
734
+ maxEvents: number;
735
+ } | {
736
+ complete: false;
737
+ reason: 'process_interrupted';
738
+ };
589
739
  /** Data shape for `workflow_end` events. Emitted once per workflow execution
590
740
  * on completion, failure, or cancellation. Distinguish cancellation via `aborted`. */
591
741
  type WorkflowEndData = {
@@ -598,6 +748,9 @@ type WorkflowEndData = {
598
748
  /** True when the failure was an `AbortError` (user cancellation, budget hard_stop,
599
749
  * or consumer disconnect on streaming workflows). */
600
750
  aborted?: boolean;
751
+ /** Completeness of the terminal trace. Present on new executions; absent
752
+ * on historical events written before completeness signaling shipped. */
753
+ observation?: ObservationStatus;
601
754
  };
602
755
  /** Data shape for `checkpoint_save` / `checkpoint_replay` events.
603
756
  * Emitted by `ctx.checkpoint(name, fn)` — `save` on first execution,
@@ -708,6 +861,8 @@ type AxlEventBase = {
708
861
  input?: number;
709
862
  output?: number;
710
863
  reasoning?: number;
864
+ cached?: number;
865
+ cacheWrite?: number;
711
866
  };
712
867
  /** Duration in ms (set on `_end` variants and a few single-point events). */
713
868
  duration?: number;
@@ -723,22 +878,6 @@ type AskScoped = {
723
878
  * events that predate agent resolution. */
724
879
  agent?: string;
725
880
  };
726
- /**
727
- * Meta carried alongside callback invocations (`onToken`, `onAgentStart`,
728
- * `onToolCall`) so consumers can group/route by ask.
729
- *
730
- * Note: `agent` is **required** here (the callback is always invoked
731
- * inside an ALS frame that has the agent name already resolved). On the
732
- * event side (`AskScoped.agent`) the field is optional — events emitted
733
- * before agent resolution (e.g., `ask_start` is fired before the
734
- * dynamic agent selector runs) can land without it.
735
- */
736
- type CallbackMeta = {
737
- askId: string;
738
- parentAskId?: string;
739
- depth: number;
740
- agent: string;
741
- };
742
881
  /**
743
882
  * Unified event union. Replaces the old `TraceEvent` (rich, persisted) and
744
883
  * `StreamEvent` (lean, wire) by emitting a single rich event from one site
@@ -757,7 +896,7 @@ type CallbackMeta = {
757
896
  * exhaustiveness fixture in `__tests__/axl-event-exhaustive.test-d.ts` will
758
897
  * also fail until the new case is handled.
759
898
  */
760
- type AxlEvent = (AxlEventBase & {
899
+ type LegacyAxlEventPayloadV1 = (AxlEventBase & {
761
900
  type: 'workflow_start';
762
901
  workflow: string;
763
902
  data: WorkflowStartData;
@@ -809,6 +948,8 @@ type AxlEvent = (AxlEventBase & {
809
948
  input?: number;
810
949
  output?: number;
811
950
  reasoning?: number;
951
+ cached?: number;
952
+ cacheWrite?: number;
812
953
  };
813
954
  /** Response-side payload — response text, thinking. */
814
955
  data: AgentCallEndData;
@@ -934,6 +1075,59 @@ type AxlEvent = (AxlEventBase & {
934
1075
  code?: string;
935
1076
  };
936
1077
  });
1078
+ /** Tool lifecycle variants written by the v2 event schema. */
1079
+ type ToolLifecycleEventV2 = (AxlEventBase & AskScoped & {
1080
+ schemaVersion: 2;
1081
+ type: 'tool_call_start';
1082
+ agent: string;
1083
+ tool: string;
1084
+ callId: string;
1085
+ data: ToolCallStartDataV2;
1086
+ }) | (AxlEventBase & AskScoped & {
1087
+ schemaVersion: 2;
1088
+ type: 'tool_call_end';
1089
+ agent: string;
1090
+ tool: string;
1091
+ callId: string;
1092
+ duration: number;
1093
+ cost?: number;
1094
+ data: ToolCallEndData;
1095
+ }) | (AxlEventBase & AskScoped & {
1096
+ schemaVersion: 2;
1097
+ type: 'tool_call_rejected';
1098
+ agent: string;
1099
+ tool: string;
1100
+ callId: string;
1101
+ data: ToolCallRejectedData;
1102
+ });
1103
+ /** Event persisted by the legacy unversioned writer. Readers may normalize the
1104
+ * absent marker to an explicit `1` without reinterpreting its payload. */
1105
+ type LegacyAxlEventV1 = LegacyAxlEventPayloadV1 & {
1106
+ schemaVersion?: 1;
1107
+ };
1108
+ /** Named v2 rejection event for consumers that do not need the full union. */
1109
+ type ToolCallRejectedEvent = Extract<ToolLifecycleEventV2, {
1110
+ type: 'tool_call_rejected';
1111
+ }>;
1112
+ /** Event contract written by the next breaking runtime.
1113
+ *
1114
+ * This additive prototype lets consumers and type tests lock the schema before
1115
+ * the runtime writer switches. Every v2 event carries the version directly;
1116
+ * `tool_denied` and the v1 tool end shape cannot be represented.
1117
+ */
1118
+ type AxlEventV2 = ToolLifecycleEventV2 | (Exclude<LegacyAxlEventPayloadV1, {
1119
+ type: 'tool_call_start' | 'tool_call_end' | 'tool_denied';
1120
+ }> & {
1121
+ schemaVersion: 2;
1122
+ });
1123
+ /** Current live event contract. Every emitted event is explicitly v2. */
1124
+ type AxlEvent = AxlEventV2;
1125
+ /** Event returned by state-store and recovery readers during the migration. */
1126
+ type HistoricalAxlEvent = LegacyAxlEventV1 | AxlEventV2;
1127
+ /** Convenience: extract a v2 union member by discriminator. */
1128
+ type AxlEventV2Of<T extends AxlEventV2['type']> = Extract<AxlEventV2, {
1129
+ type: T;
1130
+ }>;
937
1131
  /** Convenience: extract the union member matching a given `type` discriminator. */
938
1132
  type AxlEventOf<T extends AxlEventType> = Extract<AxlEvent, {
939
1133
  type: T;
@@ -975,14 +1169,14 @@ type OutputValidator<T = unknown> = (output: T, ctx: {
975
1169
  metadata: Record<string, unknown>;
976
1170
  }) => ValidateResult | Promise<ValidateResult>;
977
1171
  /** Execution info */
978
- type ExecutionInfo = {
1172
+ type ExecutionInfoV1 = {
979
1173
  executionId: string;
980
1174
  workflow: string;
981
1175
  status: ExecutionStatus;
982
1176
  /** Full event timeline. Tokens and `partial_object` events are NOT persisted
983
1177
  * here (stream-only); aggregate `tokens: { input, output, reasoning? }`
984
1178
  * on `agent_call_end` is the persisted token representation. */
985
- events: AxlEvent[];
1179
+ events: LegacyAxlEventV1[];
986
1180
  /** Total spend for the execution. A LOWER BOUND when an unpriced model ran
987
1181
  * (those calls contribute nothing) — read {@link ExecutionInfo.unpriced} to
988
1182
  * know whether it's exact, rather than scanning the event timeline. */
@@ -999,6 +1193,9 @@ type ExecutionInfo = {
999
1193
  duration: number;
1000
1194
  result?: unknown;
1001
1195
  error?: string;
1196
+ /** Completeness of the persisted event timeline. Absent on historical
1197
+ * rows written before completeness signaling shipped. */
1198
+ observation?: ObservationStatus;
1002
1199
  /** Caller-supplied metadata threaded verbatim from `ExecuteOptions.metadata`
1003
1200
  * (or `runtime.stream()`'s `options.metadata`). Persisted as part of the
1004
1201
  * `ExecutionInfo` snapshot so callers have a stable, queryable surface for
@@ -1008,6 +1205,19 @@ type ExecutionInfo = {
1008
1205
  * provided — `StateStore` is a persistence boundary, not a query engine. */
1009
1206
  metadata?: Record<string, unknown>;
1010
1207
  };
1208
+ /** Stored execution written before explicit event schema versioning. */
1209
+ type LegacyExecutionInfoV1 = ExecutionInfoV1 & {
1210
+ eventSchemaVersion?: 1;
1211
+ };
1212
+ /** Stored or live execution written by the v2 event writer. */
1213
+ type ExecutionInfoV2 = Omit<ExecutionInfoV1, 'events'> & {
1214
+ eventSchemaVersion: 2;
1215
+ events: AxlEventV2[];
1216
+ };
1217
+ /** Current live execution contract. Historical reads retain their explicit union. */
1218
+ type ExecutionInfo = ExecutionInfoV2;
1219
+ /** Honest state-store read contract: missing version metadata means v1. */
1220
+ type HistoricalExecutionInfo = LegacyExecutionInfoV1 | ExecutionInfoV2;
1011
1221
  /** Record of an agent handoff event (persisted in session metadata).
1012
1222
  *
1013
1223
  * `duration` semantics:
@@ -1092,12 +1302,90 @@ type ProviderResponse = {
1092
1302
  total_tokens: number;
1093
1303
  reasoning_tokens?: number;
1094
1304
  cached_tokens?: number;
1305
+ /** Tokens written to a provider prompt cache during this call, when reported. */
1306
+ cache_write_tokens?: number;
1095
1307
  };
1096
1308
  cost?: number;
1097
1309
  /** Provider-specific opaque metadata that needs to round-trip through conversation history. */
1098
1310
  providerMetadata?: Record<string, unknown>;
1099
1311
  };
1100
1312
 
1313
+ /** Base error class for all Axl errors */
1314
+ declare class AxlError extends Error {
1315
+ readonly code: string;
1316
+ constructor(code: string, message: string);
1317
+ }
1318
+ /**
1319
+ * Strict observation overflow. Kept in the shared error module so every
1320
+ * recovery boundary can identify the same non-recoverable control error.
1321
+ * Thrown at the producer when an event queue configured with
1322
+ * `onOverflow: 'throw'` exceeds `maxQueued`.
1323
+ */
1324
+ declare class EventStreamOverflowError extends Error {
1325
+ readonly maxQueued: number;
1326
+ readonly eventType: string;
1327
+ readonly cause?: unknown;
1328
+ constructor(maxQueued: number, eventType: string, cause?: unknown);
1329
+ }
1330
+ /** A known tool failure whose author-provided model message is safe to expose. */
1331
+ declare class ToolFailure extends AxlError {
1332
+ readonly modelMessage: string;
1333
+ readonly cause?: unknown;
1334
+ constructor(options: ToolFailureOptions);
1335
+ }
1336
+ type ToolFailureConstructor = typeof ToolFailure;
1337
+ /** Thrown when a tool's model-facing output cannot be projected safely. */
1338
+ declare class ToolModelOutputError extends AxlError {
1339
+ readonly toolName: string;
1340
+ readonly cause: unknown;
1341
+ constructor(toolName: string, cause: unknown);
1342
+ }
1343
+ /** Thrown when schema validation fails after all retries exhausted */
1344
+ declare class VerifyError extends AxlError {
1345
+ readonly lastOutput: unknown;
1346
+ readonly zodError: ZodError;
1347
+ readonly retries: number;
1348
+ constructor(lastOutput: unknown, zodError: ZodError, retries: number);
1349
+ }
1350
+ /** Thrown when quorum is not met in spawn */
1351
+ declare class QuorumNotMet extends AxlError {
1352
+ readonly results: Result<unknown>[];
1353
+ constructor(required: number, actual: number, results: Result<unknown>[]);
1354
+ }
1355
+ /** Thrown when vote cannot reach consensus */
1356
+ declare class NoConsensus extends AxlError {
1357
+ constructor(reason: string);
1358
+ }
1359
+ /** Thrown when an operation exceeds its timeout */
1360
+ declare class TimeoutError extends AxlError {
1361
+ constructor(operation: string, timeoutMs: number);
1362
+ }
1363
+ /** Thrown when a budget limit is exceeded */
1364
+ declare class BudgetExceededError extends AxlError {
1365
+ readonly limit: number;
1366
+ readonly spent: number;
1367
+ readonly policy: string;
1368
+ constructor(limit: number, spent: number, policy: string);
1369
+ }
1370
+ /** Thrown when an agent exceeds its maximum number of tool-calling turns */
1371
+ declare class MaxTurnsError extends AxlError {
1372
+ readonly maxTurns: number;
1373
+ constructor(operation: string, maxTurns: number);
1374
+ }
1375
+ /** Thrown when a guardrail blocks a request/response and the policy is 'throw'. */
1376
+ declare class GuardrailError extends AxlError {
1377
+ readonly guardrailType: 'input' | 'output';
1378
+ readonly reason: string;
1379
+ constructor(guardrailType: 'input' | 'output', reason: string);
1380
+ }
1381
+ /** Thrown when post-schema business rule validation fails after all retries exhausted */
1382
+ declare class ValidationError extends AxlError {
1383
+ readonly lastOutput: unknown;
1384
+ readonly reason: string;
1385
+ readonly retries: number;
1386
+ constructor(lastOutput: unknown, reason: string, retries: number);
1387
+ }
1388
+
1101
1389
  /** Descriptor for a handoff target agent with optional description. */
1102
1390
  type HandoffDescriptor = {
1103
1391
  agent: Agent;
@@ -1165,11 +1453,13 @@ type Agent = {
1165
1453
  declare function agent(config: AgentConfig): Agent;
1166
1454
 
1167
1455
  /** Options shared between `AxlEventBus` (and therefore `AxlStream` and
1168
- * `ctx.events`). Controls the overflow safety net on the iterator queue. */
1456
+ * `ctx.events`). Controls the overflow safety net on the main iterator queue
1457
+ * and each listener-based `stringStream()` subscriber queue. */
1169
1458
  interface EventStreamOptions {
1170
- /** Soft cap on the number of events held in the iterator queue while
1171
- * waiting for a consumer. Terminal events (`done`, `error`,
1172
- * `workflow_end`) are exempt and always pass through. Default 10_000.
1459
+ /** Soft cap on the number of events held while waiting for a consumer,
1460
+ * including distinct pending fields in each `stringStream()` subscriber.
1461
+ * Terminal events (`done`, `error`, `workflow_end`) are exempt from the
1462
+ * main iterator cap and always pass through. Default 10_000.
1173
1463
  *
1174
1464
  * Set to `Infinity` to disable the cap (matches pre-0.x behavior). */
1175
1465
  maxQueued?: number;
@@ -1216,7 +1506,8 @@ type CoalescedPartialObject = {
1216
1506
  /**
1217
1507
  * The shape yielded by `AxlEventBus.stringStream` (and `AxlStream.stringStream`).
1218
1508
  *
1219
- * A live `string_delta` event carries `delta` (the new chars from this chunk)
1509
+ * A live `string_delta` event carries `delta` (the new chars since this
1510
+ * subscriber's previous yield; slow subscribers may coalesce source chunks)
1220
1511
  * and `accumulated` (every char emitted so far for this ask + path,
1221
1512
  * i.e. `delta1 + delta2 + ...`). Consumers rendering full-field state set
1222
1513
  * their UI text to `accumulated`; consumers rendering incrementally use
@@ -1240,8 +1531,9 @@ type StringStreamEvent = {
1240
1531
  agent?: string;
1241
1532
  /** RFC 6901 JSON Pointer; matches the source `string_delta.data.path`. */
1242
1533
  path: string;
1243
- /** Chars added in this delta. For seeded synthetic events on subscribe,
1244
- * equals `accumulated` (the full text-so-far). */
1534
+ /** Chars added since this subscriber's previous yield. May combine several
1535
+ * source chunks when the subscriber is slow. For seeded events, equals
1536
+ * `accumulated` (the full text-so-far). */
1245
1537
  delta: string;
1246
1538
  /** Concatenation of every delta this ask + path has emitted in the
1247
1539
  * current attempt. Cleared on `pipeline(failed)` and `ask_end`. */
@@ -1266,29 +1558,6 @@ type StringStreamFilter = {
1266
1558
  path?: string;
1267
1559
  askId?: string;
1268
1560
  };
1269
- /**
1270
- * Thrown when an `AxlEventBus` queue exceeds `maxQueued` and `onOverflow`
1271
- * is set to `'throw'`. Surfaced as a typed error so the runtime's emit
1272
- * pipeline can distinguish a legitimate overflow signal (which must
1273
- * propagate to fail the workflow) from a buggy trace-listener exception
1274
- * (which gets swallowed).
1275
- *
1276
- * Consumers using `instanceof` to handle overflow specifically:
1277
- * ```typescript
1278
- * try {
1279
- * await runtime.execute('wf', input, { events: { onOverflow: 'throw' } });
1280
- * } catch (err) {
1281
- * if (err instanceof EventStreamOverflowError) {
1282
- * // overflow — back off, retry, or surface to user
1283
- * }
1284
- * }
1285
- * ```
1286
- */
1287
- declare class EventStreamOverflowError extends Error {
1288
- readonly maxQueued: number;
1289
- readonly eventType: string;
1290
- constructor(maxQueued: number, eventType: string);
1291
- }
1292
1561
  /**
1293
1562
  * Iterable + EventEmitter event bus carrying `AxlEvent`.
1294
1563
  *
@@ -1319,6 +1588,7 @@ declare class AxlEventBus implements AsyncIterable<AxlEvent> {
1319
1588
  private readonly maxQueued;
1320
1589
  private readonly onOverflow;
1321
1590
  private overflowWarned;
1591
+ private droppedEvents;
1322
1592
  /** Callbacks fired exactly once when `_finish()` is called. Used by
1323
1593
  * curated views (e.g., `partialObjects`) that are listener-based and
1324
1594
  * need a termination signal independent of any synthetic `done` event. */
@@ -1364,6 +1634,10 @@ declare class AxlEventBus implements AsyncIterable<AxlEvent> {
1364
1634
  * can be 4 KB+ each, hence the more aggressive cleanup here).
1365
1635
  */
1366
1636
  private stringStreamByAsk;
1637
+ /** Internal fan-out for `stringStream()` subscribers. Kept separate from
1638
+ * the public EventEmitter so strict curated-view overflow is a runtime
1639
+ * signal, not mistaken for (and swallowed as) a buggy user listener. */
1640
+ private stringStreamSubscribers;
1367
1641
  /**
1368
1642
  * Hook fired when an iterator obtained from `[Symbol.asyncIterator]`
1369
1643
  * is `await using`-disposed. Set via the second constructor argument.
@@ -1385,6 +1659,10 @@ declare class AxlEventBus implements AsyncIterable<AxlEvent> {
1385
1659
  * Used by `AxlStream` to forward to `Readable.destroy()`.
1386
1660
  */
1387
1661
  constructor(options?: EventStreamOptions, onIteratorDispose?: () => void);
1662
+ /** Machine-readable completeness across this bus's bounded iterable views.
1663
+ * EventEmitter listener delivery is independent and is not described by
1664
+ * this status. */
1665
+ get observationStatus(): ObservationStatus;
1388
1666
  private unknownEventWarned;
1389
1667
  /** Subscribe to an `AxlEvent` variant by type. Names outside
1390
1668
  * `AXL_EVENT_TYPES` are dropped (the bus only emits those names) but
@@ -1519,6 +1797,7 @@ declare class AxlEventBus implements AsyncIterable<AxlEvent> {
1519
1797
  * non-terminal event arrives. Terminal events bypass this path entirely
1520
1798
  * (checked by the caller). */
1521
1799
  private handleOverflow;
1800
+ private warnOverflow;
1522
1801
  /**
1523
1802
  * Mark the bus as finished. Wakes any pending iterators with `done: true`
1524
1803
  * and drops further `_push` calls. Idempotent.
@@ -1678,6 +1957,8 @@ type PricingTable = Record<string, [number, number, number]>;
1678
1957
  type PricingSource = {
1679
1958
  kind: 'table';
1680
1959
  table: PricingTable;
1960
+ /** Exact matching prevents a future sibling from inheriting a base price. */
1961
+ match?: 'prefix' | 'exact';
1681
1962
  }
1682
1963
  /** Provider reports per-call cost in `usage.cost` (OpenRouter credits ≈ USD). */
1683
1964
  | {
@@ -1804,7 +2085,7 @@ type ProviderProfile = {
1804
2085
  * versioned snapshots like `gpt-4o-2024-05-13`). Returns `undefined` on a miss —
1805
2086
  * callers MUST treat that as "unknown cost", never as free.
1806
2087
  */
1807
- declare function priceFromTable(table: PricingTable, model: string, promptTokens: number, completionTokens: number, cachedTokens?: number): number | undefined;
2088
+ declare function priceFromTable(table: PricingTable, model: string, promptTokens: number, completionTokens: number, cachedTokens?: number, match?: 'prefix' | 'exact'): number | undefined;
1808
2089
  /**
1809
2090
  * Incremental scanner that separates streamed content into visible text and
1810
2091
  * `<think>…</think>` reasoning, tolerating tags split across chunks.
@@ -1876,11 +2157,21 @@ declare class OpenAICompatibleProvider implements Provider {
1876
2157
  protected buildRequestBody(messages: ChatMessage[], options: ChatOptions, stream: boolean): Record<string, unknown>;
1877
2158
  protected formatMessage(msg: ChatMessage, model: string): Record<string, unknown>;
1878
2159
  protected extractErrorMessage(body: string, status: number): string;
2160
+ private requestModel;
1879
2161
  private toUsage;
1880
- private computeCost;
1881
- protected parseResponse(json: OpenAIChatResponse, model: string): ProviderResponse;
2162
+ private reportedCost;
2163
+ /**
2164
+ * The generic profile path stays flat and public. Native subclasses may
2165
+ * override this protected seam to use a provider-internal estimator without
2166
+ * widening `PricingSource` or `ProviderProfile`.
2167
+ */
2168
+ protected computeCost(model: string, usage: ProviderResponse['usage'], reportedCost: number | undefined, context?: {
2169
+ request?: Record<string, unknown>;
2170
+ response?: OpenAIModelResponse;
2171
+ }): number | undefined;
2172
+ protected parseResponse(json: OpenAIChatResponse, model: string, request?: Record<string, unknown>): ProviderResponse;
1882
2173
  private roundTripMetadata;
1883
- protected parseSSEStream(body: ReadableStream<Uint8Array>, model: string): AsyncGenerator<StreamChunk>;
2174
+ protected parseSSEStream(body: ReadableStream<Uint8Array>, model: string, request?: Record<string, unknown>): AsyncGenerator<StreamChunk>;
1884
2175
  }
1885
2176
  type OpenAIUsage = {
1886
2177
  prompt_tokens: number;
@@ -1891,9 +2182,15 @@ type OpenAIUsage = {
1891
2182
  };
1892
2183
  prompt_tokens_details?: {
1893
2184
  cached_tokens?: number;
2185
+ cache_write_tokens?: number;
1894
2186
  };
1895
2187
  /** OpenRouter / Vercel Gateway: per-call cost in USD. */
1896
2188
  cost?: number;
2189
+ /** xAI: exact billed USD cost in ten-billionths of a dollar. */
2190
+ cost_in_usd_ticks?: number;
2191
+ /** DeepSeek: normalized cache hit/miss split for table pricing. */
2192
+ prompt_cache_hit_tokens?: number;
2193
+ prompt_cache_miss_tokens?: number;
1897
2194
  };
1898
2195
  type OpenAIChatMessage = {
1899
2196
  content: string | null | Array<string | {
@@ -1918,6 +2215,12 @@ type OpenAIChatResponse = {
1918
2215
  finish_reason: string;
1919
2216
  }>;
1920
2217
  usage?: OpenAIUsage;
2218
+ } & OpenAIModelResponse;
2219
+ type OpenAIModelResponse = {
2220
+ model?: string;
2221
+ service_tier?: unknown;
2222
+ serviceTier?: unknown;
2223
+ usage?: OpenAIUsage;
1921
2224
  };
1922
2225
 
1923
2226
  /** A pending human decision awaiting resolution. */
@@ -1928,7 +2231,8 @@ type PendingDecision = {
1928
2231
  metadata?: Record<string, unknown>;
1929
2232
  createdAt: string;
1930
2233
  };
1931
- /** Persisted execution state for suspend/resume. */
2234
+ /** Legacy application-managed execution state. Axl does not automatically
2235
+ * resume workflow continuations from this record. */
1932
2236
  type ExecutionState = {
1933
2237
  workflow: string;
1934
2238
  input: unknown;
@@ -1968,11 +2272,11 @@ interface StateStore {
1968
2272
  /** Delete a memory entry by key. */
1969
2273
  deleteMemory?(scope: string, key: string): Promise<void>;
1970
2274
  /** Save a completed/failed execution to history. */
1971
- saveExecution?(execution: ExecutionInfo): Promise<void>;
2275
+ saveExecution?(execution: HistoricalExecutionInfo): Promise<void>;
1972
2276
  /** Get a specific execution by ID from history. */
1973
- getExecution?(executionId: string): Promise<ExecutionInfo | null>;
2277
+ getExecution?(executionId: string): Promise<HistoricalExecutionInfo | null>;
1974
2278
  /** List recent executions (most recent first). */
1975
- listExecutions?(limit?: number): Promise<ExecutionInfo[]>;
2279
+ listExecutions?(limit?: number): Promise<HistoricalExecutionInfo[]>;
1976
2280
  /**
1977
2281
  * Delete an execution from history by ID. Returns `true` if an entry was
1978
2282
  * deleted, `false` if the ID didn't exist. Used for GDPR right-to-be-
@@ -2029,7 +2333,7 @@ interface StateStore {
2029
2333
  * Read the events accumulated in the streaming buffer for an execution.
2030
2334
  * Returns `[]` if no buffer exists.
2031
2335
  */
2032
- getStreamingEvents?(executionId: string): Promise<AxlEvent[]>;
2336
+ getStreamingEvents?(executionId: string): Promise<HistoricalAxlEvent[]>;
2033
2337
  close?(): Promise<void>;
2034
2338
  deleteCheckpoints?(executionId: string): Promise<void>;
2035
2339
  }
@@ -2054,7 +2358,7 @@ type TelemetryConfig = {
2054
2358
  interface SpanHandle {
2055
2359
  setAttribute(key: string, value: string | number | boolean): void;
2056
2360
  addEvent(name: string, attributes?: Record<string, string | number | boolean>): void;
2057
- setStatus(code: 'ok' | 'error', message?: string): void;
2361
+ setStatus(code: 'unset' | 'ok' | 'error', message?: string): void;
2058
2362
  end(): void;
2059
2363
  }
2060
2364
  /** Manages span creation and context propagation. */
@@ -2214,7 +2518,8 @@ type StateConfig = {
2214
2518
  * `log` event with `data.event === 'events_truncated'` is appended
2215
2519
  * recording the truncation. The trace channel (`runtime.on('trace')`)
2216
2520
  * and WS broadcast continue to receive every event — only the
2217
- * in-memory `ExecutionInfo.events` array is bounded.
2521
+ * in-memory `ExecutionInfo.events` array is bounded. The execution's
2522
+ * `observation` becomes `persistence_truncated`.
2218
2523
  *
2219
2524
  * Default: 50_000. Set to `Infinity` to disable the cap (legacy
2220
2525
  * behavior; only safe for short-lived executions). Must be a positive
@@ -2235,7 +2540,8 @@ type StateConfig = {
2235
2540
  * terminal exit. If the process crashes mid-run, call
2236
2541
  * `runtime.recoverIncompleteStreams()` on the next process to reconstruct
2237
2542
  * the partial `ExecutionInfo` from the streaming buffer (status: `'failed'`,
2238
- * error: `'process terminated'`). Use this in production when you need to
2543
+ * error: `'process terminated'`, observation: `process_interrupted`). Use
2544
+ * this in production when you need to
2239
2545
  * know "what did the workflow do up to the crash."
2240
2546
  *
2241
2547
  * Excluded from streaming flush even in `'streaming'` mode: `token`,
@@ -2554,6 +2860,16 @@ declare class MemoryManager {
2554
2860
  close(): Promise<void>;
2555
2861
  }
2556
2862
 
2863
+ type BranchDrainState = {
2864
+ pending: Set<Promise<unknown>>;
2865
+ overflow?: EventStreamOverflowError;
2866
+ timeoutMs: number;
2867
+ deadline?: number;
2868
+ };
2869
+ type WorkflowLifecycleState = {
2870
+ startEmitted: boolean;
2871
+ endEmitted: boolean;
2872
+ };
2557
2873
  /** Convert a Zod schema to JSON Schema. Exported for Studio tool introspection.
2558
2874
  * Wraps Zod v4's built-in `z.toJSONSchema()`, stripping the `$schema` key
2559
2875
  * since tool parameter schemas are embedded objects, not standalone documents.
@@ -2599,6 +2915,15 @@ type BudgetContextState = {
2599
2915
  /** Dedup guard so the unpriced warning fires at most once per budget block. */
2600
2916
  unpricedWarned: boolean;
2601
2917
  };
2918
+ /** Structured host signal emitted when approval compensation cannot remove a
2919
+ * persisted pending request. This is deliberately a runtime event rather than
2920
+ * an `AxlEvent`: it describes control-plane store health, not workflow work. */
2921
+ type DecisionCleanupFailedEvent = {
2922
+ executionId: string;
2923
+ workflow?: string;
2924
+ operation: 'resolveDecision_compensation';
2925
+ error: unknown;
2926
+ };
2602
2927
  type WorkflowContextInit = {
2603
2928
  input: unknown;
2604
2929
  executionId: string;
@@ -2607,17 +2932,10 @@ type WorkflowContextInit = {
2607
2932
  providerRegistry: ProviderRegistry;
2608
2933
  sessionHistory?: ChatMessage[];
2609
2934
  onTrace?: (event: AxlEvent) => void;
2610
- /** Per-token streaming callback. `meta` carries `askId`/`parentAskId`/
2611
- * `depth`/`agent` so consumers can route or filter (e.g., `meta.depth === 0`
2612
- * for root-only chat UIs). */
2613
- onToken?: (token: string, meta: CallbackMeta) => void;
2614
- /** Pre-execution tool-call callback. `meta` carries the ask correlation. */
2615
- onToolCall?: (call: {
2616
- name: string;
2617
- args: unknown;
2618
- callId?: string;
2619
- }, meta: CallbackMeta) => void;
2620
- pendingDecisions?: Map<string, (d: HumanDecision) => void>;
2935
+ pendingDecisions?: Map<string, PendingDecisionResolver>;
2936
+ /** Internal: root-shared guard because pending decisions are currently
2937
+ * keyed by executionId rather than requestId. */
2938
+ awaitHumanClaims?: Map<string, AbortController>;
2621
2939
  budgetContext?: BudgetContextState;
2622
2940
  stateStore?: StateStore;
2623
2941
  signal?: AbortSignal;
@@ -2627,19 +2945,14 @@ type WorkflowContextInit = {
2627
2945
  spanManager?: SpanManager;
2628
2946
  /** MemoryManager for ctx.remember() / ctx.recall() operations. */
2629
2947
  memoryManager?: MemoryManager;
2630
- /** When true, the context replays from checkpoints before executing. */
2631
- resumeMode?: boolean;
2632
2948
  /** Override tool handlers by name. Bypasses normal tool lookup in executeAgentCall. */
2633
2949
  toolOverrides?: Map<string, (args: unknown) => Promise<unknown>>;
2634
2950
  /** Handler for awaitHuman — when set, returns immediately instead of waiting for pendingDecisions. */
2635
2951
  awaitHumanHandler?: (options: AwaitHumanOptions) => HumanDecision | Promise<HumanDecision>;
2636
- /** Callback fired when an agent LLM call is about to start. */
2637
- onAgentStart?: (info: {
2638
- agent: string;
2639
- model: string;
2640
- }, meta: CallbackMeta) => void;
2641
2952
  /** Callback fired after each ctx.ask() completes (once per ask invocation). */
2642
2953
  onAgentCallComplete?: (call: AgentCallInfo) => void;
2954
+ /** Internal: reports approval compensation failures to the owning runtime. */
2955
+ _onDecisionCleanupFailed?: (event: DecisionCleanupFailedEvent) => void;
2643
2956
  /** Options for the lazy `ctx.events` `AxlEventBus`. Forwarded by
2644
2957
  * `runtime.createContext({ events })` / `runtime.execute(name, input,
2645
2958
  * { events })` / `runtime.stream(name, input, { events })`. If unset,
@@ -2656,6 +2969,9 @@ type WorkflowContextInit = {
2656
2969
  _busRef?: {
2657
2970
  current: AxlEventBus | undefined;
2658
2971
  };
2972
+ /** Internal: force provider streaming for runtime.stream(). Inherited by
2973
+ * child contexts. */
2974
+ _forceStreaming?: boolean;
2659
2975
  /** Internal: shared auto-checkpoint counters. Set by `createChildContext`
2660
2976
  * so parent + child share the same number space, preventing checkpoint
2661
2977
  * store key collisions across nested `WorkflowContext` instances.
@@ -2673,6 +2989,31 @@ type WorkflowContextInit = {
2673
2989
  byAgent: Map<string, number>;
2674
2990
  root: number;
2675
2991
  };
2992
+ /** Internal: root-shared state for branch continuations that must settle
2993
+ * before the runtime emits the workflow terminal and snapshots cost. */
2994
+ branchDrainState?: BranchDrainState;
2995
+ /** Internal: root-shared lifecycle state. Prevents child contexts from
2996
+ * emitting trace events after the workflow terminal. */
2997
+ workflowLifecycleState?: WorkflowLifecycleState;
2998
+ /** Runtime terminal barrier for abort-ignoring race/quorum branches. */
2999
+ branchDrainTimeoutMs?: number;
3000
+ };
3001
+ /** @internal Coordination gate shared between WorkflowContext and AxlRuntime. */
3002
+ type PendingDecisionResolver = {
3003
+ resolve: (decision: HumanDecision) => void;
3004
+ ready: Promise<void>;
3005
+ state: 'preparing' | 'pending' | 'resolving' | 'resolved' | 'failed';
3006
+ /** Set synchronously by the abort listener so no new public resolution can
3007
+ * claim the request while cleanup remains discoverable to deleteExecution. */
3008
+ cancelled: boolean;
3009
+ /** Present while runtime.resolveDecision owns the durable store mutation.
3010
+ * Cancellation waits for this result before deciding whether compensation
3011
+ * is still needed, so custom stores never receive contradictory writes in
3012
+ * parallel for the same request. */
3013
+ resolution?: Promise<boolean>;
3014
+ /** Resolves after cancellation compensation and resolver cleanup finish.
3015
+ * deleteExecution joins this barrier before its total store sweep. */
3016
+ cleanupFinished: Promise<void>;
2676
3017
  };
2677
3018
  /**
2678
3019
  * The central coordination object for all Axl primitives.
@@ -2692,9 +3033,8 @@ declare class WorkflowContext<TInput = unknown> {
2692
3033
  private providerRegistry;
2693
3034
  private sessionHistory;
2694
3035
  private onTrace?;
2695
- private onToken?;
2696
- private onToolCall?;
2697
3036
  private pendingDecisions?;
3037
+ private readonly awaitHumanClaims;
2698
3038
  private budgetContext?;
2699
3039
  private stateStore?;
2700
3040
  /** Root step counter for this execution. Inherited by every ctx.ask()
@@ -2715,27 +3055,27 @@ declare class WorkflowContext<TInput = unknown> {
2715
3055
  * the caller-supplied key.
2716
3056
  */
2717
3057
  private autoCheckpointCounters;
2718
- /** Idempotency guards for `workflow_start` / `workflow_end` emission.
3058
+ private readonly branchDrainState;
3059
+ /** Root-shared idempotency guards for workflow lifecycle emission.
2719
3060
  * Both `runtime.execute()` and `runtime.stream()` have paths where a
2720
3061
  * post-emit side-effect (checkpoint deletion, state-store persistence)
2721
3062
  * can throw AFTER `_emitWorkflowEnd({status: 'completed'})` has already
2722
3063
  * fired — the outer catch would then fire `_emitWorkflowEnd({status:
2723
3064
  * 'failed'})` for a second time. These flags make both emitters
2724
3065
  * single-fire so consumers never see paired-then-conflicting terminal
2725
- * events for one execution. */
2726
- private _workflowStartEmitted;
2727
- private _workflowEndEmitted;
3066
+ * events for one execution. Sharing the state with child contexts also
3067
+ * suppresses late branch events after bounded finalization. */
3068
+ private readonly workflowLifecycleState;
2728
3069
  private signal?;
2729
3070
  private summaryCache?;
2730
3071
  private workflowName?;
2731
3072
  private mcpManager?;
2732
3073
  private spanManager?;
2733
3074
  private memoryManager?;
2734
- private resumeMode;
2735
3075
  private toolOverrides?;
2736
3076
  private awaitHumanHandler?;
2737
- private onAgentStart?;
2738
3077
  private onAgentCallComplete?;
3078
+ private _onDecisionCleanupFailed?;
2739
3079
  /** Shared mutable slot for the lazy `AxlEventBus`. The slot is shared
2740
3080
  * by reference across parent/child contexts so a late allocation
2741
3081
  * (consumer subscribes after a child context exists) is visible
@@ -2744,6 +3084,7 @@ declare class WorkflowContext<TInput = unknown> {
2744
3084
  * contexts that never observe). */
2745
3085
  private readonly _busRef;
2746
3086
  private readonly _eventStreamOptions?;
3087
+ private readonly _forceStreaming;
2747
3088
  /** Removes the constructor-registered `'abort'` listener from
2748
3089
  * `this.signal` so a long-lived signal (e.g., a request-scoped or
2749
3090
  * process-wide signal reused across many `runtime.createContext()` /
@@ -2763,8 +3104,7 @@ declare class WorkflowContext<TInput = unknown> {
2763
3104
  * *between* asks. `ctx.events.partialObjects` is the coalescing view
2764
3105
  * designed for streaming-structured-output UIs.
2765
3106
  * - **Ad-hoc contexts** from `runtime.createContext()`: the same
2766
- * iterable replaces the legacy `onToken` / `onToolCall` /
2767
- * `onAgentStart` callbacks.
3107
+ * iterable provides typed per-context observation.
2768
3108
  * - **Cross-execution**: prefer `runtime.on('trace', …)` instead — that
2769
3109
  * fans out across all executions, while `ctx.events` is per-context.
2770
3110
  *
@@ -2779,9 +3119,9 @@ declare class WorkflowContext<TInput = unknown> {
2779
3119
  *
2780
3120
  * **Subscribe before the first `ctx.ask()`.** The streaming code
2781
3121
  * path inside `ctx.ask()` activates only when an observer is
2782
- * present at the time the ask starts (`_streamingEnabled` — either
2783
- * the legacy `onToken` callback is set or `ctx.events` has been
2784
- * allocated). If you allocate `ctx.events` AFTER a `ctx.ask()` has
3122
+ * present at the time the ask starts (`_streamingEnabled` — an explicit
3123
+ * runtime streaming mode or allocated `ctx.events`). If you allocate
3124
+ * `ctx.events` AFTER a `ctx.ask()` has
2785
3125
  * begun, that in-flight ask will not stream `token` /
2786
3126
  * `partial_object` events at all (the agent loop went through
2787
3127
  * `provider.chat` instead of `provider.stream`). Subsequent asks
@@ -2809,11 +3149,9 @@ declare class WorkflowContext<TInput = unknown> {
2809
3149
  * long-lived `signal` reused across many ad-hoc contexts doesn't
2810
3150
  * accumulate listeners. */
2811
3151
  disposeEvents(): void;
2812
- /** True if any observer wants per-token streaming for asks started
2813
- * from this context: either the legacy `onToken` callback is set
2814
- * (e.g., `runtime.stream()` plumbs a sentinel) OR `ctx.events` has
2815
- * been allocated (a workflow-handler consumer subscribed before
2816
- * the ask). `ctx.ask` reads this to decide whether to enter the
3152
+ /** True when asks should use provider streaming: `runtime.stream()` set an
3153
+ * explicit internal mode or `ctx.events` has been allocated. `ctx.ask`
3154
+ * reads this to decide whether to enter the
2817
3155
  * streaming code path; the gate is re-checked per ask, so a
2818
3156
  * consumer subscribing AFTER the first ask started still gets
2819
3157
  * streaming on the next one. The check `_busRef.current !== undefined`
@@ -2825,16 +3163,9 @@ declare class WorkflowContext<TInput = unknown> {
2825
3163
  * Create a child context for nested agent invocations (e.g., agent-as-tool).
2826
3164
  * Shares: budget tracking, abort signals, trace emission, provider registry,
2827
3165
  * state store, span manager, memory manager, MCP manager, config,
2828
- * awaitHuman handler, pending decisions, tool overrides, AND the
2829
- * streaming callbacks (onToken / onAgentStart / onToolCall).
3166
+ * awaitHuman handler, pending decisions, tool overrides, and event bus.
2830
3167
  * Isolates: session history.
2831
3168
  *
2832
- * Streaming callbacks now propagate into nested asks because every callback
2833
- * invocation carries `meta.askId`/`meta.parentAskId`/`meta.depth` so
2834
- * consumers that want root-only behavior can filter on `meta.depth === 0`
2835
- * instead of relying on the runtime to drop nested events. This is the
2836
- * "nested ask visibility" fix from spec §3.2.
2837
- *
2838
3169
  * The shared step counter lives in `askStorage` (ALS), so there is no
2839
3170
  * per-context counter to pass through anymore. Nested events are
2840
3171
  * correlated to their parent via `parentAskId` (set on every nested ask
@@ -2848,18 +3179,15 @@ declare class WorkflowContext<TInput = unknown> {
2848
3179
  * take priority over the instance-level signal.
2849
3180
  */
2850
3181
  private get currentSignal();
2851
- /**
2852
- * Build a `CallbackMeta` for the current ask frame. Used at every
2853
- * `onToken`/`onToolCall`/`onAgentStart` call site so consumers can
2854
- * route or filter by ask correlation (`meta.depth === 0` for root
2855
- * chat UIs, etc.).
2856
- *
2857
- * If the call is somehow outside an ask frame (e.g., a programmatic
2858
- * `tool.run()` test harness), falls back to a synthetic meta keyed off
2859
- * `executionId` so the type contract holds — consumers see `depth: 0`
2860
- * and can ignore those events.
2861
- */
2862
- private currentCallbackMeta;
3182
+ private _registerBranchDrain;
3183
+ /** Wait for race/quorum losers (including nested branch work) to settle.
3184
+ * Primitive calls still resolve as soon as their winner/quorum is known;
3185
+ * this is only the runtime's terminal/persistence barrier. */
3186
+ _drainBranchWork(): Promise<ObservationStatus>;
3187
+ /** Resolve, execute, and observe one non-handoff tool request. Rejections
3188
+ * never start. Every accepted request emits one terminal event before a
3189
+ * continuation message or abort escapes this coordinator. */
3190
+ private observeToolInvocation;
2863
3191
  ask<T = string>(agent: Agent, prompt: string, options?: AskOptions<T>): Promise<T>;
2864
3192
  private executeAgentCall;
2865
3193
  /**
@@ -2895,12 +3223,12 @@ declare class WorkflowContext<TInput = unknown> {
2895
3223
  * Execute a function with checkpoint-replay semantics.
2896
3224
  *
2897
3225
  * On first execution, runs `fn()`, saves the result under `name`, and
2898
- * returns it. On replay (resume after restart), returns the saved result
2899
- * without re-executing. This prevents duplicate side effects (double API
2900
- * calls, double refunds, etc.).
3226
+ * returns it. A later evaluation in the same explicit execution scope
3227
+ * returns the saved result without re-executing. Axl does not restart or
3228
+ * resume workflow continuations across processes.
2901
3229
  *
2902
3230
  * `name` must be a stable, caller-supplied identifier — the same call
2903
- * site MUST pass the same name across runs of the same execution for
3231
+ * site MUST pass the same name across evaluations of the same execution for
2904
3232
  * replay to work. Names are scoped to a single execution and must be
2905
3233
  * unique within it; reusing a name (e.g. inside a loop) gives
2906
3234
  * last-write-wins behavior. For loops, compose names from the iterator:
@@ -3015,6 +3343,7 @@ declare class WorkflowContext<TInput = unknown> {
3015
3343
  result?: unknown;
3016
3344
  error?: string;
3017
3345
  aborted?: boolean;
3346
+ observation?: ObservationStatus;
3018
3347
  }): void;
3019
3348
  log(event: string, data?: unknown): void;
3020
3349
  /**
@@ -3210,6 +3539,9 @@ declare class AxlStream extends Readable implements AsyncIterable<AxlEvent> {
3210
3539
  text: string;
3211
3540
  }>;
3212
3541
  get lifecycle(): AsyncIterable<AxlEvent>;
3542
+ /** Completeness of this stream's iterator queue. Check after consumption
3543
+ * before treating an unmatched lifecycle event as a producer defect. */
3544
+ get observationStatus(): ObservationStatus;
3213
3545
  /** Coalescing iterator over `partial_object` events — yields the latest
3214
3546
  * object payload per `askId`. Designed for streaming-structured-output
3215
3547
  * UIs: when the producer outpaces the consumer, intermediate snapshots
@@ -3383,6 +3715,9 @@ type ExecuteOptions = {
3383
3715
  * defaults are `maxQueued: 10_000` and `onOverflow:
3384
3716
  * 'drop-oldest-non-terminal'`. */
3385
3717
  events?: EventStreamOptions;
3718
+ /** Maximum terminal wait for abort-ignoring race/quorum branches. Once
3719
+ * exceeded, finalization proceeds with observation.complete=false. */
3720
+ branchDrainTimeoutMs?: number;
3386
3721
  };
3387
3722
  /**
3388
3723
  * Shape of events forwarded to an eval `onProgress` callback. Mirrors
@@ -3426,23 +3761,6 @@ type CreateContextOptions = {
3426
3761
  signal?: AbortSignal;
3427
3762
  /** Prior conversation history for multi-turn eval testing. */
3428
3763
  sessionHistory?: ChatMessage[];
3429
- /** Token streaming callback. `meta` carries `askId`/`parentAskId`/`depth`/`agent`
3430
- * so consumers can route or filter by ask correlation (e.g.,
3431
- * `meta.depth === 0` for root-only chat UIs). */
3432
- onToken?: (token: string, meta: CallbackMeta) => void;
3433
- /** Fires when an agent invokes a tool. `meta` carries the same ask
3434
- * correlation shape as `onToken`. */
3435
- onToolCall?: (call: {
3436
- name: string;
3437
- args: unknown;
3438
- callId?: string;
3439
- }, meta: CallbackMeta) => void;
3440
- /** Fires when an agent begins processing a turn. `meta` carries the
3441
- * same ask correlation shape as `onToken`. */
3442
- onAgentStart?: (info: {
3443
- agent: string;
3444
- model?: string;
3445
- }, meta: CallbackMeta) => void;
3446
3764
  /** Handler for tool approval requests. Called when an agent invokes a tool with requireApproval. */
3447
3765
  awaitHumanHandler?: (options: AwaitHumanOptions) => Promise<HumanDecision>;
3448
3766
  /** Configuration for the lazy `ctx.events` bus on the returned context.
@@ -3547,9 +3865,7 @@ declare class AxlRuntime extends EventEmitter {
3547
3865
  * → parse output → emit `workflow_end` → delete checkpoints → persist.
3548
3866
  *
3549
3867
  * Shared between `execute()` and `stream()`. Centralizes the
3550
- * "start iff end" pairing invariant so a future emit path
3551
- * (e.g., `resumeExecution`) can inherit correct behavior by routing
3552
- * through this helper. Also factors out the AbortError detection.
3868
+ * "start iff end" pairing invariant and AbortError detection.
3553
3869
  *
3554
3870
  * Side effects on `execInfo`: sets `status` / `completedAt` /
3555
3871
  * `duration` / `result` (or `error`) before emitting `workflow_end`.
@@ -3639,15 +3955,15 @@ declare class AxlRuntime extends EventEmitter {
3639
3955
  captureTraces?: boolean;
3640
3956
  }): Promise<unknown>;
3641
3957
  /** Get all execution info (running + completed + historical). */
3642
- /** Normalize an `ExecutionInfo` loaded from a `StateStore` so the
3643
- * `events: AxlEvent[]` type contract holds for downstream consumers
3958
+ /** Normalize an execution loaded from a `StateStore` so the
3959
+ * historical event union holds for downstream consumers
3644
3960
  * (Studio aggregators, REST routes, redaction). Custom or legacy stores
3645
3961
  * may persist rows without `events` (or with a non-array value) — without
3646
3962
  * this guard, a single malformed row crashes every iterator over
3647
- * `exec.events` and takes down dependent features. Mutates the row
3648
- * in place; logs at most one warning per `executionId`. */
3963
+ * `exec.events` and takes down dependent features. Returns a normalized
3964
+ * copy; logs at most one warning per `executionId`. */
3649
3965
  private normalizeStoredExecution;
3650
- getExecutions(): Promise<ExecutionInfo[]>;
3966
+ getExecutions(): Promise<HistoricalExecutionInfo[]>;
3651
3967
  /**
3652
3968
  * Create a WorkflowContext for ad-hoc use (evals, tool testing, prototyping).
3653
3969
  * The context has access to the runtime's providers, state store, MCP manager,
@@ -3708,11 +4024,11 @@ declare class AxlRuntime extends EventEmitter {
3708
4024
  * finalize. The implementation checks the historical store before
3709
4025
  * synthesizing, so a re-run is safe.
3710
4026
  */
3711
- recoverIncompleteStreams(): Promise<ExecutionInfo[]>;
4027
+ recoverIncompleteStreams(): Promise<HistoricalExecutionInfo[]>;
3712
4028
  /** Abort a running execution by its ID. */
3713
4029
  abort(executionId: string): void;
3714
4030
  /** Get execution details by ID. */
3715
- getExecution(executionId: string): Promise<ExecutionInfo | undefined>;
4031
+ getExecution(executionId: string): Promise<HistoricalExecutionInfo | undefined>;
3716
4032
  /** Save an eval result to history. */
3717
4033
  saveEvalResult(entry: EvalHistoryEntry): Promise<void>;
3718
4034
  /**
@@ -3767,18 +4083,6 @@ declare class AxlRuntime extends EventEmitter {
3767
4083
  getPendingDecisions(): Promise<PendingDecision[]>;
3768
4084
  /** Resolve a pending human decision. */
3769
4085
  resolveDecision(executionId: string, decision: HumanDecision): Promise<void>;
3770
- /**
3771
- * Resume a specific execution that was waiting for a human decision.
3772
- * Re-runs the workflow from scratch; the workflow should use checkpoint-replay
3773
- * to skip already-completed steps and pick up from the awaitHuman point.
3774
- */
3775
- resumeExecution(executionId: string): Promise<unknown>;
3776
- /**
3777
- * Resume all pending executions that were waiting for human decisions.
3778
- * Call this on startup to resume workflows that were interrupted by a restart.
3779
- * Returns the execution IDs that were resumed.
3780
- */
3781
- resumePending(): Promise<string[]>;
3782
4086
  /**
3783
4087
  * Summarize a list of chat messages into a concise summary string.
3784
4088
  * Used by Session to summarize dropped messages when history.summarize is enabled.
@@ -4189,6 +4493,8 @@ declare function hasPositiveTokens(event: {
4189
4493
  input?: number;
4190
4494
  output?: number;
4191
4495
  reasoning?: number;
4496
+ cached?: number;
4497
+ cacheWrite?: number;
4192
4498
  } | null;
4193
4499
  }): boolean;
4194
4500
  /**
@@ -4215,7 +4521,7 @@ declare function isUsableCost(cost: unknown): cost is number;
4215
4521
  * `ask_end.cost` directly — that field is populated whether or not
4216
4522
  * the leaf events were summed separately. Spec decision 10.
4217
4523
  */
4218
- declare function eventCostContribution(event: AxlEvent): number;
4524
+ declare function eventCostContribution(event: HistoricalAxlEvent): number;
4219
4525
  /**
4220
4526
  * True when the event is a cost-bearing leaf (contributes directly to
4221
4527
  * totals) — used by internal emitters that need to know whether to
@@ -4225,7 +4531,7 @@ declare function eventCostContribution(event: AxlEvent): number;
4225
4531
  * with `cost: 0` is still a leaf (produced by a free / cached turn),
4226
4532
  * just one that happens to contribute zero.
4227
4533
  */
4228
- declare function isCostBearingLeaf(event: AxlEvent): boolean;
4534
+ declare function isCostBearingLeaf(event: HistoricalAxlEvent): boolean;
4229
4535
  /**
4230
4536
  * True when the event is the "unpriced lower-bound" signal: a cost-bearing leaf
4231
4537
  * that did measurable, billable work (POSITIVE tokens) but produced no usable
@@ -4252,6 +4558,8 @@ declare function isUnpricedLeaf(event: {
4252
4558
  input?: number;
4253
4559
  output?: number;
4254
4560
  reasoning?: number;
4561
+ cached?: number;
4562
+ cacheWrite?: number;
4255
4563
  } | null;
4256
4564
  }): boolean;
4257
4565
  /**
@@ -4265,7 +4573,7 @@ declare function isUnpricedLeaf(event: {
4265
4573
  * (out-of-ask lifecycle events, synthesized terminals) are treated
4266
4574
  * as root-level — they're never at depth ≥ 1.
4267
4575
  */
4268
- declare function isRootLevel(event: AxlEvent): boolean;
4576
+ declare function isRootLevel(event: HistoricalAxlEvent): boolean;
4269
4577
 
4270
4578
  /**
4271
4579
  * Tolerant JSON parser for progressive structured-output streaming.
@@ -4299,6 +4607,25 @@ declare function isRootLevel(event: AxlEvent): boolean;
4299
4607
  /** Parse a JSON-shaped string that may be truncated mid-stream. */
4300
4608
  declare function parsePartialJson(input: string): unknown;
4301
4609
 
4610
+ declare class UnsupportedEventSchemaVersionError extends Error {
4611
+ readonly version: unknown;
4612
+ constructor(version: unknown);
4613
+ }
4614
+ /** Missing event metadata is the documented v1 sentinel. */
4615
+ declare function getEventSchemaVersion(event: {
4616
+ schemaVersion?: unknown;
4617
+ }): 1 | 2;
4618
+ /** Missing execution metadata is the documented v1 sentinel. */
4619
+ declare function getExecutionEventSchemaVersion(execution: {
4620
+ eventSchemaVersion?: unknown;
4621
+ }): 1 | 2;
4622
+ /**
4623
+ * Normalize one state-store row without reinterpreting event payloads.
4624
+ * Every event must agree with the execution carrier; mixed-version traces fail
4625
+ * loudly instead of being guessed into either reducer.
4626
+ */
4627
+ declare function normalizeStoredExecution(execution: HistoricalExecutionInfo): HistoricalExecutionInfo;
4628
+
4302
4629
  /**
4303
4630
  * Per-variant redaction rules for `AxlEvent`.
4304
4631
  *
@@ -4333,94 +4660,52 @@ declare function parsePartialJson(input: string): unknown;
4333
4660
  */
4334
4661
 
4335
4662
  declare const REDACTED = "[redacted]";
4336
- /** Type-safe rule signature: takes a specific event variant, returns the same variant. */
4337
4663
  type RuleFor<T extends AxlEventType> = (event: AxlEventOf<T>) => AxlEventOf<T>;
4338
- /**
4339
- * Per-variant rule table. Adding a new variant to `AXL_EVENT_TYPES`
4340
- * without a corresponding entry here is a typecheck error — the
4341
- * `Record<AxlEventType, ...>` mapped type forces exhaustiveness.
4342
- *
4343
- * For variants that ship no user content today (`delegate`,
4344
- * `handoff_return`, `checkpoint_*`), the rule is `passthrough` — but
4345
- * that's still an explicit, reviewed decision rather than a
4346
- * silent omission.
4347
- */
4664
+ type V2ToolEventType = ToolLifecycleEventV2['type'];
4665
+ type V2ToolRule<T extends V2ToolEventType> = (event: Extract<ToolLifecycleEventV2, {
4666
+ type: T;
4667
+ }>) => Extract<ToolLifecycleEventV2, {
4668
+ type: T;
4669
+ }>;
4670
+ /** Current-writer redaction rules. The mapped type makes every live event
4671
+ * discriminator an explicit compile-time redaction decision. */
4348
4672
  declare const REDACTION_RULES: {
4349
- [K in AxlEventType]: RuleFor<K>;
4673
+ tool_call_start: V2ToolRule<"tool_call_start">;
4674
+ tool_call_end: V2ToolRule<"tool_call_end">;
4675
+ tool_call_rejected: V2ToolRule<"tool_call_rejected">;
4676
+ workflow_start: RuleFor<"workflow_start">;
4677
+ workflow_end: RuleFor<"workflow_end">;
4678
+ ask_start: RuleFor<"ask_start">;
4679
+ ask_end: RuleFor<"ask_end">;
4680
+ agent_call_start: RuleFor<"agent_call_start">;
4681
+ agent_call_end: RuleFor<"agent_call_end">;
4682
+ token: RuleFor<"token">;
4683
+ tool_approval: RuleFor<"tool_approval">;
4684
+ delegate: RuleFor<"delegate">;
4685
+ handoff_start: RuleFor<"handoff_start">;
4686
+ handoff_return: RuleFor<"handoff_return">;
4687
+ pipeline: RuleFor<"pipeline">;
4688
+ partial_object: RuleFor<"partial_object">;
4689
+ string_delta: RuleFor<"string_delta">;
4690
+ verify: RuleFor<"verify">;
4691
+ schema_diagnostic: RuleFor<"schema_diagnostic">;
4692
+ log: RuleFor<"log">;
4693
+ memory_remember: RuleFor<"memory_remember">;
4694
+ memory_recall: RuleFor<"memory_recall">;
4695
+ memory_forget: RuleFor<"memory_forget">;
4696
+ checkpoint_save: RuleFor<"checkpoint_save">;
4697
+ checkpoint_replay: RuleFor<"checkpoint_replay">;
4698
+ await_human: RuleFor<"await_human">;
4699
+ await_human_resolved: RuleFor<"await_human_resolved">;
4700
+ guardrail: RuleFor<"guardrail">;
4701
+ schema_check: RuleFor<"schema_check">;
4702
+ validate: RuleFor<"validate">;
4703
+ done: RuleFor<"done">;
4704
+ error: RuleFor<"error">;
4350
4705
  };
4351
- /**
4352
- * Apply the redaction rule for `event.type` and return a new event with
4353
- * user-content fields scrubbed. Pure: never mutates the input.
4354
- *
4355
- * Caller responsibility: only invoke when redaction is enabled. The rules
4356
- * unconditionally scrub — they don't gate on `config.trace.redact`. Both
4357
- * `WorkflowContext.emitEvent` (core) and `redactStreamEvent` (Studio)
4358
- * check the flag before calling this function.
4359
- */
4360
4706
  declare function redactEvent(event: AxlEvent): AxlEvent;
4361
-
4362
- /** Base error class for all Axl errors */
4363
- declare class AxlError extends Error {
4364
- readonly code: string;
4365
- constructor(code: string, message: string);
4366
- }
4367
- /** Thrown when a tool's model-facing output cannot be projected safely. */
4368
- declare class ToolModelOutputError extends AxlError {
4369
- readonly toolName: string;
4370
- readonly cause: unknown;
4371
- constructor(toolName: string, cause: unknown);
4372
- }
4373
- /** Thrown when schema validation fails after all retries exhausted */
4374
- declare class VerifyError extends AxlError {
4375
- readonly lastOutput: unknown;
4376
- readonly zodError: ZodError;
4377
- readonly retries: number;
4378
- constructor(lastOutput: unknown, zodError: ZodError, retries: number);
4379
- }
4380
- /** Thrown when quorum is not met in spawn */
4381
- declare class QuorumNotMet extends AxlError {
4382
- readonly results: Result<unknown>[];
4383
- constructor(required: number, actual: number, results: Result<unknown>[]);
4384
- }
4385
- /** Thrown when vote cannot reach consensus */
4386
- declare class NoConsensus extends AxlError {
4387
- constructor(reason: string);
4388
- }
4389
- /** Thrown when an operation exceeds its timeout */
4390
- declare class TimeoutError extends AxlError {
4391
- constructor(operation: string, timeoutMs: number);
4392
- }
4393
- /** Thrown when a budget limit is exceeded */
4394
- declare class BudgetExceededError extends AxlError {
4395
- readonly limit: number;
4396
- readonly spent: number;
4397
- readonly policy: string;
4398
- constructor(limit: number, spent: number, policy: string);
4399
- }
4400
- /** Thrown when an agent exceeds its maximum number of tool-calling turns */
4401
- declare class MaxTurnsError extends AxlError {
4402
- readonly maxTurns: number;
4403
- constructor(operation: string, maxTurns: number);
4404
- }
4405
- /** Thrown when a guardrail blocks a request/response and the policy is 'throw'. */
4406
- declare class GuardrailError extends AxlError {
4407
- readonly guardrailType: 'input' | 'output';
4408
- readonly reason: string;
4409
- constructor(guardrailType: 'input' | 'output', reason: string);
4410
- }
4411
- /** Thrown when post-schema business rule validation fails after all retries exhausted */
4412
- declare class ValidationError extends AxlError {
4413
- readonly lastOutput: unknown;
4414
- readonly reason: string;
4415
- readonly retries: number;
4416
- constructor(lastOutput: unknown, reason: string, retries: number);
4417
- }
4418
- /** Internal: thrown when an agent tries to call a tool not in its ACL */
4419
- declare class ToolDenied extends AxlError {
4420
- readonly toolName: string;
4421
- readonly agentName: string;
4422
- constructor(toolName: string, agentName: string);
4423
- }
4707
+ /** Redact either persisted schema without reinterpreting its lifecycle. */
4708
+ declare function redactHistoricalEvent(event: HistoricalAxlEvent): HistoricalAxlEvent;
4424
4709
 
4425
4710
  /**
4426
4711
  * Typed provider errors + shared HTTP-failure classification.
@@ -4490,6 +4775,15 @@ declare class ProviderError extends AxlError {
4490
4775
  declare function isRetryableStatus(status: number): boolean;
4491
4776
 
4492
4777
  declare const OPENAI_PRICING: PricingTable;
4778
+ type DirectOpenAIPricingContext = {
4779
+ /** Only the canonical direct API endpoint has a usable catalog. */
4780
+ baseUrl?: string;
4781
+ request?: Record<string, unknown>;
4782
+ response?: {
4783
+ service_tier?: unknown;
4784
+ serviceTier?: unknown;
4785
+ };
4786
+ };
4493
4787
  /**
4494
4788
  * Estimate OpenAI call cost from token usage. Exact match first, then
4495
4789
  * longest-prefix match for versioned models (e.g. `gpt-4o-2024-05-13`).
@@ -4521,6 +4815,7 @@ declare class OpenAIProvider extends OpenAICompatibleProvider {
4521
4815
  baseUrl?: string;
4522
4816
  rateLimit?: RateLimitConfig;
4523
4817
  });
4818
+ protected computeCost(model: string, usage: ProviderResponse['usage'], _reportedCost: number | undefined, context?: DirectOpenAIPricingContext): number | undefined;
4524
4819
  }
4525
4820
 
4526
4821
  /**
@@ -4549,6 +4844,7 @@ declare class OpenAIResponsesProvider implements Provider {
4549
4844
  chat(messages: ChatMessage[], options: ChatOptions): Promise<ProviderResponse>;
4550
4845
  stream(messages: ChatMessage[], options: ChatOptions): AsyncGenerator<StreamChunk>;
4551
4846
  private buildRequestBody;
4847
+ private requestModel;
4552
4848
  private buildInput;
4553
4849
  /**
4554
4850
  * The Responses API uses `text.format` instead of `response_format`.
@@ -4607,6 +4903,7 @@ declare class AnthropicProvider implements Provider {
4607
4903
  * - tool messages (tool results) -> user messages with tool_result content blocks
4608
4904
  */
4609
4905
  private mapMessages;
4906
+ private getReplayedThinkingBlocks;
4610
4907
  /**
4611
4908
  * Merge consecutive messages with the same role into a single message.
4612
4909
  * This handles cases where multiple tool_result blocks need to be in one user message.
@@ -4667,6 +4964,11 @@ declare class GeminiProvider implements Provider {
4667
4964
  stream(messages: ChatMessage[], options: ChatOptions): AsyncGenerator<StreamChunk>;
4668
4965
  private buildHeaders;
4669
4966
  private extractErrorMessage;
4967
+ private pricingContext;
4968
+ private requestModel;
4969
+ private assertSafeGemini3Continuation;
4970
+ private isTextOnlyClientRequest;
4971
+ private isNonTextGeminiPart;
4670
4972
  private buildRequestBody;
4671
4973
  /**
4672
4974
  * Map OpenAI-format ChatMessages to Gemini content format.
@@ -4696,6 +4998,7 @@ declare class GeminiProvider implements Provider {
4696
4998
  private mapToolChoice;
4697
4999
  private mapToolDefinition;
4698
5000
  private parseResponse;
5001
+ private isTextOnlyGeminiResponse;
4699
5002
  private parseSSEStream;
4700
5003
  }
4701
5004
 
@@ -4705,9 +5008,9 @@ declare class GeminiProvider implements Provider {
4705
5008
  * - Reasoning is the unified `reasoning` object (`{ effort }` XOR `{ max_tokens }`,
4706
5009
  * or `{ enabled: false }`); reasoning text comes back in `message.reasoning`
4707
5010
  * with a structured `reasoning_details[]` we round-trip on tool-call turns.
4708
- * - Cost is provider-reported: `usage: { include: true }` makes OpenRouter return
4709
- * `usage.cost` (USD), so Axl keeps cost-as-a-primitive working across the whole
4710
- * catalog where a static table never could.
5011
+ * - Cost is provider-reported in `usage.cost` (USD), so Axl keeps
5012
+ * cost-as-a-primitive working across the whole catalog where a static table
5013
+ * never could. OpenRouter now returns it automatically; no request opt-in.
4711
5014
  * - Model ids are `vendor/model` slugs (e.g. `anthropic/claude-opus-4.7`); the
4712
5015
  * registry's first-colon split keeps `openrouter:anthropic/claude-…` intact.
4713
5016
  *
@@ -4729,20 +5032,17 @@ declare const OPENROUTER_PROFILE: ProviderProfile;
4729
5032
  * Entra/AAD bearer-token auth uses the async key callback plus an `authHeader:
4730
5033
  * 'bearer'` override.
4731
5034
  *
4732
- * Azure serves OpenAI models, so the OpenAI reasoning logic and pricing table
4733
- * are reused. Caveat: deployment names are arbitrary, so o-series/GPT-5
4734
- * detection and pricing only fire when the deployment is named after the model;
4735
- * otherwise effort is a no-op and cost is `undefined` (honest, not a fake $0).
5035
+ * Azure can share OpenAI's wire reasoning behavior, but never its direct-API
5036
+ * price catalog: model meters, deployment types, regions, and agreements vary.
4736
5037
  */
4737
5038
  declare const AZURE_PROFILE: ProviderProfile;
4738
5039
 
4739
5040
  /**
4740
- * xAI (Grok). OpenAI-compatible at `https://api.x.ai/v1`.
5041
+ * xAI (Grok) Chat Completions at `https://api.x.ai/v1`.
4741
5042
  *
4742
- * - `reasoning_effort` (`low` for effort `low`, else `high`) for grok-3-mini;
4743
- * omitted for grok-4* (auto-reasoning) and non-reasoning models.
4744
- * - `stop` + penalty params are stripped on reasoning models (they 400).
4745
- * Penalties aren't engine-computed, so they only matter if a user adds them.
5043
+ * Pricing is the exact response total in `usage.cost_in_usd_ticks`; it already
5044
+ * includes cache, service-tier, and server-side-tool charges. Grok 4.20
5045
+ * multi-agent is Responses-only, so it deliberately has no Chat descriptor.
4746
5046
  */
4747
5047
  declare const XAI_PROFILE: ProviderProfile;
4748
5048
 
@@ -4852,9 +5152,9 @@ declare class MemoryStore implements StateStore {
4852
5152
  value: unknown;
4853
5153
  }>>;
4854
5154
  deleteMemory(scope: string, key: string): Promise<void>;
4855
- saveExecution(execution: ExecutionInfo): Promise<void>;
4856
- getExecution(executionId: string): Promise<ExecutionInfo | null>;
4857
- listExecutions(limit?: number): Promise<ExecutionInfo[]>;
5155
+ saveExecution(execution: HistoricalExecutionInfo): Promise<void>;
5156
+ getExecution(executionId: string): Promise<HistoricalExecutionInfo | null>;
5157
+ listExecutions(limit?: number): Promise<HistoricalExecutionInfo[]>;
4858
5158
  deleteExecution(executionId: string): Promise<boolean>;
4859
5159
  saveEvalResult(entry: EvalHistoryEntry): Promise<void>;
4860
5160
  listEvalResults(limit?: number): Promise<EvalHistoryEntry[]>;
@@ -4864,7 +5164,7 @@ declare class MemoryStore implements StateStore {
4864
5164
  appendStreamingEvents(executionId: string, events: AxlEvent[]): Promise<void>;
4865
5165
  finalizeStreamingEvents(executionId: string): Promise<void>;
4866
5166
  listStreamingExecutions(): Promise<string[]>;
4867
- getStreamingEvents(executionId: string): Promise<AxlEvent[]>;
5167
+ getStreamingEvents(executionId: string): Promise<HistoricalAxlEvent[]>;
4868
5168
  close(): Promise<void>;
4869
5169
  deleteCheckpoints(executionId: string): Promise<void>;
4870
5170
  private persistAwaitHumanState;
@@ -4905,6 +5205,10 @@ declare class SQLiteStore implements StateStore {
4905
5205
  * column (TEXT, nullable, JSON-serialized) so caller-supplied
4906
5206
  * `ExecuteOptions.metadata` round-trips through history. Existing
4907
5207
  * rows get `NULL`, deserialized as `metadata: undefined`.
5208
+ * - v4 (event schema): add `execution_history.event_schema_version`.
5209
+ * Existing rows remain `NULL`, the documented v1 sentinel.
5210
+ * - v5 (observation completeness): add `execution_history.observation`.
5211
+ * Existing rows remain `NULL`, meaning they predate the contract.
4908
5212
  *
4909
5213
  * Applied BEFORE `initTables()` so the subsequent `CREATE TABLE
4910
5214
  * IF NOT EXISTS` runs against the post-migration column name. Fresh
@@ -4936,9 +5240,9 @@ declare class SQLiteStore implements StateStore {
4936
5240
  saveExecutionState(executionId: string, state: ExecutionState): Promise<void>;
4937
5241
  getExecutionState(executionId: string): Promise<ExecutionState | null>;
4938
5242
  listPendingExecutions(): Promise<string[]>;
4939
- saveExecution(execution: ExecutionInfo): Promise<void>;
4940
- getExecution(executionId: string): Promise<ExecutionInfo | null>;
4941
- listExecutions(limit?: number): Promise<ExecutionInfo[]>;
5243
+ saveExecution(execution: HistoricalExecutionInfo): Promise<void>;
5244
+ getExecution(executionId: string): Promise<HistoricalExecutionInfo | null>;
5245
+ listExecutions(limit?: number): Promise<HistoricalExecutionInfo[]>;
4942
5246
  deleteExecution(executionId: string): Promise<boolean>;
4943
5247
  saveEvalResult(entry: EvalHistoryEntry): Promise<void>;
4944
5248
  listEvalResults(limit?: number): Promise<EvalHistoryEntry[]>;
@@ -5167,9 +5471,9 @@ declare class RedisStore implements StateStore {
5167
5471
  value: unknown;
5168
5472
  }>>;
5169
5473
  deleteMemory(scope: string, key: string): Promise<void>;
5170
- saveExecution(execution: ExecutionInfo): Promise<void>;
5171
- getExecution(executionId: string): Promise<ExecutionInfo | null>;
5172
- listExecutions(limit?: number): Promise<ExecutionInfo[]>;
5474
+ saveExecution(execution: HistoricalExecutionInfo): Promise<void>;
5475
+ getExecution(executionId: string): Promise<HistoricalExecutionInfo | null>;
5476
+ listExecutions(limit?: number): Promise<HistoricalExecutionInfo[]>;
5173
5477
  deleteExecution(executionId: string): Promise<boolean>;
5174
5478
  saveEvalResult(entry: EvalHistoryEntry): Promise<void>;
5175
5479
  listEvalResults(limit?: number): Promise<EvalHistoryEntry[]>;
@@ -5186,7 +5490,7 @@ declare class RedisStore implements StateStore {
5186
5490
  appendStreamingEvents(executionId: string, events: AxlEvent[]): Promise<void>;
5187
5491
  finalizeStreamingEvents(executionId: string): Promise<void>;
5188
5492
  listStreamingExecutions(): Promise<string[]>;
5189
- getStreamingEvents(executionId: string): Promise<AxlEvent[]>;
5493
+ getStreamingEvents(executionId: string): Promise<HistoricalAxlEvent[]>;
5190
5494
  /** Close the Redis connection. */
5191
5495
  close(): Promise<void>;
5192
5496
  deleteCheckpoints(executionId: string): Promise<void>;
@@ -5258,4 +5562,4 @@ declare class NoopSpanManager implements SpanManager {
5258
5562
  */
5259
5563
  declare function createSpanManager(config?: TelemetryConfig): Promise<SpanManager>;
5260
5564
 
5261
- export { AXL_EVENT_TYPES, AZURE_PROFILE, type Agent, type AgentCallEndData, type AgentCallInfo, type AgentCallParams, type AgentCallStartData, type AgentConfig, AnthropicProvider, type AnyWorkflow, type ApiKeySource, type AskOptions, type AskScoped, type AuthHeader, type AwaitHumanData, type AwaitHumanOptions, type AwaitHumanResolvedData, type AxlConfig, AxlError, type AxlEvent, type AxlEventBase, AxlEventBus, type AxlEventOf, type AxlEventType, AxlRuntime, AxlStream, BEDROCK_PROFILE, BUILTIN_PROFILES, BudgetExceededError, type BudgetOptions, type BudgetResult, CONFIG_CANDIDATES, COST_BEARING_LEAF_TYPES, type CallbackMeta, type CapabilityFlags, type ChatMessage, type ChatOptions, type CheckpointEventData, type CoalescedPartialObject, type CreateContextOptions, DEEPSEEK_PROFILE, type DelegateData, type DelegateOptions, type Effort, type EmbedResult, type EmbedUsage, type Embedder, type EvalExecuteWorkflow, type EvalHistoryEntry, type EventStreamOptions, EventStreamOverflowError, type ExecuteOptions, type ExecutionInfo, type ExecutionState, GROQ_PROFILE, GeminiProvider, type GuardrailBlockHandler, type GuardrailData, GuardrailError, type GuardrailResult, type GuardrailsConfig, type HandoffDescriptor, type HandoffRecord, type HandoffReturnData, type HandoffStartData, type HumanDecision, InMemoryVectorStore, type InputGuardrail, LLAMACPP_PROFILE, LMSTUDIO_PROFILE, MISTRAL_PROFILE, type MapOptions, MaxTurnsError, McpManager, type McpServer, type McpServerConfig, type McpToolDefinition, type McpToolResult, type MemoryConfig, type MemoryEventData, MemoryManager, MemoryStore, NoConsensus, NoopSpanManager, OLLAMA_PROFILE, OPENAI_PRICING, OPENAI_PROFILE, OPENROUTER_PROFILE, type OpenAICompatibleOptions, OpenAICompatibleProvider, OpenAIEmbedder, OpenAIProvider, OpenAIResponsesProvider, type OutputGuardrail, type OutputValidator, type PendingDecision, type PerModel, type PricingSource, type PricingTable, type Provider, type ProviderAdapter, ProviderError, type ProviderProfile, ProviderRegistry, type ProviderResponse, QuorumNotMet, REDACTED, REDACTION_RULES, type RaceOptions, type RateLimitConfig, RateLimiter, type ReasoningCapture, type ReasoningEmit, type ReasoningProfile, type ReasoningRoundTrip, type RecallOptions, type RecallResult, RedisStore, type RememberOptions, type RememberResult, type ResolvedThinkingOptions, type Result, type RetryPolicy, SGLANG_PROFILE, SQLiteStore, type SchemaCheckData, type SchemaDiagnosticData, type SchemaPromptOption, Session, type SessionOptions, type SpanHandle, type SpanManager, type SpawnOptions, SqliteVectorStore, type StateStore, type StreamChunk, type StringDeltaData, type StringStreamEvent, type StringStreamFilter, type TelemetryConfig, ThinkTagScanner, TimeoutError, type Tool, type ToolApprovalData, type ToolCallData, type ToolCallMessage, type ToolCallStartData, type ToolChoice, type ToolConfig, ToolDenied, type ToolDeniedData, type ToolHooks, type ToolModelOutput, ToolModelOutputError, VLLM_PROFILE, type ValidateData, type ValidateResult, ValidationError, type VectorEntry, type VectorResult, type VectorStore, type VerifyData, VerifyError, type VerifyOptions, type VerifyRetry, type VoteOptions, type Workflow, type WorkflowConfig, WorkflowContext, type WorkflowContextInit, type WorkflowEndData, type WorkflowStartData, XAI_PROFILE, agent, createSpanManager, defineConfig, estimateOpenAICost, eventCostContribution, expandGlob, extractJson, extractThinkTags, findConfig, hasPositiveTokens, importModule, isCostBearingLeaf, isRetryableStatus, isRootLevel, isUnpricedLeaf, isUsableCost, needsTsxLoader, openaiReasoningEmit, parsePartialJson, pickDefault, pickExport, priceFromTable, reasoningEffortEmit, reasoningObjectEmit, redactEvent, registerConditions, resolveApiKey, resolvePerModel, resolveRuntime, resolveThinkingOptions, stringStreamFromEvents, tool, workflow, zodToJsonSchema };
5565
+ export { AXL_EVENT_TYPES, AXL_EVENT_TYPES_V2, AXL_TOOL_LIFECYCLE_TYPES_V2, AZURE_PROFILE, type Agent, type AgentCallEndData, type AgentCallInfo, type AgentCallParams, type AgentCallStartData, type AgentConfig, AnthropicProvider, type AnyWorkflow, type ApiKeySource, type AskOptions, type AskScoped, type AuthHeader, type AwaitHumanData, type AwaitHumanOptions, type AwaitHumanResolvedData, type AxlConfig, AxlError, type AxlEvent, type AxlEventBase, AxlEventBus, type AxlEventOf, type AxlEventType, type AxlEventV2, type AxlEventV2Of, AxlRuntime, AxlStream, BEDROCK_PROFILE, BUILTIN_PROFILES, BudgetExceededError, type BudgetOptions, type BudgetResult, CONFIG_CANDIDATES, COST_BEARING_LEAF_TYPES, type CapabilityFlags, type ChatMessage, type ChatOptions, type CheckpointEventData, type CoalescedPartialObject, type CreateContextOptions, DEEPSEEK_PROFILE, type DecisionCleanupFailedEvent, type DelegateData, type DelegateOptions, type Effort, type EmbedResult, type EmbedUsage, type Embedder, type EvalExecuteWorkflow, type EvalHistoryEntry, type EventStreamOptions, EventStreamOverflowError, type ExecuteOptions, type ExecutionInfo, type ExecutionInfoV1, type ExecutionInfoV2, type ExecutionState, GROQ_PROFILE, GeminiProvider, type GuardrailBlockHandler, type GuardrailData, GuardrailError, type GuardrailResult, type GuardrailsConfig, type HandoffDescriptor, type HandoffRecord, type HandoffReturnData, type HandoffStartData, type HistoricalAxlEvent, type HistoricalExecutionInfo, type HumanDecision, InMemoryVectorStore, type InputGuardrail, LLAMACPP_PROFILE, LMSTUDIO_PROFILE, type LegacyAxlEventV1, type LegacyExecutionInfoV1, MISTRAL_PROFILE, type MapOptions, MaxTurnsError, McpManager, type McpServer, type McpServerConfig, type McpToolDefinition, type McpToolResult, type MemoryConfig, type MemoryEventData, MemoryManager, MemoryStore, NoConsensus, NoopSpanManager, OLLAMA_PROFILE, OPENAI_PRICING, OPENAI_PROFILE, OPENROUTER_PROFILE, type ObservationStatus, type OpenAICompatibleOptions, OpenAICompatibleProvider, OpenAIEmbedder, OpenAIProvider, OpenAIResponsesProvider, type OutputGuardrail, type OutputValidator, type PendingDecision, type PerModel, type PricingSource, type PricingTable, type Provider, type ProviderAdapter, ProviderError, type ProviderProfile, ProviderRegistry, type ProviderResponse, QuorumNotMet, REDACTED, REDACTION_RULES, type RaceOptions, type RateLimitConfig, RateLimiter, type ReasoningCapture, type ReasoningEmit, type ReasoningProfile, type ReasoningRoundTrip, type RecallOptions, type RecallResult, RedisStore, type RememberOptions, type RememberResult, type ResolvedThinkingOptions, type Result, type RetryPolicy, SGLANG_PROFILE, SQLiteStore, type SchemaCheckData, type SchemaDiagnosticData, type SchemaPromptOption, Session, type SessionOptions, type SpanHandle, type SpanManager, type SpawnOptions, SqliteVectorStore, type StateStore, type StreamChunk, type StringDeltaData, type StringStreamEvent, type StringStreamFilter, type TelemetryConfig, ThinkTagScanner, TimeoutError, type Tool, type ToolApprovalData, type ToolArgumentIssue, type ToolCallCancellation, type ToolCallData, type ToolCallEndData, type ToolCallFailure, type ToolCallMessage, type ToolCallOutcome, type ToolCallRejectedData, type ToolCallRejectedEvent, type ToolCallStartData, type ToolCallStartDataV2, type ToolChoice, type ToolConfig, type ToolDeniedData, type ToolEventError, ToolFailure, type ToolFailureConstructor, type ToolFailureOptions, type ToolHooks, type ToolLifecycleEventV2, type ToolModelOutput, ToolModelOutputError, UnsupportedEventSchemaVersionError, VLLM_PROFILE, type ValidateData, type ValidateResult, ValidationError, type VectorEntry, type VectorResult, type VectorStore, type VerifyData, VerifyError, type VerifyOptions, type VerifyRetry, type VoteOptions, type Workflow, type WorkflowConfig, WorkflowContext, type WorkflowContextInit, type WorkflowEndData, type WorkflowStartData, XAI_PROFILE, agent, createSpanManager, defineConfig, estimateOpenAICost, eventCostContribution, expandGlob, extractJson, extractThinkTags, findConfig, getEventSchemaVersion, getExecutionEventSchemaVersion, hasPositiveTokens, importModule, isCostBearingLeaf, isRetryableStatus, isRootLevel, isUnpricedLeaf, isUsableCost, needsTsxLoader, normalizeStoredExecution, openaiReasoningEmit, parsePartialJson, pickDefault, pickExport, priceFromTable, reasoningEffortEmit, reasoningObjectEmit, redactEvent, redactHistoricalEvent, registerConditions, resolveApiKey, resolvePerModel, resolveRuntime, resolveThinkingOptions, stringStreamFromEvents, tool, workflow, zodToJsonSchema };