axiom 0.22.1 → 0.23.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/README.md CHANGED
@@ -10,6 +10,8 @@ Axiom AI SDK provides
10
10
  npm install axiom
11
11
  ```
12
12
 
13
+ Evals require Node 22.20 or higher.
14
+
13
15
  ## Model Wrapping
14
16
 
15
17
  ```ts
package/dist/bin.cjs CHANGED
@@ -478,21 +478,6 @@ var u = p(r);
478
478
  // src/evals/run-vitest.ts
479
479
  var import_node = require("vitest/node");
480
480
 
481
- // src/evals/context/global-flags.ts
482
- var GLOBAL_OVERRIDES_SYMBOL = Symbol.for("axiom.global_flag_overrides");
483
- function getRoot() {
484
- return globalThis[GLOBAL_OVERRIDES_SYMBOL] ?? {};
485
- }
486
- function setRoot(val) {
487
- globalThis[GLOBAL_OVERRIDES_SYMBOL] = val;
488
- }
489
- function setGlobalFlagOverrides(overrides2) {
490
- setRoot(overrides2);
491
- }
492
- function getGlobalFlagOverrides() {
493
- return getRoot();
494
- }
495
-
496
481
  // src/evals/context/storage.ts
497
482
  var import_api9 = require("@opentelemetry/api");
498
483
 
@@ -563,6 +548,15 @@ function createAsyncHook(_name) {
563
548
  };
564
549
  }
565
550
 
551
+ // src/evals/context/global-flags.ts
552
+ var GLOBAL_OVERRIDES_SYMBOL = Symbol.for("axiom.global_flag_overrides");
553
+ function setRoot(val) {
554
+ globalThis[GLOBAL_OVERRIDES_SYMBOL] = val;
555
+ }
556
+ function setGlobalFlagOverrides(overrides2) {
557
+ setRoot(overrides2);
558
+ }
559
+
566
560
  // src/validate-flags.ts
567
561
  var import_zod3 = require("zod");
568
562
 
@@ -610,7 +604,7 @@ var import_api4 = require("@opentelemetry/api");
610
604
  // package.json
611
605
  var package_default = {
612
606
  name: "axiom",
613
- version: "0.22.1",
607
+ version: "0.23.0",
614
608
  type: "module",
615
609
  author: "Axiom, Inc.",
616
610
  contributors: [
@@ -764,9 +758,6 @@ var import_api7 = require("@opentelemetry/api");
764
758
 
765
759
  // src/evals/context/storage.ts
766
760
  var CONFIG_SCOPE_SYMBOL = Symbol.for("axiom.eval.configScope");
767
- function getGlobalConfigScope() {
768
- return globalThis[CONFIG_SCOPE_SYMBOL];
769
- }
770
761
  var AXIOM_CONFIG_SYMBOL = Symbol.for("axiom.eval.config");
771
762
  function getAxiomConfig() {
772
763
  return globalThis[AXIOM_CONFIG_SYMBOL];
@@ -814,15 +805,20 @@ function withEvalContext(options = {}, fn) {
814
805
  fn
815
806
  );
816
807
  }
817
- function getConfigScope() {
818
- const current = EVAL_CONTEXT.get();
819
- return current?.configScope ?? getGlobalConfigScope();
820
- }
821
808
 
822
809
  // src/config/resolver.ts
810
+ var buildConsoleUrl = (urlString) => {
811
+ const url = new URL(urlString);
812
+ return `${url.protocol}//app.${url.host.split("api.").at(-1)}`;
813
+ };
823
814
  function resolveAxiomConnection(config) {
815
+ let consoleEndpointUrl = buildConsoleUrl(config.eval.url);
816
+ if ("__overrideEndpointUrl" in config.eval) {
817
+ consoleEndpointUrl = config.eval.__overrideEndpointUrl;
818
+ }
824
819
  return {
825
820
  url: config.eval.url,
821
+ consoleEndpointUrl,
826
822
  token: config.eval.token,
827
823
  dataset: config.eval.dataset
828
824
  };
@@ -1157,8 +1153,10 @@ function printTestCaseSuccessOrFailed(testMeta, ok) {
1157
1153
  function printTestCaseScores(testMeta, baseline) {
1158
1154
  const index = testMeta.case.index;
1159
1155
  Object.keys(testMeta.case.scores).forEach((k) => {
1160
- const v = testMeta.case.scores[k].score ? testMeta.case.scores[k].score : 0;
1161
- const scoreValue = Number(v * 100).toFixed(2) + "%";
1156
+ const scoreData = testMeta.case.scores[k];
1157
+ const hasError = scoreData.metadata?.error;
1158
+ const v = scoreData.score ? scoreData.score : 0;
1159
+ const scoreValue = hasError ? u.dim("N/A") : Number(v * 100).toFixed(2) + "%";
1162
1160
  if (baseline?.cases[index]?.scores[k]) {
1163
1161
  const baselineScoreValue = baseline.cases[index].scores[k].value;
1164
1162
  const diff = v - baselineScoreValue;
@@ -1169,11 +1167,16 @@ function printTestCaseScores(testMeta, baseline) {
1169
1167
  k,
1170
1168
  u.magentaBright(blScoreText),
1171
1169
  "->",
1172
- u.blueBright(scoreValue),
1173
- diff > 0 ? u.green("+" + diffText) : diff < 0 ? u.red(diffText) : diffText
1170
+ hasError ? scoreValue : u.blueBright(scoreValue),
1171
+ hasError ? u.dim("(scorer not run)") : diff > 0 ? u.green("+" + diffText) : diff < 0 ? u.red(diffText) : diffText
1174
1172
  );
1175
1173
  } else {
1176
- console.log(" ", k, u.blueBright(scoreValue));
1174
+ console.log(
1175
+ " ",
1176
+ k,
1177
+ hasError ? scoreValue : u.blueBright(scoreValue),
1178
+ hasError ? u.dim("(scorer not run)") : ""
1179
+ );
1177
1180
  }
1178
1181
  return [k, scoreValue];
1179
1182
  });
@@ -1260,7 +1263,7 @@ function printGlobalFlagOverrides(overrides2, defaults) {
1260
1263
  function printSuiteBox({
1261
1264
  suite,
1262
1265
  scorerAverages,
1263
- calculateBaselineScorerAverage,
1266
+ calculateBaselineScorerAverage: calculateBaselineScorerAverage2,
1264
1267
  flagDiff
1265
1268
  }) {
1266
1269
  const filename = suite.file.split("/").pop();
@@ -1269,29 +1272,33 @@ function printSuiteBox({
1269
1272
  console.log("\u251C\u2500");
1270
1273
  const scorerNames = Object.keys(scorerAverages);
1271
1274
  const maxNameLength = Math.max(...scorerNames.map((name) => name.length));
1275
+ const allCasesErrored = (scorerName) => {
1276
+ return suite.cases.every((caseData) => caseData.scores[scorerName]?.metadata?.error);
1277
+ };
1272
1278
  for (const scorerName of scorerNames) {
1273
1279
  const avg = scorerAverages[scorerName];
1274
1280
  const paddedName = scorerName.padEnd(maxNameLength);
1281
+ const hasAllErrors = allCasesErrored(scorerName);
1275
1282
  if (suite.baseline) {
1276
- const baselineAvg = calculateBaselineScorerAverage(suite.baseline, scorerName);
1283
+ const baselineAvg = calculateBaselineScorerAverage2(suite.baseline, scorerName);
1277
1284
  if (baselineAvg !== null) {
1278
- const currentPercent = (avg * 100).toFixed(2) + "%";
1285
+ const currentPercent = hasAllErrors ? u.dim("N/A") : (avg * 100).toFixed(2) + "%";
1279
1286
  const baselinePercent = (baselineAvg * 100).toFixed(2) + "%";
1280
1287
  const diff = avg - baselineAvg;
1281
1288
  const diffText = (diff >= 0 ? "+" : "") + (diff * 100).toFixed(2) + "%";
1282
1289
  const diffColor = diff > 0 ? u.green : diff < 0 ? u.red : u.dim;
1283
1290
  const paddedBaseline = baselinePercent.padStart(7);
1284
- const paddedCurrent = currentPercent.padStart(7);
1285
- const paddedDiff = diffText.padStart(8);
1291
+ const paddedCurrent = hasAllErrors ? currentPercent : currentPercent.padStart(7);
1292
+ const paddedDiff = hasAllErrors ? u.dim("(all cases failed)") : diffText.padStart(8);
1286
1293
  console.log(
1287
- `\u2502 ${paddedName} ${u.blueBright(paddedBaseline)} \u2192 ${u.magentaBright(paddedCurrent)} (${diffColor(paddedDiff)})`
1294
+ `\u2502 ${paddedName} ${u.blueBright(paddedBaseline)} \u2192 ${hasAllErrors ? paddedCurrent : u.magentaBright(paddedCurrent)} (${hasAllErrors ? paddedDiff : diffColor(paddedDiff)})`
1288
1295
  );
1289
1296
  } else {
1290
- const currentPercent = (avg * 100).toFixed(2) + "%";
1297
+ const currentPercent = hasAllErrors ? u.red("N/A (all cases failed)") : (avg * 100).toFixed(2) + "%";
1291
1298
  console.log(`\u2502 \u2022 ${paddedName} ${currentPercent}`);
1292
1299
  }
1293
1300
  } else {
1294
- const currentPercent = (avg * 100).toFixed(2) + "%";
1301
+ const currentPercent = hasAllErrors ? u.red("N/A (all cases failed)") : (avg * 100).toFixed(2) + "%";
1295
1302
  console.log(`\u2502 \u2022 ${paddedName} ${currentPercent}`);
1296
1303
  }
1297
1304
  }
@@ -1332,12 +1339,62 @@ function printSuiteBox({
1332
1339
  }
1333
1340
  console.log("\u2514\u2500");
1334
1341
  }
1335
- function printFinalReport({
1336
- suiteData,
1337
- calculateScorerAverages,
1338
- calculateBaselineScorerAverage,
1339
- calculateFlagDiff
1340
- }) {
1342
+ function calculateScorerAverages(suite) {
1343
+ const scorerTotals = {};
1344
+ for (const caseData of suite.cases) {
1345
+ for (const [scorerName, score] of Object.entries(caseData.scores)) {
1346
+ if (!scorerTotals[scorerName]) {
1347
+ scorerTotals[scorerName] = { sum: 0, count: 0 };
1348
+ }
1349
+ if (!score.metadata?.error) {
1350
+ scorerTotals[scorerName].sum += score.score || 0;
1351
+ scorerTotals[scorerName].count += 1;
1352
+ }
1353
+ }
1354
+ }
1355
+ const averages = {};
1356
+ for (const [scorerName, totals] of Object.entries(scorerTotals)) {
1357
+ averages[scorerName] = totals.count > 0 ? totals.sum / totals.count : 0;
1358
+ }
1359
+ return averages;
1360
+ }
1361
+ function calculateBaselineScorerAverage(baseline, scorerName) {
1362
+ const scores = [];
1363
+ for (const caseData of baseline.cases) {
1364
+ if (caseData.scores[scorerName]) {
1365
+ scores.push(caseData.scores[scorerName].value);
1366
+ }
1367
+ }
1368
+ if (scores.length === 0) return null;
1369
+ const sum = scores.reduce((acc, val) => acc + val, 0);
1370
+ return sum / scores.length;
1371
+ }
1372
+ function calculateFlagDiff(suite) {
1373
+ if (!suite.baseline || !suite.configFlags || suite.configFlags.length === 0) {
1374
+ return [];
1375
+ }
1376
+ const diffs = [];
1377
+ const currentConfig = suite.flagConfig || {};
1378
+ const baselineConfig = suite.baseline.flagConfig || {};
1379
+ const currentFlat = flattenObject(currentConfig);
1380
+ const baselineFlat = flattenObject(baselineConfig);
1381
+ const allKeys = /* @__PURE__ */ new Set([...Object.keys(currentFlat), ...Object.keys(baselineFlat)]);
1382
+ for (const key of allKeys) {
1383
+ const isInScope = suite.configFlags.some((pattern) => key.startsWith(pattern));
1384
+ if (!isInScope) continue;
1385
+ const currentValue = currentFlat[key];
1386
+ const baselineValue = baselineFlat[key];
1387
+ if (JSON.stringify(currentValue) !== JSON.stringify(baselineValue)) {
1388
+ diffs.push({
1389
+ flag: key,
1390
+ current: currentValue ? JSON.stringify(currentValue) : void 0,
1391
+ baseline: baselineValue ? JSON.stringify(baselineValue) : void 0
1392
+ });
1393
+ }
1394
+ }
1395
+ return diffs;
1396
+ }
1397
+ function printFinalReport({ suiteData }) {
1341
1398
  console.log("");
1342
1399
  console.log(u.bgBlue(u.white(" FINAL EVALUATION REPORT ")));
1343
1400
  console.log("");
@@ -1376,19 +1433,25 @@ var AxiomReporter = class {
1376
1433
  __publicField(this, "_endOfRunConfigEnd");
1377
1434
  __publicField(this, "_suiteData", []);
1378
1435
  __publicField(this, "_baselines", /* @__PURE__ */ new Map());
1436
+ __publicField(this, "_printedFlagOverrides", false);
1379
1437
  }
1380
1438
  onTestRunStart() {
1381
1439
  this.start = performance.now();
1382
1440
  this.startTime = (/* @__PURE__ */ new Date()).getTime();
1383
- const overrides2 = getGlobalFlagOverrides();
1384
- const defaults = getConfigScope()?.getAllDefaultFlags?.() ?? {};
1385
- printGlobalFlagOverrides(overrides2, defaults);
1386
1441
  }
1387
1442
  async onTestSuiteReady(_testSuite) {
1388
1443
  const meta = _testSuite.meta();
1389
1444
  if (_testSuite.state() === "skipped") {
1390
1445
  return;
1391
1446
  }
1447
+ if (!this._printedFlagOverrides) {
1448
+ const defaultsFromConfigEnd = meta.evaluation.configEnd?.flags ?? {};
1449
+ const overridesFromConfigEnd = meta.evaluation.configEnd?.overrides ?? {};
1450
+ if (Object.keys(overridesFromConfigEnd).length > 0) {
1451
+ printGlobalFlagOverrides(overridesFromConfigEnd, defaultsFromConfigEnd);
1452
+ }
1453
+ this._printedFlagOverrides = true;
1454
+ }
1392
1455
  const baseline = meta.evaluation.baseline;
1393
1456
  if (baseline) {
1394
1457
  const config = getAxiomConfig();
@@ -1464,10 +1527,7 @@ var AxiomReporter = class {
1464
1527
  process.stdout.write("\x1B[2J\x1B[0f");
1465
1528
  }
1466
1529
  printFinalReport({
1467
- suiteData: this._suiteData,
1468
- calculateScorerAverages: this.calculateScorerAverages.bind(this),
1469
- calculateBaselineScorerAverage: this.calculateBaselineScorerAverage.bind(this),
1470
- calculateFlagDiff: this.calculateFlagDiff.bind(this)
1530
+ suiteData: this._suiteData
1471
1531
  });
1472
1532
  const DEBUG = process.env.AXIOM_DEBUG === "true";
1473
1533
  if (DEBUG && this._endOfRunConfigEnd) {
@@ -1485,68 +1545,6 @@ var AxiomReporter = class {
1485
1545
  printRuntimeFlags(testMeta);
1486
1546
  printOutOfScopeFlags(testMeta);
1487
1547
  }
1488
- /**
1489
- * Calculate average scores per scorer for a suite
1490
- */
1491
- calculateScorerAverages(suite) {
1492
- const scorerTotals = {};
1493
- for (const caseData of suite.cases) {
1494
- for (const [scorerName, score] of Object.entries(caseData.scores)) {
1495
- if (!scorerTotals[scorerName]) {
1496
- scorerTotals[scorerName] = { sum: 0, count: 0 };
1497
- }
1498
- scorerTotals[scorerName].sum += score.score || 0;
1499
- scorerTotals[scorerName].count += 1;
1500
- }
1501
- }
1502
- const averages = {};
1503
- for (const [scorerName, totals] of Object.entries(scorerTotals)) {
1504
- averages[scorerName] = totals.count > 0 ? totals.sum / totals.count : 0;
1505
- }
1506
- return averages;
1507
- }
1508
- /**
1509
- * Calculate average score for a specific scorer from baseline data
1510
- */
1511
- calculateBaselineScorerAverage(baseline, scorerName) {
1512
- const scores = [];
1513
- for (const caseData of baseline.cases) {
1514
- if (caseData.scores[scorerName]) {
1515
- scores.push(caseData.scores[scorerName].value);
1516
- }
1517
- }
1518
- if (scores.length === 0) return null;
1519
- const sum = scores.reduce((acc, val) => acc + val, 0);
1520
- return sum / scores.length;
1521
- }
1522
- /**
1523
- * Calculate flag diff between current run and baseline (filtered by configFlags)
1524
- */
1525
- calculateFlagDiff(suite) {
1526
- if (!suite.baseline || !suite.configFlags || suite.configFlags.length === 0) {
1527
- return [];
1528
- }
1529
- const diffs = [];
1530
- const currentConfig = suite.flagConfig || {};
1531
- const baselineConfig = suite.baseline.flagConfig || {};
1532
- const currentFlat = flattenObject(currentConfig);
1533
- const baselineFlat = flattenObject(baselineConfig);
1534
- const allKeys = /* @__PURE__ */ new Set([...Object.keys(currentFlat), ...Object.keys(baselineFlat)]);
1535
- for (const key of allKeys) {
1536
- const isInScope = suite.configFlags.some((pattern) => key.startsWith(pattern));
1537
- if (!isInScope) continue;
1538
- const currentValue = currentFlat[key];
1539
- const baselineValue = baselineFlat[key];
1540
- if (JSON.stringify(currentValue) !== JSON.stringify(baselineValue)) {
1541
- diffs.push({
1542
- flag: key,
1543
- current: currentValue ? JSON.stringify(currentValue) : void 0,
1544
- baseline: baselineValue ? JSON.stringify(baselineValue) : void 0
1545
- });
1546
- }
1547
- }
1548
- return diffs;
1549
- }
1550
1548
  /**
1551
1549
  * End-of-suite config summary (console only)
1552
1550
  */
@@ -1561,11 +1559,111 @@ var import_sdk_trace_node = require("@opentelemetry/sdk-trace-node");
1561
1559
  var import_resources = require("@opentelemetry/resources");
1562
1560
  var import_exporter_trace_otlp_http = require("@opentelemetry/exporter-trace-otlp-http");
1563
1561
  var import_api10 = require("@opentelemetry/api");
1562
+
1563
+ // src/config/loader.ts
1564
+ var import_c12 = require("c12");
1565
+ var import_defu = require("defu");
1566
+
1567
+ // src/config/index.ts
1568
+ var DEFAULT_EVAL_INCLUDE = ["**/*.eval.{ts,js,mts,mjs,cts,cjs}"];
1569
+ function createPartialDefaults() {
1570
+ return {
1571
+ eval: {
1572
+ url: process.env.AXIOM_URL || "https://api.axiom.co",
1573
+ token: process.env.AXIOM_TOKEN,
1574
+ dataset: process.env.AXIOM_DATASET,
1575
+ instrumentation: null,
1576
+ include: [...DEFAULT_EVAL_INCLUDE],
1577
+ exclude: [],
1578
+ timeoutMs: 6e4
1579
+ }
1580
+ };
1581
+ }
1582
+ function validateConfig(config) {
1583
+ const errors = [];
1584
+ if (!config.eval?.token) {
1585
+ errors.push(
1586
+ "eval.token is required (set in axiom.config.ts or AXIOM_TOKEN environment variable)"
1587
+ );
1588
+ }
1589
+ if (!config.eval?.dataset) {
1590
+ errors.push(
1591
+ "eval.dataset is required (set in axiom.config.ts or AXIOM_DATASET environment variable)"
1592
+ );
1593
+ }
1594
+ if (!config.eval?.url) {
1595
+ console.log(
1596
+ "eval.url was not specified. Defaulting to `https://api.axiom.co`. Please set it in axiom.config.ts or AXIOM_URL environment variable if you want to use a different endpoint."
1597
+ );
1598
+ }
1599
+ const instrumentation = config.eval?.instrumentation;
1600
+ if (instrumentation !== null && instrumentation !== void 0 && typeof instrumentation !== "function") {
1601
+ errors.push(
1602
+ "eval.instrumentation must be a function returning OTEL setup information or null."
1603
+ );
1604
+ }
1605
+ if (errors.length > 0) {
1606
+ throw new AxiomCLIError(`Invalid Axiom configuration:
1607
+ - ${errors.join("\n - ")}`);
1608
+ }
1609
+ return config;
1610
+ }
1611
+
1612
+ // src/config/loader.ts
1613
+ function customMerger(target, source) {
1614
+ const merged = (0, import_defu.defu)(source, target);
1615
+ if (source?.eval && "include" in source.eval) {
1616
+ merged.eval.include = source.eval.include;
1617
+ }
1618
+ return merged;
1619
+ }
1620
+ async function loadConfig(cwd = process.cwd()) {
1621
+ try {
1622
+ const defaults = createPartialDefaults();
1623
+ const result = await (0, import_c12.loadConfig)({
1624
+ name: "axiom",
1625
+ cwd,
1626
+ // Support common config file extensions
1627
+ configFile: "axiom.config",
1628
+ // Don't use defaultConfig - we'll merge manually to control array behavior
1629
+ // Disable configs other than .ts/.js/.mts/.mjs/.cts/.cjs
1630
+ rcFile: false,
1631
+ globalRc: false,
1632
+ packageJson: false,
1633
+ giget: false
1634
+ });
1635
+ const mergedConfig = customMerger(defaults, result.config);
1636
+ const validatedConfig = validateConfig(mergedConfig);
1637
+ return {
1638
+ config: validatedConfig
1639
+ };
1640
+ } catch (error) {
1641
+ if (error instanceof AxiomCLIError) {
1642
+ throw error;
1643
+ }
1644
+ throw new AxiomCLIError(`Failed to load config file: ${errorToString(error)}`);
1645
+ }
1646
+ }
1647
+
1648
+ // src/evals/instrument.ts
1564
1649
  var axiomProvider;
1565
1650
  var axiomTracer;
1566
1651
  var userProvider;
1567
1652
  var initializationPromise = null;
1568
1653
  var initialized = false;
1654
+ async function resolveInstrumentationHook(config) {
1655
+ if (config.eval.instrumentation) {
1656
+ return config.eval.instrumentation;
1657
+ }
1658
+ try {
1659
+ const { config: loadedConfig } = await loadConfig(process.cwd());
1660
+ return loadedConfig.eval.instrumentation ?? null;
1661
+ } catch (error) {
1662
+ throw new AxiomCLIError(
1663
+ `Failed to reload instrumentation from config: ${errorToString(error)}`
1664
+ );
1665
+ }
1666
+ }
1569
1667
  async function runInstrumentationHook(hook, options) {
1570
1668
  try {
1571
1669
  return await hook(options);
@@ -1595,11 +1693,11 @@ function setupEvalProvider(connection) {
1595
1693
  axiomProvider = new import_sdk_trace_node.NodeTracerProvider({
1596
1694
  resource: (0, import_resources.resourceFromAttributes)({
1597
1695
  ["service.name"]: "axiom",
1598
- ["service.version"]: "0.22.1"
1696
+ ["service.version"]: "0.23.0"
1599
1697
  }),
1600
1698
  spanProcessors: [processor]
1601
1699
  });
1602
- axiomTracer = axiomProvider.getTracer("axiom", "0.22.1");
1700
+ axiomTracer = axiomProvider.getTracer("axiom", "0.23.0");
1603
1701
  }
1604
1702
  async function initInstrumentation(config) {
1605
1703
  if (initialized) {
@@ -1611,12 +1709,12 @@ async function initInstrumentation(config) {
1611
1709
  }
1612
1710
  initializationPromise = (async () => {
1613
1711
  if (!config.enabled) {
1614
- axiomTracer = import_api10.trace.getTracer("axiom", "0.22.1");
1712
+ axiomTracer = import_api10.trace.getTracer("axiom", "0.23.0");
1615
1713
  initialized = true;
1616
1714
  return;
1617
1715
  }
1618
1716
  const connection = resolveAxiomConnection(config.config);
1619
- const hook = config.config.eval.instrumentation;
1717
+ const hook = await resolveInstrumentationHook(config.config);
1620
1718
  let hookResult = void 0;
1621
1719
  if (hook) {
1622
1720
  config.config.eval.instrumentation = hook;
@@ -1769,91 +1867,6 @@ function isGlob(str) {
1769
1867
  return /[*?[\]{}!]/.test(str);
1770
1868
  }
1771
1869
 
1772
- // src/config/loader.ts
1773
- var import_c12 = require("c12");
1774
- var import_defu = require("defu");
1775
-
1776
- // src/config/index.ts
1777
- var DEFAULT_EVAL_INCLUDE = ["**/*.eval.{ts,js,mts,mjs,cts,cjs}"];
1778
- function createPartialDefaults() {
1779
- return {
1780
- eval: {
1781
- url: process.env.AXIOM_URL || "https://api.axiom.co",
1782
- token: process.env.AXIOM_TOKEN,
1783
- dataset: process.env.AXIOM_DATASET,
1784
- instrumentation: null,
1785
- include: [...DEFAULT_EVAL_INCLUDE],
1786
- exclude: [],
1787
- timeoutMs: 6e4
1788
- }
1789
- };
1790
- }
1791
- function validateConfig(config) {
1792
- const errors = [];
1793
- if (!config.eval?.token) {
1794
- errors.push(
1795
- "eval.token is required (set in axiom.config.ts or AXIOM_TOKEN environment variable)"
1796
- );
1797
- }
1798
- if (!config.eval?.dataset) {
1799
- errors.push(
1800
- "eval.dataset is required (set in axiom.config.ts or AXIOM_DATASET environment variable)"
1801
- );
1802
- }
1803
- if (!config.eval?.url) {
1804
- console.log(
1805
- "eval.url was not specified. Defaulting to `https://api.axiom.co`. Please set it in axiom.config.ts or AXIOM_URL environment variable if you want to use a different endpoint."
1806
- );
1807
- }
1808
- const instrumentation = config.eval?.instrumentation;
1809
- if (instrumentation !== null && instrumentation !== void 0 && typeof instrumentation !== "function") {
1810
- errors.push(
1811
- "eval.instrumentation must be a function returning OTEL setup information or null."
1812
- );
1813
- }
1814
- if (errors.length > 0) {
1815
- throw new AxiomCLIError(`Invalid Axiom configuration:
1816
- - ${errors.join("\n - ")}`);
1817
- }
1818
- return config;
1819
- }
1820
-
1821
- // src/config/loader.ts
1822
- function customMerger(target, source) {
1823
- const merged = (0, import_defu.defu)(source, target);
1824
- if (source?.eval && "include" in source.eval) {
1825
- merged.eval.include = source.eval.include;
1826
- }
1827
- return merged;
1828
- }
1829
- async function loadConfig(cwd = process.cwd()) {
1830
- try {
1831
- const defaults = createPartialDefaults();
1832
- const result = await (0, import_c12.loadConfig)({
1833
- name: "axiom",
1834
- cwd,
1835
- // Support common config file extensions
1836
- configFile: "axiom.config",
1837
- // Don't use defaultConfig - we'll merge manually to control array behavior
1838
- // Disable configs other than .ts/.js/.mts/.mjs/.cts/.cjs
1839
- rcFile: false,
1840
- globalRc: false,
1841
- packageJson: false,
1842
- giget: false
1843
- });
1844
- const mergedConfig = customMerger(defaults, result.config);
1845
- const validatedConfig = validateConfig(mergedConfig);
1846
- return {
1847
- config: validatedConfig
1848
- };
1849
- } catch (error) {
1850
- if (error instanceof AxiomCLIError) {
1851
- throw error;
1852
- }
1853
- throw new AxiomCLIError(`Failed to load config file: ${errorToString(error)}`);
1854
- }
1855
- }
1856
-
1857
1870
  // src/cli/commands/eval.command.ts
1858
1871
  var loadEvalCommand = (program2, flagOverrides = {}) => {
1859
1872
  return program2.addCommand(
@@ -2029,7 +2042,7 @@ var import_commander4 = require("commander");
2029
2042
  var loadVersionCommand = (program2) => {
2030
2043
  return program2.addCommand(
2031
2044
  new import_commander4.Command("version").description("cli version").action(() => {
2032
- console.log("0.22.1");
2045
+ console.log("0.23.0");
2033
2046
  })
2034
2047
  );
2035
2048
  };
@@ -2039,7 +2052,7 @@ var { loadEnvConfig } = import_env.default;
2039
2052
  loadEnvConfig(process.cwd());
2040
2053
  var { cleanedArgv, overrides } = extractOverrides(process.argv.slice(2));
2041
2054
  var program = new import_commander5.Command();
2042
- program.name("axiom").description("Axiom's CLI to manage your objects and run evals").version("0.22.1");
2055
+ program.name("axiom").description("Axiom's CLI to manage your objects and run evals").version("0.23.0");
2043
2056
  loadPushCommand(program);
2044
2057
  loadPullCommand(program);
2045
2058
  loadEvalCommand(program, overrides);