@axlsdk/axl 0.17.2 → 0.17.4
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/README.md +63 -1
- package/dist/index.cjs +1110 -370
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +559 -55
- package/dist/index.d.ts +559 -55
- package/dist/index.js +1108 -370
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -863,6 +863,18 @@ type ChatMessage = {
|
|
|
863
863
|
tool_call_id?: string;
|
|
864
864
|
/** Provider-specific opaque metadata that must round-trip through conversation history. */
|
|
865
865
|
providerMetadata?: Record<string, unknown>;
|
|
866
|
+
/** Name of the agent that produced this message. Populated on `assistant`
|
|
867
|
+
* messages committed via `ctx.ask()`; absent on `user` messages and on
|
|
868
|
+
* assistant messages pushed by external callers (e.g., the
|
|
869
|
+
* `Session.send` fallback when no agent context is available).
|
|
870
|
+
*
|
|
871
|
+
* This is observability metadata only — it is NOT sent on the wire to
|
|
872
|
+
* any provider. Provider adapters cherry-pick the fields they need
|
|
873
|
+
* (`role`, `content`, `name`, `tool_calls`, `tool_call_id`) and ignore
|
|
874
|
+
* the rest. Future per-agent history filtering may consume this field
|
|
875
|
+
* (the option name and shape are not yet stable); today it is purely
|
|
876
|
+
* informational. */
|
|
877
|
+
agent?: string;
|
|
866
878
|
};
|
|
867
879
|
type ToolCallMessage = {
|
|
868
880
|
id: string;
|
|
@@ -949,6 +961,290 @@ type Agent = {
|
|
|
949
961
|
*/
|
|
950
962
|
declare function agent(config: AgentConfig): Agent;
|
|
951
963
|
|
|
964
|
+
/** Options shared between `AxlEventBus` (and therefore `AxlStream` and
|
|
965
|
+
* `ctx.events`). Controls the overflow safety net on the iterator queue. */
|
|
966
|
+
interface EventStreamOptions {
|
|
967
|
+
/** Soft cap on the number of events held in the iterator queue while
|
|
968
|
+
* waiting for a consumer. Terminal events (`done`, `error`,
|
|
969
|
+
* `workflow_end`) are exempt and always pass through. Default 10_000.
|
|
970
|
+
*
|
|
971
|
+
* Set to `Infinity` to disable the cap (matches pre-0.x behavior). */
|
|
972
|
+
maxQueued?: number;
|
|
973
|
+
/** Policy when an event arrives and the queue is at `maxQueued`.
|
|
974
|
+
*
|
|
975
|
+
* - `'drop-oldest-non-terminal'` (default): scan the queue head-to-tail,
|
|
976
|
+
* splice out the oldest non-terminal event, push the new one. The first
|
|
977
|
+
* drop per bus instance fires a one-shot `console.warn` so saturating
|
|
978
|
+
* consumers see the signal without log spam.
|
|
979
|
+
* - `'throw'`: throw an `EventStreamOverflowError` at the producer call
|
|
980
|
+
* site. **This will fail the active workflow** — `_push` is called
|
|
981
|
+
* from `WorkflowContext.emitEvent`, which runs inside `ctx.ask()` /
|
|
982
|
+
* `runtime.execute()`. The throw unwinds the agent loop and the
|
|
983
|
+
* `runtime.execute()` (or `runtime.stream()`) promise rejects with
|
|
984
|
+
* the typed error. Useful in tests or strict environments where
|
|
985
|
+
* silent drop would mask a problem; not the right default for
|
|
986
|
+
* production where a slow consumer should degrade gracefully rather
|
|
987
|
+
* than abort the workflow. Catch with `instanceof
|
|
988
|
+
* EventStreamOverflowError` to distinguish from other workflow
|
|
989
|
+
* errors.
|
|
990
|
+
*
|
|
991
|
+
* `'block'` is intentionally absent: `_push` is synchronous and there's no
|
|
992
|
+
* producer to suspend. To bound queue growth via backpressure, the
|
|
993
|
+
* producer side has to model it explicitly (out of scope for v1). */
|
|
994
|
+
onOverflow?: 'drop-oldest-non-terminal' | 'throw';
|
|
995
|
+
}
|
|
996
|
+
/**
|
|
997
|
+
* The shape yielded by `AxlEventBus.partialObjects` (and `AxlStream.partialObjects`).
|
|
998
|
+
* Coalesced latest-per-`askId` snapshot of a `partial_object` event.
|
|
999
|
+
*
|
|
1000
|
+
* `attempt` is the 1-indexed attempt number from the underlying
|
|
1001
|
+
* `partial_object` event — pinned in the public type so consumers can
|
|
1002
|
+
* conditionally render a "regenerating" indicator when it jumps from 1
|
|
1003
|
+
* to 2. Failed attempts are dropped from the view via the
|
|
1004
|
+
* `pipeline(failed)` listener before they leak across the retry
|
|
1005
|
+
* boundary.
|
|
1006
|
+
*/
|
|
1007
|
+
type CoalescedPartialObject = {
|
|
1008
|
+
askId: string;
|
|
1009
|
+
agent?: string;
|
|
1010
|
+
object: unknown;
|
|
1011
|
+
attempt: number;
|
|
1012
|
+
};
|
|
1013
|
+
/**
|
|
1014
|
+
* Thrown when an `AxlEventBus` queue exceeds `maxQueued` and `onOverflow`
|
|
1015
|
+
* is set to `'throw'`. Surfaced as a typed error so the runtime's emit
|
|
1016
|
+
* pipeline can distinguish a legitimate overflow signal (which must
|
|
1017
|
+
* propagate to fail the workflow) from a buggy trace-listener exception
|
|
1018
|
+
* (which gets swallowed).
|
|
1019
|
+
*
|
|
1020
|
+
* Consumers using `instanceof` to handle overflow specifically:
|
|
1021
|
+
* ```typescript
|
|
1022
|
+
* try {
|
|
1023
|
+
* await runtime.execute('wf', input, { events: { onOverflow: 'throw' } });
|
|
1024
|
+
* } catch (err) {
|
|
1025
|
+
* if (err instanceof EventStreamOverflowError) {
|
|
1026
|
+
* // overflow — back off, retry, or surface to user
|
|
1027
|
+
* }
|
|
1028
|
+
* }
|
|
1029
|
+
* ```
|
|
1030
|
+
*/
|
|
1031
|
+
declare class EventStreamOverflowError extends Error {
|
|
1032
|
+
readonly maxQueued: number;
|
|
1033
|
+
readonly eventType: string;
|
|
1034
|
+
constructor(maxQueued: number, eventType: string);
|
|
1035
|
+
}
|
|
1036
|
+
/**
|
|
1037
|
+
* Iterable + EventEmitter event bus carrying `AxlEvent`.
|
|
1038
|
+
*
|
|
1039
|
+
* Public observation surface for `ctx.events` and the underlying machinery
|
|
1040
|
+
* for `AxlStream`. Provides:
|
|
1041
|
+
*
|
|
1042
|
+
* - `for await (const e of bus)` — sequential iteration over every pushed event
|
|
1043
|
+
* - `.on('agent_call_end', fn)` / `.off(...)` — EventEmitter style, gated on
|
|
1044
|
+
* `AXL_EVENT_TYPES` so unknown event names cannot be subscribed
|
|
1045
|
+
* - Curated views: `.text` (root-only token chunks), `.lifecycle` (structural
|
|
1046
|
+
* events only), `.textByAsk` (per-ask token chunks)
|
|
1047
|
+
*
|
|
1048
|
+
* Multiple async iterators on the same bus race for the same FIFO queue —
|
|
1049
|
+
* iterating both `bus` and `bus.text` (or `bus.lifecycle` / `bus.textByAsk`)
|
|
1050
|
+
* concurrently will see each event at most once because the views pull from
|
|
1051
|
+
* the same underlying iterator. For two independent observers, attach
|
|
1052
|
+
* `.on(type, handler)` listeners instead — those each receive every event.
|
|
1053
|
+
*
|
|
1054
|
+
* Multiple `.on()` listeners on the same event type each receive every
|
|
1055
|
+
* matching event. Subscriptions to non-`AxlEventType` names are silently
|
|
1056
|
+
* dropped (the bus emits no other event names).
|
|
1057
|
+
*/
|
|
1058
|
+
declare class AxlEventBus implements AsyncIterable<AxlEvent> {
|
|
1059
|
+
protected readonly bus: EventEmitter<any>;
|
|
1060
|
+
protected eventQueue: AxlEvent[];
|
|
1061
|
+
protected waiters: Array<(value: IteratorResult<AxlEvent>) => void>;
|
|
1062
|
+
protected finished: boolean;
|
|
1063
|
+
private readonly maxQueued;
|
|
1064
|
+
private readonly onOverflow;
|
|
1065
|
+
private overflowWarned;
|
|
1066
|
+
/** Callbacks fired exactly once when `_finish()` is called. Used by
|
|
1067
|
+
* curated views (e.g., `partialObjects`) that are listener-based and
|
|
1068
|
+
* need a termination signal independent of any synthetic `done` event. */
|
|
1069
|
+
private finishCallbacks;
|
|
1070
|
+
/**
|
|
1071
|
+
* Latest coalesced partial-object snapshot per `askId`, maintained on
|
|
1072
|
+
* every `_push` regardless of consumer state. Seeds the
|
|
1073
|
+
* `partialObjects` view's `pending` map at subscription time so a
|
|
1074
|
+
* late subscriber recovers the most recent state per ask even if
|
|
1075
|
+
* earlier `partial_object` events were already delivered to a prior
|
|
1076
|
+
* iterator's waiter (and thus removed from `eventQueue`).
|
|
1077
|
+
*
|
|
1078
|
+
* The pre-fix snapshot walked `eventQueue` directly — that misses
|
|
1079
|
+
* events already drained by past consumers. The map walks past
|
|
1080
|
+
* `_push` calls instead, which is the actual definition of "what's
|
|
1081
|
+
* the latest partial per ask". `pipeline(status: 'failed')` clears
|
|
1082
|
+
* the entry for the affected askId so a discarded attempt can't
|
|
1083
|
+
* surface to a future subscriber.
|
|
1084
|
+
*
|
|
1085
|
+
* Memory bound: O(active asks holding a pending partial). Cleared
|
|
1086
|
+
* on `pipeline(failed)` (per ask) and otherwise grows with the
|
|
1087
|
+
* number of distinct askIds that emitted at least one partial.
|
|
1088
|
+
*/
|
|
1089
|
+
private latestPartialByAsk;
|
|
1090
|
+
/**
|
|
1091
|
+
* Hook fired when an iterator obtained from `[Symbol.asyncIterator]`
|
|
1092
|
+
* is `await using`-disposed. Set via the second constructor argument.
|
|
1093
|
+
* Used by `AxlStream` to call `Readable.destroy()` on its owning
|
|
1094
|
+
* stream so disposing the iterator cascades to the Readable contract.
|
|
1095
|
+
* Set once at construction; never reassigned.
|
|
1096
|
+
*
|
|
1097
|
+
* Replaces the previous `AxlStreamEventBus extends AxlEventBus`
|
|
1098
|
+
* subclass — composition over inheritance for what is essentially a
|
|
1099
|
+
* single function-pointer hook.
|
|
1100
|
+
*
|
|
1101
|
+
* @internal
|
|
1102
|
+
*/
|
|
1103
|
+
protected readonly onIteratorDispose?: () => void;
|
|
1104
|
+
/**
|
|
1105
|
+
* @param options Public stream options (queue cap, overflow policy).
|
|
1106
|
+
* @param onIteratorDispose @internal Invoked from `_disposeIterator`
|
|
1107
|
+
* when an iterator obtained from this bus is `await using`-disposed.
|
|
1108
|
+
* Used by `AxlStream` to forward to `Readable.destroy()`.
|
|
1109
|
+
*/
|
|
1110
|
+
constructor(options?: EventStreamOptions, onIteratorDispose?: () => void);
|
|
1111
|
+
private unknownEventWarned;
|
|
1112
|
+
/** Subscribe to an `AxlEvent` variant by type. Names outside
|
|
1113
|
+
* `AXL_EVENT_TYPES` are dropped (the bus only emits those names) but
|
|
1114
|
+
* the first such call per bus instance fires a one-shot
|
|
1115
|
+
* `console.warn` so a typo (`'agent_call_ended'`) doesn't silently
|
|
1116
|
+
* vanish. Subclasses (e.g., `AxlStream`) pre-filter via
|
|
1117
|
+
* `knowsEventName` so their own routing for non-`AxlEvent` names
|
|
1118
|
+
* like `'close'` doesn't trip the warn. */
|
|
1119
|
+
on<T extends AxlEventType>(event: T, handler: (e: AxlEventOf<T>) => void): this;
|
|
1120
|
+
on(event: string, handler: (event: any) => void): this;
|
|
1121
|
+
off<T extends AxlEventType>(event: T, handler: (e: AxlEventOf<T>) => void): this;
|
|
1122
|
+
off(event: string, handler: (event: any) => void): this;
|
|
1123
|
+
/** One-shot warn on subscribe/unsubscribe for an event name outside
|
|
1124
|
+
* `AXL_EVENT_TYPES`. Pre-fix this branch silently dropped, which
|
|
1125
|
+
* meant a typo like `'agent_call_ended'` produced no signal. */
|
|
1126
|
+
private warnUnknownEventName;
|
|
1127
|
+
[Symbol.asyncIterator](): {
|
|
1128
|
+
next: () => Promise<IteratorResult<AxlEvent>>;
|
|
1129
|
+
return: () => Promise<IteratorResult<AxlEvent>>;
|
|
1130
|
+
[Symbol.asyncIterator](): /*elided*/ any;
|
|
1131
|
+
[Symbol.asyncDispose]: () => Promise<void>;
|
|
1132
|
+
};
|
|
1133
|
+
/** Hook for iterator disposal. Calls the constructor-supplied
|
|
1134
|
+
* `onIteratorDispose` callback if any. The default behavior is a
|
|
1135
|
+
* no-op when no callback was passed — a plain bus has no
|
|
1136
|
+
* Node-stream resource to release. */
|
|
1137
|
+
protected _disposeIterator(): Promise<void>;
|
|
1138
|
+
/** Iterator over root-only `token` chunks. Skips nested-ask tokens
|
|
1139
|
+
* (consumers wanting nested can iterate the full bus and filter on
|
|
1140
|
+
* `event.depth >= 1`). */
|
|
1141
|
+
get text(): AsyncIterable<string>;
|
|
1142
|
+
/** Iterator over `{ askId, agent?, text }` for every token across root and
|
|
1143
|
+
* nested asks. Useful for split-pane UIs that render each sub-agent's
|
|
1144
|
+
* output in its own lane. `agent` is undefined when the token was emitted
|
|
1145
|
+
* outside any ask (rare — synthesized test fixtures). */
|
|
1146
|
+
get textByAsk(): AsyncIterable<{
|
|
1147
|
+
askId: string;
|
|
1148
|
+
agent?: string;
|
|
1149
|
+
text: string;
|
|
1150
|
+
}>;
|
|
1151
|
+
/**
|
|
1152
|
+
* Coalescing iterator over `partial_object` events — yields the latest
|
|
1153
|
+
* payload per `askId`. When a newer `partial_object` arrives for an
|
|
1154
|
+
* `askId` while the consumer is busy, the older value is silently
|
|
1155
|
+
* superseded; the consumer sees only the most recent state per ask on
|
|
1156
|
+
* its next `.next()` await.
|
|
1157
|
+
*
|
|
1158
|
+
* Memory bound: O(active asks holding a pending partial), not O(events).
|
|
1159
|
+
* This is what UIs streaming structured output actually want — rendering
|
|
1160
|
+
* every intermediate snapshot just to overwrite it ms later is wasted
|
|
1161
|
+
* work, and unbounded queueing of intermediate JSON snapshots is the
|
|
1162
|
+
* memory-pressure scenario this view is designed to avoid. In practice
|
|
1163
|
+
* "active asks" is small (1-10 even for fan-out workflows); a workflow
|
|
1164
|
+
* fanning out to 10k concurrent asks each producing partials would
|
|
1165
|
+
* accumulate ≈10k pending entries (~1 MB), which is the realistic
|
|
1166
|
+
* ceiling for this view.
|
|
1167
|
+
*
|
|
1168
|
+
* Schema-retry awareness: each yielded value carries the 1-indexed
|
|
1169
|
+
* `attempt` field from the underlying `partial_object` event. When a
|
|
1170
|
+
* schema check fails and the agent retries, the runtime emits
|
|
1171
|
+
* `pipeline(status: 'failed')`; this view drops any undrained pending
|
|
1172
|
+
* partial for the affected ask so the consumer never sees stale
|
|
1173
|
+
* attempt-N snapshots after attempt-N+1 has begun. Mirrors the
|
|
1174
|
+
* per-attempt buffer reset that `AxlStream.fullText` applies to
|
|
1175
|
+
* tokens. (Validate-stage and guardrail retries trigger the same
|
|
1176
|
+
* reset.)
|
|
1177
|
+
*
|
|
1178
|
+
* Malformed `partial_object` events (those missing `data.object`) are
|
|
1179
|
+
* silently filtered — the variant shape requires the field, so an
|
|
1180
|
+
* undefined value is a producer bug rather than a meaningful state.
|
|
1181
|
+
*
|
|
1182
|
+
* Implementation note: this is a listener-based view (subscribes to the
|
|
1183
|
+
* bus's `partial_object` channel via `.on()`), not an iterator-based
|
|
1184
|
+
* filter like `.text` / `.lifecycle` / `.textByAsk`. As a result it does
|
|
1185
|
+
* NOT race with the main async iterator — running `for await (const e of bus)`
|
|
1186
|
+
* concurrently with `for await (const p of bus.partialObjects)` works
|
|
1187
|
+
* cleanly (each `partial_object` event fires the listener AND queues for
|
|
1188
|
+
* iterators).
|
|
1189
|
+
*
|
|
1190
|
+
* Termination: yields any pending coalesced values first, then `done: true`
|
|
1191
|
+
* once the bus is finished (via `_finish()`).
|
|
1192
|
+
*/
|
|
1193
|
+
get partialObjects(): AsyncIterable<CoalescedPartialObject>;
|
|
1194
|
+
/** Iterator over structural lifecycle events only — skips per-token chatter
|
|
1195
|
+
* and progressive `partial_object` emissions. Useful for waterfall UIs
|
|
1196
|
+
* and any consumer that wants the "what happened" timeline. */
|
|
1197
|
+
get lifecycle(): AsyncIterable<AxlEvent>;
|
|
1198
|
+
/**
|
|
1199
|
+
* Push an event onto the bus. Emits on the typed channel (for `.on()`
|
|
1200
|
+
* subscribers) and queues for async iterators. No-op once `_finish()` has
|
|
1201
|
+
* been called.
|
|
1202
|
+
*
|
|
1203
|
+
* Subclasses (AxlStream) override to add token accounting and Readable
|
|
1204
|
+
* fan-out before delegating to this implementation.
|
|
1205
|
+
*
|
|
1206
|
+
* @internal — called by the runtime / WorkflowContext / AxlStream.
|
|
1207
|
+
*/
|
|
1208
|
+
_push(event: AxlEvent): void;
|
|
1209
|
+
/** Apply the overflow policy when the queue is at `maxQueued` and a
|
|
1210
|
+
* non-terminal event arrives. Terminal events bypass this path entirely
|
|
1211
|
+
* (checked by the caller). */
|
|
1212
|
+
private handleOverflow;
|
|
1213
|
+
/**
|
|
1214
|
+
* Mark the bus as finished. Wakes any pending iterators with `done: true`
|
|
1215
|
+
* and drops further `_push` calls. Idempotent.
|
|
1216
|
+
*
|
|
1217
|
+
* Does not synthesize a terminal `done` AxlEvent — callers (AxlStream) that
|
|
1218
|
+
* want one push it via `_push` before calling `_finish`.
|
|
1219
|
+
*
|
|
1220
|
+
* Late iterators that connect after `_finish()` still drain any events
|
|
1221
|
+
* remaining in `eventQueue` (the `next()` short-circuit in
|
|
1222
|
+
* `[Symbol.asyncIterator]` checks the queue before checking `finished`),
|
|
1223
|
+
* then receive `done: true`.
|
|
1224
|
+
*
|
|
1225
|
+
* @internal
|
|
1226
|
+
*/
|
|
1227
|
+
_finish(): void;
|
|
1228
|
+
/** Register a one-shot callback fired when `_finish()` is called.
|
|
1229
|
+
* Returns an unsubscribe function. If the bus is already finished,
|
|
1230
|
+
* the callback is invoked synchronously and the returned unsubscribe
|
|
1231
|
+
* is a no-op.
|
|
1232
|
+
*
|
|
1233
|
+
* Used by listener-based curated views (e.g., `partialObjects`) that
|
|
1234
|
+
* need a termination signal independent of any synthesized `done`
|
|
1235
|
+
* event. Iterator consumers don't need this — `[Symbol.asyncIterator]`
|
|
1236
|
+
* resolves with `done: true` automatically.
|
|
1237
|
+
*
|
|
1238
|
+
* @internal */
|
|
1239
|
+
_onFinish(cb: () => void): () => void;
|
|
1240
|
+
/** Whether `event` is one of the `AxlEventType` names this bus emits.
|
|
1241
|
+
* Subclasses (e.g., `AxlStream`) consult this to route AxlEvent names to
|
|
1242
|
+
* the bus and other names (`'close'`, `'data'`, ...) to a wider emitter. */
|
|
1243
|
+
knowsEventName(event: string): boolean;
|
|
1244
|
+
/** Whether `_finish()` has been called. */
|
|
1245
|
+
get isFinished(): boolean;
|
|
1246
|
+
}
|
|
1247
|
+
|
|
952
1248
|
/** A pending human decision awaiting resolution. */
|
|
953
1249
|
type PendingDecision = {
|
|
954
1250
|
executionId: string;
|
|
@@ -1522,6 +1818,22 @@ type WorkflowContextInit = {
|
|
|
1522
1818
|
}, meta: CallbackMeta) => void;
|
|
1523
1819
|
/** Callback fired after each ctx.ask() completes (once per ask invocation). */
|
|
1524
1820
|
onAgentCallComplete?: (call: AgentCallInfo) => void;
|
|
1821
|
+
/** Options for the lazy `ctx.events` `AxlEventBus`. Forwarded by
|
|
1822
|
+
* `runtime.createContext({ events })` / `runtime.execute(name, input,
|
|
1823
|
+
* { events })` / `runtime.stream(name, input, { events })`. If unset,
|
|
1824
|
+
* the bus uses its built-in defaults (`maxQueued: 10_000`,
|
|
1825
|
+
* `onOverflow: 'drop-oldest-non-terminal'`). Child contexts share the
|
|
1826
|
+
* parent's bus instance, so this option has no effect on
|
|
1827
|
+
* `createChildContext()` callers. */
|
|
1828
|
+
eventStreamOptions?: EventStreamOptions;
|
|
1829
|
+
/** Internal: shared mutable holder for the lazy `AxlEventBus`. Set by
|
|
1830
|
+
* `createChildContext` so parent + children read and write the same
|
|
1831
|
+
* slot — late allocation in the parent (after children exist) is
|
|
1832
|
+
* visible to those children, and child allocation is visible to the
|
|
1833
|
+
* parent. Direct callers should not pass this. */
|
|
1834
|
+
_busRef?: {
|
|
1835
|
+
current: AxlEventBus | undefined;
|
|
1836
|
+
};
|
|
1525
1837
|
/** Internal: shared auto-checkpoint counters. Set by `createChildContext`
|
|
1526
1838
|
* so parent + child share the same number space, preventing checkpoint
|
|
1527
1839
|
* store key collisions across nested `WorkflowContext` instances.
|
|
@@ -1602,6 +1914,90 @@ declare class WorkflowContext<TInput = unknown> {
|
|
|
1602
1914
|
private awaitHumanHandler?;
|
|
1603
1915
|
private onAgentStart?;
|
|
1604
1916
|
private onAgentCallComplete?;
|
|
1917
|
+
/** Shared mutable slot for the lazy `AxlEventBus`. The slot is shared
|
|
1918
|
+
* by reference across parent/child contexts so a late allocation
|
|
1919
|
+
* (consumer subscribes after a child context exists) is visible
|
|
1920
|
+
* everywhere. Until first access `_busRef.current` is undefined and
|
|
1921
|
+
* `emitEvent` skips the bus fan-out entirely (zero overhead for
|
|
1922
|
+
* contexts that never observe). */
|
|
1923
|
+
private readonly _busRef;
|
|
1924
|
+
private readonly _eventStreamOptions?;
|
|
1925
|
+
/** Removes the constructor-registered `'abort'` listener from
|
|
1926
|
+
* `this.signal` so a long-lived signal (e.g., a request-scoped or
|
|
1927
|
+
* process-wide signal reused across many `runtime.createContext()` /
|
|
1928
|
+
* `runtime.execute()` calls) doesn't accumulate listeners forever.
|
|
1929
|
+
* Called from `disposeEvents()` and from the workflow_end/error
|
|
1930
|
+
* emission in `emitEvent`. Undefined when no abort listener was
|
|
1931
|
+
* registered (no signal, signal already aborted, or non-root
|
|
1932
|
+
* context). */
|
|
1933
|
+
private abortListenerCleanup?;
|
|
1934
|
+
/**
|
|
1935
|
+
* Iterable + EventEmitter view over every `AxlEvent` emitted by this
|
|
1936
|
+
* context (and its child contexts — agent-as-tool nested asks bubble up).
|
|
1937
|
+
*
|
|
1938
|
+
* Use cases:
|
|
1939
|
+
* - **Inside a workflow handler**: subscribe before the first `ctx.ask()`
|
|
1940
|
+
* to observe `partial_object`, `agent_call_*`, `tool_call_*`, etc.
|
|
1941
|
+
* *between* asks. `ctx.events.partialObjects` is the coalescing view
|
|
1942
|
+
* designed for streaming-structured-output UIs.
|
|
1943
|
+
* - **Ad-hoc contexts** from `runtime.createContext()`: the same
|
|
1944
|
+
* iterable replaces the legacy `onToken` / `onToolCall` /
|
|
1945
|
+
* `onAgentStart` callbacks.
|
|
1946
|
+
* - **Cross-execution**: prefer `runtime.on('trace', …)` instead — that
|
|
1947
|
+
* fans out across all executions, while `ctx.events` is per-context.
|
|
1948
|
+
*
|
|
1949
|
+
* Lazy: the bus is allocated on first access. The bus's iterator
|
|
1950
|
+
* queue retains events emitted before any consumer iterates, so a
|
|
1951
|
+
* late `for await (const e of ctx.events)` still drains queued
|
|
1952
|
+
* events. The `partialObjects` view additionally seeds from a
|
|
1953
|
+
* per-bus `latestPartialByAsk` map, so a late subscriber may see
|
|
1954
|
+
* the latest coalesced state per ask even when earlier events were
|
|
1955
|
+
* already drained by another iterator. **Neither rescues a late
|
|
1956
|
+
* subscriber from the streaming-gate behavior** (see below).
|
|
1957
|
+
*
|
|
1958
|
+
* **Subscribe before the first `ctx.ask()`.** The streaming code
|
|
1959
|
+
* path inside `ctx.ask()` activates only when an observer is
|
|
1960
|
+
* present at the time the ask starts (`_streamingEnabled` — either
|
|
1961
|
+
* the legacy `onToken` callback is set or `ctx.events` has been
|
|
1962
|
+
* allocated). If you allocate `ctx.events` AFTER a `ctx.ask()` has
|
|
1963
|
+
* begun, that in-flight ask will not stream `token` /
|
|
1964
|
+
* `partial_object` events at all (the agent loop went through
|
|
1965
|
+
* `provider.chat` instead of `provider.stream`). Subsequent asks
|
|
1966
|
+
* will stream normally — the gate is re-checked per ask. The
|
|
1967
|
+
* unambiguous pattern is `const events = ctx.events;` on the first
|
|
1968
|
+
* line of the handler.
|
|
1969
|
+
*
|
|
1970
|
+
* Auto-termination: `emitEvent` calls `_eventBus._finish()` after
|
|
1971
|
+
* emitting `workflow_end` or `error`, so iterators terminate
|
|
1972
|
+
* cleanly with `done: true`. For ad-hoc contexts that never run a
|
|
1973
|
+
* workflow (no terminal event), pass `signal: AbortSignal.timeout(...)`
|
|
1974
|
+
* to `runtime.createContext` (the bus auto-disposes on abort) or
|
|
1975
|
+
* call `ctx.disposeEvents()` when done observing.
|
|
1976
|
+
*/
|
|
1977
|
+
get events(): AxlEventBus;
|
|
1978
|
+
/** Manually finish the `ctx.events` bus, terminating any active
|
|
1979
|
+
* iterators with `done: true`. Idempotent. Useful for ad-hoc contexts
|
|
1980
|
+
* from `runtime.createContext()` that never emit a `workflow_end` /
|
|
1981
|
+
* `error` terminal — observers iterating `for await (const e of
|
|
1982
|
+
* ctx.events)` would otherwise hang. Workflow-driven contexts
|
|
1983
|
+
* (`runtime.execute` / `runtime.stream`) terminate automatically and
|
|
1984
|
+
* don't need this.
|
|
1985
|
+
*
|
|
1986
|
+
* Also removes the constructor-registered abort listener so a
|
|
1987
|
+
* long-lived `signal` reused across many ad-hoc contexts doesn't
|
|
1988
|
+
* accumulate listeners. */
|
|
1989
|
+
disposeEvents(): void;
|
|
1990
|
+
/** True if any observer wants per-token streaming for asks started
|
|
1991
|
+
* from this context: either the legacy `onToken` callback is set
|
|
1992
|
+
* (e.g., `runtime.stream()` plumbs a sentinel) OR `ctx.events` has
|
|
1993
|
+
* been allocated (a workflow-handler consumer subscribed before
|
|
1994
|
+
* the ask). `ctx.ask` reads this to decide whether to enter the
|
|
1995
|
+
* streaming code path; the gate is re-checked per ask, so a
|
|
1996
|
+
* consumer subscribing AFTER the first ask started still gets
|
|
1997
|
+
* streaming on the next one. The check `_busRef.current !== undefined`
|
|
1998
|
+
* is a one-way flag — `_finish` does not unset the reference, so
|
|
1999
|
+
* once an observer was present, every subsequent ask streams. */
|
|
2000
|
+
private get _streamingEnabled();
|
|
1605
2001
|
constructor(init: WorkflowContextInit);
|
|
1606
2002
|
/**
|
|
1607
2003
|
* Create a child context for nested agent invocations (e.g., agent-as-tool).
|
|
@@ -1646,7 +2042,8 @@ declare class WorkflowContext<TInput = unknown> {
|
|
|
1646
2042
|
private executeAgentCall;
|
|
1647
2043
|
/**
|
|
1648
2044
|
* Push the final assistant message into session history, preserving providerMetadata
|
|
1649
|
-
* (e.g., Gemini thought signatures needed for multi-turn reasoning context)
|
|
2045
|
+
* (e.g., Gemini thought signatures needed for multi-turn reasoning context) and
|
|
2046
|
+
* stamping the agent name for observability + future per-agent scoping.
|
|
1650
2047
|
*/
|
|
1651
2048
|
private pushAssistantToSessionHistory;
|
|
1652
2049
|
private buildToolDefs;
|
|
@@ -1891,27 +2288,38 @@ declare function workflow<TInput extends z.ZodType, TOutput extends z.ZodType =
|
|
|
1891
2288
|
/**
|
|
1892
2289
|
* A streamable workflow execution.
|
|
1893
2290
|
*
|
|
1894
|
-
* Extends Node's Readable and implements `AsyncIterable<AxlEvent
|
|
1895
|
-
* `.on()` events, `for-await-of`, the
|
|
1896
|
-
*
|
|
2291
|
+
* Extends Node's `Readable` and implements `AsyncIterable<AxlEvent>` via a
|
|
2292
|
+
* composed `AxlEventBus`. Supports `.on()` events, `for-await-of`, the
|
|
2293
|
+
* `.text` iterator (root-only tokens), the `.lifecycle` iterator (structural
|
|
2294
|
+
* events only), the `.textByAsk` iterator (per-ask token chunks), and `.pipe()`.
|
|
1897
2295
|
*
|
|
1898
2296
|
* The wire carries `AxlEvent` directly — there is no per-stream synthesized
|
|
1899
2297
|
* shape. Consumers narrow on `event.type` and use `AskScoped` fields
|
|
1900
2298
|
* (`askId`, `parentAskId`, `depth`) for routing/filtering.
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
*
|
|
1912
|
-
*
|
|
1913
|
-
|
|
1914
|
-
|
|
2299
|
+
*
|
|
2300
|
+
* The underlying `AxlEventBus` is shared with `ctx.events` — both surfaces
|
|
2301
|
+
* expose the same iterator/EventEmitter contract over the same `AxlEvent`
|
|
2302
|
+
* union. AxlStream layers on top: Readable backpressure shape, terminal
|
|
2303
|
+
* `done`/`error` synthesis, `.pipe()`, and per-ask `fullText` token
|
|
2304
|
+
* accounting (which is stream-specific because the runtime emits the
|
|
2305
|
+
* structured `pipeline` events that drive commit/discard).
|
|
2306
|
+
*/
|
|
2307
|
+
declare class AxlStream extends Readable implements AsyncIterable<AxlEvent> {
|
|
2308
|
+
/** Composed event bus — owns iterator queue, EventEmitter gating, and
|
|
2309
|
+
* curated views (`.text`, `.lifecycle`, `.textByAsk`). Private; the
|
|
2310
|
+
* public surface is via the delegating methods below. */
|
|
2311
|
+
private readonly events;
|
|
2312
|
+
/**
|
|
2313
|
+
* Per-ask token buffers split into "in-progress" and "committed" halves
|
|
2314
|
+
* so `fullText` only includes tokens from attempts that actually won.
|
|
2315
|
+
* Scoping is per-`askId` so concurrent root-level asks
|
|
2316
|
+
* (`ctx.parallel`, `ctx.spawn`, `ctx.race`, `ctx.map`) don't interleave
|
|
2317
|
+
* each other's tokens — each branch's chunks stay contiguous, and a
|
|
2318
|
+
* `pipeline(failed)` on one branch only discards THAT branch's
|
|
2319
|
+
* in-progress buffer (previously: shared buffer caused a failure on
|
|
2320
|
+
* one branch to discard a peer's in-flight successful tokens).
|
|
2321
|
+
* Insertion order in the Maps reflects which ask emitted its first
|
|
2322
|
+
* token first, which is what `fullText` joins on.
|
|
1915
2323
|
*
|
|
1916
2324
|
* On `pipeline(status: 'committed')` for an ask, that ask's
|
|
1917
2325
|
* in-progress entry flushes to its committed entry. On
|
|
@@ -1925,52 +2333,54 @@ declare class AxlStream extends Readable {
|
|
|
1925
2333
|
private attemptByAsk;
|
|
1926
2334
|
private committedByAsk;
|
|
1927
2335
|
private result;
|
|
1928
|
-
private finished;
|
|
1929
2336
|
readonly promise: Promise<unknown>;
|
|
1930
|
-
private
|
|
1931
|
-
private
|
|
1932
|
-
constructor();
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
on(event: string, handler: (...args: unknown[]) => void): this;
|
|
1938
|
-
off(event: string, handler: (...args: unknown[]) => void): this;
|
|
2337
|
+
private resolvePromise;
|
|
2338
|
+
private rejectPromise;
|
|
2339
|
+
constructor(options?: EventStreamOptions);
|
|
2340
|
+
on<T extends AxlEventType>(event: T, handler: (e: AxlEventOf<T>) => void): this;
|
|
2341
|
+
on(event: string, handler: (...args: any[]) => void): this;
|
|
2342
|
+
off<T extends AxlEventType>(event: T, handler: (e: AxlEventOf<T>) => void): this;
|
|
2343
|
+
off(event: string, handler: (...args: any[]) => void): this;
|
|
1939
2344
|
[Symbol.asyncIterator](): {
|
|
1940
2345
|
next: () => Promise<IteratorResult<AxlEvent>>;
|
|
2346
|
+
return: () => Promise<IteratorResult<AxlEvent>>;
|
|
1941
2347
|
[Symbol.asyncIterator](): /*elided*/ any;
|
|
1942
|
-
[Symbol.asyncDispose]()
|
|
2348
|
+
[Symbol.asyncDispose]: () => Promise<void>;
|
|
1943
2349
|
};
|
|
1944
2350
|
get text(): AsyncIterable<string>;
|
|
1945
|
-
/**
|
|
1946
|
-
* Iterator over `{ askId, text }` pairs — one emission per token chunk,
|
|
1947
|
-
* tagged with the ask frame that produced it. Complements `.text`
|
|
1948
|
-
* (root-only stream): consumers building a split-pane UI that shows
|
|
1949
|
-
* each sub-agent's output in its own lane can group by `askId`
|
|
1950
|
-
* without iterating the raw stream and hand-filtering on `event.type`.
|
|
1951
|
-
*
|
|
1952
|
-
* Nested and root tokens both flow through. The `agent` field names
|
|
1953
|
-
* the producing agent for UI labelling; it's undefined when the token
|
|
1954
|
-
* was emitted outside any ask (rare — synthesized test fixtures).
|
|
1955
|
-
*/
|
|
1956
2351
|
get textByAsk(): AsyncIterable<{
|
|
1957
2352
|
askId: string;
|
|
1958
2353
|
agent?: string;
|
|
1959
2354
|
text: string;
|
|
1960
2355
|
}>;
|
|
1961
|
-
/**
|
|
1962
|
-
* Iterator over structural lifecycle events only — skips per-token chatter
|
|
1963
|
-
* and progressive partial_object emissions. Useful for waterfall UIs and
|
|
1964
|
-
* any consumer that wants the "what happened" timeline without per-chunk
|
|
1965
|
-
* noise. Renamed from `.steps` in the unified-event-model migration
|
|
1966
|
-
* because these are events, not pipeline steps.
|
|
1967
|
-
*/
|
|
1968
2356
|
get lifecycle(): AsyncIterable<AxlEvent>;
|
|
2357
|
+
/** Coalescing iterator over `partial_object` events — yields the latest
|
|
2358
|
+
* object payload per `askId`. Designed for streaming-structured-output
|
|
2359
|
+
* UIs: when the producer outpaces the consumer, intermediate snapshots
|
|
2360
|
+
* are silently superseded and the next `.next()` await sees only the
|
|
2361
|
+
* most recent state per ask. Listener-based, so does NOT race with the
|
|
2362
|
+
* main `for await (const e of stream)` iterator. See
|
|
2363
|
+
* `AxlEventBus.partialObjects` for full semantics. The yielded
|
|
2364
|
+
* `CoalescedPartialObject` shape is shared with the bus so the two
|
|
2365
|
+
* surfaces can never drift on the `attempt` field. */
|
|
2366
|
+
get partialObjects(): AsyncIterable<CoalescedPartialObject>;
|
|
1969
2367
|
pipe<T extends NodeJS.WritableStream>(destination: T, options?: {
|
|
1970
2368
|
end?: boolean;
|
|
1971
2369
|
}): T;
|
|
1972
|
-
/** Push an event onto the stream. Called by the runtime.
|
|
2370
|
+
/** Push an event onto the stream. Called by the runtime.
|
|
2371
|
+
*
|
|
2372
|
+
* Side-effect ordering: `accountForToken` (fullText buffers) →
|
|
2373
|
+
* `events._push` (bus.emit + iterator waiter/queue) → `Readable.push`
|
|
2374
|
+
* (object-mode buffer for `.pipe()` consumers and `'data'` listeners).
|
|
2375
|
+
* Pre-refactor the order was `bus.emit → Readable.push → waiter/queue`;
|
|
2376
|
+
* the new order resolves async iterators before Readable.push. The
|
|
2377
|
+
* difference is invisible to all in-tree consumers — `.pipe()` here
|
|
2378
|
+
* routes through the bus's `'token'` listener (line 129), and existing
|
|
2379
|
+
* tests pass — but it's intentional rather than accidental. */
|
|
1973
2380
|
_push(event: AxlEvent): void;
|
|
2381
|
+
/** Token accumulation and pipeline commit/discard accounting for
|
|
2382
|
+
* `fullText`. Extracted from `_push` so the bus delegation reads cleanly. */
|
|
2383
|
+
private accountForToken;
|
|
1974
2384
|
/**
|
|
1975
2385
|
* Signal successful completion.
|
|
1976
2386
|
*
|
|
@@ -2017,6 +2427,18 @@ type SessionOptions = {
|
|
|
2017
2427
|
/**
|
|
2018
2428
|
* A stateful conversation session.
|
|
2019
2429
|
* Persists message history across multiple interactions.
|
|
2430
|
+
*
|
|
2431
|
+
* **Concurrency contract:** `send`, `stream`, `end`, and `fork` are
|
|
2432
|
+
* serialized per session id within one runtime instance. Two
|
|
2433
|
+
* `runtime.session('x')` handles share the same lock (it lives on
|
|
2434
|
+
* `AxlRuntime`, not the `Session` instance). `history()` and
|
|
2435
|
+
* `handoffs()` bypass the lock and return the last persisted snapshot.
|
|
2436
|
+
*
|
|
2437
|
+
* **⚠️ Cross-process locking is NOT provided.** Multiple Node workers
|
|
2438
|
+
* behind a load balancer hitting the same Redis-backed `sessionId`
|
|
2439
|
+
* will still race. Pin sessions to workers (sticky routing) or use
|
|
2440
|
+
* distinct ids per request. See `docs/api-reference.md` →
|
|
2441
|
+
* Sessions → Concurrency.
|
|
2020
2442
|
*/
|
|
2021
2443
|
declare class Session {
|
|
2022
2444
|
private sessionId;
|
|
@@ -2026,13 +2448,36 @@ declare class Session {
|
|
|
2026
2448
|
private options;
|
|
2027
2449
|
constructor(sessionId: string, runtime: AxlRuntime, store: StateStore, options?: SessionOptions);
|
|
2028
2450
|
get id(): string;
|
|
2029
|
-
send(workflowName: string, input: unknown
|
|
2030
|
-
|
|
2451
|
+
send(workflowName: string, input: unknown, options?: {
|
|
2452
|
+
signal?: AbortSignal;
|
|
2453
|
+
events?: EventStreamOptions;
|
|
2454
|
+
}): Promise<unknown>;
|
|
2455
|
+
private sendImpl;
|
|
2456
|
+
/** Read history + summary, apply maxMessages limit (with optional
|
|
2457
|
+
* summarization), and push the new user message. Returns the mutable
|
|
2458
|
+
* `history` array (which `executeAgentCall` will append the assistant
|
|
2459
|
+
* reply to in-place) and the `metadata` payload to forward to
|
|
2460
|
+
* `runtime.execute()` / `runtime.stream()`. Shared by `sendImpl` and
|
|
2461
|
+
* `streamImpl` so future fixes (e.g., to summarization wiring) land in
|
|
2462
|
+
* one place. */
|
|
2463
|
+
private prepareHistory;
|
|
2464
|
+
/** Push the assistant reply (if `executeAgentCall` didn't already) and
|
|
2465
|
+
* persist. Shared by `sendImpl` and `streamImpl`. The fallback assistant
|
|
2466
|
+
* push has no agent context and so leaves `agent` undefined — see the
|
|
2467
|
+
* `ChatMessage.agent` field doc. */
|
|
2468
|
+
private commitHistory;
|
|
2469
|
+
stream(workflowName: string, input: unknown, options?: {
|
|
2470
|
+
signal?: AbortSignal;
|
|
2471
|
+
events?: EventStreamOptions;
|
|
2472
|
+
}): Promise<AxlStream>;
|
|
2473
|
+
private streamImpl;
|
|
2031
2474
|
history(): Promise<ChatMessage[]>;
|
|
2032
2475
|
/** Get the handoff history for this session. */
|
|
2033
2476
|
handoffs(): Promise<HandoffRecord[]>;
|
|
2034
2477
|
end(): Promise<void>;
|
|
2035
|
-
fork(newId: string
|
|
2478
|
+
fork(newId: string, options?: {
|
|
2479
|
+
overwrite?: boolean;
|
|
2480
|
+
}): Promise<Session>;
|
|
2036
2481
|
}
|
|
2037
2482
|
|
|
2038
2483
|
/**
|
|
@@ -2059,6 +2504,17 @@ type ExecuteOptions = {
|
|
|
2059
2504
|
* Useful for in-process testing and ad-hoc invocations where you don't want to poll
|
|
2060
2505
|
* `runtime.getPendingDecisions()` and call `runtime.resolveDecision()`. */
|
|
2061
2506
|
awaitHumanHandler?: (options: AwaitHumanOptions) => Promise<HumanDecision>;
|
|
2507
|
+
/** External AbortSignal. When fired, aborts the workflow exactly as
|
|
2508
|
+
* `runtime.abort(executionId)` would. Lets callers use the standard
|
|
2509
|
+
* JS cancellation pattern (e.g., AbortController from a UI's "stop"
|
|
2510
|
+
* button) without having to track the execution id. */
|
|
2511
|
+
signal?: AbortSignal;
|
|
2512
|
+
/** Configuration for the workflow context's `ctx.events` bus and the
|
|
2513
|
+
* `AxlStream` returned by `runtime.stream()`. Both consume the same
|
|
2514
|
+
* `EventStreamOptions` (queue cap + overflow policy). When omitted,
|
|
2515
|
+
* defaults are `maxQueued: 10_000` and `onOverflow:
|
|
2516
|
+
* 'drop-oldest-non-terminal'`. */
|
|
2517
|
+
events?: EventStreamOptions;
|
|
2062
2518
|
};
|
|
2063
2519
|
/**
|
|
2064
2520
|
* Shape of events forwarded to an eval `onProgress` callback. Mirrors
|
|
@@ -2101,6 +2557,10 @@ type CreateContextOptions = {
|
|
|
2101
2557
|
}, meta: CallbackMeta) => void;
|
|
2102
2558
|
/** Handler for tool approval requests. Called when an agent invokes a tool with requireApproval. */
|
|
2103
2559
|
awaitHumanHandler?: (options: AwaitHumanOptions) => Promise<HumanDecision>;
|
|
2560
|
+
/** Configuration for the lazy `ctx.events` bus on the returned context.
|
|
2561
|
+
* Defaults: `maxQueued: 10_000`, `onOverflow:
|
|
2562
|
+
* 'drop-oldest-non-terminal'`. */
|
|
2563
|
+
events?: EventStreamOptions;
|
|
2104
2564
|
};
|
|
2105
2565
|
/**
|
|
2106
2566
|
* The main entry point for executing Axl workflows.
|
|
@@ -2124,12 +2584,23 @@ declare class AxlRuntime extends EventEmitter {
|
|
|
2124
2584
|
private spanManager;
|
|
2125
2585
|
private historicalExecutions;
|
|
2126
2586
|
private historicalExecutionsLoadPromise;
|
|
2587
|
+
/** Per-session in-process serialization. Each entry is a chain of pending
|
|
2588
|
+
* work for that session id — `Session.send` / `Session.stream` await the
|
|
2589
|
+
* prior entry before reading history, so concurrent calls produce a
|
|
2590
|
+
* sequenced conversation log instead of last-writer-wins corruption.
|
|
2591
|
+
* Cross-process locking is NOT provided; use distinct session ids when
|
|
2592
|
+
* multiple processes share a store. */
|
|
2593
|
+
private sessionLocks;
|
|
2127
2594
|
private evalHistory;
|
|
2128
2595
|
private evalHistoryLoadPromise;
|
|
2129
2596
|
/** Resolved cap on `ExecutionInfo.events` per execution. Cached on
|
|
2130
2597
|
* the instance so per-event onTrace handlers don't reach into
|
|
2131
2598
|
* `this.config.state` on every emission. */
|
|
2132
2599
|
private readonly maxEventsPerExecution;
|
|
2600
|
+
/** Tracks executionIds for which we've already warned about a malformed
|
|
2601
|
+
* `events` field — keeps the log to one line per row instead of one per
|
|
2602
|
+
* rebuild tick. */
|
|
2603
|
+
private warnedMalformedExecutions;
|
|
2133
2604
|
constructor(config?: AxlConfig);
|
|
2134
2605
|
/**
|
|
2135
2606
|
* Whether `config.trace.redact` is enabled on this runtime. A narrow
|
|
@@ -2171,8 +2642,9 @@ declare class AxlRuntime extends EventEmitter {
|
|
|
2171
2642
|
* Side effects on `execInfo`: sets `status` / `completedAt` /
|
|
2172
2643
|
* `duration` / `result` (or `error`) before emitting `workflow_end`.
|
|
2173
2644
|
* On throw: emits `workflow_end({status: 'failed', aborted?})` and
|
|
2174
|
-
* persists before rethrowing. `abortControllers.delete`
|
|
2175
|
-
* `
|
|
2645
|
+
* persists before rethrowing. `abortControllers.delete` and
|
|
2646
|
+
* `cleanupAbortForwarder` (if provided) both run in `finally`
|
|
2647
|
+
* regardless of outcome.
|
|
2176
2648
|
*
|
|
2177
2649
|
* Caller responsibilities:
|
|
2178
2650
|
* - Allocate `executionId` and register it in `abortControllers` map
|
|
@@ -2182,6 +2654,10 @@ declare class AxlRuntime extends EventEmitter {
|
|
|
2182
2654
|
* - Pass `span` if the call site is inside a tracer span — this
|
|
2183
2655
|
* helper sets `axl.workflow.cost` / `.duration` attributes on
|
|
2184
2656
|
* success.
|
|
2657
|
+
* - Pass `cleanupAbortForwarder` (the cleanup fn returned from
|
|
2658
|
+
* `forwardAbortSignal`) so the listener on the user's external
|
|
2659
|
+
* signal is removed when the workflow completes — see the
|
|
2660
|
+
* helper's docstring for the leak this prevents.
|
|
2185
2661
|
*/
|
|
2186
2662
|
private runWorkflowBody;
|
|
2187
2663
|
/**
|
|
@@ -2245,6 +2721,14 @@ declare class AxlRuntime extends EventEmitter {
|
|
|
2245
2721
|
captureTraces?: boolean;
|
|
2246
2722
|
}): Promise<unknown>;
|
|
2247
2723
|
/** Get all execution info (running + completed + historical). */
|
|
2724
|
+
/** Normalize an `ExecutionInfo` loaded from a `StateStore` so the
|
|
2725
|
+
* `events: AxlEvent[]` type contract holds for downstream consumers
|
|
2726
|
+
* (Studio aggregators, REST routes, redaction). Custom or legacy stores
|
|
2727
|
+
* may persist rows without `events` (or with a non-array value) — without
|
|
2728
|
+
* this guard, a single malformed row crashes every iterator over
|
|
2729
|
+
* `exec.events` and takes down dependent features. Mutates the row
|
|
2730
|
+
* in place; logs at most one warning per `executionId`. */
|
|
2731
|
+
private normalizeStoredExecution;
|
|
2248
2732
|
getExecutions(): Promise<ExecutionInfo[]>;
|
|
2249
2733
|
/**
|
|
2250
2734
|
* Create a WorkflowContext for ad-hoc use (evals, tool testing, prototyping).
|
|
@@ -2265,7 +2749,27 @@ declare class AxlRuntime extends EventEmitter {
|
|
|
2265
2749
|
stream(name: string, input: unknown, options?: ExecuteOptions): AxlStream;
|
|
2266
2750
|
/** Create or resume a session. */
|
|
2267
2751
|
session(id: string, options?: SessionOptions): Session;
|
|
2268
|
-
/**
|
|
2752
|
+
/** @internal Serialize work per session id within this runtime instance.
|
|
2753
|
+
* Subsequent calls await the prior task's settlement (success or failure)
|
|
2754
|
+
* before running. Used by `Session.send` / `Session.stream` / `end` /
|
|
2755
|
+
* `fork` to eliminate read-modify-write races on `StateStore.saveSession`
|
|
2756
|
+
* (and on `delete`/`getSession` ordering vs in-flight saves).
|
|
2757
|
+
*
|
|
2758
|
+
* ⚠️ NOT REENTRANT. Calling this from inside an `fn` already running
|
|
2759
|
+
* under `_serializeSession(sameId, ...)` will deadlock — the inner
|
|
2760
|
+
* call awaits the outer's settlement, the outer awaits the inner's
|
|
2761
|
+
* return. `Session.fork` deliberately calls with TWO different ids
|
|
2762
|
+
* (source and target) and never the same id twice. Any future caller
|
|
2763
|
+
* must follow the same rule. */
|
|
2764
|
+
_serializeSession<T>(id: string, fn: () => Promise<T>): Promise<T>;
|
|
2765
|
+
/** Gracefully shut down the runtime, aborting in-flight executions and
|
|
2766
|
+
* closing state stores and MCP servers. Drains in-flight per-session
|
|
2767
|
+
* work (Session.send / Session.stream) before closing the state store.
|
|
2768
|
+
*
|
|
2769
|
+
* This is a drain of EXISTING work, not a barrier against new calls —
|
|
2770
|
+
* callers should stop accepting work (e.g., close their HTTP server)
|
|
2771
|
+
* before invoking `shutdown()`. A `Session.send` invoked after the
|
|
2772
|
+
* drain snapshot is taken can still race a closed state store. */
|
|
2269
2773
|
shutdown(): Promise<void>;
|
|
2270
2774
|
/** Abort a running execution by its ID. */
|
|
2271
2775
|
abort(executionId: string): void;
|
|
@@ -3231,4 +3735,4 @@ declare class NoopSpanManager implements SpanManager {
|
|
|
3231
3735
|
*/
|
|
3232
3736
|
declare function createSpanManager(config?: TelemetryConfig): Promise<SpanManager>;
|
|
3233
3737
|
|
|
3234
|
-
export { AXL_EVENT_TYPES, type Agent, type AgentCallEndData, type AgentCallInfo, type AgentCallParams, type AgentCallStartData, type AgentConfig, AnthropicProvider, type AnyWorkflow, type AskOptions, type AskScoped, type AwaitHumanData, type AwaitHumanOptions, type AwaitHumanResolvedData, type AxlConfig, AxlError, type AxlEvent, type AxlEventBase, type AxlEventOf, type AxlEventType, AxlRuntime, AxlStream, BudgetExceededError, type BudgetOptions, type BudgetResult, CONFIG_CANDIDATES, COST_BEARING_LEAF_TYPES, type CallbackMeta, type ChatMessage, type ChatOptions, type CheckpointEventData, type CreateContextOptions, type DelegateData, type DelegateOptions, type Effort, type EmbedResult, type EmbedUsage, type Embedder, type EvalExecuteWorkflow, type EvalHistoryEntry, type ExecuteOptions, type ExecutionInfo, type ExecutionState, GeminiProvider, type GuardrailBlockHandler, type GuardrailData, GuardrailError, type GuardrailResult, type GuardrailsConfig, type HandoffDescriptor, type HandoffRecord, type HandoffReturnData, type HandoffStartData, type HumanDecision, InMemoryVectorStore, type InputGuardrail, type MapOptions, MaxTurnsError, McpManager, type McpServer, type McpServerConfig, type McpToolDefinition, type McpToolResult, type MemoryConfig, type MemoryEventData, MemoryManager, MemoryStore, NoConsensus, NoopSpanManager, OpenAIEmbedder, OpenAIProvider, OpenAIResponsesProvider, type OutputGuardrail, type OutputValidator, type PendingDecision, type Provider, type ProviderAdapter, ProviderRegistry, type ProviderResponse, QuorumNotMet, REDACTED, REDACTION_RULES, type RaceOptions, type RecallOptions, type RecallResult, RedisStore, type RememberOptions, type RememberResult, type ResolvedThinkingOptions, type Result, type RetryPolicy, SQLiteStore, type SchemaCheckData, Session, type SessionOptions, type SpanHandle, type SpanManager, type SpawnOptions, SqliteVectorStore, type StateStore, type StreamChunk, type TelemetryConfig, TimeoutError, type Tool, type ToolApprovalData, type ToolCallData, type ToolCallMessage, type ToolCallStartData, type ToolChoice, type ToolConfig, ToolDenied, type ToolDeniedData, type ToolHooks, 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, agent, createSpanManager, defineConfig, eventCostContribution, expandGlob, extractJson, findConfig, importModule, isCostBearingLeaf, isRootLevel, needsTsxLoader, parsePartialJson, pickDefault, pickExport, redactEvent, registerConditions, resolveRuntime, resolveThinkingOptions, tool, workflow, zodToJsonSchema };
|
|
3738
|
+
export { AXL_EVENT_TYPES, type Agent, type AgentCallEndData, type AgentCallInfo, type AgentCallParams, type AgentCallStartData, type AgentConfig, AnthropicProvider, type AnyWorkflow, type AskOptions, type AskScoped, type AwaitHumanData, type AwaitHumanOptions, type AwaitHumanResolvedData, type AxlConfig, AxlError, type AxlEvent, type AxlEventBase, AxlEventBus, type AxlEventOf, type AxlEventType, AxlRuntime, AxlStream, BudgetExceededError, type BudgetOptions, type BudgetResult, CONFIG_CANDIDATES, COST_BEARING_LEAF_TYPES, type CallbackMeta, type ChatMessage, type ChatOptions, type CheckpointEventData, type CoalescedPartialObject, type CreateContextOptions, 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, GeminiProvider, type GuardrailBlockHandler, type GuardrailData, GuardrailError, type GuardrailResult, type GuardrailsConfig, type HandoffDescriptor, type HandoffRecord, type HandoffReturnData, type HandoffStartData, type HumanDecision, InMemoryVectorStore, type InputGuardrail, type MapOptions, MaxTurnsError, McpManager, type McpServer, type McpServerConfig, type McpToolDefinition, type McpToolResult, type MemoryConfig, type MemoryEventData, MemoryManager, MemoryStore, NoConsensus, NoopSpanManager, OpenAIEmbedder, OpenAIProvider, OpenAIResponsesProvider, type OutputGuardrail, type OutputValidator, type PendingDecision, type Provider, type ProviderAdapter, ProviderRegistry, type ProviderResponse, QuorumNotMet, REDACTED, REDACTION_RULES, type RaceOptions, type RecallOptions, type RecallResult, RedisStore, type RememberOptions, type RememberResult, type ResolvedThinkingOptions, type Result, type RetryPolicy, SQLiteStore, type SchemaCheckData, Session, type SessionOptions, type SpanHandle, type SpanManager, type SpawnOptions, SqliteVectorStore, type StateStore, type StreamChunk, type TelemetryConfig, TimeoutError, type Tool, type ToolApprovalData, type ToolCallData, type ToolCallMessage, type ToolCallStartData, type ToolChoice, type ToolConfig, ToolDenied, type ToolDeniedData, type ToolHooks, 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, agent, createSpanManager, defineConfig, eventCostContribution, expandGlob, extractJson, findConfig, importModule, isCostBearingLeaf, isRootLevel, needsTsxLoader, parsePartialJson, pickDefault, pickExport, redactEvent, registerConditions, resolveRuntime, resolveThinkingOptions, tool, workflow, zodToJsonSchema };
|