@axlsdk/axl 0.24.1 → 0.24.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/dist/index.cjs CHANGED
@@ -352,12 +352,14 @@ function preserveErrorCause(error, cause) {
352
352
  });
353
353
  return error;
354
354
  }
355
+ var TOOL_FAILURE_MARKER = /* @__PURE__ */ Symbol.for("axl.toolFailure.v1");
355
356
  var ToolFailure = class extends AxlError {
356
357
  modelMessage;
357
358
  constructor(options) {
358
359
  super(options.code ?? "TOOL_FAILURE", options.message);
359
360
  this.name = "ToolFailure";
360
361
  this.modelMessage = options.modelMessage;
362
+ Object.defineProperty(this, TOOL_FAILURE_MARKER, { value: true });
361
363
  if (options.cause !== void 0) {
362
364
  Object.defineProperty(this, "cause", {
363
365
  configurable: true,
@@ -367,6 +369,13 @@ var ToolFailure = class extends AxlError {
367
369
  }
368
370
  }
369
371
  };
372
+ function isToolFailureError(error) {
373
+ try {
374
+ return error instanceof ToolFailure || typeof error === "object" && error !== null && error[TOOL_FAILURE_MARKER] === true && typeof error.modelMessage === "string";
375
+ } catch {
376
+ return false;
377
+ }
378
+ }
370
379
  var ToolModelOutputError = class extends AxlError {
371
380
  toolName;
372
381
  cause;
@@ -548,7 +557,7 @@ var sharedGuard = typeof installedGuard === "object" && installedGuard !== null
548
557
  var buildPath = typeof __AXL_BUILD_PATH__ === "string" ? __AXL_BUILD_PATH__ : "<source>";
549
558
  var thisCopy = {
550
559
  path: buildPath.startsWith("file:") ? (0, import_node_url.fileURLToPath)(buildPath) : buildPath,
551
- version: true ? "0.24.1" : "unknown"
560
+ version: true ? "0.24.2" : "unknown"
552
561
  };
553
562
  function warnCrossCopy(other, joined) {
554
563
  if (other === thisCopy) return;
@@ -649,10 +658,16 @@ var AccountingScope = class {
649
658
  reasons = /* @__PURE__ */ new Map();
650
659
  breakdown = { generation: 0, judging: 0, external: 0 };
651
660
  provenance = /* @__PURE__ */ new Map();
661
+ modelCalls = /* @__PURE__ */ new Map();
662
+ modelTiming = /* @__PURE__ */ new Map();
663
+ diagnosticTokens = { input: 0, output: 0, reasoning: 0 };
664
+ agentCalls = 0;
665
+ captureTimingSamples;
652
666
  constructor(options) {
653
667
  this.parent = options.parent;
654
668
  this.purpose = options.purpose;
655
669
  this.admission = options.admission;
670
+ this.captureTimingSamples = options.captureTimingSamples === true;
656
671
  }
657
672
  get isFinalized() {
658
673
  return this.finalized;
@@ -681,7 +696,7 @@ var AccountingScope = class {
681
696
  else this.byKind.delete(op.kind);
682
697
  this.denied += 1;
683
698
  }
684
- recordSettled(op, cost, provenance, usage) {
699
+ recordSettled(op, cost, provenance, usage, timing) {
685
700
  this.seen.add(op.id);
686
701
  this.openOps.delete(op.id);
687
702
  this.settled += 1;
@@ -690,13 +705,57 @@ var AccountingScope = class {
690
705
  else this.breakdown[op.purpose] += cost;
691
706
  this.provenance.set(provenance, (this.provenance.get(provenance) ?? 0) + cost);
692
707
  if (usage) this.addUsage(usage);
708
+ this.recordAgentCall(op, usage, timing);
693
709
  }
694
- recordUnknown(op, reason, usage) {
710
+ recordUnknown(op, reason, usage, timing) {
695
711
  this.seen.add(op.id);
696
712
  this.openOps.delete(op.id);
697
713
  this.unknown += 1;
698
714
  this.reasons.set(reason, (this.reasons.get(reason) ?? 0) + 1);
699
715
  if (usage) this.addUsage(usage);
716
+ this.recordAgentCall(op, usage, timing);
717
+ }
718
+ recordAgentCall(op, usage, timing) {
719
+ if (!op.agentCall) return;
720
+ this.agentCalls++;
721
+ const model = op.diagnosticModelUri ?? op.model;
722
+ if (!model) return;
723
+ this.modelCalls.set(model, (this.modelCalls.get(model) ?? 0) + 1);
724
+ if (usage) {
725
+ const finite = (value) => typeof value === "number" && Number.isFinite(value) ? value : 0;
726
+ this.diagnosticTokens.input += finite(usage.inputTokens);
727
+ this.diagnosticTokens.output += finite(usage.outputTokens);
728
+ this.diagnosticTokens.reasoning += finite(usage.reasoningTokens);
729
+ }
730
+ if (!timing) return;
731
+ let bucket = this.modelTiming.get(model);
732
+ if (!bucket) {
733
+ bucket = {
734
+ calls: 0,
735
+ queuedMs: 0,
736
+ retryMs: 0,
737
+ wireMs: 0,
738
+ ...this.captureTimingSamples ? { samples: [] } : {}
739
+ };
740
+ this.modelTiming.set(model, bucket);
741
+ }
742
+ bucket.calls++;
743
+ bucket.queuedMs += timing.queuedMs;
744
+ bucket.retryMs += timing.retryMs;
745
+ bucket.wireMs += timing.wireMs;
746
+ bucket.samples?.push(timing);
747
+ if (timing.firstTokenMs != null) {
748
+ bucket.firstTokenMs = (bucket.firstTokenMs ?? 0) + timing.firstTokenMs;
749
+ bucket.firstTokenCalls = (bucket.firstTokenCalls ?? 0) + 1;
750
+ }
751
+ }
752
+ toDiagnostics() {
753
+ return {
754
+ modelCallCounts: Object.fromEntries(this.modelCalls),
755
+ tokens: { ...this.diagnosticTokens },
756
+ agentCalls: this.agentCalls,
757
+ modelTiming: Object.fromEntries(this.modelTiming)
758
+ };
700
759
  }
701
760
  hasSeen(id) {
702
761
  return this.seen.has(id);
@@ -768,14 +827,14 @@ function settleOperationUp(start, op, outcome) {
768
827
  if (scope.isFinalized) return;
769
828
  switch (outcome.outcome) {
770
829
  case "settled":
771
- scope.recordSettled(op, outcome.cost, outcome.provenance, outcome.usage);
830
+ scope.recordSettled(op, outcome.cost, outcome.provenance, outcome.usage, outcome.timing);
772
831
  if (scope.admission && !chargedControllers.has(scope.admission)) {
773
832
  chargedControllers.add(scope.admission);
774
833
  recordSpend(scope.admission, outcome.cost);
775
834
  }
776
835
  break;
777
836
  case "unknown":
778
- scope.recordUnknown(op, outcome.reason, outcome.usage);
837
+ scope.recordUnknown(op, outcome.reason, outcome.usage, outcome.timing);
779
838
  break;
780
839
  case "retracted":
781
840
  scope.recordRetracted(op);
@@ -827,6 +886,8 @@ function openOperation(descriptor) {
827
886
  kind: descriptor.kind,
828
887
  purpose: scope.purpose,
829
888
  model: descriptor.model,
889
+ diagnosticModelUri: descriptor.diagnosticModelUri,
890
+ agentCall: descriptor.agentCall === true,
830
891
  dispatched: false,
831
892
  dispatchObservable: false
832
893
  };
@@ -867,25 +928,31 @@ function openOperation(descriptor) {
867
928
  outcome: "settled",
868
929
  cost: input.cost,
869
930
  provenance: input.provenance ?? "adapter_reported",
870
- usage: input.usage
931
+ usage: input.usage,
932
+ timing: input.timing
871
933
  });
872
934
  return;
873
935
  }
874
936
  if (input.cost !== void 0 || input.usage !== void 0) {
875
- finish({ outcome: "unknown", reason: "unpriced_model", usage: input.usage });
937
+ finish({
938
+ outcome: "unknown",
939
+ reason: "unpriced_model",
940
+ usage: input.usage,
941
+ timing: input.timing
942
+ });
876
943
  return;
877
944
  }
878
- handle.settleFailure();
945
+ handle.settleFailure(void 0, input.timing);
879
946
  },
880
947
  settleUnknown(reason, usage) {
881
948
  finish({ outcome: "unknown", reason, usage });
882
949
  },
883
- settleFailure(usage) {
950
+ settleFailure(usage, timing) {
884
951
  if (op.dispatchObservable && !op.dispatched) {
885
- finish({ outcome: "settled", cost: 0, provenance: "adapter_reported", usage });
952
+ finish({ outcome: "settled", cost: 0, provenance: "adapter_reported", usage, timing });
886
953
  return;
887
954
  }
888
- finish({ outcome: "unknown", reason: "usage_missing", usage });
955
+ finish({ outcome: "unknown", reason: "usage_missing", usage, timing });
889
956
  },
890
957
  run(fn) {
891
958
  return runWithDispatchAdmission(handle.dispatchAdmission, fn);
@@ -898,7 +965,8 @@ async function runInAccountingScope(options, fn) {
898
965
  const scope = new AccountingScope({
899
966
  parent,
900
967
  purpose: options.purpose ?? parent?.purpose ?? "generation",
901
- admission: options.admission
968
+ admission: options.admission,
969
+ captureTimingSamples: options.captureTimingSamples
902
970
  });
903
971
  const inheritedGuard = sharedGuard.storage.getStore();
904
972
  const enclosingGuard = inheritedGuard && (inheritedGuard.isActive?.() ?? true) ? inheritedGuard : void 0;
@@ -916,7 +984,8 @@ async function runInAccountingScope(options, fn) {
916
984
  "The active @axlsdk/axl accounting scope uses an incompatible loaded copy; paid work was refused before dispatch."
917
985
  )
918
986
  },
919
- accounting: scope.toAccounting()
987
+ accounting: scope.toAccounting(),
988
+ diagnostics: scope.toDiagnostics()
920
989
  };
921
990
  }
922
991
  const markUninstrumented = () => {
@@ -940,10 +1009,18 @@ async function runInAccountingScope(options, fn) {
940
1009
  () => accountingStorage.run(scope, fn)
941
1010
  );
942
1011
  scope.finalize();
943
- return { outcome: { status: "fulfilled", value }, accounting: scope.toAccounting() };
1012
+ return {
1013
+ outcome: { status: "fulfilled", value },
1014
+ accounting: scope.toAccounting(),
1015
+ diagnostics: scope.toDiagnostics()
1016
+ };
944
1017
  } catch (error) {
945
1018
  scope.finalize();
946
- return { outcome: { status: "rejected", error }, accounting: scope.toAccounting() };
1019
+ return {
1020
+ outcome: { status: "rejected", error },
1021
+ accounting: scope.toAccounting(),
1022
+ diagnostics: scope.toDiagnostics()
1023
+ };
947
1024
  }
948
1025
  }
949
1026
  function validateReportedCost(amountUsd) {
@@ -1322,10 +1399,12 @@ function toolArgumentIssues(error) {
1322
1399
  }
1323
1400
  return [{ path: [], code: "invalid_arguments", message: "Tool arguments are invalid." }];
1324
1401
  }
1325
- var TOOL_INTERNALS = /* @__PURE__ */ new WeakMap();
1402
+ var TOOL_INTERNALS = /* @__PURE__ */ Symbol.for("axl.tool.internals.v1");
1326
1403
  function getToolInternals(tool2) {
1327
- const internals = TOOL_INTERNALS.get(tool2);
1328
- if (!internals) throw new Error(`Tool "${tool2.name}" was not created by tool()`);
1404
+ const internals = tool2[TOOL_INTERNALS];
1405
+ if (!internals || typeof internals.prepareInput !== "function" || typeof internals.executePrepared !== "function") {
1406
+ throw new Error(`Tool "${tool2.name}" was not created by a compatible tool()`);
1407
+ }
1329
1408
  return internals;
1330
1409
  }
1331
1410
  function prepareToolInput(tool2, input) {
@@ -1426,9 +1505,11 @@ function tool(config) {
1426
1505
  },
1427
1506
  _execute: execute
1428
1507
  };
1429
- TOOL_INTERNALS.set(instance, {
1430
- prepareInput,
1431
- executePrepared
1508
+ Object.defineProperty(instance, TOOL_INTERNALS, {
1509
+ value: {
1510
+ prepareInput,
1511
+ executePrepared
1512
+ }
1432
1513
  });
1433
1514
  return instance;
1434
1515
  }
@@ -1459,6 +1540,7 @@ async function resolveApiKey(source) {
1459
1540
  // src/providers/default-endpoints.ts
1460
1541
  var OPENAI_DEFAULT_BASE_URL = "https://api.openai.com/v1";
1461
1542
  var ANTHROPIC_DEFAULT_BASE_URL = "https://api.anthropic.com/v1";
1543
+ var GEMINI_DEFAULT_BASE_URL = "https://generativelanguage.googleapis.com/v1beta";
1462
1544
 
1463
1545
  // src/providers/rate-limiter.ts
1464
1546
  function sanitizeRateLimitConfig(config) {
@@ -1856,12 +1938,36 @@ var anthropicQuotaDialect = makeDialect(
1856
1938
  return "unknown";
1857
1939
  }
1858
1940
  );
1941
+ var geminiQuotaDialect = makeDialect([], (error) => {
1942
+ if (error.code === "quota_exceeded") return "spend_cap";
1943
+ if (Array.isArray(error.details)) {
1944
+ for (const detail of error.details) {
1945
+ if (typeof detail !== "object" || detail === null) continue;
1946
+ const violations = detail.violations;
1947
+ if (!Array.isArray(violations)) continue;
1948
+ if (violations.some((violation) => {
1949
+ if (typeof violation !== "object" || violation === null) return false;
1950
+ const id = violation.quotaId;
1951
+ return typeof id === "string" && /perday|daily|spend|billing/i.test(id);
1952
+ }))
1953
+ return "spend_cap";
1954
+ }
1955
+ }
1956
+ const message = error.message;
1957
+ if (typeof message === "string" && /monthly spending cap|spend(?:-based|ing)? (?:cap|limit)|prepay(?:ment)? credits? (?:are )?depleted/i.test(
1958
+ message
1959
+ )) {
1960
+ return "spend_cap";
1961
+ }
1962
+ return "unknown";
1963
+ });
1859
1964
  var DIALECTS = /* @__PURE__ */ new Map([
1860
1965
  ["openai", { origin: new URL(OPENAI_DEFAULT_BASE_URL).origin, dialect: openaiQuotaDialect }],
1861
1966
  [
1862
1967
  "anthropic",
1863
1968
  { origin: new URL(ANTHROPIC_DEFAULT_BASE_URL).origin, dialect: anthropicQuotaDialect }
1864
- ]
1969
+ ],
1970
+ ["google", { origin: new URL(GEMINI_DEFAULT_BASE_URL).origin, dialect: geminiQuotaDialect }]
1865
1971
  ]);
1866
1972
  function quotaDialectFor(family, origin) {
1867
1973
  const entry = DIALECTS.get(family);
@@ -6052,7 +6158,7 @@ var GEMINI_PRICING = {
6052
6158
  },
6053
6159
  "gemini-3.8-flash": { input: 75e-8, cached: 75e-9, output: 375e-8 }
6054
6160
  };
6055
- var CANONICAL_GEMINI_BASE_URL = "https://generativelanguage.googleapis.com/v1beta";
6161
+ var CANONICAL_GEMINI_BASE_URL = GEMINI_DEFAULT_BASE_URL;
6056
6162
  function isValidTokenCount2(value) {
6057
6163
  return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
6058
6164
  }
@@ -6409,10 +6515,7 @@ var GeminiProvider = class {
6409
6515
  axlRateGovernors;
6410
6516
  constructor(options = {}) {
6411
6517
  this.apiKeySource = options.apiKey ?? process.env.GOOGLE_API_KEY ?? process.env.GEMINI_API_KEY ?? "";
6412
- this.baseUrl = (options.baseUrl ?? "https://generativelanguage.googleapis.com/v1beta").replace(
6413
- /\/$/,
6414
- ""
6415
- );
6518
+ this.baseUrl = (options.baseUrl ?? GEMINI_DEFAULT_BASE_URL).replace(/\/$/, "");
6416
6519
  assertSafeProviderBaseUrl(
6417
6520
  this.baseUrl,
6418
6521
  "Google provider",
@@ -11611,6 +11714,34 @@ function toAccountingUsage(usage) {
11611
11714
  cacheWriteTokens: usage.cache_write_tokens ?? 0
11612
11715
  };
11613
11716
  }
11717
+ function safeTiming(response) {
11718
+ try {
11719
+ const timing = response.timing;
11720
+ if (!timing) return void 0;
11721
+ const queuedMs = timing.queuedMs;
11722
+ const retryMs = timing.retryMs;
11723
+ const wireMs = timing.wireMs;
11724
+ if (![queuedMs, retryMs, wireMs].every((value) => Number.isFinite(value) && value >= 0)) {
11725
+ return void 0;
11726
+ }
11727
+ const attempts = timing.attempts;
11728
+ const ttfbMs = timing.ttfbMs;
11729
+ const rateLimitRetries = timing.rateLimitRetries;
11730
+ const firstTokenMs = timing.firstTokenMs;
11731
+ const valid = (value) => typeof value === "number" && Number.isFinite(value) && value >= 0;
11732
+ return {
11733
+ queuedMs,
11734
+ retryMs,
11735
+ wireMs,
11736
+ ...valid(attempts) ? { attempts } : {},
11737
+ ...valid(ttfbMs) ? { ttfbMs } : {},
11738
+ ...valid(rateLimitRetries) ? { rateLimitRetries } : {},
11739
+ ...valid(firstTokenMs) ? { firstTokenMs } : {}
11740
+ };
11741
+ } catch {
11742
+ return void 0;
11743
+ }
11744
+ }
11614
11745
  function composeLifecycle(caller, onDispatch) {
11615
11746
  return {
11616
11747
  onDispatch() {
@@ -11804,7 +11935,13 @@ var CaptureRecorder = class {
11804
11935
  }
11805
11936
  };
11806
11937
  function openProviderOperation(raw, kind, options) {
11807
- const handle = openOperation({ kind, model: options.model, provider: raw.name });
11938
+ const handle = openOperation({
11939
+ kind,
11940
+ model: options.model,
11941
+ diagnosticModelUri: options.accountingModelUri,
11942
+ provider: raw.name,
11943
+ agentCall: options.accountingModelUri !== void 0
11944
+ });
11808
11945
  if (handle && raw.reportsRequestLifecycle === true) handle.markDispatchObservable();
11809
11946
  return handle;
11810
11947
  }
@@ -11821,7 +11958,8 @@ function createScopedProvider(raw) {
11821
11958
  handle.settle({
11822
11959
  cost: response.cost,
11823
11960
  provenance: response.costProvenance,
11824
- usage: toAccountingUsage(response.usage)
11961
+ usage: toAccountingUsage(response.usage),
11962
+ timing: safeTiming(response)
11825
11963
  });
11826
11964
  recorder?.end({ response });
11827
11965
  return response;
@@ -11876,7 +12014,8 @@ function createScopedProvider(raw) {
11876
12014
  handle?.settle({
11877
12015
  cost: result.value.cost,
11878
12016
  provenance: result.value.costProvenance,
11879
- usage: toAccountingUsage(result.value.usage)
12017
+ usage: toAccountingUsage(result.value.usage),
12018
+ timing: safeTiming(result.value)
11880
12019
  });
11881
12020
  settled = true;
11882
12021
  recorder?.end({
@@ -12309,13 +12448,6 @@ function eventError(error) {
12309
12448
  return { name: "Error", message: "Unknown thrown value" };
12310
12449
  }
12311
12450
  }
12312
- function isToolFailure(error) {
12313
- try {
12314
- return error instanceof ToolFailure;
12315
- } catch {
12316
- return false;
12317
- }
12318
- }
12319
12451
  function cancellation(phase, error, result) {
12320
12452
  let reason;
12321
12453
  try {
@@ -12331,7 +12463,7 @@ function cancellation(phase, error, result) {
12331
12463
  }
12332
12464
  function failed(phase, error, options = {}) {
12333
12465
  let modelMessage;
12334
- if (isToolFailure(error)) {
12466
+ if (isToolFailureError(error)) {
12335
12467
  try {
12336
12468
  modelMessage = typeof error.modelMessage === "string" ? error.modelMessage : void 0;
12337
12469
  } catch {
@@ -14019,6 +14151,7 @@ ${appendedSchemaText}`;
14019
14151
  const turnStart = Date.now();
14020
14152
  const chatOptions = {
14021
14153
  model,
14154
+ accountingModelUri: effectiveModelUri,
14022
14155
  temperature: options?.temperature ?? agent2._config.temperature,
14023
14156
  tools: toolDefs.length > 0 ? toolDefs : void 0,
14024
14157
  maxTokens: options?.maxTokens ?? agent2._config.maxTokens ?? 4096,
@@ -20764,8 +20897,9 @@ var AxlRuntime = class extends import_node_events2.EventEmitter {
20764
20897
  * new paid operations once known spend reaches the limit. Already-dispatched
20765
20898
  * work still settles and is still counted.
20766
20899
  *
20767
- * `metadata`, `modelTiming` and `traces` remain EVENT-derived and therefore
20768
- * depend on trace configuration; `accounting` never does.
20900
+ * Model metadata and timing share the settlement scope with accounting, so
20901
+ * they cross runtimes and compatible ESM/CJS copies. Workflow names and
20902
+ * captured traces still come from this runtime's events.
20769
20903
  */
20770
20904
  async trackOutcome(fn, options) {
20771
20905
  const parentScope = costScopeStorage.getStore();
@@ -20774,49 +20908,11 @@ var AxlRuntime = class extends import_node_events2.EventEmitter {
20774
20908
  trackedIds: /* @__PURE__ */ new Set(),
20775
20909
  parent: parentScope
20776
20910
  };
20777
- const modelCalls = /* @__PURE__ */ new Map();
20778
- const modelTiming = /* @__PURE__ */ new Map();
20779
- const captureTimingSamples = options?.captureTimingSamples === true;
20780
20911
  const workflowCalls = /* @__PURE__ */ new Map();
20781
- const tokens = { input: 0, output: 0, reasoning: 0 };
20782
- let agentCalls = 0;
20783
20912
  const capturedTraces = options?.captureTraces ? [] : void 0;
20784
20913
  const listener = (event) => {
20785
20914
  if (!scope.trackedIds.has(event.executionId)) return;
20786
20915
  scope.totalCost += eventCostContribution(event);
20787
- if (event.type === "agent_call_end") {
20788
- if (event.model) modelCalls.set(event.model, (modelCalls.get(event.model) ?? 0) + 1);
20789
- agentCalls++;
20790
- if (event.tokens) {
20791
- tokens.input += event.tokens.input ?? 0;
20792
- tokens.output += event.tokens.output ?? 0;
20793
- tokens.reasoning += event.tokens.reasoning ?? 0;
20794
- }
20795
- const failed2 = event.data?.error != null;
20796
- if (event.model && event.timing && !failed2) {
20797
- const t = event.timing;
20798
- let bucket = modelTiming.get(event.model);
20799
- if (!bucket) {
20800
- bucket = {
20801
- calls: 0,
20802
- queuedMs: 0,
20803
- retryMs: 0,
20804
- wireMs: 0,
20805
- ...captureTimingSamples ? { samples: [] } : {}
20806
- };
20807
- modelTiming.set(event.model, bucket);
20808
- }
20809
- bucket.calls++;
20810
- bucket.samples?.push(t);
20811
- bucket.queuedMs += t.queuedMs;
20812
- bucket.retryMs += t.retryMs;
20813
- bucket.wireMs += t.wireMs;
20814
- if (t.firstTokenMs != null) {
20815
- bucket.firstTokenMs = (bucket.firstTokenMs ?? 0) + t.firstTokenMs;
20816
- bucket.firstTokenCalls = (bucket.firstTokenCalls ?? 0) + 1;
20817
- }
20818
- }
20819
- }
20820
20916
  if (event.type === "workflow_start" && event.workflow) {
20821
20917
  workflowCalls.set(event.workflow, (workflowCalls.get(event.workflow) ?? 0) + 1);
20822
20918
  }
@@ -20842,9 +20938,14 @@ var AxlRuntime = class extends import_node_events2.EventEmitter {
20842
20938
  this.on("trace", listener);
20843
20939
  let outcome;
20844
20940
  let accounting;
20941
+ let diagnostics;
20845
20942
  try {
20846
- ({ outcome, accounting } = await runInAccountingScope(
20847
- { purpose: options?.purpose, admission: options?.admission },
20943
+ ({ outcome, accounting, diagnostics } = await runInAccountingScope(
20944
+ {
20945
+ purpose: options?.purpose,
20946
+ admission: options?.admission,
20947
+ captureTimingSamples: options?.captureTimingSamples
20948
+ },
20848
20949
  () => (
20849
20950
  // Capture wraps the cost scope rather than the other way round so a
20850
20951
  // record can never be written for an operation the accounting scope
@@ -20868,13 +20969,13 @@ var AxlRuntime = class extends import_node_events2.EventEmitter {
20868
20969
  return {
20869
20970
  ...outcome,
20870
20971
  accounting,
20871
- ...modelTiming.size > 0 ? { modelTiming: Object.fromEntries(modelTiming) } : {},
20972
+ ...Object.keys(diagnostics.modelTiming).length > 0 ? { modelTiming: diagnostics.modelTiming } : {},
20872
20973
  ...capturedTraces ? { traces: capturedTraces } : {},
20873
20974
  metadata: {
20874
- models: [...modelCalls.keys()],
20875
- modelCallCounts: modelCalls.size > 0 ? Object.fromEntries(modelCalls) : void 0,
20876
- tokens,
20877
- agentCalls,
20975
+ models: Object.keys(diagnostics.modelCallCounts),
20976
+ modelCallCounts: Object.keys(diagnostics.modelCallCounts).length > 0 ? diagnostics.modelCallCounts : void 0,
20977
+ tokens: diagnostics.tokens,
20978
+ agentCalls: diagnostics.agentCalls,
20878
20979
  workflows: [...workflowCalls.keys()],
20879
20980
  workflowCallCounts: workflowCalls.size > 0 ? Object.fromEntries(workflowCalls) : void 0
20880
20981
  }