@axlsdk/axl 0.13.6 → 0.13.8

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
@@ -1373,10 +1373,13 @@ declare class AxlRuntime extends EventEmitter {
1373
1373
  executeWorkflow?: (input: unknown, runtime?: AxlRuntime) => Promise<{
1374
1374
  output: unknown;
1375
1375
  cost?: number;
1376
+ metadata?: Record<string, unknown>;
1376
1377
  }>;
1377
1378
  } | undefined;
1378
1379
  /** Run a registered eval by name. */
1379
- runRegisteredEval(name: string): Promise<unknown>;
1380
+ runRegisteredEval(name: string, options?: {
1381
+ metadata?: Record<string, unknown>;
1382
+ }): Promise<unknown>;
1380
1383
  /** Get all execution info (running + completed + historical). */
1381
1384
  getExecutions(): Promise<ExecutionInfo[]>;
1382
1385
  /**
@@ -1451,7 +1454,7 @@ declare class AxlRuntime extends EventEmitter {
1451
1454
  *
1452
1455
  * @see Spec Section 13.6
1453
1456
  */
1454
- evalCompare(baseline: unknown, candidate: unknown): Promise<unknown>;
1457
+ evalCompare(baseline: unknown, candidate: unknown, options?: unknown): Promise<unknown>;
1455
1458
  /**
1456
1459
  * Track cost across any runtime operations within the given function.
1457
1460
  * Uses AsyncLocalStorage to scope cost attribution to specific execution IDs,
@@ -1463,6 +1466,30 @@ declare class AxlRuntime extends EventEmitter {
1463
1466
  result: T;
1464
1467
  cost: number;
1465
1468
  }>;
1469
+ /**
1470
+ * Track cost and execution metadata across any runtime operations within the given function.
1471
+ * Uses AsyncLocalStorage to scope attribution to specific execution IDs,
1472
+ * making it correct with concurrent calls.
1473
+ *
1474
+ * Returns cost (same as `trackCost`) plus metadata extracted from trace events:
1475
+ * models (unique URIs), tokens (input/output/reasoning sums), and agent call count.
1476
+ *
1477
+ * Works with both `createContext()` and `execute()` calls inside `fn`.
1478
+ */
1479
+ trackExecution<T>(fn: () => Promise<T>): Promise<{
1480
+ result: T;
1481
+ cost: number;
1482
+ metadata: {
1483
+ models: string[];
1484
+ modelCallCounts?: Record<string, number>;
1485
+ tokens: {
1486
+ input: number;
1487
+ output: number;
1488
+ reasoning: number;
1489
+ };
1490
+ agentCalls: number;
1491
+ };
1492
+ }>;
1466
1493
  /** Register an execution ID with the active cost scope for trackCost() attribution. */
1467
1494
  private registerWithCostScope;
1468
1495
  /**
package/dist/index.d.ts CHANGED
@@ -1373,10 +1373,13 @@ declare class AxlRuntime extends EventEmitter {
1373
1373
  executeWorkflow?: (input: unknown, runtime?: AxlRuntime) => Promise<{
1374
1374
  output: unknown;
1375
1375
  cost?: number;
1376
+ metadata?: Record<string, unknown>;
1376
1377
  }>;
1377
1378
  } | undefined;
1378
1379
  /** Run a registered eval by name. */
1379
- runRegisteredEval(name: string): Promise<unknown>;
1380
+ runRegisteredEval(name: string, options?: {
1381
+ metadata?: Record<string, unknown>;
1382
+ }): Promise<unknown>;
1380
1383
  /** Get all execution info (running + completed + historical). */
1381
1384
  getExecutions(): Promise<ExecutionInfo[]>;
1382
1385
  /**
@@ -1451,7 +1454,7 @@ declare class AxlRuntime extends EventEmitter {
1451
1454
  *
1452
1455
  * @see Spec Section 13.6
1453
1456
  */
1454
- evalCompare(baseline: unknown, candidate: unknown): Promise<unknown>;
1457
+ evalCompare(baseline: unknown, candidate: unknown, options?: unknown): Promise<unknown>;
1455
1458
  /**
1456
1459
  * Track cost across any runtime operations within the given function.
1457
1460
  * Uses AsyncLocalStorage to scope cost attribution to specific execution IDs,
@@ -1463,6 +1466,30 @@ declare class AxlRuntime extends EventEmitter {
1463
1466
  result: T;
1464
1467
  cost: number;
1465
1468
  }>;
1469
+ /**
1470
+ * Track cost and execution metadata across any runtime operations within the given function.
1471
+ * Uses AsyncLocalStorage to scope attribution to specific execution IDs,
1472
+ * making it correct with concurrent calls.
1473
+ *
1474
+ * Returns cost (same as `trackCost`) plus metadata extracted from trace events:
1475
+ * models (unique URIs), tokens (input/output/reasoning sums), and agent call count.
1476
+ *
1477
+ * Works with both `createContext()` and `execute()` calls inside `fn`.
1478
+ */
1479
+ trackExecution<T>(fn: () => Promise<T>): Promise<{
1480
+ result: T;
1481
+ cost: number;
1482
+ metadata: {
1483
+ models: string[];
1484
+ modelCallCounts?: Record<string, number>;
1485
+ tokens: {
1486
+ input: number;
1487
+ output: number;
1488
+ reasoning: number;
1489
+ };
1490
+ agentCalls: number;
1491
+ };
1492
+ }>;
1466
1493
  /** Register an execution ID with the active cost scope for trackCost() attribution. */
1467
1494
  private registerWithCostScope;
1468
1495
  /**
package/dist/index.js CHANGED
@@ -5420,7 +5420,7 @@ var AxlRuntime = class extends EventEmitter2 {
5420
5420
  return this.registeredEvals.get(name);
5421
5421
  }
5422
5422
  /** Run a registered eval by name. */
5423
- async runRegisteredEval(name) {
5423
+ async runRegisteredEval(name, options) {
5424
5424
  const entry = this.registeredEvals.get(name);
5425
5425
  if (!entry) throw new Error(`Eval "${name}" is not registered`);
5426
5426
  let result;
@@ -5435,10 +5435,18 @@ var AxlRuntime = class extends EventEmitter2 {
5435
5435
  }
5436
5436
  const originalExecuteFn = entry.executeWorkflow;
5437
5437
  const wrappedExecuteFn = async (input, runtime) => {
5438
- const { result: result2, cost: trackedCost } = await this.trackCost(async () => {
5438
+ const {
5439
+ result: result2,
5440
+ cost: trackedCost,
5441
+ metadata
5442
+ } = await this.trackExecution(async () => {
5439
5443
  return originalExecuteFn(input, runtime);
5440
5444
  });
5441
- return { output: result2.output, cost: result2.cost ?? trackedCost };
5445
+ return {
5446
+ output: result2.output,
5447
+ cost: result2.cost ?? trackedCost,
5448
+ metadata: result2.metadata ?? metadata
5449
+ };
5442
5450
  };
5443
5451
  result = await runEvalFn(entry.config, wrappedExecuteFn, this);
5444
5452
  } else {
@@ -5447,6 +5455,12 @@ var AxlRuntime = class extends EventEmitter2 {
5447
5455
  );
5448
5456
  }
5449
5457
  const resultObj = result;
5458
+ if (options?.metadata) {
5459
+ resultObj.metadata = {
5460
+ ...resultObj.metadata,
5461
+ ...options.metadata
5462
+ };
5463
+ }
5450
5464
  try {
5451
5465
  await this.saveEvalResult({
5452
5466
  id: resultObj.id ?? randomUUID2(),
@@ -5982,10 +5996,10 @@ var AxlRuntime = class extends EventEmitter2 {
5982
5996
  );
5983
5997
  }
5984
5998
  const executeWorkflow = async (input) => {
5985
- const { result, cost } = await this.trackCost(async () => {
5999
+ const { result, cost, metadata } = await this.trackExecution(async () => {
5986
6000
  return this.execute(config.workflow, input);
5987
6001
  });
5988
- return { output: result, cost };
6002
+ return { output: result, cost, metadata };
5989
6003
  };
5990
6004
  return runEvalFn(config, executeWorkflow, this);
5991
6005
  }
@@ -5995,7 +6009,7 @@ var AxlRuntime = class extends EventEmitter2 {
5995
6009
  *
5996
6010
  * @see Spec Section 13.6
5997
6011
  */
5998
- async evalCompare(baseline, candidate) {
6012
+ async evalCompare(baseline, candidate, options) {
5999
6013
  let evalCompareFn;
6000
6014
  try {
6001
6015
  ({ evalCompare: evalCompareFn } = await import("@axlsdk/eval"));
@@ -6004,7 +6018,7 @@ var AxlRuntime = class extends EventEmitter2 {
6004
6018
  "axl-eval is required for AxlRuntime.evalCompare(). Install it with: npm install @axlsdk/eval"
6005
6019
  );
6006
6020
  }
6007
- return evalCompareFn(baseline, candidate);
6021
+ return evalCompareFn(baseline, candidate, options);
6008
6022
  }
6009
6023
  /**
6010
6024
  * Track cost across any runtime operations within the given function.
@@ -6014,24 +6028,58 @@ var AxlRuntime = class extends EventEmitter2 {
6014
6028
  * Works with both `createContext()` and `execute()` calls inside `fn`.
6015
6029
  */
6016
6030
  async trackCost(fn) {
6031
+ const { result, cost } = await this.trackExecution(fn);
6032
+ return { result, cost };
6033
+ }
6034
+ /**
6035
+ * Track cost and execution metadata across any runtime operations within the given function.
6036
+ * Uses AsyncLocalStorage to scope attribution to specific execution IDs,
6037
+ * making it correct with concurrent calls.
6038
+ *
6039
+ * Returns cost (same as `trackCost`) plus metadata extracted from trace events:
6040
+ * models (unique URIs), tokens (input/output/reasoning sums), and agent call count.
6041
+ *
6042
+ * Works with both `createContext()` and `execute()` calls inside `fn`.
6043
+ */
6044
+ async trackExecution(fn) {
6017
6045
  const parentScope = costScopeStorage.getStore();
6018
6046
  const scope = {
6019
6047
  totalCost: 0,
6020
6048
  trackedIds: /* @__PURE__ */ new Set(),
6021
6049
  parent: parentScope
6022
6050
  };
6023
- const costListener = (event) => {
6024
- if (event.cost && scope.trackedIds.has(event.executionId)) {
6025
- scope.totalCost += event.cost;
6051
+ const modelCalls = /* @__PURE__ */ new Map();
6052
+ const tokens = { input: 0, output: 0, reasoning: 0 };
6053
+ let agentCalls = 0;
6054
+ const listener = (event) => {
6055
+ if (!scope.trackedIds.has(event.executionId)) return;
6056
+ if (event.cost) scope.totalCost += event.cost;
6057
+ if (event.type === "agent_call") {
6058
+ if (event.model) modelCalls.set(event.model, (modelCalls.get(event.model) ?? 0) + 1);
6059
+ agentCalls++;
6060
+ if (event.tokens) {
6061
+ tokens.input += event.tokens.input ?? 0;
6062
+ tokens.output += event.tokens.output ?? 0;
6063
+ tokens.reasoning += event.tokens.reasoning ?? 0;
6064
+ }
6026
6065
  }
6027
6066
  };
6028
6067
  this.setMaxListeners(this.getMaxListeners() + 1);
6029
- this.on("trace", costListener);
6068
+ this.on("trace", listener);
6030
6069
  try {
6031
6070
  const result = await costScopeStorage.run(scope, fn);
6032
- return { result, cost: scope.totalCost };
6071
+ return {
6072
+ result,
6073
+ cost: scope.totalCost,
6074
+ metadata: {
6075
+ models: [...modelCalls.keys()],
6076
+ modelCallCounts: modelCalls.size > 0 ? Object.fromEntries(modelCalls) : void 0,
6077
+ tokens,
6078
+ agentCalls
6079
+ }
6080
+ };
6033
6081
  } finally {
6034
- this.off("trace", costListener);
6082
+ this.off("trace", listener);
6035
6083
  this.setMaxListeners(this.getMaxListeners() - 1);
6036
6084
  }
6037
6085
  }