@tangle-network/agent-eval 0.123.1 → 0.123.3

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 (94) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/README.md +191 -157
  3. package/dist/analyst/index.d.ts +27 -4
  4. package/dist/analyst/index.js +6 -6
  5. package/dist/authenticity/index.js +3 -2
  6. package/dist/authenticity/index.js.map +1 -1
  7. package/dist/benchmarks/index.d.ts +12 -4
  8. package/dist/benchmarks/index.js +9 -9
  9. package/dist/campaign/index.d.ts +270 -254
  10. package/dist/campaign/index.js +22 -18
  11. package/dist/{chunk-GS3FJGUF.js → chunk-22VO7T2I.js} +805 -366
  12. package/dist/chunk-22VO7T2I.js.map +1 -0
  13. package/dist/{chunk-LBAHQOBI.js → chunk-4KO6D2BO.js} +38 -12
  14. package/dist/chunk-4KO6D2BO.js.map +1 -0
  15. package/dist/{chunk-3FCG7FBV.js → chunk-D5JZ7UDZ.js} +2 -2
  16. package/dist/{chunk-XJYR7XFV.js → chunk-GC4ATIKK.js} +1 -1
  17. package/dist/chunk-GC4ATIKK.js.map +1 -0
  18. package/dist/{chunk-BGVTIE2C.js → chunk-GRCDRKII.js} +13 -2
  19. package/dist/chunk-GRCDRKII.js.map +1 -0
  20. package/dist/{chunk-FHFTYX2Q.js → chunk-JKDNAOF5.js} +2 -2
  21. package/dist/{chunk-S3UZOQ5Y.js → chunk-LOW3U7JZ.js} +2 -2
  22. package/dist/{chunk-FC5NDO3E.js → chunk-MHPEGJHC.js} +4 -4
  23. package/dist/{chunk-NJC7U437.js → chunk-MK3Q6GCL.js} +33 -18
  24. package/dist/chunk-MK3Q6GCL.js.map +1 -0
  25. package/dist/{chunk-U5CHZ5M3.js → chunk-N7ZS6PEF.js} +4 -4
  26. package/dist/{chunk-A5S77LSE.js → chunk-QFQZ3U3X.js} +2 -2
  27. package/dist/chunk-QFQZ3U3X.js.map +1 -0
  28. package/dist/{chunk-G2GPNLSX.js → chunk-QNVBALEX.js} +4 -4
  29. package/dist/{chunk-OYZAPX5G.js → chunk-R226UZOI.js} +2 -2
  30. package/dist/{chunk-6WX7CBAR.js → chunk-SJT4OBVL.js} +20 -9
  31. package/dist/chunk-SJT4OBVL.js.map +1 -0
  32. package/dist/{chunk-HZJF4IUO.js → chunk-SUN7QLPB.js} +6 -6
  33. package/dist/{chunk-HZJF4IUO.js.map → chunk-SUN7QLPB.js.map} +1 -1
  34. package/dist/{chunk-VJ7T5WIO.js → chunk-WP3GEXKI.js} +3 -3
  35. package/dist/cli.js +101 -11
  36. package/dist/cli.js.map +1 -1
  37. package/dist/contract/index.d.ts +115 -8
  38. package/dist/contract/index.js +11 -9
  39. package/dist/contract/index.js.map +1 -1
  40. package/dist/control.js +3 -3
  41. package/dist/fuzz.d.ts +8 -1
  42. package/dist/fuzz.js +7 -6
  43. package/dist/fuzz.js.map +1 -1
  44. package/dist/hosted/index.d.ts +8 -2
  45. package/dist/index.d.ts +36 -10
  46. package/dist/index.js +18 -16
  47. package/dist/index.js.map +1 -1
  48. package/dist/multishot/index.d.ts +2 -2
  49. package/dist/openapi.json +1 -1
  50. package/dist/rl.d.ts +24 -3
  51. package/dist/rl.js +6 -4
  52. package/dist/rl.js.map +1 -1
  53. package/dist/{run-campaign-ZKR5MQMQ.js → run-campaign-I3JXKVAK.js} +3 -3
  54. package/dist/storyboard/index.js +1 -1
  55. package/dist/storyboard/index.js.map +1 -1
  56. package/dist/traces.d.ts +2 -2
  57. package/dist/traces.js +3 -3
  58. package/dist/wire/index.d.ts +77 -5
  59. package/dist/wire/index.js +3 -3
  60. package/docs/adapters-observability.md +6 -6
  61. package/docs/building-doctrine.md +5 -5
  62. package/docs/campaign-proposers.md +142 -131
  63. package/docs/concepts.md +49 -53
  64. package/docs/customer-journeys.md +80 -155
  65. package/docs/design/loop-taxonomy.md +27 -29
  66. package/docs/design.md +69 -0
  67. package/docs/distributed-driver.md +14 -14
  68. package/docs/eval-surface-map.md +11 -11
  69. package/docs/hosted-ingest-spec.md +4 -4
  70. package/docs/insight-report.md +32 -27
  71. package/docs/multi-shot-optimization.md +41 -49
  72. package/docs/research-report-methodology.md +9 -9
  73. package/docs/trace-analysis.md +2 -2
  74. package/docs/wire-protocol.md +16 -16
  75. package/package.json +2 -1
  76. package/dist/chunk-6WX7CBAR.js.map +0 -1
  77. package/dist/chunk-A5S77LSE.js.map +0 -1
  78. package/dist/chunk-BGVTIE2C.js.map +0 -1
  79. package/dist/chunk-GS3FJGUF.js.map +0 -1
  80. package/dist/chunk-LBAHQOBI.js.map +0 -1
  81. package/dist/chunk-NJC7U437.js.map +0 -1
  82. package/dist/chunk-XJYR7XFV.js.map +0 -1
  83. package/docs/auto-research-loop-end-to-end.md +0 -186
  84. package/docs/improvement-glossary.md +0 -204
  85. package/docs/self-improvement-map.md +0 -115
  86. /package/dist/{chunk-3FCG7FBV.js.map → chunk-D5JZ7UDZ.js.map} +0 -0
  87. /package/dist/{chunk-FHFTYX2Q.js.map → chunk-JKDNAOF5.js.map} +0 -0
  88. /package/dist/{chunk-S3UZOQ5Y.js.map → chunk-LOW3U7JZ.js.map} +0 -0
  89. /package/dist/{chunk-FC5NDO3E.js.map → chunk-MHPEGJHC.js.map} +0 -0
  90. /package/dist/{chunk-U5CHZ5M3.js.map → chunk-N7ZS6PEF.js.map} +0 -0
  91. /package/dist/{chunk-G2GPNLSX.js.map → chunk-QNVBALEX.js.map} +0 -0
  92. /package/dist/{chunk-OYZAPX5G.js.map → chunk-R226UZOI.js.map} +0 -0
  93. /package/dist/{chunk-VJ7T5WIO.js.map → chunk-WP3GEXKI.js.map} +0 -0
  94. /package/dist/{run-campaign-ZKR5MQMQ.js.map → run-campaign-I3JXKVAK.js.map} +0 -0
@@ -6,10 +6,10 @@ import {
6
6
  DEFAULT_TRACE_ANALYST_KINDS,
7
7
  createTraceAnalystKind,
8
8
  makeFinding
9
- } from "./chunk-FC5NDO3E.js";
9
+ } from "./chunk-MHPEGJHC.js";
10
10
  import {
11
11
  LlmClient
12
- } from "./chunk-NJC7U437.js";
12
+ } from "./chunk-MK3Q6GCL.js";
13
13
  import {
14
14
  spanEpochMillis
15
15
  } from "./chunk-IR3KBHOY.js";
@@ -547,4 +547,4 @@ export {
547
547
  behavioralAnalyst,
548
548
  buildDefaultAnalystRegistry
549
549
  };
550
- //# sourceMappingURL=chunk-VJ7T5WIO.js.map
550
+ //# sourceMappingURL=chunk-WP3GEXKI.js.map
package/dist/cli.js CHANGED
@@ -4,10 +4,10 @@ import {
4
4
  handleVersion,
5
5
  runRpcBatch,
6
6
  runRpcOnce,
7
- startServer
8
- } from "./chunk-LBAHQOBI.js";
9
- import "./chunk-NJC7U437.js";
10
- import "./chunk-BGVTIE2C.js";
7
+ startServerAsync
8
+ } from "./chunk-4KO6D2BO.js";
9
+ import "./chunk-MK3Q6GCL.js";
10
+ import "./chunk-GRCDRKII.js";
11
11
  import "./chunk-VI2UW6B6.js";
12
12
  import "./chunk-PC4UYEBM.js";
13
13
  import "./chunk-ONWEPEDO.js";
@@ -15,6 +15,25 @@ import "./chunk-PZ5AY32C.js";
15
15
 
16
16
  // src/cli.ts
17
17
  import { writeFileSync } from "fs";
18
+
19
+ // src/cli-config.ts
20
+ function resolveCliLlmConfig(env = process.env) {
21
+ const explicitBaseUrl = nonEmpty(env.AGENT_EVAL_LLM_BASE_URL);
22
+ const explicitApiKey = nonEmpty(env.AGENT_EVAL_LLM_API_KEY);
23
+ const openAiApiKey = nonEmpty(env.OPENAI_API_KEY);
24
+ const tangleApiKey = nonEmpty(env.TANGLE_API_KEY);
25
+ const baseUrl = explicitBaseUrl ?? nonEmpty(env.OPENAI_BASE_URL) ?? nonEmpty(env.TANGLE_ROUTER_URL) ?? (openAiApiKey ? "https://api.openai.com/v1" : void 0) ?? (tangleApiKey ? "https://router.tangle.tools/v1" : void 0);
26
+ const apiKey = explicitApiKey ?? openAiApiKey ?? tangleApiKey;
27
+ const model = nonEmpty(env.AGENT_EVAL_LLM_MODEL) ?? nonEmpty(env.OPENAI_MODEL) ?? nonEmpty(env.TANGLE_MODEL);
28
+ const client = baseUrl || apiKey ? { ...baseUrl ? { baseUrl } : {}, ...apiKey ? { apiKey } : {} } : void 0;
29
+ return { ...client ? { client } : {}, ...model ? { model } : {} };
30
+ }
31
+ function nonEmpty(value) {
32
+ const trimmed = value?.trim();
33
+ return trimmed ? trimmed : void 0;
34
+ }
35
+
36
+ // src/cli.ts
18
37
  function parseArgs(argv) {
19
38
  const [command, ...rest] = argv;
20
39
  const positional = [];
@@ -22,7 +41,17 @@ function parseArgs(argv) {
22
41
  for (let i = 0; i < rest.length; i++) {
23
42
  const tok = rest[i];
24
43
  if (tok.startsWith("--")) {
25
- const key = tok.slice(2);
44
+ const raw = tok.slice(2);
45
+ const equalsAt = raw.indexOf("=");
46
+ if (equalsAt >= 0) {
47
+ flags[raw.slice(0, equalsAt)] = raw.slice(equalsAt + 1);
48
+ continue;
49
+ }
50
+ const key = raw;
51
+ if (key === "help") {
52
+ flags[key] = "true";
53
+ continue;
54
+ }
26
55
  const next = rest[i + 1];
27
56
  if (next != null && !next.startsWith("--")) {
28
57
  flags[key] = next;
@@ -30,20 +59,22 @@ function parseArgs(argv) {
30
59
  } else {
31
60
  flags[key] = "true";
32
61
  }
62
+ } else if (tok === "-h") {
63
+ flags.help = "true";
33
64
  } else {
34
65
  positional.push(tok);
35
66
  }
36
67
  }
37
68
  return { command: command ?? "help", positional, flags };
38
69
  }
39
- var HELP = `agent-eval \u2014 wire-protocol entry point.
70
+ var HELP = `agent-eval: evaluation RPC and HTTP server.
40
71
 
41
72
  Commands:
42
73
  serve [--port 5005] [--host 127.0.0.1]
43
74
  Start the HTTP server. POST /v1/judge, GET /v1/rubrics, GET /v1/version, GET /openapi.json.
44
75
  rpc <method>
45
76
  Read one JSON object from stdin (the params for <method>), write one
46
- JSON object to stdout. Method \u2208 {judge, listRubrics, version}.
77
+ JSON object to stdout. Methods: judge, listRubrics, version.
47
78
  rpc-batch <method>
48
79
  Like 'rpc' but JSONL in / JSONL out.
49
80
  openapi [--out openapi.json]
@@ -51,14 +82,31 @@ Commands:
51
82
  version
52
83
  Print server + wire-protocol version JSON.
53
84
 
85
+ Judge provider:
86
+ Set AGENT_EVAL_LLM_BASE_URL, AGENT_EVAL_LLM_API_KEY, and AGENT_EVAL_LLM_MODEL.
87
+ OPENAI_* and TANGLE_* equivalents are also accepted.
88
+
54
89
  Without arguments, prints this help.`;
55
90
  async function main() {
56
91
  const { command, positional, flags } = parseArgs(process.argv.slice(2));
92
+ assertKnownFlags(command, flags);
93
+ if (flags.help === "true") {
94
+ process.stdout.write(`${HELP}
95
+ `);
96
+ return 0;
97
+ }
57
98
  switch (command) {
58
99
  case "serve": {
59
- const port = Number(flags.port ?? 5005);
100
+ const port = parsePort(flags.port ?? "5005");
60
101
  const host = flags.host ?? "127.0.0.1";
61
- const server = startServer({ port, host });
102
+ const llm = resolveCliLlmConfig();
103
+ const { server } = await startServerAsync({
104
+ port,
105
+ host,
106
+ llm: llm.client,
107
+ judgeModel: llm.model,
108
+ llmRouteRequirements: { requireExplicitBaseUrl: true }
109
+ });
62
110
  const shutdown = (sig) => {
63
111
  console.log(`[agent-eval] received ${sig}, shutting down`);
64
112
  server.close(() => process.exit(0));
@@ -72,11 +120,21 @@ async function main() {
72
120
  }
73
121
  case "rpc": {
74
122
  const [method] = positional;
75
- return await runRpcOnce(method);
123
+ const llm = resolveCliLlmConfig();
124
+ return await runRpcOnce(method, {
125
+ llm: llm.client,
126
+ judgeModel: llm.model,
127
+ llmRouteRequirements: { requireExplicitBaseUrl: true }
128
+ });
76
129
  }
77
130
  case "rpc-batch": {
78
131
  const [method] = positional;
79
- return await runRpcBatch(method);
132
+ const llm = resolveCliLlmConfig();
133
+ return await runRpcBatch(method, {
134
+ llm: llm.client,
135
+ judgeModel: llm.model,
136
+ llmRouteRequirements: { requireExplicitBaseUrl: true }
137
+ });
80
138
  }
81
139
  case "openapi": {
82
140
  const out = flags.out ?? "openapi.json";
@@ -88,6 +146,11 @@ async function main() {
88
146
  }
89
147
  case "version": {
90
148
  process.stdout.write(`${JSON.stringify(handleVersion(), null, 2)}
149
+ `);
150
+ return 0;
151
+ }
152
+ case "--version": {
153
+ process.stdout.write(`${handleVersion().version}
91
154
  `);
92
155
  return 0;
93
156
  }
@@ -105,6 +168,33 @@ ${HELP}
105
168
  return 1;
106
169
  }
107
170
  }
171
+ var FLAGS_BY_COMMAND = {
172
+ serve: /* @__PURE__ */ new Set(["help", "host", "port"]),
173
+ rpc: /* @__PURE__ */ new Set(["help"]),
174
+ "rpc-batch": /* @__PURE__ */ new Set(["help"]),
175
+ openapi: /* @__PURE__ */ new Set(["help", "out"]),
176
+ version: /* @__PURE__ */ new Set(["help"]),
177
+ help: /* @__PURE__ */ new Set(),
178
+ "--help": /* @__PURE__ */ new Set(),
179
+ "-h": /* @__PURE__ */ new Set(),
180
+ "--version": /* @__PURE__ */ new Set(),
181
+ "": /* @__PURE__ */ new Set()
182
+ };
183
+ function assertKnownFlags(command, flags) {
184
+ const allowed = FLAGS_BY_COMMAND[command];
185
+ if (!allowed) return;
186
+ const unknown = Object.keys(flags).filter((flag) => !allowed.has(flag));
187
+ if (unknown.length > 0) {
188
+ throw new Error(`unknown flag for ${command || "help"}: --${unknown[0]}`);
189
+ }
190
+ }
191
+ function parsePort(raw) {
192
+ const port = Number(raw);
193
+ if (!Number.isInteger(port) || port < 0 || port > 65535) {
194
+ throw new Error(`--port must be an integer from 0 to 65535; received ${JSON.stringify(raw)}`);
195
+ }
196
+ return port;
197
+ }
108
198
  main().then((code) => process.exit(code)).catch((err) => {
109
199
  console.error("[agent-eval] cli error:", err);
110
200
  process.exit(1);
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * agent-eval CLI.\n *\n * agent-eval serve [--port 5005] [--host 127.0.0.1]\n * agent-eval rpc <method> # one request from stdin → one response on stdout\n * agent-eval rpc-batch <method> # JSONL stdin → JSONL stdout\n * agent-eval openapi [--out path] # write OpenAPI spec\n * agent-eval version\n *\n * <method> is one of: judge, listRubrics, version. When omitted, the\n * stdin payload must be a full {method, params} envelope.\n */\nimport { writeFileSync } from 'node:fs'\nimport { handleVersion } from './wire/handlers'\nimport { buildOpenApi } from './wire/openapi'\nimport { runRpcBatch, runRpcOnce } from './wire/rpc'\nimport { startServer } from './wire/server'\n\ninterface Args {\n command: string\n positional: string[]\n flags: Record<string, string>\n}\n\nfunction parseArgs(argv: string[]): Args {\n const [command, ...rest] = argv\n const positional: string[] = []\n const flags: Record<string, string> = {}\n for (let i = 0; i < rest.length; i++) {\n const tok = rest[i]!\n if (tok.startsWith('--')) {\n const key = tok.slice(2)\n const next = rest[i + 1]\n if (next != null && !next.startsWith('--')) {\n flags[key] = next\n i++\n } else {\n flags[key] = 'true'\n }\n } else {\n positional.push(tok)\n }\n }\n return { command: command ?? 'help', positional, flags }\n}\n\nconst HELP = `agent-eval — wire-protocol entry point.\n\nCommands:\n serve [--port 5005] [--host 127.0.0.1]\n Start the HTTP server. POST /v1/judge, GET /v1/rubrics, GET /v1/version, GET /openapi.json.\n rpc <method>\n Read one JSON object from stdin (the params for <method>), write one\n JSON object to stdout. Method ∈ {judge, listRubrics, version}.\n rpc-batch <method>\n Like 'rpc' but JSONL in / JSONL out.\n openapi [--out openapi.json]\n Write the OpenAPI 3.1 spec.\n version\n Print server + wire-protocol version JSON.\n\nWithout arguments, prints this help.`\n\nasync function main(): Promise<number> {\n const { command, positional, flags } = parseArgs(process.argv.slice(2))\n\n switch (command) {\n case 'serve': {\n const port = Number(flags.port ?? 5005)\n const host = flags.host ?? '127.0.0.1'\n const server = startServer({ port, host })\n // Keep process alive on SIGINT/SIGTERM\n const shutdown = (sig: string) => {\n // eslint-disable-next-line no-console\n console.log(`[agent-eval] received ${sig}, shutting down`)\n server.close(() => process.exit(0))\n // Force exit after 5s if close hangs\n setTimeout(() => process.exit(1), 5000).unref()\n }\n process.on('SIGINT', () => shutdown('SIGINT'))\n process.on('SIGTERM', () => shutdown('SIGTERM'))\n // Block forever\n await new Promise(() => {})\n return 0\n }\n case 'rpc': {\n const [method] = positional\n return await runRpcOnce(method)\n }\n case 'rpc-batch': {\n const [method] = positional\n return await runRpcBatch(method)\n }\n case 'openapi': {\n const out = flags.out ?? 'openapi.json'\n const spec = buildOpenApi(handleVersion().version)\n writeFileSync(out, `${JSON.stringify(spec, null, 2)}\\n`, 'utf-8')\n // eslint-disable-next-line no-console\n console.log(`[agent-eval] wrote OpenAPI 3.1 spec to ${out}`)\n return 0\n }\n case 'version': {\n process.stdout.write(`${JSON.stringify(handleVersion(), null, 2)}\\n`)\n return 0\n }\n case 'help':\n case '--help':\n case '-h':\n case '':\n process.stdout.write(`${HELP}\\n`)\n return 0\n default:\n process.stderr.write(`unknown command: ${command}\\n${HELP}\\n`)\n return 1\n }\n}\n\nmain()\n .then((code) => process.exit(code))\n .catch((err) => {\n // eslint-disable-next-line no-console\n console.error('[agent-eval] cli error:', err)\n process.exit(1)\n })\n"],"mappings":";;;;;;;;;;;;;;;;AAaA,SAAS,qBAAqB;AAY9B,SAAS,UAAU,MAAsB;AACvC,QAAM,CAAC,SAAS,GAAG,IAAI,IAAI;AAC3B,QAAM,aAAuB,CAAC;AAC9B,QAAM,QAAgC,CAAC;AACvC,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,UAAM,MAAM,KAAK,CAAC;AAClB,QAAI,IAAI,WAAW,IAAI,GAAG;AACxB,YAAM,MAAM,IAAI,MAAM,CAAC;AACvB,YAAM,OAAO,KAAK,IAAI,CAAC;AACvB,UAAI,QAAQ,QAAQ,CAAC,KAAK,WAAW,IAAI,GAAG;AAC1C,cAAM,GAAG,IAAI;AACb;AAAA,MACF,OAAO;AACL,cAAM,GAAG,IAAI;AAAA,MACf;AAAA,IACF,OAAO;AACL,iBAAW,KAAK,GAAG;AAAA,IACrB;AAAA,EACF;AACA,SAAO,EAAE,SAAS,WAAW,QAAQ,YAAY,MAAM;AACzD;AAEA,IAAM,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiBb,eAAe,OAAwB;AACrC,QAAM,EAAE,SAAS,YAAY,MAAM,IAAI,UAAU,QAAQ,KAAK,MAAM,CAAC,CAAC;AAEtE,UAAQ,SAAS;AAAA,IACf,KAAK,SAAS;AACZ,YAAM,OAAO,OAAO,MAAM,QAAQ,IAAI;AACtC,YAAM,OAAO,MAAM,QAAQ;AAC3B,YAAM,SAAS,YAAY,EAAE,MAAM,KAAK,CAAC;AAEzC,YAAM,WAAW,CAAC,QAAgB;AAEhC,gBAAQ,IAAI,yBAAyB,GAAG,iBAAiB;AACzD,eAAO,MAAM,MAAM,QAAQ,KAAK,CAAC,CAAC;AAElC,mBAAW,MAAM,QAAQ,KAAK,CAAC,GAAG,GAAI,EAAE,MAAM;AAAA,MAChD;AACA,cAAQ,GAAG,UAAU,MAAM,SAAS,QAAQ,CAAC;AAC7C,cAAQ,GAAG,WAAW,MAAM,SAAS,SAAS,CAAC;AAE/C,YAAM,IAAI,QAAQ,MAAM;AAAA,MAAC,CAAC;AAC1B,aAAO;AAAA,IACT;AAAA,IACA,KAAK,OAAO;AACV,YAAM,CAAC,MAAM,IAAI;AACjB,aAAO,MAAM,WAAW,MAAM;AAAA,IAChC;AAAA,IACA,KAAK,aAAa;AAChB,YAAM,CAAC,MAAM,IAAI;AACjB,aAAO,MAAM,YAAY,MAAM;AAAA,IACjC;AAAA,IACA,KAAK,WAAW;AACd,YAAM,MAAM,MAAM,OAAO;AACzB,YAAM,OAAO,aAAa,cAAc,EAAE,OAAO;AACjD,oBAAc,KAAK,GAAG,KAAK,UAAU,MAAM,MAAM,CAAC,CAAC;AAAA,GAAM,OAAO;AAEhE,cAAQ,IAAI,0CAA0C,GAAG,EAAE;AAC3D,aAAO;AAAA,IACT;AAAA,IACA,KAAK,WAAW;AACd,cAAQ,OAAO,MAAM,GAAG,KAAK,UAAU,cAAc,GAAG,MAAM,CAAC,CAAC;AAAA,CAAI;AACpE,aAAO;AAAA,IACT;AAAA,IACA,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,cAAQ,OAAO,MAAM,GAAG,IAAI;AAAA,CAAI;AAChC,aAAO;AAAA,IACT;AACE,cAAQ,OAAO,MAAM,oBAAoB,OAAO;AAAA,EAAK,IAAI;AAAA,CAAI;AAC7D,aAAO;AAAA,EACX;AACF;AAEA,KAAK,EACF,KAAK,CAAC,SAAS,QAAQ,KAAK,IAAI,CAAC,EACjC,MAAM,CAAC,QAAQ;AAEd,UAAQ,MAAM,2BAA2B,GAAG;AAC5C,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":[]}
1
+ {"version":3,"sources":["../src/cli.ts","../src/cli-config.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * agent-eval CLI.\n *\n * agent-eval serve [--port 5005] [--host 127.0.0.1]\n * agent-eval rpc <method> # one request from stdin → one response on stdout\n * agent-eval rpc-batch <method> # JSONL stdin → JSONL stdout\n * agent-eval openapi [--out path] # write OpenAPI spec\n * agent-eval version\n *\n * <method> is one of: judge, listRubrics, version. When omitted, the\n * stdin payload must be a full {method, params} envelope.\n */\nimport { writeFileSync } from 'node:fs'\nimport { resolveCliLlmConfig } from './cli-config'\nimport { handleVersion } from './wire/handlers'\nimport { buildOpenApi } from './wire/openapi'\nimport { runRpcBatch, runRpcOnce } from './wire/rpc'\nimport { startServerAsync } from './wire/server'\n\ninterface Args {\n command: string\n positional: string[]\n flags: Record<string, string>\n}\n\nfunction parseArgs(argv: string[]): Args {\n const [command, ...rest] = argv\n const positional: string[] = []\n const flags: Record<string, string> = {}\n for (let i = 0; i < rest.length; i++) {\n const tok = rest[i]!\n if (tok.startsWith('--')) {\n const raw = tok.slice(2)\n const equalsAt = raw.indexOf('=')\n if (equalsAt >= 0) {\n flags[raw.slice(0, equalsAt)] = raw.slice(equalsAt + 1)\n continue\n }\n const key = raw\n if (key === 'help') {\n flags[key] = 'true'\n continue\n }\n const next = rest[i + 1]\n if (next != null && !next.startsWith('--')) {\n flags[key] = next\n i++\n } else {\n flags[key] = 'true'\n }\n } else if (tok === '-h') {\n flags.help = 'true'\n } else {\n positional.push(tok)\n }\n }\n return { command: command ?? 'help', positional, flags }\n}\n\nconst HELP = `agent-eval: evaluation RPC and HTTP server.\n\nCommands:\n serve [--port 5005] [--host 127.0.0.1]\n Start the HTTP server. POST /v1/judge, GET /v1/rubrics, GET /v1/version, GET /openapi.json.\n rpc <method>\n Read one JSON object from stdin (the params for <method>), write one\n JSON object to stdout. Methods: judge, listRubrics, version.\n rpc-batch <method>\n Like 'rpc' but JSONL in / JSONL out.\n openapi [--out openapi.json]\n Write the OpenAPI 3.1 spec.\n version\n Print server + wire-protocol version JSON.\n\nJudge provider:\n Set AGENT_EVAL_LLM_BASE_URL, AGENT_EVAL_LLM_API_KEY, and AGENT_EVAL_LLM_MODEL.\n OPENAI_* and TANGLE_* equivalents are also accepted.\n\nWithout arguments, prints this help.`\n\nasync function main(): Promise<number> {\n const { command, positional, flags } = parseArgs(process.argv.slice(2))\n assertKnownFlags(command, flags)\n\n if (flags.help === 'true') {\n process.stdout.write(`${HELP}\\n`)\n return 0\n }\n\n switch (command) {\n case 'serve': {\n const port = parsePort(flags.port ?? '5005')\n const host = flags.host ?? '127.0.0.1'\n const llm = resolveCliLlmConfig()\n const { server } = await startServerAsync({\n port,\n host,\n llm: llm.client,\n judgeModel: llm.model,\n llmRouteRequirements: { requireExplicitBaseUrl: true },\n })\n // Keep process alive on SIGINT/SIGTERM\n const shutdown = (sig: string) => {\n // eslint-disable-next-line no-console\n console.log(`[agent-eval] received ${sig}, shutting down`)\n server.close(() => process.exit(0))\n // Force exit after 5s if close hangs\n setTimeout(() => process.exit(1), 5000).unref()\n }\n process.on('SIGINT', () => shutdown('SIGINT'))\n process.on('SIGTERM', () => shutdown('SIGTERM'))\n // Block forever\n await new Promise(() => {})\n return 0\n }\n case 'rpc': {\n const [method] = positional\n const llm = resolveCliLlmConfig()\n return await runRpcOnce(method, {\n llm: llm.client,\n judgeModel: llm.model,\n llmRouteRequirements: { requireExplicitBaseUrl: true },\n })\n }\n case 'rpc-batch': {\n const [method] = positional\n const llm = resolveCliLlmConfig()\n return await runRpcBatch(method, {\n llm: llm.client,\n judgeModel: llm.model,\n llmRouteRequirements: { requireExplicitBaseUrl: true },\n })\n }\n case 'openapi': {\n const out = flags.out ?? 'openapi.json'\n const spec = buildOpenApi(handleVersion().version)\n writeFileSync(out, `${JSON.stringify(spec, null, 2)}\\n`, 'utf-8')\n // eslint-disable-next-line no-console\n console.log(`[agent-eval] wrote OpenAPI 3.1 spec to ${out}`)\n return 0\n }\n case 'version': {\n process.stdout.write(`${JSON.stringify(handleVersion(), null, 2)}\\n`)\n return 0\n }\n case '--version': {\n process.stdout.write(`${handleVersion().version}\\n`)\n return 0\n }\n case 'help':\n case '--help':\n case '-h':\n case '':\n process.stdout.write(`${HELP}\\n`)\n return 0\n default:\n process.stderr.write(`unknown command: ${command}\\n${HELP}\\n`)\n return 1\n }\n}\n\nconst FLAGS_BY_COMMAND: Record<string, ReadonlySet<string>> = {\n serve: new Set(['help', 'host', 'port']),\n rpc: new Set(['help']),\n 'rpc-batch': new Set(['help']),\n openapi: new Set(['help', 'out']),\n version: new Set(['help']),\n help: new Set(),\n '--help': new Set(),\n '-h': new Set(),\n '--version': new Set(),\n '': new Set(),\n}\n\nfunction assertKnownFlags(command: string, flags: Record<string, string>): void {\n const allowed = FLAGS_BY_COMMAND[command]\n if (!allowed) return\n const unknown = Object.keys(flags).filter((flag) => !allowed.has(flag))\n if (unknown.length > 0) {\n throw new Error(`unknown flag for ${command || 'help'}: --${unknown[0]}`)\n }\n}\n\nfunction parsePort(raw: string): number {\n const port = Number(raw)\n if (!Number.isInteger(port) || port < 0 || port > 65_535) {\n throw new Error(`--port must be an integer from 0 to 65535; received ${JSON.stringify(raw)}`)\n }\n return port\n}\n\nmain()\n .then((code) => process.exit(code))\n .catch((err) => {\n // eslint-disable-next-line no-console\n console.error('[agent-eval] cli error:', err)\n process.exit(1)\n })\n","import type { LlmClientOptions } from './llm-client'\n\nexport interface CliLlmConfig {\n client?: LlmClientOptions\n model?: string\n}\n\nexport function resolveCliLlmConfig(env: NodeJS.ProcessEnv = process.env): CliLlmConfig {\n const explicitBaseUrl = nonEmpty(env.AGENT_EVAL_LLM_BASE_URL)\n const explicitApiKey = nonEmpty(env.AGENT_EVAL_LLM_API_KEY)\n const openAiApiKey = nonEmpty(env.OPENAI_API_KEY)\n const tangleApiKey = nonEmpty(env.TANGLE_API_KEY)\n const baseUrl =\n explicitBaseUrl ??\n nonEmpty(env.OPENAI_BASE_URL) ??\n nonEmpty(env.TANGLE_ROUTER_URL) ??\n (openAiApiKey ? 'https://api.openai.com/v1' : undefined) ??\n (tangleApiKey ? 'https://router.tangle.tools/v1' : undefined)\n const apiKey = explicitApiKey ?? openAiApiKey ?? tangleApiKey\n const model =\n nonEmpty(env.AGENT_EVAL_LLM_MODEL) ?? nonEmpty(env.OPENAI_MODEL) ?? nonEmpty(env.TANGLE_MODEL)\n\n const client =\n baseUrl || apiKey\n ? { ...(baseUrl ? { baseUrl } : {}), ...(apiKey ? { apiKey } : {}) }\n : undefined\n return { ...(client ? { client } : {}), ...(model ? { model } : {}) }\n}\n\nfunction nonEmpty(value: string | undefined): string | undefined {\n const trimmed = value?.trim()\n return trimmed ? trimmed : undefined\n}\n"],"mappings":"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","names":[]}
@@ -1,11 +1,12 @@
1
+ import { z } from 'zod';
1
2
  import { AgentCandidateExperiment, AgentCandidateBundle, AgentCandidateBenchmarkTask, AgentCandidateBenchmarkCellRef, AgentCandidateExperimentMeasurement, AgentImprovementMeasuredComparison, CandidateExecutionEvidence, AgentCandidateBenchmarkSuiteInputs, AgentCandidateBenchmarkTaskMaterial, AgentCandidateExperimentMaterial } from '@tangle-network/agent-interface';
2
3
  import { AxFunction, AxAIService } from '@ax-llm/ax';
3
- import { z } from 'zod';
4
4
 
5
5
  type AgentProfileCellSchemaVersion = 'agent-profile-cell/v1';
6
- type AgentProfileJson = string | number | boolean | null | AgentProfileJson[] | {
6
+ type AgentProfileJsonObject = {
7
7
  [key: string]: AgentProfileJson;
8
8
  };
9
+ type AgentProfileJson = string | number | boolean | null | AgentProfileJson[] | AgentProfileJsonObject;
9
10
  type AgentProfileDimensionValue = string | number | boolean | null;
10
11
  interface AgentProfileSource {
11
12
  /** Runtime/profile contract being fingerprinted, e.g. `agent-interface-profile`. */
@@ -75,9 +76,16 @@ interface CostReceiptInput extends CostUsage {
75
76
  costUnknown?: boolean;
76
77
  usageUnknown?: boolean;
77
78
  }
79
+ /** Per-million token rates for a model or endpoint not covered by package pricing. */
80
+ interface CustomTokenPricing {
81
+ inputUsdPerMillion: number;
82
+ outputUsdPerMillion: number;
83
+ }
78
84
  type MaximumCharge = {
79
85
  externallyEnforcedMaximumUsd: number;
80
86
  } | ({
87
+ customTokenPricing: CustomTokenPricing;
88
+ } & Pick<CostUsage, 'inputTokens' | 'outputTokens'>) | ({
81
89
  model: string;
82
90
  } & CostUsage);
83
91
  interface RunPaidCallInput<T> {
@@ -89,7 +97,7 @@ interface RunPaidCallInput<T> {
89
97
  model?: string;
90
98
  tags?: Record<string, string>;
91
99
  signal?: AbortSignal;
92
- /** Provider-enforced dollar maximum, or maximum priced token usage. Required when capped. */
100
+ /** Provider-enforced dollar maximum, or maximum token usage with known pricing. Required when capped. */
93
101
  maximumCharge?: MaximumCharge;
94
102
  /** `callId` can be forwarded as the provider's idempotency key. */
95
103
  execute(signal: AbortSignal, callId: string): Promise<T>;
@@ -859,8 +867,8 @@ interface LlmCallResult {
859
867
  content: string;
860
868
  usage: LlmUsage;
861
869
  /**
862
- * Cost in USD. Pulled from proxy's `_response_cost` field when present;
863
- * `null` when neither the proxy nor the caller can derive it.
870
+ * Cost in USD. Uses the provider's reported cost when present, otherwise
871
+ * caller-supplied token pricing. `null` when neither is available.
864
872
  */
865
873
  costUsd: number | null;
866
874
  /** Model name actually used (echoed from response). */
@@ -919,6 +927,21 @@ interface LlmClientOptions {
919
927
  deadlineMs?: number;
920
928
  /** Total provider attempts. Legacy option name; default 3 (1 initial + 2 retries). */
921
929
  maxRetries?: number;
930
+ /** Token rates used when the provider omits cost or package pricing does not cover the model. */
931
+ customTokenPricing?: CustomTokenPricing;
932
+ /**
933
+ * Transport for requests that declare `jsonSchema`. `native` sends
934
+ * `response_format: json_schema`; `json-object` sends the broadly supported
935
+ * JSON mode and relies on the caller to include the schema in model-visible
936
+ * instructions. Default: `native`.
937
+ */
938
+ jsonSchemaTransport?: 'native' | 'json-object';
939
+ /**
940
+ * JSON payload parsing policy. `extract` accepts fenced or prose-prefixed JSON.
941
+ * `exact` requires the complete response content to be one JSON value.
942
+ * Default: `extract`.
943
+ */
944
+ jsonPayloadMode?: 'extract' | 'exact';
922
945
  /** Fetch implementation — defaults to global `fetch`. Override for custom transport (e.g. tests). */
923
946
  fetch?: typeof fetch;
924
947
  /**
@@ -2438,6 +2461,84 @@ interface RunImprovementLoopResult<TArtifact, TScenario extends Scenario> extend
2438
2461
  */
2439
2462
  declare function runImprovementLoop<TScenario extends Scenario, TArtifact>(opts: RunImprovementLoopOptions<TScenario, TArtifact>): Promise<RunImprovementLoopResult<TArtifact, TScenario>>;
2440
2463
 
2464
+ /**
2465
+ * `llmJudge` — the single-LLM-call bridge that turns a rubric prompt into a
2466
+ * canonical campaign `JudgeConfig`.
2467
+ *
2468
+ * The `JudgeConfig` contract (src/campaign/types.ts) is deliberately a
2469
+ * function, not a fixed LLM-prompt shape: real consumers judge with
2470
+ * ensembles, deterministic checks, or one LLM call. `ensembleJudge`
2471
+ * (src/judge-panel.ts) covers the multi-model case; `buildAgreementJudge`
2472
+ * (src/campaign/distillation) covers the pure-comparator case. `llmJudge`
2473
+ * covers the common single-call case the `JudgeConfig` doc-comment names:
2474
+ * one model call against `prompt`, parsed into the canonical `JudgeScore`
2475
+ * (`{ dimensions, composite, notes }`) on the campaign [0,1] scale.
2476
+ *
2477
+ * Transport is injected as a `ChatClient` (src/analyst/chat-client.ts) — the
2478
+ * substrate's transport-agnostic LLM seam — so the judge stays decoupled from
2479
+ * router-vs-sandbox-vs-cli-bridge and is unit-testable with the `mock`
2480
+ * transport. The composite is computed by `weightedComposite` (the same
2481
+ * sum-normalized weighting `ensembleJudge` uses), so a lift is attributable to
2482
+ * the dimension scores, not to a bespoke reducer.
2483
+ *
2484
+ * Fail-loud throughout: an unparseable model response throws `JudgeParseError`;
2485
+ * a response missing a declared dimension throws; an out-of-range score throws.
2486
+ * A thrown judge is recorded by the campaign engine as a failed cell, never
2487
+ * folded into a silent zero.
2488
+ */
2489
+
2490
+ /** A rubric dimension as a bare key or the full `{ key, description }` shape. A
2491
+ * bare string uses the key as its own description. */
2492
+ type LlmJudgeDimension = string | JudgeDimension;
2493
+ interface LlmJudgeOptions<TArtifact, TScenario extends Scenario = Scenario> {
2494
+ /** The injected LLM transport. One `chat()` call per `score()`. Required —
2495
+ * there is no default route, so a misconfigured judge fails at construction,
2496
+ * never silently against the free-tier router. */
2497
+ chat: ChatClient;
2498
+ /** Rubric dimensions the model scores. Each becomes a `[0,1]` field of the
2499
+ * returned `JudgeScore.dimensions`. Defaults to a single `quality` dimension. */
2500
+ dimensions?: LlmJudgeDimension[];
2501
+ /** Model id. Falls back to `chat.defaultModel`; one of the two MUST resolve. */
2502
+ model?: string;
2503
+ /** Explicit scoring revision for opaque transport or renderer changes. */
2504
+ judgeVersion?: string;
2505
+ temperature?: number;
2506
+ maxTokens?: number;
2507
+ /** Composite weights forwarded to `weightedComposite`: a partial map selects
2508
+ * AND weights exactly the named dimensions. Omit for a uniform mean. */
2509
+ weights?: Record<string, number>;
2510
+ /** Scale the model is prompted to score on, normalized into `[0,1]`:
2511
+ * - `'unit'` (default): the model returns `[0,1]` directly.
2512
+ * - `'ten'`: the model returns `[0,10]`; divided by 10 here.
2513
+ * The prompt is annotated with the expected range either way. */
2514
+ scale?: 'unit' | 'ten';
2515
+ /** Run this judge only on matching scenarios (mirrors `JudgeConfig.appliesTo`). */
2516
+ appliesTo?: (scenario: TScenario) => boolean;
2517
+ /** Render the artifact + scenario into the user message. Default:
2518
+ * pretty-printed JSON of `{ scenario, artifact }`. */
2519
+ renderUser?: (input: {
2520
+ artifact: TArtifact;
2521
+ scenario: TScenario;
2522
+ }) => string;
2523
+ /** Strict runtime contract; its JSON Schema is sent to the provider. */
2524
+ costLedger?: CostLedgerHandle;
2525
+ responseSchema?: {
2526
+ name: string;
2527
+ schema: z.ZodObject;
2528
+ };
2529
+ }
2530
+ /**
2531
+ * Build a campaign-shaped `JudgeConfig` whose `score()` makes ONE LLM call
2532
+ * against `prompt` and reduces the model's per-dimension scores to a canonical
2533
+ * `JudgeScore` in `[0,1]`.
2534
+ *
2535
+ * The model is instructed to return JSON `{ "dimensions": { <key>: <number>, … },
2536
+ * "notes": "…" }`; the helper strips fenced JSON, validates every declared
2537
+ * dimension is present and in range, normalizes by `scale`, and composites via
2538
+ * `weightedComposite`.
2539
+ */
2540
+ declare function llmJudge<TArtifact = unknown, TScenario extends Scenario = Scenario>(name: string, prompt: string, opts: LlmJudgeOptions<TArtifact, TScenario>): JudgeConfig<TArtifact, TScenario>;
2541
+
2441
2542
  declare const REFERENCE_EQUIVALENCE_JUDGE_VERSION = "reference-equivalence-judge-v1-2026-07-13";
2442
2543
  declare const REFERENCE_EQUIVALENCE_INPUT_LIMITS: {
2443
2544
  readonly userRequest: 8000;
@@ -3268,9 +3369,15 @@ interface InterRaterInsight {
3268
3369
  raters: number;
3269
3370
  /** Number of runs every rater scored. */
3270
3371
  jointlyRated: number;
3271
- /** Cohen's κ averaged across rater pairs. */
3372
+ /** Multi-rater weighted kappa over the jointly rated runs. */
3272
3373
  kappa: number;
3273
- /** Pairwise κ per rater pair (key = `"raterA::raterB"`). */
3374
+ /** Absolute agreement across raters, using ICC(2,1). */
3375
+ icc: number;
3376
+ /** Mean pairwise Pearson correlation. Correlation is not agreement. */
3377
+ pearson: number;
3378
+ /** Mean pairwise Spearman rank correlation. */
3379
+ spearman: number;
3380
+ /** Pairwise weighted kappa per rater pair (key = `"raterA::raterB"`). */
3274
3381
  perPair: Record<string, number>;
3275
3382
  /** Run ids where raters disagree the most — the high-value triage list. */
3276
3383
  disagreementCases: Array<{
@@ -5165,4 +5272,4 @@ interface FromOtelSpansOptions {
5165
5272
  }
5166
5273
  declare function fromOtelSpans(opts: FromOtelSpansOptions): RunRecord[];
5167
5274
 
5168
- export { type AgentEvalAgent, type AgentEvalEvaluateOptions, type AgentEvalImproveOptions, type AgentTraceContributor, type AgentTraceContributorType, type AgentTraceConversation, type AgentTraceFile, type AgentTraceIndex, type AgentTraceRange, type AgentTraceRecord, type AnalystFinding, type AnalyzeRunsOptions, type AuthoringProvenance, type AxisEvidence, type AxisVerdict, type BuildEvidenceVectorOptions, type CampaignAggregates, type CampaignArtifactWriter, type CampaignCellResult, type CampaignCostMeter, type CampaignResult, type CampaignStorage, type CampaignTraceWriter, type CandidateExperimentExecutionInput, type ChatClient, type CodeAgentSessionAction, type CodeAgentSessionActionKind, type CodeAgentSessionActionStatus, type CodeAgentSessionActionSurface, type CodeAgentSessionDiagnostic, type CodeAgentSessionExecutionReceipt, type CodeAgentSessionIntakeOptions, type CodeAgentSessionIntakeResult, type CodeAgentSessionMetrics, type CodeAgentSessionObservation, type CodeAgentSessionSource, type CodeAgentSessionTerminalStatus, type CodeSurface, type CompareCandidateExperimentOptions, type CostLedgerHandle, type CostProvenanceSummary, type CreateChatClientOpts, type DefaultAnalystRegistryOptions, type DefaultProductionGateOptions, type DefineAgentEvalOptions, type DefinedAgentEval, type DeploymentOutcome, type DispatchFn as Dispatch, type DispatchContext, type EvalCellScoreDelta, type EvalDimensionDelta, type EvalGenerationDiff, type EvalReportingSuiteInput, type EvalReportingSuiteOptions, type EvalReportingSuiteResult, type EvalRunDiff, type EvidenceVector, type EvolutionaryProposerOptions, type ExecutionInsight, type ExecutionReport, type FailureClusterInsight, type FeedbackTableMeta, type FeedbackTableRow, FileSystemOutcomeStore, type FileSystemOutcomeStoreOptions, type FromFeedbackTableOptions, type FromFeedbackTableResult, type FromOtelSpansOptions, type FromRunRecordDirOptions, type FromRunRecordDirResult, type Gate, type GateContext, type GateDecision, type GateResult, type GenerationCandidate, type GenerationRecord, type GepaProposerOptions, type HeldOutGateOptions, type HostedTenant, InMemoryOutcomeStore, type InsightReport, type InterRaterInsight, type JudgeConfig, type JudgeDimension, type JudgeInsight, type JudgeScore, type LiftInsight, type MutableSurface, type Mutator, type ObjectiveSource, type OptimizationProposer, type OptimizerConfig, type OutcomeCorrelationInsight, type OutcomeStore, type ParetoSignificanceGateOptions, type ParsedCodeAgentJsonl, type PartitionByAuthoringModelResult, type PromotionObjective, type PromotionPolicy, REFERENCE_EQUIVALENCE_INPUT_LIMITS, REFERENCE_EQUIVALENCE_JUDGE_VERSION, type Recommendation, type ReferenceEquivalenceJudgeInput, type ReferenceEquivalenceJudgeOptions, type ReferenceEquivalenceJudgeResult, type ReferenceEquivalenceScenario, type ReleaseSummary, type RunCampaignOptions, type RunCandidateExperimentOptions, type RunEvalOptions, type RunImprovementLoopOptions, type RunImprovementLoopResult, type RunRecordRejection, type ScalarDistribution, type Scenario, type SealCandidateBenchmarkSuiteOptions, type SelfImproveBudget, type SelfImproveLlm, type SelfImproveOptions, type SelfImproveProgressEvent, type SelfImproveResult, SelfImproveRunError, type SessionScript, type SummarizeExecutionOptions, type SurfaceProposer, type TokenUsageInsight, analyzeRuns, buildDefaultAnalystRegistry, buildEvidenceVector, campaignSplitDigest, composeGate, createChatClient, createReferenceEquivalenceJudge, defaultProductionGate, defineAgentEval, diffGenerations, diffRunBaselineToWinner, diffRuns, evalReportingSuite, evolutionaryProposer, fromClaudeCodeSession, fromCodexSession, fromFeedbackTable, fromKimiCodeSession, fromOpenCodeSession, fromOtelSpans, fromPiSession, fromPigraphSession, fromRunRecordDir, fsCampaignStorage, gepaProposer, heldOutGate, inMemoryCampaignStorage, measuredComparisonFromCandidateExperiment, observeCodeAgentSession, paretoPolicy, paretoSignificanceGate, parseAgentTrace, parseCodeAgentJsonl, partitionRunsByAuthoringModel, runCampaign, runCandidateExperiment, runEval, runImprovementLoop, runReferenceEquivalenceJudge, sealCandidateBenchmarkSuite, sealCandidateBenchmarkTask, sealCandidateExperiment, selfImprove, summarizeExecution, verifyCandidateBenchmarkSuite, verifyCandidateBenchmarkSuiteInputs, verifyCandidateBenchmarkTask, verifyCandidateExperiment, verifyCandidateExperimentComparison };
5275
+ export { type AgentEvalAgent, type AgentEvalEvaluateOptions, type AgentEvalImproveOptions, type AgentTraceContributor, type AgentTraceContributorType, type AgentTraceConversation, type AgentTraceFile, type AgentTraceIndex, type AgentTraceRange, type AgentTraceRecord, type AnalystFinding, type AnalyzeRunsOptions, type AuthoringProvenance, type AxisEvidence, type AxisVerdict, type BuildEvidenceVectorOptions, type CampaignAggregates, type CampaignArtifactWriter, type CampaignCellResult, type CampaignCostMeter, type CampaignResult, type CampaignStorage, type CampaignTraceWriter, type CandidateExperimentExecutionInput, type ChatClient, type CodeAgentSessionAction, type CodeAgentSessionActionKind, type CodeAgentSessionActionStatus, type CodeAgentSessionActionSurface, type CodeAgentSessionDiagnostic, type CodeAgentSessionExecutionReceipt, type CodeAgentSessionIntakeOptions, type CodeAgentSessionIntakeResult, type CodeAgentSessionMetrics, type CodeAgentSessionObservation, type CodeAgentSessionSource, type CodeAgentSessionTerminalStatus, type CodeSurface, type CompareCandidateExperimentOptions, type CostLedgerHandle, type CostProvenanceSummary, type CreateChatClientOpts, type DefaultAnalystRegistryOptions, type DefaultProductionGateOptions, type DefineAgentEvalOptions, type DefinedAgentEval, type DeploymentOutcome, type DispatchFn as Dispatch, type DispatchContext, type EvalCellScoreDelta, type EvalDimensionDelta, type EvalGenerationDiff, type EvalReportingSuiteInput, type EvalReportingSuiteOptions, type EvalReportingSuiteResult, type EvalRunDiff, type EvidenceVector, type EvolutionaryProposerOptions, type ExecutionInsight, type ExecutionReport, type FailureClusterInsight, type FeedbackTableMeta, type FeedbackTableRow, FileSystemOutcomeStore, type FileSystemOutcomeStoreOptions, type FromFeedbackTableOptions, type FromFeedbackTableResult, type FromOtelSpansOptions, type FromRunRecordDirOptions, type FromRunRecordDirResult, type Gate, type GateContext, type GateDecision, type GateResult, type GenerationCandidate, type GenerationRecord, type GepaProposerOptions, type HeldOutGateOptions, type HostedTenant, InMemoryOutcomeStore, type InsightReport, type InterRaterInsight, type JudgeConfig, type JudgeDimension, type JudgeInsight, type JudgeScore, type LiftInsight, type LlmJudgeDimension, type LlmJudgeOptions, type MutableSurface, type Mutator, type ObjectiveSource, type OptimizationProposer, type OptimizerConfig, type OutcomeCorrelationInsight, type OutcomeStore, type ParetoSignificanceGateOptions, type ParsedCodeAgentJsonl, type PartitionByAuthoringModelResult, type PromotionObjective, type PromotionPolicy, REFERENCE_EQUIVALENCE_INPUT_LIMITS, REFERENCE_EQUIVALENCE_JUDGE_VERSION, type Recommendation, type ReferenceEquivalenceJudgeInput, type ReferenceEquivalenceJudgeOptions, type ReferenceEquivalenceJudgeResult, type ReferenceEquivalenceScenario, type ReleaseSummary, type RunCampaignOptions, type RunCandidateExperimentOptions, type RunEvalOptions, type RunImprovementLoopOptions, type RunImprovementLoopResult, type RunRecordRejection, type ScalarDistribution, type Scenario, type SealCandidateBenchmarkSuiteOptions, type SelfImproveBudget, type SelfImproveLlm, type SelfImproveOptions, type SelfImproveProgressEvent, type SelfImproveResult, SelfImproveRunError, type SessionScript, type SummarizeExecutionOptions, type SurfaceProposer, type TokenUsageInsight, analyzeRuns, buildDefaultAnalystRegistry, buildEvidenceVector, campaignSplitDigest, composeGate, createChatClient, createReferenceEquivalenceJudge, defaultProductionGate, defineAgentEval, diffGenerations, diffRunBaselineToWinner, diffRuns, evalReportingSuite, evolutionaryProposer, fromClaudeCodeSession, fromCodexSession, fromFeedbackTable, fromKimiCodeSession, fromOpenCodeSession, fromOtelSpans, fromPiSession, fromPigraphSession, fromRunRecordDir, fsCampaignStorage, gepaProposer, heldOutGate, inMemoryCampaignStorage, llmJudge, measuredComparisonFromCandidateExperiment, observeCodeAgentSession, paretoPolicy, paretoSignificanceGate, parseAgentTrace, parseCodeAgentJsonl, partitionRunsByAuthoringModel, runCampaign, runCandidateExperiment, runEval, runImprovementLoop, runReferenceEquivalenceJudge, sealCandidateBenchmarkSuite, sealCandidateBenchmarkTask, sealCandidateExperiment, selfImprove, summarizeExecution, verifyCandidateBenchmarkSuite, verifyCandidateBenchmarkSuiteInputs, verifyCandidateBenchmarkTask, verifyCandidateExperiment, verifyCandidateExperimentComparison };
@@ -14,7 +14,7 @@ import {
14
14
  import {
15
15
  analyzeRuns,
16
16
  summarizeExecution
17
- } from "../chunk-6WX7CBAR.js";
17
+ } from "../chunk-SJT4OBVL.js";
18
18
  import {
19
19
  REFERENCE_EQUIVALENCE_INPUT_LIMITS,
20
20
  REFERENCE_EQUIVALENCE_JUDGE_VERSION,
@@ -27,6 +27,7 @@ import {
27
27
  gepaProposer,
28
28
  heldOutGate,
29
29
  heldoutSignificance,
30
+ llmJudge,
30
31
  loopProvenanceArgsFromResult,
31
32
  paretoPolicy,
32
33
  paretoSignificanceGate,
@@ -36,7 +37,7 @@ import {
36
37
  runReferenceEquivalenceJudge,
37
38
  surfaceContentHash,
38
39
  surfaceHash
39
- } from "../chunk-HZJF4IUO.js";
40
+ } from "../chunk-SUN7QLPB.js";
40
41
  import {
41
42
  campaignSplitDigest,
42
43
  createRunCostLedger,
@@ -44,24 +45,24 @@ import {
44
45
  inMemoryCampaignStorage,
45
46
  resolveRunDir,
46
47
  runCampaign
47
- } from "../chunk-3FCG7FBV.js";
48
+ } from "../chunk-D5JZ7UDZ.js";
48
49
  import {
49
50
  buildDefaultAnalystRegistry,
50
51
  createChatClient
51
- } from "../chunk-VJ7T5WIO.js";
52
+ } from "../chunk-WP3GEXKI.js";
52
53
  import "../chunk-HHWE3POT.js";
53
- import "../chunk-FC5NDO3E.js";
54
+ import "../chunk-MHPEGJHC.js";
54
55
  import {
55
56
  FileSystemOutcomeStore,
56
57
  InMemoryOutcomeStore
57
58
  } from "../chunk-3RF76KTD.js";
58
59
  import "../chunk-ARU2PZFM.js";
59
- import "../chunk-NJC7U437.js";
60
+ import "../chunk-MK3Q6GCL.js";
60
61
  import "../chunk-DPZAEKA6.js";
61
62
  import {
62
63
  pairedBootstrap
63
64
  } from "../chunk-PJQFMIOX.js";
64
- import "../chunk-BGVTIE2C.js";
65
+ import "../chunk-GRCDRKII.js";
65
66
  import "../chunk-VI2UW6B6.js";
66
67
  import {
67
68
  recordAggregateMeasurements,
@@ -74,9 +75,9 @@ import "../chunk-IR3KBHOY.js";
74
75
  import "../chunk-PC4UYEBM.js";
75
76
  import {
76
77
  parseRunRecordSafe
77
- } from "../chunk-S3UZOQ5Y.js";
78
+ } from "../chunk-LOW3U7JZ.js";
78
79
  import "../chunk-MA6HLL3S.js";
79
- import "../chunk-XJYR7XFV.js";
80
+ import "../chunk-GC4ATIKK.js";
80
81
  import "../chunk-VSMTAMNK.js";
81
82
  import "../chunk-ONWEPEDO.js";
82
83
  import {
@@ -1703,6 +1704,7 @@ export {
1703
1704
  gepaProposer,
1704
1705
  heldOutGate,
1705
1706
  inMemoryCampaignStorage,
1707
+ llmJudge,
1706
1708
  measuredComparisonFromCandidateExperiment,
1707
1709
  observeCodeAgentSession,
1708
1710
  paretoPolicy,