@assemblyline-agents/cli 0.1.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.
Files changed (147) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +19 -0
  3. package/dist/add.d.ts +23 -0
  4. package/dist/add.d.ts.map +1 -0
  5. package/dist/add.js +352 -0
  6. package/dist/add.js.map +1 -0
  7. package/dist/args.d.ts +14 -0
  8. package/dist/args.d.ts.map +1 -0
  9. package/dist/args.js +95 -0
  10. package/dist/args.js.map +1 -0
  11. package/dist/auth.d.ts +8 -0
  12. package/dist/auth.d.ts.map +1 -0
  13. package/dist/auth.js +74 -0
  14. package/dist/auth.js.map +1 -0
  15. package/dist/channels.d.ts +25 -0
  16. package/dist/channels.d.ts.map +1 -0
  17. package/dist/channels.js +76 -0
  18. package/dist/channels.js.map +1 -0
  19. package/dist/checkpoints.d.ts +3 -0
  20. package/dist/checkpoints.d.ts.map +1 -0
  21. package/dist/checkpoints.js +60 -0
  22. package/dist/checkpoints.js.map +1 -0
  23. package/dist/deploy-definition.d.ts +14 -0
  24. package/dist/deploy-definition.d.ts.map +1 -0
  25. package/dist/deploy-definition.js +92 -0
  26. package/dist/deploy-definition.js.map +1 -0
  27. package/dist/deploy-lifecycle.d.ts +17 -0
  28. package/dist/deploy-lifecycle.d.ts.map +1 -0
  29. package/dist/deploy-lifecycle.js +25 -0
  30. package/dist/deploy-lifecycle.js.map +1 -0
  31. package/dist/deploy.d.ts +20 -0
  32. package/dist/deploy.d.ts.map +1 -0
  33. package/dist/deploy.js +462 -0
  34. package/dist/deploy.js.map +1 -0
  35. package/dist/dev.d.ts +13 -0
  36. package/dist/dev.d.ts.map +1 -0
  37. package/dist/dev.js +157 -0
  38. package/dist/dev.js.map +1 -0
  39. package/dist/eval-assertions.d.ts +5 -0
  40. package/dist/eval-assertions.d.ts.map +1 -0
  41. package/dist/eval-assertions.js +99 -0
  42. package/dist/eval-assertions.js.map +1 -0
  43. package/dist/eval-case-runner.d.ts +38 -0
  44. package/dist/eval-case-runner.d.ts.map +1 -0
  45. package/dist/eval-case-runner.js +247 -0
  46. package/dist/eval-case-runner.js.map +1 -0
  47. package/dist/eval-cases.d.ts +6 -0
  48. package/dist/eval-cases.d.ts.map +1 -0
  49. package/dist/eval-cases.js +151 -0
  50. package/dist/eval-cases.js.map +1 -0
  51. package/dist/eval-comparison.d.ts +8 -0
  52. package/dist/eval-comparison.d.ts.map +1 -0
  53. package/dist/eval-comparison.js +90 -0
  54. package/dist/eval-comparison.js.map +1 -0
  55. package/dist/eval-custom.d.ts +15 -0
  56. package/dist/eval-custom.d.ts.map +1 -0
  57. package/dist/eval-custom.js +118 -0
  58. package/dist/eval-custom.js.map +1 -0
  59. package/dist/eval-experiment.d.ts +19 -0
  60. package/dist/eval-experiment.d.ts.map +1 -0
  61. package/dist/eval-experiment.js +122 -0
  62. package/dist/eval-experiment.js.map +1 -0
  63. package/dist/eval-fixtures.d.ts +17 -0
  64. package/dist/eval-fixtures.d.ts.map +1 -0
  65. package/dist/eval-fixtures.js +59 -0
  66. package/dist/eval-fixtures.js.map +1 -0
  67. package/dist/eval-gateway-host.d.ts +34 -0
  68. package/dist/eval-gateway-host.d.ts.map +1 -0
  69. package/dist/eval-gateway-host.js +127 -0
  70. package/dist/eval-gateway-host.js.map +1 -0
  71. package/dist/eval-judge.d.ts +35 -0
  72. package/dist/eval-judge.d.ts.map +1 -0
  73. package/dist/eval-judge.js +105 -0
  74. package/dist/eval-judge.js.map +1 -0
  75. package/dist/eval-mocks.d.ts +10 -0
  76. package/dist/eval-mocks.d.ts.map +1 -0
  77. package/dist/eval-mocks.js +57 -0
  78. package/dist/eval-mocks.js.map +1 -0
  79. package/dist/eval-report.d.ts +7 -0
  80. package/dist/eval-report.d.ts.map +1 -0
  81. package/dist/eval-report.js +89 -0
  82. package/dist/eval-report.js.map +1 -0
  83. package/dist/eval-retry.d.ts +10 -0
  84. package/dist/eval-retry.d.ts.map +1 -0
  85. package/dist/eval-retry.js +37 -0
  86. package/dist/eval-retry.js.map +1 -0
  87. package/dist/eval-trajectory.d.ts +7 -0
  88. package/dist/eval-trajectory.d.ts.map +1 -0
  89. package/dist/eval-trajectory.js +92 -0
  90. package/dist/eval-trajectory.js.map +1 -0
  91. package/dist/eval-turns.d.ts +66 -0
  92. package/dist/eval-turns.d.ts.map +1 -0
  93. package/dist/eval-turns.js +187 -0
  94. package/dist/eval-turns.js.map +1 -0
  95. package/dist/eval-types.d.ts +271 -0
  96. package/dist/eval-types.d.ts.map +1 -0
  97. package/dist/eval-types.js +4 -0
  98. package/dist/eval-types.js.map +1 -0
  99. package/dist/eval.d.ts +26 -0
  100. package/dist/eval.d.ts.map +1 -0
  101. package/dist/eval.js +218 -0
  102. package/dist/eval.js.map +1 -0
  103. package/dist/help.d.ts +12 -0
  104. package/dist/help.d.ts.map +1 -0
  105. package/dist/help.js +323 -0
  106. package/dist/help.js.map +1 -0
  107. package/dist/hosts.d.ts +3 -0
  108. package/dist/hosts.d.ts.map +1 -0
  109. package/dist/hosts.js +51 -0
  110. package/dist/hosts.js.map +1 -0
  111. package/dist/index.d.ts +3 -0
  112. package/dist/index.d.ts.map +1 -0
  113. package/dist/index.js +318 -0
  114. package/dist/index.js.map +1 -0
  115. package/dist/init.d.ts +13 -0
  116. package/dist/init.d.ts.map +1 -0
  117. package/dist/init.js +79 -0
  118. package/dist/init.js.map +1 -0
  119. package/dist/legacy-bin.d.ts +3 -0
  120. package/dist/legacy-bin.d.ts.map +1 -0
  121. package/dist/legacy-bin.js +8 -0
  122. package/dist/legacy-bin.js.map +1 -0
  123. package/dist/models.d.ts +5 -0
  124. package/dist/models.d.ts.map +1 -0
  125. package/dist/models.js +20 -0
  126. package/dist/models.js.map +1 -0
  127. package/dist/operator-client.d.ts +7 -0
  128. package/dist/operator-client.d.ts.map +1 -0
  129. package/dist/operator-client.js +62 -0
  130. package/dist/operator-client.js.map +1 -0
  131. package/dist/pm.d.ts +20 -0
  132. package/dist/pm.d.ts.map +1 -0
  133. package/dist/pm.js +70 -0
  134. package/dist/pm.js.map +1 -0
  135. package/dist/project-env.d.ts +8 -0
  136. package/dist/project-env.d.ts.map +1 -0
  137. package/dist/project-env.js +51 -0
  138. package/dist/project-env.js.map +1 -0
  139. package/dist/secrets.d.ts +3 -0
  140. package/dist/secrets.d.ts.map +1 -0
  141. package/dist/secrets.js +48 -0
  142. package/dist/secrets.js.map +1 -0
  143. package/dist/state.d.ts +3 -0
  144. package/dist/state.d.ts.map +1 -0
  145. package/dist/state.js +85 -0
  146. package/dist/state.js.map +1 -0
  147. package/package.json +67 -0
@@ -0,0 +1,151 @@
1
+ import { readdirSync, readFileSync } from "node:fs";
2
+ import { extname, relative, resolve, sep } from "node:path";
3
+ import { validateFixtures } from "./eval-fixtures.js";
4
+ import { validateMocks } from "./eval-mocks.js";
5
+ export function discoverCases(agentRoot, options = {}) {
6
+ const evalRoot = resolve(agentRoot, "evals");
7
+ let files;
8
+ try {
9
+ files = readdirSync(evalRoot, { withFileTypes: true, recursive: true })
10
+ .filter((entry) => entry.isFile() && entry.name.endsWith(".json"))
11
+ .map((entry) => resolve(entry.parentPath, entry.name))
12
+ .filter((path) => {
13
+ const relativePath = relative(evalRoot, path);
14
+ return relativePath.split(sep)[0] !== "evaluators";
15
+ })
16
+ .sort();
17
+ }
18
+ catch (error) {
19
+ const code = error && typeof error === "object" && "code" in error ? String(error.code) : "";
20
+ if (code === "ENOENT")
21
+ return [];
22
+ throw error;
23
+ }
24
+ const discovered = files.map((path) => loadCase(evalRoot, path));
25
+ const filter = options.filter?.toLocaleLowerCase();
26
+ return discovered.filter((item) => {
27
+ if (filter) {
28
+ const haystack = `${item.name} ${item.evalCase?.description ?? ""}`.toLocaleLowerCase();
29
+ if (!haystack.includes(filter))
30
+ return false;
31
+ }
32
+ if (options.tag && !item.evalCase?.tags?.includes(options.tag))
33
+ return false;
34
+ return true;
35
+ });
36
+ }
37
+ function loadCase(evalRoot, path) {
38
+ const relativePath = relative(evalRoot, path).replaceAll(sep, "/");
39
+ const fallbackName = relativePath.slice(0, relativePath.length - extname(relativePath).length);
40
+ try {
41
+ const value = JSON.parse(readFileSync(path, "utf8"));
42
+ const evalCase = normalizeCase(value, fallbackName);
43
+ return { path, name: evalCase.name, evalCase };
44
+ }
45
+ catch (error) {
46
+ return { path, name: fallbackName, error: error instanceof Error ? error.message : String(error) };
47
+ }
48
+ }
49
+ function normalizeCase(value, fallbackName) {
50
+ if (!isRecord(value))
51
+ throw new Error("case must be a JSON object");
52
+ if (!isRecord(value.input))
53
+ throw new Error("input must be a JSON object");
54
+ validateInputShape(value.input);
55
+ if (!isRecord(value.expect))
56
+ throw new Error("expect must be a JSON object");
57
+ if (value.name !== undefined && (typeof value.name !== "string" || value.name.trim() === "")) {
58
+ throw new Error("name must be a non-empty string");
59
+ }
60
+ if (value.tags !== undefined && (!Array.isArray(value.tags) || value.tags.some((tag) => typeof tag !== "string"))) {
61
+ throw new Error("tags must be an array of strings");
62
+ }
63
+ if (value.repetitions !== undefined
64
+ && (typeof value.repetitions !== "number" || !Number.isInteger(value.repetitions) || value.repetitions < 1 || value.repetitions > 100)) {
65
+ throw new Error("repetitions must be an integer between 1 and 100");
66
+ }
67
+ validateTrajectory(value.expect.trajectory);
68
+ validateEvaluators(value.expect.evaluators);
69
+ validateMocks(value.mocks);
70
+ validateFixtures(value.fixtures);
71
+ return { ...value, name: typeof value.name === "string" ? value.name : fallbackName };
72
+ }
73
+ function validateInputShape(input) {
74
+ const hasMessage = typeof input.message === "string";
75
+ const hasTurns = input.turns !== undefined;
76
+ if (hasMessage === hasTurns) {
77
+ throw new Error("input must declare exactly one of message or turns");
78
+ }
79
+ if (!hasTurns)
80
+ return;
81
+ if (input.tool !== undefined || input.toolInput !== undefined) {
82
+ throw new Error("input.tool and input.toolInput belong on individual turns when input.turns is used");
83
+ }
84
+ if (!Array.isArray(input.turns) || input.turns.length === 0) {
85
+ throw new Error("input.turns must be a non-empty array");
86
+ }
87
+ for (const [index, turn] of input.turns.entries()) {
88
+ if (!isRecord(turn) || typeof turn.message !== "string") {
89
+ throw new Error(`input.turns[${index}].message must be a string`);
90
+ }
91
+ if (turn.approve !== undefined && typeof turn.approve !== "boolean") {
92
+ throw new Error(`input.turns[${index}].approve must be a boolean`);
93
+ }
94
+ if (turn.expect !== undefined) {
95
+ if (!isRecord(turn.expect))
96
+ throw new Error(`input.turns[${index}].expect must be a JSON object`);
97
+ for (const key of ["judge", "evaluators"]) {
98
+ if (turn.expect[key] !== undefined) {
99
+ throw new Error(`input.turns[${index}].expect.${key} is not supported; declare ${key} on the case-level expect`);
100
+ }
101
+ }
102
+ validateTrajectory(turn.expect.trajectory);
103
+ }
104
+ }
105
+ }
106
+ function validateTrajectory(value) {
107
+ if (value === undefined)
108
+ return;
109
+ if (!isRecord(value) || !["contains", "ordered", "exact", "forbid"].includes(String(value.mode))) {
110
+ throw new Error("expect.trajectory.mode must be contains, ordered, exact, or forbid");
111
+ }
112
+ if (!Array.isArray(value.steps) || value.steps.some((step) => !isRecord(step) || typeof step.tool !== "string")) {
113
+ throw new Error("expect.trajectory.steps must be an array of objects with a tool string");
114
+ }
115
+ for (const step of value.steps) {
116
+ if (!isRecord(step))
117
+ continue;
118
+ if (step.argumentsMatch !== undefined && !["partial", "exact"].includes(String(step.argumentsMatch))) {
119
+ throw new Error("trajectory argumentsMatch must be partial or exact");
120
+ }
121
+ if (step.resultMatch !== undefined && !["partial", "exact"].includes(String(step.resultMatch))) {
122
+ throw new Error("trajectory resultMatch must be partial or exact");
123
+ }
124
+ }
125
+ }
126
+ function validateEvaluators(value) {
127
+ if (value === undefined)
128
+ return;
129
+ if (!Array.isArray(value))
130
+ throw new Error("expect.evaluators must be an array");
131
+ for (const evaluator of value) {
132
+ if (!isRecord(evaluator) || typeof evaluator.name !== "string" || evaluator.name.trim() === "") {
133
+ throw new Error("each expect.evaluators entry must have a non-empty name");
134
+ }
135
+ if (!/^[A-Za-z0-9._-]+$/u.test(evaluator.name))
136
+ throw new Error("expect.evaluators name contains unsupported characters");
137
+ if (evaluator.metric !== undefined && typeof evaluator.metric !== "string") {
138
+ throw new Error("expect.evaluators metric must be a string");
139
+ }
140
+ if (evaluator.requirePass !== undefined && typeof evaluator.requirePass !== "boolean") {
141
+ throw new Error("expect.evaluators requirePass must be a boolean");
142
+ }
143
+ if (evaluator.minScore !== undefined && (typeof evaluator.minScore !== "number" || !Number.isFinite(evaluator.minScore))) {
144
+ throw new Error("expect.evaluators minScore must be a finite number");
145
+ }
146
+ }
147
+ }
148
+ function isRecord(value) {
149
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
150
+ }
151
+ //# sourceMappingURL=eval-cases.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eval-cases.js","sourceRoot":"","sources":["../src/eval-cases.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { EvalComparison, EvalReport } from "./eval-types.js";
2
+ export interface EvalRegressionGates {
3
+ maxRegressions?: number;
4
+ maxCostIncreasePercent?: number;
5
+ }
6
+ export declare function loadBaselineReport(path: string): EvalReport;
7
+ export declare function compareEvalReports(baseline: EvalReport, current: EvalReport, options?: EvalRegressionGates): EvalComparison;
8
+ //# sourceMappingURL=eval-comparison.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eval-comparison.d.ts","sourceRoot":"","sources":["../src/eval-comparison.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAkB,cAAc,EAAkB,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElG,MAAM,WAAW,mBAAmB;IAClC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAO3D;AAED,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,UAAU,EACpB,OAAO,EAAE,UAAU,EACnB,OAAO,GAAE,mBAAwB,GAChC,cAAc,CAiDhB"}
@@ -0,0 +1,90 @@
1
+ import { readFileSync, statSync } from "node:fs";
2
+ import { resolve } from "node:path";
3
+ export function loadBaselineReport(path) {
4
+ let target = resolve(path);
5
+ if (statSync(target).isDirectory())
6
+ target = resolve(target, "results.json");
7
+ else if (target.endsWith("experiment.json"))
8
+ target = resolve(target, "..", "results.json");
9
+ const value = JSON.parse(readFileSync(target, "utf8"));
10
+ if (!isReport(value))
11
+ throw new Error(`Baseline ${target} is not an Assembly Line eval results file.`);
12
+ return value;
13
+ }
14
+ export function compareEvalReports(baseline, current, options = {}) {
15
+ const baselineCases = aggregateCases(baseline.results);
16
+ const currentCases = aggregateCases(current.results);
17
+ const regressions = [];
18
+ const improvements = [];
19
+ for (const [caseId, baselineCase] of baselineCases) {
20
+ const currentCase = currentCases.get(caseId);
21
+ if (!currentCase)
22
+ continue;
23
+ const comparison = {
24
+ caseId,
25
+ name: currentCase.name,
26
+ baselinePassRate: baselineCase.passRate,
27
+ currentPassRate: currentCase.passRate
28
+ };
29
+ if (currentCase.passRate < baselineCase.passRate)
30
+ regressions.push(comparison);
31
+ if (currentCase.passRate > baselineCase.passRate)
32
+ improvements.push(comparison);
33
+ }
34
+ const maxRegressions = options.maxRegressions ?? 0;
35
+ const gates = [{
36
+ name: "max-regressions",
37
+ passed: regressions.length <= maxRegressions,
38
+ actual: regressions.length,
39
+ limit: maxRegressions
40
+ }];
41
+ const costDeltaUsd = current.summary.totalCostUsd - baseline.summary.totalCostUsd;
42
+ const costDeltaPercent = baseline.summary.totalCostUsd === 0
43
+ ? undefined
44
+ : (costDeltaUsd / baseline.summary.totalCostUsd) * 100;
45
+ if (options.maxCostIncreasePercent !== undefined) {
46
+ const actual = costDeltaPercent ?? (costDeltaUsd > 0 ? null : 0);
47
+ gates.push({
48
+ name: "max-cost-increase-percent",
49
+ passed: actual !== null && actual <= options.maxCostIncreasePercent,
50
+ actual,
51
+ limit: options.maxCostIncreasePercent
52
+ });
53
+ }
54
+ return {
55
+ baselineExperimentId: baseline.experiment.id,
56
+ regressions: regressions.sort(byCaseId),
57
+ improvements: improvements.sort(byCaseId),
58
+ addedCaseIds: [...currentCases.keys()].filter((caseId) => !baselineCases.has(caseId)).sort(),
59
+ removedCaseIds: [...baselineCases.keys()].filter((caseId) => !currentCases.has(caseId)).sort(),
60
+ passRateDelta: current.summary.passRate - baseline.summary.passRate,
61
+ costDeltaUsd,
62
+ ...(costDeltaPercent === undefined ? {} : { costDeltaPercent }),
63
+ gates,
64
+ passed: gates.every((gate) => gate.passed)
65
+ };
66
+ }
67
+ function aggregateCases(results) {
68
+ const counts = new Map();
69
+ for (const result of results) {
70
+ const count = counts.get(result.caseId) ?? { name: result.name, passed: 0, total: 0 };
71
+ count.total += 1;
72
+ if (result.outcome === "passed")
73
+ count.passed += 1;
74
+ counts.set(result.caseId, count);
75
+ }
76
+ return new Map([...counts].map(([caseId, count]) => [caseId, {
77
+ name: count.name,
78
+ passRate: count.total === 0 ? 0 : count.passed / count.total
79
+ }]));
80
+ }
81
+ function isReport(value) {
82
+ if (!value || typeof value !== "object")
83
+ return false;
84
+ const report = value;
85
+ return report.schemaVersion === 1 && Array.isArray(report.results) && Boolean(report.experiment) && Boolean(report.summary);
86
+ }
87
+ function byCaseId(left, right) {
88
+ return left.caseId.localeCompare(right.caseId);
89
+ }
90
+ //# sourceMappingURL=eval-comparison.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eval-comparison.js","sourceRoot":"","sources":["../src/eval-comparison.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { EvalCustomEvaluatorExpectation, EvalEvaluator, EvalEvaluatorContext, EvalMetric } from "./eval-types.js";
2
+ export declare class EvalEvaluatorLoader {
3
+ private readonly agentRoot;
4
+ private readonly cacheRoot;
5
+ private readonly provided;
6
+ private readonly loaded;
7
+ constructor(agentRoot: string, cacheRoot: string, provided?: Record<string, EvalEvaluator>);
8
+ load(name: string): Promise<EvalEvaluator>;
9
+ private compileAndLoad;
10
+ }
11
+ export declare function evaluateCustomExpectations(expectations: EvalCustomEvaluatorExpectation[], loader: EvalEvaluatorLoader, context: Omit<EvalEvaluatorContext, "config">): Promise<{
12
+ metrics: EvalMetric[];
13
+ failures: string[];
14
+ }>;
15
+ //# sourceMappingURL=eval-custom.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eval-custom.d.ts","sourceRoot":"","sources":["../src/eval-custom.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,8BAA8B,EAC9B,aAAa,EACb,oBAAoB,EACpB,UAAU,EACX,MAAM,iBAAiB,CAAC;AAEzB,qBAAa,mBAAmB;IAI5B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAL3B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA6C;gBAGjD,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,QAAQ,GAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAM;IAGzD,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;YAYlC,cAAc;CA2B7B;AAED,wBAAsB,0BAA0B,CAC9C,YAAY,EAAE,8BAA8B,EAAE,EAC9C,MAAM,EAAE,mBAAmB,EAC3B,OAAO,EAAE,IAAI,CAAC,oBAAoB,EAAE,QAAQ,CAAC,GAC5C,OAAO,CAAC;IAAE,OAAO,EAAE,UAAU,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CA6BxD"}
@@ -0,0 +1,118 @@
1
+ import { createHash } from "node:crypto";
2
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
3
+ import { dirname, resolve } from "node:path";
4
+ import { pathToFileURL } from "node:url";
5
+ import { build } from "esbuild";
6
+ export class EvalEvaluatorLoader {
7
+ agentRoot;
8
+ cacheRoot;
9
+ provided;
10
+ loaded = new Map();
11
+ constructor(agentRoot, cacheRoot, provided = {}) {
12
+ this.agentRoot = agentRoot;
13
+ this.cacheRoot = cacheRoot;
14
+ this.provided = provided;
15
+ }
16
+ async load(name) {
17
+ if (!/^[A-Za-z0-9._-]+$/u.test(name))
18
+ throw new Error(`Invalid evaluator name: ${name}`);
19
+ const provided = this.provided[name];
20
+ if (provided)
21
+ return validateEvaluator(name, provided);
22
+ let pending = this.loaded.get(name);
23
+ if (!pending) {
24
+ pending = this.compileAndLoad(name);
25
+ this.loaded.set(name, pending);
26
+ }
27
+ return pending;
28
+ }
29
+ async compileAndLoad(name) {
30
+ const sourcePath = evaluatorSourcePath(this.agentRoot, name);
31
+ if (!sourcePath) {
32
+ throw new Error(`Custom evaluator ${name} was not found under evals/evaluators/.`);
33
+ }
34
+ const source = readFileSync(sourcePath, "utf8");
35
+ const hash = createHash("sha256").update(sourcePath).update(source).digest("hex");
36
+ mkdirSync(this.cacheRoot, { recursive: true });
37
+ const outputPath = resolve(this.cacheRoot, `${name}-${hash}.mjs`);
38
+ if (!existsSync(outputPath)) {
39
+ const bundled = await build({
40
+ entryPoints: [sourcePath],
41
+ bundle: true,
42
+ write: false,
43
+ platform: "node",
44
+ format: "esm",
45
+ target: "node22",
46
+ packages: "external",
47
+ logLevel: "silent"
48
+ });
49
+ const output = bundled.outputFiles[0]?.text;
50
+ if (!output)
51
+ throw new Error(`Failed to compile custom evaluator ${name}.`);
52
+ writeFileSync(outputPath, output, { flag: "wx" });
53
+ }
54
+ const module = await import(`${pathToFileURL(outputPath).href}?v=${hash}`);
55
+ return validateEvaluator(name, module.default);
56
+ }
57
+ }
58
+ export async function evaluateCustomExpectations(expectations, loader, context) {
59
+ const metrics = [];
60
+ const failures = [];
61
+ for (const expectation of expectations) {
62
+ const evaluator = await loader.load(expectation.name);
63
+ const result = await evaluator.evaluate({ ...context, config: expectation.config ?? {} });
64
+ const evaluated = (Array.isArray(result) ? result : [result]).map((metric) => normalizeMetric(expectation.name, metric));
65
+ if (evaluated.length === 0)
66
+ throw new Error(`Custom evaluator ${expectation.name} returned no metrics.`);
67
+ if (new Set(evaluated.map((metric) => metric.key)).size !== evaluated.length) {
68
+ throw new Error(`Custom evaluator ${expectation.name} returned duplicate metric keys.`);
69
+ }
70
+ metrics.push(...evaluated);
71
+ if (expectation.requirePass !== false) {
72
+ for (const metric of evaluated) {
73
+ if (metric.pass === false)
74
+ failures.push(`${expectation.name}.${metric.key} failed${metric.comment ? `: ${metric.comment}` : ""}`);
75
+ }
76
+ }
77
+ if (expectation.minScore !== undefined) {
78
+ const scored = expectation.metric
79
+ ? evaluated.filter((metric) => metric.key === expectation.metric)
80
+ : evaluated.filter((metric) => metric.score !== undefined);
81
+ if (scored.length === 0) {
82
+ failures.push(`${expectation.name} returned no numeric ${expectation.metric ? `${expectation.metric} ` : ""}metric for minScore`);
83
+ }
84
+ else if (scored.every((metric) => metric.score < expectation.minScore)) {
85
+ failures.push(`${expectation.name} score did not meet ${expectation.minScore}`);
86
+ }
87
+ }
88
+ }
89
+ return { metrics, failures };
90
+ }
91
+ function evaluatorSourcePath(agentRoot, name) {
92
+ const root = resolve(agentRoot, "evals", "evaluators");
93
+ for (const extension of [".ts", ".mts", ".js", ".mjs"]) {
94
+ const path = resolve(root, `${name}${extension}`);
95
+ if (existsSync(path) && dirname(path) === root)
96
+ return path;
97
+ }
98
+ return undefined;
99
+ }
100
+ function validateEvaluator(name, value) {
101
+ if (!value || typeof value !== "object" || typeof value.evaluate !== "function") {
102
+ throw new Error(`Custom evaluator ${name} must default-export an object with evaluate(context).`);
103
+ }
104
+ const evaluator = value;
105
+ if (evaluator.name !== name)
106
+ throw new Error(`Custom evaluator ${name} must declare name: ${JSON.stringify(name)}.`);
107
+ return evaluator;
108
+ }
109
+ function normalizeMetric(evaluator, metric) {
110
+ if (!metric || typeof metric !== "object" || typeof metric.key !== "string" || metric.key.trim() === "") {
111
+ throw new Error(`Custom evaluator ${evaluator} returned a metric without a non-empty key.`);
112
+ }
113
+ if (metric.score !== undefined && !Number.isFinite(metric.score)) {
114
+ throw new Error(`Custom evaluator ${evaluator} returned a non-finite score for ${metric.key}.`);
115
+ }
116
+ return { ...metric, evaluator };
117
+ }
118
+ //# sourceMappingURL=eval-custom.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eval-custom.js","sourceRoot":"","sources":["../src/eval-custom.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { DiscoveredEvalCase, EvalExecutionConfig, EvalExperimentManifest, EvalReport } from "./eval-types.js";
2
+ export interface EvalExperimentArtifacts {
3
+ root: string;
4
+ experimentPath: string;
5
+ resultsPath: string;
6
+ }
7
+ export declare function createExperimentManifest(input: {
8
+ startedAt: string;
9
+ agentRevision: string;
10
+ agentRoot: string;
11
+ cases: DiscoveredEvalCase[];
12
+ config: EvalExecutionConfig;
13
+ }): EvalExperimentManifest;
14
+ export declare function createExperimentArtifacts(artifactRoot: string, manifest: EvalExperimentManifest): EvalExperimentArtifacts;
15
+ export declare function writeExperimentManifest(manifest: EvalExperimentManifest, artifacts: EvalExperimentArtifacts): void;
16
+ export declare function writeExperimentReport(report: EvalReport, artifacts: EvalExperimentArtifacts): void;
17
+ export declare function fingerprintEvalSuite(agentRoot: string, cases: DiscoveredEvalCase[]): string;
18
+ export declare function fingerprintValue(value: unknown): string;
19
+ //# sourceMappingURL=eval-experiment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eval-experiment.d.ts","sourceRoot":"","sources":["../src/eval-experiment.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,kBAAkB,EAClB,mBAAmB,EACnB,sBAAsB,EACtB,UAAU,EACX,MAAM,iBAAiB,CAAC;AAEzB,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE;IAC9C,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,kBAAkB,EAAE,CAAC;IAC5B,MAAM,EAAE,mBAAmB,CAAC;CAC7B,GAAG,sBAAsB,CAkBzB;AAED,wBAAgB,yBAAyB,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,sBAAsB,GAAG,uBAAuB,CAOzH;AAED,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,sBAAsB,EAChC,SAAS,EAAE,uBAAuB,GACjC,IAAI,CAGN;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,uBAAuB,GAAG,IAAI,CAElG;AAED,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,EAAE,GAAG,MAAM,CAiC3F;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEvD"}
@@ -0,0 +1,122 @@
1
+ import { createHash, randomUUID } from "node:crypto";
2
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
3
+ import { basename, relative, resolve } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { buildSync } from "esbuild";
6
+ export function createExperimentManifest(input) {
7
+ const suiteFingerprint = fingerprintEvalSuite(input.agentRoot, input.cases);
8
+ const configFingerprint = fingerprintValue(input.config);
9
+ return {
10
+ schemaVersion: 1,
11
+ id: `${input.startedAt.replace(/[:.]/gu, "-")}-${suiteFingerprint.slice(0, 10)}-${randomUUID().slice(0, 8)}`,
12
+ startedAt: input.startedAt,
13
+ frameworkVersion: frameworkVersion(),
14
+ agentRevision: input.agentRevision,
15
+ suiteFingerprint,
16
+ configFingerprint,
17
+ caseCount: input.cases.length,
18
+ executionCount: input.cases.reduce((count, item) => count + (item.evalCase ? item.evalCase.repetitions ?? input.config.repetitions : 1), 0),
19
+ config: input.config
20
+ };
21
+ }
22
+ export function createExperimentArtifacts(artifactRoot, manifest) {
23
+ const root = resolve(artifactRoot, "eval-results", manifest.id);
24
+ return {
25
+ root,
26
+ experimentPath: resolve(root, "experiment.json"),
27
+ resultsPath: resolve(root, "results.json")
28
+ };
29
+ }
30
+ export function writeExperimentManifest(manifest, artifacts) {
31
+ mkdirSync(artifacts.root, { recursive: true });
32
+ writeJsonExclusive(artifacts.experimentPath, manifest);
33
+ }
34
+ export function writeExperimentReport(report, artifacts) {
35
+ writeJsonExclusive(artifacts.resultsPath, report);
36
+ }
37
+ export function fingerprintEvalSuite(agentRoot, cases) {
38
+ const files = new Set(cases.map((item) => item.path));
39
+ for (const item of cases) {
40
+ for (const evaluator of item.evalCase?.expect.evaluators ?? []) {
41
+ const source = evaluatorSourcePath(agentRoot, evaluator.name);
42
+ if (source)
43
+ files.add(source);
44
+ }
45
+ }
46
+ const hash = createHash("sha256");
47
+ for (const path of [...files].sort()) {
48
+ hash.update(relative(agentRoot, path).replaceAll("\\", "/"));
49
+ hash.update("\0");
50
+ hash.update(readFileSync(path));
51
+ hash.update("\0");
52
+ }
53
+ for (const sourcePath of evaluatorSources(agentRoot, cases)) {
54
+ const bundled = buildSync({
55
+ entryPoints: [sourcePath],
56
+ bundle: true,
57
+ write: false,
58
+ platform: "node",
59
+ format: "esm",
60
+ target: "node22",
61
+ packages: "external",
62
+ legalComments: "none",
63
+ logLevel: "silent"
64
+ }).outputFiles[0]?.contents;
65
+ if (!bundled)
66
+ throw new Error(`Failed to fingerprint custom evaluator ${basename(sourcePath)}.`);
67
+ hash.update(`bundle:${relative(agentRoot, sourcePath).replaceAll("\\", "/")}\0`);
68
+ hash.update(bundled);
69
+ hash.update("\0");
70
+ }
71
+ return hash.digest("hex");
72
+ }
73
+ export function fingerprintValue(value) {
74
+ return createHash("sha256").update(stableJson(value)).digest("hex");
75
+ }
76
+ function evaluatorSourcePath(agentRoot, name) {
77
+ if (!/^[A-Za-z0-9._-]+$/u.test(name))
78
+ return undefined;
79
+ const root = resolve(agentRoot, "evals", "evaluators");
80
+ for (const extension of [".ts", ".mts", ".js", ".mjs"]) {
81
+ const path = resolve(root, `${name}${extension}`);
82
+ if (existsSync(path))
83
+ return path;
84
+ }
85
+ return undefined;
86
+ }
87
+ function evaluatorSources(agentRoot, cases) {
88
+ const sources = new Set();
89
+ for (const item of cases) {
90
+ for (const evaluator of item.evalCase?.expect.evaluators ?? []) {
91
+ const source = evaluatorSourcePath(agentRoot, evaluator.name);
92
+ if (source)
93
+ sources.add(source);
94
+ }
95
+ }
96
+ return [...sources].sort();
97
+ }
98
+ function stableJson(value) {
99
+ if (Array.isArray(value))
100
+ return `[${value.map(stableJson).join(",")}]`;
101
+ if (value && typeof value === "object") {
102
+ const entries = Object.entries(value)
103
+ .filter(([, item]) => item !== undefined)
104
+ .sort(([left], [right]) => left.localeCompare(right));
105
+ return `{${entries.map(([key, item]) => `${JSON.stringify(key)}:${stableJson(item)}`).join(",")}}`;
106
+ }
107
+ return JSON.stringify(value);
108
+ }
109
+ function frameworkVersion() {
110
+ try {
111
+ const packagePath = resolve(fileURLToPath(new URL(".", import.meta.url)), "..", "package.json");
112
+ const parsed = JSON.parse(readFileSync(packagePath, "utf8"));
113
+ return typeof parsed.version === "string" ? parsed.version : "unknown";
114
+ }
115
+ catch {
116
+ return "unknown";
117
+ }
118
+ }
119
+ function writeJsonExclusive(path, value) {
120
+ writeFileSync(path, `${JSON.stringify(value, null, 2)}\n`, { encoding: "utf8", flag: "wx" });
121
+ }
122
+ //# sourceMappingURL=eval-experiment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eval-experiment.js","sourceRoot":"","sources":["../src/eval-experiment.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { MemoryStore, SandboxAdapter } from "@assemblyline-agents/runtime";
2
+ import type { EvalFixtures } from "./eval-types.js";
3
+ /**
4
+ * Case-declared starting state: sandbox files and memory documents seeded
5
+ * before the first turn. Sandbox seeding requires the case's runs to share a
6
+ * conversation-scoped sandbox session, so the runner assigns a conversationId
7
+ * to any case with sandbox fixtures.
8
+ */
9
+ export declare function validateFixtures(value: unknown): void;
10
+ export declare function seedEvalFixtures(input: {
11
+ fixtures: EvalFixtures;
12
+ sandbox: SandboxAdapter;
13
+ memoryStore: MemoryStore;
14
+ agentScope: string;
15
+ conversationId?: string;
16
+ }): Promise<void>;
17
+ //# sourceMappingURL=eval-fixtures.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eval-fixtures.d.ts","sourceRoot":"","sources":["../src/eval-fixtures.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAa,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAE3F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEpD;;;;;GAKG;AAEH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAcrD;AAED,wBAAsB,gBAAgB,CAAC,KAAK,EAAE;IAC5C,QAAQ,EAAE,YAAY,CAAC;IACvB,OAAO,EAAE,cAAc,CAAC;IACxB,WAAW,EAAE,WAAW,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,GAAG,OAAO,CAAC,IAAI,CAAC,CAyBhB"}