@axlsdk/axl 0.23.0 → 0.23.2
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 +29 -0
- package/dist/index.cjs +311 -116
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +62 -31
- package/dist/index.d.ts +62 -31
- package/dist/index.js +310 -116
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -167,6 +167,7 @@ __export(index_exports, {
|
|
|
167
167
|
SQLiteStore: () => SQLiteStore,
|
|
168
168
|
Session: () => Session,
|
|
169
169
|
SqliteVectorStore: () => SqliteVectorStore,
|
|
170
|
+
StallTimeoutError: () => StallTimeoutError,
|
|
170
171
|
ThinkTagScanner: () => ThinkTagScanner,
|
|
171
172
|
TimeoutError: () => TimeoutError,
|
|
172
173
|
ToolFailure: () => ToolFailure,
|
|
@@ -394,15 +395,22 @@ var NoConsensus = class extends AxlError {
|
|
|
394
395
|
var TimeoutError = class extends AxlError {
|
|
395
396
|
/** Latency attribution for the timed-out operation, when measurable. */
|
|
396
397
|
breakdown;
|
|
397
|
-
constructor(operation, timeoutMs, breakdown) {
|
|
398
|
+
constructor(operation, timeoutMs, breakdown, agent2) {
|
|
398
399
|
super(
|
|
399
400
|
"TIMEOUT",
|
|
400
|
-
`${operation} exceeded timeout of ${timeoutMs}ms` + (breakdown ? ` (elapsed ${breakdown.elapsedMs}ms: queued ${breakdown.queuedMs}ms, retries ${breakdown.retryMs}ms, wire ${breakdown.wireMs}ms, other ${breakdown.otherMs}ms)` : "")
|
|
401
|
+
`${operation} exceeded timeout of ${timeoutMs}ms` + (breakdown ? ` (elapsed ${breakdown.elapsedMs}ms: queued ${breakdown.queuedMs}ms, retries ${breakdown.retryMs}ms, wire ${breakdown.wireMs}ms, other ${breakdown.otherMs}ms)` : "") + (agent2 ? ` for agent '${agent2}'` : "")
|
|
401
402
|
);
|
|
402
403
|
this.name = "TimeoutError";
|
|
403
404
|
if (breakdown) this.breakdown = breakdown;
|
|
404
405
|
}
|
|
405
406
|
};
|
|
407
|
+
var StallTimeoutError = class extends TimeoutError {
|
|
408
|
+
constructor(operation, timeoutMs, agent2) {
|
|
409
|
+
super(operation, timeoutMs, void 0, agent2);
|
|
410
|
+
this.name = "StallTimeoutError";
|
|
411
|
+
this.message = `${operation} provider request stalled for ${timeoutMs}ms` + (agent2 ? ` for agent '${agent2}'` : "");
|
|
412
|
+
}
|
|
413
|
+
};
|
|
406
414
|
function formatBudgetCost(cost) {
|
|
407
415
|
if (Number.isNaN(cost)) return "$NaN";
|
|
408
416
|
if (cost === Infinity) return "$Infinity";
|
|
@@ -1075,6 +1083,7 @@ async function fetchWithRetry(input, init, opts) {
|
|
|
1075
1083
|
message: err instanceof Error ? err.message : String(err)
|
|
1076
1084
|
});
|
|
1077
1085
|
}
|
|
1086
|
+
observer?.onRetry?.(attempt + 1, Date.now());
|
|
1078
1087
|
await sleep2(jitter(BASE_DELAY_MS * 2 ** attempt), init?.signal ?? void 0);
|
|
1079
1088
|
continue;
|
|
1080
1089
|
}
|
|
@@ -1090,6 +1099,7 @@ async function fetchWithRetry(input, init, opts) {
|
|
|
1090
1099
|
}
|
|
1091
1100
|
const retryAfterMs = parseRetryAfter(res.headers);
|
|
1092
1101
|
const baseDelay = retryAfterMs !== void 0 ? Math.min(retryAfterMs, MAX_BACKOFF_MS) : BASE_DELAY_MS * 2 ** attempt;
|
|
1102
|
+
observer?.onRetry?.(attempt + 1, Date.now());
|
|
1093
1103
|
await sleep2(jitter(baseDelay), init?.signal ?? void 0);
|
|
1094
1104
|
}
|
|
1095
1105
|
} finally {
|
|
@@ -1099,12 +1109,23 @@ async function fetchWithRetry(input, init, opts) {
|
|
|
1099
1109
|
|
|
1100
1110
|
// src/providers/call-timing.ts
|
|
1101
1111
|
var CallTimingRecorder = class {
|
|
1112
|
+
constructor(requestLifecycle) {
|
|
1113
|
+
this.requestLifecycle = requestLifecycle;
|
|
1114
|
+
}
|
|
1102
1115
|
fetchTiming;
|
|
1103
1116
|
firstTokenAt;
|
|
1117
|
+
/** Consumer suspension after pre-content chunks (for example, tool deltas). */
|
|
1118
|
+
preFirstTokenConsumerMs = 0;
|
|
1104
1119
|
/** Cumulative time awaiting `reader.read()`, i.e. transport, not consumer. */
|
|
1105
1120
|
readWaitMs = 0;
|
|
1106
1121
|
/** Pass as `timing` in the `fetchWithRetry` options object. */
|
|
1107
1122
|
observer = {
|
|
1123
|
+
onDispatch: () => {
|
|
1124
|
+
this.requestLifecycle?.onDispatch?.();
|
|
1125
|
+
},
|
|
1126
|
+
onRetry: () => {
|
|
1127
|
+
this.requestLifecycle?.onRetry?.();
|
|
1128
|
+
},
|
|
1108
1129
|
onComplete: (timing) => {
|
|
1109
1130
|
this.fetchTiming = timing;
|
|
1110
1131
|
}
|
|
@@ -1126,6 +1147,12 @@ var CallTimingRecorder = class {
|
|
|
1126
1147
|
markFirstToken() {
|
|
1127
1148
|
this.firstTokenAt ??= Date.now();
|
|
1128
1149
|
}
|
|
1150
|
+
/** Exclude backpressure after a pre-content yield from first-content latency. */
|
|
1151
|
+
recordPreFirstTokenConsumerPause(startedAt) {
|
|
1152
|
+
if (this.firstTokenAt === void 0) {
|
|
1153
|
+
this.preFirstTokenConsumerMs += Math.max(0, Date.now() - startedAt);
|
|
1154
|
+
}
|
|
1155
|
+
}
|
|
1129
1156
|
/**
|
|
1130
1157
|
* Timing for a non-streaming call. Call once the response body is parsed.
|
|
1131
1158
|
*
|
|
@@ -1149,13 +1176,17 @@ var CallTimingRecorder = class {
|
|
|
1149
1176
|
const t = this.fetchTiming;
|
|
1150
1177
|
if (!t) return void 0;
|
|
1151
1178
|
const ttfbMs = Math.max(0, t.headersAt - t.dispatchedAt);
|
|
1179
|
+
const firstTokenMs = this.firstTokenAt !== void 0 ? Math.max(0, this.firstTokenAt - t.dispatchedAt - this.preFirstTokenConsumerMs) : void 0;
|
|
1152
1180
|
return {
|
|
1153
1181
|
queuedMs: t.queuedMs,
|
|
1154
1182
|
attempts: t.attempts,
|
|
1155
1183
|
retryMs: t.retryMs,
|
|
1156
1184
|
ttfbMs,
|
|
1157
|
-
...
|
|
1158
|
-
|
|
1185
|
+
...firstTokenMs !== void 0 ? { firstTokenMs } : {},
|
|
1186
|
+
// Parsing and generator scheduling can happen after the first read has
|
|
1187
|
+
// settled. Include that pre-first-token gap so the public relationship
|
|
1188
|
+
// stays intuitive, without charging pauses after any chunk is yielded.
|
|
1189
|
+
wireMs: Math.max(ttfbMs + this.readWaitMs, firstTokenMs ?? 0)
|
|
1159
1190
|
};
|
|
1160
1191
|
}
|
|
1161
1192
|
};
|
|
@@ -1168,7 +1199,9 @@ async function* withCallTiming(recorder, source) {
|
|
|
1168
1199
|
const timing = recorder.streamTiming();
|
|
1169
1200
|
yield timing ? { ...chunk, timing } : chunk;
|
|
1170
1201
|
} else {
|
|
1202
|
+
const yieldedAt = Date.now();
|
|
1171
1203
|
yield chunk;
|
|
1204
|
+
recorder.recordPreFirstTokenConsumerPause(yieldedAt);
|
|
1172
1205
|
}
|
|
1173
1206
|
}
|
|
1174
1207
|
}
|
|
@@ -1178,9 +1211,6 @@ function withChatTiming(recorder, response) {
|
|
|
1178
1211
|
}
|
|
1179
1212
|
|
|
1180
1213
|
// src/providers/rate-limiter.ts
|
|
1181
|
-
function abortError() {
|
|
1182
|
-
return Object.assign(new Error("The operation was aborted"), { name: "AbortError" });
|
|
1183
|
-
}
|
|
1184
1214
|
var RateLimiter = class {
|
|
1185
1215
|
maxConcurrent;
|
|
1186
1216
|
minIntervalMs;
|
|
@@ -1229,11 +1259,11 @@ var RateLimiter = class {
|
|
|
1229
1259
|
* With `acquireTimeoutMs`, a waiter that sits in the queue too long rejects.
|
|
1230
1260
|
*/
|
|
1231
1261
|
acquire(signal) {
|
|
1232
|
-
if (signal?.aborted) return Promise.reject(
|
|
1262
|
+
if (signal?.aborted) return Promise.reject(signal.reason);
|
|
1233
1263
|
return new Promise((resolve2, reject) => {
|
|
1234
1264
|
const waiter = { resolve: resolve2, reject, signal };
|
|
1235
1265
|
if (signal) {
|
|
1236
|
-
waiter.onAbort = () => this.settleWaiter(waiter,
|
|
1266
|
+
waiter.onAbort = () => this.settleWaiter(waiter, signal.reason);
|
|
1237
1267
|
signal.addEventListener("abort", waiter.onAbort, { once: true });
|
|
1238
1268
|
}
|
|
1239
1269
|
if (this.acquireTimeoutMs != null) {
|
|
@@ -1533,6 +1563,7 @@ function normalizeMessageContent(content) {
|
|
|
1533
1563
|
}
|
|
1534
1564
|
var OpenAICompatibleProvider = class {
|
|
1535
1565
|
name;
|
|
1566
|
+
reportsRequestLifecycle = true;
|
|
1536
1567
|
inputCapabilities(model) {
|
|
1537
1568
|
return this.name === "openrouter" && model.trim().length > 0 ? { image: { sources: ["url", "bytes", "base64"] } } : {};
|
|
1538
1569
|
}
|
|
@@ -1629,7 +1660,7 @@ var OpenAICompatibleProvider = class {
|
|
|
1629
1660
|
async chat(messages, options) {
|
|
1630
1661
|
const headers = this.buildHeaders(await this.resolveKey());
|
|
1631
1662
|
const body = this.buildRequestBody(messages, options, false);
|
|
1632
|
-
const recorder = new CallTimingRecorder();
|
|
1663
|
+
const recorder = new CallTimingRecorder(options.requestLifecycle);
|
|
1633
1664
|
const res = await fetchWithRetry(
|
|
1634
1665
|
`${this.baseUrl}/chat/completions`,
|
|
1635
1666
|
{
|
|
@@ -1660,7 +1691,7 @@ var OpenAICompatibleProvider = class {
|
|
|
1660
1691
|
async *stream(messages, options) {
|
|
1661
1692
|
const headers = this.buildHeaders(await this.resolveKey());
|
|
1662
1693
|
const body = this.buildRequestBody(messages, options, true);
|
|
1663
|
-
const recorder = new CallTimingRecorder();
|
|
1694
|
+
const recorder = new CallTimingRecorder(options.requestLifecycle);
|
|
1664
1695
|
const res = await fetchWithRetry(
|
|
1665
1696
|
`${this.baseUrl}/chat/completions`,
|
|
1666
1697
|
{
|
|
@@ -2568,6 +2599,7 @@ function responseImageParts(parts) {
|
|
|
2568
2599
|
}
|
|
2569
2600
|
var OpenAIResponsesProvider = class {
|
|
2570
2601
|
name = "openai-responses";
|
|
2602
|
+
reportsRequestLifecycle = true;
|
|
2571
2603
|
inputCapabilities(model) {
|
|
2572
2604
|
return model.trim().length > 0 ? { image: { sources: ["url", "bytes", "base64", "provider-file"] } } : {};
|
|
2573
2605
|
}
|
|
@@ -2654,7 +2686,7 @@ var OpenAIResponsesProvider = class {
|
|
|
2654
2686
|
async chat(messages, options) {
|
|
2655
2687
|
const headers = this.buildHeaders(await this.resolveKey());
|
|
2656
2688
|
const body = this.buildRequestBody(messages, options, false);
|
|
2657
|
-
const recorder = new CallTimingRecorder();
|
|
2689
|
+
const recorder = new CallTimingRecorder(options.requestLifecycle);
|
|
2658
2690
|
const res = await fetchWithRetry(
|
|
2659
2691
|
`${this.baseUrl}/responses`,
|
|
2660
2692
|
{
|
|
@@ -2689,7 +2721,7 @@ var OpenAIResponsesProvider = class {
|
|
|
2689
2721
|
async *stream(messages, options) {
|
|
2690
2722
|
const headers = this.buildHeaders(await this.resolveKey());
|
|
2691
2723
|
const body = this.buildRequestBody(messages, options, true);
|
|
2692
|
-
const recorder = new CallTimingRecorder();
|
|
2724
|
+
const recorder = new CallTimingRecorder(options.requestLifecycle);
|
|
2693
2725
|
const res = await fetchWithRetry(
|
|
2694
2726
|
`${this.baseUrl}/responses`,
|
|
2695
2727
|
{
|
|
@@ -3493,6 +3525,7 @@ function mergeAnthropicUsage(initial, update) {
|
|
|
3493
3525
|
}
|
|
3494
3526
|
var AnthropicProvider = class {
|
|
3495
3527
|
name = "anthropic";
|
|
3528
|
+
reportsRequestLifecycle = true;
|
|
3496
3529
|
/** Report a clamped `effort`. Anthropic clamps to each model's supported
|
|
3497
3530
|
* `output_config.effort` levels, and models that always think fall back to
|
|
3498
3531
|
* adaptive `'low'` when asked to disable thinking. Only reported when the
|
|
@@ -3610,7 +3643,7 @@ var AnthropicProvider = class {
|
|
|
3610
3643
|
);
|
|
3611
3644
|
const body = this.buildRequestBody(messages, options, false);
|
|
3612
3645
|
const pricingContext = pricingContextFromBody(body);
|
|
3613
|
-
const recorder = new CallTimingRecorder();
|
|
3646
|
+
const recorder = new CallTimingRecorder(options.requestLifecycle);
|
|
3614
3647
|
const res = await fetchWithRetry(
|
|
3615
3648
|
`${this.baseUrl}/messages`,
|
|
3616
3649
|
{
|
|
@@ -3646,7 +3679,7 @@ var AnthropicProvider = class {
|
|
|
3646
3679
|
);
|
|
3647
3680
|
const body = this.buildRequestBody(messages, options, true);
|
|
3648
3681
|
const pricingContext = pricingContextFromBody(body);
|
|
3649
|
-
const recorder = new CallTimingRecorder();
|
|
3682
|
+
const recorder = new CallTimingRecorder(options.requestLifecycle);
|
|
3650
3683
|
const res = await fetchWithRetry(
|
|
3651
3684
|
`${this.baseUrl}/messages`,
|
|
3652
3685
|
{
|
|
@@ -4473,6 +4506,7 @@ function resolveGeminiThinking(model, resolved) {
|
|
|
4473
4506
|
}
|
|
4474
4507
|
var GeminiProvider = class {
|
|
4475
4508
|
name = "google";
|
|
4509
|
+
reportsRequestLifecycle = true;
|
|
4476
4510
|
inputCapabilities(model) {
|
|
4477
4511
|
return model.trim().length > 0 ? { image: { sources: ["bytes", "base64", "provider-file"] } } : {};
|
|
4478
4512
|
}
|
|
@@ -4590,7 +4624,7 @@ var GeminiProvider = class {
|
|
|
4590
4624
|
const pricingContext = this.pricingContext(this.requestModel(options), body);
|
|
4591
4625
|
this.assertSafeGemini3Continuation(messages, pricingContext.model);
|
|
4592
4626
|
const headers = this.buildHeaders(await this.resolveKey());
|
|
4593
|
-
const recorder = new CallTimingRecorder();
|
|
4627
|
+
const recorder = new CallTimingRecorder(options.requestLifecycle);
|
|
4594
4628
|
const res = await fetchWithRetry(
|
|
4595
4629
|
`${this.baseUrl}/models/${pricingContext.model}:generateContent`,
|
|
4596
4630
|
{
|
|
@@ -4628,7 +4662,7 @@ var GeminiProvider = class {
|
|
|
4628
4662
|
const pricingContext = this.pricingContext(this.requestModel(options), body);
|
|
4629
4663
|
this.assertSafeGemini3Continuation(messages, pricingContext.model);
|
|
4630
4664
|
const headers = this.buildHeaders(await this.resolveKey());
|
|
4631
|
-
const recorder = new CallTimingRecorder();
|
|
4665
|
+
const recorder = new CallTimingRecorder(options.requestLifecycle);
|
|
4632
4666
|
const res = await fetchWithRetry(
|
|
4633
4667
|
`${this.baseUrl}/models/${pricingContext.model}:streamGenerateContent?alt=sse`,
|
|
4634
4668
|
{
|
|
@@ -4665,7 +4699,7 @@ var GeminiProvider = class {
|
|
|
4665
4699
|
this.assertSafeInteractionOptions(options);
|
|
4666
4700
|
const body = this.buildInteractionRequestBody(messages, options, false);
|
|
4667
4701
|
const headers = this.buildHeaders(await this.resolveKey());
|
|
4668
|
-
const recorder = new CallTimingRecorder();
|
|
4702
|
+
const recorder = new CallTimingRecorder(options.requestLifecycle);
|
|
4669
4703
|
const res = await fetchWithRetry(
|
|
4670
4704
|
`${this.baseUrl}/interactions`,
|
|
4671
4705
|
{ method: "POST", headers, body: JSON.stringify(body), signal: options.signal },
|
|
@@ -4691,7 +4725,7 @@ var GeminiProvider = class {
|
|
|
4691
4725
|
this.assertSafeInteractionOptions(options);
|
|
4692
4726
|
const body = this.buildInteractionRequestBody(messages, options, true);
|
|
4693
4727
|
const headers = this.buildHeaders(await this.resolveKey());
|
|
4694
|
-
const recorder = new CallTimingRecorder();
|
|
4728
|
+
const recorder = new CallTimingRecorder(options.requestLifecycle);
|
|
4695
4729
|
const res = await fetchWithRetry(
|
|
4696
4730
|
`${this.baseUrl}/interactions?alt=sse`,
|
|
4697
4731
|
{ method: "POST", headers, body: JSON.stringify(body), signal: options.signal },
|
|
@@ -6410,7 +6444,7 @@ var GEMINI_AUDIO_MEDIA_TYPES = /* @__PURE__ */ new Set([
|
|
|
6410
6444
|
"audio/mulaw",
|
|
6411
6445
|
"audio/webm"
|
|
6412
6446
|
]);
|
|
6413
|
-
function
|
|
6447
|
+
function abortError() {
|
|
6414
6448
|
return new DOMException("The transcription operation was aborted", "AbortError");
|
|
6415
6449
|
}
|
|
6416
6450
|
function audioMime(audio) {
|
|
@@ -6442,13 +6476,13 @@ function secondsOffset(value) {
|
|
|
6442
6476
|
function sleep3(ms, signal) {
|
|
6443
6477
|
return new Promise((resolve2, reject) => {
|
|
6444
6478
|
if (signal?.aborted) {
|
|
6445
|
-
reject(
|
|
6479
|
+
reject(abortError());
|
|
6446
6480
|
return;
|
|
6447
6481
|
}
|
|
6448
6482
|
const timer = setTimeout(done, ms);
|
|
6449
6483
|
const onAbort = () => {
|
|
6450
6484
|
clearTimeout(timer);
|
|
6451
|
-
done(
|
|
6485
|
+
done(abortError());
|
|
6452
6486
|
};
|
|
6453
6487
|
function done(error) {
|
|
6454
6488
|
signal?.removeEventListener("abort", onAbort);
|
|
@@ -7769,7 +7803,7 @@ function isCostBearingLeaf(event) {
|
|
|
7769
7803
|
return COST_LEAF_SET.has(event.type);
|
|
7770
7804
|
}
|
|
7771
7805
|
function isUnpricedLeaf(event) {
|
|
7772
|
-
return event.type !== void 0 && COST_LEAF_SET.has(event.type) && !isUsableCost(event.cost) && hasPositiveBillableWork(event);
|
|
7806
|
+
return event.type !== void 0 && COST_LEAF_SET.has(event.type) && !isUsableCost(event.cost) && (event.unpriced === true || hasPositiveBillableWork(event));
|
|
7773
7807
|
}
|
|
7774
7808
|
function isRootLevel(event) {
|
|
7775
7809
|
const d = event.depth;
|
|
@@ -9055,18 +9089,27 @@ function parseDuration(duration) {
|
|
|
9055
9089
|
if (!match) throw new Error(`Invalid duration format: "${duration}"`);
|
|
9056
9090
|
const value = parseFloat(match[1]);
|
|
9057
9091
|
const unit = match[2];
|
|
9092
|
+
let milliseconds;
|
|
9058
9093
|
switch (unit) {
|
|
9059
9094
|
case "ms":
|
|
9060
|
-
|
|
9095
|
+
milliseconds = value;
|
|
9096
|
+
break;
|
|
9061
9097
|
case "s":
|
|
9062
|
-
|
|
9098
|
+
milliseconds = value * 1e3;
|
|
9099
|
+
break;
|
|
9063
9100
|
case "m":
|
|
9064
|
-
|
|
9101
|
+
milliseconds = value * 6e4;
|
|
9102
|
+
break;
|
|
9065
9103
|
case "h":
|
|
9066
|
-
|
|
9104
|
+
milliseconds = value * 36e5;
|
|
9105
|
+
break;
|
|
9067
9106
|
default:
|
|
9068
9107
|
throw new Error(`Unknown duration unit: "${unit}"`);
|
|
9069
9108
|
}
|
|
9109
|
+
if (!Number.isFinite(milliseconds)) {
|
|
9110
|
+
throw new Error(`Duration is too large: "${duration}"`);
|
|
9111
|
+
}
|
|
9112
|
+
return milliseconds;
|
|
9070
9113
|
}
|
|
9071
9114
|
function parseCost(cost) {
|
|
9072
9115
|
const match = cost.match(/^\$?([\d.]+)$/);
|
|
@@ -9722,6 +9765,42 @@ function recordToolSpanOutcome(span, outcome) {
|
|
|
9722
9765
|
|
|
9723
9766
|
// src/context.ts
|
|
9724
9767
|
var signalStorage = new import_node_async_hooks.AsyncLocalStorage();
|
|
9768
|
+
var hardSignalStorage = new import_node_async_hooks.AsyncLocalStorage();
|
|
9769
|
+
var timeoutTrackerStorage = new import_node_async_hooks.AsyncLocalStorage();
|
|
9770
|
+
var MAX_TIMER_DELAY_MS = 2147483647;
|
|
9771
|
+
function composeAbortSignals(...signals) {
|
|
9772
|
+
const active = signals.filter((signal) => signal !== void 0);
|
|
9773
|
+
if (active.length === 0) return void 0;
|
|
9774
|
+
if (active.length === 1) return active[0];
|
|
9775
|
+
return AbortSignal.any(active);
|
|
9776
|
+
}
|
|
9777
|
+
function raceWithAbortSignal(promise, signal) {
|
|
9778
|
+
if (!signal) return promise;
|
|
9779
|
+
if (signal.aborted) {
|
|
9780
|
+
void promise.catch(() => {
|
|
9781
|
+
});
|
|
9782
|
+
return Promise.reject(signal.reason);
|
|
9783
|
+
}
|
|
9784
|
+
return new Promise((resolve2, reject) => {
|
|
9785
|
+
let settled = false;
|
|
9786
|
+
const finish = (callback) => {
|
|
9787
|
+
if (settled) return;
|
|
9788
|
+
settled = true;
|
|
9789
|
+
signal.removeEventListener("abort", onAbort);
|
|
9790
|
+
callback();
|
|
9791
|
+
};
|
|
9792
|
+
const onAbort = () => finish(() => reject(signal.reason));
|
|
9793
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
9794
|
+
if (signal.aborted) onAbort();
|
|
9795
|
+
promise.then(
|
|
9796
|
+
(value) => finish(() => resolve2(value)),
|
|
9797
|
+
(error) => finish(() => reject(error))
|
|
9798
|
+
);
|
|
9799
|
+
});
|
|
9800
|
+
}
|
|
9801
|
+
function pausedHumanWaitMs(tracker, now = Date.now()) {
|
|
9802
|
+
return tracker.humanWaitMs + (tracker.activeHumanWaits > 0 && tracker.humanWaitStartedAt !== void 0 ? now - tracker.humanWaitStartedAt : 0);
|
|
9803
|
+
}
|
|
9725
9804
|
var DEFAULT_BRANCH_DRAIN_TIMEOUT_MS = 5e3;
|
|
9726
9805
|
function resolveBranchDrainTimeoutMs(value) {
|
|
9727
9806
|
const resolved = value === void 0 ? DEFAULT_BRANCH_DRAIN_TIMEOUT_MS : value;
|
|
@@ -10523,7 +10602,10 @@ var WorkflowContext = class _WorkflowContext {
|
|
|
10523
10602
|
tool_call_id: parsed.callId
|
|
10524
10603
|
});
|
|
10525
10604
|
}
|
|
10526
|
-
if (settlement.abortError !== void 0)
|
|
10605
|
+
if (settlement.abortError !== void 0) {
|
|
10606
|
+
signal?.throwIfAborted();
|
|
10607
|
+
throw settlement.abortError;
|
|
10608
|
+
}
|
|
10527
10609
|
}
|
|
10528
10610
|
// ── ctx.ask() ─────────────────────────────────────────────────────────
|
|
10529
10611
|
async ask(agent2, prompt, options) {
|
|
@@ -10539,7 +10621,10 @@ var WorkflowContext = class _WorkflowContext {
|
|
|
10539
10621
|
const promptText = inputText(normalizedInput);
|
|
10540
10622
|
const inputDescriptor = describeModelInput(normalizedInput);
|
|
10541
10623
|
const agentName = agent2._name;
|
|
10542
|
-
|
|
10624
|
+
const inheritedHardSignal = hardSignalStorage.getStore() ?? this.signal;
|
|
10625
|
+
const hardAskSignal = composeAbortSignals(inheritedHardSignal, options?.signal);
|
|
10626
|
+
const askSignal = composeAbortSignals(this.currentSignal, options?.signal);
|
|
10627
|
+
const runAsk = () => this._checkpoint(
|
|
10543
10628
|
this._autoCheckpointName("ask", agentName),
|
|
10544
10629
|
async () => {
|
|
10545
10630
|
const parentFrame = askStorage.getStore();
|
|
@@ -10694,8 +10779,25 @@ var WorkflowContext = class _WorkflowContext {
|
|
|
10694
10779
|
},
|
|
10695
10780
|
{ agent: agentName }
|
|
10696
10781
|
);
|
|
10782
|
+
const runWithAskSignal = () => askSignal ? signalStorage.run(askSignal, runAsk) : runAsk();
|
|
10783
|
+
return hardAskSignal ? hardSignalStorage.run(hardAskSignal, runWithAskSignal) : runWithAskSignal();
|
|
10697
10784
|
}
|
|
10698
10785
|
async executeAgentCall(agent2, input, options, handoffMessages, usageCapture, sessionHistory = normalizeSessionHistory(this.sessionHistory)) {
|
|
10786
|
+
const tracker = { humanWaitMs: 0, activeHumanWaits: 0 };
|
|
10787
|
+
const enclosing = timeoutTrackerStorage.getStore() ?? [];
|
|
10788
|
+
return timeoutTrackerStorage.run(
|
|
10789
|
+
[...enclosing, tracker],
|
|
10790
|
+
() => this.executeAgentCallImpl(
|
|
10791
|
+
agent2,
|
|
10792
|
+
input,
|
|
10793
|
+
options,
|
|
10794
|
+
handoffMessages,
|
|
10795
|
+
usageCapture,
|
|
10796
|
+
sessionHistory
|
|
10797
|
+
)
|
|
10798
|
+
);
|
|
10799
|
+
}
|
|
10800
|
+
async executeAgentCallImpl(agent2, input, options, handoffMessages, usageCapture, sessionHistory = normalizeSessionHistory(this.sessionHistory)) {
|
|
10699
10801
|
if (this.budgetContext?.exceeded) {
|
|
10700
10802
|
const { limit, totalCost: spent, policy } = this.budgetContext;
|
|
10701
10803
|
if (policy === "warn") {
|
|
@@ -10935,8 +11037,18 @@ ${appendedSchemaText}`;
|
|
|
10935
11037
|
}
|
|
10936
11038
|
}
|
|
10937
11039
|
const maxTurns = agent2._config.maxTurns ?? 25;
|
|
10938
|
-
const timeoutMs = parseDuration(
|
|
11040
|
+
const timeoutMs = parseDuration(
|
|
11041
|
+
options?.timeout ?? agent2._config.timeout ?? this.config.defaults?.timeout ?? "60s"
|
|
11042
|
+
);
|
|
11043
|
+
const stallTimeout = options?.stallTimeout ?? agent2._config.stallTimeout ?? this.config.defaults?.stallTimeout;
|
|
11044
|
+
const stallTimeoutMs = stallTimeout === void 0 ? void 0 : parseDuration(stallTimeout);
|
|
11045
|
+
if (stallTimeoutMs !== void 0 && stallTimeoutMs > MAX_TIMER_DELAY_MS) {
|
|
11046
|
+
throw new RangeError(
|
|
11047
|
+
`stallTimeout exceeds the maximum supported timer duration of ${MAX_TIMER_DELAY_MS}ms`
|
|
11048
|
+
);
|
|
11049
|
+
}
|
|
10939
11050
|
const startTime = Date.now();
|
|
11051
|
+
const timeoutTracker = timeoutTrackerStorage.getStore()?.at(-1);
|
|
10940
11052
|
const timingTotals = { turns: 0, queuedMs: 0, retryMs: 0, wireMs: 0 };
|
|
10941
11053
|
const currentMessages = [...messages];
|
|
10942
11054
|
let turns = 0;
|
|
@@ -10951,7 +11063,8 @@ ${appendedSchemaText}`;
|
|
|
10951
11063
|
let lastStartMaxAttempts = 1;
|
|
10952
11064
|
while (turns < maxTurns) {
|
|
10953
11065
|
this.currentSignal?.throwIfAborted();
|
|
10954
|
-
const
|
|
11066
|
+
const now = Date.now();
|
|
11067
|
+
const elapsedMs = now - startTime - (timeoutTracker ? pausedHumanWaitMs(timeoutTracker, now) : 0);
|
|
10955
11068
|
if (elapsedMs > timeoutMs) {
|
|
10956
11069
|
throw new TimeoutError(
|
|
10957
11070
|
"ctx.ask()",
|
|
@@ -10965,7 +11078,8 @@ ${appendedSchemaText}`;
|
|
|
10965
11078
|
0,
|
|
10966
11079
|
elapsedMs - timingTotals.queuedMs - timingTotals.retryMs - timingTotals.wireMs
|
|
10967
11080
|
)
|
|
10968
|
-
} : void 0
|
|
11081
|
+
} : void 0,
|
|
11082
|
+
agent2._name
|
|
10969
11083
|
);
|
|
10970
11084
|
}
|
|
10971
11085
|
turns++;
|
|
@@ -11012,6 +11126,43 @@ ${appendedSchemaText}`;
|
|
|
11012
11126
|
providerOptions,
|
|
11013
11127
|
signal: this.currentSignal
|
|
11014
11128
|
};
|
|
11129
|
+
const requestSignal = chatOptions.signal;
|
|
11130
|
+
const hardRequestSignal = hardSignalStorage.getStore() ?? this.signal;
|
|
11131
|
+
const stallController = stallTimeoutMs === void 0 ? void 0 : new AbortController();
|
|
11132
|
+
const stallReason = stallController === void 0 ? void 0 : new DOMException("Provider request stalled", "StallTimeout");
|
|
11133
|
+
let stallTimer;
|
|
11134
|
+
let providerCallActive = true;
|
|
11135
|
+
let requestDispatched = false;
|
|
11136
|
+
const clearStallTimer = () => {
|
|
11137
|
+
if (stallTimer !== void 0) {
|
|
11138
|
+
clearTimeout(stallTimer);
|
|
11139
|
+
stallTimer = void 0;
|
|
11140
|
+
}
|
|
11141
|
+
};
|
|
11142
|
+
const armStallTimer = () => {
|
|
11143
|
+
if (!providerCallActive || !stallController || !stallReason || stallTimeoutMs === void 0)
|
|
11144
|
+
return;
|
|
11145
|
+
requestDispatched = true;
|
|
11146
|
+
clearStallTimer();
|
|
11147
|
+
if (stallController.signal.aborted) return;
|
|
11148
|
+
stallTimer = setTimeout(() => stallController.abort(stallReason), stallTimeoutMs);
|
|
11149
|
+
};
|
|
11150
|
+
if (stallController) {
|
|
11151
|
+
chatOptions.signal = composeAbortSignals(requestSignal, stallController.signal);
|
|
11152
|
+
chatOptions.requestLifecycle = {
|
|
11153
|
+
onDispatch: armStallTimer,
|
|
11154
|
+
onRetry: clearStallTimer
|
|
11155
|
+
};
|
|
11156
|
+
}
|
|
11157
|
+
const providerSettlementSignal = composeAbortSignals(
|
|
11158
|
+
hardRequestSignal,
|
|
11159
|
+
stallController?.signal
|
|
11160
|
+
);
|
|
11161
|
+
const throwIfRequestStalled = () => {
|
|
11162
|
+
if (stallReason !== void 0 && providerSettlementSignal?.reason === stallReason) {
|
|
11163
|
+
throw new StallTimeoutError("ctx.ask()", stallTimeoutMs, agent2._name);
|
|
11164
|
+
}
|
|
11165
|
+
};
|
|
11015
11166
|
if (options?.schema && toolDefs.length === 0) {
|
|
11016
11167
|
const nativeOut = options?.nativeStructuredOutput ?? agent2._config.nativeStructuredOutput ?? false;
|
|
11017
11168
|
chatOptions.responseFormat = nativeOut ? {
|
|
@@ -11098,55 +11249,77 @@ ${appendedSchemaText}`;
|
|
|
11098
11249
|
});
|
|
11099
11250
|
}
|
|
11100
11251
|
}) : void 0;
|
|
11101
|
-
|
|
11252
|
+
if (stallController && provider.reportsRequestLifecycle !== true) armStallTimer();
|
|
11253
|
+
const providerStream = provider.stream(
|
|
11102
11254
|
cloneMessagesForProvider(currentMessages),
|
|
11103
11255
|
chatOptions
|
|
11104
|
-
)
|
|
11105
|
-
|
|
11106
|
-
|
|
11107
|
-
|
|
11108
|
-
|
|
11109
|
-
|
|
11110
|
-
|
|
11111
|
-
|
|
11112
|
-
|
|
11113
|
-
|
|
11114
|
-
|
|
11115
|
-
|
|
11116
|
-
|
|
11117
|
-
|
|
11118
|
-
|
|
11119
|
-
|
|
11120
|
-
|
|
11121
|
-
|
|
11122
|
-
|
|
11123
|
-
|
|
11256
|
+
);
|
|
11257
|
+
const iterator = providerStream[Symbol.asyncIterator]();
|
|
11258
|
+
try {
|
|
11259
|
+
while (true) {
|
|
11260
|
+
const next = await raceWithAbortSignal(
|
|
11261
|
+
Promise.resolve(iterator.next()),
|
|
11262
|
+
providerSettlementSignal
|
|
11263
|
+
);
|
|
11264
|
+
if (next.done) break;
|
|
11265
|
+
const chunk = next.value;
|
|
11266
|
+
if (stallController) armStallTimer();
|
|
11267
|
+
if (chunk.type === "text_delta") {
|
|
11268
|
+
content2 += chunk.content;
|
|
11269
|
+
this.emitEvent({ type: "token", data: chunk.content });
|
|
11270
|
+
if (walker) {
|
|
11271
|
+
walker.processChunk(chunk.content);
|
|
11272
|
+
if (walker.consumeBoundary()) {
|
|
11273
|
+
let parsed;
|
|
11274
|
+
try {
|
|
11275
|
+
parsed = parsePartialJson(extractJson(content2));
|
|
11276
|
+
} catch {
|
|
11277
|
+
parsed = void 0;
|
|
11278
|
+
}
|
|
11279
|
+
if (parsed !== void 0) {
|
|
11280
|
+
this.emitEvent({
|
|
11281
|
+
type: "partial_object",
|
|
11282
|
+
agent: agent2._name,
|
|
11283
|
+
attempt: currentAttempt,
|
|
11284
|
+
data: { object: parsed }
|
|
11285
|
+
});
|
|
11286
|
+
}
|
|
11124
11287
|
}
|
|
11125
11288
|
}
|
|
11126
|
-
}
|
|
11127
|
-
|
|
11128
|
-
|
|
11129
|
-
|
|
11130
|
-
|
|
11131
|
-
|
|
11132
|
-
|
|
11133
|
-
|
|
11134
|
-
|
|
11135
|
-
|
|
11136
|
-
if (chunk.
|
|
11137
|
-
|
|
11138
|
-
|
|
11139
|
-
streamTiming = chunk.timing;
|
|
11140
|
-
if (chunk.usage) {
|
|
11289
|
+
} else if (chunk.type === "thinking_delta") {
|
|
11290
|
+
thinkingContent += chunk.content;
|
|
11291
|
+
} else if (chunk.type === "tool_call_delta") {
|
|
11292
|
+
let buffer = toolCallBuffers.get(chunk.id);
|
|
11293
|
+
if (!buffer) {
|
|
11294
|
+
buffer = { id: chunk.id, name: "", arguments: "" };
|
|
11295
|
+
toolCallBuffers.set(chunk.id, buffer);
|
|
11296
|
+
}
|
|
11297
|
+
if (chunk.name) buffer.name = chunk.name;
|
|
11298
|
+
if (chunk.arguments) buffer.arguments += chunk.arguments;
|
|
11299
|
+
} else if (chunk.type === "done") {
|
|
11300
|
+
streamProviderMetadata = chunk.providerMetadata;
|
|
11301
|
+
streamTiming = chunk.timing;
|
|
11141
11302
|
response = {
|
|
11142
11303
|
content: content2,
|
|
11143
11304
|
tool_calls: void 0,
|
|
11144
11305
|
usage: chunk.usage,
|
|
11145
|
-
cost: chunk.cost
|
|
11306
|
+
cost: chunk.cost,
|
|
11307
|
+
providerMetadata: chunk.providerMetadata,
|
|
11308
|
+
timing: chunk.timing
|
|
11146
11309
|
};
|
|
11147
11310
|
}
|
|
11148
11311
|
}
|
|
11312
|
+
} catch (error) {
|
|
11313
|
+
if (iterator.return) {
|
|
11314
|
+
try {
|
|
11315
|
+
void Promise.resolve(iterator.return(void 0)).catch(() => {
|
|
11316
|
+
});
|
|
11317
|
+
} catch {
|
|
11318
|
+
}
|
|
11319
|
+
}
|
|
11320
|
+
throw error;
|
|
11149
11321
|
}
|
|
11322
|
+
throwIfRequestStalled();
|
|
11150
11323
|
for (const buffer of toolCallBuffers.values()) {
|
|
11151
11324
|
toolCalls.push({
|
|
11152
11325
|
id: buffer.id,
|
|
@@ -11171,16 +11344,27 @@ ${appendedSchemaText}`;
|
|
|
11171
11344
|
response.thinking_content = thinkingContent;
|
|
11172
11345
|
}
|
|
11173
11346
|
} else {
|
|
11174
|
-
|
|
11347
|
+
if (stallController && provider.reportsRequestLifecycle !== true) armStallTimer();
|
|
11348
|
+
response = await raceWithAbortSignal(
|
|
11349
|
+
provider.chat(cloneMessagesForProvider(currentMessages), chatOptions),
|
|
11350
|
+
providerSettlementSignal
|
|
11351
|
+
);
|
|
11352
|
+
throwIfRequestStalled();
|
|
11175
11353
|
}
|
|
11176
11354
|
} catch (err) {
|
|
11177
|
-
|
|
11178
|
-
|
|
11355
|
+
const callError = stallReason !== void 0 && providerSettlementSignal?.reason === stallReason ? new StallTimeoutError("ctx.ask()", stallTimeoutMs, agent2._name) : err;
|
|
11356
|
+
if (richRequest) this.recordRichFailure(callError);
|
|
11357
|
+
const failureTiming = callError instanceof ProviderError ? callError.timing : void 0;
|
|
11179
11358
|
this.emitEvent({
|
|
11180
11359
|
type: "agent_call_end",
|
|
11181
11360
|
agent: agent2._name,
|
|
11182
11361
|
model: effectiveModelUri,
|
|
11183
11362
|
promptVersion: agent2._config.version,
|
|
11363
|
+
// A dispatched request abandoned at the runtime boundary may still
|
|
11364
|
+
// be billed even though a non-cooperative provider supplied no
|
|
11365
|
+
// usage. Preserve budget honesty by marking the known total as a
|
|
11366
|
+
// lower bound rather than presenting an exact $0.
|
|
11367
|
+
...callError instanceof StallTimeoutError && requestDispatched ? { unpriced: true } : {},
|
|
11184
11368
|
duration: Date.now() - turnStart,
|
|
11185
11369
|
// Top-level beside `duration`, exactly as on the success path.
|
|
11186
11370
|
...failureTiming ? { timing: failureTiming } : {},
|
|
@@ -11188,14 +11372,17 @@ ${appendedSchemaText}`;
|
|
|
11188
11372
|
response: "",
|
|
11189
11373
|
turn: turns,
|
|
11190
11374
|
...retryReason ? { retryReason } : {},
|
|
11191
|
-
error: this._observerErrorProjection(
|
|
11375
|
+
error: this._observerErrorProjection(callError)?.message ?? legacyErrorMessage(callError),
|
|
11192
11376
|
// Enrich with typed-error metadata when available. `body` is
|
|
11193
11377
|
// deliberately NOT emitted — it's redaction-eligible (see
|
|
11194
11378
|
// docs/security.md). `data.error` already carries the message.
|
|
11195
|
-
...providerErrorEventMetadata(
|
|
11379
|
+
...providerErrorEventMetadata(callError, richRequest)
|
|
11196
11380
|
}
|
|
11197
11381
|
});
|
|
11198
|
-
throw
|
|
11382
|
+
throw callError;
|
|
11383
|
+
} finally {
|
|
11384
|
+
providerCallActive = false;
|
|
11385
|
+
clearStallTimer();
|
|
11199
11386
|
}
|
|
11200
11387
|
if (usageCapture && response.usage) {
|
|
11201
11388
|
usageCapture.value = response.usage;
|
|
@@ -12720,46 +12907,52 @@ ${summaryResponse.content}`
|
|
|
12720
12907
|
}
|
|
12721
12908
|
// ── ctx.awaitHuman() ──────────────────────────────────────────────────
|
|
12722
12909
|
async awaitHuman(options) {
|
|
12723
|
-
|
|
12724
|
-
|
|
12725
|
-
|
|
12726
|
-
|
|
12727
|
-
|
|
12728
|
-
|
|
12729
|
-
|
|
12730
|
-
|
|
12731
|
-
|
|
12732
|
-
|
|
12733
|
-
|
|
12734
|
-
|
|
12910
|
+
const trackers = timeoutTrackerStorage.getStore();
|
|
12911
|
+
const startedAt = Date.now();
|
|
12912
|
+
for (const tracker of trackers ?? []) {
|
|
12913
|
+
if (tracker.activeHumanWaits++ === 0) tracker.humanWaitStartedAt = startedAt;
|
|
12914
|
+
}
|
|
12915
|
+
try {
|
|
12916
|
+
if (this.spanManager) {
|
|
12917
|
+
return await this.spanManager.withSpanAsync(
|
|
12918
|
+
"axl.ctx.awaitHuman",
|
|
12919
|
+
{
|
|
12920
|
+
"axl.awaitHuman.channel": options.channel
|
|
12921
|
+
},
|
|
12922
|
+
async (span) => {
|
|
12923
|
+
const start = Date.now();
|
|
12924
|
+
const result = await this._awaitHumanImpl(options);
|
|
12925
|
+
span.setAttribute("axl.awaitHuman.wait_duration", Date.now() - start);
|
|
12926
|
+
span.setAttribute("axl.awaitHuman.approved", result.approved);
|
|
12927
|
+
return result;
|
|
12928
|
+
}
|
|
12929
|
+
);
|
|
12930
|
+
}
|
|
12931
|
+
return await this._awaitHumanImpl(options);
|
|
12932
|
+
} finally {
|
|
12933
|
+
const finishedAt = Date.now();
|
|
12934
|
+
for (const tracker of trackers ?? []) {
|
|
12935
|
+
tracker.activeHumanWaits--;
|
|
12936
|
+
if (tracker.activeHumanWaits === 0 && tracker.humanWaitStartedAt !== void 0) {
|
|
12937
|
+
tracker.humanWaitMs += finishedAt - tracker.humanWaitStartedAt;
|
|
12938
|
+
tracker.humanWaitStartedAt = void 0;
|
|
12735
12939
|
}
|
|
12736
|
-
|
|
12940
|
+
}
|
|
12737
12941
|
}
|
|
12738
|
-
return this._awaitHumanImpl(options);
|
|
12739
12942
|
}
|
|
12740
12943
|
async _awaitHumanImpl(options) {
|
|
12741
12944
|
const branchSignal = this.currentSignal;
|
|
12742
|
-
const makeAbortError = (reason) => {
|
|
12743
|
-
if (typeof DOMException !== "undefined") {
|
|
12744
|
-
return new DOMException(
|
|
12745
|
-
typeof reason === "string" ? reason : "awaitHuman aborted",
|
|
12746
|
-
"AbortError"
|
|
12747
|
-
);
|
|
12748
|
-
}
|
|
12749
|
-
const err = new Error(typeof reason === "string" ? reason : "awaitHuman aborted");
|
|
12750
|
-
err.name = "AbortError";
|
|
12751
|
-
return err;
|
|
12752
|
-
};
|
|
12753
12945
|
const awaitWithAbort = async (promise, signal2 = branchSignal) => {
|
|
12754
12946
|
if (!signal2) return promise;
|
|
12755
|
-
|
|
12947
|
+
signal2.throwIfAborted();
|
|
12756
12948
|
let onAbort;
|
|
12757
12949
|
try {
|
|
12758
12950
|
return await Promise.race([
|
|
12759
12951
|
promise,
|
|
12760
12952
|
new Promise((_, reject) => {
|
|
12761
|
-
onAbort = () => reject(
|
|
12953
|
+
onAbort = () => reject(signal2.reason);
|
|
12762
12954
|
signal2.addEventListener("abort", onAbort, { once: true });
|
|
12955
|
+
if (signal2.aborted) onAbort();
|
|
12763
12956
|
})
|
|
12764
12957
|
]);
|
|
12765
12958
|
} finally {
|
|
@@ -12767,12 +12960,12 @@ ${summaryResponse.content}`
|
|
|
12767
12960
|
}
|
|
12768
12961
|
};
|
|
12769
12962
|
if (this.awaitHumanHandler) {
|
|
12770
|
-
|
|
12963
|
+
branchSignal?.throwIfAborted();
|
|
12771
12964
|
this.emitEvent({
|
|
12772
12965
|
type: "await_human",
|
|
12773
12966
|
data: { channel: options.channel, prompt: options.prompt }
|
|
12774
12967
|
});
|
|
12775
|
-
|
|
12968
|
+
branchSignal?.throwIfAborted();
|
|
12776
12969
|
const decision2 = parseHumanDecision(
|
|
12777
12970
|
await awaitWithAbort(Promise.resolve(this.awaitHumanHandler(options)))
|
|
12778
12971
|
);
|
|
@@ -12827,12 +13020,12 @@ ${summaryResponse.content}`
|
|
|
12827
13020
|
const abortListener = () => {
|
|
12828
13021
|
registeredResolver.cancelled = true;
|
|
12829
13022
|
markReady();
|
|
12830
|
-
rejectDecision(
|
|
13023
|
+
rejectDecision(signal.reason);
|
|
12831
13024
|
};
|
|
12832
13025
|
signal.addEventListener("abort", abortListener, { once: true });
|
|
12833
13026
|
let decision;
|
|
12834
13027
|
try {
|
|
12835
|
-
|
|
13028
|
+
signal.throwIfAborted();
|
|
12836
13029
|
if (this.stateStore) {
|
|
12837
13030
|
saveAttempted = true;
|
|
12838
13031
|
await this.stateStore.savePendingDecision(this.executionId, {
|
|
@@ -12843,7 +13036,7 @@ ${summaryResponse.content}`
|
|
|
12843
13036
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
12844
13037
|
});
|
|
12845
13038
|
}
|
|
12846
|
-
|
|
13039
|
+
signal.throwIfAborted();
|
|
12847
13040
|
this.emitEvent({
|
|
12848
13041
|
type: "await_human",
|
|
12849
13042
|
data: { channel: options.channel, prompt: options.prompt }
|
|
@@ -13313,7 +13506,7 @@ ${summaryResponse.content}`
|
|
|
13313
13506
|
data: partial.data
|
|
13314
13507
|
});
|
|
13315
13508
|
};
|
|
13316
|
-
const
|
|
13509
|
+
const abortError2 = () => new DOMException("The transcription operation was aborted", "AbortError");
|
|
13317
13510
|
const cleanupStatus = (value) => value === "not_required" || value === "deleted" || value === "failed" || value === "timed_out" ? value : void 0;
|
|
13318
13511
|
const safeProviderFailure = (error, provider, model) => {
|
|
13319
13512
|
const details = error && typeof error === "object" ? error : void 0;
|
|
@@ -13364,7 +13557,7 @@ ${summaryResponse.content}`
|
|
|
13364
13557
|
hasWork: false
|
|
13365
13558
|
})
|
|
13366
13559
|
});
|
|
13367
|
-
throw
|
|
13560
|
+
throw abortError2();
|
|
13368
13561
|
}
|
|
13369
13562
|
if (this.budgetContext?.exceeded) {
|
|
13370
13563
|
const { limit, totalCost: spent, policy } = this.budgetContext;
|
|
@@ -13430,7 +13623,7 @@ ${summaryResponse.content}`
|
|
|
13430
13623
|
...failure.cleanup ? [{ cleanupStatus: failure.cleanup }] : []
|
|
13431
13624
|
)
|
|
13432
13625
|
});
|
|
13433
|
-
throw
|
|
13626
|
+
throw abortError2();
|
|
13434
13627
|
}
|
|
13435
13628
|
if (failure.accounting.cost !== void 0)
|
|
13436
13629
|
this._accumulateBudgetCost(failure.accounting.cost);
|
|
@@ -13473,7 +13666,7 @@ ${summaryResponse.content}`
|
|
|
13473
13666
|
...cleanupStatus(result.cleanupStatus) ? [{ cleanupStatus: cleanupStatus(result.cleanupStatus) }] : []
|
|
13474
13667
|
)
|
|
13475
13668
|
});
|
|
13476
|
-
throw
|
|
13669
|
+
throw abortError2();
|
|
13477
13670
|
}
|
|
13478
13671
|
let transcript;
|
|
13479
13672
|
try {
|
|
@@ -13559,9 +13752,9 @@ ${summaryResponse.content}`
|
|
|
13559
13752
|
const cost = partial.cost;
|
|
13560
13753
|
if (COST_BEARING_LEAF_TYPES.includes(partial.type)) {
|
|
13561
13754
|
const usable = isUsableCost(cost);
|
|
13562
|
-
const unpriced = !usable && hasPositiveBillableWork(
|
|
13755
|
+
const unpriced = !usable && (partial.unpriced === true || hasPositiveBillableWork(
|
|
13563
13756
|
partial
|
|
13564
|
-
);
|
|
13757
|
+
));
|
|
13565
13758
|
if (frame) {
|
|
13566
13759
|
if (usable) frame.askCost.value += cost;
|
|
13567
13760
|
else if (unpriced) frame.askUnpriced = true;
|
|
@@ -13572,7 +13765,7 @@ ${summaryResponse.content}`
|
|
|
13572
13765
|
if (!this.budgetContext.unpricedWarned && Number.isFinite(this.budgetContext.limit)) {
|
|
13573
13766
|
this.budgetContext.unpricedWarned = true;
|
|
13574
13767
|
console.warn(
|
|
13575
|
-
"Budget honesty:
|
|
13768
|
+
"Budget honesty: unknown-cost work detected \u2014 this budget's cost limit is a lower bound and is NOT enforced on unknown spend. See docs/observability.md#budget-honesty."
|
|
13576
13769
|
);
|
|
13577
13770
|
}
|
|
13578
13771
|
}
|
|
@@ -15541,12 +15734,13 @@ function forwardAbortSignal(external, internal) {
|
|
|
15541
15734
|
if (!external) return () => {
|
|
15542
15735
|
};
|
|
15543
15736
|
if (external.aborted) {
|
|
15544
|
-
internal.abort();
|
|
15737
|
+
internal.abort(external.reason);
|
|
15545
15738
|
return () => {
|
|
15546
15739
|
};
|
|
15547
15740
|
}
|
|
15548
|
-
const onAbort = () => internal.abort();
|
|
15741
|
+
const onAbort = () => internal.abort(external.reason);
|
|
15549
15742
|
external.addEventListener("abort", onAbort, { once: true });
|
|
15743
|
+
if (external.aborted) onAbort();
|
|
15550
15744
|
return () => external.removeEventListener("abort", onAbort);
|
|
15551
15745
|
}
|
|
15552
15746
|
var AxlRuntime = class extends import_node_events2.EventEmitter {
|
|
@@ -18028,6 +18222,7 @@ function cosineSimilarity2(a, b) {
|
|
|
18028
18222
|
SQLiteStore,
|
|
18029
18223
|
Session,
|
|
18030
18224
|
SqliteVectorStore,
|
|
18225
|
+
StallTimeoutError,
|
|
18031
18226
|
ThinkTagScanner,
|
|
18032
18227
|
TimeoutError,
|
|
18033
18228
|
ToolFailure,
|