agentv 3.11.1 → 3.12.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 (126) hide show
  1. package/README.md +16 -12
  2. package/dist/{agentv-provider-MIDKLYIH-6LIYKQRP.js → agentv-provider-NFFLXG5M-TJAWCWCX.js} +1 -2
  3. package/dist/{chunk-V2S5CZU3.js → chunk-2ELQ6F3C.js} +916 -523
  4. package/dist/chunk-2ELQ6F3C.js.map +1 -0
  5. package/dist/{chunk-JK6V4KVD.js → chunk-NR7QVL75.js} +32 -24
  6. package/dist/chunk-NR7QVL75.js.map +1 -0
  7. package/dist/{chunk-OYD2NB55.js → chunk-UYBLUYHN.js} +104 -15
  8. package/dist/chunk-UYBLUYHN.js.map +1 -0
  9. package/dist/{chunk-CKMAM2GD.js → chunk-VLOFRXH4.js} +461 -196
  10. package/dist/chunk-VLOFRXH4.js.map +1 -0
  11. package/dist/{chunk-BAUNAXHT.js → chunk-XOSNETAV.js} +1 -1
  12. package/dist/cli.js +5 -6
  13. package/dist/cli.js.map +1 -1
  14. package/dist/{dist-VUPMLHIV.js → dist-L6R5HJ72.js} +4 -5
  15. package/dist/{esm-OJ2BXJK4-YKEI3Z7E.js → esm-5Q4BZALM-5REQWAUV.js} +2 -3
  16. package/dist/{esm-OJ2BXJK4-YKEI3Z7E.js.map → esm-5Q4BZALM-5REQWAUV.js.map} +1 -1
  17. package/dist/{esm-UYZ3HJBU.js → esm-CZAWIY6F.js} +2 -2
  18. package/dist/index.js +5 -6
  19. package/dist/{interactive-FZJANO4A.js → interactive-5X62YEEX.js} +5 -6
  20. package/dist/{interactive-FZJANO4A.js.map → interactive-5X62YEEX.js.map} +1 -1
  21. package/dist/{otlp-json-file-exporter-VN67MK3S-RQIM6EHY.js → otlp-json-file-exporter-77FDBRSY-EZAPHWP6.js} +1 -2
  22. package/dist/{simple-trace-file-exporter-XWZTIZR2-4JKATE5G.js → simple-trace-file-exporter-CRIO5HDZ-QYYT2QQT.js} +2 -3
  23. package/dist/{src-PXDA7QIS.js → src-ML4D2MC2.js} +2 -2
  24. package/dist/templates/.agentv/.env.example +23 -0
  25. package/dist/templates/.agentv/config.yaml +13 -4
  26. package/dist/templates/.agentv/targets.yaml +16 -0
  27. package/package.json +1 -1
  28. package/dist/chunk-2QFWRIYL.js +0 -186
  29. package/dist/chunk-2QFWRIYL.js.map +0 -1
  30. package/dist/chunk-2RMPO6LY.js +0 -747
  31. package/dist/chunk-2RMPO6LY.js.map +0 -1
  32. package/dist/chunk-3Q7WIXT4.js +0 -4846
  33. package/dist/chunk-3Q7WIXT4.js.map +0 -1
  34. package/dist/chunk-73O2DCJP.js +0 -1274
  35. package/dist/chunk-73O2DCJP.js.map +0 -1
  36. package/dist/chunk-AUKF3Y3W.js +0 -212
  37. package/dist/chunk-AUKF3Y3W.js.map +0 -1
  38. package/dist/chunk-BRH7SIDP.js +0 -133
  39. package/dist/chunk-BRH7SIDP.js.map +0 -1
  40. package/dist/chunk-BXM4I3BM.js +0 -526
  41. package/dist/chunk-BXM4I3BM.js.map +0 -1
  42. package/dist/chunk-CKMAM2GD.js.map +0 -1
  43. package/dist/chunk-FHTURHTY.js +0 -546
  44. package/dist/chunk-FHTURHTY.js.map +0 -1
  45. package/dist/chunk-GJFXQQWG.js +0 -21
  46. package/dist/chunk-GJFXQQWG.js.map +0 -1
  47. package/dist/chunk-HKMLG4KF.js +0 -38
  48. package/dist/chunk-HKMLG4KF.js.map +0 -1
  49. package/dist/chunk-JGU3PVA4.js +0 -133
  50. package/dist/chunk-JGU3PVA4.js.map +0 -1
  51. package/dist/chunk-JK6V4KVD.js.map +0 -1
  52. package/dist/chunk-LHU5FGVZ.js +0 -4804
  53. package/dist/chunk-LHU5FGVZ.js.map +0 -1
  54. package/dist/chunk-OL2WGI6E.js +0 -149
  55. package/dist/chunk-OL2WGI6E.js.map +0 -1
  56. package/dist/chunk-ONETZL6N.js +0 -15
  57. package/dist/chunk-ONETZL6N.js.map +0 -1
  58. package/dist/chunk-OYD2NB55.js.map +0 -1
  59. package/dist/chunk-QV4UGEN6.js +0 -320
  60. package/dist/chunk-QV4UGEN6.js.map +0 -1
  61. package/dist/chunk-QXLDKGF3.js +0 -46
  62. package/dist/chunk-QXLDKGF3.js.map +0 -1
  63. package/dist/chunk-U6VEM66A.js +0 -63
  64. package/dist/chunk-U6VEM66A.js.map +0 -1
  65. package/dist/chunk-UALXHIMX.js +0 -48
  66. package/dist/chunk-UALXHIMX.js.map +0 -1
  67. package/dist/chunk-UGXG73VF.js +0 -55
  68. package/dist/chunk-UGXG73VF.js.map +0 -1
  69. package/dist/chunk-UHP5KEDL.js +0 -38
  70. package/dist/chunk-UHP5KEDL.js.map +0 -1
  71. package/dist/chunk-V2S5CZU3.js.map +0 -1
  72. package/dist/chunk-WVSXFZWP.js +0 -204
  73. package/dist/chunk-WVSXFZWP.js.map +0 -1
  74. package/dist/chunk-XSUMCWKO.js +0 -30
  75. package/dist/chunk-XSUMCWKO.js.map +0 -1
  76. package/dist/chunk-XUO7ZEHU.js +0 -181
  77. package/dist/chunk-XUO7ZEHU.js.map +0 -1
  78. package/dist/chunk-YSGUX5JT.js +0 -1002
  79. package/dist/chunk-YSGUX5JT.js.map +0 -1
  80. package/dist/dist-3PCP5TNF-RYMVLILE.js +0 -25785
  81. package/dist/dist-3PCP5TNF-RYMVLILE.js.map +0 -1
  82. package/dist/dist-BOIN5LC5-T5UWUK43.js +0 -76113
  83. package/dist/dist-BOIN5LC5-T5UWUK43.js.map +0 -1
  84. package/dist/dist-LXPDQOBI-4V5J2WDS.js +0 -13
  85. package/dist/dist-LXPDQOBI-4V5J2WDS.js.map +0 -1
  86. package/dist/dist-es-4WSJUIYR-XKIX65IH.js +0 -69
  87. package/dist/dist-es-4WSJUIYR-XKIX65IH.js.map +0 -1
  88. package/dist/dist-es-7K7MKRME-CCMAZOQC.js +0 -355
  89. package/dist/dist-es-7K7MKRME-CCMAZOQC.js.map +0 -1
  90. package/dist/dist-es-B2RTOKRI-VWZHK5RE.js +0 -191
  91. package/dist/dist-es-B2RTOKRI-VWZHK5RE.js.map +0 -1
  92. package/dist/dist-es-HHZ4FAXA-CRERHWKB.js +0 -164
  93. package/dist/dist-es-HHZ4FAXA-CRERHWKB.js.map +0 -1
  94. package/dist/dist-es-HVS3RPMX-AYJ3DW4L.js +0 -355
  95. package/dist/dist-es-HVS3RPMX-AYJ3DW4L.js.map +0 -1
  96. package/dist/dist-es-L6R4FPI5-IKIRYN45.js +0 -472
  97. package/dist/dist-es-L6R4FPI5-IKIRYN45.js.map +0 -1
  98. package/dist/dist-es-SRVEB5QV-Q4CTC2HX.js +0 -24
  99. package/dist/dist-es-TRIVUKV4-2J47CDXR.js +0 -85
  100. package/dist/dist-es-TRIVUKV4-2J47CDXR.js.map +0 -1
  101. package/dist/dist-es-UEEUAV34-IZQDTAMW.js +0 -16
  102. package/dist/event-streams-NZADSH5J-6MOSNEV3.js +0 -247
  103. package/dist/event-streams-NZADSH5J-6MOSNEV3.js.map +0 -1
  104. package/dist/loadSso-IQZ5NB6C-DZJTORO3.js +0 -738
  105. package/dist/loadSso-IQZ5NB6C-DZJTORO3.js.map +0 -1
  106. package/dist/multipart-parser-IPYBIGNL-LFMNMM6D.js +0 -387
  107. package/dist/multipart-parser-IPYBIGNL-LFMNMM6D.js.map +0 -1
  108. package/dist/otlp-json-file-exporter-VN67MK3S-RQIM6EHY.js.map +0 -1
  109. package/dist/signin-2ANR4DVS-K5VGBEJF.js +0 -556
  110. package/dist/signin-2ANR4DVS-K5VGBEJF.js.map +0 -1
  111. package/dist/simple-trace-file-exporter-XWZTIZR2-4JKATE5G.js.map +0 -1
  112. package/dist/src-SLOMUG7K-CV5JG263.js +0 -1408
  113. package/dist/src-SLOMUG7K-CV5JG263.js.map +0 -1
  114. package/dist/sso-oidc-HVCDATR2-CYP3BM5O.js +0 -708
  115. package/dist/sso-oidc-HVCDATR2-CYP3BM5O.js.map +0 -1
  116. package/dist/sts-X7JGSP4H-PDAAYDDH.js +0 -2917
  117. package/dist/sts-X7JGSP4H-PDAAYDDH.js.map +0 -1
  118. package/dist/undici-VAR2VUJI-6PAOUXZC.js +0 -23388
  119. package/dist/undici-VAR2VUJI-6PAOUXZC.js.map +0 -1
  120. /package/dist/{agentv-provider-MIDKLYIH-6LIYKQRP.js.map → agentv-provider-NFFLXG5M-TJAWCWCX.js.map} +0 -0
  121. /package/dist/{chunk-BAUNAXHT.js.map → chunk-XOSNETAV.js.map} +0 -0
  122. /package/dist/{dist-VUPMLHIV.js.map → dist-L6R5HJ72.js.map} +0 -0
  123. /package/dist/{dist-es-SRVEB5QV-Q4CTC2HX.js.map → esm-CZAWIY6F.js.map} +0 -0
  124. /package/dist/{dist-es-UEEUAV34-IZQDTAMW.js.map → otlp-json-file-exporter-77FDBRSY-EZAPHWP6.js.map} +0 -0
  125. /package/dist/{esm-UYZ3HJBU.js.map → simple-trace-file-exporter-CRIO5HDZ-QYYT2QQT.js.map} +0 -0
  126. /package/dist/{src-PXDA7QIS.js.map → src-ML4D2MC2.js.map} +0 -0
@@ -1,6 +1,6 @@
1
1
  import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
2
2
 
3
- // ../../packages/core/dist/chunk-HMXZ2AX4.js
3
+ // ../../packages/core/dist/chunk-3G2KXH7N.js
4
4
  import { createWriteStream } from "node:fs";
5
5
  import { mkdir } from "node:fs/promises";
6
6
  import { dirname } from "node:path";
@@ -10,6 +10,7 @@ var SimpleTraceFileExporter = class {
10
10
  streamReady = null;
11
11
  pendingWrites = [];
12
12
  _shuttingDown = false;
13
+ spansByTraceId = /* @__PURE__ */ new Map();
13
14
  constructor(filePath) {
14
15
  this.filePath = filePath;
15
16
  }
@@ -28,25 +29,27 @@ var SimpleTraceFileExporter = class {
28
29
  resultCallback({ code: 0 });
29
30
  return;
30
31
  }
31
- const spanMap = /* @__PURE__ */ new Map();
32
- const childMap = /* @__PURE__ */ new Map();
32
+ const rootSpans = [];
33
33
  for (const span of spans) {
34
- spanMap.set(span.spanContext().spanId, span);
35
- const parentId = span.parentSpanId;
36
- if (parentId) {
37
- if (!childMap.has(parentId)) childMap.set(parentId, []);
38
- childMap.get(parentId)?.push(span);
34
+ const traceId = span.spanContext().traceId;
35
+ const existing = this.spansByTraceId.get(traceId) ?? [];
36
+ existing.push(span);
37
+ this.spansByTraceId.set(traceId, existing);
38
+ if (span.name === "agentv.eval") {
39
+ rootSpans.push(span);
39
40
  }
40
41
  }
41
- const rootSpans = spans.filter(
42
- (s) => !s.parentSpanId || !spanMap.has(s.parentSpanId)
43
- );
44
42
  const writePromise = this.ensureStream().then((stream) => {
45
43
  for (const root of rootSpans) {
46
- const children = this.collectChildren(root.spanContext().spanId, childMap);
44
+ const traceId = root.spanContext().traceId;
45
+ const traceSpans = this.spansByTraceId.get(traceId) ?? [root];
46
+ const children = traceSpans.filter(
47
+ (span) => span.spanContext().spanId !== root.spanContext().spanId
48
+ );
47
49
  const record = this.buildSimpleRecord(root, children);
48
50
  stream.write(`${JSON.stringify(record)}
49
51
  `);
52
+ this.spansByTraceId.delete(traceId);
50
53
  }
51
54
  });
52
55
  this.pendingWrites.push(writePromise);
@@ -56,6 +59,7 @@ var SimpleTraceFileExporter = class {
56
59
  this._shuttingDown = true;
57
60
  await Promise.all(this.pendingWrites);
58
61
  this.pendingWrites = [];
62
+ this.spansByTraceId.clear();
59
63
  return new Promise((resolve) => {
60
64
  if (this.stream) {
61
65
  this.stream.end(() => resolve());
@@ -68,17 +72,9 @@ var SimpleTraceFileExporter = class {
68
72
  await Promise.all(this.pendingWrites);
69
73
  this.pendingWrites = [];
70
74
  }
71
- collectChildren(spanId, childMap) {
72
- const direct = childMap.get(spanId) || [];
73
- const all = [...direct];
74
- for (const child of direct) {
75
- all.push(...this.collectChildren(child.spanContext().spanId, childMap));
76
- }
77
- return all;
78
- }
79
75
  buildSimpleRecord(root, children) {
80
76
  const attrs = root.attributes || {};
81
- const durationMs = hrTimeDiffMs(root.startTime, root.endTime);
77
+ const durationMs = typeof attrs["agentv.trace.duration_ms"] === "number" ? attrs["agentv.trace.duration_ms"] : hrTimeDiffMs(root.startTime, root.endTime);
82
78
  let inputTokens = 0;
83
79
  let outputTokens = 0;
84
80
  for (const child of children) {
@@ -86,6 +82,14 @@ var SimpleTraceFileExporter = class {
86
82
  if (ca["gen_ai.usage.input_tokens"]) inputTokens += ca["gen_ai.usage.input_tokens"];
87
83
  if (ca["gen_ai.usage.output_tokens"]) outputTokens += ca["gen_ai.usage.output_tokens"];
88
84
  }
85
+ const rootInputTokens = typeof attrs["agentv.trace.token_input"] === "number" ? attrs["agentv.trace.token_input"] : 0;
86
+ const rootOutputTokens = typeof attrs["agentv.trace.token_output"] === "number" ? attrs["agentv.trace.token_output"] : 0;
87
+ const rootCachedTokens = typeof attrs["agentv.trace.token_cached"] === "number" ? attrs["agentv.trace.token_cached"] : void 0;
88
+ const llmSpans = children.filter((s) => s.attributes?.["gen_ai.operation.name"] === "chat").map((s) => ({
89
+ type: "llm",
90
+ name: s.name,
91
+ duration_ms: hrTimeDiffMs(s.startTime, s.endTime)
92
+ }));
89
93
  const toolSpans = children.filter((s) => s.attributes?.["gen_ai.tool.name"]).map((s) => ({
90
94
  type: "tool",
91
95
  name: s.attributes["gen_ai.tool.name"],
@@ -97,8 +101,12 @@ var SimpleTraceFileExporter = class {
97
101
  score: attrs["agentv.score"],
98
102
  duration_ms: durationMs,
99
103
  cost_usd: attrs["agentv.trace.cost_usd"],
100
- token_usage: inputTokens || outputTokens ? { input: inputTokens, output: outputTokens } : void 0,
101
- spans: toolSpans.length > 0 ? toolSpans : void 0
104
+ token_usage: inputTokens || outputTokens || rootInputTokens || rootOutputTokens || rootCachedTokens ? {
105
+ input: inputTokens || rootInputTokens,
106
+ output: outputTokens || rootOutputTokens,
107
+ ...rootCachedTokens ? { cached: rootCachedTokens } : {}
108
+ } : void 0,
109
+ spans: [...llmSpans, ...toolSpans].length > 0 ? [...llmSpans, ...toolSpans] : void 0
102
110
  };
103
111
  }
104
112
  };
@@ -111,4 +119,4 @@ function hrTimeDiffMs(start, end) {
111
119
  export {
112
120
  SimpleTraceFileExporter
113
121
  };
114
- //# sourceMappingURL=chunk-JK6V4KVD.js.map
122
+ //# sourceMappingURL=chunk-NR7QVL75.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../packages/core/src/observability/simple-trace-file-exporter.ts"],"sourcesContent":["import { type WriteStream, createWriteStream } from 'node:fs';\nimport { mkdir } from 'node:fs/promises';\nimport { dirname } from 'node:path';\n\n// biome-ignore lint/suspicious/noExplicitAny: OTel ReadableSpan loaded dynamically\ntype ReadableSpan = any;\n\n/**\n * SpanExporter that writes human-readable JSONL (one line per root span).\n * Designed for quick debugging and analysis without OTel tooling.\n */\nexport class SimpleTraceFileExporter {\n private stream: WriteStream | null = null;\n private filePath: string;\n private streamReady: Promise<WriteStream> | null = null;\n private pendingWrites: Promise<void>[] = [];\n private _shuttingDown = false;\n private spansByTraceId = new Map<string, ReadableSpan[]>();\n\n constructor(filePath: string) {\n this.filePath = filePath;\n }\n\n private async ensureStream(): Promise<WriteStream> {\n if (!this.streamReady) {\n this.streamReady = (async () => {\n await mkdir(dirname(this.filePath), { recursive: true });\n this.stream = createWriteStream(this.filePath, { flags: 'w' });\n return this.stream;\n })();\n }\n return this.streamReady;\n }\n\n export(spans: ReadableSpan[], resultCallback: (result: { code: number }) => void): void {\n if (this._shuttingDown) {\n resultCallback({ code: 0 });\n return;\n }\n const rootSpans: ReadableSpan[] = [];\n for (const span of spans) {\n const traceId = span.spanContext().traceId;\n const existing = this.spansByTraceId.get(traceId) ?? [];\n existing.push(span);\n this.spansByTraceId.set(traceId, existing);\n if (span.name === 'agentv.eval') {\n rootSpans.push(span);\n }\n }\n\n const writePromise = this.ensureStream().then((stream) => {\n for (const root of rootSpans) {\n const traceId = root.spanContext().traceId;\n const traceSpans = this.spansByTraceId.get(traceId) ?? [root];\n const children = traceSpans.filter(\n (span) => span.spanContext().spanId !== root.spanContext().spanId,\n );\n const record = this.buildSimpleRecord(root, children);\n stream.write(`${JSON.stringify(record)}\\n`);\n this.spansByTraceId.delete(traceId);\n }\n });\n this.pendingWrites.push(writePromise);\n\n resultCallback({ code: 0 });\n }\n\n async shutdown(): Promise<void> {\n this._shuttingDown = true;\n await Promise.all(this.pendingWrites);\n this.pendingWrites = [];\n this.spansByTraceId.clear();\n return new Promise((resolve) => {\n if (this.stream) {\n this.stream.end(() => resolve());\n } else {\n resolve();\n }\n });\n }\n\n async forceFlush(): Promise<void> {\n await Promise.all(this.pendingWrites);\n this.pendingWrites = [];\n }\n\n private buildSimpleRecord(root: ReadableSpan, children: ReadableSpan[]): Record<string, unknown> {\n const attrs = root.attributes || {};\n const durationMs =\n typeof attrs['agentv.trace.duration_ms'] === 'number'\n ? attrs['agentv.trace.duration_ms']\n : hrTimeDiffMs(root.startTime, root.endTime);\n\n let inputTokens = 0;\n let outputTokens = 0;\n for (const child of children) {\n const ca = child.attributes || {};\n if (ca['gen_ai.usage.input_tokens']) inputTokens += ca['gen_ai.usage.input_tokens'];\n if (ca['gen_ai.usage.output_tokens']) outputTokens += ca['gen_ai.usage.output_tokens'];\n }\n const rootInputTokens =\n typeof attrs['agentv.trace.token_input'] === 'number' ? attrs['agentv.trace.token_input'] : 0;\n const rootOutputTokens =\n typeof attrs['agentv.trace.token_output'] === 'number'\n ? attrs['agentv.trace.token_output']\n : 0;\n const rootCachedTokens =\n typeof attrs['agentv.trace.token_cached'] === 'number'\n ? attrs['agentv.trace.token_cached']\n : undefined;\n\n const llmSpans = children\n .filter((s: ReadableSpan) => s.attributes?.['gen_ai.operation.name'] === 'chat')\n .map((s: ReadableSpan) => ({\n type: 'llm' as const,\n name: s.name,\n duration_ms: hrTimeDiffMs(s.startTime, s.endTime),\n }));\n\n const toolSpans = children\n .filter((s: ReadableSpan) => s.attributes?.['gen_ai.tool.name'])\n .map((s: ReadableSpan) => ({\n type: 'tool' as const,\n name: s.attributes['gen_ai.tool.name'],\n duration_ms: hrTimeDiffMs(s.startTime, s.endTime),\n }));\n\n return {\n test_id: attrs['agentv.test_id'],\n target: attrs['agentv.target'],\n score: attrs['agentv.score'],\n duration_ms: durationMs,\n cost_usd: attrs['agentv.trace.cost_usd'],\n token_usage:\n inputTokens || outputTokens || rootInputTokens || rootOutputTokens || rootCachedTokens\n ? {\n input: inputTokens || rootInputTokens,\n output: outputTokens || rootOutputTokens,\n ...(rootCachedTokens ? { cached: rootCachedTokens } : {}),\n }\n : undefined,\n spans: [...llmSpans, ...toolSpans].length > 0 ? [...llmSpans, ...toolSpans] : undefined,\n };\n }\n}\n\nfunction hrTimeDiffMs(start: [number, number], end: [number, number]): number {\n const diffSec = end[0] - start[0];\n const diffNano = end[1] - start[1];\n return Math.round(diffSec * 1000 + diffNano / 1_000_000);\n}\n"],"mappings":"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","names":[]}
@@ -1,4 +1,7 @@
1
1
  import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
2
+ import {
3
+ require_token_error
4
+ } from "./chunk-HQDCIXVH.js";
2
5
  import {
3
6
  AISDKError,
4
7
  APICallError,
@@ -147,9 +150,6 @@ import {
147
150
  withoutTrailingSlash,
148
151
  zodSchema
149
152
  } from "./chunk-BJV6MDBE.js";
150
- import {
151
- require_token_error
152
- } from "./chunk-HQDCIXVH.js";
153
153
  import {
154
154
  SpanStatusCode,
155
155
  context,
@@ -21644,7 +21644,7 @@ async function loadSdkModules() {
21644
21644
  try {
21645
21645
  [piCodingAgentModule, piAiModule] = await Promise.all([
21646
21646
  import("@mariozechner/pi-coding-agent"),
21647
- import("./dist-BOIN5LC5-T5UWUK43.js")
21647
+ import("@mariozechner/pi-ai")
21648
21648
  ]);
21649
21649
  } catch {
21650
21650
  if (await promptInstall()) {
@@ -21652,7 +21652,7 @@ async function loadSdkModules() {
21652
21652
  execSync("bun add @mariozechner/pi-coding-agent", { stdio: "inherit" });
21653
21653
  [piCodingAgentModule, piAiModule] = await Promise.all([
21654
21654
  import("@mariozechner/pi-coding-agent"),
21655
- import("./dist-BOIN5LC5-T5UWUK43.js")
21655
+ import("@mariozechner/pi-ai")
21656
21656
  ]);
21657
21657
  } else {
21658
21658
  throw new Error(
@@ -24416,7 +24416,7 @@ ${context2.fileChanges}`;
24416
24416
  async evaluateWithRubrics(context2, graderProvider, rubrics) {
24417
24417
  if (!rubrics || rubrics.length === 0) {
24418
24418
  throw new Error(
24419
- `No rubrics found for evaluator "${context2.evaluator?.name ?? "llm-grader"}". Run "agentv generate rubrics" first.`
24419
+ `No rubrics found for evaluator "${context2.evaluator?.name ?? "llm-grader"}". Add rubric criteria under assertions or use the agentv-eval-writer skill for authoring help.`
24420
24420
  );
24421
24421
  }
24422
24422
  const hasScoreRanges = rubrics.some((r) => r.score_ranges && r.score_ranges.length > 0);
@@ -28654,7 +28654,7 @@ async function runEvaluation(options) {
28654
28654
  if (!cliModel) {
28655
28655
  throw new Error('--grader-target "agentv" requires --model (e.g., "openai:gpt-5-mini")');
28656
28656
  }
28657
- const { AgentvProvider: AgentvProvider2 } = await import("./agentv-provider-MIDKLYIH-6LIYKQRP.js");
28657
+ const { AgentvProvider: AgentvProvider2 } = await import("./agentv-provider-NFFLXG5M-TJAWCWCX.js");
28658
28658
  return new AgentvProvider2("agentv", { model: cliModel, temperature: 0 });
28659
28659
  }
28660
28660
  const overrideTarget = resolveTargetByName(cliGraderTarget);
@@ -30978,11 +30978,11 @@ var OtelTraceExporter = class {
30978
30978
  async init() {
30979
30979
  try {
30980
30980
  const [sdkTraceNode, resourcesMod, semconvMod, api, coreMod] = await Promise.all([
30981
- import("./src-PXDA7QIS.js"),
30982
- import("./esm-UYZ3HJBU.js"),
30981
+ import("./src-ML4D2MC2.js"),
30982
+ import("./esm-CZAWIY6F.js"),
30983
30983
  import("./esm-RVQPUGWH.js"),
30984
30984
  import("./esm-R77SNOF5.js"),
30985
- import("./esm-OJ2BXJK4-YKEI3Z7E.js").catch(() => null)
30985
+ import("./esm-5Q4BZALM-5REQWAUV.js").catch(() => null)
30986
30986
  ]);
30987
30987
  const { NodeTracerProvider: Provider, SimpleSpanProcessor } = sdkTraceNode;
30988
30988
  const { resourceFromAttributes } = resourcesMod;
@@ -31001,13 +31001,13 @@ var OtelTraceExporter = class {
31001
31001
  processors.push(new SimpleSpanProcessor(exporter));
31002
31002
  }
31003
31003
  if (this.options.otlpFilePath) {
31004
- const { OtlpJsonFileExporter: OtlpJsonFileExporter2 } = await import("./otlp-json-file-exporter-VN67MK3S-RQIM6EHY.js");
31004
+ const { OtlpJsonFileExporter: OtlpJsonFileExporter2 } = await import("./otlp-json-file-exporter-77FDBRSY-EZAPHWP6.js");
31005
31005
  processors.push(
31006
31006
  new SimpleSpanProcessor(new OtlpJsonFileExporter2(this.options.otlpFilePath))
31007
31007
  );
31008
31008
  }
31009
31009
  if (this.options.traceFilePath) {
31010
- const { SimpleTraceFileExporter: SimpleTraceFileExporter2 } = await import("./simple-trace-file-exporter-XWZTIZR2-4JKATE5G.js");
31010
+ const { SimpleTraceFileExporter: SimpleTraceFileExporter2 } = await import("./simple-trace-file-exporter-CRIO5HDZ-QYYT2QQT.js");
31011
31011
  processors.push(
31012
31012
  new SimpleSpanProcessor(new SimpleTraceFileExporter2(this.options.traceFilePath))
31013
31013
  );
@@ -31071,6 +31071,17 @@ var OtelTraceExporter = class {
31071
31071
  if (result.durationMs != null)
31072
31072
  rootSpan.setAttribute("agentv.trace.duration_ms", result.durationMs);
31073
31073
  if (result.costUsd != null) rootSpan.setAttribute("agentv.trace.cost_usd", result.costUsd);
31074
+ if (result.tokenUsage) {
31075
+ if (result.tokenUsage.input != null) {
31076
+ rootSpan.setAttribute("agentv.trace.token_input", result.tokenUsage.input);
31077
+ }
31078
+ if (result.tokenUsage.output != null) {
31079
+ rootSpan.setAttribute("agentv.trace.token_output", result.tokenUsage.output);
31080
+ }
31081
+ if (result.tokenUsage.cached != null) {
31082
+ rootSpan.setAttribute("agentv.trace.token_cached", result.tokenUsage.cached);
31083
+ }
31084
+ }
31074
31085
  if (result.trace) {
31075
31086
  const t = result.trace;
31076
31087
  rootSpan.setAttribute("agentv.trace.event_count", t.eventCount);
@@ -31173,6 +31184,7 @@ var OtelTraceExporter = class {
31173
31184
  tracer.startActiveSpan(
31174
31185
  spanName,
31175
31186
  { startTime: startHr },
31187
+ parentCtx,
31176
31188
  (span) => {
31177
31189
  if (isAssistant) {
31178
31190
  span.setAttribute("gen_ai.operation.name", "chat");
@@ -31205,6 +31217,7 @@ var OtelTraceExporter = class {
31205
31217
  tracer.startActiveSpan(
31206
31218
  `execute_tool ${tc.tool}`,
31207
31219
  {},
31220
+ msgCtx,
31208
31221
  (toolSpan) => {
31209
31222
  toolSpan.setAttribute("gen_ai.tool.name", tc.tool);
31210
31223
  if (tc.id) toolSpan.setAttribute("gen_ai.tool.call.id", tc.id);
@@ -31245,8 +31258,12 @@ var OtelStreamingObserver = class {
31245
31258
  rootSpan = null;
31246
31259
  // biome-ignore lint/suspicious/noExplicitAny: OTel context loaded dynamically
31247
31260
  rootCtx = null;
31261
+ observedChildSpans = false;
31262
+ pendingMetrics = null;
31248
31263
  /** Create root eval span immediately (visible in backend right away) */
31249
31264
  startEvalCase(testId, target, evalSet) {
31265
+ this.pendingMetrics = null;
31266
+ this.observedChildSpans = false;
31250
31267
  const ctx = this.parentCtx ?? this.api.context.active();
31251
31268
  this.rootSpan = this.tracer.startSpan("agentv.eval", void 0, ctx);
31252
31269
  this.rootSpan.setAttribute("gen_ai.operation.name", "evaluate");
@@ -31259,8 +31276,9 @@ var OtelStreamingObserver = class {
31259
31276
  /** Create and immediately export a tool span */
31260
31277
  onToolCall(name21, input, output, _durationMs, toolCallId) {
31261
31278
  if (!this.rootCtx) return;
31279
+ this.observedChildSpans = true;
31262
31280
  this.api.context.with(this.rootCtx, () => {
31263
- const span = this.tracer.startSpan(`execute_tool ${name21}`);
31281
+ const span = this.tracer.startSpan(`execute_tool ${name21}`, void 0, this.rootCtx);
31264
31282
  span.setAttribute("gen_ai.tool.name", name21);
31265
31283
  if (toolCallId) span.setAttribute("gen_ai.tool.call.id", toolCallId);
31266
31284
  if (this.captureContent) {
@@ -31281,8 +31299,9 @@ var OtelStreamingObserver = class {
31281
31299
  /** Create and immediately export an LLM span */
31282
31300
  onLlmCall(model, tokenUsage) {
31283
31301
  if (!this.rootCtx) return;
31302
+ this.observedChildSpans = true;
31284
31303
  this.api.context.with(this.rootCtx, () => {
31285
- const span = this.tracer.startSpan(`chat ${model}`);
31304
+ const span = this.tracer.startSpan(`chat ${model}`, void 0, this.rootCtx);
31286
31305
  span.setAttribute("gen_ai.operation.name", "chat");
31287
31306
  span.setAttribute("gen_ai.request.model", model);
31288
31307
  span.setAttribute("gen_ai.response.model", model);
@@ -31297,10 +31316,53 @@ var OtelStreamingObserver = class {
31297
31316
  span.end();
31298
31317
  });
31299
31318
  }
31319
+ /** Record final execution metrics before the root span is finalized. */
31320
+ recordEvalMetrics(result) {
31321
+ this.pendingMetrics = result;
31322
+ }
31300
31323
  /** Finalize root span with score/verdict after evaluation completes */
31301
31324
  finalizeEvalCase(score, error) {
31302
31325
  if (!this.rootSpan) return;
31303
31326
  this.rootSpan.setAttribute("agentv.score", score);
31327
+ if (this.pendingMetrics?.durationMs != null) {
31328
+ this.rootSpan.setAttribute("agentv.trace.duration_ms", this.pendingMetrics.durationMs);
31329
+ }
31330
+ if (this.pendingMetrics?.costUsd != null) {
31331
+ this.rootSpan.setAttribute("agentv.trace.cost_usd", this.pendingMetrics.costUsd);
31332
+ }
31333
+ if (this.pendingMetrics?.tokenUsage) {
31334
+ if (this.pendingMetrics.tokenUsage.input != null) {
31335
+ this.rootSpan.setAttribute(
31336
+ "agentv.trace.token_input",
31337
+ this.pendingMetrics.tokenUsage.input
31338
+ );
31339
+ }
31340
+ if (this.pendingMetrics.tokenUsage.output != null) {
31341
+ this.rootSpan.setAttribute(
31342
+ "agentv.trace.token_output",
31343
+ this.pendingMetrics.tokenUsage.output
31344
+ );
31345
+ }
31346
+ if (this.pendingMetrics.tokenUsage.cached != null) {
31347
+ this.rootSpan.setAttribute(
31348
+ "agentv.trace.token_cached",
31349
+ this.pendingMetrics.tokenUsage.cached
31350
+ );
31351
+ }
31352
+ }
31353
+ if (this.pendingMetrics?.trace) {
31354
+ this.rootSpan.setAttribute("agentv.trace.event_count", this.pendingMetrics.trace.eventCount);
31355
+ this.rootSpan.setAttribute(
31356
+ "agentv.trace.tool_names",
31357
+ Object.keys(this.pendingMetrics.trace.toolCalls).sort().join(",")
31358
+ );
31359
+ if (this.pendingMetrics.trace.llmCallCount != null) {
31360
+ this.rootSpan.setAttribute(
31361
+ "agentv.trace.llm_call_count",
31362
+ this.pendingMetrics.trace.llmCallCount
31363
+ );
31364
+ }
31365
+ }
31304
31366
  if (error) {
31305
31367
  this.rootSpan.setStatus({ code: this.api.SpanStatusCode.ERROR, message: error });
31306
31368
  } else {
@@ -31309,6 +31371,33 @@ var OtelStreamingObserver = class {
31309
31371
  this.rootSpan.end();
31310
31372
  this.rootSpan = null;
31311
31373
  this.rootCtx = null;
31374
+ this.observedChildSpans = false;
31375
+ this.pendingMetrics = null;
31376
+ }
31377
+ /** Backfill child spans from the completed result when the provider emitted no live callbacks. */
31378
+ completeFromResult(result) {
31379
+ this.recordEvalMetrics({
31380
+ durationMs: result.durationMs,
31381
+ costUsd: result.costUsd,
31382
+ tokenUsage: result.tokenUsage,
31383
+ trace: result.trace
31384
+ });
31385
+ if (this.observedChildSpans || !this.rootCtx) {
31386
+ return;
31387
+ }
31388
+ const model = result.output.find((msg) => msg.role === "assistant")?.metadata?.model ?? result.target ?? "unknown";
31389
+ this.onLlmCall(String(model), result.tokenUsage);
31390
+ for (const message of result.output) {
31391
+ for (const toolCall of message.toolCalls ?? []) {
31392
+ this.onToolCall(
31393
+ toolCall.tool,
31394
+ toolCall.input,
31395
+ toolCall.output,
31396
+ toolCall.durationMs ?? 0,
31397
+ toolCall.id
31398
+ );
31399
+ }
31400
+ }
31312
31401
  }
31313
31402
  /** Return the active eval span's trace ID and span ID for Braintrust trace bridging */
31314
31403
  getActiveSpanIds() {
@@ -31499,4 +31588,4 @@ export {
31499
31588
  OtelStreamingObserver,
31500
31589
  createAgentKernel
31501
31590
  };
31502
- //# sourceMappingURL=chunk-OYD2NB55.js.map
31591
+ //# sourceMappingURL=chunk-UYBLUYHN.js.map