modelrig 0.11.1 → 0.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 (182) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/dist/adapters/anthropic.d.ts +4 -4
  3. package/dist/adapters/anthropic.d.ts.map +1 -1
  4. package/dist/adapters/anthropic.js +8 -1
  5. package/dist/adapters/deepseek.d.ts +2 -4
  6. package/dist/adapters/deepseek.d.ts.map +1 -1
  7. package/dist/adapters/deepseek.js +9 -5
  8. package/dist/adapters/gemini.d.ts +4 -1
  9. package/dist/adapters/gemini.d.ts.map +1 -1
  10. package/dist/adapters/gemini.js +16 -1
  11. package/dist/adapters/grok.d.ts +2 -4
  12. package/dist/adapters/grok.d.ts.map +1 -1
  13. package/dist/adapters/grok.js +8 -4
  14. package/dist/adapters/history-mapping.d.ts +126 -0
  15. package/dist/adapters/history-mapping.d.ts.map +1 -0
  16. package/dist/adapters/history-mapping.js +230 -0
  17. package/dist/adapters/openai-compat.d.ts +2 -4
  18. package/dist/adapters/openai-compat.d.ts.map +1 -1
  19. package/dist/adapters/openai-compat.js +9 -5
  20. package/dist/adapters/openai.d.ts +2 -4
  21. package/dist/adapters/openai.d.ts.map +1 -1
  22. package/dist/adapters/openai.js +8 -4
  23. package/dist/adapters/responses-api.d.ts.map +1 -1
  24. package/dist/adapters/responses-api.js +9 -4
  25. package/dist/artifacts/artifact.d.ts.map +1 -1
  26. package/dist/artifacts/artifact.js +79 -0
  27. package/dist/artifacts/conversation.d.ts +128 -0
  28. package/dist/artifacts/conversation.d.ts.map +1 -0
  29. package/dist/artifacts/conversation.js +172 -0
  30. package/dist/artifacts/index.d.ts +1 -1
  31. package/dist/artifacts/index.d.ts.map +1 -1
  32. package/dist/artifacts/media.d.ts +46 -0
  33. package/dist/artifacts/media.d.ts.map +1 -0
  34. package/dist/artifacts/media.js +88 -0
  35. package/dist/artifacts/run-context.d.ts +61 -2
  36. package/dist/artifacts/run-context.d.ts.map +1 -1
  37. package/dist/artifacts/run-context.js +183 -12
  38. package/dist/artifacts/scrub.d.ts +3 -0
  39. package/dist/artifacts/scrub.d.ts.map +1 -1
  40. package/dist/bakeoff/engine.d.ts.map +1 -1
  41. package/dist/bakeoff/engine.js +34 -7
  42. package/dist/bakeoff/eval-cases.d.ts +5 -0
  43. package/dist/bakeoff/eval-cases.d.ts.map +1 -1
  44. package/dist/bakeoff/eval-cases.js +10 -1
  45. package/dist/bakeoff/replay.d.ts +15 -0
  46. package/dist/bakeoff/replay.d.ts.map +1 -1
  47. package/dist/bakeoff/replay.js +19 -1
  48. package/dist/bakeoff/report.d.ts.map +1 -1
  49. package/dist/bakeoff/report.js +9 -2
  50. package/dist/bakeoff/turn-replay.d.ts +93 -0
  51. package/dist/bakeoff/turn-replay.d.ts.map +1 -0
  52. package/dist/bakeoff/turn-replay.js +150 -0
  53. package/dist/bakeoff/types.d.ts +12 -0
  54. package/dist/bakeoff/types.d.ts.map +1 -1
  55. package/dist/feedback/grade.d.ts +7 -2
  56. package/dist/feedback/grade.d.ts.map +1 -1
  57. package/dist/feedback/grade.js +14 -0
  58. package/dist/feedback/outcome.d.ts +103 -0
  59. package/dist/feedback/outcome.d.ts.map +1 -0
  60. package/dist/feedback/outcome.js +175 -0
  61. package/dist/gateway/history-bridge.d.ts +32 -0
  62. package/dist/gateway/history-bridge.d.ts.map +1 -0
  63. package/dist/gateway/history-bridge.js +64 -0
  64. package/dist/gateway/serve-client.d.ts.map +1 -1
  65. package/dist/gateway/serve-client.js +6 -0
  66. package/dist/index.d.ts +44 -1
  67. package/dist/index.d.ts.map +1 -1
  68. package/dist/index.js +106 -6
  69. package/dist/init/observe.d.ts.map +1 -1
  70. package/dist/init/observe.js +3 -3
  71. package/dist/registry/build.d.ts +4 -0
  72. package/dist/registry/build.d.ts.map +1 -1
  73. package/dist/registry/generation-models.d.ts +68 -0
  74. package/dist/registry/generation-models.d.ts.map +1 -0
  75. package/dist/registry/generation-models.js +168 -0
  76. package/dist/registry/model-kind.d.ts +34 -0
  77. package/dist/registry/model-kind.d.ts.map +1 -0
  78. package/dist/registry/model-kind.js +40 -0
  79. package/dist/registry/pricing-shape.d.ts +29 -1
  80. package/dist/registry/pricing-shape.d.ts.map +1 -1
  81. package/dist/registry/pricing-shape.js +9 -0
  82. package/dist/registry/pricing.d.ts +26 -0
  83. package/dist/registry/pricing.d.ts.map +1 -1
  84. package/dist/registry/pricing.js +29 -0
  85. package/dist/registry/rows.d.ts.map +1 -1
  86. package/dist/registry/rows.js +3 -1
  87. package/dist/registry/unit-pricing.d.ts +32 -0
  88. package/dist/registry/unit-pricing.d.ts.map +1 -0
  89. package/dist/registry/unit-pricing.js +62 -0
  90. package/dist/routes/input-loader.d.ts +38 -0
  91. package/dist/routes/input-loader.d.ts.map +1 -0
  92. package/dist/routes/input-loader.js +80 -0
  93. package/dist/routes/loader.d.ts.map +1 -1
  94. package/dist/routes/loader.js +3 -0
  95. package/dist/routes/resolved-bundle.d.ts +2 -0
  96. package/dist/routes/resolved-bundle.d.ts.map +1 -1
  97. package/dist/routes/resolved-bundle.js +3 -0
  98. package/dist/run/cost.d.ts +28 -0
  99. package/dist/run/cost.d.ts.map +1 -1
  100. package/dist/run/cost.js +74 -0
  101. package/dist/run/dispatch.d.ts +4 -1
  102. package/dist/run/dispatch.d.ts.map +1 -1
  103. package/dist/run/dispatch.js +3 -0
  104. package/dist/run/limits.d.ts +88 -0
  105. package/dist/run/limits.d.ts.map +1 -0
  106. package/dist/run/limits.js +155 -0
  107. package/dist/run/messages.d.ts +199 -0
  108. package/dist/run/messages.d.ts.map +1 -0
  109. package/dist/run/messages.js +430 -0
  110. package/dist/run/raw-finalize.d.ts +5 -2
  111. package/dist/run/raw-finalize.d.ts.map +1 -1
  112. package/dist/run/raw-finalize.js +8 -5
  113. package/dist/run/raw-request.d.ts.map +1 -1
  114. package/dist/run/raw-request.js +2 -1
  115. package/dist/run/raw.d.ts +10 -4
  116. package/dist/run/raw.d.ts.map +1 -1
  117. package/dist/run/raw.js +11 -3
  118. package/dist/run/record-attempt.d.ts.map +1 -1
  119. package/dist/run/record-attempt.js +16 -6
  120. package/dist/run/record-call.d.ts +13 -2
  121. package/dist/run/record-call.d.ts.map +1 -1
  122. package/dist/run/record-call.js +50 -7
  123. package/dist/run/run.d.ts.map +1 -1
  124. package/dist/run/run.js +12 -8
  125. package/dist/telemetry/attempt-meta.d.ts +49 -1
  126. package/dist/telemetry/attempt-meta.d.ts.map +1 -1
  127. package/dist/telemetry/attempt-meta.js +45 -1
  128. package/dist/telemetry/exporter.d.ts.map +1 -1
  129. package/dist/telemetry/exporter.js +2 -1
  130. package/dist/telemetry/grade-mappers.d.ts +1 -1
  131. package/dist/telemetry/grade-mappers.d.ts.map +1 -1
  132. package/dist/telemetry/grade-mappers.js +7 -1
  133. package/dist/telemetry/grade-task.d.ts +49 -0
  134. package/dist/telemetry/grade-task.d.ts.map +1 -0
  135. package/dist/telemetry/grade-task.js +85 -0
  136. package/dist/telemetry/grades-sql.d.ts +16 -1
  137. package/dist/telemetry/grades-sql.d.ts.map +1 -1
  138. package/dist/telemetry/grades-sql.js +64 -4
  139. package/dist/telemetry/ingest-protocol.d.ts +24 -1
  140. package/dist/telemetry/ingest-protocol.d.ts.map +1 -1
  141. package/dist/telemetry/ingest-protocol.js +72 -43
  142. package/dist/telemetry/otel-content.d.ts +31 -0
  143. package/dist/telemetry/otel-content.d.ts.map +1 -0
  144. package/dist/telemetry/otel-content.js +106 -0
  145. package/dist/telemetry/otel-hierarchy.d.ts +57 -0
  146. package/dist/telemetry/otel-hierarchy.d.ts.map +1 -0
  147. package/dist/telemetry/otel-hierarchy.js +155 -0
  148. package/dist/telemetry/otel-normalize.d.ts +15 -1
  149. package/dist/telemetry/otel-normalize.d.ts.map +1 -1
  150. package/dist/telemetry/otel-normalize.js +24 -39
  151. package/dist/telemetry/sinks.d.ts +4 -1
  152. package/dist/telemetry/sinks.d.ts.map +1 -1
  153. package/dist/telemetry/sinks.js +53 -34
  154. package/dist/telemetry/store-migrations.d.ts.map +1 -1
  155. package/dist/telemetry/store-migrations.js +8 -0
  156. package/dist/telemetry/store.d.ts +9 -0
  157. package/dist/telemetry/store.d.ts.map +1 -1
  158. package/dist/telemetry/store.js +10 -0
  159. package/dist/telemetry/uniform-rows.d.ts +43 -0
  160. package/dist/telemetry/uniform-rows.d.ts.map +1 -0
  161. package/dist/telemetry/uniform-rows.js +139 -0
  162. package/dist/types/failures-teaching.d.ts.map +1 -1
  163. package/dist/types/failures-teaching.js +11 -0
  164. package/dist/types/failures.d.ts +1 -1
  165. package/dist/types/failures.d.ts.map +1 -1
  166. package/dist/types/failures.js +2 -0
  167. package/dist/types/provider.d.ts +12 -0
  168. package/dist/types/provider.d.ts.map +1 -1
  169. package/dist/types/route.d.ts +13 -0
  170. package/dist/types/route.d.ts.map +1 -1
  171. package/dist/types/telemetry.d.ts +14 -1
  172. package/dist/types/telemetry.d.ts.map +1 -1
  173. package/docs/agent-skill/SKILL.md +16 -3
  174. package/docs/how-it-fits.md +3 -3
  175. package/docs/instrumentation.md +15 -6
  176. package/docs/llms.txt +55 -7
  177. package/docs/mcp-oracle.md +15 -4
  178. package/docs/quickstart.md +6 -5
  179. package/package.json +4 -2
  180. package/registry/registry.json +456 -0
  181. package/templates/creative-approval.json +81 -0
  182. package/templates/support-conversation.json +82 -0
@@ -75,12 +75,16 @@ function createRecordAttempt(deps) {
75
75
  const isPrimary = attempt.repairedBy === undefined;
76
76
  const cacheStamp = isPrimary ? (0, cache_stamp_1.cacheStampForCandidate)(route, attempt.candidate) : null;
77
77
  // The customer key marks rows whose REQUEST carried the handle. A terminal
78
- // failure (budget_exhausted / invariant_violation) is recorded by failRun
79
- // BEFORE any dispatch — the wire never carried the handle — so those rows
80
- // must not claim a customer key. Terminal classes come only from failRun;
81
- // adapters never return them. (A grounding-search failure is the one
82
- // non-terminal pre-dispatch path, but a customer cachedContents handle and
83
- // the inject rung are mutually exclusive, so it is unreachable in practice.)
78
+ // failure (budget_exhausted / invariant_violation) is always a PRE-DISPATCH
79
+ // outcome — the wire never carried the handle — so those rows must not claim
80
+ // a customer key. Terminal classes come from failRun, and from adapter guards
81
+ // that refuse BEFORE building a provider client (gemini's non-thinking-model
82
+ // `reasoning` guard; the ARC-β messages-lane history guards in anthropic.ts /
83
+ // gemini.ts, which the run loop normally pre-empts by skipping incompatible
84
+ // candidates — run/messages.ts). No adapter returns a terminal class after a
85
+ // provider call. (A grounding-search failure is the one non-terminal
86
+ // pre-dispatch path, but a customer cachedContents handle and the inject rung
87
+ // are mutually exclusive, so it is unreachable in practice.)
84
88
  const preDispatch = attempt.failure !== null && failures_1.TERMINAL_CLASSES.has(attempt.failure.class);
85
89
  const dropped = droppedCacheHandle.has(`${attempt.candidate.provider} ${attempt.candidate.model}`);
86
90
  const customer = isPrimary && !preDispatch ? (0, cache_handle_1.customerCacheHandle)(cache, attempt.candidate, dropped) : null;
@@ -183,6 +187,12 @@ function createRecordAttempt(deps) {
183
187
  startedAt: row.ts,
184
188
  endedAt: new Date().toISOString(),
185
189
  failureClass: row.failureClass,
190
+ // ARC-5: cost + requested tool calls feed the run-limit tally (a success
191
+ // with no tool call breaks a repeat streak; a failure leaves it as is).
192
+ costUsd: row.costEstimateUsd,
193
+ ...(attempt.toolCalls !== undefined
194
+ ? { toolCalls: attempt.toolCalls.map((t) => ({ name: t.function.name, arguments: t.function.arguments })) }
195
+ : attempt.failure === null ? { toolCalls: [] } : {}),
186
196
  });
187
197
  }
188
198
  return row.id;
@@ -25,6 +25,7 @@
25
25
  * No route/registry/capability-gate dependency beyond the raw lane's own (cost
26
26
  * + telemetry + run context) — the raw lane's no-hard-hot-path invariant holds.
27
27
  */
28
+ import { type RecordedUnits } from "../telemetry/attempt-meta";
28
29
  import type { FailureClass } from "../types/failures";
29
30
  import type { ProviderId, ServiceTier } from "../types/provider";
30
31
  import type { RunTags } from "../types/route";
@@ -50,7 +51,16 @@ export interface RecordCallInput {
50
51
  * recorded at $0 with `pricingMissing: true`. */
51
52
  readonly provider: ProviderId | (string & {});
52
53
  readonly model: string;
54
+ /** Token usage. A generation call billed per image/second/character reports
55
+ * `{ tokensIn: 0, tokensOut: 0 }` and its `units`. */
53
56
  readonly usage: RecordCallUsage;
57
+ /** ARC-4: the call's non-token units — images generated, seconds of audio or
58
+ * video, characters synthesized, diffusion steps. Non-negative finite
59
+ * numbers; at least one must be > 0 when the token counts are all zero.
60
+ * Recorded on `meta.units` and priced from the registry, then the vendored
61
+ * pricing map, else `pricingMissing` (never from token rates). `steps` is
62
+ * recorded, never priced. */
63
+ readonly units?: RecordedUnits;
54
64
  /** The tier that SERVED the call — the row is priced at it (flex is cheaper),
55
65
  * exactly as the raw lane prices. Default `"standard"`. */
56
66
  readonly servedTier?: ServiceTier;
@@ -76,8 +86,9 @@ export interface RecordCallResult {
76
86
  * was rejected and nothing was recorded. */
77
87
  readonly inferenceId: string | null;
78
88
  readonly callId: string | null;
79
- /** The token row's list-price cost (a `webSearchCalls` surcharge rides its own
80
- * row, as on the raw lane). 0 when unpriced or rejected. */
89
+ /** The row's list-price cost — tokens plus any priced `units` (a
90
+ * `webSearchCalls` surcharge rides its own row, as on the raw lane). 0 when
91
+ * unpriced or rejected. */
81
92
  readonly costEstimateUsd: number;
82
93
  readonly pricingMissing: boolean;
83
94
  }
@@ -1 +1 @@
1
- {"version":3,"file":"record-call.d.ts","sourceRoot":"","sources":["../../src/run/record-call.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAYH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,EAAgB,UAAU,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAC/E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAExC,2FAA2F;AAC3F,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,kEAAkE;AAClE,eAAO,MAAM,oBAAoB,2CAA2C,CAAC;AAE7E;;;;gFAIgF;AAChF,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;CACnC;AAED,MAAM,WAAW,eAAe;IAC9B;qDACiD;IACjD,QAAQ,CAAC,QAAQ,EAAE,UAAU,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;IAC9C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAC;IAChC;+DAC2D;IAC3D,QAAQ,CAAC,UAAU,CAAC,EAAE,WAAW,CAAC;IAClC,2DAA2D;IAC3D,QAAQ,CAAC,aAAa,CAAC,EAAE,WAAW,CAAC;IACrC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,sEAAsE;IACtE,QAAQ,CAAC,YAAY,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;IAC5C;8EAC0E;IAC1E,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,0EAA0E;IAC1E,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC;sDACkD;IAClD,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,gBAAgB;IAC/B;gDAC4C;IAC5C,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B;gEAC4D;IAC5D,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;CAClC;AAQD,kGAAkG;AAClG,eAAO,MAAM,eAAe,MAAM,CAAC;AAcnC,wDAAwD;AACxD,wBAAgB,8BAA8B,IAAI,IAAI,CAErD;AAMD,+EAA+E;AAC/E,eAAO,MAAM,MAAM,aAAgB,CAAC;AAEpC;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAEtD;AA6GD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,eAAe,GAAG,gBAAgB,CAarF"}
1
+ {"version":3,"file":"record-call.d.ts","sourceRoot":"","sources":["../../src/run/record-call.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AASH,OAAO,EAAsF,KAAK,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAGnJ,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,EAAgB,UAAU,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAC/E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAExC,2FAA2F;AAC3F,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,kEAAkE;AAClE,eAAO,MAAM,oBAAoB,2CAA2C,CAAC;AAE7E;;;;gFAIgF;AAChF,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;CACnC;AAED,MAAM,WAAW,eAAe;IAC9B;qDACiD;IACjD,QAAQ,CAAC,QAAQ,EAAE,UAAU,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;IAC9C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB;0DACsD;IACtD,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAC;IAChC;;;;;iCAK6B;IAC7B,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC;IAC/B;+DAC2D;IAC3D,QAAQ,CAAC,UAAU,CAAC,EAAE,WAAW,CAAC;IAClC,2DAA2D;IAC3D,QAAQ,CAAC,aAAa,CAAC,EAAE,WAAW,CAAC;IACrC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,sEAAsE;IACtE,QAAQ,CAAC,YAAY,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;IAC5C;8EAC0E;IAC1E,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,0EAA0E;IAC1E,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC;sDACkD;IAClD,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,gBAAgB;IAC/B;gDAC4C;IAC5C,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B;;+BAE2B;IAC3B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;CAClC;AAQD,kGAAkG;AAClG,eAAO,MAAM,eAAe,MAAM,CAAC;AAcnC,wDAAwD;AACxD,wBAAgB,8BAA8B,IAAI,IAAI,CAErD;AAMD,+EAA+E;AAC/E,eAAO,MAAM,MAAM,aAAgB,CAAC;AAEpC;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAEtD;AA4ID;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,eAAe,GAAG,gBAAgB,CAarF"}
@@ -117,6 +117,9 @@ function validateShape(input) {
117
117
  fix: `shorten the provider or model id so "provider/model" is at most ${exports.MAX_ROUTE_CHARS} characters`,
118
118
  };
119
119
  }
120
+ const unitsProblem = validateUnits(i.units, i.usage);
121
+ if (unitsProblem !== null)
122
+ return unitsProblem;
120
123
  const u = i.usage;
121
124
  if (typeof u !== "object" || u === null || !isCount(u.tokensIn) || !isCount(u.tokensOut)) {
122
125
  return {
@@ -174,6 +177,34 @@ function validateShape(input) {
174
177
  }
175
178
  return null;
176
179
  }
180
+ const UNIT_KEY_SET = new Set(attempt_meta_1.UNIT_KEYS);
181
+ /** ARC-4 `units` rules. Every fix string is built from SDK constants only (it
182
+ * doubles as the warning-latch rule id). */
183
+ function validateUnits(units, usage) {
184
+ if (units === undefined)
185
+ return null;
186
+ if (typeof units !== "object" || units === null || Array.isArray(units)) {
187
+ return { problem: "units is not an object", fix: `pass units as { ${attempt_meta_1.UNIT_KEYS.join("?, ")}? } numbers, or omit it` };
188
+ }
189
+ for (const [k, v] of Object.entries(units)) {
190
+ if (!UNIT_KEY_SET.has(k)) {
191
+ return { problem: "units carries an unknown key", fix: `units keys are ${attempt_meta_1.UNIT_KEYS.join(", ")}` };
192
+ }
193
+ if (v !== undefined && !isCount(v)) {
194
+ return { problem: `units.${k} is not a non-negative number`, fix: `omit units.${k} or pass a finite number ≥ 0` };
195
+ }
196
+ }
197
+ const u = (typeof usage === "object" && usage !== null ? usage : {});
198
+ const tokensZero = tok(u.tokensIn) === 0 && tok(u.tokensOut) === 0;
199
+ const anyUnit = Object.values(units).some((v) => typeof v === "number" && v > 0);
200
+ if (tokensZero && !anyUnit) {
201
+ return {
202
+ problem: "units are all zero and the call reports no tokens",
203
+ fix: "report what the call produced — e.g. units: { images: 1 } for one generated image, { seconds: 8 } for an 8 s clip, { characters: 1200 } for a TTS request",
204
+ };
205
+ }
206
+ return null;
207
+ }
177
208
  /** Normalize a caller finish reason: an enum value passes; a provider-native one
178
209
  * maps through the adapters' own table; empty ⇒ absent. */
179
210
  function finishReasonOf(provider, raw) {
@@ -212,21 +243,31 @@ function record(deps, input) {
212
243
  const servedTier = input.servedTier ?? "standard";
213
244
  const requestedTier = input.requestedTier ?? servedTier;
214
245
  // MUST-3: integers only on the row (rounded + clamped — see toCount).
246
+ const reported = input.usage;
215
247
  const usage = {
216
- tokensIn: tok(input.usage.tokensIn),
217
- tokensOut: tok(input.usage.tokensOut),
218
- tokensCached: tok(input.usage.tokensCached),
219
- ...(input.usage.tokensCacheWrite !== undefined ? { tokensCacheWrite: tok(input.usage.tokensCacheWrite) } : {}),
248
+ tokensIn: tok(reported.tokensIn),
249
+ tokensOut: tok(reported.tokensOut),
250
+ tokensCached: tok(reported.tokensCached),
251
+ ...(reported.tokensCacheWrite !== undefined ? { tokensCacheWrite: tok(reported.tokensCacheWrite) } : {}),
220
252
  servedTier,
221
253
  ...(input.ttfbMs !== undefined ? { ttfbMs: toCount(input.ttfbMs, exports.MAX_MS) } : {}),
222
254
  };
223
255
  const latencyMs = toCount(input.latencyMs, exports.MAX_MS);
256
+ const units = (0, attempt_meta_1.cleanUnits)(input.units);
224
257
  // Priced exactly like the raw lane: list price at the SERVED tier. A provider
225
258
  // ModelRig has no price table for is recorded honestly at $0, flagged.
226
259
  const unpricedRatePerTok = (deps.unpricedRateUsdPerMTok ?? cost_1.DEFAULT_UNPRICED_RATE_USD_PER_MTOK) / 1000000;
227
- const { costUsd, pricingMissing } = known
260
+ const tokenCost = known
228
261
  ? (0, cost_1.attemptCost)(provider, input.model, usage, unpricedRatePerTok)
229
262
  : { costUsd: 0, pricingMissing: true };
263
+ // ARC-4: units price separately (registry → pricing map → missing; never from
264
+ // token rates) and ADD to the token cost. With units present, a zero-token
265
+ // call's token price is moot, so only nonzero tokens can flag it missing.
266
+ // No units ⇒ exactly the token path (byte-identical).
267
+ const unitCost = units !== undefined ? (0, cost_1.estimateUnitCostUsd)(provider, input.model, units) : null;
268
+ const tokensReported = usage.tokensIn > 0 || usage.tokensOut > 0;
269
+ const costUsd = tokenCost.costUsd + (unitCost?.costUsd ?? 0);
270
+ const pricingMissing = unitCost === null ? tokenCost.pricingMissing : unitCost.pricingMissing || (tokensReported && tokenCost.pricingMissing);
230
271
  // Tags: caller tags + the ambient step/run_id (same order as finalizeRaw), then
231
272
  // the SDK-owned markers LAST so a caller value cannot override them.
232
273
  const stepTag = step !== null ? { step: step.stepKey } : {};
@@ -240,7 +281,7 @@ function record(deps, input) {
240
281
  const adapterMeta = {
241
282
  ...(finishReason !== undefined ? { finish_reason: finishReason } : {}),
242
283
  ...(input.providerRequestId !== undefined ? { provider_request_id: input.providerRequestId } : {}),
243
- ...(input.usage.reasoningTokens !== undefined ? { reasoning_tokens: tok(input.usage.reasoningTokens) } : {}),
284
+ ...(reported.reasoningTokens !== undefined ? { reasoning_tokens: tok(reported.reasoningTokens) } : {}),
244
285
  };
245
286
  // No rendered request and no output text: ModelRig never saw the content, so
246
287
  // there is no input/output hash. Cost components only for a priced provider.
@@ -249,6 +290,8 @@ function record(deps, input) {
249
290
  provenance: "caller-reported",
250
291
  ...(known ? { provider: provider, model: input.model } : {}),
251
292
  usage,
293
+ ...(units !== undefined ? { units } : {}),
294
+ ...(unitCost !== null && unitCost.costUsd > 0 ? { unitCostUsd: unitCost.costUsd } : {}),
252
295
  });
253
296
  const id = (0, node_crypto_1.randomUUID)();
254
297
  const callId = (0, node_crypto_1.randomUUID)();
@@ -268,7 +311,7 @@ function record(deps, input) {
268
311
  callId,
269
312
  meta,
270
313
  });
271
- (0, raw_finalize_1.emitRawStep)(step, input.tags?.step ?? rawModelId, id, failureClass);
314
+ (0, raw_finalize_1.emitRawStep)(step, input.tags?.step ?? rawModelId, id, failureClass, { costUsd }); // ARC-5: accumulates toward run limits (cannot prevent — the next dispatch throws)
272
315
  const searchCalls = input.webSearchCalls ?? 0;
273
316
  if (searchCalls >= 1) {
274
317
  (0, raw_search_cost_1.recordRawSearchCostRow)(deps.telemetry, { provider, rawModelId, tags, callId, searchCalls });
@@ -1 +1 @@
1
- {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/run/run.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/run/run.ts"],"names":[],"mappings":"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"}
package/dist/run/run.js CHANGED
@@ -36,6 +36,7 @@ const quality_gate_1 = require("./quality-gate");
36
36
  const accept_1 = require("./accept");
37
37
  const run_context_1 = require("../artifacts/run-context");
38
38
  const capture_write_1 = require("./capture-write");
39
+ const messages_1 = require("./messages");
39
40
  /** Phase 1 prompt convention: the bundle's system template carries the whole
40
41
  * task (constitution, data, step instructions); the user turn is a terse
41
42
  * trigger. Providers treat long system prompts + short user turns well, and
@@ -65,12 +66,14 @@ async function run(deps, routeName, opts) {
65
66
  const baseRoute = deps.routes.get(routeName);
66
67
  const variant = (0, variant_1.resolveVariant)(baseRoute, opts.variant, mode);
67
68
  const servedVariant = variant?.name ?? null;
68
- const route = (0, resolve_1.applyRunRequirements)((0, variant_1.effectiveRoute)(baseRoute, variant), opts.zeroRetention === true);
69
+ const requiredRoute = (0, resolve_1.applyRunRequirements)((0, variant_1.effectiveRoute)(baseRoute, variant), opts.zeroRetention === true);
70
+ const { history, route, skipTag } = (0, messages_1.routedHistory)(requiredRoute, opts); // ARC-β messages lane (run/messages.ts): no history ⇒ same route, byte-identical; R2-2 skips incompatible candidates
69
71
  const destination = (0, resolve_destination_1.resolveDestination)(route.destination, opts.destination); // U2 (D-2): RunOptions > route > `direct`. Guard runs below, once the serving provider is resolved (U3).
70
72
  // RC-1: inside a run context the SDK stamps `run_id` (episodeKey, else run id)
71
73
  // when the caller passed none — the bridge between tags and the run graph.
72
74
  const runCtx = (0, run_context_1.getActiveRunContext)();
73
- const runTags = (0, run_context_1.withRunIdTag)(opts.tags, runCtx);
75
+ (0, run_context_1.enforceRunLimits)(); // ARC-5: pre-dispatch run-limit check (throws RunLimitExceeded; no-op without limits)
76
+ const runTags = (0, messages_1.withSkipTag)((0, run_context_1.withRunIdTag)(opts.tags, runCtx), skipTag);
74
77
  const effectiveTags = route.require.includes("zero_retention") ? { ...runTags, zdr_enforced: "true" } : runTags;
75
78
  // Data-hygiene warning (spec WS5): once per process per dimension.
76
79
  (0, manifest_1.warnMissingRequiredDimensions)(deps.manifest ?? null, effectiveTags);
@@ -96,7 +99,7 @@ async function run(deps, routeName, opts) {
96
99
  // Capture-WRITE gate (settings-plane §1.5, closes gate 5): the control-plane
97
100
  // capture flag wins over the YAML flag, the task's scrub setting is honored,
98
101
  // and capture OFF is a no-op writer (byte-identical). See ./capture-write.ts.
99
- const captureAttempt = (0, capture_write_1.buildCaptureWriter)(deps.settings ?? null, deps.captures, route, opts.input);
102
+ const captureAttempt = (0, capture_write_1.buildCaptureWriter)(deps.settings ?? null, deps.captures, route, (0, messages_1.captureInputFor)(opts.input, history, opts));
100
103
  const droppedCacheHandle = new Set(); // CE-1 retry-drop (spec §2.2)
101
104
  // Per-attempt telemetry recorder (extracted to ./record-attempt.ts — WS-A,
102
105
  // to keep run.ts under the LOC cap and shrink the run-loop conflict surface).
@@ -210,7 +213,8 @@ async function run(deps, routeName, opts) {
210
213
  // Issue #5 (R1): the user turn — the route's `prompt.user` when declared
211
214
  // (rendered with the SAME context, so an untrusted variable is removed from
212
215
  // it too and arrives via the spotlight block), else the fixed trigger.
213
- const userPrompt = userTurnFor(route, renderCtx);
216
+ const userPrompt = history !== undefined ? (0, messages_1.messagesUserTurn)(route, renderCtx) : userTurnFor(route, renderCtx);
217
+ const metaUser = (0, messages_1.userSideForHash)(userPrompt, history); // ARC-β: the envelope hash covers the history
214
218
  // Variant augmentation (WS1): appended after capability-conditionals,
215
219
  // before json coaching — promptAppend first, then the reasoning scaffold.
216
220
  if (variant?.promptAppend !== undefined) {
@@ -274,7 +278,7 @@ async function run(deps, routeName, opts) {
274
278
  // pricing snapshot (prompt-length input + full output budget).
275
279
  if (guard !== null) {
276
280
  // A1: an unpriced model must never precheck at $0 (fail closed).
277
- const breach = guard.precheck((0, cost_1.dispatchEstimateUsd)(candidate.provider, candidate.model, systemPrompt.length + userPrompt.length, unpricedRatePerTok));
281
+ const breach = guard.precheck((0, cost_1.dispatchEstimateUsd)(candidate.provider, candidate.model, systemPrompt.length + userPrompt.length + (0, messages_1.historyChars)(history), unpricedRatePerTok));
278
282
  if (breach !== null) {
279
283
  failRun(candidate, breach, 0);
280
284
  }
@@ -308,11 +312,11 @@ async function run(deps, routeName, opts) {
308
312
  servedVariant,
309
313
  pricingMissing,
310
314
  callId: ladder.callId, destination,
311
- metaInputs: (0, dispatch_1.attemptMetaInputs)({ systemPrompt, userDirective: userPrompt, outputSchema: route.outputSchema, outputKind: route.outputKind, result, tools: opts.tools }),
315
+ metaInputs: (0, dispatch_1.attemptMetaInputs)({ systemPrompt, userDirective: metaUser, outputSchema: route.outputSchema, outputKind: route.outputKind, result, tools: opts.tools }),
312
316
  });
313
317
  }
314
318
  const outcome = (0, validate_1.validateOutput)(route, result.text);
315
- const metaInputs = (0, dispatch_1.attemptMetaInputs)({ systemPrompt, userDirective: userPrompt, outputSchema: route.outputSchema, outputKind: route.outputKind, result, tools: opts.tools });
319
+ const metaInputs = (0, dispatch_1.attemptMetaInputs)({ systemPrompt, userDirective: metaUser, outputSchema: route.outputSchema, outputKind: route.outputKind, result, tools: opts.tools });
316
320
  if (outcome.valid) {
317
321
  // Q1 quality gate (spec §4.1): a schema-valid output must still clear the
318
322
  // builder's bar before it is accepted. Tool-call turns never reach here;
@@ -432,7 +436,7 @@ async function run(deps, routeName, opts) {
432
436
  ...(result.usage?.ttfbMs !== undefined ? { ttfbMs: result.usage.ttfbMs } : {}),
433
437
  failure,
434
438
  pricingMissing: failurePricingMissing,
435
- metaInputs: (0, dispatch_1.attemptMetaInputs)({ systemPrompt, userDirective: userPrompt, outputSchema: route.outputSchema, outputKind: route.outputKind, result, tools: opts.tools }),
439
+ metaInputs: (0, dispatch_1.attemptMetaInputs)({ systemPrompt, userDirective: metaUser, outputSchema: route.outputSchema, outputKind: route.outputKind, result, tools: opts.tools }),
436
440
  });
437
441
  if (failures_1.TERMINAL_CLASSES.has(failure.class)) {
438
442
  throw new failures_1.RigFailureError(failure);
@@ -130,16 +130,58 @@ export interface AttemptMetaV1 {
130
130
  * ModelRig dispatched the attempt and measured it (every other row). Additive
131
131
  * — no version bump. */
132
132
  readonly provenance?: AttemptProvenance;
133
+ /** ARC-4 (ARC-γ): the call's non-token units (`rig.recordCall({ units })`) —
134
+ * numbers only, keys from {@link UNIT_KEYS}. Additive, no column (zero DDL):
135
+ * rides `inferences.meta.units`. Absent ⇒ a token-only call. */
136
+ readonly units?: RecordedUnits;
133
137
  }
134
138
  /** OBS-1: the one non-default provenance value (see {@link AttemptMetaV1.provenance}). */
135
139
  export type AttemptProvenance = "caller-reported";
140
+ /** ARC-4 (ARC-γ): the non-token units a generation call is billed in — the ONE
141
+ * list. `rig.recordCall({ units })` validates against it, `meta.units` carries
142
+ * exactly these keys, and unit pricing (run/cost.ts) prices from it (the drift
143
+ * test pins all three). `steps` is recorded but never priced: no source we
144
+ * vendor publishes a per-step rate (L5). */
145
+ export declare const UNIT_KEYS: readonly ["images", "seconds", "characters", "steps"];
146
+ export type UnitKey = (typeof UNIT_KEYS)[number];
147
+ /** Non-negative finite counts of a call's non-token units (ARC-4). */
148
+ export type RecordedUnits = {
149
+ readonly [K in UnitKey]?: number;
150
+ };
151
+ /** The units envelope, cleaned: only {@link UNIT_KEYS}, only finite numbers
152
+ * ≥ 0. Returns undefined when nothing survives (absent ⇒ no `units` key). */
153
+ export declare function cleanUnits(raw: unknown): RecordedUnits | undefined;
154
+ /** The `RunMeta.trigger` vocabulary (WI-1 + ARC-1 `conversation`, set by
155
+ * `rig.conversation`). The ONE list — the type and its drift test read it. */
156
+ export declare const RUN_TRIGGERS: readonly ["cron", "api", "manual", "replay", "other", "conversation"];
157
+ export type RunTrigger = (typeof RUN_TRIGGERS)[number];
158
+ /** ARC-5: the `RunMeta.failure_reason` values a run-limit breach writes —
159
+ * `limit:<which>`, one per `RunLimits` field (run/limits.ts). Other reasons are
160
+ * caller-supplied identifiers (R9). */
161
+ export declare const LIMIT_FAILURE_REASONS: readonly ["limit:max_usd", "limit:max_calls", "limit:max_wall_ms", "limit:max_repeat_tool_call"];
162
+ export type LimitFailureReason = (typeof LIMIT_FAILURE_REASONS)[number];
136
163
  export interface RunMetaV1 {
137
164
  readonly v: 1;
138
165
  readonly pipeline_sha?: string;
139
166
  readonly config_hash?: string;
140
- readonly trigger?: "cron" | "api" | "manual" | "replay" | "other";
167
+ readonly trigger?: RunTrigger;
141
168
  readonly actor?: string;
142
169
  readonly input_hash?: string;
170
+ /**
171
+ * R9 (InferWealth report integrity, 2026-10-22): the run's failure reason —
172
+ * an identifier (e.g. a gate code `eps_integrity_failure`), set only when the
173
+ * run ends `failed` via `run.end("failed", { failureReason })` or
174
+ * `run.setFailureReason()`. `run-outcome@v1` labels a failed run with it.
175
+ */
176
+ readonly failure_reason?: string;
177
+ /** ARC-5: the run's limits as set on run.start / rig.conversation (snake_case
178
+ * numbers). Additive; absent when no limits were set. */
179
+ readonly limits?: {
180
+ readonly max_usd?: number;
181
+ readonly max_calls?: number;
182
+ readonly max_wall_ms?: number;
183
+ readonly max_repeat_tool_call?: number;
184
+ };
143
185
  }
144
186
  /**
145
187
  * The per-attempt content the RECORDER carries from the run/raw loop to the
@@ -205,6 +247,12 @@ export interface AttemptMetaInputs {
205
247
  /** OBS-1: stamp `meta.provenance` (`rig.recordCall` rows only). Absent ⇒ no
206
248
  * key ⇒ byte-identical to every dispatched row. */
207
249
  readonly provenance?: AttemptProvenance;
250
+ /** ARC-4: the call's non-token units, stamped on `meta.units` after
251
+ * {@link cleanUnits}. Absent ⇒ no key ⇒ byte-identical. */
252
+ readonly units?: RecordedUnits;
253
+ /** ARC-4: the unit cost (USD) already priced for this call — added to
254
+ * `meta.cost.other` so the components still sum to the row. Absent ⇒ 0. */
255
+ readonly unitCostUsd?: number;
208
256
  }
209
257
  /** The classification-rule string test (spec §2, §5 wire backstop): a value is
210
258
  * an ENUM / IDENTIFIER / HASH only if it is at most 128 chars AND contains no
@@ -1 +1 @@
1
- {"version":3,"file":"attempt-meta.d.ts","sourceRoot":"","sources":["../../src/telemetry/attempt-meta.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAOH,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD,MAAM,MAAM,YAAY,GACpB,MAAM,GACN,QAAQ,GACR,YAAY,GACZ,gBAAgB,GAChB,SAAS,GACT,OAAO,GACP,OAAO,CAAC;AAEZ,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;AAExE;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,MAAM,GAAG,YAAY,CAAC;AAC9D,eAAO,MAAM,iBAAiB,EAAE,WAAW,CAAC,MAAM,CAA6D,CAAC;AAEhH;;;;yDAIyD;AACzD,eAAO,MAAM,YAAY,EAAE,WAAW,CAAC,MAAM,CAAyC,CAAC;AAEvF,4EAA4E;AAC5E,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,GAAG,CAAC,EAAE;QAAE,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACnG,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,MAAM,gBAAgB,GAAG,UAAU,GAAG,oBAAoB,CAAC;AAEjE,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC;IACd,QAAQ,CAAC,aAAa,CAAC,EAAE,YAAY,CAAC;IACtC,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,QAAQ,CAAC,EAAE;QAAE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACpH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,8EAA8E;IAC9E,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACnF,QAAQ,CAAC,SAAS,CAAC,EAAE;QAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACxF,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC;;;;;iBAKa;IACb,QAAQ,CAAC,kBAAkB,CAAC,EAAE,gBAAgB,CAAC;IAC/C,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE;QACd,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;QAC7B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAC9B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;KACzB,CAAC;IACF,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,8DAA8D;IAC9D,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B;;;oFAGgF;IAChF,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,cAAc,CAAC,EAAE,aAAa,CAAC;IACxC,QAAQ,CAAC,MAAM,CAAC,EAAE,eAAe,CAAC;IAClC;;;qFAGiF;IACjF,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;;mBAMe;IACf,QAAQ,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC;IAChC;yEACqE;IACrE,QAAQ,CAAC,eAAe,CAAC,EAAE,cAAc,CAAC;IAC1C;+DAC2D;IAC3D,QAAQ,CAAC,WAAW,CAAC,EAAE,UAAU,CAAC;IAClC;;;;4BAIwB;IACxB,QAAQ,CAAC,UAAU,CAAC,EAAE,iBAAiB,CAAC;CACzC;AAED,0FAA0F;AAC1F,MAAM,MAAM,iBAAiB,GAAG,iBAAiB,CAAC;AAElD,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC;IACd,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC;IAClE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;IAC9C,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/C,4DAA4D;IAC5D,QAAQ,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC;CAClC;AAED;;;;uEAIuE;AACvE,wBAAgB,oBAAoB,CAAC,KAAK,EAAE;IAC1C,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC,GAAG,MAAM,CAMT;AAED;;uEAEuE;AACvE,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;IAC9C,4EAA4E;IAC5E,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,8DAA8D;IAC9D,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,uEAAuE;IACvE,QAAQ,CAAC,iBAAiB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/C;;gEAE4D;IAC5D,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B;0DACsD;IACtD,QAAQ,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC;IACjC,qDAAqD;IACrD,QAAQ,CAAC,QAAQ,CAAC,EAAE,UAAU,CAAC;IAC/B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,IAAI,CACnB,YAAY,EACZ,UAAU,GAAG,WAAW,GAAG,cAAc,GAAG,kBAAkB,GAAG,oBAAoB,CACtF;IACC,+EAA+E;IAC/E,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC,CAAC;IAC5C,mEAAmE;IACnE,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAC7B,yDAAyD;IACzD,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B;qFACiF;IACjF,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB;;8DAE0D;IAC1D,QAAQ,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC;IAChC;uDACmD;IACnD,QAAQ,CAAC,UAAU,CAAC,EAAE,iBAAiB,CAAC;CACzC;AAID;;;;+BAI+B;AAC/B,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,MAAM,CAExD;AAOD;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAgCrG;AAID;gEACgE;AAChE,eAAO,MAAM,iBAAiB,mEAAoE,CAAC;AACnG,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AA4BhE;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,cAAc,CAAA;CAAE,EAAE,CAS5G;AAID;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAInE;AAED;;;2CAG2C;AAC3C,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAkBrE;AAwCD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,iBAAiB,GAAG,aAAa,GAAG,IAAI,CA6GpF"}
1
+ {"version":3,"file":"attempt-meta.d.ts","sourceRoot":"","sources":["../../src/telemetry/attempt-meta.ts"],"names":[],"mappings":"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"}
@@ -13,7 +13,8 @@
13
13
  * enum/identifier/hash (length > 128 or containing whitespace).
14
14
  */
15
15
  Object.defineProperty(exports, "__esModule", { value: true });
16
- exports.RESERVED_TAG_KEYS = exports.OUTPUT_KINDS = exports.PROMPT_DELIVERIES = void 0;
16
+ exports.RESERVED_TAG_KEYS = exports.LIMIT_FAILURE_REASONS = exports.RUN_TRIGGERS = exports.UNIT_KEYS = exports.OUTPUT_KINDS = exports.PROMPT_DELIVERIES = void 0;
17
+ exports.cleanUnits = cleanUnits;
17
18
  exports.renderRequestForHash = renderRequestForHash;
18
19
  exports.isMetaSafeString = isMetaSafeString;
19
20
  exports.sanitizeMetaForWire = sanitizeMetaForWire;
@@ -33,6 +34,37 @@ exports.PROMPT_DELIVERIES = new Set(["system", "user", "user+cache"]);
33
34
  * `inferences.meta.output_kind` for every dispatched route-lane row, absent on
34
35
  * raw-lane rows (the raw lane has no route contract). */
35
36
  exports.OUTPUT_KINDS = new Set(["json", "text"]);
37
+ /** ARC-4 (ARC-γ): the non-token units a generation call is billed in — the ONE
38
+ * list. `rig.recordCall({ units })` validates against it, `meta.units` carries
39
+ * exactly these keys, and unit pricing (run/cost.ts) prices from it (the drift
40
+ * test pins all three). `steps` is recorded but never priced: no source we
41
+ * vendor publishes a per-step rate (L5). */
42
+ exports.UNIT_KEYS = ["images", "seconds", "characters", "steps"];
43
+ /** The units envelope, cleaned: only {@link UNIT_KEYS}, only finite numbers
44
+ * ≥ 0. Returns undefined when nothing survives (absent ⇒ no `units` key). */
45
+ function cleanUnits(raw) {
46
+ if (typeof raw !== "object" || raw === null || Array.isArray(raw))
47
+ return undefined;
48
+ const out = {};
49
+ for (const key of exports.UNIT_KEYS) {
50
+ const v = raw[key];
51
+ if (typeof v === "number" && Number.isFinite(v) && v >= 0)
52
+ out[key] = v;
53
+ }
54
+ return Object.keys(out).length > 0 ? out : undefined;
55
+ }
56
+ /** The `RunMeta.trigger` vocabulary (WI-1 + ARC-1 `conversation`, set by
57
+ * `rig.conversation`). The ONE list — the type and its drift test read it. */
58
+ exports.RUN_TRIGGERS = ["cron", "api", "manual", "replay", "other", "conversation"];
59
+ /** ARC-5: the `RunMeta.failure_reason` values a run-limit breach writes —
60
+ * `limit:<which>`, one per `RunLimits` field (run/limits.ts). Other reasons are
61
+ * caller-supplied identifiers (R9). */
62
+ exports.LIMIT_FAILURE_REASONS = [
63
+ "limit:max_usd",
64
+ "limit:max_calls",
65
+ "limit:max_wall_ms",
66
+ "limit:max_repeat_tool_call",
67
+ ];
36
68
  /** Canonicalize the RENDERED request for `input_hash` (spec §2) — system + user
37
69
  * + schema, joined the SAME way in both lanes so a routed and a raw call with
38
70
  * the identical prompt+schema hash identically (lane parity, spec §6.3). The
@@ -273,6 +305,10 @@ function summarizeAttemptMeta(inputs) {
273
305
  // OBS-1: caller-reported provenance — an enum; anything else is dropped.
274
306
  if (inputs.provenance === "caller-reported")
275
307
  meta.provenance = inputs.provenance;
308
+ // ARC-4: non-token units — numbers only, known keys only.
309
+ const units = cleanUnits(inputs.units);
310
+ if (units !== undefined)
311
+ meta.units = units;
276
312
  // Externally-sourced identifiers — gated by the classification rule.
277
313
  if (isMetaSafeString(a.model_snapshot))
278
314
  meta.model_snapshot = a.model_snapshot;
@@ -346,6 +382,14 @@ function summarizeAttemptMeta(inputs) {
346
382
  if (cost !== null)
347
383
  meta.cost = cost;
348
384
  }
385
+ // ARC-4: a priced unit cost rides `other` (reserved for it), so the
386
+ // components sum to the recorded row. A unit-only call (no token price)
387
+ // gets an all-zero token block plus `other`.
388
+ const unitCost = num(inputs.unitCostUsd);
389
+ if (unitCost !== undefined && unitCost > 0) {
390
+ const base = meta.cost ?? { in: 0, out: 0, cache_read: 0, cache_write: 0, other: 0 };
391
+ meta.cost = { ...base, other: (base.other ?? 0) + unitCost };
392
+ }
349
393
  return meta;
350
394
  }
351
395
  catch {
@@ -1 +1 @@
1
- {"version":3,"file":"exporter.d.ts","sourceRoot":"","sources":["../../src/telemetry/exporter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"exporter.d.ts","sourceRoot":"","sources":["../../src/telemetry/exporter.ts"],"names":[],"mappings":"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"}
@@ -301,8 +301,9 @@ function createTelemetryExporter(store, config) {
301
301
  poisonState.delete(stream);
302
302
  poisonSkipped[stream] = (poisonSkipped[stream] ?? 0) + rowCount;
303
303
  const status = err instanceof sinks_1.SinkSendError ? err.status : undefined;
304
+ const reason = err instanceof sinks_1.SinkSendError && err.reasonCode !== null ? `, reason ${err.reasonCode}` : "";
304
305
  console.warn(`[modelrig exporter] POISON-SKIP: stream "${stream}" batch at watermark ${watermark} ` +
305
- `(${rowCount} row(s), status ${status ?? "network"}) was rejected deterministically ` +
306
+ `(${rowCount} row(s), status ${status ?? "network"}${reason}) was rejected deterministically ` +
306
307
  `${POISON_SKIP_THRESHOLD}× running — advancing the watermark PAST it WITHOUT writing. ` +
307
308
  `These rows are dropped and will NOT be retried; investigate the rejection and backfill.`);
308
309
  return "skip";
@@ -15,7 +15,7 @@ export declare function toWireGrade(row: GradeRow): WireGrade;
15
15
  * (F4) is deliberately destructured OUT here: `public.grades` has no criteria
16
16
  * column — the per-criterion breakdown fans out to `grade_criteria` in a
17
17
  * separate best-effort write at the ingest boundary, keyed to this grade's id. */
18
- export declare function gradeToRow({ org_id, criteria: _criteria, ...g }: WireGrade, tenancy: Tenancy): Record<string, unknown>;
18
+ export declare function gradeToRow({ org_id, criteria: _criteria, idempotency_key: _idem, ...g }: WireGrade, tenancy: Tenancy): Record<string, unknown>;
19
19
  /**
20
20
  * Grades naming an org other than the presented key's. The ingest endpoint drops
21
21
  * and COUNTS these so a caller cannot file a judgment into another tenant's corpus
@@ -1 +1 @@
1
- {"version":3,"file":"grade-mappers.d.ts","sourceRoot":"","sources":["../../src/telemetry/grade-mappers.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEnD;2EAC2E;AAC3E,wBAAgB,WAAW,CAAC,GAAG,EAAE,QAAQ,GAAG,SAAS,CAmBpD;AAED;;;kFAGkF;AAClF,wBAAgB,UAAU,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,CAAC,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAiBtH;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,SAAS,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAEhG"}
1
+ {"version":3,"file":"grade-mappers.d.ts","sourceRoot":"","sources":["../../src/telemetry/grade-mappers.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEnD;2EAC2E;AAC3E,wBAAgB,WAAW,CAAC,GAAG,EAAE,QAAQ,GAAG,SAAS,CAsBpD;AAED;;;kFAGkF;AAClF,wBAAgB,UAAU,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,eAAe,EAAE,KAAK,EAAE,GAAG,CAAC,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAoB9I;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,SAAS,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAEhG"}
@@ -30,13 +30,16 @@ function toWireGrade(row) {
30
30
  // F4: mirror the per-criterion breakdown iff present (spread-iff — a
31
31
  // single-score grade's wire shape is byte-identical to pre-F4).
32
32
  ...(row.criteria !== undefined ? { criteria: row.criteria } : {}),
33
+ // ARC-3: the outcome's raw value rides iff set (non-outcome wire unchanged).
34
+ ...(row.value !== undefined && row.value !== null ? { value: row.value } : {}),
35
+ ...(row.idempotencyKey !== undefined ? { idempotency_key: row.idempotencyKey } : {}),
33
36
  };
34
37
  }
35
38
  /** WireGrade → a grades row (the SDK's sole judgment write path). `criteria`
36
39
  * (F4) is deliberately destructured OUT here: `public.grades` has no criteria
37
40
  * column — the per-criterion breakdown fans out to `grade_criteria` in a
38
41
  * separate best-effort write at the ingest boundary, keyed to this grade's id. */
39
- function gradeToRow({ org_id, criteria: _criteria, ...g }, tenancy) {
42
+ function gradeToRow({ org_id, criteria: _criteria, idempotency_key: _idem, ...g }, tenancy) {
40
43
  return {
41
44
  org_id: org_id ?? tenancy.org_id,
42
45
  project_id: tenancy.project_id,
@@ -52,6 +55,9 @@ function gradeToRow({ org_id, criteria: _criteria, ...g }, tenancy) {
52
55
  source: g.source,
53
56
  created_by: g.created_by,
54
57
  ts: g.ts,
58
+ // ARC-3 (00089): `value` is written ONLY when present, so a non-outcome row
59
+ // never names the column (it would 42703 on a pre-00089 plane).
60
+ ...(g.value !== undefined && g.value !== null ? { value: g.value } : {}),
55
61
  };
56
62
  }
57
63
  /**
@@ -0,0 +1,49 @@
1
+ /**
2
+ * THE grade-task key (GRADE-RAW, grade-ux-plan.md §1 item 2) — which TASK a
3
+ * telemetry row is graded under. ONE helper; every grading surface (teaching
4
+ * feed, auto-grade enqueue, calibration subject attribution, the /grades
5
+ * rollup, the grader's subject loader and the ingest-side task registration)
6
+ * keys through it, so they can never disagree about where a call belongs.
7
+ *
8
+ * • A ROUTED call is graded under its route (`inferences.route`).
9
+ * • A raw-lane (`rig.runRaw`) or recorded (`rig.recordCall`) call stores
10
+ * `provider/model` in `inferences.route` — not a task anyone would write a
11
+ * grading guide for. Its task is the customer's step name, `tags.step`,
12
+ * when present and a valid task name. Otherwise it falls back to the route
13
+ * (honest: an unnamed raw call has no task of its own).
14
+ *
15
+ * The SDK's auto step key inside a run (`<provider>/<model>#<n>`) contains a
16
+ * `/`, so it is never a valid task name and never becomes a task — a grader is
17
+ * for a step the customer named.
18
+ *
19
+ * Pure, dependency-free (the server, the console and stampBatch import it).
20
+ */
21
+ /** A task name is one URL path segment (`/v1/tasks/<task>/settings`): starts
22
+ * with a letter or digit, then letters, digits, `.`, `_`, `:` or `-`; at most
23
+ * 128 characters. No `/`, no spaces. */
24
+ export declare const TASK_NAME_PATTERN: RegExp;
25
+ /** The teaching copy every bad-name refusal uses (one wording, everywhere). */
26
+ export declare const TASK_NAME_RULE = "a task name starts with a letter or digit and then uses only letters, digits, '.', '_', ':' or '-' (max 128 chars, no '/' or spaces)";
27
+ /** At most this many NEW step tasks are registered per ingest batch (abuse
28
+ * cap: a batch cannot mint an unbounded number of task rows). Excess steps are
29
+ * not lost — they register on a later batch that carries them. */
30
+ export declare const MAX_REGISTERED_STEPS_PER_BATCH = 50;
31
+ export declare function isValidTaskName(value: unknown): value is string;
32
+ /** The minimal row shape the helper needs. `tags` may be the parsed object (wire
33
+ * rows, PostgREST reads) or the JSON text the local store keeps (`tagsJson`). */
34
+ export interface GradeTaskRow {
35
+ readonly route: string;
36
+ readonly tags?: unknown;
37
+ readonly tagsJson?: string;
38
+ }
39
+ /** The step a raw/recorded row names, or null (routed row, no step, or a step
40
+ * that is not a valid task name). */
41
+ export declare function stepTaskOf(row: GradeTaskRow): string | null;
42
+ /** The task a row is graded under: `tags.step` for a raw/recorded row that names
43
+ * a valid step, else `route`. */
44
+ export declare function gradeTaskOf(row: GradeTaskRow): string;
45
+ /** The distinct step tasks a batch of rows names, first-seen order, capped at
46
+ * {@link MAX_REGISTERED_STEPS_PER_BATCH}. Routed rows contribute nothing (route
47
+ * sync owns their task rows). */
48
+ export declare function registrableStepTasks(rows: readonly GradeTaskRow[], cap?: number): string[];
49
+ //# sourceMappingURL=grade-task.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grade-task.d.ts","sourceRoot":"","sources":["../../src/telemetry/grade-task.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH;;wCAEwC;AACxC,eAAO,MAAM,iBAAiB,QAAwC,CAAC;AAEvE,+EAA+E;AAC/E,eAAO,MAAM,cAAc,yIAC6G,CAAC;AAEzI;;kEAEkE;AAClE,eAAO,MAAM,8BAA8B,KAAK,CAAC;AAEjD,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAE/D;AAED;iFACiF;AACjF,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B;AAeD;qCACqC;AACrC,wBAAgB,UAAU,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,GAAG,IAAI,CAI3D;AAED;iCACiC;AACjC,wBAAgB,WAAW,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,CAErD;AAED;;iCAEiC;AACjC,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,SAAS,YAAY,EAAE,EAC7B,GAAG,GAAE,MAAuC,GAC3C,MAAM,EAAE,CAWV"}