@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.js
CHANGED
|
@@ -172,15 +172,22 @@ var NoConsensus = class extends AxlError {
|
|
|
172
172
|
var TimeoutError = class extends AxlError {
|
|
173
173
|
/** Latency attribution for the timed-out operation, when measurable. */
|
|
174
174
|
breakdown;
|
|
175
|
-
constructor(operation, timeoutMs, breakdown) {
|
|
175
|
+
constructor(operation, timeoutMs, breakdown, agent2) {
|
|
176
176
|
super(
|
|
177
177
|
"TIMEOUT",
|
|
178
|
-
`${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)` : "")
|
|
178
|
+
`${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}'` : "")
|
|
179
179
|
);
|
|
180
180
|
this.name = "TimeoutError";
|
|
181
181
|
if (breakdown) this.breakdown = breakdown;
|
|
182
182
|
}
|
|
183
183
|
};
|
|
184
|
+
var StallTimeoutError = class extends TimeoutError {
|
|
185
|
+
constructor(operation, timeoutMs, agent2) {
|
|
186
|
+
super(operation, timeoutMs, void 0, agent2);
|
|
187
|
+
this.name = "StallTimeoutError";
|
|
188
|
+
this.message = `${operation} provider request stalled for ${timeoutMs}ms` + (agent2 ? ` for agent '${agent2}'` : "");
|
|
189
|
+
}
|
|
190
|
+
};
|
|
184
191
|
function formatBudgetCost(cost) {
|
|
185
192
|
if (Number.isNaN(cost)) return "$NaN";
|
|
186
193
|
if (cost === Infinity) return "$Infinity";
|
|
@@ -853,6 +860,7 @@ async function fetchWithRetry(input, init, opts) {
|
|
|
853
860
|
message: err instanceof Error ? err.message : String(err)
|
|
854
861
|
});
|
|
855
862
|
}
|
|
863
|
+
observer?.onRetry?.(attempt + 1, Date.now());
|
|
856
864
|
await sleep2(jitter(BASE_DELAY_MS * 2 ** attempt), init?.signal ?? void 0);
|
|
857
865
|
continue;
|
|
858
866
|
}
|
|
@@ -868,6 +876,7 @@ async function fetchWithRetry(input, init, opts) {
|
|
|
868
876
|
}
|
|
869
877
|
const retryAfterMs = parseRetryAfter(res.headers);
|
|
870
878
|
const baseDelay = retryAfterMs !== void 0 ? Math.min(retryAfterMs, MAX_BACKOFF_MS) : BASE_DELAY_MS * 2 ** attempt;
|
|
879
|
+
observer?.onRetry?.(attempt + 1, Date.now());
|
|
871
880
|
await sleep2(jitter(baseDelay), init?.signal ?? void 0);
|
|
872
881
|
}
|
|
873
882
|
} finally {
|
|
@@ -877,12 +886,23 @@ async function fetchWithRetry(input, init, opts) {
|
|
|
877
886
|
|
|
878
887
|
// src/providers/call-timing.ts
|
|
879
888
|
var CallTimingRecorder = class {
|
|
889
|
+
constructor(requestLifecycle) {
|
|
890
|
+
this.requestLifecycle = requestLifecycle;
|
|
891
|
+
}
|
|
880
892
|
fetchTiming;
|
|
881
893
|
firstTokenAt;
|
|
894
|
+
/** Consumer suspension after pre-content chunks (for example, tool deltas). */
|
|
895
|
+
preFirstTokenConsumerMs = 0;
|
|
882
896
|
/** Cumulative time awaiting `reader.read()`, i.e. transport, not consumer. */
|
|
883
897
|
readWaitMs = 0;
|
|
884
898
|
/** Pass as `timing` in the `fetchWithRetry` options object. */
|
|
885
899
|
observer = {
|
|
900
|
+
onDispatch: () => {
|
|
901
|
+
this.requestLifecycle?.onDispatch?.();
|
|
902
|
+
},
|
|
903
|
+
onRetry: () => {
|
|
904
|
+
this.requestLifecycle?.onRetry?.();
|
|
905
|
+
},
|
|
886
906
|
onComplete: (timing) => {
|
|
887
907
|
this.fetchTiming = timing;
|
|
888
908
|
}
|
|
@@ -904,6 +924,12 @@ var CallTimingRecorder = class {
|
|
|
904
924
|
markFirstToken() {
|
|
905
925
|
this.firstTokenAt ??= Date.now();
|
|
906
926
|
}
|
|
927
|
+
/** Exclude backpressure after a pre-content yield from first-content latency. */
|
|
928
|
+
recordPreFirstTokenConsumerPause(startedAt) {
|
|
929
|
+
if (this.firstTokenAt === void 0) {
|
|
930
|
+
this.preFirstTokenConsumerMs += Math.max(0, Date.now() - startedAt);
|
|
931
|
+
}
|
|
932
|
+
}
|
|
907
933
|
/**
|
|
908
934
|
* Timing for a non-streaming call. Call once the response body is parsed.
|
|
909
935
|
*
|
|
@@ -927,13 +953,17 @@ var CallTimingRecorder = class {
|
|
|
927
953
|
const t = this.fetchTiming;
|
|
928
954
|
if (!t) return void 0;
|
|
929
955
|
const ttfbMs = Math.max(0, t.headersAt - t.dispatchedAt);
|
|
956
|
+
const firstTokenMs = this.firstTokenAt !== void 0 ? Math.max(0, this.firstTokenAt - t.dispatchedAt - this.preFirstTokenConsumerMs) : void 0;
|
|
930
957
|
return {
|
|
931
958
|
queuedMs: t.queuedMs,
|
|
932
959
|
attempts: t.attempts,
|
|
933
960
|
retryMs: t.retryMs,
|
|
934
961
|
ttfbMs,
|
|
935
|
-
...
|
|
936
|
-
|
|
962
|
+
...firstTokenMs !== void 0 ? { firstTokenMs } : {},
|
|
963
|
+
// Parsing and generator scheduling can happen after the first read has
|
|
964
|
+
// settled. Include that pre-first-token gap so the public relationship
|
|
965
|
+
// stays intuitive, without charging pauses after any chunk is yielded.
|
|
966
|
+
wireMs: Math.max(ttfbMs + this.readWaitMs, firstTokenMs ?? 0)
|
|
937
967
|
};
|
|
938
968
|
}
|
|
939
969
|
};
|
|
@@ -946,7 +976,9 @@ async function* withCallTiming(recorder, source) {
|
|
|
946
976
|
const timing = recorder.streamTiming();
|
|
947
977
|
yield timing ? { ...chunk, timing } : chunk;
|
|
948
978
|
} else {
|
|
979
|
+
const yieldedAt = Date.now();
|
|
949
980
|
yield chunk;
|
|
981
|
+
recorder.recordPreFirstTokenConsumerPause(yieldedAt);
|
|
950
982
|
}
|
|
951
983
|
}
|
|
952
984
|
}
|
|
@@ -956,9 +988,6 @@ function withChatTiming(recorder, response) {
|
|
|
956
988
|
}
|
|
957
989
|
|
|
958
990
|
// src/providers/rate-limiter.ts
|
|
959
|
-
function abortError() {
|
|
960
|
-
return Object.assign(new Error("The operation was aborted"), { name: "AbortError" });
|
|
961
|
-
}
|
|
962
991
|
var RateLimiter = class {
|
|
963
992
|
maxConcurrent;
|
|
964
993
|
minIntervalMs;
|
|
@@ -1007,11 +1036,11 @@ var RateLimiter = class {
|
|
|
1007
1036
|
* With `acquireTimeoutMs`, a waiter that sits in the queue too long rejects.
|
|
1008
1037
|
*/
|
|
1009
1038
|
acquire(signal) {
|
|
1010
|
-
if (signal?.aborted) return Promise.reject(
|
|
1039
|
+
if (signal?.aborted) return Promise.reject(signal.reason);
|
|
1011
1040
|
return new Promise((resolve2, reject) => {
|
|
1012
1041
|
const waiter = { resolve: resolve2, reject, signal };
|
|
1013
1042
|
if (signal) {
|
|
1014
|
-
waiter.onAbort = () => this.settleWaiter(waiter,
|
|
1043
|
+
waiter.onAbort = () => this.settleWaiter(waiter, signal.reason);
|
|
1015
1044
|
signal.addEventListener("abort", waiter.onAbort, { once: true });
|
|
1016
1045
|
}
|
|
1017
1046
|
if (this.acquireTimeoutMs != null) {
|
|
@@ -1311,6 +1340,7 @@ function normalizeMessageContent(content) {
|
|
|
1311
1340
|
}
|
|
1312
1341
|
var OpenAICompatibleProvider = class {
|
|
1313
1342
|
name;
|
|
1343
|
+
reportsRequestLifecycle = true;
|
|
1314
1344
|
inputCapabilities(model) {
|
|
1315
1345
|
return this.name === "openrouter" && model.trim().length > 0 ? { image: { sources: ["url", "bytes", "base64"] } } : {};
|
|
1316
1346
|
}
|
|
@@ -1407,7 +1437,7 @@ var OpenAICompatibleProvider = class {
|
|
|
1407
1437
|
async chat(messages, options) {
|
|
1408
1438
|
const headers = this.buildHeaders(await this.resolveKey());
|
|
1409
1439
|
const body = this.buildRequestBody(messages, options, false);
|
|
1410
|
-
const recorder = new CallTimingRecorder();
|
|
1440
|
+
const recorder = new CallTimingRecorder(options.requestLifecycle);
|
|
1411
1441
|
const res = await fetchWithRetry(
|
|
1412
1442
|
`${this.baseUrl}/chat/completions`,
|
|
1413
1443
|
{
|
|
@@ -1438,7 +1468,7 @@ var OpenAICompatibleProvider = class {
|
|
|
1438
1468
|
async *stream(messages, options) {
|
|
1439
1469
|
const headers = this.buildHeaders(await this.resolveKey());
|
|
1440
1470
|
const body = this.buildRequestBody(messages, options, true);
|
|
1441
|
-
const recorder = new CallTimingRecorder();
|
|
1471
|
+
const recorder = new CallTimingRecorder(options.requestLifecycle);
|
|
1442
1472
|
const res = await fetchWithRetry(
|
|
1443
1473
|
`${this.baseUrl}/chat/completions`,
|
|
1444
1474
|
{
|
|
@@ -2346,6 +2376,7 @@ function responseImageParts(parts) {
|
|
|
2346
2376
|
}
|
|
2347
2377
|
var OpenAIResponsesProvider = class {
|
|
2348
2378
|
name = "openai-responses";
|
|
2379
|
+
reportsRequestLifecycle = true;
|
|
2349
2380
|
inputCapabilities(model) {
|
|
2350
2381
|
return model.trim().length > 0 ? { image: { sources: ["url", "bytes", "base64", "provider-file"] } } : {};
|
|
2351
2382
|
}
|
|
@@ -2432,7 +2463,7 @@ var OpenAIResponsesProvider = class {
|
|
|
2432
2463
|
async chat(messages, options) {
|
|
2433
2464
|
const headers = this.buildHeaders(await this.resolveKey());
|
|
2434
2465
|
const body = this.buildRequestBody(messages, options, false);
|
|
2435
|
-
const recorder = new CallTimingRecorder();
|
|
2466
|
+
const recorder = new CallTimingRecorder(options.requestLifecycle);
|
|
2436
2467
|
const res = await fetchWithRetry(
|
|
2437
2468
|
`${this.baseUrl}/responses`,
|
|
2438
2469
|
{
|
|
@@ -2467,7 +2498,7 @@ var OpenAIResponsesProvider = class {
|
|
|
2467
2498
|
async *stream(messages, options) {
|
|
2468
2499
|
const headers = this.buildHeaders(await this.resolveKey());
|
|
2469
2500
|
const body = this.buildRequestBody(messages, options, true);
|
|
2470
|
-
const recorder = new CallTimingRecorder();
|
|
2501
|
+
const recorder = new CallTimingRecorder(options.requestLifecycle);
|
|
2471
2502
|
const res = await fetchWithRetry(
|
|
2472
2503
|
`${this.baseUrl}/responses`,
|
|
2473
2504
|
{
|
|
@@ -3271,6 +3302,7 @@ function mergeAnthropicUsage(initial, update) {
|
|
|
3271
3302
|
}
|
|
3272
3303
|
var AnthropicProvider = class {
|
|
3273
3304
|
name = "anthropic";
|
|
3305
|
+
reportsRequestLifecycle = true;
|
|
3274
3306
|
/** Report a clamped `effort`. Anthropic clamps to each model's supported
|
|
3275
3307
|
* `output_config.effort` levels, and models that always think fall back to
|
|
3276
3308
|
* adaptive `'low'` when asked to disable thinking. Only reported when the
|
|
@@ -3388,7 +3420,7 @@ var AnthropicProvider = class {
|
|
|
3388
3420
|
);
|
|
3389
3421
|
const body = this.buildRequestBody(messages, options, false);
|
|
3390
3422
|
const pricingContext = pricingContextFromBody(body);
|
|
3391
|
-
const recorder = new CallTimingRecorder();
|
|
3423
|
+
const recorder = new CallTimingRecorder(options.requestLifecycle);
|
|
3392
3424
|
const res = await fetchWithRetry(
|
|
3393
3425
|
`${this.baseUrl}/messages`,
|
|
3394
3426
|
{
|
|
@@ -3424,7 +3456,7 @@ var AnthropicProvider = class {
|
|
|
3424
3456
|
);
|
|
3425
3457
|
const body = this.buildRequestBody(messages, options, true);
|
|
3426
3458
|
const pricingContext = pricingContextFromBody(body);
|
|
3427
|
-
const recorder = new CallTimingRecorder();
|
|
3459
|
+
const recorder = new CallTimingRecorder(options.requestLifecycle);
|
|
3428
3460
|
const res = await fetchWithRetry(
|
|
3429
3461
|
`${this.baseUrl}/messages`,
|
|
3430
3462
|
{
|
|
@@ -4251,6 +4283,7 @@ function resolveGeminiThinking(model, resolved) {
|
|
|
4251
4283
|
}
|
|
4252
4284
|
var GeminiProvider = class {
|
|
4253
4285
|
name = "google";
|
|
4286
|
+
reportsRequestLifecycle = true;
|
|
4254
4287
|
inputCapabilities(model) {
|
|
4255
4288
|
return model.trim().length > 0 ? { image: { sources: ["bytes", "base64", "provider-file"] } } : {};
|
|
4256
4289
|
}
|
|
@@ -4368,7 +4401,7 @@ var GeminiProvider = class {
|
|
|
4368
4401
|
const pricingContext = this.pricingContext(this.requestModel(options), body);
|
|
4369
4402
|
this.assertSafeGemini3Continuation(messages, pricingContext.model);
|
|
4370
4403
|
const headers = this.buildHeaders(await this.resolveKey());
|
|
4371
|
-
const recorder = new CallTimingRecorder();
|
|
4404
|
+
const recorder = new CallTimingRecorder(options.requestLifecycle);
|
|
4372
4405
|
const res = await fetchWithRetry(
|
|
4373
4406
|
`${this.baseUrl}/models/${pricingContext.model}:generateContent`,
|
|
4374
4407
|
{
|
|
@@ -4406,7 +4439,7 @@ var GeminiProvider = class {
|
|
|
4406
4439
|
const pricingContext = this.pricingContext(this.requestModel(options), body);
|
|
4407
4440
|
this.assertSafeGemini3Continuation(messages, pricingContext.model);
|
|
4408
4441
|
const headers = this.buildHeaders(await this.resolveKey());
|
|
4409
|
-
const recorder = new CallTimingRecorder();
|
|
4442
|
+
const recorder = new CallTimingRecorder(options.requestLifecycle);
|
|
4410
4443
|
const res = await fetchWithRetry(
|
|
4411
4444
|
`${this.baseUrl}/models/${pricingContext.model}:streamGenerateContent?alt=sse`,
|
|
4412
4445
|
{
|
|
@@ -4443,7 +4476,7 @@ var GeminiProvider = class {
|
|
|
4443
4476
|
this.assertSafeInteractionOptions(options);
|
|
4444
4477
|
const body = this.buildInteractionRequestBody(messages, options, false);
|
|
4445
4478
|
const headers = this.buildHeaders(await this.resolveKey());
|
|
4446
|
-
const recorder = new CallTimingRecorder();
|
|
4479
|
+
const recorder = new CallTimingRecorder(options.requestLifecycle);
|
|
4447
4480
|
const res = await fetchWithRetry(
|
|
4448
4481
|
`${this.baseUrl}/interactions`,
|
|
4449
4482
|
{ method: "POST", headers, body: JSON.stringify(body), signal: options.signal },
|
|
@@ -4469,7 +4502,7 @@ var GeminiProvider = class {
|
|
|
4469
4502
|
this.assertSafeInteractionOptions(options);
|
|
4470
4503
|
const body = this.buildInteractionRequestBody(messages, options, true);
|
|
4471
4504
|
const headers = this.buildHeaders(await this.resolveKey());
|
|
4472
|
-
const recorder = new CallTimingRecorder();
|
|
4505
|
+
const recorder = new CallTimingRecorder(options.requestLifecycle);
|
|
4473
4506
|
const res = await fetchWithRetry(
|
|
4474
4507
|
`${this.baseUrl}/interactions?alt=sse`,
|
|
4475
4508
|
{ method: "POST", headers, body: JSON.stringify(body), signal: options.signal },
|
|
@@ -6188,7 +6221,7 @@ var GEMINI_AUDIO_MEDIA_TYPES = /* @__PURE__ */ new Set([
|
|
|
6188
6221
|
"audio/mulaw",
|
|
6189
6222
|
"audio/webm"
|
|
6190
6223
|
]);
|
|
6191
|
-
function
|
|
6224
|
+
function abortError() {
|
|
6192
6225
|
return new DOMException("The transcription operation was aborted", "AbortError");
|
|
6193
6226
|
}
|
|
6194
6227
|
function audioMime(audio) {
|
|
@@ -6220,13 +6253,13 @@ function secondsOffset(value) {
|
|
|
6220
6253
|
function sleep3(ms, signal) {
|
|
6221
6254
|
return new Promise((resolve2, reject) => {
|
|
6222
6255
|
if (signal?.aborted) {
|
|
6223
|
-
reject(
|
|
6256
|
+
reject(abortError());
|
|
6224
6257
|
return;
|
|
6225
6258
|
}
|
|
6226
6259
|
const timer = setTimeout(done, ms);
|
|
6227
6260
|
const onAbort = () => {
|
|
6228
6261
|
clearTimeout(timer);
|
|
6229
|
-
done(
|
|
6262
|
+
done(abortError());
|
|
6230
6263
|
};
|
|
6231
6264
|
function done(error) {
|
|
6232
6265
|
signal?.removeEventListener("abort", onAbort);
|
|
@@ -7547,7 +7580,7 @@ function isCostBearingLeaf(event) {
|
|
|
7547
7580
|
return COST_LEAF_SET.has(event.type);
|
|
7548
7581
|
}
|
|
7549
7582
|
function isUnpricedLeaf(event) {
|
|
7550
|
-
return event.type !== void 0 && COST_LEAF_SET.has(event.type) && !isUsableCost(event.cost) && hasPositiveBillableWork(event);
|
|
7583
|
+
return event.type !== void 0 && COST_LEAF_SET.has(event.type) && !isUsableCost(event.cost) && (event.unpriced === true || hasPositiveBillableWork(event));
|
|
7551
7584
|
}
|
|
7552
7585
|
function isRootLevel(event) {
|
|
7553
7586
|
const d = event.depth;
|
|
@@ -8833,18 +8866,27 @@ function parseDuration(duration) {
|
|
|
8833
8866
|
if (!match) throw new Error(`Invalid duration format: "${duration}"`);
|
|
8834
8867
|
const value = parseFloat(match[1]);
|
|
8835
8868
|
const unit = match[2];
|
|
8869
|
+
let milliseconds;
|
|
8836
8870
|
switch (unit) {
|
|
8837
8871
|
case "ms":
|
|
8838
|
-
|
|
8872
|
+
milliseconds = value;
|
|
8873
|
+
break;
|
|
8839
8874
|
case "s":
|
|
8840
|
-
|
|
8875
|
+
milliseconds = value * 1e3;
|
|
8876
|
+
break;
|
|
8841
8877
|
case "m":
|
|
8842
|
-
|
|
8878
|
+
milliseconds = value * 6e4;
|
|
8879
|
+
break;
|
|
8843
8880
|
case "h":
|
|
8844
|
-
|
|
8881
|
+
milliseconds = value * 36e5;
|
|
8882
|
+
break;
|
|
8845
8883
|
default:
|
|
8846
8884
|
throw new Error(`Unknown duration unit: "${unit}"`);
|
|
8847
8885
|
}
|
|
8886
|
+
if (!Number.isFinite(milliseconds)) {
|
|
8887
|
+
throw new Error(`Duration is too large: "${duration}"`);
|
|
8888
|
+
}
|
|
8889
|
+
return milliseconds;
|
|
8848
8890
|
}
|
|
8849
8891
|
function parseCost(cost) {
|
|
8850
8892
|
const match = cost.match(/^\$?([\d.]+)$/);
|
|
@@ -9500,6 +9542,42 @@ function recordToolSpanOutcome(span, outcome) {
|
|
|
9500
9542
|
|
|
9501
9543
|
// src/context.ts
|
|
9502
9544
|
var signalStorage = new AsyncLocalStorage();
|
|
9545
|
+
var hardSignalStorage = new AsyncLocalStorage();
|
|
9546
|
+
var timeoutTrackerStorage = new AsyncLocalStorage();
|
|
9547
|
+
var MAX_TIMER_DELAY_MS = 2147483647;
|
|
9548
|
+
function composeAbortSignals(...signals) {
|
|
9549
|
+
const active = signals.filter((signal) => signal !== void 0);
|
|
9550
|
+
if (active.length === 0) return void 0;
|
|
9551
|
+
if (active.length === 1) return active[0];
|
|
9552
|
+
return AbortSignal.any(active);
|
|
9553
|
+
}
|
|
9554
|
+
function raceWithAbortSignal(promise, signal) {
|
|
9555
|
+
if (!signal) return promise;
|
|
9556
|
+
if (signal.aborted) {
|
|
9557
|
+
void promise.catch(() => {
|
|
9558
|
+
});
|
|
9559
|
+
return Promise.reject(signal.reason);
|
|
9560
|
+
}
|
|
9561
|
+
return new Promise((resolve2, reject) => {
|
|
9562
|
+
let settled = false;
|
|
9563
|
+
const finish = (callback) => {
|
|
9564
|
+
if (settled) return;
|
|
9565
|
+
settled = true;
|
|
9566
|
+
signal.removeEventListener("abort", onAbort);
|
|
9567
|
+
callback();
|
|
9568
|
+
};
|
|
9569
|
+
const onAbort = () => finish(() => reject(signal.reason));
|
|
9570
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
9571
|
+
if (signal.aborted) onAbort();
|
|
9572
|
+
promise.then(
|
|
9573
|
+
(value) => finish(() => resolve2(value)),
|
|
9574
|
+
(error) => finish(() => reject(error))
|
|
9575
|
+
);
|
|
9576
|
+
});
|
|
9577
|
+
}
|
|
9578
|
+
function pausedHumanWaitMs(tracker, now = Date.now()) {
|
|
9579
|
+
return tracker.humanWaitMs + (tracker.activeHumanWaits > 0 && tracker.humanWaitStartedAt !== void 0 ? now - tracker.humanWaitStartedAt : 0);
|
|
9580
|
+
}
|
|
9503
9581
|
var DEFAULT_BRANCH_DRAIN_TIMEOUT_MS = 5e3;
|
|
9504
9582
|
function resolveBranchDrainTimeoutMs(value) {
|
|
9505
9583
|
const resolved = value === void 0 ? DEFAULT_BRANCH_DRAIN_TIMEOUT_MS : value;
|
|
@@ -10301,7 +10379,10 @@ var WorkflowContext = class _WorkflowContext {
|
|
|
10301
10379
|
tool_call_id: parsed.callId
|
|
10302
10380
|
});
|
|
10303
10381
|
}
|
|
10304
|
-
if (settlement.abortError !== void 0)
|
|
10382
|
+
if (settlement.abortError !== void 0) {
|
|
10383
|
+
signal?.throwIfAborted();
|
|
10384
|
+
throw settlement.abortError;
|
|
10385
|
+
}
|
|
10305
10386
|
}
|
|
10306
10387
|
// ── ctx.ask() ─────────────────────────────────────────────────────────
|
|
10307
10388
|
async ask(agent2, prompt, options) {
|
|
@@ -10317,7 +10398,10 @@ var WorkflowContext = class _WorkflowContext {
|
|
|
10317
10398
|
const promptText = inputText(normalizedInput);
|
|
10318
10399
|
const inputDescriptor = describeModelInput(normalizedInput);
|
|
10319
10400
|
const agentName = agent2._name;
|
|
10320
|
-
|
|
10401
|
+
const inheritedHardSignal = hardSignalStorage.getStore() ?? this.signal;
|
|
10402
|
+
const hardAskSignal = composeAbortSignals(inheritedHardSignal, options?.signal);
|
|
10403
|
+
const askSignal = composeAbortSignals(this.currentSignal, options?.signal);
|
|
10404
|
+
const runAsk = () => this._checkpoint(
|
|
10321
10405
|
this._autoCheckpointName("ask", agentName),
|
|
10322
10406
|
async () => {
|
|
10323
10407
|
const parentFrame = askStorage.getStore();
|
|
@@ -10472,8 +10556,25 @@ var WorkflowContext = class _WorkflowContext {
|
|
|
10472
10556
|
},
|
|
10473
10557
|
{ agent: agentName }
|
|
10474
10558
|
);
|
|
10559
|
+
const runWithAskSignal = () => askSignal ? signalStorage.run(askSignal, runAsk) : runAsk();
|
|
10560
|
+
return hardAskSignal ? hardSignalStorage.run(hardAskSignal, runWithAskSignal) : runWithAskSignal();
|
|
10475
10561
|
}
|
|
10476
10562
|
async executeAgentCall(agent2, input, options, handoffMessages, usageCapture, sessionHistory = normalizeSessionHistory(this.sessionHistory)) {
|
|
10563
|
+
const tracker = { humanWaitMs: 0, activeHumanWaits: 0 };
|
|
10564
|
+
const enclosing = timeoutTrackerStorage.getStore() ?? [];
|
|
10565
|
+
return timeoutTrackerStorage.run(
|
|
10566
|
+
[...enclosing, tracker],
|
|
10567
|
+
() => this.executeAgentCallImpl(
|
|
10568
|
+
agent2,
|
|
10569
|
+
input,
|
|
10570
|
+
options,
|
|
10571
|
+
handoffMessages,
|
|
10572
|
+
usageCapture,
|
|
10573
|
+
sessionHistory
|
|
10574
|
+
)
|
|
10575
|
+
);
|
|
10576
|
+
}
|
|
10577
|
+
async executeAgentCallImpl(agent2, input, options, handoffMessages, usageCapture, sessionHistory = normalizeSessionHistory(this.sessionHistory)) {
|
|
10477
10578
|
if (this.budgetContext?.exceeded) {
|
|
10478
10579
|
const { limit, totalCost: spent, policy } = this.budgetContext;
|
|
10479
10580
|
if (policy === "warn") {
|
|
@@ -10713,8 +10814,18 @@ ${appendedSchemaText}`;
|
|
|
10713
10814
|
}
|
|
10714
10815
|
}
|
|
10715
10816
|
const maxTurns = agent2._config.maxTurns ?? 25;
|
|
10716
|
-
const timeoutMs = parseDuration(
|
|
10817
|
+
const timeoutMs = parseDuration(
|
|
10818
|
+
options?.timeout ?? agent2._config.timeout ?? this.config.defaults?.timeout ?? "60s"
|
|
10819
|
+
);
|
|
10820
|
+
const stallTimeout = options?.stallTimeout ?? agent2._config.stallTimeout ?? this.config.defaults?.stallTimeout;
|
|
10821
|
+
const stallTimeoutMs = stallTimeout === void 0 ? void 0 : parseDuration(stallTimeout);
|
|
10822
|
+
if (stallTimeoutMs !== void 0 && stallTimeoutMs > MAX_TIMER_DELAY_MS) {
|
|
10823
|
+
throw new RangeError(
|
|
10824
|
+
`stallTimeout exceeds the maximum supported timer duration of ${MAX_TIMER_DELAY_MS}ms`
|
|
10825
|
+
);
|
|
10826
|
+
}
|
|
10717
10827
|
const startTime = Date.now();
|
|
10828
|
+
const timeoutTracker = timeoutTrackerStorage.getStore()?.at(-1);
|
|
10718
10829
|
const timingTotals = { turns: 0, queuedMs: 0, retryMs: 0, wireMs: 0 };
|
|
10719
10830
|
const currentMessages = [...messages];
|
|
10720
10831
|
let turns = 0;
|
|
@@ -10729,7 +10840,8 @@ ${appendedSchemaText}`;
|
|
|
10729
10840
|
let lastStartMaxAttempts = 1;
|
|
10730
10841
|
while (turns < maxTurns) {
|
|
10731
10842
|
this.currentSignal?.throwIfAborted();
|
|
10732
|
-
const
|
|
10843
|
+
const now = Date.now();
|
|
10844
|
+
const elapsedMs = now - startTime - (timeoutTracker ? pausedHumanWaitMs(timeoutTracker, now) : 0);
|
|
10733
10845
|
if (elapsedMs > timeoutMs) {
|
|
10734
10846
|
throw new TimeoutError(
|
|
10735
10847
|
"ctx.ask()",
|
|
@@ -10743,7 +10855,8 @@ ${appendedSchemaText}`;
|
|
|
10743
10855
|
0,
|
|
10744
10856
|
elapsedMs - timingTotals.queuedMs - timingTotals.retryMs - timingTotals.wireMs
|
|
10745
10857
|
)
|
|
10746
|
-
} : void 0
|
|
10858
|
+
} : void 0,
|
|
10859
|
+
agent2._name
|
|
10747
10860
|
);
|
|
10748
10861
|
}
|
|
10749
10862
|
turns++;
|
|
@@ -10790,6 +10903,43 @@ ${appendedSchemaText}`;
|
|
|
10790
10903
|
providerOptions,
|
|
10791
10904
|
signal: this.currentSignal
|
|
10792
10905
|
};
|
|
10906
|
+
const requestSignal = chatOptions.signal;
|
|
10907
|
+
const hardRequestSignal = hardSignalStorage.getStore() ?? this.signal;
|
|
10908
|
+
const stallController = stallTimeoutMs === void 0 ? void 0 : new AbortController();
|
|
10909
|
+
const stallReason = stallController === void 0 ? void 0 : new DOMException("Provider request stalled", "StallTimeout");
|
|
10910
|
+
let stallTimer;
|
|
10911
|
+
let providerCallActive = true;
|
|
10912
|
+
let requestDispatched = false;
|
|
10913
|
+
const clearStallTimer = () => {
|
|
10914
|
+
if (stallTimer !== void 0) {
|
|
10915
|
+
clearTimeout(stallTimer);
|
|
10916
|
+
stallTimer = void 0;
|
|
10917
|
+
}
|
|
10918
|
+
};
|
|
10919
|
+
const armStallTimer = () => {
|
|
10920
|
+
if (!providerCallActive || !stallController || !stallReason || stallTimeoutMs === void 0)
|
|
10921
|
+
return;
|
|
10922
|
+
requestDispatched = true;
|
|
10923
|
+
clearStallTimer();
|
|
10924
|
+
if (stallController.signal.aborted) return;
|
|
10925
|
+
stallTimer = setTimeout(() => stallController.abort(stallReason), stallTimeoutMs);
|
|
10926
|
+
};
|
|
10927
|
+
if (stallController) {
|
|
10928
|
+
chatOptions.signal = composeAbortSignals(requestSignal, stallController.signal);
|
|
10929
|
+
chatOptions.requestLifecycle = {
|
|
10930
|
+
onDispatch: armStallTimer,
|
|
10931
|
+
onRetry: clearStallTimer
|
|
10932
|
+
};
|
|
10933
|
+
}
|
|
10934
|
+
const providerSettlementSignal = composeAbortSignals(
|
|
10935
|
+
hardRequestSignal,
|
|
10936
|
+
stallController?.signal
|
|
10937
|
+
);
|
|
10938
|
+
const throwIfRequestStalled = () => {
|
|
10939
|
+
if (stallReason !== void 0 && providerSettlementSignal?.reason === stallReason) {
|
|
10940
|
+
throw new StallTimeoutError("ctx.ask()", stallTimeoutMs, agent2._name);
|
|
10941
|
+
}
|
|
10942
|
+
};
|
|
10793
10943
|
if (options?.schema && toolDefs.length === 0) {
|
|
10794
10944
|
const nativeOut = options?.nativeStructuredOutput ?? agent2._config.nativeStructuredOutput ?? false;
|
|
10795
10945
|
chatOptions.responseFormat = nativeOut ? {
|
|
@@ -10876,55 +11026,77 @@ ${appendedSchemaText}`;
|
|
|
10876
11026
|
});
|
|
10877
11027
|
}
|
|
10878
11028
|
}) : void 0;
|
|
10879
|
-
|
|
11029
|
+
if (stallController && provider.reportsRequestLifecycle !== true) armStallTimer();
|
|
11030
|
+
const providerStream = provider.stream(
|
|
10880
11031
|
cloneMessagesForProvider(currentMessages),
|
|
10881
11032
|
chatOptions
|
|
10882
|
-
)
|
|
10883
|
-
|
|
10884
|
-
|
|
10885
|
-
|
|
10886
|
-
|
|
10887
|
-
|
|
10888
|
-
|
|
10889
|
-
|
|
10890
|
-
|
|
10891
|
-
|
|
10892
|
-
|
|
10893
|
-
|
|
10894
|
-
|
|
10895
|
-
|
|
10896
|
-
|
|
10897
|
-
|
|
10898
|
-
|
|
10899
|
-
|
|
10900
|
-
|
|
10901
|
-
|
|
11033
|
+
);
|
|
11034
|
+
const iterator = providerStream[Symbol.asyncIterator]();
|
|
11035
|
+
try {
|
|
11036
|
+
while (true) {
|
|
11037
|
+
const next = await raceWithAbortSignal(
|
|
11038
|
+
Promise.resolve(iterator.next()),
|
|
11039
|
+
providerSettlementSignal
|
|
11040
|
+
);
|
|
11041
|
+
if (next.done) break;
|
|
11042
|
+
const chunk = next.value;
|
|
11043
|
+
if (stallController) armStallTimer();
|
|
11044
|
+
if (chunk.type === "text_delta") {
|
|
11045
|
+
content2 += chunk.content;
|
|
11046
|
+
this.emitEvent({ type: "token", data: chunk.content });
|
|
11047
|
+
if (walker) {
|
|
11048
|
+
walker.processChunk(chunk.content);
|
|
11049
|
+
if (walker.consumeBoundary()) {
|
|
11050
|
+
let parsed;
|
|
11051
|
+
try {
|
|
11052
|
+
parsed = parsePartialJson(extractJson(content2));
|
|
11053
|
+
} catch {
|
|
11054
|
+
parsed = void 0;
|
|
11055
|
+
}
|
|
11056
|
+
if (parsed !== void 0) {
|
|
11057
|
+
this.emitEvent({
|
|
11058
|
+
type: "partial_object",
|
|
11059
|
+
agent: agent2._name,
|
|
11060
|
+
attempt: currentAttempt,
|
|
11061
|
+
data: { object: parsed }
|
|
11062
|
+
});
|
|
11063
|
+
}
|
|
10902
11064
|
}
|
|
10903
11065
|
}
|
|
10904
|
-
}
|
|
10905
|
-
|
|
10906
|
-
|
|
10907
|
-
|
|
10908
|
-
|
|
10909
|
-
|
|
10910
|
-
|
|
10911
|
-
|
|
10912
|
-
|
|
10913
|
-
|
|
10914
|
-
if (chunk.
|
|
10915
|
-
|
|
10916
|
-
|
|
10917
|
-
streamTiming = chunk.timing;
|
|
10918
|
-
if (chunk.usage) {
|
|
11066
|
+
} else if (chunk.type === "thinking_delta") {
|
|
11067
|
+
thinkingContent += chunk.content;
|
|
11068
|
+
} else if (chunk.type === "tool_call_delta") {
|
|
11069
|
+
let buffer = toolCallBuffers.get(chunk.id);
|
|
11070
|
+
if (!buffer) {
|
|
11071
|
+
buffer = { id: chunk.id, name: "", arguments: "" };
|
|
11072
|
+
toolCallBuffers.set(chunk.id, buffer);
|
|
11073
|
+
}
|
|
11074
|
+
if (chunk.name) buffer.name = chunk.name;
|
|
11075
|
+
if (chunk.arguments) buffer.arguments += chunk.arguments;
|
|
11076
|
+
} else if (chunk.type === "done") {
|
|
11077
|
+
streamProviderMetadata = chunk.providerMetadata;
|
|
11078
|
+
streamTiming = chunk.timing;
|
|
10919
11079
|
response = {
|
|
10920
11080
|
content: content2,
|
|
10921
11081
|
tool_calls: void 0,
|
|
10922
11082
|
usage: chunk.usage,
|
|
10923
|
-
cost: chunk.cost
|
|
11083
|
+
cost: chunk.cost,
|
|
11084
|
+
providerMetadata: chunk.providerMetadata,
|
|
11085
|
+
timing: chunk.timing
|
|
10924
11086
|
};
|
|
10925
11087
|
}
|
|
10926
11088
|
}
|
|
11089
|
+
} catch (error) {
|
|
11090
|
+
if (iterator.return) {
|
|
11091
|
+
try {
|
|
11092
|
+
void Promise.resolve(iterator.return(void 0)).catch(() => {
|
|
11093
|
+
});
|
|
11094
|
+
} catch {
|
|
11095
|
+
}
|
|
11096
|
+
}
|
|
11097
|
+
throw error;
|
|
10927
11098
|
}
|
|
11099
|
+
throwIfRequestStalled();
|
|
10928
11100
|
for (const buffer of toolCallBuffers.values()) {
|
|
10929
11101
|
toolCalls.push({
|
|
10930
11102
|
id: buffer.id,
|
|
@@ -10949,16 +11121,27 @@ ${appendedSchemaText}`;
|
|
|
10949
11121
|
response.thinking_content = thinkingContent;
|
|
10950
11122
|
}
|
|
10951
11123
|
} else {
|
|
10952
|
-
|
|
11124
|
+
if (stallController && provider.reportsRequestLifecycle !== true) armStallTimer();
|
|
11125
|
+
response = await raceWithAbortSignal(
|
|
11126
|
+
provider.chat(cloneMessagesForProvider(currentMessages), chatOptions),
|
|
11127
|
+
providerSettlementSignal
|
|
11128
|
+
);
|
|
11129
|
+
throwIfRequestStalled();
|
|
10953
11130
|
}
|
|
10954
11131
|
} catch (err) {
|
|
10955
|
-
|
|
10956
|
-
|
|
11132
|
+
const callError = stallReason !== void 0 && providerSettlementSignal?.reason === stallReason ? new StallTimeoutError("ctx.ask()", stallTimeoutMs, agent2._name) : err;
|
|
11133
|
+
if (richRequest) this.recordRichFailure(callError);
|
|
11134
|
+
const failureTiming = callError instanceof ProviderError ? callError.timing : void 0;
|
|
10957
11135
|
this.emitEvent({
|
|
10958
11136
|
type: "agent_call_end",
|
|
10959
11137
|
agent: agent2._name,
|
|
10960
11138
|
model: effectiveModelUri,
|
|
10961
11139
|
promptVersion: agent2._config.version,
|
|
11140
|
+
// A dispatched request abandoned at the runtime boundary may still
|
|
11141
|
+
// be billed even though a non-cooperative provider supplied no
|
|
11142
|
+
// usage. Preserve budget honesty by marking the known total as a
|
|
11143
|
+
// lower bound rather than presenting an exact $0.
|
|
11144
|
+
...callError instanceof StallTimeoutError && requestDispatched ? { unpriced: true } : {},
|
|
10962
11145
|
duration: Date.now() - turnStart,
|
|
10963
11146
|
// Top-level beside `duration`, exactly as on the success path.
|
|
10964
11147
|
...failureTiming ? { timing: failureTiming } : {},
|
|
@@ -10966,14 +11149,17 @@ ${appendedSchemaText}`;
|
|
|
10966
11149
|
response: "",
|
|
10967
11150
|
turn: turns,
|
|
10968
11151
|
...retryReason ? { retryReason } : {},
|
|
10969
|
-
error: this._observerErrorProjection(
|
|
11152
|
+
error: this._observerErrorProjection(callError)?.message ?? legacyErrorMessage(callError),
|
|
10970
11153
|
// Enrich with typed-error metadata when available. `body` is
|
|
10971
11154
|
// deliberately NOT emitted — it's redaction-eligible (see
|
|
10972
11155
|
// docs/security.md). `data.error` already carries the message.
|
|
10973
|
-
...providerErrorEventMetadata(
|
|
11156
|
+
...providerErrorEventMetadata(callError, richRequest)
|
|
10974
11157
|
}
|
|
10975
11158
|
});
|
|
10976
|
-
throw
|
|
11159
|
+
throw callError;
|
|
11160
|
+
} finally {
|
|
11161
|
+
providerCallActive = false;
|
|
11162
|
+
clearStallTimer();
|
|
10977
11163
|
}
|
|
10978
11164
|
if (usageCapture && response.usage) {
|
|
10979
11165
|
usageCapture.value = response.usage;
|
|
@@ -12498,46 +12684,52 @@ ${summaryResponse.content}`
|
|
|
12498
12684
|
}
|
|
12499
12685
|
// ── ctx.awaitHuman() ──────────────────────────────────────────────────
|
|
12500
12686
|
async awaitHuman(options) {
|
|
12501
|
-
|
|
12502
|
-
|
|
12503
|
-
|
|
12504
|
-
|
|
12505
|
-
|
|
12506
|
-
|
|
12507
|
-
|
|
12508
|
-
|
|
12509
|
-
|
|
12510
|
-
|
|
12511
|
-
|
|
12512
|
-
|
|
12687
|
+
const trackers = timeoutTrackerStorage.getStore();
|
|
12688
|
+
const startedAt = Date.now();
|
|
12689
|
+
for (const tracker of trackers ?? []) {
|
|
12690
|
+
if (tracker.activeHumanWaits++ === 0) tracker.humanWaitStartedAt = startedAt;
|
|
12691
|
+
}
|
|
12692
|
+
try {
|
|
12693
|
+
if (this.spanManager) {
|
|
12694
|
+
return await this.spanManager.withSpanAsync(
|
|
12695
|
+
"axl.ctx.awaitHuman",
|
|
12696
|
+
{
|
|
12697
|
+
"axl.awaitHuman.channel": options.channel
|
|
12698
|
+
},
|
|
12699
|
+
async (span) => {
|
|
12700
|
+
const start = Date.now();
|
|
12701
|
+
const result = await this._awaitHumanImpl(options);
|
|
12702
|
+
span.setAttribute("axl.awaitHuman.wait_duration", Date.now() - start);
|
|
12703
|
+
span.setAttribute("axl.awaitHuman.approved", result.approved);
|
|
12704
|
+
return result;
|
|
12705
|
+
}
|
|
12706
|
+
);
|
|
12707
|
+
}
|
|
12708
|
+
return await this._awaitHumanImpl(options);
|
|
12709
|
+
} finally {
|
|
12710
|
+
const finishedAt = Date.now();
|
|
12711
|
+
for (const tracker of trackers ?? []) {
|
|
12712
|
+
tracker.activeHumanWaits--;
|
|
12713
|
+
if (tracker.activeHumanWaits === 0 && tracker.humanWaitStartedAt !== void 0) {
|
|
12714
|
+
tracker.humanWaitMs += finishedAt - tracker.humanWaitStartedAt;
|
|
12715
|
+
tracker.humanWaitStartedAt = void 0;
|
|
12513
12716
|
}
|
|
12514
|
-
|
|
12717
|
+
}
|
|
12515
12718
|
}
|
|
12516
|
-
return this._awaitHumanImpl(options);
|
|
12517
12719
|
}
|
|
12518
12720
|
async _awaitHumanImpl(options) {
|
|
12519
12721
|
const branchSignal = this.currentSignal;
|
|
12520
|
-
const makeAbortError = (reason) => {
|
|
12521
|
-
if (typeof DOMException !== "undefined") {
|
|
12522
|
-
return new DOMException(
|
|
12523
|
-
typeof reason === "string" ? reason : "awaitHuman aborted",
|
|
12524
|
-
"AbortError"
|
|
12525
|
-
);
|
|
12526
|
-
}
|
|
12527
|
-
const err = new Error(typeof reason === "string" ? reason : "awaitHuman aborted");
|
|
12528
|
-
err.name = "AbortError";
|
|
12529
|
-
return err;
|
|
12530
|
-
};
|
|
12531
12722
|
const awaitWithAbort = async (promise, signal2 = branchSignal) => {
|
|
12532
12723
|
if (!signal2) return promise;
|
|
12533
|
-
|
|
12724
|
+
signal2.throwIfAborted();
|
|
12534
12725
|
let onAbort;
|
|
12535
12726
|
try {
|
|
12536
12727
|
return await Promise.race([
|
|
12537
12728
|
promise,
|
|
12538
12729
|
new Promise((_, reject) => {
|
|
12539
|
-
onAbort = () => reject(
|
|
12730
|
+
onAbort = () => reject(signal2.reason);
|
|
12540
12731
|
signal2.addEventListener("abort", onAbort, { once: true });
|
|
12732
|
+
if (signal2.aborted) onAbort();
|
|
12541
12733
|
})
|
|
12542
12734
|
]);
|
|
12543
12735
|
} finally {
|
|
@@ -12545,12 +12737,12 @@ ${summaryResponse.content}`
|
|
|
12545
12737
|
}
|
|
12546
12738
|
};
|
|
12547
12739
|
if (this.awaitHumanHandler) {
|
|
12548
|
-
|
|
12740
|
+
branchSignal?.throwIfAborted();
|
|
12549
12741
|
this.emitEvent({
|
|
12550
12742
|
type: "await_human",
|
|
12551
12743
|
data: { channel: options.channel, prompt: options.prompt }
|
|
12552
12744
|
});
|
|
12553
|
-
|
|
12745
|
+
branchSignal?.throwIfAborted();
|
|
12554
12746
|
const decision2 = parseHumanDecision(
|
|
12555
12747
|
await awaitWithAbort(Promise.resolve(this.awaitHumanHandler(options)))
|
|
12556
12748
|
);
|
|
@@ -12605,12 +12797,12 @@ ${summaryResponse.content}`
|
|
|
12605
12797
|
const abortListener = () => {
|
|
12606
12798
|
registeredResolver.cancelled = true;
|
|
12607
12799
|
markReady();
|
|
12608
|
-
rejectDecision(
|
|
12800
|
+
rejectDecision(signal.reason);
|
|
12609
12801
|
};
|
|
12610
12802
|
signal.addEventListener("abort", abortListener, { once: true });
|
|
12611
12803
|
let decision;
|
|
12612
12804
|
try {
|
|
12613
|
-
|
|
12805
|
+
signal.throwIfAborted();
|
|
12614
12806
|
if (this.stateStore) {
|
|
12615
12807
|
saveAttempted = true;
|
|
12616
12808
|
await this.stateStore.savePendingDecision(this.executionId, {
|
|
@@ -12621,7 +12813,7 @@ ${summaryResponse.content}`
|
|
|
12621
12813
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
12622
12814
|
});
|
|
12623
12815
|
}
|
|
12624
|
-
|
|
12816
|
+
signal.throwIfAborted();
|
|
12625
12817
|
this.emitEvent({
|
|
12626
12818
|
type: "await_human",
|
|
12627
12819
|
data: { channel: options.channel, prompt: options.prompt }
|
|
@@ -13091,7 +13283,7 @@ ${summaryResponse.content}`
|
|
|
13091
13283
|
data: partial.data
|
|
13092
13284
|
});
|
|
13093
13285
|
};
|
|
13094
|
-
const
|
|
13286
|
+
const abortError2 = () => new DOMException("The transcription operation was aborted", "AbortError");
|
|
13095
13287
|
const cleanupStatus = (value) => value === "not_required" || value === "deleted" || value === "failed" || value === "timed_out" ? value : void 0;
|
|
13096
13288
|
const safeProviderFailure = (error, provider, model) => {
|
|
13097
13289
|
const details = error && typeof error === "object" ? error : void 0;
|
|
@@ -13142,7 +13334,7 @@ ${summaryResponse.content}`
|
|
|
13142
13334
|
hasWork: false
|
|
13143
13335
|
})
|
|
13144
13336
|
});
|
|
13145
|
-
throw
|
|
13337
|
+
throw abortError2();
|
|
13146
13338
|
}
|
|
13147
13339
|
if (this.budgetContext?.exceeded) {
|
|
13148
13340
|
const { limit, totalCost: spent, policy } = this.budgetContext;
|
|
@@ -13208,7 +13400,7 @@ ${summaryResponse.content}`
|
|
|
13208
13400
|
...failure.cleanup ? [{ cleanupStatus: failure.cleanup }] : []
|
|
13209
13401
|
)
|
|
13210
13402
|
});
|
|
13211
|
-
throw
|
|
13403
|
+
throw abortError2();
|
|
13212
13404
|
}
|
|
13213
13405
|
if (failure.accounting.cost !== void 0)
|
|
13214
13406
|
this._accumulateBudgetCost(failure.accounting.cost);
|
|
@@ -13251,7 +13443,7 @@ ${summaryResponse.content}`
|
|
|
13251
13443
|
...cleanupStatus(result.cleanupStatus) ? [{ cleanupStatus: cleanupStatus(result.cleanupStatus) }] : []
|
|
13252
13444
|
)
|
|
13253
13445
|
});
|
|
13254
|
-
throw
|
|
13446
|
+
throw abortError2();
|
|
13255
13447
|
}
|
|
13256
13448
|
let transcript;
|
|
13257
13449
|
try {
|
|
@@ -13337,9 +13529,9 @@ ${summaryResponse.content}`
|
|
|
13337
13529
|
const cost = partial.cost;
|
|
13338
13530
|
if (COST_BEARING_LEAF_TYPES.includes(partial.type)) {
|
|
13339
13531
|
const usable = isUsableCost(cost);
|
|
13340
|
-
const unpriced = !usable && hasPositiveBillableWork(
|
|
13532
|
+
const unpriced = !usable && (partial.unpriced === true || hasPositiveBillableWork(
|
|
13341
13533
|
partial
|
|
13342
|
-
);
|
|
13534
|
+
));
|
|
13343
13535
|
if (frame) {
|
|
13344
13536
|
if (usable) frame.askCost.value += cost;
|
|
13345
13537
|
else if (unpriced) frame.askUnpriced = true;
|
|
@@ -13350,7 +13542,7 @@ ${summaryResponse.content}`
|
|
|
13350
13542
|
if (!this.budgetContext.unpricedWarned && Number.isFinite(this.budgetContext.limit)) {
|
|
13351
13543
|
this.budgetContext.unpricedWarned = true;
|
|
13352
13544
|
console.warn(
|
|
13353
|
-
"Budget honesty:
|
|
13545
|
+
"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."
|
|
13354
13546
|
);
|
|
13355
13547
|
}
|
|
13356
13548
|
}
|
|
@@ -15319,12 +15511,13 @@ function forwardAbortSignal(external, internal) {
|
|
|
15319
15511
|
if (!external) return () => {
|
|
15320
15512
|
};
|
|
15321
15513
|
if (external.aborted) {
|
|
15322
|
-
internal.abort();
|
|
15514
|
+
internal.abort(external.reason);
|
|
15323
15515
|
return () => {
|
|
15324
15516
|
};
|
|
15325
15517
|
}
|
|
15326
|
-
const onAbort = () => internal.abort();
|
|
15518
|
+
const onAbort = () => internal.abort(external.reason);
|
|
15327
15519
|
external.addEventListener("abort", onAbort, { once: true });
|
|
15520
|
+
if (external.aborted) onAbort();
|
|
15328
15521
|
return () => external.removeEventListener("abort", onAbort);
|
|
15329
15522
|
}
|
|
15330
15523
|
var AxlRuntime = class extends EventEmitter2 {
|
|
@@ -17805,6 +17998,7 @@ export {
|
|
|
17805
17998
|
SQLiteStore,
|
|
17806
17999
|
Session,
|
|
17807
18000
|
SqliteVectorStore,
|
|
18001
|
+
StallTimeoutError,
|
|
17808
18002
|
ThinkTagScanner,
|
|
17809
18003
|
TimeoutError,
|
|
17810
18004
|
ToolFailure,
|