modelrig 0.8.1 → 0.10.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 (382) hide show
  1. package/CHANGELOG.md +324 -0
  2. package/README.md +55 -29
  3. package/data/PROVENANCE.md +14 -0
  4. package/data/pricing-map.json +26 -0
  5. package/dist/adapters/attempt-meta-map.d.ts +8 -1
  6. package/dist/adapters/attempt-meta-map.d.ts.map +1 -1
  7. package/dist/adapters/attempt-meta-map.js +4 -0
  8. package/dist/adapters/build-adapters.js +2 -2
  9. package/dist/adapters/gemini.d.ts +28 -1
  10. package/dist/adapters/gemini.d.ts.map +1 -1
  11. package/dist/adapters/gemini.js +38 -9
  12. package/dist/adapters/grok.d.ts.map +1 -1
  13. package/dist/adapters/grok.js +53 -4
  14. package/dist/adapters/openai-compat.d.ts +8 -2
  15. package/dist/adapters/openai-compat.d.ts.map +1 -1
  16. package/dist/adapters/openai-compat.js +8 -1
  17. package/dist/adapters/openai-stream.d.ts +10 -2
  18. package/dist/adapters/openai-stream.d.ts.map +1 -1
  19. package/dist/adapters/openai-stream.js +5 -1
  20. package/dist/adapters/openai.d.ts +10 -1
  21. package/dist/adapters/openai.d.ts.map +1 -1
  22. package/dist/adapters/openai.js +57 -7
  23. package/dist/adapters/responses-api.d.ts +61 -0
  24. package/dist/adapters/responses-api.d.ts.map +1 -0
  25. package/dist/adapters/responses-api.js +124 -0
  26. package/dist/artifacts/artifact.d.ts +31 -12
  27. package/dist/artifacts/artifact.d.ts.map +1 -1
  28. package/dist/artifacts/artifact.js +218 -188
  29. package/dist/artifacts/index.d.ts +15 -5
  30. package/dist/artifacts/index.d.ts.map +1 -1
  31. package/dist/artifacts/index.js +19 -5
  32. package/dist/artifacts/run-context.d.ts +3 -24
  33. package/dist/artifacts/run-context.d.ts.map +1 -1
  34. package/dist/artifacts/run-context.js +3 -39
  35. package/dist/bakeoff/engine.d.ts +29 -0
  36. package/dist/bakeoff/engine.d.ts.map +1 -1
  37. package/dist/bakeoff/engine.js +47 -0
  38. package/dist/bakeoff/eval-cases-rig.d.ts +36 -0
  39. package/dist/bakeoff/eval-cases-rig.d.ts.map +1 -0
  40. package/dist/bakeoff/eval-cases-rig.js +27 -0
  41. package/dist/bakeoff/eval-cases.d.ts +19 -0
  42. package/dist/bakeoff/eval-cases.d.ts.map +1 -1
  43. package/dist/bakeoff/eval-cases.js +18 -1
  44. package/dist/bakeoff/golden-judge.d.ts +47 -0
  45. package/dist/bakeoff/golden-judge.d.ts.map +1 -0
  46. package/dist/bakeoff/golden-judge.js +49 -0
  47. package/dist/bakeoff/groundedness.d.ts +58 -0
  48. package/dist/bakeoff/groundedness.d.ts.map +1 -0
  49. package/dist/bakeoff/groundedness.js +165 -0
  50. package/dist/bakeoff/quality.d.ts +43 -0
  51. package/dist/bakeoff/quality.d.ts.map +1 -1
  52. package/dist/bakeoff/quality.js +31 -0
  53. package/dist/bakeoff/replay.d.ts +11 -0
  54. package/dist/bakeoff/replay.d.ts.map +1 -1
  55. package/dist/bakeoff/replay.js +12 -0
  56. package/dist/bakeoff/report.d.ts +7 -0
  57. package/dist/bakeoff/report.d.ts.map +1 -1
  58. package/dist/bakeoff/report.js +26 -0
  59. package/dist/cli-judge.d.ts +12 -0
  60. package/dist/cli-judge.d.ts.map +1 -0
  61. package/dist/cli-judge.js +48 -0
  62. package/dist/cli.d.ts.map +1 -1
  63. package/dist/cli.js +22 -42
  64. package/dist/config.d.ts +85 -29
  65. package/dist/config.d.ts.map +1 -1
  66. package/dist/config.js +109 -47
  67. package/dist/detect/detector.d.ts +4 -2
  68. package/dist/detect/detector.d.ts.map +1 -1
  69. package/dist/detect/safe-harbor.d.ts +57 -0
  70. package/dist/detect/safe-harbor.d.ts.map +1 -0
  71. package/dist/detect/safe-harbor.js +278 -0
  72. package/dist/doctor-cli.d.ts +7 -0
  73. package/dist/doctor-cli.d.ts.map +1 -0
  74. package/dist/doctor-cli.js +67 -0
  75. package/dist/doctor-preflight.d.ts +52 -0
  76. package/dist/doctor-preflight.d.ts.map +1 -0
  77. package/dist/doctor-preflight.js +112 -0
  78. package/dist/feedback/coverage.d.ts +11 -8
  79. package/dist/feedback/coverage.d.ts.map +1 -1
  80. package/dist/feedback/coverage.js +29 -16
  81. package/dist/feedback/grade.d.ts +58 -0
  82. package/dist/feedback/grade.d.ts.map +1 -0
  83. package/dist/feedback/grade.js +67 -0
  84. package/dist/gateway/http-protocol.d.ts +20 -1
  85. package/dist/gateway/http-protocol.d.ts.map +1 -1
  86. package/dist/gateway/http-protocol.js +1 -1
  87. package/dist/gateway/serve-client.d.ts +99 -0
  88. package/dist/gateway/serve-client.d.ts.map +1 -0
  89. package/dist/gateway/serve-client.js +360 -0
  90. package/dist/index.d.ts +68 -29
  91. package/dist/index.d.ts.map +1 -1
  92. package/dist/index.js +167 -46
  93. package/dist/init/observe-cli.js +1 -1
  94. package/dist/init/observe.d.ts +2 -2
  95. package/dist/init/observe.d.ts.map +1 -1
  96. package/dist/init/observe.js +11 -7
  97. package/dist/mask/arm.d.ts +112 -0
  98. package/dist/mask/arm.d.ts.map +1 -0
  99. package/dist/mask/arm.js +179 -0
  100. package/dist/mask/index.d.ts +2 -0
  101. package/dist/mask/index.d.ts.map +1 -1
  102. package/dist/mask/index.js +7 -1
  103. package/dist/mask/mask-policy-cli.d.ts +12 -4
  104. package/dist/mask/mask-policy-cli.d.ts.map +1 -1
  105. package/dist/mask/mask-policy-cli.js +34 -9
  106. package/dist/prompts/manifest.d.ts +128 -0
  107. package/dist/prompts/manifest.d.ts.map +1 -0
  108. package/dist/prompts/manifest.js +214 -0
  109. package/dist/prompts/prompt-fetch.d.ts +84 -0
  110. package/dist/prompts/prompt-fetch.d.ts.map +1 -0
  111. package/dist/prompts/prompt-fetch.js +120 -0
  112. package/dist/prompts/prompt-resolve.d.ts +76 -0
  113. package/dist/prompts/prompt-resolve.d.ts.map +1 -0
  114. package/dist/prompts/prompt-resolve.js +93 -0
  115. package/dist/prompts/slot-resolver.d.ts +91 -0
  116. package/dist/prompts/slot-resolver.d.ts.map +1 -0
  117. package/dist/prompts/slot-resolver.js +135 -0
  118. package/dist/prompts/tools-register.d.ts +60 -0
  119. package/dist/prompts/tools-register.d.ts.map +1 -0
  120. package/dist/prompts/tools-register.js +48 -0
  121. package/dist/prompts/version-hash.d.ts +29 -0
  122. package/dist/prompts/version-hash.d.ts.map +1 -0
  123. package/dist/prompts/version-hash.js +54 -0
  124. package/dist/prompts-export-cli.d.ts +21 -0
  125. package/dist/prompts-export-cli.d.ts.map +1 -0
  126. package/dist/prompts-export-cli.js +130 -0
  127. package/dist/query/grammar.d.ts +2 -2
  128. package/dist/query/grammar.d.ts.map +1 -1
  129. package/dist/query/grammar.js +3 -1
  130. package/dist/query/saved.d.ts +13 -0
  131. package/dist/query/saved.d.ts.map +1 -1
  132. package/dist/query/saved.js +67 -1
  133. package/dist/receipts/types.d.ts +1 -1
  134. package/dist/receipts/types.d.ts.map +1 -1
  135. package/dist/receipts/types.js +1 -0
  136. package/dist/registry/build.d.ts +43 -1
  137. package/dist/registry/build.d.ts.map +1 -1
  138. package/dist/registry/build.js +52 -0
  139. package/dist/registry/cache-policy.d.ts.map +1 -1
  140. package/dist/registry/cache-policy.js +22 -0
  141. package/dist/registry/pricing-shape.d.ts +67 -8
  142. package/dist/registry/pricing-shape.d.ts.map +1 -1
  143. package/dist/registry/pricing-shape.js +50 -13
  144. package/dist/registry/pricing.d.ts +6 -5
  145. package/dist/registry/pricing.d.ts.map +1 -1
  146. package/dist/registry/pricing.js +9 -5
  147. package/dist/registry/rows.d.ts.map +1 -1
  148. package/dist/registry/rows.js +1 -0
  149. package/dist/registry/select.d.ts +6 -1
  150. package/dist/registry/select.d.ts.map +1 -1
  151. package/dist/registry/select.js +11 -0
  152. package/dist/routes/call-config.d.ts +199 -0
  153. package/dist/routes/call-config.d.ts.map +1 -0
  154. package/dist/routes/call-config.js +343 -0
  155. package/dist/routes/destination-loader.d.ts +16 -0
  156. package/dist/routes/destination-loader.d.ts.map +1 -0
  157. package/dist/routes/destination-loader.js +29 -0
  158. package/dist/routes/draft.d.ts +7 -0
  159. package/dist/routes/draft.d.ts.map +1 -1
  160. package/dist/routes/draft.js +12 -0
  161. package/dist/routes/loader.d.ts.map +1 -1
  162. package/dist/routes/loader.js +31 -56
  163. package/dist/routes/objective-loader.d.ts +12 -0
  164. package/dist/routes/objective-loader.d.ts.map +1 -1
  165. package/dist/routes/objective-loader.js +82 -0
  166. package/dist/routes/output-loader.d.ts +42 -0
  167. package/dist/routes/output-loader.d.ts.map +1 -0
  168. package/dist/routes/output-loader.js +112 -0
  169. package/dist/routes/prompt-loader.d.ts +49 -0
  170. package/dist/routes/prompt-loader.d.ts.map +1 -0
  171. package/dist/routes/prompt-loader.js +113 -0
  172. package/dist/routes/resolved-bundle.d.ts +69 -0
  173. package/dist/routes/resolved-bundle.d.ts.map +1 -1
  174. package/dist/routes/resolved-bundle.js +76 -0
  175. package/dist/routes/screen-loader.d.ts +29 -1
  176. package/dist/routes/screen-loader.d.ts.map +1 -1
  177. package/dist/routes/screen-loader.js +59 -1
  178. package/dist/run/accept.d.ts +5 -0
  179. package/dist/run/accept.d.ts.map +1 -1
  180. package/dist/run/accept.js +2 -0
  181. package/dist/run/cost.d.ts +31 -2
  182. package/dist/run/cost.d.ts.map +1 -1
  183. package/dist/run/cost.js +57 -2
  184. package/dist/run/destination.d.ts +39 -0
  185. package/dist/run/destination.d.ts.map +1 -0
  186. package/dist/run/destination.js +45 -0
  187. package/dist/run/dispatch.d.ts +67 -16
  188. package/dist/run/dispatch.d.ts.map +1 -1
  189. package/dist/run/dispatch.js +133 -29
  190. package/dist/run/grounding.d.ts +28 -2
  191. package/dist/run/grounding.d.ts.map +1 -1
  192. package/dist/run/grounding.js +54 -10
  193. package/dist/run/raw-defaults.d.ts.map +1 -1
  194. package/dist/run/raw-defaults.js +6 -1
  195. package/dist/run/raw-finalize.d.ts +50 -0
  196. package/dist/run/raw-finalize.d.ts.map +1 -0
  197. package/dist/run/raw-finalize.js +266 -0
  198. package/dist/run/raw-knobs.d.ts +36 -0
  199. package/dist/run/raw-knobs.d.ts.map +1 -0
  200. package/dist/run/raw-knobs.js +99 -0
  201. package/dist/run/raw-request.d.ts +24 -0
  202. package/dist/run/raw-request.d.ts.map +1 -0
  203. package/dist/run/raw-request.js +69 -0
  204. package/dist/run/raw-schema.d.ts +76 -0
  205. package/dist/run/raw-schema.d.ts.map +1 -0
  206. package/dist/run/raw-schema.js +166 -0
  207. package/dist/run/raw-search-cost.d.ts +48 -0
  208. package/dist/run/raw-search-cost.d.ts.map +1 -0
  209. package/dist/run/raw-search-cost.js +78 -0
  210. package/dist/run/raw-support.d.ts +64 -6
  211. package/dist/run/raw-support.d.ts.map +1 -1
  212. package/dist/run/raw-support.js +84 -11
  213. package/dist/run/raw.d.ts +25 -26
  214. package/dist/run/raw.d.ts.map +1 -1
  215. package/dist/run/raw.js +30 -351
  216. package/dist/run/record-attempt.d.ts +12 -0
  217. package/dist/run/record-attempt.d.ts.map +1 -1
  218. package/dist/run/record-attempt.js +30 -12
  219. package/dist/run/repair-attempt.d.ts +68 -0
  220. package/dist/run/repair-attempt.d.ts.map +1 -0
  221. package/dist/run/repair-attempt.js +180 -0
  222. package/dist/run/resolve-destination.d.ts +49 -0
  223. package/dist/run/resolve-destination.d.ts.map +1 -0
  224. package/dist/run/resolve-destination.js +76 -0
  225. package/dist/run/routing-docs.d.ts.map +1 -1
  226. package/dist/run/routing-docs.js +10 -5
  227. package/dist/run/run.d.ts +30 -1
  228. package/dist/run/run.d.ts.map +1 -1
  229. package/dist/run/run.js +94 -172
  230. package/dist/run/telemetry-row.d.ts +92 -0
  231. package/dist/run/telemetry-row.d.ts.map +1 -0
  232. package/dist/run/telemetry-row.js +81 -0
  233. package/dist/run/validate.d.ts +12 -1
  234. package/dist/run/validate.d.ts.map +1 -1
  235. package/dist/run/validate.js +31 -0
  236. package/dist/run/web-search-pricing.d.ts +43 -0
  237. package/dist/run/web-search-pricing.d.ts.map +1 -0
  238. package/dist/run/web-search-pricing.js +56 -0
  239. package/dist/savings/odometer.d.ts +4 -0
  240. package/dist/savings/odometer.d.ts.map +1 -1
  241. package/dist/savings/odometer.js +20 -1
  242. package/dist/savings/swap-execute.d.ts +7 -0
  243. package/dist/savings/swap-execute.d.ts.map +1 -1
  244. package/dist/savings/swap-execute.js +30 -0
  245. package/dist/savings/swaps-client.d.ts +10 -0
  246. package/dist/savings/swaps-client.d.ts.map +1 -1
  247. package/dist/screen/fixtures/probe-corpora.d.ts +23 -0
  248. package/dist/screen/fixtures/probe-corpora.d.ts.map +1 -0
  249. package/dist/screen/fixtures/probe-corpora.js +69 -0
  250. package/dist/screen/index.d.ts +21 -0
  251. package/dist/screen/index.d.ts.map +1 -0
  252. package/dist/screen/index.js +64 -0
  253. package/dist/screen/model-screen.d.ts +111 -0
  254. package/dist/screen/model-screen.d.ts.map +1 -0
  255. package/dist/screen/model-screen.js +178 -0
  256. package/dist/screen/patterns.d.ts +51 -0
  257. package/dist/screen/patterns.d.ts.map +1 -0
  258. package/dist/screen/patterns.js +151 -0
  259. package/dist/screen/phi-gate.d.ts +52 -0
  260. package/dist/screen/phi-gate.d.ts.map +1 -0
  261. package/dist/screen/phi-gate.js +86 -0
  262. package/dist/screen/policy.d.ts +71 -0
  263. package/dist/screen/policy.d.ts.map +1 -0
  264. package/dist/screen/policy.js +334 -0
  265. package/dist/screen/probe.d.ts +118 -0
  266. package/dist/screen/probe.d.ts.map +1 -0
  267. package/dist/screen/probe.js +132 -0
  268. package/dist/screen/screen-cli.d.ts +16 -0
  269. package/dist/screen/screen-cli.d.ts.map +1 -0
  270. package/dist/screen/screen-cli.js +178 -0
  271. package/dist/screen/screen.d.ts +99 -0
  272. package/dist/screen/screen.d.ts.map +1 -0
  273. package/dist/screen/screen.js +0 -0
  274. package/dist/screen/sidecar.d.ts +69 -0
  275. package/dist/screen/sidecar.d.ts.map +1 -0
  276. package/dist/screen/sidecar.js +145 -0
  277. package/dist/screen/types.d.ts +43 -2
  278. package/dist/screen/types.d.ts.map +1 -1
  279. package/dist/settings/api-fetcher.d.ts +14 -3
  280. package/dist/settings/api-fetcher.d.ts.map +1 -1
  281. package/dist/settings/api-fetcher.js +61 -10
  282. package/dist/settings/grading-guide.d.ts +102 -0
  283. package/dist/settings/grading-guide.d.ts.map +1 -0
  284. package/dist/settings/grading-guide.js +23 -0
  285. package/dist/settings/index.d.ts +3 -2
  286. package/dist/settings/index.d.ts.map +1 -1
  287. package/dist/settings/index.js +2 -1
  288. package/dist/settings/task-settings.d.ts +44 -7
  289. package/dist/settings/task-settings.d.ts.map +1 -1
  290. package/dist/settings/task-settings.js +53 -12
  291. package/dist/status.d.ts +32 -20
  292. package/dist/status.d.ts.map +1 -1
  293. package/dist/status.js +51 -30
  294. package/dist/telemetry/artifact-store.d.ts +5 -6
  295. package/dist/telemetry/artifact-store.d.ts.map +1 -1
  296. package/dist/telemetry/artifact-store.js +21 -24
  297. package/dist/telemetry/attempt-meta.d.ts +76 -1
  298. package/dist/telemetry/attempt-meta.d.ts.map +1 -1
  299. package/dist/telemetry/attempt-meta.js +33 -1
  300. package/dist/telemetry/exporter-setup.d.ts +2 -0
  301. package/dist/telemetry/exporter-setup.d.ts.map +1 -1
  302. package/dist/telemetry/exporter-setup.js +6 -1
  303. package/dist/telemetry/exporter.d.ts +2 -2
  304. package/dist/telemetry/exporter.d.ts.map +1 -1
  305. package/dist/telemetry/exporter.js +22 -41
  306. package/dist/telemetry/grade-mappers.d.ts +25 -0
  307. package/dist/telemetry/grade-mappers.d.ts.map +1 -0
  308. package/dist/telemetry/grade-mappers.js +64 -0
  309. package/dist/telemetry/grades-sql.d.ts +56 -0
  310. package/dist/telemetry/grades-sql.d.ts.map +1 -0
  311. package/dist/telemetry/grades-sql.js +156 -0
  312. package/dist/telemetry/ingest-protocol.d.ts +55 -48
  313. package/dist/telemetry/ingest-protocol.d.ts.map +1 -1
  314. package/dist/telemetry/ingest-protocol.js +48 -83
  315. package/dist/telemetry/org-identity.d.ts +44 -0
  316. package/dist/telemetry/org-identity.d.ts.map +1 -0
  317. package/dist/telemetry/org-identity.js +98 -0
  318. package/dist/telemetry/route-registration.d.ts +48 -0
  319. package/dist/telemetry/route-registration.d.ts.map +1 -0
  320. package/dist/telemetry/route-registration.js +77 -0
  321. package/dist/telemetry/sinks.d.ts +10 -1
  322. package/dist/telemetry/sinks.d.ts.map +1 -1
  323. package/dist/telemetry/sinks.js +52 -6
  324. package/dist/telemetry/store-migrations.d.ts.map +1 -1
  325. package/dist/telemetry/store-migrations.js +64 -0
  326. package/dist/telemetry/store.d.ts +9 -6
  327. package/dist/telemetry/store.d.ts.map +1 -1
  328. package/dist/telemetry/store.js +8 -50
  329. package/dist/tenancy/api-key-format.d.ts +45 -1
  330. package/dist/tenancy/api-key-format.d.ts.map +1 -1
  331. package/dist/tenancy/api-key-format.js +50 -1
  332. package/dist/types/provider.d.ts +23 -3
  333. package/dist/types/provider.d.ts.map +1 -1
  334. package/dist/types/provider.js +26 -0
  335. package/dist/types/route.d.ts +154 -2
  336. package/dist/types/route.d.ts.map +1 -1
  337. package/dist/types/telemetry.d.ts +73 -48
  338. package/dist/types/telemetry.d.ts.map +1 -1
  339. package/dist/validate-cli.d.ts.map +1 -1
  340. package/dist/validate-cli.js +32 -0
  341. package/dist/verify/verify.d.ts +5 -0
  342. package/dist/verify/verify.d.ts.map +1 -1
  343. package/dist/verify/verify.js +2 -0
  344. package/dist/watch/evaluate.d.ts +84 -1
  345. package/dist/watch/evaluate.d.ts.map +1 -1
  346. package/dist/watch/evaluate.js +28 -0
  347. package/dist/watch/monitor.d.ts +8 -2
  348. package/dist/watch/monitor.d.ts.map +1 -1
  349. package/dist/watch/monitor.js +13 -5
  350. package/dist/watch/regret-monitor-cli.d.ts +16 -0
  351. package/dist/watch/regret-monitor-cli.d.ts.map +1 -0
  352. package/dist/watch/regret-monitor-cli.js +137 -0
  353. package/dist/watch/regret-monitor.d.ts +168 -0
  354. package/dist/watch/regret-monitor.d.ts.map +1 -0
  355. package/dist/watch/regret-monitor.js +304 -0
  356. package/dist/watch/upgrade.d.ts +62 -0
  357. package/dist/watch/upgrade.d.ts.map +1 -0
  358. package/dist/watch/upgrade.js +57 -0
  359. package/docs/agent-skill/SKILL.md +181 -9
  360. package/docs/how-it-fits.md +3 -2
  361. package/docs/instrumentation.md +219 -46
  362. package/docs/llms.txt +158 -35
  363. package/docs/managed-serving.md +150 -0
  364. package/docs/mcp-oracle.md +322 -0
  365. package/docs/migration-playbook.md +5 -4
  366. package/docs/quickstart.md +263 -89
  367. package/package.json +18 -4
  368. package/registry/leaderboard.json +74 -0
  369. package/registry/registry.json +232 -112
  370. package/screen.d.ts +16 -0
  371. package/templates/call-disposition-qa.json +77 -0
  372. package/templates/catalog-cleansing.json +77 -0
  373. package/templates/compliance-review.json +76 -0
  374. package/templates/cs-next-action.json +76 -0
  375. package/templates/document-extraction.json +78 -0
  376. package/templates/financial-classification.json +75 -0
  377. package/templates/lead-qualification.json +76 -0
  378. package/templates/medical-classification.json +71 -0
  379. package/templates/ticket-triage.json +76 -0
  380. package/dist/feedback/feedback.d.ts +0 -35
  381. package/dist/feedback/feedback.d.ts.map +0 -1
  382. package/dist/feedback/feedback.js +0 -39
@@ -8,20 +8,25 @@
8
8
  * Tool *execution* is never ours (spec §4.4); these helpers normalize the
9
9
  * protocol and surface it — nothing here runs a tool.
10
10
  */
11
- import type { AdapterRequest, AdapterResult, CandidateRef, ProviderAdapter, ToolDefinition } from "../types/provider";
11
+ import type { AdapterRequest, AdapterResult, CandidateRef, ProviderAdapter, ServiceTier, ToolDefinition } from "../types/provider";
12
12
  import type { RigFailure } from "../types/failures";
13
- import type { RouteBundle, RunMeta, RunOptions, RunResult, RunTags } from "../types/route";
13
+ import type { OutputKind, RouteBundle, RunMeta, RunOptions, RunResult, RunTags } from "../types/route";
14
14
  import type { TelemetryRung, TelemetryStore } from "../types/telemetry";
15
15
  import type { AttemptMetaSource } from "../telemetry/attempt-meta";
16
+ import type { Destination } from "./destination";
16
17
  import type { LadderKeyMinter } from "./ladder-key";
17
18
  import type { MaskReceipt, ResolvedMaskPolicy } from "../mask/types";
18
19
  import type { RunVault } from "../mask/vault";
19
20
  import { type MaskSeam } from "../mask/seam";
21
+ import { type SearchResultItem } from "./grounding";
22
+ import type { ResolvedScreenPolicy, ScreenReceipt } from "../screen/types";
20
23
  /** One telemetry attempt row's inputs — shared with run.ts's recordAttempt so
21
24
  * the tool-call helper here can record through the same closure. */
22
25
  export interface AttemptTelemetry {
23
26
  readonly candidate: CandidateRef;
24
- readonly servedTier: string;
27
+ /** Issue #2 (L6 F1): typed as the tier vocabulary (every producer passes a
28
+ * `ServiceTier`) so the meta usage can price at the served tier. */
29
+ readonly servedTier: ServiceTier;
25
30
  readonly tokensIn: number;
26
31
  readonly tokensOut: number;
27
32
  readonly tokensCached: number;
@@ -56,6 +61,11 @@ export interface AttemptTelemetry {
56
61
  * this attempt, written to `inferences.mask` by record-attempt.ts. Present
57
62
  * only on a masked route; NEVER a matched value. Additive & optional. */
58
63
  readonly mask?: MaskReceipt;
64
+ /** SC-1a screen receipt (spec §5) — the counts-only screen summary for this
65
+ * attempt, merged onto `inferences.meta.screen` by record-attempt.ts (ZERO
66
+ * migration, §8). Present only on a screened route; NEVER a matched value.
67
+ * Additive & optional. */
68
+ readonly screen?: ScreenReceipt;
59
69
  }
60
70
  /** Assemble the recorder's `metaInputs` from a completed dispatch (WI-1) — the
61
71
  * adapter's native meta plus the rendered request (system+user+schema, hashed)
@@ -65,12 +75,28 @@ export declare function attemptMetaInputs(args: {
65
75
  readonly systemPrompt: string;
66
76
  readonly userDirective: string;
67
77
  readonly outputSchema: object | null;
78
+ /** QA-S7: the route's `outputKind` (absent on the bundle ⇒ `json`). This
79
+ * helper serves the ROUTE lane only, so every row it feeds carries the
80
+ * contract; the raw lane assembles its inputs inline and never sets it. */
81
+ readonly outputKind?: OutputKind | undefined;
68
82
  readonly result: AdapterResult;
69
83
  readonly tools?: readonly ToolDefinition[];
70
84
  }): AttemptMetaSource;
71
85
  /** run.ts's recordAttempt, threaded in so the tool-call path records through
72
86
  * the same ledger/tenancy closure the rest of the loop uses. */
73
87
  export type RecordAttempt = (attempt: AttemptTelemetry) => string;
88
+ /**
89
+ * Telemetry tag entry for a serving destination (Unified Route U2, ruling D-2 —
90
+ * the SINGLE tag literal U3/U4 stamp through). Returns the `destination` tag
91
+ * ONLY for a NON-default destination; for `direct` (the default) it returns `{}`
92
+ * so a routed telemetry row gains NO new tag — this is the CRITICAL
93
+ * absent⇒byte-identical rule (never stamp `destination` when it is `direct`, or
94
+ * every routed row would drift). DORMANT in U2: `modelrig-served` fails closed
95
+ * pre-dispatch (resolve-destination.ts), so no successful row reaches recording
96
+ * with a non-default destination yet; U3 stamps through this one helper once
97
+ * managed serving is enabled.
98
+ */
99
+ export declare function destinationTag(destination: Destination): Record<string, string>;
74
100
  /** Record the grounding-inject search's own telemetry row (WS3): a $-only line
75
101
  * under the synthetic "search" provider. Extracted from run.ts to keep it under
76
102
  * the LOC cap; behaviour is byte-identical to the prior inline recorder. */
@@ -93,6 +119,11 @@ export interface PrimaryRequestParts {
93
119
  /** True when this candidate has native grounding AND the route requires it. */
94
120
  readonly nativeGrounded: boolean;
95
121
  readonly opts: RunOptions;
122
+ /** Screening SC-1a (spec §2.2): the grounding-inject results for THIS candidate
123
+ * (or null/absent when the run is not spotlight-grounded). Threaded so the
124
+ * dispatch helper can collect the `search`-source untrusted segments the screen
125
+ * engine scans + the assembler spotlights. Optional ⇒ treated as null. */
126
+ readonly injectedSources?: readonly SearchResultItem[] | null;
96
127
  /** CE-1 retry-drop: suppress a customer cache handle on THIS dispatch after a
97
128
  * prior `cache_invalid` on the same candidate carried it. Additive; absent /
98
129
  * false = normal (the handle applies when provider matches). */
@@ -118,28 +149,45 @@ export interface MaskContext {
118
149
  readonly policy: ResolvedMaskPolicy;
119
150
  readonly vault: RunVault;
120
151
  }
121
- /** The outcome of a build+mask+dispatch (CS-1 seam, spec §1.2). Carries the
122
- * (possibly masked) request, the adapter result, measured latency, and the
123
- * per-attempt {@link MaskSeam} the run loop uses to rehydrate the response and
124
- * build the receipt. `maskRefusal` is set when masking FAILED CLOSED
125
- * pre-dispatch (`block` found a match, or a detector threw in mask/block) — no
126
- * request was sent, and the run loop fails the run with `invariant_violation`. */
152
+ /** The per-run guards the run loop hands the dispatch seam: the CS-1 mask
153
+ * context and the SC-1a resolved screen policy (spec §4). Both null ⇒ the
154
+ * dispatch path is byte-identical to `buildAdapterRequest` + `dispatchCandidate`
155
+ * over the assembled request (the golden test). */
156
+ export interface RunGuards {
157
+ readonly mask: MaskContext | null;
158
+ readonly screen: ResolvedScreenPolicy | null;
159
+ }
160
+ /** Build the per-run guards for a route (called ONCE at run start). The mask
161
+ * vault is run-scoped (shared across attempts); the screen policy is resolved at
162
+ * load and reused. Null members ⇒ that guard is inert (byte-identical). */
163
+ export declare function buildRunGuards(route: RouteBundle, newVault: () => RunVault): RunGuards;
164
+ /** The outcome of an assemble+screen+mask+dispatch (CS-1/SC-1a seam). Carries the
165
+ * (possibly rewritten) request, the adapter result, measured latency, the
166
+ * per-attempt {@link MaskSeam} the run loop uses to rehydrate, and the counts-only
167
+ * screen receipt for `meta.screen`. `maskRefusal` is set when masking failed
168
+ * closed; `screenRefusal` when screening resolved `block` (spec §4.3) — in both
169
+ * cases NO request was sent and the run loop fails the run with
170
+ * `invariant_violation`. */
127
171
  export interface DispatchOutcome {
128
172
  readonly request: AdapterRequest;
129
173
  readonly result: AdapterResult;
130
174
  readonly latencyMs: number;
131
175
  readonly seam: MaskSeam | null;
132
176
  readonly maskRefusal?: "blocked" | "error";
177
+ readonly screenRefusal?: "block";
178
+ readonly screenReceipt?: ScreenReceipt;
133
179
  }
134
180
  /**
135
- * Build the primary AdapterRequest, mask its outgoing user slot when the route
136
- * has an active policy (spec §1.2 — "rewrites the AdapterRequest before dispatch
137
- * and rehydrates the AdapterResult after"), dispatch, and time it. With no mask
138
- * context this is byte-identical to `buildAdapterRequest` + `dispatchCandidate`
139
- * (the golden test). The trusted system slot is never masked (B3 keeps untrusted
140
- * content in the user path).
181
+ * Assemble the untrusted block, SCREEN it (spec §4 — the request-side seam),
182
+ * MASK the user slot (CS-1, screening runs BEFORE masking so mask tokens never
183
+ * confuse a detector), dispatch, and apply the output-side screen (canary /
184
+ * citations / Unicode strip + quarantine drop-count). With both guards null this
185
+ * is byte-identical to `buildAdapterRequest(assembled)` + `dispatchCandidate`
186
+ * (the golden test) — the untrusted-block assembly moved here from run.ts so the
187
+ * loop stays under the LOC cap (spec §10(i)). The trusted system slot is never
188
+ * masked (B3 keeps untrusted content in the user path).
141
189
  */
142
- export declare function buildDispatchMaybeMasked(adapter: ProviderAdapter, parts: PrimaryRequestParts, onDelta: StreamDeltaSink | undefined, mask: MaskContext | null): Promise<DispatchOutcome>;
190
+ export declare function buildDispatchMaybeMasked(adapter: ProviderAdapter, parts: PrimaryRequestParts, onDelta: StreamDeltaSink | undefined, guards: RunGuards): Promise<DispatchOutcome>;
143
191
  export interface ToolCallResultParts {
144
192
  readonly route: RouteBundle;
145
193
  readonly candidate: CandidateRef;
@@ -156,6 +204,9 @@ export interface ToolCallResultParts {
156
204
  readonly callId: string;
157
205
  /** WI-1: the attempt-envelope inputs for the recorded row (spec §2). */
158
206
  readonly metaInputs?: AttemptMetaSource;
207
+ /** Unified Route U2 (D-2): the resolved served destination for `RunMeta`
208
+ * (always `direct` in U2 — `modelrig-served` fails closed pre-dispatch). */
209
+ readonly destination?: RunMeta["destination"];
159
210
  }
160
211
  /**
161
212
  * Record a tool-call turn and build its RunResult (spec §4.4). A tool call is
@@ -1 +1 @@
1
- {"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../../src/run/dispatch.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../../src/run/dispatch.ts"],"names":[],"mappings":"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"}
@@ -11,18 +11,25 @@
11
11
  */
12
12
  Object.defineProperty(exports, "__esModule", { value: true });
13
13
  exports.attemptMetaInputs = attemptMetaInputs;
14
+ exports.destinationTag = destinationTag;
14
15
  exports.recordSearchCostRow = recordSearchCostRow;
15
16
  exports.jsonModeCoaching = jsonModeCoaching;
16
17
  exports.buildAdapterRequest = buildAdapterRequest;
17
18
  exports.buildRepairAdapterRequest = buildRepairAdapterRequest;
18
19
  exports.dispatchCandidate = dispatchCandidate;
20
+ exports.buildRunGuards = buildRunGuards;
19
21
  exports.buildDispatchMaybeMasked = buildDispatchMaybeMasked;
20
22
  exports.emitToolCallResult = emitToolCallResult;
23
+ const provider_1 = require("../types/provider");
21
24
  const node_crypto_1 = require("node:crypto");
22
25
  const attempt_meta_1 = require("../telemetry/attempt-meta");
23
26
  const cache_stamp_1 = require("./cache-stamp");
24
27
  const cache_handle_1 = require("./cache-handle");
28
+ const destination_1 = require("./destination");
29
+ const telemetry_row_1 = require("./telemetry-row");
25
30
  const seam_1 = require("../mask/seam");
31
+ const grounding_1 = require("./grounding");
32
+ const screen_1 = require("../screen/screen");
26
33
  /** Assemble the recorder's `metaInputs` from a completed dispatch (WI-1) — the
27
34
  * adapter's native meta plus the rendered request (system+user+schema, hashed)
28
35
  * and the output text (hashed). One helper so the routed lane's several record
@@ -30,6 +37,7 @@ const seam_1 = require("../mask/seam");
30
37
  function attemptMetaInputs(args) {
31
38
  return {
32
39
  ...(args.result.meta !== undefined ? { adapterMeta: args.result.meta } : {}),
40
+ outputKind: args.outputKind ?? "json",
33
41
  renderedRequest: (0, attempt_meta_1.renderRequestForHash)({
34
42
  system: args.systemPrompt,
35
43
  user: args.userDirective,
@@ -39,6 +47,20 @@ function attemptMetaInputs(args) {
39
47
  ...(args.tools !== undefined ? { declaredToolNames: args.tools.map((t) => t.function.name) } : {}),
40
48
  };
41
49
  }
50
+ /**
51
+ * Telemetry tag entry for a serving destination (Unified Route U2, ruling D-2 —
52
+ * the SINGLE tag literal U3/U4 stamp through). Returns the `destination` tag
53
+ * ONLY for a NON-default destination; for `direct` (the default) it returns `{}`
54
+ * so a routed telemetry row gains NO new tag — this is the CRITICAL
55
+ * absent⇒byte-identical rule (never stamp `destination` when it is `direct`, or
56
+ * every routed row would drift). DORMANT in U2: `modelrig-served` fails closed
57
+ * pre-dispatch (resolve-destination.ts), so no successful row reaches recording
58
+ * with a non-default destination yet; U3 stamps through this one helper once
59
+ * managed serving is enabled.
60
+ */
61
+ function destinationTag(destination) {
62
+ return destination === destination_1.DEFAULT_DESTINATION ? {} : { destination };
63
+ }
42
64
  /** Record the grounding-inject search's own telemetry row (WS3): a $-only line
43
65
  * under the synthetic "search" provider. Extracted from run.ts to keep it under
44
66
  * the LOC cap; behaviour is byte-identical to the prior inline recorder. */
@@ -47,9 +69,11 @@ function recordSearchCostRow(telemetry, route, effectiveTags, servedVariant, sea
47
69
  // rides the same monotonic seq; candidate_index is the candidate this search
48
70
  // grounds for (the current one — the run loop set it before the search).
49
71
  const ladderKey = ladder.stamp();
50
- telemetry.record({
72
+ // U4: assembled by the ONE shared builder (./telemetry-row.ts). This row
73
+ // carries NO attempt-envelope `meta` — buildTelemetryRow omits the key when
74
+ // `meta` is not passed, preserving the former shape exactly.
75
+ telemetry.record((0, telemetry_row_1.buildTelemetryRow)({
51
76
  id: (0, node_crypto_1.randomUUID)(),
52
- ts: new Date().toISOString(),
53
77
  route: route.route,
54
78
  routeVersion: route.version,
55
79
  provider: "search",
@@ -67,7 +91,8 @@ function recordSearchCostRow(telemetry, route, effectiveTags, servedVariant, sea
67
91
  failureClass: null,
68
92
  attemptsJson: "{}",
69
93
  // Rung tag (R1 review, F1): the grounding-inject search-cost row.
70
- tagsJson: JSON.stringify({ ...effectiveTags, rung: "search" }),
94
+ baseTags: effectiveTags,
95
+ rung: "search",
71
96
  fingerprintCell: route.fingerprintCell,
72
97
  servedVariant,
73
98
  repairedBy: null,
@@ -77,7 +102,7 @@ function recordSearchCostRow(telemetry, route, effectiveTags, servedVariant, sea
77
102
  callId: ladderKey.callId,
78
103
  attemptSeq: ladderKey.attemptSeq,
79
104
  candidateIndex: ladderKey.candidateIndex,
80
- });
105
+ }));
81
106
  }
82
107
  /** Schema coaching for the json_mode rung — ported from the production DeepSeek
83
108
  * provider's schema-in-prompt guidance (minLength-is-a-FLOOR etc.). Lives here
@@ -181,36 +206,114 @@ async function dispatchCandidate(adapter, req, onDelta) {
181
206
  },
182
207
  });
183
208
  }
209
+ /** Build the per-run guards for a route (called ONCE at run start). The mask
210
+ * vault is run-scoped (shared across attempts); the screen policy is resolved at
211
+ * load and reused. Null members ⇒ that guard is inert (byte-identical). */
212
+ function buildRunGuards(route, newVault) {
213
+ return {
214
+ mask: route.mask !== undefined ? { policy: route.mask, vault: newVault() } : null,
215
+ screen: route.screen ?? null,
216
+ };
217
+ }
218
+ function invariantResult(parts, why) {
219
+ return {
220
+ ok: false,
221
+ failure: { class: "invariant_violation", message: why, provider: parts.candidate.provider, model: parts.candidate.model },
222
+ };
223
+ }
184
224
  /**
185
- * Build the primary AdapterRequest, mask its outgoing user slot when the route
186
- * has an active policy (spec §1.2 — "rewrites the AdapterRequest before dispatch
187
- * and rehydrates the AdapterResult after"), dispatch, and time it. With no mask
188
- * context this is byte-identical to `buildAdapterRequest` + `dispatchCandidate`
189
- * (the golden test). The trusted system slot is never masked (B3 keeps untrusted
190
- * content in the user path).
225
+ * Assemble the untrusted block, SCREEN it (spec §4 — the request-side seam),
226
+ * MASK the user slot (CS-1, screening runs BEFORE masking so mask tokens never
227
+ * confuse a detector), dispatch, and apply the output-side screen (canary /
228
+ * citations / Unicode strip + quarantine drop-count). With both guards null this
229
+ * is byte-identical to `buildAdapterRequest(assembled)` + `dispatchCandidate`
230
+ * (the golden test) — the untrusted-block assembly moved here from run.ts so the
231
+ * loop stays under the LOC cap (spec §10(i)). The trusted system slot is never
232
+ * masked (B3 keeps untrusted content in the user path).
191
233
  */
192
- async function buildDispatchMaybeMasked(adapter, parts, onDelta, mask) {
193
- const built = buildAdapterRequest(parts);
194
- if (mask === null) {
195
- const started = Date.now();
196
- const result = await dispatchCandidate(adapter, built, onDelta);
197
- return { request: built, result, latencyMs: Date.now() - started, seam: null };
234
+ async function buildDispatchMaybeMasked(adapter, parts, onDelta, guards) {
235
+ const provider = parts.candidate.provider;
236
+ // The untrusted segments this route+input contribute (search / x-trust
237
+ // variable / proxy_user). Empty on a plain route ⇒ empty appends below.
238
+ const segments = (0, grounding_1.collectUntrustedSegments)(parts.route, parts.opts.input, parts.injectedSources ?? null, parts.opts.proxyTrust);
239
+ // Request-side screening (spec §4.2/§4.3). A `block` outcome fails closed
240
+ // pre-dispatch (no request sent). `strip` filters segments; `quarantine` gates
241
+ // tool calls below. Screening runs on the RAW untrusted content, before mask.
242
+ const screenSeam = guards.screen !== null ? (0, screen_1.createScreenSeam)(guards.screen) : null;
243
+ let keep = segments;
244
+ let quarantine = false;
245
+ if (screenSeam !== null) {
246
+ const decided = await screenSeam.screenRequest(segments);
247
+ if (decided.kind === "block") {
248
+ return {
249
+ request: buildAdapterRequest(parts),
250
+ result: invariantResult(parts, "screening resolved block (untrusted content matched an enforce rule)"),
251
+ latencyMs: 0,
252
+ seam: null,
253
+ screenRefusal: "block",
254
+ screenReceipt: screenSeam.receipt(),
255
+ };
256
+ }
257
+ keep = decided.keepSegments;
258
+ quarantine = decided.quarantine;
198
259
  }
199
- const seam = (0, seam_1.createMaskSeam)(mask.policy, mask.vault);
200
- const outcome = seam.maskRequest(built);
201
- if (outcome.kind !== "ok") {
202
- // Fail closed: no request is sent. The run loop refuses pre-dispatch.
203
- return {
204
- request: built,
205
- result: { ok: false, failure: { class: "invariant_violation", message: `masking failed closed (${outcome.kind})`, provider: parts.candidate.provider, model: parts.candidate.model } },
206
- latencyMs: 0,
207
- seam,
208
- maskRefusal: outcome.kind,
209
- };
260
+ // Assemble the (post-strip) untrusted appends + the optional canary into the
261
+ // trusted system slot. Screening-OFF ⇒ `keep === segments` ⇒ byte-identical.
262
+ const { systemAppend, userAppend } = (0, grounding_1.assembleUntrustedAppends)(keep, provider);
263
+ const canaryAppend = screenSeam?.canaryToken != null ? `\n\n${screenSeam.canaryToken}` : "";
264
+ const assembledParts = {
265
+ ...parts,
266
+ systemPrompt: parts.systemPrompt + systemAppend + canaryAppend,
267
+ userDirective: parts.userDirective + userAppend,
268
+ };
269
+ let built = buildAdapterRequest(assembledParts);
270
+ // Quarantine (spec §4.2): prevent the flagged turn from actuating a tool call
271
+ // via `tool_choice: "none"` where the served model supports it; otherwise fall
272
+ // back to dropping + counting tool calls in the response (A7, honest).
273
+ const capable = (0, provider_1.toolChoiceNoneCapable)(provider);
274
+ if (quarantine && capable)
275
+ built = { ...built, toolChoice: "none" };
276
+ // Mask the (screened) user slot. Fail-closed refusal is unchanged (CS-1 §9).
277
+ let request = built;
278
+ let seam = null;
279
+ if (guards.mask !== null) {
280
+ seam = (0, seam_1.createMaskSeam)(guards.mask.policy, guards.mask.vault);
281
+ const outcome = seam.maskRequest(built);
282
+ if (outcome.kind !== "ok") {
283
+ return {
284
+ request: built,
285
+ result: invariantResult(parts, `masking failed closed (${outcome.kind})`),
286
+ latencyMs: 0,
287
+ seam,
288
+ maskRefusal: outcome.kind,
289
+ ...(screenSeam !== null ? { screenReceipt: screenSeam.receipt() } : {}),
290
+ };
291
+ }
292
+ request = outcome.request;
210
293
  }
211
294
  const started = Date.now();
212
- const result = await dispatchCandidate(adapter, outcome.request, onDelta);
213
- return { request: outcome.request, result, latencyMs: Date.now() - started, seam };
295
+ let result = await dispatchCandidate(adapter, request, onDelta);
296
+ const latencyMs = Date.now() - started;
297
+ // Output-side screening (spec §2.3): strip Unicode tags, allowlist citations,
298
+ // detect canary leak, and — on a quarantined turn without tool_choice parity —
299
+ // DROP + COUNT any tool calls the model emitted (A7).
300
+ if (screenSeam !== null && result.ok) {
301
+ if (quarantine && result.toolCalls !== undefined && result.toolCalls.length > 0) {
302
+ screenSeam.noteQuarantineDrop(result.toolCalls.length);
303
+ result = { ...result, toolCalls: [] };
304
+ }
305
+ const injectedUrls = (parts.injectedSources ?? []).map((s) => s.url);
306
+ const cleaned = screenSeam.screenResponse(result.text, injectedUrls);
307
+ if (cleaned !== result.text)
308
+ result = { ...result, text: cleaned };
309
+ }
310
+ return {
311
+ request,
312
+ result,
313
+ latencyMs,
314
+ seam,
315
+ ...(screenSeam !== null ? { screenReceipt: screenSeam.receipt() } : {}),
316
+ };
214
317
  }
215
318
  /**
216
319
  * Record a tool-call turn and build its RunResult (spec §4.4). A tool call is
@@ -267,6 +370,7 @@ function emitToolCallResult(record, parts) {
267
370
  repairedBy: null,
268
371
  callId: parts.callId,
269
372
  toolCalls: result.toolCalls,
373
+ ...(parts.destination !== undefined ? { destination: parts.destination } : {}),
270
374
  },
271
375
  };
272
376
  }
@@ -16,6 +16,7 @@
16
16
  */
17
17
  import type { RouteBundle } from "../types/route";
18
18
  import { type ProviderId } from "../types/provider";
19
+ import { type ContentSegment } from "../screen/provenance";
19
20
  export interface SearchResultItem {
20
21
  readonly title: string;
21
22
  readonly url: string;
@@ -85,11 +86,36 @@ export declare const SEARCH_SNIPPET_MAX_CHARS = 500;
85
86
  * untrusted-input policy sentence is owned by the provenance assembler and added
86
87
  * to the system slot via `untrustedSystemAppend` — screening F2, single owner). */
87
88
  export declare function groundingSystemAppend(assembly: RouteBundle["groundingAssembly"], results: readonly SearchResultItem[], retrievedAt: string): string;
89
+ /** S3 (SC-0, spec §11.3): the effective system-slot removal set for the template
90
+ * renderer = `keys(variableTrust)` ∪ `proxyTrust`, expressed in the SAME shape the
91
+ * x-trust removal path consumes (`Record<name, "untrusted">`, routes/template.ts).
92
+ * A name in `proxyTrust` therefore renders EMPTY in the trusted system slot,
93
+ * reusing that path rather than forking it. Absent/empty `proxyTrust` ⇒ the
94
+ * `variableTrust` reference is returned UNCHANGED, so the render is byte-identical. */
95
+ export declare function systemSlotRemoval(variableTrust: Readonly<Record<string, "untrusted">> | undefined, proxyTrust: readonly string[] | undefined): Readonly<Record<string, "untrusted">> | undefined;
96
+ /** Screening S1 + S2 (SC-0 B3) + S3 (SC-0): the untrusted segments a route+input
97
+ * contribute — (a) each name in `proxyTrust` present in input, tagged
98
+ * `proxy_user` (S3); (b) each `x-trust: untrusted` variable (S2), tagged
99
+ * `variable`; and (c), when `grounding.assembly: spotlight`, the search results
100
+ * (S1), tagged `search`. Shared by the system- and user-slot builders so the two
101
+ * slots agree on "is anything untrusted present" (screening F2). Empty ⇒ nothing
102
+ * untrusted (byte-identical default — `proxyTrust` is unset in S3). */
103
+ export declare function collectUntrustedSegments(route: Pick<RouteBundle, "groundingAssembly" | "variableTrust">, input: Record<string, unknown>, injectedSources: readonly SearchResultItem[] | null, proxyTrust?: readonly string[]): ContentSegment[];
88
104
  /** Screening S1 + S2 (SC-0 B3): the USER-slot untrusted block appended after the
89
105
  * user directive. Assembles the untrusted segments into a single spotlighted,
90
106
  * JSON-encoded, delimiter-wrapped block via the provenance assembler. Returns ""
91
107
  * when there is nothing untrusted (byte-identical default). */
92
- export declare function untrustedUserBlock(route: Pick<RouteBundle, "groundingAssembly" | "variableTrust">, input: Record<string, unknown>, injectedSources: readonly SearchResultItem[] | null, provider: ProviderId): string;
108
+ export declare function untrustedUserBlock(route: Pick<RouteBundle, "groundingAssembly" | "variableTrust">, input: Record<string, unknown>, injectedSources: readonly SearchResultItem[] | null, provider: ProviderId, proxyTrust?: readonly string[]): string;
109
+ /** SC-1a: assemble a GIVEN segment list into the {systemAppend, userAppend} the
110
+ * dispatch helper appends. Byte-identical to `untrustedSystemAppend` +
111
+ * `untrustedUserBlock` when `segments` is the full collected set (same
112
+ * assemblePrompt calls, same nonce semantics) — so the screening-OFF path stays
113
+ * golden. The screening path passes the POST-strip `keepSegments`, so a stripped
114
+ * segment vanishes from both slots. Returns empty appends for an empty list. */
115
+ export declare function assembleUntrustedAppends(segments: readonly ContentSegment[], provider: ProviderId): {
116
+ readonly systemAppend: string;
117
+ readonly userAppend: string;
118
+ };
93
119
  /** Screening F2 (SC-0 B3): the SYSTEM-slot untrusted-input policy sentence. The
94
120
  * provenance assembler is the SINGLE owner of this sentence (spec §2.2); this
95
121
  * surfaces its system-slot output whenever ANY untrusted segment is delivered —
@@ -97,5 +123,5 @@ export declare function untrustedUserBlock(route: Pick<RouteBundle, "groundingAs
97
123
  * template still gets its "this is data" framing. Returns "" when there is
98
124
  * nothing untrusted (byte-identical default). The assembler's system slot does
99
125
  * not depend on the nonce or the block shape, so fixed placeholders suffice. */
100
- export declare function untrustedSystemAppend(route: Pick<RouteBundle, "groundingAssembly" | "variableTrust">, input: Record<string, unknown>, injectedSources: readonly SearchResultItem[] | null): string;
126
+ export declare function untrustedSystemAppend(route: Pick<RouteBundle, "groundingAssembly" | "variableTrust">, input: Record<string, unknown>, injectedSources: readonly SearchResultItem[] | null, proxyTrust?: readonly string[]): string;
101
127
  //# sourceMappingURL=grounding.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"grounding.d.ts","sourceRoot":"","sources":["../../src/run/grounding.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"grounding.d.ts","sourceRoot":"","sources":["../../src/run/grounding.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAqB,KAAK,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAkB,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3E,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CACjC;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,OAAO,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAC9C,mEAAmE;IACnE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;CACzF;AAED,sEAAsE;AACtE,eAAO,MAAM,sBAAsB,MAAM,CAAC;AAE1C,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;uDACmD;IACnD,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;IAC5C,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,sDAAsD;IACtD,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;CACjC;AAaD,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,kBAAkB,GAAG,cAAc,CAoCrF;AAED;gEACgE;AAChE,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,SAAS,gBAAgB,EAAE,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAYtG;AAED,yEAAyE;AACzE,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAWD;;;;;;mFAMmF;AACnF,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,SAAS,gBAAgB,EAAE,GACnC,WAAW,EAAE,CAYf;AAED;kFACkF;AAClF,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,SAAS,gBAAgB,EAAE,GACnC,MAAM,CAGR;AAED;;kFAEkF;AAClF,wBAAgB,aAAa,CAC3B,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,SAAS,gBAAgB,EAAE,GACnC;IAAE,SAAS,EAAE,WAAW,EAAE,CAAC;IAAC,SAAS,EAAE;QAAE,iBAAiB,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,CAKxE;AAED;mDACmD;AACnD,eAAO,MAAM,wBAAwB,MAAM,CAAC;AAM5C;;;;mFAImF;AACnF,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,WAAW,CAAC,mBAAmB,CAAC,EAC1C,OAAO,EAAE,SAAS,gBAAgB,EAAE,EACpC,WAAW,EAAE,MAAM,GAClB,MAAM,CAGR;AAED;;;;;uFAKuF;AACvF,wBAAgB,iBAAiB,CAC/B,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,GAAG,SAAS,EAChE,UAAU,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,GACxC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,GAAG,SAAS,CAKnD;AAED;;;;;;uEAMuE;AACvE,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,IAAI,CAAC,WAAW,EAAE,mBAAmB,GAAG,eAAe,CAAC,EAC/D,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,eAAe,EAAE,SAAS,gBAAgB,EAAE,GAAG,IAAI,EACnD,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,GAC7B,cAAc,EAAE,CA8BlB;AAED;;;+DAG+D;AAC/D,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,IAAI,CAAC,WAAW,EAAE,mBAAmB,GAAG,eAAe,CAAC,EAC/D,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,eAAe,EAAE,SAAS,gBAAgB,EAAE,GAAG,IAAI,EACnD,QAAQ,EAAE,UAAU,EACpB,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,GAC7B,MAAM,CAKR;AAED;;;;;gFAKgF;AAChF,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,SAAS,cAAc,EAAE,EACnC,QAAQ,EAAE,UAAU,GACnB;IAAE,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAKhE;AAED;;;;;;gFAMgF;AAChF,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,IAAI,CAAC,WAAW,EAAE,mBAAmB,GAAG,eAAe,CAAC,EAC/D,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,eAAe,EAAE,SAAS,gBAAgB,EAAE,GAAG,IAAI,EACnD,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,GAC7B,MAAM,CAKR"}
@@ -24,7 +24,10 @@ exports.extractCitations = extractCitations;
24
24
  exports.countDroppedCitations = countDroppedCitations;
25
25
  exports.groundingMeta = groundingMeta;
26
26
  exports.groundingSystemAppend = groundingSystemAppend;
27
+ exports.systemSlotRemoval = systemSlotRemoval;
28
+ exports.collectUntrustedSegments = collectUntrustedSegments;
27
29
  exports.untrustedUserBlock = untrustedUserBlock;
30
+ exports.assembleUntrustedAppends = assembleUntrustedAppends;
28
31
  exports.untrustedSystemAppend = untrustedSystemAppend;
29
32
  const node_crypto_1 = require("node:crypto");
30
33
  const provider_1 = require("../types/provider");
@@ -141,17 +144,45 @@ function groundingSystemAppend(assembly, results, retrievedAt) {
141
144
  return "";
142
145
  return searchInjectionBlock(results, retrievedAt); // legacy default — byte-identical
143
146
  }
144
- /** Screening S1 + S2 (SC-0 B3): the untrusted segments a route+input contribute
145
- * — (a) each `x-trust: untrusted` variable (S2) and (b), when
146
- * `grounding.assembly: spotlight`, the search results (S1). Shared by the system-
147
- * and user-slot builders so the two slots agree on "is anything untrusted
148
- * present" (screening F2). Empty ⇒ nothing untrusted (byte-identical default). */
149
- function collectUntrustedSegments(route, input, injectedSources) {
147
+ /** S3 (SC-0, spec §11.3): the effective system-slot removal set for the template
148
+ * renderer = `keys(variableTrust)` ∪ `proxyTrust`, expressed in the SAME shape the
149
+ * x-trust removal path consumes (`Record<name, "untrusted">`, routes/template.ts).
150
+ * A name in `proxyTrust` therefore renders EMPTY in the trusted system slot,
151
+ * reusing that path rather than forking it. Absent/empty `proxyTrust` ⇒ the
152
+ * `variableTrust` reference is returned UNCHANGED, so the render is byte-identical. */
153
+ function systemSlotRemoval(variableTrust, proxyTrust) {
154
+ if (proxyTrust === undefined || proxyTrust.length === 0)
155
+ return variableTrust;
156
+ const merged = { ...(variableTrust ?? {}) };
157
+ for (const name of proxyTrust)
158
+ merged[name] = "untrusted";
159
+ return merged;
160
+ }
161
+ /** Screening S1 + S2 (SC-0 B3) + S3 (SC-0): the untrusted segments a route+input
162
+ * contribute — (a) each name in `proxyTrust` present in input, tagged
163
+ * `proxy_user` (S3); (b) each `x-trust: untrusted` variable (S2), tagged
164
+ * `variable`; and (c), when `grounding.assembly: spotlight`, the search results
165
+ * (S1), tagged `search`. Shared by the system- and user-slot builders so the two
166
+ * slots agree on "is anything untrusted present" (screening F2). Empty ⇒ nothing
167
+ * untrusted (byte-identical default — `proxyTrust` is unset in S3). */
168
+ function collectUntrustedSegments(route, input, injectedSources, proxyTrust) {
150
169
  const segments = [];
170
+ // S3: each per-call proxyTrust name present in input is `proxy_user` untrusted
171
+ // content — the request-side isolation seam for the slug/proxy lane.
172
+ const proxyNames = new Set(proxyTrust ?? []);
173
+ for (const name of proxyNames) {
174
+ const value = input[name];
175
+ if (value === undefined)
176
+ continue;
177
+ const text = typeof value === "string" ? value : JSON.stringify(value);
178
+ segments.push({ source: "proxy_user", tier: "untrusted", text });
179
+ }
151
180
  // S2: each variable annotated `x-trust: untrusted` moves out of the system slot.
152
181
  for (const [name, trust] of Object.entries(route.variableTrust ?? {})) {
153
182
  if (trust !== "untrusted")
154
183
  continue;
184
+ if (proxyNames.has(name))
185
+ continue; // proxy_user takes precedence — never double-emit
155
186
  const value = input[name];
156
187
  if (value === undefined)
157
188
  continue;
@@ -173,13 +204,26 @@ function collectUntrustedSegments(route, input, injectedSources) {
173
204
  * user directive. Assembles the untrusted segments into a single spotlighted,
174
205
  * JSON-encoded, delimiter-wrapped block via the provenance assembler. Returns ""
175
206
  * when there is nothing untrusted (byte-identical default). */
176
- function untrustedUserBlock(route, input, injectedSources, provider) {
177
- const segments = collectUntrustedSegments(route, input, injectedSources);
207
+ function untrustedUserBlock(route, input, injectedSources, provider, proxyTrust) {
208
+ const segments = collectUntrustedSegments(route, input, injectedSources, proxyTrust);
178
209
  if (segments.length === 0)
179
210
  return "";
180
211
  const assembled = (0, provenance_1.assemblePrompt)(segments, { nonce: (0, node_crypto_1.randomUUID)(), untrustedBlock: (0, provider_1.untrustedBlockFor)(provider) });
181
212
  return `\n\n${assembled.user}`;
182
213
  }
214
+ /** SC-1a: assemble a GIVEN segment list into the {systemAppend, userAppend} the
215
+ * dispatch helper appends. Byte-identical to `untrustedSystemAppend` +
216
+ * `untrustedUserBlock` when `segments` is the full collected set (same
217
+ * assemblePrompt calls, same nonce semantics) — so the screening-OFF path stays
218
+ * golden. The screening path passes the POST-strip `keepSegments`, so a stripped
219
+ * segment vanishes from both slots. Returns empty appends for an empty list. */
220
+ function assembleUntrustedAppends(segments, provider) {
221
+ if (segments.length === 0)
222
+ return { systemAppend: "", userAppend: "" };
223
+ const sys = (0, provenance_1.assemblePrompt)(segments, { nonce: "", untrustedBlock: "user_json" }).system;
224
+ const { user } = (0, provenance_1.assemblePrompt)(segments, { nonce: (0, node_crypto_1.randomUUID)(), untrustedBlock: (0, provider_1.untrustedBlockFor)(provider) });
225
+ return { systemAppend: sys === "" ? "" : `\n\n${sys}`, userAppend: `\n\n${user}` };
226
+ }
183
227
  /** Screening F2 (SC-0 B3): the SYSTEM-slot untrusted-input policy sentence. The
184
228
  * provenance assembler is the SINGLE owner of this sentence (spec §2.2); this
185
229
  * surfaces its system-slot output whenever ANY untrusted segment is delivered —
@@ -187,8 +231,8 @@ function untrustedUserBlock(route, input, injectedSources, provider) {
187
231
  * template still gets its "this is data" framing. Returns "" when there is
188
232
  * nothing untrusted (byte-identical default). The assembler's system slot does
189
233
  * not depend on the nonce or the block shape, so fixed placeholders suffice. */
190
- function untrustedSystemAppend(route, input, injectedSources) {
191
- const segments = collectUntrustedSegments(route, input, injectedSources);
234
+ function untrustedSystemAppend(route, input, injectedSources, proxyTrust) {
235
+ const segments = collectUntrustedSegments(route, input, injectedSources, proxyTrust);
192
236
  if (segments.length === 0)
193
237
  return "";
194
238
  const { system } = (0, provenance_1.assemblePrompt)(segments, { nonce: "", untrustedBlock: "user_json" });
@@ -1 +1 @@
1
- {"version":3,"file":"raw-defaults.d.ts","sourceRoot":"","sources":["../../src/run/raw-defaults.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAI9D,CAAC;AAEF,uDAAuD;AACvD,MAAM,WAAW,aAAa;IAC5B,kDAAkD;IAClD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;4EACwE;IACxE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,oDAAoD;IACpD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAeD;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,EAAE,SAAS,aAAa,EA6DhD,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAK1C"}
1
+ {"version":3,"file":"raw-defaults.d.ts","sourceRoot":"","sources":["../../src/run/raw-defaults.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAI9D,CAAC;AAEF,uDAAuD;AACvD,MAAM,WAAW,aAAa;IAC5B,kDAAkD;IAClD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;4EACwE;IACxE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,oDAAoD;IACpD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAeD;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,EAAE,SAAS,aAAa,EAkEhD,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAK1C"}
@@ -55,7 +55,7 @@ exports.RAW_DEFAULTS = [
55
55
  {
56
56
  knob: "serviceTier",
57
57
  default: "standard",
58
- note: "forwarded to the adapter; `meta.servedTier` reports what actually served. On `flex`, set `timeoutMs` in minutes (default 900 s)",
58
+ note: "forwarded to the adapter; `meta.servedTier` reports what actually served, and the cost row is priced at the SERVED tier (gemini flex = 0.5× input + output, cache read NOT discounted; priority = 1.8×). On `flex`, set `timeoutMs` in minutes (default 900 s)",
59
59
  },
60
60
  {
61
61
  knob: "temperature",
@@ -87,6 +87,11 @@ exports.RAW_DEFAULTS = [
87
87
  default: "absent ⇒ byte-identical",
88
88
  note: "syntactic-JSON forcing (mime-shaping only); provider support per the raw-lane knob matrix",
89
89
  },
90
+ {
91
+ knob: "responseSchema",
92
+ default: "absent ⇒ byte-identical (no schema sent, no validation)",
93
+ note: "JSON Schema forwarded natively AND Ajv-checked client-side — a miss is a billed, terminal `content_invalid` (never repaired); `meta.schema_sha` on the row; provider support per the raw-lane knob matrix",
94
+ },
90
95
  {
91
96
  knob: "cache",
92
97
  default: "none",