niceeval 0.17.0 → 0.18.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 (89) hide show
  1. package/INDEX.md +1 -0
  2. package/dist/adapter.cjs +4 -0
  3. package/dist/adapter.cjs.map +1 -1
  4. package/dist/adapter.d.cts +25 -14
  5. package/dist/adapter.d.mts +25 -14
  6. package/dist/adapter.d.ts +25 -14
  7. package/dist/assertions/measurements.cjs +45 -0
  8. package/dist/assertions/measurements.cjs.map +1 -0
  9. package/dist/assertions/measurements.d.cts +17 -0
  10. package/dist/assertions/measurements.d.mts +17 -0
  11. package/dist/assertions/measurements.d.ts +17 -0
  12. package/dist/assertions/measurements.js +8 -0
  13. package/dist/assertions/measurements.js.map +1 -0
  14. package/dist/define.cjs +2 -0
  15. package/dist/define.cjs.map +1 -1
  16. package/dist/expect/index.cjs +4 -1
  17. package/dist/expect/index.cjs.map +1 -1
  18. package/dist/expect/index.d.cts +3 -1
  19. package/dist/expect/index.d.mts +3 -1
  20. package/dist/expect/index.d.ts +3 -1
  21. package/dist/expect/index.js +20 -16
  22. package/dist/expect/index.mjs +20 -16
  23. package/dist/experiment/host/operations.cjs +3 -1
  24. package/dist/experiment/host/operations.cjs.map +1 -1
  25. package/dist/experiment/host/runtime.cjs +3 -1
  26. package/dist/experiment/host/runtime.cjs.map +1 -1
  27. package/dist/experiment/host/teardown.cjs +1 -0
  28. package/dist/experiment/host/teardown.cjs.map +1 -1
  29. package/dist/index.cjs +3 -19
  30. package/dist/index.cjs.map +1 -1
  31. package/dist/index.d.cts +3 -7
  32. package/dist/index.d.mts +3 -7
  33. package/dist/index.d.ts +3 -7
  34. package/dist/index.js +12 -34
  35. package/dist/index.mjs +12 -34
  36. package/dist/model-slots.cjs +19 -0
  37. package/dist/model-slots.cjs.map +1 -1
  38. package/dist/model-slots.d.cts +7 -0
  39. package/dist/model-slots.d.mts +7 -0
  40. package/dist/model-slots.d.ts +7 -0
  41. package/dist/model-slots.js +8 -2
  42. package/dist/o11y/eval-usage.cjs +20 -2
  43. package/dist/o11y/eval-usage.cjs.map +1 -1
  44. package/dist/o11y/eval-usage.d.cts +7 -2
  45. package/dist/o11y/eval-usage.d.mts +7 -2
  46. package/dist/o11y/eval-usage.d.ts +7 -2
  47. package/dist/runner/adoption.cjs +1 -0
  48. package/dist/runner/adoption.cjs.map +1 -1
  49. package/dist/runner/eval-selection.cjs +15 -1
  50. package/dist/runner/eval-selection.cjs.map +1 -1
  51. package/dist/runner/eval-selection.d.cts +4 -0
  52. package/dist/runner/eval-selection.d.mts +4 -0
  53. package/dist/runner/eval-selection.d.ts +4 -0
  54. package/dist/runner/lock.cjs +1 -3
  55. package/dist/runner/lock.cjs.map +1 -1
  56. package/dist/runner/lock.d.cts +0 -2
  57. package/dist/runner/lock.d.mts +0 -2
  58. package/dist/runner/lock.d.ts +0 -2
  59. package/dist/runner/lock.js +14 -16
  60. package/dist/runner/types.cjs.map +1 -1
  61. package/dist/runner/types.d.cts +1 -0
  62. package/dist/runner/types.d.mts +1 -0
  63. package/dist/runner/types.d.ts +1 -0
  64. package/dist/sandbox/docker-profile/registry.cjs +1 -2
  65. package/dist/sandbox/docker-profile/registry.cjs.map +1 -1
  66. package/dist/sandbox/docker-profile/registry.d.cts +0 -1
  67. package/dist/sandbox/docker-profile/registry.d.mts +0 -1
  68. package/dist/sandbox/docker-profile/registry.d.ts +0 -1
  69. package/dist/sandbox/docker-profile/registry.js +2 -4
  70. package/dist/sandbox/index.cjs +1 -2
  71. package/dist/sandbox/index.cjs.map +1 -1
  72. package/dist/sandbox/index.d.cts +1 -1
  73. package/dist/sandbox/index.d.mts +1 -1
  74. package/dist/sandbox/index.d.ts +1 -1
  75. package/dist/sandbox/index.js +32 -34
  76. package/dist/sandbox/index.mjs +32 -34
  77. package/docs-site/zh/examples/integrations/ai-sdk-v7.mdx +5 -5
  78. package/docs-site/zh/examples/integrations/claude-sdk.mdx +5 -5
  79. package/docs-site/zh/examples/integrations/langgraph.mdx +3 -3
  80. package/docs-site/zh/examples/integrations/pi-sdk.mdx +5 -5
  81. package/docs-site/zh/explanation/judge.mdx +1 -1
  82. package/docs-site/zh/index.mdx +18 -0
  83. package/docs-site/zh/introduction.mdx +2 -1
  84. package/docs-site/zh/reference/define-agent.mdx +2 -2
  85. package/docs-site/zh/tutorials/authoring.mdx +2 -1
  86. package/docs-site/zh/tutorials/control-run-cost.mdx +84 -5
  87. package/docs-site/zh/tutorials/upgrade-0-18.mdx +64 -0
  88. package/docs-site/zh/tutorials/verify-judge.mdx +2 -1
  89. package/package.json +1 -1
@@ -3,6 +3,12 @@ const __niceevalRequire = __niceevalCreateRequire(import.meta.url);
3
3
  const __niceevalCanonical = __niceevalRequire("./model-slots.cjs");
4
4
  const __niceevalExport0 = __niceevalCanonical["ResolvedModelSlotsSchema"];
5
5
  export { __niceevalExport0 as ResolvedModelSlotsSchema };
6
- const __niceevalExport1 = __niceevalCanonical["normalizeModelSlots"];
7
- export { __niceevalExport1 as normalizeModelSlots };
6
+ const __niceevalExport1 = __niceevalCanonical["assertRequiredModelSlots"];
7
+ export { __niceevalExport1 as assertRequiredModelSlots };
8
+ const __niceevalExport2 = __niceevalCanonical["defineModelSlots"];
9
+ export { __niceevalExport2 as defineModelSlots };
10
+ const __niceevalExport3 = __niceevalCanonical["normalizeModelRequirements"];
11
+ export { __niceevalExport3 as normalizeModelRequirements };
12
+ const __niceevalExport4 = __niceevalCanonical["normalizeModelSlots"];
13
+ export { __niceevalExport4 as normalizeModelSlots };
8
14
  //# sourceMappingURL=model-slots.js.map
@@ -5,6 +5,24 @@ exports.projectAgentEvalUsage = projectAgentEvalUsage;
5
5
  const cache_read_ts_1 = require("./cache-read.cjs");
6
6
  const pricing_ts_1 = require("../record/family/adapter-usage/pricing.cjs");
7
7
  const adapter_usage_projection_ts_1 = require("./adapter-usage-projection.cjs");
8
+ function authorCacheRead(report, models) {
9
+ const declared = new Set(Object.keys(models ?? {}));
10
+ const rates = new Map(report.modelSlots.map((group) => [group.modelSlot, group.rate]));
11
+ return Object.freeze({
12
+ ...report,
13
+ rate: (modelSlot) => {
14
+ if (modelSlot === undefined)
15
+ return report.total.rate;
16
+ if (!declared.has(modelSlot)) {
17
+ throw new TypeError(`Undeclared model slot ${JSON.stringify(modelSlot)}; declared slots: ${[...declared].join(", ") || "(none)"}.`);
18
+ }
19
+ const rate = rates.get(modelSlot);
20
+ if (rate !== undefined && !(rate.state === "unavailable" && rate.reason === "no-calls"))
21
+ return rate;
22
+ return Object.freeze({ state: "unavailable", reason: "slot-has-no-calls" });
23
+ },
24
+ });
25
+ }
8
26
  function contributionCosts(calls, complete) {
9
27
  const totals = (0, adapter_usage_projection_ts_1.effectiveCostTotals)(calls, complete ? "complete" : "partial");
10
28
  return Object.freeze({
@@ -26,7 +44,7 @@ function projectAdapterEvalUsage(usage, models) {
26
44
  scope: "attempt",
27
45
  basis: "recorded-calls",
28
46
  cut: "call-time",
29
- cacheRead: (0, cache_read_ts_1.projectCacheRead)(usage, models, true),
47
+ cacheRead: authorCacheRead((0, cache_read_ts_1.projectCacheRead)(usage, models, true), models),
30
48
  inputTokens: (0, adapter_usage_projection_ts_1.adapterTokenMaterial)(usage, "inputTokens"),
31
49
  inputTotalTokens: (0, adapter_usage_projection_ts_1.adapterTokenMaterial)(usage, "inputTotalTokens"),
32
50
  outputTokens: (0, adapter_usage_projection_ts_1.adapterTokenMaterial)(usage, "outputTokens"),
@@ -137,7 +155,7 @@ function projectAgentEvalUsage(input) {
137
155
  scope: input.scope,
138
156
  basis: "reported-sends",
139
157
  cut: "call-time",
140
- cacheRead: (0, cache_read_ts_1.projectCacheRead)(null, undefined, false, "adapter-usage-required"),
158
+ cacheRead: authorCacheRead((0, cache_read_ts_1.projectCacheRead)(null, undefined, false, "adapter-usage-required")),
141
159
  inputTokens: agentTokenMaterial(input.contributions, "inputTokens", input.scope),
142
160
  inputTotalTokens: agentTokenMaterial(input.contributions, "inputTotalTokens", input.scope),
143
161
  outputTokens: agentTokenMaterial(input.contributions, "outputTokens", input.scope),
@@ -1 +1 @@
1
- {"version":3,"file":"eval-usage.js","sourceRoot":"","sources":["eval-usage.ts"],"names":[],"mappings":"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","sourcesContent":["import { projectCacheRead, type CacheReadReport } from \"./cache-read.ts\";\nimport type { ResolvedModelSlots } from \"../model-slots.ts\";\nimport type { NumericMaterial } from \"../assertions/match.ts\";\nimport type { ResolvedEvidenceCoverage } from \"../assertions/coverage.ts\";\nimport type { PriceOverride, Usage } from \"../types.ts\";\nimport type { ReadableAdapterUsageAttachment } from \"../record/family/adapter-usage/schema.ts\";\nimport { addCanonicalDecimals, canonicalDecimalFromNumber, multiplyCanonicalDecimalPerMillion, } from \"../record/family/adapter-usage/pricing.ts\";\nimport { adapterTokenMaterial, effectiveCostTotals, effectiveUsageCalls, type EffectiveCallCost, } from \"./adapter-usage-projection.ts\";\n/** Internal source-owned shape; package-root exposure belongs to the author facade. */\nexport interface EvalUsage {\n readonly source: \"agent\" | \"adapter\" | \"unavailable\";\n readonly scope: \"turn\" | \"session\" | \"attempt\";\n readonly basis: \"reported-sends\" | \"recorded-calls\" | \"unbound\";\n readonly cut: \"call-time\";\n readonly cacheRead: CacheReadReport;\n readonly inputTokens: NumericMaterial;\n readonly inputTotalTokens: NumericMaterial;\n readonly outputTokens: NumericMaterial;\n readonly cacheReadTokens: NumericMaterial;\n readonly cacheWriteTokens: NumericMaterial;\n readonly totalTokens: NumericMaterial;\n readonly costs: {\n readonly state: \"complete\" | \"partial\" | \"unavailable\";\n readonly values: readonly {\n readonly currency: string;\n readonly value: string;\n readonly source: \"reported\" | \"estimated\" | \"mixed\";\n readonly coveredContributions: number;\n readonly reportedContributions: number;\n readonly estimatedContributions: number;\n }[];\n readonly totalContributions: number;\n };\n}\nexport interface AgentUsageContribution {\n readonly sessionScopeId: string;\n readonly turnId: string;\n readonly sendAttempt: number;\n readonly state: \"pending\" | \"terminal\";\n readonly outcome: \"completed\" | \"failed\" | \"interrupted\" | null;\n readonly model: string | null;\n readonly usage: Readonly<Usage> | null;\n readonly coverage: ResolvedEvidenceCoverage[\"usage\"];\n}\ntype TokenMetric = \"inputTokens\" | \"inputTotalTokens\" | \"outputTokens\" | \"cacheReadTokens\" | \"cacheWriteTokens\" | \"totalTokens\";\nfunction contributionCosts(calls: readonly {\n readonly effectiveCost: EffectiveCallCost | null;\n}[], complete: boolean): EvalUsage[\"costs\"] {\n const totals = effectiveCostTotals(calls, complete ? \"complete\" : \"partial\");\n return Object.freeze({\n state: totals.state,\n values: Object.freeze(totals.values.map((value) => Object.freeze({\n currency: value.currency,\n value: value.value,\n source: value.source,\n coveredContributions: value.coveredCalls,\n reportedContributions: value.reportedCalls,\n estimatedContributions: value.estimatedCalls,\n }))),\n totalContributions: totals.totalCalls,\n });\n}\nexport function projectAdapterEvalUsage(usage: ReadableAdapterUsageAttachment, models?: ResolvedModelSlots): EvalUsage {\n return Object.freeze({\n source: \"adapter\",\n scope: \"attempt\",\n basis: \"recorded-calls\",\n cut: \"call-time\",\n cacheRead: projectCacheRead(usage, models, true),\n inputTokens: adapterTokenMaterial(usage, \"inputTokens\"),\n inputTotalTokens: adapterTokenMaterial(usage, \"inputTotalTokens\"),\n outputTokens: adapterTokenMaterial(usage, \"outputTokens\"),\n cacheReadTokens: adapterTokenMaterial(usage, \"cacheReadTokens\"),\n cacheWriteTokens: adapterTokenMaterial(usage, \"cacheWriteTokens\"),\n totalTokens: adapterTokenMaterial(usage, \"totalTokens\"),\n costs: contributionCosts(effectiveUsageCalls(usage), usage.collection.state === \"complete\"),\n });\n}\nfunction tokenBuckets(contribution: AgentUsageContribution, metric: TokenMetric): readonly (number | undefined)[] {\n // Some producers have an independent total. Missing totals retain the mutually exclusive bucket fallback.\n const usage: (Readonly<Usage> & {\n readonly inputTotalTokens?: number;\n }) | null = contribution.usage;\n if (contribution.state === \"pending\" || usage === null)\n return [undefined];\n const input = usage.inputTotalTokens !== undefined\n ? [usage.inputTotalTokens]\n : [usage.inputTokens, usage.cacheReadTokens, usage.cacheCreationTokens];\n switch (metric) {\n case \"inputTotalTokens\": return input;\n case \"totalTokens\": return [...input, usage.outputTokens];\n case \"cacheWriteTokens\": return [usage.cacheCreationTokens];\n default: return [usage[metric]];\n }\n}\nfunction agentTokenMaterial(contributions: readonly AgentUsageContribution[], metric: TokenMetric, scope: EvalUsage[\"scope\"]): NumericMaterial {\n const provenance = Object.freeze({ source: \"agent\", scope, unit: \"tokens\", cut: \"call-time\" });\n let value = 0;\n let observed = false;\n let complete = contributions.length > 0;\n for (const contribution of contributions) {\n if (contribution.state !== \"terminal\" || contribution.coverage.status !== \"complete\")\n complete = false;\n for (const bucket of tokenBuckets(contribution, metric)) {\n if (bucket === undefined) {\n complete = false;\n continue;\n }\n if (!Number.isSafeInteger(bucket) || bucket < 0) {\n return Object.freeze({ state: \"unavailable\", reason: \"usage-invalid-token-value\", provenance });\n }\n value += bucket;\n observed = true;\n if (!Number.isSafeInteger(value)) {\n return Object.freeze({ state: \"unavailable\", reason: \"usage-exceeds-safe-integer\", provenance });\n }\n }\n }\n return Object.freeze(!observed\n ? { state: \"unavailable\", reason: \"usage-not-reported\", provenance }\n : { state: complete ? \"exact\" : \"lower-bound\", value, provenance });\n}\nfunction agentCost(contribution: AgentUsageContribution, pricing: Record<string, PriceOverride> | undefined): EffectiveCallCost | null {\n const usage = contribution.usage;\n if (contribution.state === \"pending\" || usage === null)\n return null;\n const coverageComplete = contribution.coverage.status === \"complete\";\n if (usage.costUSD !== undefined) {\n const amount = canonicalDecimalFromNumber(usage.costUSD);\n return amount === undefined ? null : Object.freeze({\n amount, currency: \"USD\", source: Object.freeze({ kind: \"reported\", id: \"agent-send\" }),\n state: coverageComplete ? \"complete\" : \"partial\",\n });\n }\n const model = contribution.model;\n if (model === null || pricing === undefined)\n return null;\n const wildcard = model.includes(\"/\") ? `${model.slice(0, model.indexOf(\"/\"))}/*` : undefined;\n const profile = Object.hasOwn(pricing, model) ? pricing[model]\n : wildcard !== undefined && Object.hasOwn(pricing, wildcard) ? pricing[wildcard] : undefined;\n if (profile === undefined || profile.currency !== undefined && profile.currency !== \"USD\" ||\n profile.basis !== undefined && profile.basis !== \"catalog-reference\")\n return null;\n const buckets = [\n [usage.inputTokens, profile.inputPerMTok],\n [usage.outputTokens, profile.outputPerMTok],\n [usage.cacheReadTokens, profile.cacheReadPerMTok],\n [usage.cacheCreationTokens, profile.cacheWritePerMTok],\n ] as const;\n const charges: string[] = [];\n let complete = coverageComplete;\n for (const [tokens, price] of buckets) {\n if (tokens === undefined || !Number.isSafeInteger(tokens) || tokens < 0) {\n complete = false;\n continue;\n }\n if (tokens === 0) {\n charges.push(\"0\");\n continue;\n }\n const rate = price === undefined ? undefined : canonicalDecimalFromNumber(price);\n if (rate === undefined) {\n complete = false;\n continue;\n }\n charges.push(multiplyCanonicalDecimalPerMillion(rate, tokens));\n }\n return charges.length === 0 ? null : Object.freeze({\n amount: addCanonicalDecimals(charges),\n currency: \"USD\",\n source: Object.freeze({ kind: \"estimated\", id: profile.source?.id ?? \"niceeval.config.pricing\" }),\n state: complete ? \"complete\" : \"partial\",\n });\n}\n/** The receiver selects scope membership before calling this pure projection. */\nexport function projectAgentEvalUsage(input: {\n contributions: readonly AgentUsageContribution[];\n scope: \"turn\" | \"session\" | \"attempt\";\n pricing?: Record<string, PriceOverride>;\n}): EvalUsage {\n return Object.freeze({\n source: \"agent\",\n scope: input.scope,\n basis: \"reported-sends\",\n cut: \"call-time\",\n cacheRead: projectCacheRead(null, undefined, false, \"adapter-usage-required\"),\n inputTokens: agentTokenMaterial(input.contributions, \"inputTokens\", input.scope),\n inputTotalTokens: agentTokenMaterial(input.contributions, \"inputTotalTokens\", input.scope),\n outputTokens: agentTokenMaterial(input.contributions, \"outputTokens\", input.scope),\n cacheReadTokens: agentTokenMaterial(input.contributions, \"cacheReadTokens\", input.scope),\n cacheWriteTokens: agentTokenMaterial(input.contributions, \"cacheWriteTokens\", input.scope),\n totalTokens: agentTokenMaterial(input.contributions, \"totalTokens\", input.scope),\n costs: contributionCosts(input.contributions.map((contribution) => ({\n effectiveCost: agentCost(contribution, input.pricing),\n })), input.contributions.every((contribution) => contribution.state === \"terminal\" && contribution.coverage.status === \"complete\")),\n });\n}\n"]}
1
+ {"version":3,"file":"eval-usage.js","sourceRoot":"","sources":["eval-usage.ts"],"names":[],"mappings":"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","sourcesContent":["import { projectCacheRead, type CacheReadReport } from \"./cache-read.ts\";\nimport type { ResolvedModelSlots } from \"../model-slots.ts\";\nimport type { NumericMaterial } from \"../assertions/match.ts\";\nimport type { ResolvedEvidenceCoverage } from \"../assertions/coverage.ts\";\nimport type { PriceOverride, Usage } from \"../types.ts\";\nimport type { ReadableAdapterUsageAttachment } from \"../record/family/adapter-usage/schema.ts\";\nimport { addCanonicalDecimals, canonicalDecimalFromNumber, multiplyCanonicalDecimalPerMillion, } from \"../record/family/adapter-usage/pricing.ts\";\nimport { adapterTokenMaterial, effectiveCostTotals, effectiveUsageCalls, type EffectiveCallCost, } from \"./adapter-usage-projection.ts\";\n/** Frozen cache report with author-facing selection by Experiment model purpose. */\nexport interface EvalCacheRead<ModelSlot extends string = string> extends CacheReadReport {\n /** Omit the slot for the total. An undeclared slot throws; missing observations remain unavailable. */\n rate(modelSlot?: ModelSlot): NumericMaterial;\n}\nfunction authorCacheRead(report: CacheReadReport, models?: ResolvedModelSlots): EvalCacheRead {\n const declared = new Set(Object.keys(models ?? {}));\n const rates = new Map(report.modelSlots.map((group) => [group.modelSlot, group.rate]));\n return Object.freeze({\n ...report,\n rate: (modelSlot?: string): NumericMaterial => {\n if (modelSlot === undefined)\n return report.total.rate;\n if (!declared.has(modelSlot)) {\n throw new TypeError(`Undeclared model slot ${JSON.stringify(modelSlot)}; declared slots: ${[...declared].join(\", \") || \"(none)\"}.`);\n }\n const rate = rates.get(modelSlot);\n if (rate !== undefined && !(rate.state === \"unavailable\" && rate.reason === \"no-calls\"))\n return rate;\n return Object.freeze({ state: \"unavailable\", reason: \"slot-has-no-calls\" });\n },\n });\n}\n/** Internal source-owned shape; package-root exposure belongs to the author facade. */\nexport interface EvalUsage<ModelSlot extends string = string> {\n readonly source: \"agent\" | \"adapter\" | \"unavailable\";\n readonly scope: \"turn\" | \"session\" | \"attempt\";\n readonly basis: \"reported-sends\" | \"recorded-calls\" | \"unbound\";\n readonly cut: \"call-time\";\n readonly cacheRead: EvalCacheRead<ModelSlot>;\n readonly inputTokens: NumericMaterial;\n readonly inputTotalTokens: NumericMaterial;\n readonly outputTokens: NumericMaterial;\n readonly cacheReadTokens: NumericMaterial;\n readonly cacheWriteTokens: NumericMaterial;\n readonly totalTokens: NumericMaterial;\n readonly costs: {\n readonly state: \"complete\" | \"partial\" | \"unavailable\";\n readonly values: readonly {\n readonly currency: string;\n readonly value: string;\n readonly source: \"reported\" | \"estimated\" | \"mixed\";\n readonly coveredContributions: number;\n readonly reportedContributions: number;\n readonly estimatedContributions: number;\n }[];\n readonly totalContributions: number;\n };\n}\nexport interface AgentUsageContribution {\n readonly sessionScopeId: string;\n readonly turnId: string;\n readonly sendAttempt: number;\n readonly state: \"pending\" | \"terminal\";\n readonly outcome: \"completed\" | \"failed\" | \"interrupted\" | null;\n readonly model: string | null;\n readonly usage: Readonly<Usage> | null;\n readonly coverage: ResolvedEvidenceCoverage[\"usage\"];\n}\ntype TokenMetric = \"inputTokens\" | \"inputTotalTokens\" | \"outputTokens\" | \"cacheReadTokens\" | \"cacheWriteTokens\" | \"totalTokens\";\nfunction contributionCosts(calls: readonly {\n readonly effectiveCost: EffectiveCallCost | null;\n}[], complete: boolean): EvalUsage[\"costs\"] {\n const totals = effectiveCostTotals(calls, complete ? \"complete\" : \"partial\");\n return Object.freeze({\n state: totals.state,\n values: Object.freeze(totals.values.map((value) => Object.freeze({\n currency: value.currency,\n value: value.value,\n source: value.source,\n coveredContributions: value.coveredCalls,\n reportedContributions: value.reportedCalls,\n estimatedContributions: value.estimatedCalls,\n }))),\n totalContributions: totals.totalCalls,\n });\n}\nexport function projectAdapterEvalUsage(usage: ReadableAdapterUsageAttachment, models?: ResolvedModelSlots): EvalUsage {\n return Object.freeze({\n source: \"adapter\",\n scope: \"attempt\",\n basis: \"recorded-calls\",\n cut: \"call-time\",\n cacheRead: authorCacheRead(projectCacheRead(usage, models, true), models),\n inputTokens: adapterTokenMaterial(usage, \"inputTokens\"),\n inputTotalTokens: adapterTokenMaterial(usage, \"inputTotalTokens\"),\n outputTokens: adapterTokenMaterial(usage, \"outputTokens\"),\n cacheReadTokens: adapterTokenMaterial(usage, \"cacheReadTokens\"),\n cacheWriteTokens: adapterTokenMaterial(usage, \"cacheWriteTokens\"),\n totalTokens: adapterTokenMaterial(usage, \"totalTokens\"),\n costs: contributionCosts(effectiveUsageCalls(usage), usage.collection.state === \"complete\"),\n });\n}\nfunction tokenBuckets(contribution: AgentUsageContribution, metric: TokenMetric): readonly (number | undefined)[] {\n // Some producers have an independent total. Missing totals retain the mutually exclusive bucket fallback.\n const usage: (Readonly<Usage> & {\n readonly inputTotalTokens?: number;\n }) | null = contribution.usage;\n if (contribution.state === \"pending\" || usage === null)\n return [undefined];\n const input = usage.inputTotalTokens !== undefined\n ? [usage.inputTotalTokens]\n : [usage.inputTokens, usage.cacheReadTokens, usage.cacheCreationTokens];\n switch (metric) {\n case \"inputTotalTokens\": return input;\n case \"totalTokens\": return [...input, usage.outputTokens];\n case \"cacheWriteTokens\": return [usage.cacheCreationTokens];\n default: return [usage[metric]];\n }\n}\nfunction agentTokenMaterial(contributions: readonly AgentUsageContribution[], metric: TokenMetric, scope: EvalUsage[\"scope\"]): NumericMaterial {\n const provenance = Object.freeze({ source: \"agent\", scope, unit: \"tokens\", cut: \"call-time\" });\n let value = 0;\n let observed = false;\n let complete = contributions.length > 0;\n for (const contribution of contributions) {\n if (contribution.state !== \"terminal\" || contribution.coverage.status !== \"complete\")\n complete = false;\n for (const bucket of tokenBuckets(contribution, metric)) {\n if (bucket === undefined) {\n complete = false;\n continue;\n }\n if (!Number.isSafeInteger(bucket) || bucket < 0) {\n return Object.freeze({ state: \"unavailable\", reason: \"usage-invalid-token-value\", provenance });\n }\n value += bucket;\n observed = true;\n if (!Number.isSafeInteger(value)) {\n return Object.freeze({ state: \"unavailable\", reason: \"usage-exceeds-safe-integer\", provenance });\n }\n }\n }\n return Object.freeze(!observed\n ? { state: \"unavailable\", reason: \"usage-not-reported\", provenance }\n : { state: complete ? \"exact\" : \"lower-bound\", value, provenance });\n}\nfunction agentCost(contribution: AgentUsageContribution, pricing: Record<string, PriceOverride> | undefined): EffectiveCallCost | null {\n const usage = contribution.usage;\n if (contribution.state === \"pending\" || usage === null)\n return null;\n const coverageComplete = contribution.coverage.status === \"complete\";\n if (usage.costUSD !== undefined) {\n const amount = canonicalDecimalFromNumber(usage.costUSD);\n return amount === undefined ? null : Object.freeze({\n amount, currency: \"USD\", source: Object.freeze({ kind: \"reported\", id: \"agent-send\" }),\n state: coverageComplete ? \"complete\" : \"partial\",\n });\n }\n const model = contribution.model;\n if (model === null || pricing === undefined)\n return null;\n const wildcard = model.includes(\"/\") ? `${model.slice(0, model.indexOf(\"/\"))}/*` : undefined;\n const profile = Object.hasOwn(pricing, model) ? pricing[model]\n : wildcard !== undefined && Object.hasOwn(pricing, wildcard) ? pricing[wildcard] : undefined;\n if (profile === undefined || profile.currency !== undefined && profile.currency !== \"USD\" ||\n profile.basis !== undefined && profile.basis !== \"catalog-reference\")\n return null;\n const buckets = [\n [usage.inputTokens, profile.inputPerMTok],\n [usage.outputTokens, profile.outputPerMTok],\n [usage.cacheReadTokens, profile.cacheReadPerMTok],\n [usage.cacheCreationTokens, profile.cacheWritePerMTok],\n ] as const;\n const charges: string[] = [];\n let complete = coverageComplete;\n for (const [tokens, price] of buckets) {\n if (tokens === undefined || !Number.isSafeInteger(tokens) || tokens < 0) {\n complete = false;\n continue;\n }\n if (tokens === 0) {\n charges.push(\"0\");\n continue;\n }\n const rate = price === undefined ? undefined : canonicalDecimalFromNumber(price);\n if (rate === undefined) {\n complete = false;\n continue;\n }\n charges.push(multiplyCanonicalDecimalPerMillion(rate, tokens));\n }\n return charges.length === 0 ? null : Object.freeze({\n amount: addCanonicalDecimals(charges),\n currency: \"USD\",\n source: Object.freeze({ kind: \"estimated\", id: profile.source?.id ?? \"niceeval.config.pricing\" }),\n state: complete ? \"complete\" : \"partial\",\n });\n}\n/** The receiver selects scope membership before calling this pure projection. */\nexport function projectAgentEvalUsage(input: {\n contributions: readonly AgentUsageContribution[];\n scope: \"turn\" | \"session\" | \"attempt\";\n pricing?: Record<string, PriceOverride>;\n}): EvalUsage {\n return Object.freeze({\n source: \"agent\",\n scope: input.scope,\n basis: \"reported-sends\",\n cut: \"call-time\",\n cacheRead: authorCacheRead(projectCacheRead(null, undefined, false, \"adapter-usage-required\")),\n inputTokens: agentTokenMaterial(input.contributions, \"inputTokens\", input.scope),\n inputTotalTokens: agentTokenMaterial(input.contributions, \"inputTotalTokens\", input.scope),\n outputTokens: agentTokenMaterial(input.contributions, \"outputTokens\", input.scope),\n cacheReadTokens: agentTokenMaterial(input.contributions, \"cacheReadTokens\", input.scope),\n cacheWriteTokens: agentTokenMaterial(input.contributions, \"cacheWriteTokens\", input.scope),\n totalTokens: agentTokenMaterial(input.contributions, \"totalTokens\", input.scope),\n costs: contributionCosts(input.contributions.map((contribution) => ({\n effectiveCost: agentCost(contribution, input.pricing),\n })), input.contributions.every((contribution) => contribution.state === \"terminal\" && contribution.coverage.status === \"complete\")),\n });\n}\n"]}
@@ -4,13 +4,18 @@ import type { NumericMaterial } from "../assertions/match.cjs";
4
4
  import type { ResolvedEvidenceCoverage } from "../assertions/coverage.cjs";
5
5
  import type { PriceOverride, Usage } from "../types.cjs";
6
6
  import type { ReadableAdapterUsageAttachment } from "../record/family/adapter-usage/schema.cjs";
7
+ /** Frozen cache report with author-facing selection by Experiment model purpose. */
8
+ export interface EvalCacheRead<ModelSlot extends string = string> extends CacheReadReport {
9
+ /** Omit the slot for the total. An undeclared slot throws; missing observations remain unavailable. */
10
+ rate(modelSlot?: ModelSlot): NumericMaterial;
11
+ }
7
12
  /** Internal source-owned shape; package-root exposure belongs to the author facade. */
8
- export interface EvalUsage {
13
+ export interface EvalUsage<ModelSlot extends string = string> {
9
14
  readonly source: "agent" | "adapter" | "unavailable";
10
15
  readonly scope: "turn" | "session" | "attempt";
11
16
  readonly basis: "reported-sends" | "recorded-calls" | "unbound";
12
17
  readonly cut: "call-time";
13
- readonly cacheRead: CacheReadReport;
18
+ readonly cacheRead: EvalCacheRead<ModelSlot>;
14
19
  readonly inputTokens: NumericMaterial;
15
20
  readonly inputTotalTokens: NumericMaterial;
16
21
  readonly outputTokens: NumericMaterial;
@@ -4,13 +4,18 @@ import type { NumericMaterial } from "../assertions/match.mjs";
4
4
  import type { ResolvedEvidenceCoverage } from "../assertions/coverage.mjs";
5
5
  import type { PriceOverride, Usage } from "../types.mjs";
6
6
  import type { ReadableAdapterUsageAttachment } from "../record/family/adapter-usage/schema.mjs";
7
+ /** Frozen cache report with author-facing selection by Experiment model purpose. */
8
+ export interface EvalCacheRead<ModelSlot extends string = string> extends CacheReadReport {
9
+ /** Omit the slot for the total. An undeclared slot throws; missing observations remain unavailable. */
10
+ rate(modelSlot?: ModelSlot): NumericMaterial;
11
+ }
7
12
  /** Internal source-owned shape; package-root exposure belongs to the author facade. */
8
- export interface EvalUsage {
13
+ export interface EvalUsage<ModelSlot extends string = string> {
9
14
  readonly source: "agent" | "adapter" | "unavailable";
10
15
  readonly scope: "turn" | "session" | "attempt";
11
16
  readonly basis: "reported-sends" | "recorded-calls" | "unbound";
12
17
  readonly cut: "call-time";
13
- readonly cacheRead: CacheReadReport;
18
+ readonly cacheRead: EvalCacheRead<ModelSlot>;
14
19
  readonly inputTokens: NumericMaterial;
15
20
  readonly inputTotalTokens: NumericMaterial;
16
21
  readonly outputTokens: NumericMaterial;
@@ -4,13 +4,18 @@ import type { NumericMaterial } from "../assertions/match.js";
4
4
  import type { ResolvedEvidenceCoverage } from "../assertions/coverage.js";
5
5
  import type { PriceOverride, Usage } from "../types.js";
6
6
  import type { ReadableAdapterUsageAttachment } from "../record/family/adapter-usage/schema.js";
7
+ /** Frozen cache report with author-facing selection by Experiment model purpose. */
8
+ export interface EvalCacheRead<ModelSlot extends string = string> extends CacheReadReport {
9
+ /** Omit the slot for the total. An undeclared slot throws; missing observations remain unavailable. */
10
+ rate(modelSlot?: ModelSlot): NumericMaterial;
11
+ }
7
12
  /** Internal source-owned shape; package-root exposure belongs to the author facade. */
8
- export interface EvalUsage {
13
+ export interface EvalUsage<ModelSlot extends string = string> {
9
14
  readonly source: "agent" | "adapter" | "unavailable";
10
15
  readonly scope: "turn" | "session" | "attempt";
11
16
  readonly basis: "reported-sends" | "recorded-calls" | "unbound";
12
17
  readonly cut: "call-time";
13
- readonly cacheRead: CacheReadReport;
18
+ readonly cacheRead: EvalCacheRead<ModelSlot>;
14
19
  readonly inputTokens: NumericMaterial;
15
20
  readonly inputTotalTokens: NumericMaterial;
16
21
  readonly outputTokens: NumericMaterial;
@@ -224,6 +224,7 @@ function prepareCurrentAdoptionTarget(input) {
224
224
  const selection = yield* effect_1.Effect.try({
225
225
  try: () => (0, eval_selection_ts_1.resolveExperimentEvals)({
226
226
  experimentId: experiment.id,
227
+ models: experiment.models,
227
228
  selector: experiment.evals,
228
229
  cliPatterns: [],
229
230
  evals: input.project.evals,