axiom 0.18.0 → 0.20.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/bin.cjs +370 -35
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +160 -20
- package/dist/bin.js.map +1 -1
- package/dist/chunk-I42N5ZVU.js +1435 -0
- package/dist/chunk-I42N5ZVU.js.map +1 -0
- package/dist/chunk-KDJRDUK4.js +2061 -0
- package/dist/chunk-KDJRDUK4.js.map +1 -0
- package/dist/evals.cjs +1146 -88
- package/dist/evals.cjs.map +1 -1
- package/dist/evals.d.cts +281 -40
- package/dist/evals.d.ts +281 -40
- package/dist/evals.js +169 -59
- package/dist/evals.js.map +1 -1
- package/dist/index.cjs +12 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +101 -4
- package/dist/index.d.ts +101 -4
- package/dist/index.js +15 -1500
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
- package/dist/chunk-4WSJ7VVA.js +0 -330
- package/dist/chunk-4WSJ7VVA.js.map +0 -1
- package/dist/chunk-5336ZOJZ.js +0 -464
- package/dist/chunk-5336ZOJZ.js.map +0 -1
- package/dist/chunk-LNTOR4X7.js +0 -233
- package/dist/chunk-LNTOR4X7.js.map +0 -1
- package/dist/types-DGiZzDAy.d.cts +0 -113
- package/dist/types-DGiZzDAy.d.ts +0 -113
package/dist/bin.cjs
CHANGED
|
@@ -255,10 +255,10 @@ async function askConfirmation(message) {
|
|
|
255
255
|
input: process.stdin,
|
|
256
256
|
output: process.stdout
|
|
257
257
|
});
|
|
258
|
-
return new Promise((
|
|
258
|
+
return new Promise((resolve3) => {
|
|
259
259
|
rl.question(`${message} (y/N): `, (answer) => {
|
|
260
260
|
rl.close();
|
|
261
|
-
|
|
261
|
+
resolve3(answer.toLowerCase() === "y" || answer.toLowerCase() === "yes");
|
|
262
262
|
});
|
|
263
263
|
});
|
|
264
264
|
}
|
|
@@ -349,8 +349,8 @@ var loadPullCommand = (program2) => {
|
|
|
349
349
|
).option("--version <version>", "The version to pull, default: latest", "latest").option("--output <path>", "Output file path (optional, defaults to <slug>.prompt.ts)").action(async (slug, options) => {
|
|
350
350
|
try {
|
|
351
351
|
console.log(`Pulling prompt: ${slug} (version: ${options.version})`);
|
|
352
|
-
const
|
|
353
|
-
const response = await fetch(
|
|
352
|
+
const url = `${process.env.AXIOM_URL}/v1/prompts/${slug}`;
|
|
353
|
+
const response = await fetch(url, {
|
|
354
354
|
method: "GET",
|
|
355
355
|
headers: {
|
|
356
356
|
Authorization: `Bearer ${process.env.AXIOM_TOKEN}`,
|
|
@@ -479,11 +479,16 @@ var r = process.env.FORCE_TTY !== void 0 || (0, import_tty.isatty)(1);
|
|
|
479
479
|
var u = p(r);
|
|
480
480
|
|
|
481
481
|
// src/evals/eval.service.ts
|
|
482
|
-
var
|
|
483
|
-
|
|
484
|
-
|
|
482
|
+
var getEnvVars = () => {
|
|
483
|
+
return {
|
|
484
|
+
datasetName: process.env.AXIOM_DATASET ?? "",
|
|
485
|
+
url: process.env.AXIOM_URL ?? "https://api.axiom.co",
|
|
486
|
+
token: process.env.AXIOM_TOKEN
|
|
487
|
+
};
|
|
488
|
+
};
|
|
485
489
|
var findEvaluationCases = async (evalId) => {
|
|
486
490
|
try {
|
|
491
|
+
const { datasetName, url, token } = getEnvVars();
|
|
487
492
|
const apl = `['${datasetName}'] | where trace_id == "${evalId}" | order by _time`;
|
|
488
493
|
const headers = new Headers({
|
|
489
494
|
Authorization: `Bearer ${token}`,
|
|
@@ -646,6 +651,9 @@ var AxiomReporter = class {
|
|
|
646
651
|
}
|
|
647
652
|
async onTestSuiteReady(_testSuite) {
|
|
648
653
|
const meta = _testSuite.meta();
|
|
654
|
+
if (_testSuite.state() === "skipped") {
|
|
655
|
+
return;
|
|
656
|
+
}
|
|
649
657
|
const baseline = meta.evaluation.baseline;
|
|
650
658
|
if (baseline) {
|
|
651
659
|
this.baseline = await findEvaluationCases(baseline.id);
|
|
@@ -673,16 +681,20 @@ var AxiomReporter = class {
|
|
|
673
681
|
}
|
|
674
682
|
onTestCaseReady(test) {
|
|
675
683
|
const meta = test.meta();
|
|
684
|
+
if (!meta.case) return;
|
|
676
685
|
console.log(u.blue(` \u2713 evaluating case ${meta.case.index}`));
|
|
677
686
|
}
|
|
678
687
|
onTestSuiteResult(testSuite) {
|
|
688
|
+
if (testSuite.state() === "skipped") {
|
|
689
|
+
return;
|
|
690
|
+
}
|
|
679
691
|
const duration = Number((performance.now() - this.start) / 1e3).toFixed(2);
|
|
680
692
|
console.log(" ");
|
|
681
693
|
console.log(" ", u.dim("Cases"), testSuite.children.size);
|
|
682
694
|
console.log(" ", u.dim("Start at"), new Date(this.startTime).toTimeString());
|
|
683
695
|
console.log(" ", u.dim("Duration"), `${duration}s`);
|
|
684
696
|
const meta = testSuite.meta();
|
|
685
|
-
const
|
|
697
|
+
const url = `https://app.axiom.co/evaluations/${meta.evaluation.name}/${meta.evaluation.id}`;
|
|
686
698
|
for (const test of testSuite.children) {
|
|
687
699
|
if (test.type !== "test") return;
|
|
688
700
|
this.printCaseResult(test);
|
|
@@ -690,7 +702,7 @@ var AxiomReporter = class {
|
|
|
690
702
|
console.log("");
|
|
691
703
|
console.log(
|
|
692
704
|
" ",
|
|
693
|
-
`see results for ${meta.evaluation.name}-${meta.evaluation.version} at ${
|
|
705
|
+
`see results for ${meta.evaluation.name}-${meta.evaluation.version} at ${url}`
|
|
694
706
|
);
|
|
695
707
|
console.log(
|
|
696
708
|
" ",
|
|
@@ -736,6 +748,20 @@ var AxiomReporter = class {
|
|
|
736
748
|
}
|
|
737
749
|
return [k, scoreValue];
|
|
738
750
|
});
|
|
751
|
+
if (testMeta.case.outOfScopeFlags && testMeta.case.outOfScopeFlags.length > 0) {
|
|
752
|
+
const pickedFlagsText = testMeta.case.pickedFlags ? `(picked: ${testMeta.case.pickedFlags.map((f2) => `'${f2}'`).join(", ")})` : "(none)";
|
|
753
|
+
console.log(" ", u.yellow(`\u26A0 Out-of-scope flags: ${pickedFlagsText}`));
|
|
754
|
+
testMeta.case.outOfScopeFlags.forEach((flag) => {
|
|
755
|
+
const timeStr = new Date(flag.accessedAt).toLocaleTimeString();
|
|
756
|
+
console.log(" ", `${flag.flagPath} (at ${timeStr})`);
|
|
757
|
+
if (flag.stackTrace && flag.stackTrace.length > 0) {
|
|
758
|
+
flag.stackTrace.forEach((frame, i) => {
|
|
759
|
+
const prefix = i === flag.stackTrace.length - 1 ? " \u2514\u2500" : " \u251C\u2500";
|
|
760
|
+
console.log(" ", u.dim(`${prefix} ${frame}`));
|
|
761
|
+
});
|
|
762
|
+
}
|
|
763
|
+
});
|
|
764
|
+
}
|
|
739
765
|
}
|
|
740
766
|
};
|
|
741
767
|
|
|
@@ -751,7 +777,7 @@ var import_api2 = require("@opentelemetry/api");
|
|
|
751
777
|
// package.json
|
|
752
778
|
var package_default = {
|
|
753
779
|
name: "axiom",
|
|
754
|
-
version: "0.
|
|
780
|
+
version: "0.20.0",
|
|
755
781
|
type: "module",
|
|
756
782
|
author: "Axiom, Inc.",
|
|
757
783
|
contributors: [
|
|
@@ -823,14 +849,12 @@ var package_default = {
|
|
|
823
849
|
"@sinclair/typebox": "^0.34.37",
|
|
824
850
|
commander: "^14.0.0",
|
|
825
851
|
"console-table-printer": "^2.14.6",
|
|
826
|
-
esbuild: "^0.25.8",
|
|
827
852
|
handlebars: "^4.7.8",
|
|
828
|
-
nanoid: "^5.1.5"
|
|
829
|
-
vitest: "catalog:",
|
|
830
|
-
zod: "catalog:"
|
|
853
|
+
nanoid: "^5.1.5"
|
|
831
854
|
},
|
|
832
855
|
peerDependencies: {
|
|
833
|
-
"@opentelemetry/api": "^1.9.0"
|
|
856
|
+
"@opentelemetry/api": "^1.9.0",
|
|
857
|
+
zod: "^3.25.0 || ^4.0.0"
|
|
834
858
|
},
|
|
835
859
|
devDependencies: {
|
|
836
860
|
"@ai-sdk/anthropicv1": "npm:@ai-sdk/anthropic@^1.2.12",
|
|
@@ -848,17 +872,19 @@ var package_default = {
|
|
|
848
872
|
"@vitest/coverage-v8": "^3.2.4",
|
|
849
873
|
aiv4: "npm:ai@^4.3.19",
|
|
850
874
|
aiv5: "npm:ai@^5.0.0",
|
|
875
|
+
esbuild: "^0.25.8",
|
|
851
876
|
eslint: "catalog:",
|
|
852
877
|
prettier: "catalog:",
|
|
853
878
|
tinyrainbow: "^2.0.0",
|
|
854
879
|
tsup: "catalog:",
|
|
855
880
|
typescript: "catalog:",
|
|
856
|
-
vitest: "catalog:"
|
|
881
|
+
vitest: "catalog:",
|
|
882
|
+
zod: "catalog:"
|
|
857
883
|
},
|
|
858
884
|
files: [
|
|
859
885
|
"dist"
|
|
860
886
|
],
|
|
861
|
-
packageManager: "pnpm@10.
|
|
887
|
+
packageManager: "pnpm@10.16.1"
|
|
862
888
|
};
|
|
863
889
|
|
|
864
890
|
// src/otel/utils/redaction.ts
|
|
@@ -913,12 +939,12 @@ var processor = new import_sdk_trace_node.BatchSpanProcessor(exporter, {
|
|
|
913
939
|
var provider = new import_sdk_trace_node.NodeTracerProvider({
|
|
914
940
|
resource: (0, import_resources.resourceFromAttributes)({
|
|
915
941
|
["service.name"]: "axiom",
|
|
916
|
-
["service.version"]: "0.
|
|
942
|
+
["service.version"]: "0.20.0"
|
|
917
943
|
}),
|
|
918
944
|
spanProcessors: [processor]
|
|
919
945
|
});
|
|
920
946
|
provider.register();
|
|
921
|
-
var tracer = import_api3.trace.getTracer("axiom", "0.
|
|
947
|
+
var tracer = import_api3.trace.getTracer("axiom", "0.20.0");
|
|
922
948
|
var flush = async () => {
|
|
923
949
|
await provider.forceFlush();
|
|
924
950
|
};
|
|
@@ -931,7 +957,8 @@ var runVitest = async (dir, opts) => {
|
|
|
931
957
|
root: dir ? dir : process.cwd(),
|
|
932
958
|
mode: "test",
|
|
933
959
|
include: opts.include,
|
|
934
|
-
|
|
960
|
+
testNamePattern: opts.testNamePattern,
|
|
961
|
+
reporters: ["verbose", new AxiomReporter()],
|
|
935
962
|
environment: "node",
|
|
936
963
|
browser: void 0,
|
|
937
964
|
watch: opts.watch,
|
|
@@ -958,30 +985,337 @@ var runVitest = async (dir, opts) => {
|
|
|
958
985
|
|
|
959
986
|
// src/cli/commands/eval.command.ts
|
|
960
987
|
var import_node_fs = require("fs");
|
|
961
|
-
|
|
988
|
+
|
|
989
|
+
// src/evals/context/storage.ts
|
|
990
|
+
var import_api10 = require("@opentelemetry/api");
|
|
991
|
+
|
|
992
|
+
// src/evals/context/manager.ts
|
|
993
|
+
var import_node_module = require("module");
|
|
994
|
+
var import_meta = {};
|
|
995
|
+
var CONTEXT_MANAGER_SYMBOL = Symbol.for("axiom.context_manager");
|
|
996
|
+
function getGlobalContextManager() {
|
|
997
|
+
return globalThis[CONTEXT_MANAGER_SYMBOL];
|
|
998
|
+
}
|
|
999
|
+
function setGlobalContextManager(manager) {
|
|
1000
|
+
globalThis[CONTEXT_MANAGER_SYMBOL] = manager;
|
|
1001
|
+
}
|
|
1002
|
+
var isNodeJS = typeof process !== "undefined" && !!process.versions?.node;
|
|
1003
|
+
function getContextManager() {
|
|
1004
|
+
const existing = getGlobalContextManager();
|
|
1005
|
+
if (existing) return existing;
|
|
1006
|
+
let manager;
|
|
1007
|
+
if (isNodeJS) {
|
|
1008
|
+
try {
|
|
1009
|
+
let AsyncLocalStorage;
|
|
1010
|
+
const req = (0, import_node_module.createRequire)(import_meta.url);
|
|
1011
|
+
try {
|
|
1012
|
+
AsyncLocalStorage = req("node:async_hooks").AsyncLocalStorage;
|
|
1013
|
+
} catch {
|
|
1014
|
+
AsyncLocalStorage = req("async_hooks").AsyncLocalStorage;
|
|
1015
|
+
}
|
|
1016
|
+
manager = new AsyncLocalStorage();
|
|
1017
|
+
} catch (error) {
|
|
1018
|
+
console.warn("AsyncLocalStorage not available, using fallback context manager:", error);
|
|
1019
|
+
manager = createFallbackManager();
|
|
1020
|
+
}
|
|
1021
|
+
} else {
|
|
1022
|
+
console.warn("AsyncLocalStorage not available, using fallback context manager");
|
|
1023
|
+
manager = createFallbackManager();
|
|
1024
|
+
}
|
|
1025
|
+
setGlobalContextManager(manager);
|
|
1026
|
+
return manager;
|
|
1027
|
+
}
|
|
1028
|
+
function createFallbackManager() {
|
|
1029
|
+
let currentContext = null;
|
|
1030
|
+
return {
|
|
1031
|
+
getStore: () => currentContext,
|
|
1032
|
+
run: (value, fn) => {
|
|
1033
|
+
const prev = currentContext;
|
|
1034
|
+
currentContext = value;
|
|
1035
|
+
try {
|
|
1036
|
+
return fn();
|
|
1037
|
+
} finally {
|
|
1038
|
+
currentContext = prev;
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
};
|
|
1042
|
+
}
|
|
1043
|
+
function createAsyncHook(_name) {
|
|
1044
|
+
return {
|
|
1045
|
+
get() {
|
|
1046
|
+
const manager = getContextManager();
|
|
1047
|
+
if (manager.getStore) {
|
|
1048
|
+
return manager.getStore();
|
|
1049
|
+
}
|
|
1050
|
+
return void 0;
|
|
1051
|
+
},
|
|
1052
|
+
run(value, fn) {
|
|
1053
|
+
const manager = getContextManager();
|
|
1054
|
+
return manager.run(value, fn);
|
|
1055
|
+
}
|
|
1056
|
+
};
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
// src/evals/context/global-flags.ts
|
|
1060
|
+
var GLOBAL_OVERRIDES_SYMBOL = Symbol.for("axiom.global_flag_overrides");
|
|
1061
|
+
function setRoot(val) {
|
|
1062
|
+
globalThis[GLOBAL_OVERRIDES_SYMBOL] = val;
|
|
1063
|
+
}
|
|
1064
|
+
function setGlobalFlagOverrides(overrides2) {
|
|
1065
|
+
setRoot(overrides2);
|
|
1066
|
+
}
|
|
1067
|
+
|
|
1068
|
+
// src/validate-flags.ts
|
|
1069
|
+
var import_zod3 = require("zod");
|
|
1070
|
+
|
|
1071
|
+
// src/cli/utils/format-zod-errors.ts
|
|
1072
|
+
var import_zod = require("zod");
|
|
1073
|
+
|
|
1074
|
+
// src/util/dot-path.ts
|
|
1075
|
+
var import_zod2 = require("zod");
|
|
1076
|
+
|
|
1077
|
+
// src/app-scope.ts
|
|
1078
|
+
var import_api9 = require("@opentelemetry/api");
|
|
1079
|
+
var import_zod4 = require("zod");
|
|
1080
|
+
|
|
1081
|
+
// src/otel/utils/to-otel-attribute.ts
|
|
1082
|
+
var import_api4 = require("@opentelemetry/api");
|
|
1083
|
+
|
|
1084
|
+
// src/otel/withSpan.ts
|
|
1085
|
+
var import_api7 = require("@opentelemetry/api");
|
|
1086
|
+
|
|
1087
|
+
// src/otel/utils/wrapperUtils.ts
|
|
1088
|
+
var import_api6 = require("@opentelemetry/api");
|
|
1089
|
+
|
|
1090
|
+
// src/otel/semconv/attributes.ts
|
|
1091
|
+
var import_semantic_conventions = require("@opentelemetry/semantic-conventions");
|
|
1092
|
+
var import_incubating = require("@opentelemetry/semantic-conventions/incubating");
|
|
1093
|
+
|
|
1094
|
+
// src/otel/startActiveSpan.ts
|
|
1095
|
+
var import_api5 = require("@opentelemetry/api");
|
|
1096
|
+
|
|
1097
|
+
// src/otel/middleware.ts
|
|
1098
|
+
var import_api8 = require("@opentelemetry/api");
|
|
1099
|
+
|
|
1100
|
+
// src/evals/context/storage.ts
|
|
1101
|
+
var EVAL_CONTEXT = createAsyncHook("eval-context");
|
|
1102
|
+
function getEvalContext() {
|
|
1103
|
+
const ctx = EVAL_CONTEXT.get();
|
|
1104
|
+
if (!ctx) {
|
|
1105
|
+
return {
|
|
1106
|
+
flags: {},
|
|
1107
|
+
facts: {},
|
|
1108
|
+
pickedFlags: void 0,
|
|
1109
|
+
outOfScopeFlags: void 0
|
|
1110
|
+
};
|
|
1111
|
+
}
|
|
1112
|
+
return {
|
|
1113
|
+
flags: ctx.flags,
|
|
1114
|
+
facts: ctx.facts,
|
|
1115
|
+
pickedFlags: ctx.pickedFlags,
|
|
1116
|
+
outOfScopeFlags: ctx.outOfScopeFlags,
|
|
1117
|
+
parent: ctx.parent,
|
|
1118
|
+
overrides: ctx.overrides
|
|
1119
|
+
};
|
|
1120
|
+
}
|
|
1121
|
+
function putOnSpan(kind, key, value) {
|
|
1122
|
+
const span = import_api10.trace.getActiveSpan();
|
|
1123
|
+
if (span?.isRecording()) {
|
|
1124
|
+
span.setAttributes({ [`${kind}.${key}`]: value });
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1127
|
+
function withEvalContext(options = {}, fn) {
|
|
1128
|
+
const { initialFlags = {}, pickedFlags = [] } = options;
|
|
1129
|
+
return EVAL_CONTEXT.run(
|
|
1130
|
+
{ flags: { ...initialFlags }, facts: {}, pickedFlags, outOfScopeFlags: [] },
|
|
1131
|
+
fn
|
|
1132
|
+
);
|
|
1133
|
+
}
|
|
1134
|
+
|
|
1135
|
+
// src/context.ts
|
|
1136
|
+
function overrideFlags(partial) {
|
|
1137
|
+
const current = getEvalContext();
|
|
1138
|
+
if (!current) {
|
|
1139
|
+
if (process.env.NODE_ENV !== "test") {
|
|
1140
|
+
console.warn("overrideFlags called outside of evaluation context");
|
|
1141
|
+
}
|
|
1142
|
+
return;
|
|
1143
|
+
}
|
|
1144
|
+
const overlayContext = {
|
|
1145
|
+
...current,
|
|
1146
|
+
flags: { ...current.flags, ...partial },
|
|
1147
|
+
// Merge for backwards compatibility
|
|
1148
|
+
parent: current,
|
|
1149
|
+
overrides: { ...partial }
|
|
1150
|
+
};
|
|
1151
|
+
const currentCtx = EVAL_CONTEXT.get();
|
|
1152
|
+
if (currentCtx) {
|
|
1153
|
+
Object.assign(currentCtx, overlayContext);
|
|
1154
|
+
}
|
|
1155
|
+
for (const [key, value] of Object.entries(partial)) {
|
|
1156
|
+
putOnSpan("flag", key, value);
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1160
|
+
// src/cli/utils/eval-context-runner.ts
|
|
1161
|
+
async function runEvalWithContext(overrides2, runFn) {
|
|
1162
|
+
setGlobalFlagOverrides(overrides2);
|
|
1163
|
+
return withEvalContext({ initialFlags: overrides2 }, async () => {
|
|
1164
|
+
if (Object.keys(overrides2).length > 0) {
|
|
1165
|
+
overrideFlags(overrides2);
|
|
1166
|
+
}
|
|
1167
|
+
return runFn();
|
|
1168
|
+
});
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1171
|
+
// src/cli/utils/glob-utils.ts
|
|
1172
|
+
function isGlob(str) {
|
|
1173
|
+
return /[*?[\]{}!]/.test(str);
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1176
|
+
// src/cli/commands/eval.command.ts
|
|
1177
|
+
var loadEvalCommand = (program2, flagOverrides = {}) => {
|
|
962
1178
|
return program2.addCommand(
|
|
963
1179
|
new import_commander3.Command("eval").description("run evals locally").addArgument(
|
|
964
|
-
new import_commander3.Argument("[
|
|
1180
|
+
new import_commander3.Argument("[target]", "file, directory, glob pattern, or eval name").default(
|
|
965
1181
|
".",
|
|
966
1182
|
"any *.eval.ts file in current directory"
|
|
967
1183
|
)
|
|
968
|
-
).option("-w, --watch true", "keep server running and watch for changes", false).option("-t, --token <TOKEN>", "axiom token", process.env.AXIOM_TOKEN).option("-d, --dataset <DATASET>", "axiom dataset name", process.env.AXIOM_DATASET).option("-u, --url <AXIOM URL>", "axiom url", process.env.AXIOM_URL ?? "https://api.axiom.co").option("-b, --baseline <BASELINE ID>", "id of baseline evaluation to compare against").action(async (
|
|
1184
|
+
).option("-w, --watch true", "keep server running and watch for changes", false).option("-t, --token <TOKEN>", "axiom token", process.env.AXIOM_TOKEN).option("-d, --dataset <DATASET>", "axiom dataset name", process.env.AXIOM_DATASET).option("-u, --url <AXIOM URL>", "axiom url", process.env.AXIOM_URL ?? "https://api.axiom.co").option("-b, --baseline <BASELINE ID>", "id of baseline evaluation to compare against").action(async (target, options) => {
|
|
969
1185
|
if (!options.token || !options.dataset) {
|
|
970
1186
|
throw new Error("AXIOM_TOKEN, and AXIOM_DATASET must be set");
|
|
971
1187
|
}
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
const
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
1188
|
+
let targetPath = ".";
|
|
1189
|
+
let include = ["**/*.eval.ts"];
|
|
1190
|
+
let testNamePattern;
|
|
1191
|
+
const isGlobPattern = isGlob(target);
|
|
1192
|
+
if (isGlobPattern) {
|
|
1193
|
+
include = [target];
|
|
1194
|
+
} else {
|
|
1195
|
+
try {
|
|
1196
|
+
const stat = (0, import_node_fs.lstatSync)(target);
|
|
1197
|
+
if (stat.isDirectory()) {
|
|
1198
|
+
targetPath = target;
|
|
1199
|
+
include = ["**/*.eval.ts"];
|
|
1200
|
+
} else {
|
|
1201
|
+
include = [target];
|
|
1202
|
+
}
|
|
1203
|
+
} catch {
|
|
1204
|
+
testNamePattern = new RegExp(target, "i");
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
await runEvalWithContext(flagOverrides, async () => {
|
|
1208
|
+
return runVitest(targetPath, {
|
|
1209
|
+
watch: options.watch,
|
|
1210
|
+
baseline: options.baseline,
|
|
1211
|
+
include,
|
|
1212
|
+
testNamePattern
|
|
1213
|
+
});
|
|
980
1214
|
});
|
|
981
1215
|
})
|
|
982
1216
|
);
|
|
983
1217
|
};
|
|
984
1218
|
|
|
1219
|
+
// src/cli/utils/parse-flag-overrides.ts
|
|
1220
|
+
var import_zod5 = require("zod");
|
|
1221
|
+
var import_node_fs2 = require("fs");
|
|
1222
|
+
var import_node_path3 = require("path");
|
|
1223
|
+
var FLAG_RE = /^--flag\.([^=]+)(?:=(.*))?$/;
|
|
1224
|
+
var CONFIG_RE = /^--flags-config(?:=(.*))?$/;
|
|
1225
|
+
function ensureNoSpaceSeparatedSyntax(flagName, value, nextToken, flagType) {
|
|
1226
|
+
if (value === void 0 && nextToken !== void 0) {
|
|
1227
|
+
if (flagType === "flag" && !nextToken.startsWith("-") && nextToken !== "true" && nextToken !== "false") {
|
|
1228
|
+
console.error(`\u274C Invalid syntax: --flag.${flagName} ${nextToken}`);
|
|
1229
|
+
console.error(`\u{1F4A1} Use: --flag.${flagName}=${nextToken}`);
|
|
1230
|
+
process.exit(1);
|
|
1231
|
+
} else if (flagType === "config" && !nextToken.startsWith("-")) {
|
|
1232
|
+
console.error(`\u274C Invalid syntax: --flags-config ${nextToken}`);
|
|
1233
|
+
console.error(`\u{1F4A1} Use: --flags-config=${nextToken}`);
|
|
1234
|
+
process.exit(1);
|
|
1235
|
+
}
|
|
1236
|
+
}
|
|
1237
|
+
}
|
|
1238
|
+
function coerceValue(raw) {
|
|
1239
|
+
if (raw === "true") return true;
|
|
1240
|
+
if (raw === "false") return false;
|
|
1241
|
+
const num = Number(raw);
|
|
1242
|
+
if (!Number.isNaN(num) && raw.trim() === num.toString()) {
|
|
1243
|
+
return num;
|
|
1244
|
+
}
|
|
1245
|
+
try {
|
|
1246
|
+
return JSON.parse(raw);
|
|
1247
|
+
} catch {
|
|
1248
|
+
return raw;
|
|
1249
|
+
}
|
|
1250
|
+
}
|
|
1251
|
+
function loadConfigFile(path3) {
|
|
1252
|
+
const abs = (0, import_node_path3.resolve)(process.cwd(), path3);
|
|
1253
|
+
try {
|
|
1254
|
+
const contents = (0, import_node_fs2.readFileSync)(abs, "utf8");
|
|
1255
|
+
const parsed = JSON.parse(contents);
|
|
1256
|
+
if (typeof parsed !== "object" || Array.isArray(parsed) || parsed === null) {
|
|
1257
|
+
console.error(
|
|
1258
|
+
`\u274C Flags config must be a JSON object, got ${Array.isArray(parsed) ? "array" : typeof parsed}`
|
|
1259
|
+
);
|
|
1260
|
+
process.exit(1);
|
|
1261
|
+
}
|
|
1262
|
+
return parsed;
|
|
1263
|
+
} catch (err) {
|
|
1264
|
+
console.error(`\u274C Could not read or parse flags config "${path3}": ${err.message}`);
|
|
1265
|
+
process.exit(1);
|
|
1266
|
+
}
|
|
1267
|
+
}
|
|
1268
|
+
function extractOverrides(argv) {
|
|
1269
|
+
const cleanedArgv2 = [];
|
|
1270
|
+
const overrides2 = {};
|
|
1271
|
+
let configPath = null;
|
|
1272
|
+
let hasCliFlags = false;
|
|
1273
|
+
let configPathCount = 0;
|
|
1274
|
+
for (let i = 0; i < argv.length; i++) {
|
|
1275
|
+
const token = argv[i];
|
|
1276
|
+
const configMatch = token.match(CONFIG_RE);
|
|
1277
|
+
const flagMatch = token.match(FLAG_RE);
|
|
1278
|
+
if (configMatch) {
|
|
1279
|
+
configPathCount++;
|
|
1280
|
+
if (configPathCount > 1) {
|
|
1281
|
+
console.error("\u274C Only one --flags-config can be supplied.");
|
|
1282
|
+
process.exit(1);
|
|
1283
|
+
}
|
|
1284
|
+
const value = configMatch[1];
|
|
1285
|
+
const nextToken = argv.length > i + 1 ? argv[i + 1] : void 0;
|
|
1286
|
+
ensureNoSpaceSeparatedSyntax("flags-config", value, nextToken, "config");
|
|
1287
|
+
if (!value) {
|
|
1288
|
+
console.error("\u274C --flags-config requires a file path");
|
|
1289
|
+
console.error("\u{1F4A1} Use: --flags-config=path/to/config.json");
|
|
1290
|
+
process.exit(1);
|
|
1291
|
+
}
|
|
1292
|
+
configPath = value;
|
|
1293
|
+
} else if (flagMatch) {
|
|
1294
|
+
hasCliFlags = true;
|
|
1295
|
+
const key = flagMatch[1];
|
|
1296
|
+
const value = flagMatch[2];
|
|
1297
|
+
const nextToken = argv.length > i + 1 ? argv[i + 1] : void 0;
|
|
1298
|
+
ensureNoSpaceSeparatedSyntax(key, value, nextToken, "flag");
|
|
1299
|
+
const finalValue = value === void 0 ? "true" : value;
|
|
1300
|
+
overrides2[key] = coerceValue(finalValue);
|
|
1301
|
+
} else {
|
|
1302
|
+
cleanedArgv2.push(token);
|
|
1303
|
+
}
|
|
1304
|
+
}
|
|
1305
|
+
if (configPath && hasCliFlags) {
|
|
1306
|
+
console.error("\u274C Cannot use both --flags-config and --flag.* arguments together.");
|
|
1307
|
+
console.error("Choose one approach:");
|
|
1308
|
+
console.error(" \u2022 Config file: --flags-config=my-flags.json");
|
|
1309
|
+
console.error(" \u2022 CLI flags: --flag.temperature=0.9 --flag.model=gpt-4o");
|
|
1310
|
+
process.exit(1);
|
|
1311
|
+
}
|
|
1312
|
+
if (configPath) {
|
|
1313
|
+
const configOverrides = loadConfigFile(configPath);
|
|
1314
|
+
return { cleanedArgv: cleanedArgv2, overrides: configOverrides };
|
|
1315
|
+
}
|
|
1316
|
+
return { cleanedArgv: cleanedArgv2, overrides: overrides2 };
|
|
1317
|
+
}
|
|
1318
|
+
|
|
985
1319
|
// src/bin.ts
|
|
986
1320
|
var import_env = __toESM(require("@next/env"), 1);
|
|
987
1321
|
|
|
@@ -990,7 +1324,7 @@ var import_commander4 = require("commander");
|
|
|
990
1324
|
var loadVersionCommand = (program2) => {
|
|
991
1325
|
return program2.addCommand(
|
|
992
1326
|
new import_commander4.Command("version").description("cli version").action(() => {
|
|
993
|
-
console.log("0.
|
|
1327
|
+
console.log("0.20.0");
|
|
994
1328
|
})
|
|
995
1329
|
);
|
|
996
1330
|
};
|
|
@@ -998,13 +1332,14 @@ var loadVersionCommand = (program2) => {
|
|
|
998
1332
|
// src/bin.ts
|
|
999
1333
|
var { loadEnvConfig } = import_env.default;
|
|
1000
1334
|
loadEnvConfig(process.cwd());
|
|
1335
|
+
var { cleanedArgv, overrides } = extractOverrides(process.argv.slice(2));
|
|
1001
1336
|
var program = new import_commander5.Command();
|
|
1002
|
-
program.name("axiom").description("Axiom's CLI to manage your objects and run evals").version("0.
|
|
1337
|
+
program.name("axiom").description("Axiom's CLI to manage your objects and run evals").version("0.20.0");
|
|
1003
1338
|
loadPushCommand(program);
|
|
1004
1339
|
loadPullCommand(program);
|
|
1005
|
-
loadEvalCommand(program);
|
|
1340
|
+
loadEvalCommand(program, overrides);
|
|
1006
1341
|
loadVersionCommand(program);
|
|
1007
|
-
program.parse();
|
|
1342
|
+
program.parse(["node", "axiom", ...cleanedArgv]);
|
|
1008
1343
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1009
1344
|
0 && (module.exports = {
|
|
1010
1345
|
program
|