@tangle-network/agent-eval 0.126.7 → 0.128.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 (132) hide show
  1. package/CHANGELOG.md +59 -0
  2. package/README.md +6 -2
  3. package/dist/analyst/index.d.ts +52 -43
  4. package/dist/analyst/index.js +4 -4
  5. package/dist/belief-state/index.d.ts +35 -40
  6. package/dist/belief-state/index.js +2 -2
  7. package/dist/benchmarks/index.d.ts +30 -12
  8. package/dist/benchmarks/index.js +12 -11
  9. package/dist/builder-eval/index.js +1 -1
  10. package/dist/campaign/index.d.ts +441 -160
  11. package/dist/campaign/index.js +11 -10
  12. package/dist/{chunk-IILEIWGW.js → chunk-2JX3CFMB.js} +100 -40
  13. package/dist/chunk-2JX3CFMB.js.map +1 -0
  14. package/dist/chunk-2MKQIFS4.js +183 -0
  15. package/dist/chunk-2MKQIFS4.js.map +1 -0
  16. package/dist/{chunk-NUKSVU3W.js → chunk-5DTSBUL2.js} +2 -2
  17. package/dist/{chunk-H5UD2323.js → chunk-7ZZMD7UK.js} +102 -2
  18. package/dist/chunk-7ZZMD7UK.js.map +1 -0
  19. package/dist/{chunk-474LBSOX.js → chunk-BYT7ELPS.js} +45 -18
  20. package/dist/chunk-BYT7ELPS.js.map +1 -0
  21. package/dist/{chunk-LUNF2SEL.js → chunk-DJKY2TSY.js} +3 -3
  22. package/dist/chunk-DPUHNQLN.js +232 -0
  23. package/dist/chunk-DPUHNQLN.js.map +1 -0
  24. package/dist/chunk-DRYIUNWY.js +622 -0
  25. package/dist/chunk-DRYIUNWY.js.map +1 -0
  26. package/dist/{chunk-IPYXE555.js → chunk-EJGRPCO3.js} +36 -13
  27. package/dist/chunk-EJGRPCO3.js.map +1 -0
  28. package/dist/{chunk-OCFJACJU.js → chunk-EOSZT7PL.js} +82 -18
  29. package/dist/chunk-EOSZT7PL.js.map +1 -0
  30. package/dist/{chunk-ZVCHKKOP.js → chunk-EZJEIH2R.js} +39 -15
  31. package/dist/chunk-EZJEIH2R.js.map +1 -0
  32. package/dist/{chunk-M7AH34KV.js → chunk-IHQDPH7D.js} +32 -16
  33. package/dist/chunk-IHQDPH7D.js.map +1 -0
  34. package/dist/{chunk-PJQFMIOX.js → chunk-MHELPNRP.js} +31 -1
  35. package/dist/chunk-MHELPNRP.js.map +1 -0
  36. package/dist/{chunk-K6IAZZ6L.js → chunk-NACAGYSY.js} +153 -122
  37. package/dist/chunk-NACAGYSY.js.map +1 -0
  38. package/dist/{chunk-BTACVO2W.js → chunk-NKAGIDE2.js} +542 -258
  39. package/dist/chunk-NKAGIDE2.js.map +1 -0
  40. package/dist/{chunk-ARU2PZFM.js → chunk-NYLOYM6N.js} +43 -23
  41. package/dist/chunk-NYLOYM6N.js.map +1 -0
  42. package/dist/{chunk-QOTFXW5L.js → chunk-P5W7RQKK.js} +2 -2
  43. package/dist/{chunk-IR3KBHOY.js → chunk-P6FYH6K4.js} +39 -3
  44. package/dist/chunk-P6FYH6K4.js.map +1 -0
  45. package/dist/{chunk-J5SQWP6Y.js → chunk-PBE2LOSS.js} +18 -2
  46. package/dist/chunk-PBE2LOSS.js.map +1 -0
  47. package/dist/{chunk-X4UCIOTZ.js → chunk-S5YLIBFX.js} +2 -2
  48. package/dist/{chunk-7VYEGHWF.js → chunk-SZLVEKMJ.js} +41 -20
  49. package/dist/chunk-SZLVEKMJ.js.map +1 -0
  50. package/dist/{chunk-P22LJ3Y2.js → chunk-TBL77AUT.js} +8 -8
  51. package/dist/chunk-TBL77AUT.js.map +1 -0
  52. package/dist/{chunk-LKKT3IVV.js → chunk-TSN7JT6D.js} +6 -4
  53. package/dist/{chunk-LKKT3IVV.js.map → chunk-TSN7JT6D.js.map} +1 -1
  54. package/dist/{chunk-E3IADPLG.js → chunk-UB2LOJ6Q.js} +51 -227
  55. package/dist/chunk-UB2LOJ6Q.js.map +1 -0
  56. package/dist/{chunk-MAX3TN3C.js → chunk-UWZZKKU7.js} +7 -19
  57. package/dist/chunk-UWZZKKU7.js.map +1 -0
  58. package/dist/{chunk-DPZAEKA6.js → chunk-VLOATJQ2.js} +85 -57
  59. package/dist/chunk-VLOATJQ2.js.map +1 -0
  60. package/dist/{chunk-MOXWMGPC.js → chunk-XDWDC2MP.js} +197 -79
  61. package/dist/chunk-XDWDC2MP.js.map +1 -0
  62. package/dist/{chunk-CGG5SLH3.js → chunk-XPRT64IE.js} +2 -2
  63. package/dist/{chunk-FO7HEH76.js → chunk-YJBNWCAA.js} +2 -2
  64. package/dist/{chunk-KE2VWPZX.js → chunk-ZUUWPZCV.js} +3 -3
  65. package/dist/cli.js +4 -4
  66. package/dist/contract/index.d.ts +438 -138
  67. package/dist/contract/index.js +259 -113
  68. package/dist/contract/index.js.map +1 -1
  69. package/dist/control.d.ts +56 -39
  70. package/dist/control.js +2 -3
  71. package/dist/hosted/index.d.ts +152 -51
  72. package/dist/hosted/index.js +24 -1
  73. package/dist/index.d.ts +399 -277
  74. package/dist/index.js +363 -244
  75. package/dist/index.js.map +1 -1
  76. package/dist/meta-eval/index.d.ts +33 -36
  77. package/dist/meta-eval/index.js +2 -2
  78. package/dist/multishot/index.d.ts +1 -0
  79. package/dist/openapi.json +1 -1
  80. package/dist/pipelines/index.js +2 -2
  81. package/dist/reporting.d.ts +101 -80
  82. package/dist/reporting.js +7 -5
  83. package/dist/rl.d.ts +198 -142
  84. package/dist/rl.js +235 -127
  85. package/dist/rl.js.map +1 -1
  86. package/dist/rollout/index.d.ts +54 -67
  87. package/dist/rollout/index.js +6 -5
  88. package/dist/{run-campaign-FFRM3RH5.js → run-campaign-ISHFZ7FJ.js} +6 -3
  89. package/dist/supervisor-run/index.d.ts +7 -15
  90. package/dist/supervisor-run/index.js +2 -2
  91. package/dist/traces.d.ts +72 -50
  92. package/dist/traces.js +9 -6
  93. package/dist/wire/index.d.ts +1 -0
  94. package/dist/wire/index.js +2 -2
  95. package/docs/concepts.md +18 -1
  96. package/docs/customer-journeys.md +7 -6
  97. package/docs/hosted-ingest-spec.md +37 -40
  98. package/docs/insight-report.md +78 -7
  99. package/docs/research-report-methodology.md +20 -21
  100. package/docs/rollout.md +13 -8
  101. package/package.json +4 -3
  102. package/dist/chunk-474LBSOX.js.map +0 -1
  103. package/dist/chunk-7VYEGHWF.js.map +0 -1
  104. package/dist/chunk-ARU2PZFM.js.map +0 -1
  105. package/dist/chunk-BTACVO2W.js.map +0 -1
  106. package/dist/chunk-DPZAEKA6.js.map +0 -1
  107. package/dist/chunk-E3IADPLG.js.map +0 -1
  108. package/dist/chunk-H5UD2323.js.map +0 -1
  109. package/dist/chunk-IILEIWGW.js.map +0 -1
  110. package/dist/chunk-IPYXE555.js.map +0 -1
  111. package/dist/chunk-IR3KBHOY.js.map +0 -1
  112. package/dist/chunk-J5SQWP6Y.js.map +0 -1
  113. package/dist/chunk-K6IAZZ6L.js.map +0 -1
  114. package/dist/chunk-M7AH34KV.js.map +0 -1
  115. package/dist/chunk-MAX3TN3C.js.map +0 -1
  116. package/dist/chunk-MOXWMGPC.js.map +0 -1
  117. package/dist/chunk-OCFJACJU.js.map +0 -1
  118. package/dist/chunk-P22LJ3Y2.js.map +0 -1
  119. package/dist/chunk-PJQFMIOX.js.map +0 -1
  120. package/dist/chunk-VSMTAMNK.js +0 -53
  121. package/dist/chunk-VSMTAMNK.js.map +0 -1
  122. package/dist/chunk-ZVCHKKOP.js.map +0 -1
  123. package/dist/chunk-ZZUXHH3R.js +0 -99
  124. package/dist/chunk-ZZUXHH3R.js.map +0 -1
  125. /package/dist/{chunk-NUKSVU3W.js.map → chunk-5DTSBUL2.js.map} +0 -0
  126. /package/dist/{chunk-LUNF2SEL.js.map → chunk-DJKY2TSY.js.map} +0 -0
  127. /package/dist/{chunk-QOTFXW5L.js.map → chunk-P5W7RQKK.js.map} +0 -0
  128. /package/dist/{chunk-X4UCIOTZ.js.map → chunk-S5YLIBFX.js.map} +0 -0
  129. /package/dist/{chunk-CGG5SLH3.js.map → chunk-XPRT64IE.js.map} +0 -0
  130. /package/dist/{chunk-FO7HEH76.js.map → chunk-YJBNWCAA.js.map} +0 -0
  131. /package/dist/{chunk-KE2VWPZX.js.map → chunk-ZUUWPZCV.js.map} +0 -0
  132. /package/dist/{run-campaign-FFRM3RH5.js.map → run-campaign-ISHFZ7FJ.js.map} +0 -0
@@ -0,0 +1,622 @@
1
+ import {
2
+ FAILURE_CLASSES
3
+ } from "./chunk-MA6HLL3S.js";
4
+
5
+ // src/hosted/types.ts
6
+ var HOSTED_WIRE_VERSION = "2026-07-24.v1";
7
+
8
+ // src/hosted/schemas.ts
9
+ import { z } from "zod";
10
+ var finiteNumber = z.number().finite();
11
+ var nonNegativeNumber = finiteNumber.nonnegative();
12
+ var nonNegativeInteger = z.number().int().nonnegative();
13
+ var nonEmptyString = z.string().min(1).refine((value) => value.trim().length > 0, "must not be blank");
14
+ var attributeValue = z.union([z.string(), finiteNumber, z.boolean()]);
15
+ var attributes = z.record(z.string(), attributeValue);
16
+ var FailureClassSchema = z.custom(
17
+ (value) => typeof value === "string" && FAILURE_CLASSES.includes(value),
18
+ `expected one of ${FAILURE_CLASSES.join(", ")}`
19
+ );
20
+ var UINT64_MAX = 18446744073709551615n;
21
+ var UnixNanoTimestampSchema = z.string().regex(/^(0|[1-9][0-9]*)$/, "expected an unsigned base-10 integer string").refine((value) => BigInt(value) <= UINT64_MAX, "must fit in an unsigned 64-bit integer");
22
+ var GainDistributionBinSchema = z.object({
23
+ lo: finiteNumber,
24
+ hi: finiteNumber,
25
+ count: nonNegativeInteger
26
+ }).strict();
27
+ var ScalarDistributionSchema = z.object({
28
+ n: nonNegativeInteger,
29
+ mean: finiteNumber.nullable(),
30
+ p50: finiteNumber.nullable(),
31
+ p95: finiteNumber.nullable(),
32
+ stddev: nonNegativeNumber.nullable(),
33
+ min: finiteNumber.nullable(),
34
+ max: finiteNumber.nullable(),
35
+ histogram: z.array(GainDistributionBinSchema),
36
+ tailRuns: z.array(
37
+ z.object({
38
+ runId: nonEmptyString,
39
+ score: finiteNumber
40
+ }).strict()
41
+ ).optional()
42
+ }).strict().superRefine((distribution, ctx) => {
43
+ const values = [
44
+ distribution.mean,
45
+ distribution.p50,
46
+ distribution.p95,
47
+ distribution.stddev,
48
+ distribution.min,
49
+ distribution.max
50
+ ];
51
+ if (distribution.n === 0 && values.some((value) => value !== null)) {
52
+ ctx.addIssue({
53
+ code: "custom",
54
+ message: "distribution values must be null when n is 0"
55
+ });
56
+ }
57
+ if (distribution.n > 0 && values.some((value) => value === null)) {
58
+ ctx.addIssue({
59
+ code: "custom",
60
+ message: "distribution values must be numbers when n is greater than 0"
61
+ });
62
+ }
63
+ if (distribution.min !== null && distribution.max !== null && distribution.min > distribution.max) {
64
+ ctx.addIssue({ code: "custom", path: ["min"], message: "min must not exceed max" });
65
+ }
66
+ });
67
+ var TokenUsageInsightSchema = z.object({
68
+ input: ScalarDistributionSchema,
69
+ output: ScalarDistributionSchema,
70
+ reasoning: ScalarDistributionSchema,
71
+ cached: ScalarDistributionSchema,
72
+ cacheWrite: ScalarDistributionSchema,
73
+ totals: z.object({
74
+ input: nonNegativeNumber,
75
+ output: nonNegativeNumber,
76
+ reasoning: nonNegativeNumber,
77
+ cached: nonNegativeNumber,
78
+ cacheWrite: nonNegativeNumber
79
+ }).strict()
80
+ }).strict();
81
+ var ExecutionErrorOutcomeCellSchema = z.object({
82
+ withErrors: nonNegativeInteger,
83
+ withoutErrors: nonNegativeInteger,
84
+ unreported: nonNegativeInteger
85
+ }).strict();
86
+ var ExecutionInsightSchema = z.object({
87
+ durationMs: ScalarDistributionSchema,
88
+ queueMs: ScalarDistributionSchema,
89
+ tokenUsage: TokenUsageInsightSchema,
90
+ aggregateUsage: z.object({
91
+ runs: nonNegativeInteger,
92
+ tokenUsage: TokenUsageInsightSchema,
93
+ costUsd: ScalarDistributionSchema,
94
+ totalCostUsd: nonNegativeNumber
95
+ }).strict(),
96
+ models: z.array(
97
+ z.object({
98
+ model: nonEmptyString,
99
+ runs: nonNegativeInteger
100
+ }).strict()
101
+ ),
102
+ modelCalls: z.object({
103
+ runs: nonNegativeInteger,
104
+ events: nonNegativeInteger,
105
+ reportingRuns: nonNegativeInteger
106
+ }).strict(),
107
+ executionErrors: z.object({
108
+ runs: nonNegativeInteger,
109
+ fraction: finiteNumber.min(0).max(1).nullable(),
110
+ events: nonNegativeInteger,
111
+ reportingRuns: nonNegativeInteger,
112
+ errorSpanEvents: nonNegativeInteger,
113
+ errorSpanReportingRuns: nonNegativeInteger,
114
+ byTerminalOutcome: z.object({
115
+ succeeded: ExecutionErrorOutcomeCellSchema,
116
+ failed: ExecutionErrorOutcomeCellSchema,
117
+ cancelled: ExecutionErrorOutcomeCellSchema,
118
+ incomplete: ExecutionErrorOutcomeCellSchema,
119
+ unknown: ExecutionErrorOutcomeCellSchema
120
+ }).strict()
121
+ }).strict(),
122
+ terminalOutcomes: z.object({
123
+ succeeded: nonNegativeInteger,
124
+ failed: nonNegativeInteger,
125
+ cancelled: nonNegativeInteger,
126
+ incomplete: nonNegativeInteger,
127
+ unknown: nonNegativeInteger
128
+ }).strict()
129
+ }).strict();
130
+ var CostProvenanceSummarySchema = z.object({
131
+ observed: z.object({
132
+ n: nonNegativeInteger,
133
+ totalUsd: nonNegativeNumber
134
+ }).strict(),
135
+ estimated: z.object({
136
+ n: nonNegativeInteger,
137
+ totalUsd: nonNegativeNumber
138
+ }).strict(),
139
+ uncaptured: z.object({ n: nonNegativeInteger }).strict(),
140
+ knownFraction: finiteNumber.min(0).max(1)
141
+ }).strict();
142
+ var ParetoFigureSpecSchema = z.object({
143
+ kind: z.literal("pareto-cost-quality"),
144
+ split: z.enum(["search", "holdout"]),
145
+ points: z.array(
146
+ z.object({
147
+ candidateId: nonEmptyString,
148
+ cost: nonNegativeNumber,
149
+ quality: finiteNumber,
150
+ n: nonNegativeInteger,
151
+ onFrontier: z.boolean(),
152
+ gate: z.enum(["promote", "reject"]).optional()
153
+ }).strict()
154
+ ),
155
+ axes: z.object({ x: z.literal("costUsd"), y: z.literal("score") }).strict()
156
+ }).strict();
157
+ var ContinuousAgreementSchema = z.object({
158
+ weightedKappa: finiteNumber,
159
+ icc: finiteNumber,
160
+ pearson: finiteNumber,
161
+ spearman: finiteNumber,
162
+ ci: z.object({
163
+ icc: z.tuple([finiteNumber, finiteNumber]),
164
+ weightedKappa: z.tuple([finiteNumber, finiteNumber])
165
+ }).strict(),
166
+ n: nonNegativeInteger,
167
+ raters: nonNegativeInteger
168
+ }).strict();
169
+ var JudgeInsightSchema = z.object({
170
+ n: nonNegativeInteger,
171
+ meanScore: finiteNumber,
172
+ calibration: ContinuousAgreementSchema.optional(),
173
+ positionalBias: finiteNumber.optional(),
174
+ selfPreference: finiteNumber.optional(),
175
+ verbosityBias: finiteNumber.optional()
176
+ }).strict();
177
+ var InterRaterInsightSchema = z.object({
178
+ raters: nonNegativeInteger,
179
+ jointlyRated: nonNegativeInteger,
180
+ kappa: finiteNumber,
181
+ icc: finiteNumber,
182
+ pearson: finiteNumber,
183
+ spearman: finiteNumber,
184
+ perPair: z.record(z.string(), finiteNumber),
185
+ disagreementCases: z.array(
186
+ z.object({
187
+ runId: nonEmptyString,
188
+ ratings: z.array(
189
+ z.object({
190
+ rater: nonEmptyString,
191
+ score: finiteNumber
192
+ }).strict()
193
+ ),
194
+ range: nonNegativeNumber
195
+ }).strict()
196
+ )
197
+ }).strict();
198
+ var LiftInsightSchema = z.object({
199
+ baselineMean: finiteNumber,
200
+ candidateMean: finiteNumber,
201
+ delta: finiteNumber,
202
+ ci95: z.tuple([finiteNumber, finiteNumber]),
203
+ pValue: finiteNumber.min(0).max(1),
204
+ n: nonNegativeInteger,
205
+ unpairedBaseline: nonNegativeInteger,
206
+ unpairedCandidate: nonNegativeInteger,
207
+ cohensD: finiteNumber.nullable(),
208
+ mde: nonNegativeNumber,
209
+ requiredN: nonNegativeInteger.nullable()
210
+ }).strict();
211
+ var FailureClusterInsightSchema = z.object({
212
+ clusters: z.array(
213
+ z.object({
214
+ id: nonEmptyString,
215
+ name: nonEmptyString,
216
+ share: finiteNumber.min(0).max(1),
217
+ exemplars: z.array(nonEmptyString).max(5),
218
+ suggestedFix: nonEmptyString.optional()
219
+ }).strict()
220
+ ),
221
+ totalFailures: nonNegativeInteger
222
+ }).strict();
223
+ var ContaminationInsightSchema = z.object({
224
+ leaks: nonNegativeInteger,
225
+ holdoutAuditPassed: z.boolean(),
226
+ details: z.array(
227
+ z.object({
228
+ runId: nonEmptyString,
229
+ canary: nonEmptyString,
230
+ matched: nonEmptyString
231
+ }).strict()
232
+ ).optional()
233
+ }).strict();
234
+ var OutcomeCorrelationInsightSchema = z.object({
235
+ metric: nonEmptyString,
236
+ n: nonNegativeInteger,
237
+ pearson: finiteNumber,
238
+ spearman: finiteNumber,
239
+ rewardModel: z.object({
240
+ intercept: finiteNumber,
241
+ slope: finiteNumber,
242
+ r2: finiteNumber
243
+ }).strict().optional()
244
+ }).strict();
245
+ var ReleaseSummarySchema = z.object({
246
+ status: z.enum(["pass", "warn", "fail"]),
247
+ axes: z.array(
248
+ z.object({
249
+ name: z.enum(["quality-lift", "contamination", "composite-distribution"]),
250
+ status: z.enum(["pass", "warn", "fail", "not_evaluated"]),
251
+ detail: nonEmptyString
252
+ }).strict()
253
+ ),
254
+ issues: z.array(z.string())
255
+ }).strict();
256
+ var MetricDeltaSchema = z.object({
257
+ current: finiteNumber,
258
+ baseline: finiteNumber,
259
+ delta: finiteNumber,
260
+ ci95: z.tuple([finiteNumber, finiteNumber]),
261
+ pValue: finiteNumber.min(0).max(1),
262
+ cohensD: finiteNumber,
263
+ baselineN: nonNegativeInteger,
264
+ currentN: nonNegativeInteger,
265
+ significant: z.boolean()
266
+ }).strict();
267
+ var PriorPeriodComparisonSchema = z.object({
268
+ baselineN: nonNegativeInteger,
269
+ currentN: nonNegativeInteger,
270
+ windowLabel: nonEmptyString.optional(),
271
+ metrics: z.record(z.string(), MetricDeltaSchema),
272
+ regressedMetrics: z.array(nonEmptyString),
273
+ improvedMetrics: z.array(nonEmptyString)
274
+ }).strict();
275
+ var RecommendationSchema = z.object({
276
+ priority: z.enum(["critical", "high", "medium", "low"]),
277
+ kind: z.enum(["ship", "hold", "investigate", "fix", "recalibrate", "expand-corpus"]),
278
+ title: nonEmptyString,
279
+ detail: nonEmptyString,
280
+ evidencePath: nonEmptyString.optional()
281
+ }).strict();
282
+ var InsightReportSchema = z.object({
283
+ n: nonNegativeInteger,
284
+ execution: ExecutionInsightSchema,
285
+ composite: ScalarDistributionSchema,
286
+ perDimension: z.record(z.string(), ScalarDistributionSchema),
287
+ costQuality: z.object({
288
+ cost: ScalarDistributionSchema,
289
+ pareto: ParetoFigureSpecSchema,
290
+ provenance: CostProvenanceSummarySchema.optional(),
291
+ degraded: z.object({
292
+ cost: nonEmptyString.optional(),
293
+ pareto: nonEmptyString.optional()
294
+ }).strict().optional()
295
+ }).strict(),
296
+ judges: z.record(z.string(), JudgeInsightSchema),
297
+ interRater: InterRaterInsightSchema.optional(),
298
+ lift: LiftInsightSchema.optional(),
299
+ failureClusters: FailureClusterInsightSchema.optional(),
300
+ contamination: ContaminationInsightSchema.optional(),
301
+ outcomeCorrelation: OutcomeCorrelationInsightSchema.optional(),
302
+ release: ReleaseSummarySchema,
303
+ priorPeriodComparison: PriorPeriodComparisonSchema.optional(),
304
+ failureClasses: z.array(
305
+ z.object({
306
+ failureClass: FailureClassSchema,
307
+ count: nonNegativeInteger,
308
+ share: finiteNumber.min(0).max(1)
309
+ }).strict()
310
+ ).optional(),
311
+ recommendations: z.array(RecommendationSchema)
312
+ }).strict();
313
+ var sha256Digest = z.custom(
314
+ (value) => typeof value === "string" && /^sha256:[0-9a-f]{64}$/.test(value),
315
+ "expected sha256:<64 lowercase hex characters>"
316
+ );
317
+ var MutableSurfaceSchema = z.union([
318
+ z.string(),
319
+ z.object({
320
+ kind: z.literal("components"),
321
+ components: z.record(z.string(), z.string())
322
+ }).strict(),
323
+ z.object({
324
+ kind: z.literal("code"),
325
+ worktreeRef: nonEmptyString,
326
+ baseRef: nonEmptyString,
327
+ baseCommit: nonEmptyString,
328
+ baseTree: nonEmptyString,
329
+ candidateCommit: nonEmptyString,
330
+ candidateTree: nonEmptyString,
331
+ patch: z.object({
332
+ format: z.literal("git-diff-binary"),
333
+ sha256: sha256Digest,
334
+ byteLength: nonNegativeInteger
335
+ }).strict(),
336
+ summary: z.string().optional()
337
+ }).strict()
338
+ ]);
339
+ var RunTerminalOutcomeSchema = z.enum([
340
+ "succeeded",
341
+ "failed",
342
+ "cancelled",
343
+ "incomplete",
344
+ "unknown"
345
+ ]);
346
+ var EvalRunCellScoreSchema = z.object({
347
+ scenarioId: nonEmptyString,
348
+ rep: nonNegativeInteger,
349
+ compositeMean: finiteNumber.nullable(),
350
+ dimensions: z.record(z.string(), z.record(z.string(), finiteNumber)),
351
+ terminalOutcome: RunTerminalOutcomeSchema,
352
+ executionErrorCount: nonNegativeInteger.nullable(),
353
+ errorMessage: z.string().optional()
354
+ }).strict();
355
+ var EvalRunGenerationSnapshotSchema = z.object({
356
+ index: nonNegativeInteger,
357
+ surfaceHash: nonEmptyString,
358
+ surface: MutableSurfaceSchema.optional(),
359
+ cells: z.array(EvalRunCellScoreSchema),
360
+ compositeMean: finiteNumber.nullable(),
361
+ costUsd: nonNegativeNumber,
362
+ durationMs: nonNegativeNumber
363
+ }).strict();
364
+ var EvalRunStatusSchema = z.enum([
365
+ "started",
366
+ "baseline-complete",
367
+ "generation-complete",
368
+ "gate-decided",
369
+ "finished",
370
+ "errored"
371
+ ]);
372
+ var GateDecisionSchema = z.enum([
373
+ "ship",
374
+ "hold",
375
+ "need_more_work",
376
+ "model_ceiling",
377
+ "arch_ceiling"
378
+ ]);
379
+ var EvalRunEventSchema = z.object({
380
+ runId: nonEmptyString,
381
+ runDir: nonEmptyString,
382
+ timestamp: z.string().datetime({ offset: true }),
383
+ status: EvalRunStatusSchema,
384
+ labels: z.record(z.string(), z.string()),
385
+ baseline: EvalRunGenerationSnapshotSchema.optional(),
386
+ generations: z.array(EvalRunGenerationSnapshotSchema),
387
+ gateDecision: GateDecisionSchema.optional(),
388
+ holdoutLift: finiteNumber.optional(),
389
+ totalCostUsd: nonNegativeNumber,
390
+ totalDurationMs: nonNegativeNumber,
391
+ errorMessage: z.string().optional(),
392
+ insightReport: InsightReportSchema.optional()
393
+ }).strict().superRefine((event, ctx) => {
394
+ if (event.baseline && event.baseline.index !== 0) {
395
+ ctx.addIssue({
396
+ code: "custom",
397
+ path: ["baseline", "index"],
398
+ message: "baseline index must be 0"
399
+ });
400
+ }
401
+ const seen = /* @__PURE__ */ new Set();
402
+ for (let i = 0; i < event.generations.length; i++) {
403
+ const index = event.generations[i].index;
404
+ if (seen.has(index)) {
405
+ ctx.addIssue({
406
+ code: "custom",
407
+ path: ["generations", i, "index"],
408
+ message: `duplicate generation index ${index}`
409
+ });
410
+ }
411
+ seen.add(index);
412
+ }
413
+ if (event.status === "errored" && !event.errorMessage?.trim()) {
414
+ ctx.addIssue({
415
+ code: "custom",
416
+ path: ["errorMessage"],
417
+ message: "errorMessage is required when status is errored"
418
+ });
419
+ }
420
+ });
421
+ var TraceSpanEventEntrySchema = z.object({
422
+ timeUnixNano: UnixNanoTimestampSchema,
423
+ name: nonEmptyString,
424
+ attributes: attributes.optional()
425
+ }).strict();
426
+ var TraceSpanEventSchema = z.object({
427
+ traceId: nonEmptyString,
428
+ spanId: nonEmptyString,
429
+ parentSpanId: nonEmptyString.optional(),
430
+ name: nonEmptyString,
431
+ startTimeUnixNano: UnixNanoTimestampSchema,
432
+ endTimeUnixNano: UnixNanoTimestampSchema,
433
+ attributes,
434
+ events: z.array(TraceSpanEventEntrySchema).optional(),
435
+ status: z.object({
436
+ code: z.enum(["OK", "ERROR", "UNSET"]),
437
+ message: z.string().optional()
438
+ }).strict().optional(),
439
+ "tangle.runId": nonEmptyString.optional(),
440
+ "tangle.generation": nonNegativeInteger.optional(),
441
+ "tangle.cellId": nonEmptyString.optional(),
442
+ "tangle.scenarioId": nonEmptyString.optional()
443
+ }).strict().refine((span) => BigInt(span.endTimeUnixNano) >= BigInt(span.startTimeUnixNano), {
444
+ path: ["endTimeUnixNano"],
445
+ message: "endTimeUnixNano must be greater than or equal to startTimeUnixNano"
446
+ });
447
+ var IngestEvalRunsEnvelopeSchema = z.object({
448
+ wireVersion: z.literal(HOSTED_WIRE_VERSION),
449
+ events: z.array(z.unknown())
450
+ }).strict();
451
+ var IngestTracesEnvelopeSchema = z.object({
452
+ wireVersion: z.literal(HOSTED_WIRE_VERSION),
453
+ spans: z.array(z.unknown())
454
+ }).strict();
455
+ var IngestEvalRunsRequestSchema = z.object({
456
+ wireVersion: z.literal(HOSTED_WIRE_VERSION),
457
+ events: z.array(EvalRunEventSchema)
458
+ }).strict();
459
+ var IngestTracesRequestSchema = z.object({
460
+ wireVersion: z.literal(HOSTED_WIRE_VERSION),
461
+ spans: z.array(TraceSpanEventSchema)
462
+ }).strict();
463
+ var IngestResponseSchema = z.object({
464
+ accepted: nonNegativeInteger,
465
+ rejected: z.array(
466
+ z.object({
467
+ index: nonNegativeInteger,
468
+ reason: nonEmptyString
469
+ }).strict()
470
+ )
471
+ }).strict();
472
+
473
+ // src/hosted/client.ts
474
+ var MAX_IDEMPOTENCY_KEY_LENGTH = 256;
475
+ function sleep(ms) {
476
+ return new Promise((resolve) => setTimeout(resolve, ms));
477
+ }
478
+ function normalizeHostedBase(endpoint) {
479
+ return endpoint.trim().replace(/\/+$/, "").replace(/\/v1$/, "");
480
+ }
481
+ function resolveIdempotencyKey(key) {
482
+ const resolved = key ?? globalThis.crypto.randomUUID();
483
+ if (resolved.trim().length === 0) throw new Error("idempotency key must not be blank");
484
+ if (resolved.length > MAX_IDEMPOTENCY_KEY_LENGTH) {
485
+ throw new Error(`idempotency key must be at most ${MAX_IDEMPOTENCY_KEY_LENGTH} characters`);
486
+ }
487
+ return resolved;
488
+ }
489
+ function responseValidationReason(error) {
490
+ return error.issues.map(
491
+ (issue) => `${issue.path.length > 0 ? issue.path.map(String).join(".") : "value"}: ${issue.message}`
492
+ ).join("; ");
493
+ }
494
+ async function post(tenant, path, body, opts = {}) {
495
+ const timeoutMs = tenant.timeoutMs ?? 3e4;
496
+ const maxRetries = tenant.retries ?? 2;
497
+ const f = tenant.fetchImpl ?? ((...args) => fetch(...args));
498
+ const base = normalizeHostedBase(tenant.endpoint);
499
+ const url = `${base}${path}`;
500
+ const idempotencyKey = resolveIdempotencyKey(opts.idempotencyKey);
501
+ const headers = {
502
+ "content-type": "application/json",
503
+ authorization: `Bearer ${tenant.apiKey}`,
504
+ "x-tangle-tenant-id": tenant.tenantId,
505
+ "x-tangle-wire-version": HOSTED_WIRE_VERSION,
506
+ "idempotency-key": idempotencyKey
507
+ };
508
+ let lastError;
509
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
510
+ const ourTimeout = AbortSignal.timeout(timeoutMs);
511
+ const combinedSignal = opts.signal ? AbortSignal.any([opts.signal, ourTimeout]) : ourTimeout;
512
+ let res;
513
+ try {
514
+ res = await f(url, {
515
+ method: "POST",
516
+ headers,
517
+ body: JSON.stringify(body),
518
+ signal: combinedSignal
519
+ });
520
+ } catch (err) {
521
+ if (opts.signal?.aborted) throw err;
522
+ lastError = err;
523
+ if (attempt === maxRetries) throw err;
524
+ await sleep(2 ** attempt * 200 + Math.random() * 200);
525
+ continue;
526
+ }
527
+ if (!res.ok) {
528
+ const text = await res.text().catch(() => "");
529
+ const error = new Error(`hosted ingest ${url} failed (${res.status}): ${text.slice(0, 500)}`);
530
+ const retryable = res.status >= 500 || res.status === 408 || res.status === 429;
531
+ if (!retryable || attempt === maxRetries) throw error;
532
+ lastError = error;
533
+ await sleep(2 ** attempt * 200 + Math.random() * 200);
534
+ continue;
535
+ }
536
+ let rawResponse;
537
+ try {
538
+ rawResponse = await res.json();
539
+ } catch (error) {
540
+ throw new Error(`hosted ingest ${url} returned invalid JSON`, { cause: error });
541
+ }
542
+ const parsed = IngestResponseSchema.safeParse(rawResponse);
543
+ if (!parsed.success) {
544
+ throw new Error(
545
+ `hosted ingest ${url} returned an invalid response: ${responseValidationReason(parsed.error)}`
546
+ );
547
+ }
548
+ return parsed.data;
549
+ }
550
+ throw lastError ?? new Error("hosted ingest exhausted retries");
551
+ }
552
+ function createHostedClient(tenant) {
553
+ if (normalizeHostedBase(tenant.endpoint).length === 0) throw new Error("endpoint is required");
554
+ if (tenant.apiKey.trim().length === 0) throw new Error("apiKey is required");
555
+ if (tenant.tenantId.trim().length === 0) throw new Error("tenantId is required");
556
+ if (tenant.timeoutMs !== void 0 && (!Number.isFinite(tenant.timeoutMs) || tenant.timeoutMs <= 0)) {
557
+ throw new Error("timeoutMs must be greater than 0");
558
+ }
559
+ if (tenant.retries !== void 0 && (!Number.isInteger(tenant.retries) || tenant.retries < 0)) {
560
+ throw new Error("retries must be a non-negative integer");
561
+ }
562
+ return {
563
+ tenant,
564
+ wireVersion: HOSTED_WIRE_VERSION,
565
+ async ingestEvalRun(event, idempotencyKey) {
566
+ return this.ingestEvalRuns([event], idempotencyKey);
567
+ },
568
+ async ingestEvalRuns(events, idempotencyKey) {
569
+ const body = IngestEvalRunsRequestSchema.parse({
570
+ wireVersion: HOSTED_WIRE_VERSION,
571
+ events
572
+ });
573
+ return post(tenant, "/v1/ingest/eval-runs", body, {
574
+ idempotencyKey
575
+ });
576
+ },
577
+ async ingestTraces(spans, idempotencyKey) {
578
+ const body = IngestTracesRequestSchema.parse({
579
+ wireVersion: HOSTED_WIRE_VERSION,
580
+ spans
581
+ });
582
+ return post(tenant, "/v1/ingest/traces", body, {
583
+ idempotencyKey
584
+ });
585
+ }
586
+ };
587
+ }
588
+ function hostedTenantFromEnv(overrides = {}) {
589
+ const env = overrides.env ?? process.env;
590
+ const endpoint = (overrides.endpoint ?? env.TANGLE_INGEST_URL ?? env.TANGLE_ORCHESTRATOR_URL)?.trim();
591
+ const apiKey = (overrides.apiKey ?? env.TANGLE_INGEST_API_KEY ?? env.TANGLE_API_KEY)?.trim();
592
+ const tenantId = (overrides.tenantId ?? env.TANGLE_TENANT_ID)?.trim();
593
+ if (!endpoint || !apiKey || !tenantId) return void 0;
594
+ const tenant = { endpoint: endpoint.replace(/\/+$/, ""), apiKey, tenantId };
595
+ if (overrides.fetchImpl) tenant.fetchImpl = overrides.fetchImpl;
596
+ if (overrides.timeoutMs !== void 0) tenant.timeoutMs = overrides.timeoutMs;
597
+ if (overrides.retries !== void 0) tenant.retries = overrides.retries;
598
+ return tenant;
599
+ }
600
+ function hostedClientFromEnv(overrides = {}) {
601
+ const tenant = hostedTenantFromEnv(overrides);
602
+ return tenant ? createHostedClient(tenant) : void 0;
603
+ }
604
+
605
+ export {
606
+ HOSTED_WIRE_VERSION,
607
+ UnixNanoTimestampSchema,
608
+ InsightReportSchema,
609
+ MutableSurfaceSchema,
610
+ RunTerminalOutcomeSchema,
611
+ EvalRunCellScoreSchema,
612
+ EvalRunGenerationSnapshotSchema,
613
+ EvalRunEventSchema,
614
+ TraceSpanEventSchema,
615
+ IngestEvalRunsRequestSchema,
616
+ IngestTracesRequestSchema,
617
+ IngestResponseSchema,
618
+ createHostedClient,
619
+ hostedTenantFromEnv,
620
+ hostedClientFromEnv
621
+ };
622
+ //# sourceMappingURL=chunk-DRYIUNWY.js.map