@axlsdk/axl 0.24.3 → 0.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -2161,6 +2161,8 @@ declare class NoConsensus extends AxlError {
2161
2161
  type TimeoutBreakdown = {
2162
2162
  /** Wall clock consumed by the operation when it timed out. */
2163
2163
  elapsedMs: number;
2164
+ /** Graceful work budget consumed after human and observed governor waits. */
2165
+ chargedMs: number;
2164
2166
  /** Sum of `CallTiming.queuedMs` — self-imposed rate-limiter wait. */
2165
2167
  queuedMs: number;
2166
2168
  /** Sum of `CallTiming.retryMs` — failed provider attempts and their backoff. */
package/dist/index.d.ts CHANGED
@@ -2161,6 +2161,8 @@ declare class NoConsensus extends AxlError {
2161
2161
  type TimeoutBreakdown = {
2162
2162
  /** Wall clock consumed by the operation when it timed out. */
2163
2163
  elapsedMs: number;
2164
+ /** Graceful work budget consumed after human and observed governor waits. */
2165
+ chargedMs: number;
2164
2166
  /** Sum of `CallTiming.queuedMs` — self-imposed rate-limiter wait. */
2165
2167
  queuedMs: number;
2166
2168
  /** Sum of `CallTiming.retryMs` — failed provider attempts and their backoff. */
package/dist/index.js CHANGED
@@ -193,7 +193,7 @@ var TimeoutError = class extends AxlError {
193
193
  constructor(operation, timeoutMs, breakdown, agent2) {
194
194
  super(
195
195
  "TIMEOUT",
196
- `${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}'` : "")
196
+ `${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, charged ${breakdown.chargedMs}ms)` : "") + (agent2 ? ` for agent '${agent2}'` : "")
197
197
  );
198
198
  this.name = "TimeoutError";
199
199
  if (breakdown) this.breakdown = breakdown;
@@ -331,7 +331,7 @@ var sharedGuard = typeof installedGuard === "object" && installedGuard !== null
331
331
  var buildPath = typeof __AXL_BUILD_PATH__ === "string" ? __AXL_BUILD_PATH__ : "<source>";
332
332
  var thisCopy = {
333
333
  path: buildPath.startsWith("file:") ? fileURLToPath(buildPath) : buildPath,
334
- version: true ? "0.24.3" : "unknown"
334
+ version: true ? "0.25.0" : "unknown"
335
335
  };
336
336
  function warnCrossCopy(other, joined) {
337
337
  if (other === thisCopy) return;
@@ -1315,6 +1315,41 @@ var OPENAI_DEFAULT_BASE_URL = "https://api.openai.com/v1";
1315
1315
  var ANTHROPIC_DEFAULT_BASE_URL = "https://api.anthropic.com/v1";
1316
1316
  var GEMINI_DEFAULT_BASE_URL = "https://generativelanguage.googleapis.com/v1beta";
1317
1317
 
1318
+ // src/ask-clock.ts
1319
+ import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
1320
+ var askClockStorage = new AsyncLocalStorage2();
1321
+ function runWithAskClock(fn) {
1322
+ const tracker = { pausedMs: 0, activePauses: 0 };
1323
+ const enclosing = askClockStorage.getStore() ?? [];
1324
+ return askClockStorage.run([...enclosing, tracker], fn);
1325
+ }
1326
+ function currentAskClock() {
1327
+ return askClockStorage.getStore()?.at(-1);
1328
+ }
1329
+ function pausedAskClockMs(tracker, now = Date.now()) {
1330
+ return tracker.pausedMs + (tracker.activePauses > 0 && tracker.pauseStartedAt !== void 0 ? now - tracker.pauseStartedAt : 0);
1331
+ }
1332
+ async function pauseAskClocks(wait) {
1333
+ const trackers = askClockStorage.getStore();
1334
+ if (!trackers || trackers.length === 0) return wait();
1335
+ const startedAt = Date.now();
1336
+ for (const tracker of trackers) {
1337
+ if (tracker.activePauses++ === 0) tracker.pauseStartedAt = startedAt;
1338
+ }
1339
+ try {
1340
+ return await wait();
1341
+ } finally {
1342
+ const finishedAt = Date.now();
1343
+ for (const tracker of trackers) {
1344
+ tracker.activePauses--;
1345
+ if (tracker.activePauses === 0 && tracker.pauseStartedAt !== void 0) {
1346
+ tracker.pausedMs += finishedAt - tracker.pauseStartedAt;
1347
+ tracker.pauseStartedAt = void 0;
1348
+ }
1349
+ }
1350
+ }
1351
+ }
1352
+
1318
1353
  // src/providers/rate-limiter.ts
1319
1354
  function sanitizeRateLimitConfig(config) {
1320
1355
  const limits = {};
@@ -2377,7 +2412,7 @@ async function fetchWithRetry(input, init, opts) {
2377
2412
  let headersAt = 0;
2378
2413
  const waitSelfImposed = async (wait) => {
2379
2414
  const start = Date.now();
2380
- await wait();
2415
+ await pauseAskClocks(wait);
2381
2416
  const waited = Date.now() - start;
2382
2417
  queuedMs += waited;
2383
2418
  if (dispatches > 0) queuedAfterFirstDispatchMs += waited;
@@ -9002,7 +9037,7 @@ var TranscriptionProviderRegistry = class {
9002
9037
  };
9003
9038
 
9004
9039
  // src/context.ts
9005
- import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
9040
+ import { AsyncLocalStorage as AsyncLocalStorage3 } from "async_hooks";
9006
9041
  import { randomUUID } from "crypto";
9007
9042
  import { z, ZodError as ZodError2 } from "zod";
9008
9043
 
@@ -12534,9 +12569,8 @@ function recordToolSpanOutcome(span, outcome) {
12534
12569
  }
12535
12570
 
12536
12571
  // src/context.ts
12537
- var signalStorage = new AsyncLocalStorage2();
12538
- var hardSignalStorage = new AsyncLocalStorage2();
12539
- var timeoutTrackerStorage = new AsyncLocalStorage2();
12572
+ var signalStorage = new AsyncLocalStorage3();
12573
+ var hardSignalStorage = new AsyncLocalStorage3();
12540
12574
  var MAX_TIMER_DELAY_MS = 2147483647;
12541
12575
  function composeAbortSignals(...signals) {
12542
12576
  const active = signals.filter((signal) => signal !== void 0);
@@ -12568,9 +12602,6 @@ function raceWithAbortSignal(promise, signal) {
12568
12602
  );
12569
12603
  });
12570
12604
  }
12571
- function pausedHumanWaitMs(tracker, now = Date.now()) {
12572
- return tracker.humanWaitMs + (tracker.activeHumanWaits > 0 && tracker.humanWaitStartedAt !== void 0 ? now - tracker.humanWaitStartedAt : 0);
12573
- }
12574
12605
  var DEFAULT_BRANCH_DRAIN_TIMEOUT_MS = 5e3;
12575
12606
  function resolveBranchDrainTimeoutMs(value) {
12576
12607
  const resolved = value === void 0 ? DEFAULT_BRANCH_DRAIN_TIMEOUT_MS : value;
@@ -12641,7 +12672,7 @@ function parseHumanDecision(value) {
12641
12672
  }
12642
12673
  return invalid3();
12643
12674
  }
12644
- var askStorage = new AsyncLocalStorage2();
12675
+ var askStorage = new AsyncLocalStorage3();
12645
12676
  var inlineSchemaCache = /* @__PURE__ */ new WeakMap();
12646
12677
  function zodToJsonSchema(schema) {
12647
12678
  const cached = inlineSchemaCache.get(schema);
@@ -13578,10 +13609,7 @@ var WorkflowContext = class _WorkflowContext {
13578
13609
  return hardAskSignal ? hardSignalStorage.run(hardAskSignal, runWithAskSignal) : runWithAskSignal();
13579
13610
  }
13580
13611
  async executeAgentCall(agent2, input, options, handoffMessages, usageCapture, sessionHistory = normalizeSessionHistory(this.sessionHistory)) {
13581
- const tracker = { humanWaitMs: 0, activeHumanWaits: 0 };
13582
- const enclosing = timeoutTrackerStorage.getStore() ?? [];
13583
- return timeoutTrackerStorage.run(
13584
- [...enclosing, tracker],
13612
+ return runWithAskClock(
13585
13613
  () => this.executeAgentCallImpl(
13586
13614
  agent2,
13587
13615
  input,
@@ -13856,7 +13884,7 @@ ${appendedSchemaText}`;
13856
13884
  );
13857
13885
  }
13858
13886
  const startTime = Date.now();
13859
- const timeoutTracker = timeoutTrackerStorage.getStore()?.at(-1);
13887
+ const askClock = currentAskClock();
13860
13888
  const timingTotals = { turns: 0, queuedMs: 0, retryMs: 0, wireMs: 0 };
13861
13889
  const currentMessages = [...messages];
13862
13890
  let turns = 0;
@@ -13873,13 +13901,16 @@ ${appendedSchemaText}`;
13873
13901
  while (turns < maxTurns) {
13874
13902
  this.currentSignal?.throwIfAborted();
13875
13903
  const now = Date.now();
13876
- const elapsedMs = now - startTime - (timeoutTracker ? pausedHumanWaitMs(timeoutTracker, now) : 0);
13877
- if (elapsedMs > timeoutMs) {
13904
+ const elapsedMs = now - startTime;
13905
+ const pausedMs = askClock ? pausedAskClockMs(askClock, now) : 0;
13906
+ const chargedMs = Math.max(0, elapsedMs - Math.min(pausedMs, Math.max(0, elapsedMs)));
13907
+ if (chargedMs > timeoutMs) {
13878
13908
  throw new TimeoutError(
13879
13909
  "ctx.ask()",
13880
13910
  timeoutMs,
13881
13911
  timingTotals.turns > 0 ? {
13882
13912
  elapsedMs,
13913
+ chargedMs,
13883
13914
  queuedMs: timingTotals.queuedMs,
13884
13915
  retryMs: timingTotals.retryMs,
13885
13916
  wireMs: timingTotals.wireMs,
@@ -15749,12 +15780,7 @@ ${summaryResponse.content}`
15749
15780
  }
15750
15781
  // ── ctx.awaitHuman() ──────────────────────────────────────────────────
15751
15782
  async awaitHuman(options) {
15752
- const trackers = timeoutTrackerStorage.getStore();
15753
- const startedAt = Date.now();
15754
- for (const tracker of trackers ?? []) {
15755
- if (tracker.activeHumanWaits++ === 0) tracker.humanWaitStartedAt = startedAt;
15756
- }
15757
- try {
15783
+ return pauseAskClocks(async () => {
15758
15784
  if (this.spanManager) {
15759
15785
  return await this.spanManager.withSpanAsync(
15760
15786
  "axl.ctx.awaitHuman",
@@ -15771,16 +15797,7 @@ ${summaryResponse.content}`
15771
15797
  );
15772
15798
  }
15773
15799
  return await this._awaitHumanImpl(options);
15774
- } finally {
15775
- const finishedAt = Date.now();
15776
- for (const tracker of trackers ?? []) {
15777
- tracker.activeHumanWaits--;
15778
- if (tracker.activeHumanWaits === 0 && tracker.humanWaitStartedAt !== void 0) {
15779
- tracker.humanWaitMs += finishedAt - tracker.humanWaitStartedAt;
15780
- tracker.humanWaitStartedAt = void 0;
15781
- }
15782
- }
15783
- }
15800
+ });
15784
15801
  }
15785
15802
  async _awaitHumanImpl(options) {
15786
15803
  const branchSignal = this.currentSignal;
@@ -16777,7 +16794,7 @@ function workflow(config) {
16777
16794
  // src/runtime.ts
16778
16795
  import { EventEmitter as EventEmitter2 } from "events";
16779
16796
  import { randomUUID as randomUUID4 } from "crypto";
16780
- import { AsyncLocalStorage as AsyncLocalStorage3 } from "async_hooks";
16797
+ import { AsyncLocalStorage as AsyncLocalStorage4 } from "async_hooks";
16781
16798
  import { appendFileSync, mkdirSync as mkdirSync2 } from "fs";
16782
16799
  import { dirname } from "path";
16783
16800
 
@@ -18966,7 +18983,7 @@ function assertNoRemovedObservationCallbacks(options) {
18966
18983
  `runtime.createContext() no longer accepts ${removed.join(", ")}. Observe ctx.events or use runtime.stream() instead. See docs/migration/stream-first-observation.md.`
18967
18984
  );
18968
18985
  }
18969
- var costScopeStorage = new AsyncLocalStorage3();
18986
+ var costScopeStorage = new AsyncLocalStorage4();
18970
18987
  function forwardAbortSignal(external, internal) {
18971
18988
  if (!external) return () => {
18972
18989
  };