@tangle-network/agent-eval 0.215.1 → 0.216.1

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 (400) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/dist/adapters/http.d.ts +3 -3
  3. package/dist/{agent-profile-DmzL8KaJ.d.ts → agent-profile-VFcQncbW.d.ts} +5 -5
  4. package/dist/{agent-profile-DmzL8KaJ.d.ts.map → agent-profile-VFcQncbW.d.ts.map} +1 -1
  5. package/dist/{agent-profile-cell-BYc0bxsL.js → agent-profile-cell-BK8mlqlq.js} +3 -3
  6. package/dist/{agent-profile-cell-BYc0bxsL.js.map → agent-profile-cell-BK8mlqlq.js.map} +1 -1
  7. package/dist/agreement-irr-BEWLIF3_.js +186 -0
  8. package/dist/agreement-irr-BEWLIF3_.js.map +1 -0
  9. package/dist/analyst/index.d.ts +487 -14
  10. package/dist/analyst/index.d.ts.map +1 -1
  11. package/dist/analyst/index.js +1547 -12
  12. package/dist/analyst/index.js.map +1 -1
  13. package/dist/{analyze-runs-3xpby3p2.js → analyze-runs-C84irm4i.js} +608 -604
  14. package/dist/analyze-runs-C84irm4i.js.map +1 -0
  15. package/dist/{analyze-runs-BhFLOztS.d.ts → analyze-runs-D68fd-su.d.ts} +17 -15
  16. package/dist/analyze-runs-D68fd-su.d.ts.map +1 -0
  17. package/dist/{baseline-Dm8966du.js → baseline-Udi_PLuT.js} +5 -5
  18. package/dist/{baseline-Dm8966du.js.map → baseline-Udi_PLuT.js.map} +1 -1
  19. package/dist/{benchmark-BywPeAUo.js → benchmark-CXmVVHH2.js} +2 -2
  20. package/dist/{benchmark-BywPeAUo.js.map → benchmark-CXmVVHH2.js.map} +1 -1
  21. package/dist/{benchmark-command-CgpGi7vY.js → benchmark-command-By0vh8q7.js} +71 -70
  22. package/dist/benchmark-command-By0vh8q7.js.map +1 -0
  23. package/dist/benchmarks/index.d.ts +5 -5
  24. package/dist/benchmarks/index.js +3 -3
  25. package/dist/builder-eval/index.js +2 -2
  26. package/dist/campaign/index.d.ts +7 -7
  27. package/dist/campaign/index.js +14 -14
  28. package/dist/{campaign-CpnsCgfz.js → campaign-BudZ70zo.js} +245 -247
  29. package/dist/campaign-BudZ70zo.js.map +1 -0
  30. package/dist/{campaign-evidence-OcUciD-N.js → campaign-evidence-Clrn4hBV.js} +8 -8
  31. package/dist/campaign-evidence-Clrn4hBV.js.map +1 -0
  32. package/dist/{canonical-BsZVgBhW.js → canonical-B2RqLofv.js} +2 -2
  33. package/dist/{canonical-BsZVgBhW.js.map → canonical-B2RqLofv.js.map} +1 -1
  34. package/dist/{chat-client-DthPOYGd.js → chat-client-l-MVDlDk.js} +2 -2
  35. package/dist/{chat-client-DthPOYGd.js.map → chat-client-l-MVDlDk.js.map} +1 -1
  36. package/dist/{chat-json-call-BrKsyspg.js → chat-json-call-puMArmtW.js} +2 -2
  37. package/dist/{chat-json-call-BrKsyspg.js.map → chat-json-call-puMArmtW.js.map} +1 -1
  38. package/dist/{claim-BXcZw-jo.js → claim-q4HQhK1G.js} +4 -4
  39. package/dist/claim-q4HQhK1G.js.map +1 -0
  40. package/dist/cli.js +9 -9
  41. package/dist/cli.js.map +1 -1
  42. package/dist/cluster-bootstrap-qcUWYFl-.js +66 -0
  43. package/dist/cluster-bootstrap-qcUWYFl-.js.map +1 -0
  44. package/dist/contract/index.d.ts +11 -11
  45. package/dist/contract/index.js +1023 -1079
  46. package/dist/contract/index.js.map +1 -1
  47. package/dist/{cost-ledger-D2FnJPBF.js → cost-ledger-BP8V4kUQ.js} +835 -816
  48. package/dist/cost-ledger-BP8V4kUQ.js.map +1 -0
  49. package/dist/{cost-ledger-CO7UyEcQ.d.ts → cost-ledger-Jk62OBfF.d.ts} +12 -47
  50. package/dist/cost-ledger-Jk62OBfF.d.ts.map +1 -0
  51. package/dist/{counterfactual-DtMWvn7D.js → counterfactual-Dn3veueY.js} +2 -2
  52. package/dist/{counterfactual-DtMWvn7D.js.map → counterfactual-Dn3veueY.js.map} +1 -1
  53. package/dist/{default-registry-KP4-Tolz.js → default-registry-COhk9g36.js} +744 -759
  54. package/dist/default-registry-COhk9g36.js.map +1 -0
  55. package/dist/{default-registry-B4B7GMvI.d.ts → default-registry-DzHiGruW.d.ts} +6 -6
  56. package/dist/{default-registry-B4B7GMvI.d.ts.map → default-registry-DzHiGruW.d.ts.map} +1 -1
  57. package/dist/{define-agent-eval-BdfnqXeP.js → define-agent-eval-CNTPzIkp.js} +10 -10
  58. package/dist/define-agent-eval-CNTPzIkp.js.map +1 -0
  59. package/dist/{define-agent-eval-DfXvNho5.d.ts → define-agent-eval-WSck0CZJ.d.ts} +8 -8
  60. package/dist/{define-agent-eval-DfXvNho5.d.ts.map → define-agent-eval-WSck0CZJ.d.ts.map} +1 -1
  61. package/dist/{descriptive-CnU8Yq29.js → descriptive-DboxPZrG.js} +2 -2
  62. package/dist/{descriptive-CnU8Yq29.js.map → descriptive-DboxPZrG.js.map} +1 -1
  63. package/dist/diagnosis/index.d.ts +3 -3
  64. package/dist/diagnosis/index.js +4 -4
  65. package/dist/{dspy-rlm-engine-DZfHM7kT.js → dspy-rlm-engine-LRCu61m5.js} +3 -3
  66. package/dist/{dspy-rlm-engine-DZfHM7kT.js.map → dspy-rlm-engine-LRCu61m5.js.map} +1 -1
  67. package/dist/{effect-sizes-DiH8MGOH.js → effect-sizes-BhzEpXMc.js} +2 -2
  68. package/dist/{effect-sizes-DiH8MGOH.js.map → effect-sizes-BhzEpXMc.js.map} +1 -1
  69. package/dist/{engine-C37HS2kr.d.ts → engine-3A_4jOlI.d.ts} +5 -5
  70. package/dist/{engine-C37HS2kr.d.ts.map → engine-3A_4jOlI.d.ts.map} +1 -1
  71. package/dist/{equal-terms-Blx9Zk5I.js → equal-terms-BtdXayCJ.js} +2 -2
  72. package/dist/{equal-terms-Blx9Zk5I.js.map → equal-terms-BtdXayCJ.js.map} +1 -1
  73. package/dist/{errors-Dngq5h35.js → errors-DVZiqS7K.js} +6 -2
  74. package/dist/{errors-Dngq5h35.js.map → errors-DVZiqS7K.js.map} +1 -1
  75. package/dist/{eval-campaign-4byTtqrf.js → eval-campaign-90jeaCAI.js} +6 -6
  76. package/dist/{eval-campaign-4byTtqrf.js.map → eval-campaign-90jeaCAI.js.map} +1 -1
  77. package/dist/evaluation-6Yoi74gM.d.ts +75 -0
  78. package/dist/evaluation-6Yoi74gM.d.ts.map +1 -0
  79. package/dist/evaluation.d.ts +2 -74
  80. package/dist/evaluation.js +1 -1
  81. package/dist/{exact-types-Dlb73wN4.d.ts → exact-types-ClugMJfI.d.ts} +2 -2
  82. package/dist/{exact-types-Dlb73wN4.d.ts.map → exact-types-ClugMJfI.d.ts.map} +1 -1
  83. package/dist/experiment/index.d.ts +404 -3
  84. package/dist/experiment/index.d.ts.map +1 -1
  85. package/dist/experiment/index.js +313 -19
  86. package/dist/experiment/index.js.map +1 -1
  87. package/dist/{external-optimizer-process-GngofQML.js → external-optimizer-process-BjMGUuds.js} +3 -3
  88. package/dist/{external-optimizer-process-GngofQML.js.map → external-optimizer-process-BjMGUuds.js.map} +1 -1
  89. package/dist/{external-optimizer-subprocess-BUxifb8g.js → external-optimizer-subprocess-BqW0hHcI.js} +791 -532
  90. package/dist/external-optimizer-subprocess-BqW0hHcI.js.map +1 -0
  91. package/dist/{feedback-trajectory-BLN_6fEs.d.ts → feedback-trajectory-C4EG0nNH.d.ts} +5 -8
  92. package/dist/feedback-trajectory-C4EG0nNH.d.ts.map +1 -0
  93. package/dist/fuzz.d.ts +1 -1
  94. package/dist/fuzz.js +3 -3
  95. package/dist/hosted/index.js +1 -1
  96. package/dist/{index-CPJJr98o.d.ts → index-BFRO6chs.d.ts} +3 -2
  97. package/dist/index-BFRO6chs.d.ts.map +1 -0
  98. package/dist/{index-Ch9VxCpK.d.ts → index-BO41eGj5.d.ts} +2 -2
  99. package/dist/{index-Ch9VxCpK.d.ts.map → index-BO41eGj5.d.ts.map} +1 -1
  100. package/dist/{index-B3WBm953.d.ts → index-CyszSg4O.d.ts} +165 -162
  101. package/dist/index-CyszSg4O.d.ts.map +1 -0
  102. package/dist/{index-B7m2uzJL.d.ts → index-DPcngtwt.d.ts} +30 -17
  103. package/dist/index-DPcngtwt.d.ts.map +1 -0
  104. package/dist/{index-tYLUvk_w.d.ts → index-DV-jSzxF.d.ts} +9 -9
  105. package/dist/{index-tYLUvk_w.d.ts.map → index-DV-jSzxF.d.ts.map} +1 -1
  106. package/dist/index.d.ts +1969 -1871
  107. package/dist/index.d.ts.map +1 -1
  108. package/dist/index.js +162 -201
  109. package/dist/index.js.map +1 -1
  110. package/dist/{integrity-BvnVARVl.js → integrity-BXOsAb3i.js} +2 -2
  111. package/dist/{integrity-BvnVARVl.js.map → integrity-BXOsAb3i.js.map} +1 -1
  112. package/dist/{integrity-CCAxGVK6.d.ts → integrity-DAMEDFaC.d.ts} +2 -2
  113. package/dist/{integrity-CCAxGVK6.d.ts.map → integrity-DAMEDFaC.d.ts.map} +1 -1
  114. package/dist/{integrity-BV1ZDf42.js → integrity-dLiDe2kD.js} +2 -5
  115. package/dist/integrity-dLiDe2kD.js.map +1 -0
  116. package/dist/{internal-CRHwS9iz.js → internal-Epl-YBZW.js} +3 -3
  117. package/dist/{internal-CRHwS9iz.js.map → internal-Epl-YBZW.js.map} +1 -1
  118. package/dist/interval-CELpye1n.js +219 -0
  119. package/dist/interval-CELpye1n.js.map +1 -0
  120. package/dist/interval-ohuOJurX.d.ts +47 -0
  121. package/dist/interval-ohuOJurX.d.ts.map +1 -0
  122. package/dist/{journal-DvKCvjty.js → journal-DfRz9kps.js} +2 -2
  123. package/dist/{journal-DvKCvjty.js.map → journal-DfRz9kps.js.map} +1 -1
  124. package/dist/{judge-calibration-N44V04Se.js → judge-calibration-BpCy5XQl.js} +3 -3
  125. package/dist/{judge-calibration-N44V04Se.js.map → judge-calibration-BpCy5XQl.js.map} +1 -1
  126. package/dist/{judge-gate-DNcUrRFA.d.ts → judge-gate-CE7CQAgt.d.ts} +3 -3
  127. package/dist/{judge-gate-DNcUrRFA.d.ts.map → judge-gate-CE7CQAgt.d.ts.map} +1 -1
  128. package/dist/{judge-gate-B1qYnkpi.js → judge-gate-iY9s4L44.js} +3 -3
  129. package/dist/judge-gate-iY9s4L44.js.map +1 -0
  130. package/dist/{kind-factory-AaEhUADH.js → kind-factory-BobI5Jy3.js} +5 -5
  131. package/dist/{kind-factory-AaEhUADH.js.map → kind-factory-BobI5Jy3.js.map} +1 -1
  132. package/dist/ledger-core/index.js +3 -3
  133. package/dist/{ledger-core-B2hahzrt.js → ledger-core-Gq7yp8lP.js} +4 -4
  134. package/dist/{ledger-core-B2hahzrt.js.map → ledger-core-Gq7yp8lP.js.map} +1 -1
  135. package/dist/{llm-client-DQveoxSM.js → llm-client-CyBAoYiX.js} +192 -219
  136. package/dist/llm-client-CyBAoYiX.js.map +1 -0
  137. package/dist/{llm-judge-Cd5s5Ei6.js → llm-judge-CG12SQJq.js} +499 -921
  138. package/dist/llm-judge-CG12SQJq.js.map +1 -0
  139. package/dist/matrix/index.d.ts +2 -2
  140. package/dist/matrix/index.js +1 -1
  141. package/dist/{matrix-DXVAJMLD.d.ts → matrix-DSrSxjjy.d.ts} +4 -4
  142. package/dist/{matrix-DXVAJMLD.d.ts.map → matrix-DSrSxjjy.d.ts.map} +1 -1
  143. package/dist/{matrix-_BV9-Lk5.js → matrix-Dm0BQW7U.js} +7 -11
  144. package/dist/matrix-Dm0BQW7U.js.map +1 -0
  145. package/dist/{paired-tests-jbwPdSz5.js → mean-DHoMiudD.js} +11 -5
  146. package/dist/mean-DHoMiudD.js.map +1 -0
  147. package/dist/meta-eval/index.d.ts +3 -3
  148. package/dist/meta-eval/index.js +9 -70
  149. package/dist/meta-eval/index.js.map +1 -1
  150. package/dist/mint-DNU8QPG4.d.ts +81 -0
  151. package/dist/mint-DNU8QPG4.d.ts.map +1 -0
  152. package/dist/{mint-Csor1BLJ.js → mint-QaD5cA0u.js} +3 -3
  153. package/dist/{mint-Csor1BLJ.js.map → mint-QaD5cA0u.js.map} +1 -1
  154. package/dist/{multiplicity-D9cjmStq.js → multiplicity-DQUFcbW4.js} +2 -2
  155. package/dist/{multiplicity-D9cjmStq.js.map → multiplicity-DQUFcbW4.js.map} +1 -1
  156. package/dist/multishot/golden/index.d.ts +1 -1
  157. package/dist/multishot/golden/index.d.ts.map +1 -1
  158. package/dist/multishot/golden/index.js +3 -6
  159. package/dist/multishot/golden/index.js.map +1 -1
  160. package/dist/multishot/index.d.ts +2 -2
  161. package/dist/multishot/index.js +1 -1
  162. package/dist/nonnegative-number-DvdMxg_f.js +9 -0
  163. package/dist/nonnegative-number-DvdMxg_f.js.map +1 -0
  164. package/dist/openapi.json +1 -1
  165. package/dist/{otel-spans-C8YIJWy1.js → otel-spans-B9tUXRHF.js} +3 -3
  166. package/dist/{otel-spans-C8YIJWy1.js.map → otel-spans-B9tUXRHF.js.map} +1 -1
  167. package/dist/{paired-arms-DzKn0TfY.js → paired-arms-CwMGJsrS.js} +5 -5
  168. package/dist/{paired-arms-DzKn0TfY.js.map → paired-arms-CwMGJsrS.js.map} +1 -1
  169. package/dist/{paired-binary-Q36bhn2R.js → paired-binary-CvpFHfKZ.js} +2 -2
  170. package/dist/{paired-binary-Q36bhn2R.js.map → paired-binary-CvpFHfKZ.js.map} +1 -1
  171. package/dist/{paired-promotion-decision-BN6IQTiu.js → paired-promotion-decision-DsAPYGCm.js} +3 -3
  172. package/dist/{paired-promotion-decision-BN6IQTiu.js.map → paired-promotion-decision-DsAPYGCm.js.map} +1 -1
  173. package/dist/{search-kernel-BztlERLv.js → pareto-Cm6ndrWN.js} +883 -861
  174. package/dist/pareto-Cm6ndrWN.js.map +1 -0
  175. package/dist/pipelines/index.d.ts +2 -2
  176. package/dist/pipelines/index.js +3 -3
  177. package/dist/{power-and-mde-fK5Qocwo.js → power-and-mde-Hj2ubb4B.js} +2 -2
  178. package/dist/{power-and-mde-fK5Qocwo.js.map → power-and-mde-Hj2ubb4B.js.map} +1 -1
  179. package/dist/predicate-FdKmElA_.js +38 -0
  180. package/dist/predicate-FdKmElA_.js.map +1 -0
  181. package/dist/{prime-protocol-DcAK9pC8.js → prime-protocol-CHKgA3a6.js} +2 -2
  182. package/dist/{prime-protocol-DcAK9pC8.js.map → prime-protocol-CHKgA3a6.js.map} +1 -1
  183. package/dist/{prime-protocol-BHia9vDz.d.ts → prime-protocol-HiB9HX7E.d.ts} +3 -3
  184. package/dist/{prime-protocol-BHia9vDz.d.ts.map → prime-protocol-HiB9HX7E.d.ts.map} +1 -1
  185. package/dist/{produced-state-BGp4BX8t.js → produced-state-BsDmnwxc.js} +8 -8
  186. package/dist/{produced-state-BGp4BX8t.js.map → produced-state-BsDmnwxc.js.map} +1 -1
  187. package/dist/profile-cell.js +1 -1
  188. package/dist/{release-confidence-BK2QCB5M.d.ts → promotion-gate-BawrdPYr.d.ts} +102 -102
  189. package/dist/promotion-gate-BawrdPYr.d.ts.map +1 -0
  190. package/dist/{promotion-policy-CWW35UWq.js → promotion-policy-KO57gbyV.js} +4 -4
  191. package/dist/{promotion-policy-CWW35UWq.js.map → promotion-policy-KO57gbyV.js.map} +1 -1
  192. package/dist/{proposal-findings-CXblsskH.js → proposal-findings-CY1xKn_a.js} +2 -36
  193. package/dist/proposal-findings-CY1xKn_a.js.map +1 -0
  194. package/dist/{query-B1D1qp2Z.js → query-BUCZCK7F.js} +3 -3
  195. package/dist/{query-B1D1qp2Z.js.map → query-BUCZCK7F.js.map} +1 -1
  196. package/dist/{random-Dn5fPWkt.js → random-ByUSnV9w.js} +2 -2
  197. package/dist/{random-Dn5fPWkt.js.map → random-ByUSnV9w.js.map} +1 -1
  198. package/dist/{raw-provider-sink-rB2DYxr6.js → raw-provider-sink-DoHz4JNG.js} +2 -2
  199. package/dist/{raw-provider-sink-rB2DYxr6.js.map → raw-provider-sink-DoHz4JNG.js.map} +1 -1
  200. package/dist/{redact-Dk1ZdJEm.js → redact-B5xXKqQ3.js} +97 -98
  201. package/dist/redact-B5xXKqQ3.js.map +1 -0
  202. package/dist/{redact-Cveoq6fJ.d.ts → redact-mtCCcT8z.d.ts} +4 -20
  203. package/dist/redact-mtCCcT8z.d.ts.map +1 -0
  204. package/dist/{registry-CMYIaDgS.d.ts → registry-D7_hm2fK.d.ts} +11 -13
  205. package/dist/registry-D7_hm2fK.d.ts.map +1 -0
  206. package/dist/{release-confidence-Dbe9AS_X.js → release-confidence-CpuP65S5.js} +5 -5
  207. package/dist/{release-confidence-Dbe9AS_X.js.map → release-confidence-CpuP65S5.js.map} +1 -1
  208. package/dist/{report-command-CtIIsQKP.js → report-command-SC9nqb4M.js} +128 -177
  209. package/dist/report-command-SC9nqb4M.js.map +1 -0
  210. package/dist/reporting-html-Kvlc8oMt.js +100 -0
  211. package/dist/reporting-html-Kvlc8oMt.js.map +1 -0
  212. package/dist/reporting.d.ts +3 -3
  213. package/dist/reporting.js +6 -6
  214. package/dist/{researcher-f6mZhh58.d.ts → researcher-CEcfku-T.d.ts} +5 -5
  215. package/dist/{researcher-f6mZhh58.d.ts.map → researcher-CEcfku-T.d.ts.map} +1 -1
  216. package/dist/reward-CpCmAM8L.d.ts +78 -0
  217. package/dist/reward-CpCmAM8L.d.ts.map +1 -0
  218. package/dist/{reward-hacking-BFcQgkux.js → reward-hacking-E0d-WVcP.js} +2 -2
  219. package/dist/{reward-hacking-BFcQgkux.js.map → reward-hacking-E0d-WVcP.js.map} +1 -1
  220. package/dist/{reward-hacking-DHA7c1l8.d.ts → reward-hacking-RVdZ6Kkt.d.ts} +2 -2
  221. package/dist/{reward-hacking-DHA7c1l8.d.ts.map → reward-hacking-RVdZ6Kkt.d.ts.map} +1 -1
  222. package/dist/rl.d.ts +8 -8
  223. package/dist/rl.js +14 -14
  224. package/dist/rollout/index.d.ts +3 -2
  225. package/dist/rollout/index.js +2 -2
  226. package/dist/{rollout-D9bKKBnZ.js → rollout-DZV1t2Wg.js} +2 -2
  227. package/dist/{rollout-D9bKKBnZ.js.map → rollout-DZV1t2Wg.js.map} +1 -1
  228. package/dist/round-decimal-COrKglMh.js +10 -0
  229. package/dist/round-decimal-COrKglMh.js.map +1 -0
  230. package/dist/{rubric-predictive-validity-2SgHxoa5.d.ts → rubric-predictive-validity-C03EC7ZE.d.ts} +2 -2
  231. package/dist/{rubric-predictive-validity-2SgHxoa5.d.ts.map → rubric-predictive-validity-C03EC7ZE.d.ts.map} +1 -1
  232. package/dist/{rubric-predictive-validity-BsgkBfT0.js → rubric-predictive-validity-DaFW70y9.js} +3 -3
  233. package/dist/{rubric-predictive-validity-BsgkBfT0.js.map → rubric-predictive-validity-DaFW70y9.js.map} +1 -1
  234. package/dist/{run-record-DlTZ_lqe.js → run-record-Boc5IUTp.js} +4 -4
  235. package/dist/{run-record-DlTZ_lqe.js.map → run-record-Boc5IUTp.js.map} +1 -1
  236. package/dist/{run-record-D1Hw-Jml.d.ts → run-record-C1E24G2A.d.ts} +2 -2
  237. package/dist/{run-record-D1Hw-Jml.d.ts.map → run-record-C1E24G2A.d.ts.map} +1 -1
  238. package/dist/{run-record-ES07wfz9.js → run-record-C5e7FjhJ.js} +3 -5
  239. package/dist/run-record-C5e7FjhJ.js.map +1 -0
  240. package/dist/search/index.d.ts +46 -32
  241. package/dist/search/index.d.ts.map +1 -1
  242. package/dist/search/index.js +3 -3
  243. package/dist/{search-kernel-BqyBZ9Wm.d.ts → search-kernel-DyNEa6IU.d.ts} +14 -10
  244. package/dist/search-kernel-DyNEa6IU.d.ts.map +1 -0
  245. package/dist/{search-ledger-d7V8o9Lk.js → search-ledger-CVUGLDZp.js} +189 -199
  246. package/dist/search-ledger-CVUGLDZp.js.map +1 -0
  247. package/dist/{search-ledger-file-BqOo-bVo.js → search-ledger-file-DDQUgvCg.js} +4 -4
  248. package/dist/{search-ledger-file-BqOo-bVo.js.map → search-ledger-file-DDQUgvCg.js.map} +1 -1
  249. package/dist/search-ledger-types-p2xKfiDJ.d.ts.map +1 -1
  250. package/dist/{search-shipper-er4pK5_Y.js → search-shipper-BOSD46qv.js} +3 -3
  251. package/dist/{search-shipper-er4pK5_Y.js.map → search-shipper-BOSD46qv.js.map} +1 -1
  252. package/dist/{search-summary-CBvz3u_S.js → search-summary-BQCSWf1g.js} +5 -5
  253. package/dist/{search-summary-CBvz3u_S.js.map → search-summary-BQCSWf1g.js.map} +1 -1
  254. package/dist/{semantic-concept-judge-BPqbwIVs.js → semantic-concept-judge-BQF8te0T.js} +12 -14
  255. package/dist/semantic-concept-judge-BQF8te0T.js.map +1 -0
  256. package/dist/{sequential-D-1PPCmM.js → sequential-Bf_pbE50.js} +5 -5
  257. package/dist/{sequential-D-1PPCmM.js.map → sequential-Bf_pbE50.js.map} +1 -1
  258. package/dist/{sequential-eprocess-D1jKoihe.js → sequential-eprocess-DM_qENCl.js} +2 -2
  259. package/dist/{sequential-eprocess-D1jKoihe.js.map → sequential-eprocess-DM_qENCl.js.map} +1 -1
  260. package/dist/{server-DbcC7xMl.js → server-e9oWO_bN.js} +4 -4
  261. package/dist/{server-DbcC7xMl.js.map → server-e9oWO_bN.js.map} +1 -1
  262. package/dist/{single-run-lock-fVu3MZWH.js → single-run-lock-CV9Eyd_q.js} +2 -2
  263. package/dist/{single-run-lock-fVu3MZWH.js.map → single-run-lock-CV9Eyd_q.js.map} +1 -1
  264. package/dist/{skillopt-optimization-method-Dcepr6QL.js → skillopt-optimization-method-BiwA8nfX.js} +427 -12
  265. package/dist/skillopt-optimization-method-BiwA8nfX.js.map +1 -0
  266. package/dist/{spans-D9_ehFuk.d.ts → spans-BHAUXMGN.d.ts} +2 -2
  267. package/dist/{spans-D9_ehFuk.d.ts.map → spans-BHAUXMGN.d.ts.map} +1 -1
  268. package/dist/{statistical-heldout-1Gbmex7v.js → statistical-heldout-42NlCNDe.js} +3 -3
  269. package/dist/{statistical-heldout-1Gbmex7v.js.map → statistical-heldout-42NlCNDe.js.map} +1 -1
  270. package/dist/{statistical-heldout-CJTj2EoS.d.ts → statistical-heldout-CYpGaoDH.d.ts} +3 -3
  271. package/dist/{statistical-heldout-CJTj2EoS.d.ts.map → statistical-heldout-CYpGaoDH.d.ts.map} +1 -1
  272. package/dist/{store-otlp-DWVhUgEj.js → store-otlp-DJ9dtA5x.js} +135 -132
  273. package/dist/store-otlp-DJ9dtA5x.js.map +1 -0
  274. package/dist/{store-tool-spans-BNICrhsb.js → store-tool-spans-CIX5arAG.js} +7 -7
  275. package/dist/{store-tool-spans-BNICrhsb.js.map → store-tool-spans-CIX5arAG.js.map} +1 -1
  276. package/dist/{store-tool-spans-BNzls3OD.d.ts → store-tool-spans-DdCSPa7C.d.ts} +162 -161
  277. package/dist/store-tool-spans-DdCSPa7C.d.ts.map +1 -0
  278. package/dist/storyboard/index.d.ts.map +1 -1
  279. package/dist/storyboard/index.js +20 -3
  280. package/dist/storyboard/index.js.map +1 -1
  281. package/dist/{student-t-BQeKJx2N.js → student-t-DVPW7CdL.js} +2 -2
  282. package/dist/{student-t-BQeKJx2N.js.map → student-t-DVPW7CdL.js.map} +1 -1
  283. package/dist/{summary-report-DtdRucM0.js → summary-report-V_JACR4Y.js} +526 -614
  284. package/dist/summary-report-V_JACR4Y.js.map +1 -0
  285. package/dist/{summary-report-C-CtItCN.d.ts → summary-report-bdFDXq0b.d.ts} +10 -5
  286. package/dist/summary-report-bdFDXq0b.d.ts.map +1 -0
  287. package/dist/supervisor-run/index.d.ts +154 -150
  288. package/dist/supervisor-run/index.d.ts.map +1 -1
  289. package/dist/supervisor-run/index.js +65 -3
  290. package/dist/supervisor-run/index.js.map +1 -1
  291. package/dist/systemone-BomhHr2c.d.ts +135 -0
  292. package/dist/systemone-BomhHr2c.d.ts.map +1 -0
  293. package/dist/systemone-protocol.js +1 -1
  294. package/dist/{systemone-review-C4dZgrgN.d.ts → systemone-review-CUVcQJu6.d.ts} +2 -2
  295. package/dist/{systemone-review-C4dZgrgN.d.ts.map → systemone-review-CUVcQJu6.d.ts.map} +1 -1
  296. package/dist/{systemone-review-DTClwgmE.js → systemone-review-D7sXwsqq.js} +3 -3
  297. package/dist/{systemone-review-DTClwgmE.js.map → systemone-review-D7sXwsqq.js.map} +1 -1
  298. package/dist/systemone.d.ts +4 -134
  299. package/dist/systemone.js +4 -4
  300. package/dist/{task-failure-attributes-DngaLdE4.js → task-failure-attributes-hEmASjix.js} +2 -2
  301. package/dist/{task-failure-attributes-DngaLdE4.js.map → task-failure-attributes-hEmASjix.js.map} +1 -1
  302. package/dist/{terminal-record-BHocwFw1.js → terminal-record-DZyQZ3pz.js} +14 -10
  303. package/dist/terminal-record-DZyQZ3pz.js.map +1 -0
  304. package/dist/{tool-groups-BKRrtqy4.d.ts → tool-groups-C3NEcdCM.d.ts} +3 -3
  305. package/dist/tool-groups-C3NEcdCM.d.ts.map +1 -0
  306. package/dist/{tool-waste-Wi4g6Ekb.d.ts → tool-waste-BKgvd-TP.d.ts} +30 -30
  307. package/dist/tool-waste-BKgvd-TP.d.ts.map +1 -0
  308. package/dist/{tool-waste-BYt5rdt8.js → tool-waste-BlesqTqW.js} +5 -158
  309. package/dist/tool-waste-BlesqTqW.js.map +1 -0
  310. package/dist/{trace-questions-CLx8vt6t.d.ts → trace-questions-CM2CAocU.d.ts} +4 -4
  311. package/dist/{trace-questions-CLx8vt6t.d.ts.map → trace-questions-CM2CAocU.d.ts.map} +1 -1
  312. package/dist/trace-repair/index.d.ts +3 -3
  313. package/dist/trace-repair/index.d.ts.map +1 -1
  314. package/dist/trace-repair/index.js +7 -13
  315. package/dist/trace-repair/index.js.map +1 -1
  316. package/dist/traces.d.ts +76 -58
  317. package/dist/traces.d.ts.map +1 -1
  318. package/dist/traces.js +9 -9
  319. package/dist/trajectory-replay/index.js +3 -3
  320. package/dist/{tree-rXLW3M_4.js → tree-C1XYeXvy.js} +2277 -2339
  321. package/dist/tree-C1XYeXvy.js.map +1 -0
  322. package/dist/{types-DjOMwGY_.d.ts → types-BqkVmHfv.d.ts} +7 -1
  323. package/dist/types-BqkVmHfv.d.ts.map +1 -0
  324. package/dist/{types-DBZ7keha.d.ts → types-C02qtnG8.d.ts} +4 -46
  325. package/dist/types-C02qtnG8.d.ts.map +1 -0
  326. package/dist/{types-DHb5TI36.d.ts → types-C1tnkEgM.d.ts} +347 -6
  327. package/dist/types-C1tnkEgM.d.ts.map +1 -0
  328. package/dist/{types-DinHtRJp.d.ts → types-Cbe2fWBa.d.ts} +3 -3
  329. package/dist/{types-DinHtRJp.d.ts.map → types-Cbe2fWBa.d.ts.map} +1 -1
  330. package/dist/{types-CGEmVYOk.d.ts → types-Cq8mSbq8.d.ts} +78 -72
  331. package/dist/types-Cq8mSbq8.d.ts.map +1 -0
  332. package/dist/{types-CW5b90JH.js → types-IXD2HJzu.js} +16 -3
  333. package/dist/types-IXD2HJzu.js.map +1 -0
  334. package/dist/{verdict-DhPoXApk.js → verdict-Dl0tiT1X.js} +2 -2
  335. package/dist/{verdict-DhPoXApk.js.map → verdict-Dl0tiT1X.js.map} +1 -1
  336. package/dist/{verdict-cache-BQEsVy9n.js → verdict-cache-Bm8EKL2s.js} +2 -2
  337. package/dist/{verdict-cache-BQEsVy9n.js.map → verdict-cache-Bm8EKL2s.js.map} +1 -1
  338. package/dist/wire/index.d.ts +3 -3
  339. package/dist/wire/index.js +1 -1
  340. package/docs/concepts.md +1 -0
  341. package/docs/design/mlbenchmarks-book-review.md +1 -1
  342. package/docs/design/mlbenchmarks-review/probes.mts +23 -31
  343. package/docs/experiment.md +1 -1
  344. package/docs/finding-layers.md +69 -0
  345. package/package.json +1 -1
  346. package/dist/analyze-runs-3xpby3p2.js.map +0 -1
  347. package/dist/analyze-runs-BhFLOztS.d.ts.map +0 -1
  348. package/dist/ast-DJ6Bc7ab.js +0 -558
  349. package/dist/ast-DJ6Bc7ab.js.map +0 -1
  350. package/dist/ast-hI-vjW6J.d.ts +0 -457
  351. package/dist/ast-hI-vjW6J.d.ts.map +0 -1
  352. package/dist/benchmark-command-CgpGi7vY.js.map +0 -1
  353. package/dist/campaign-CpnsCgfz.js.map +0 -1
  354. package/dist/campaign-evidence-OcUciD-N.js.map +0 -1
  355. package/dist/claim-BXcZw-jo.js.map +0 -1
  356. package/dist/cost-ledger-CO7UyEcQ.d.ts.map +0 -1
  357. package/dist/cost-ledger-D2FnJPBF.js.map +0 -1
  358. package/dist/default-registry-KP4-Tolz.js.map +0 -1
  359. package/dist/define-agent-eval-BdfnqXeP.js.map +0 -1
  360. package/dist/evaluation.d.ts.map +0 -1
  361. package/dist/external-optimizer-subprocess-BUxifb8g.js.map +0 -1
  362. package/dist/feedback-trajectory-BLN_6fEs.d.ts.map +0 -1
  363. package/dist/index-B3WBm953.d.ts.map +0 -1
  364. package/dist/index-B7m2uzJL.d.ts.map +0 -1
  365. package/dist/index-CPJJr98o.d.ts.map +0 -1
  366. package/dist/integrity-BV1ZDf42.js.map +0 -1
  367. package/dist/judge-gate-B1qYnkpi.js.map +0 -1
  368. package/dist/llm-client-DQveoxSM.js.map +0 -1
  369. package/dist/llm-judge-Cd5s5Ei6.js.map +0 -1
  370. package/dist/matrix-_BV9-Lk5.js.map +0 -1
  371. package/dist/mint-DCGoBYhB.d.ts +0 -155
  372. package/dist/mint-DCGoBYhB.d.ts.map +0 -1
  373. package/dist/paired-tests-jbwPdSz5.js.map +0 -1
  374. package/dist/proposal-findings-CXblsskH.js.map +0 -1
  375. package/dist/redact-Cveoq6fJ.d.ts.map +0 -1
  376. package/dist/redact-Dk1ZdJEm.js.map +0 -1
  377. package/dist/registry-CMYIaDgS.d.ts.map +0 -1
  378. package/dist/release-confidence-BK2QCB5M.d.ts.map +0 -1
  379. package/dist/report-command-CtIIsQKP.js.map +0 -1
  380. package/dist/run-record-ES07wfz9.js.map +0 -1
  381. package/dist/search-kernel-BqyBZ9Wm.d.ts.map +0 -1
  382. package/dist/search-kernel-BztlERLv.js.map +0 -1
  383. package/dist/search-ledger-d7V8o9Lk.js.map +0 -1
  384. package/dist/semantic-concept-judge-BPqbwIVs.js.map +0 -1
  385. package/dist/skillopt-optimization-method-Dcepr6QL.js.map +0 -1
  386. package/dist/store-otlp-DWVhUgEj.js.map +0 -1
  387. package/dist/store-tool-spans-BNzls3OD.d.ts.map +0 -1
  388. package/dist/summary-report-C-CtItCN.d.ts.map +0 -1
  389. package/dist/summary-report-DtdRucM0.js.map +0 -1
  390. package/dist/systemone.d.ts.map +0 -1
  391. package/dist/terminal-record-BHocwFw1.js.map +0 -1
  392. package/dist/tool-groups-BKRrtqy4.d.ts.map +0 -1
  393. package/dist/tool-waste-BYt5rdt8.js.map +0 -1
  394. package/dist/tool-waste-Wi4g6Ekb.d.ts.map +0 -1
  395. package/dist/tree-rXLW3M_4.js.map +0 -1
  396. package/dist/types-CGEmVYOk.d.ts.map +0 -1
  397. package/dist/types-CW5b90JH.js.map +0 -1
  398. package/dist/types-DBZ7keha.d.ts.map +0 -1
  399. package/dist/types-DHb5TI36.d.ts.map +0 -1
  400. package/dist/types-DjOMwGY_.d.ts.map +0 -1
@@ -1,9 +1,14 @@
1
- import { t as canonicalJson } from "./verdict-cache-BQEsVy9n.js";
2
- import { c as costForTokenPricing, i as CostLedger } from "./cost-ledger-D2FnJPBF.js";
3
- import { n as appendSearchLedgerLine, r as tryWithSearchLedgerFileLock } from "./search-ledger-file-BqOo-bVo.js";
4
- import { f as ModelSubstitutionError, g as assertServedModelPolicy, h as assertServedModel } from "./llm-client-DQveoxSM.js";
1
+ import { l as errorMessage } from "./errors-DVZiqS7K.js";
2
+ import { t as canonicalJson } from "./verdict-cache-Bm8EKL2s.js";
3
+ import { c as costForTokenPricing, t as CostLedger } from "./cost-ledger-BP8V4kUQ.js";
4
+ import { t as deepFreezeCanonicalJson } from "./deep-freeze-CurcOQg3.js";
5
+ import { n as appendSearchLedgerLine, r as tryWithSearchLedgerFileLock } from "./search-ledger-file-DDQUgvCg.js";
6
+ import { n as ANALYST_SEVERITIES, r as FINDING_SCOPE_FIELDS } from "./types-IXD2HJzu.js";
7
+ import { c as ModelSubstitutionError, d as assertServedModel, f as assertServedModelPolicy } from "./llm-client-CyBAoYiX.js";
8
+ import { t as isNonnegativeFiniteNumber } from "./nonnegative-number-DvdMxg_f.js";
5
9
  import { createRequire } from "node:module";
6
10
  import { randomBytes } from "node:crypto";
11
+ import { z } from "zod";
7
12
  import { isAbsolute, join, resolve } from "node:path";
8
13
  import { tmpdir } from "node:os";
9
14
  import { spawn } from "node:child_process";
@@ -112,6 +117,263 @@ function createRunCostLedger(input) {
112
117
  });
113
118
  }
114
119
  //#endregion
120
+ //#region src/analyst/finding-scope.ts
121
+ /**
122
+ * What a finding is about and what it was measured on — AnalystFinding 1.1.0.
123
+ *
124
+ * A 1.0.0 finding states a claim with no layer and no population, so "a flat
125
+ * team beat a deep hierarchy", measured on 4 runs of one play where run 2
126
+ * inherited run 1's code, reads exactly like a lab-wide rule. Schema 1.1.0
127
+ * makes the population part of the record:
128
+ *
129
+ * - `layer` names the level the claim is about, on one ladder from a single
130
+ * event up to the whole lab, plus `meta` for findings about the measurement
131
+ * itself (a judge, a ruler, an analyst).
132
+ * - `scope` names the measured population, its size and time window, and the
133
+ * domain path it was drawn from.
134
+ * - `method` says whether the claim was computed, measured or judged; a
135
+ * judged claim without calibration reads as uncalibrated.
136
+ * - `evidence_units` lists the measured units with their lineage. When it is
137
+ * present the stored `scope.n` and `scope.population` must equal it, so the
138
+ * declared population cannot drift from the evidence.
139
+ *
140
+ * A claim moves above the layer it was measured at only through `promote`.
141
+ */
142
+ /**
143
+ * The layer ladder, lowest first. `problem` is what discovery-lab calls a
144
+ * theatre. `meta` sits outside the ladder: it is about the instrument, not the
145
+ * agents, so it never promotes and never bounds another layer.
146
+ */
147
+ const FINDING_LAYERS = [
148
+ "event",
149
+ "turn",
150
+ "agent",
151
+ "team",
152
+ "run",
153
+ "play",
154
+ "problem",
155
+ "domain",
156
+ "lab",
157
+ "meta"
158
+ ];
159
+ /** Rank on the ladder; `meta` has none. */
160
+ function findingLayerRank(layer) {
161
+ return layer === "meta" ? null : FINDING_LAYERS.indexOf(layer);
162
+ }
163
+ const nonEmpty = z.string().refine((value) => value.trim().length > 0, { message: "must be a non-empty string" });
164
+ const timestamp = z.string().refine((value) => Number.isFinite(Date.parse(value)), { message: "must be a valid timestamp" });
165
+ const finite = z.number().refine(Number.isFinite, { message: "must be finite" });
166
+ const unitRate = finite.refine((value) => value >= 0 && value <= 1, { message: "must be in [0,1]" });
167
+ const layerSchema = z.enum(FINDING_LAYERS);
168
+ const scopeSchema = z.object({
169
+ population: z.array(nonEmpty),
170
+ n: z.number().int().nonnegative(),
171
+ window: z.object({
172
+ from: timestamp,
173
+ to: timestamp
174
+ }).strict(),
175
+ domain_path: z.array(nonEmpty).min(1).optional()
176
+ }).strict();
177
+ const methodSchema = z.object({
178
+ kind: z.enum([
179
+ "computed",
180
+ "measured",
181
+ "judged"
182
+ ]),
183
+ name: nonEmpty,
184
+ version: nonEmpty,
185
+ calibration: z.object({
186
+ gold_n: z.number().int().positive(),
187
+ agreement: unitRate,
188
+ kappa: finite.refine((value) => value >= -1 && value <= 1, { message: "must be in [-1,1]" })
189
+ }).strict().optional()
190
+ }).strict();
191
+ const measureSchema = z.object({
192
+ name: nonEmpty,
193
+ value: finite,
194
+ unit: z.string(),
195
+ interval: z.tuple([finite, finite]).optional(),
196
+ level: finite.refine((value) => value > 0 && value < 1, { message: "must be in (0,1)" }).optional()
197
+ }).strict();
198
+ const evidenceUnitSchema = z.object({
199
+ id: nonEmpty,
200
+ layer: layerSchema,
201
+ derived_from: nonEmpty.nullable().optional()
202
+ }).strict();
203
+ const findingObject = z.object({
204
+ schema_version: z.enum(["1.0.0", "1.1.0"]),
205
+ finding_id: nonEmpty,
206
+ analyst_id: nonEmpty,
207
+ produced_at: timestamp,
208
+ severity: z.enum(ANALYST_SEVERITIES),
209
+ area: nonEmpty,
210
+ claim: nonEmpty,
211
+ rationale: z.string().optional(),
212
+ evidence_refs: z.array(z.object({
213
+ kind: z.enum([
214
+ "span",
215
+ "event",
216
+ "artifact",
217
+ "finding",
218
+ "metric"
219
+ ]),
220
+ uri: nonEmpty,
221
+ excerpt: z.string().optional()
222
+ }).strict()),
223
+ recommended_action: z.string().optional(),
224
+ validation_plan: z.string().optional(),
225
+ confidence: unitRate,
226
+ subject: z.string().optional(),
227
+ derived_from_judge: z.boolean().optional(),
228
+ metadata: z.record(z.string(), z.unknown()).optional(),
229
+ layer: layerSchema.optional(),
230
+ scope: scopeSchema.optional(),
231
+ method: methodSchema.optional(),
232
+ measure: measureSchema.optional(),
233
+ confounders: z.array(nonEmpty).optional(),
234
+ valid_for: nonEmpty.optional(),
235
+ claim_id: nonEmpty.optional(),
236
+ evidence_units: z.array(evidenceUnitSchema).min(1).optional()
237
+ }).strict();
238
+ function checkFinding(finding, context) {
239
+ const issue = (path, message) => context.addIssue({
240
+ code: "custom",
241
+ path,
242
+ message
243
+ });
244
+ if (finding.schema_version === "1.0.0") {
245
+ for (const field of FINDING_SCOPE_FIELDS) if (finding[field] !== void 0) issue([field], `${field} requires schema_version 1.1.0`);
246
+ return;
247
+ }
248
+ if (finding.layer === void 0) issue(["layer"], "1.1.0 findings require a layer");
249
+ if (finding.scope === void 0) issue(["scope"], "1.1.0 findings require a scope");
250
+ if (finding.method === void 0) issue(["method"], "1.1.0 findings require a method");
251
+ const { scope, measure, evidence_units: units } = finding;
252
+ if (scope) {
253
+ if (Date.parse(scope.window.from) > Date.parse(scope.window.to)) issue(["scope", "window"], "window.from must not be after window.to");
254
+ if (new Set(scope.population).size !== scope.population.length) issue(["scope", "population"], "population ids must be unique");
255
+ if (scope.population.length > 0 && scope.population.length !== scope.n) issue(["scope", "n"], `n ${scope.n} does not match ${scope.population.length} population ids`);
256
+ }
257
+ if (measure?.interval && measure.interval[0] > measure.interval[1]) issue(["measure", "interval"], "interval lower bound exceeds its upper bound");
258
+ if (measure?.level !== void 0 && measure.interval === void 0) issue(["measure", "level"], "level describes an interval; none is present");
259
+ if (finding.method?.kind !== "judged" && finding.method?.calibration !== void 0) issue(["method", "calibration"], "only judged findings carry a calibration");
260
+ if (!units) return;
261
+ const ids = units.map((unit) => unit.id);
262
+ if (new Set(ids).size !== ids.length) issue(["evidence_units"], "unit ids must be unique");
263
+ if (scope) {
264
+ if (scope.n !== ids.length) issue(["scope", "n"], `n ${scope.n} does not match ${ids.length} evidence units`);
265
+ const population = [...scope.population].sort();
266
+ const unitIds = [...ids].sort();
267
+ if (population.length !== unitIds.length || population.some((id, index) => id !== unitIds[index])) issue(["scope", "population"], "population must name exactly the evidence units");
268
+ }
269
+ const findingRank = finding.layer === void 0 ? null : findingLayerRank(finding.layer);
270
+ if (findingRank === null) return;
271
+ for (const [index, unit] of units.entries()) {
272
+ const unitRank = findingLayerRank(unit.layer);
273
+ if (unitRank !== null && unitRank > findingRank) issue([
274
+ "evidence_units",
275
+ index,
276
+ "layer"
277
+ ], `a ${finding.layer} finding cannot rest on a ${unit.layer} unit`);
278
+ }
279
+ }
280
+ /** The one validator for stored findings of either schema version. Unknown fields fail. */
281
+ const AnalystFindingSchema = findingObject.superRefine(checkFinding);
282
+ /** A finding admitted as candidate-generation input; same rules plus its origin. */
283
+ const ProposalFindingSchema = findingObject.extend({ proposal_origin: z.enum(["search", "production"]) }).strict().superRefine(checkFinding);
284
+ /** Validate one stored finding of schema 1.0.0 or 1.1.0. */
285
+ function parseAnalystFinding(value) {
286
+ const parsed = AnalystFindingSchema.safeParse(value);
287
+ if (parsed.success) return {
288
+ succeeded: true,
289
+ value: parsed.data
290
+ };
291
+ const issue = parsed.error.issues[0];
292
+ return {
293
+ succeeded: false,
294
+ error: {
295
+ path: (issue?.path ?? []).map(String).join("."),
296
+ message: issue?.message ?? "finding does not match the schema"
297
+ }
298
+ };
299
+ }
300
+ function readFindingScope(finding) {
301
+ if (finding.schema_version === "1.0.0" || !finding.scope || !finding.layer) return {
302
+ layer: "unknown",
303
+ n: "unknown",
304
+ independent_n: "unknown",
305
+ domain_path: null,
306
+ labels: ["unscoped"]
307
+ };
308
+ const labels = [];
309
+ if (finding.scope.n < 2) labels.push("anecdote");
310
+ if (finding.method?.kind === "judged" && finding.method.calibration === void 0) labels.push("uncalibrated");
311
+ const units = finding.evidence_units;
312
+ if (units?.some((unit) => unit.derived_from === void 0)) labels.push("lineage-unknown");
313
+ return {
314
+ layer: finding.layer,
315
+ n: finding.scope.n,
316
+ independent_n: units ? independentUnitCount(units) : "unknown",
317
+ domain_path: finding.scope.domain_path ?? null,
318
+ labels
319
+ };
320
+ }
321
+ /** Root token shared by every unit whose lineage was not recorded. */
322
+ const UNKNOWN_LINEAGE = "?unknown-lineage";
323
+ /**
324
+ * Lineage root of each unit, keyed by unit id. A unit derived from another
325
+ * unit in the list shares that unit's root; a unit derived from an id outside
326
+ * the list takes that id as its root; unknown lineage maps to one shared root.
327
+ */
328
+ function lineageRoots(units) {
329
+ const byId = new Map(units.map((unit) => [unit.id, unit]));
330
+ const roots = /* @__PURE__ */ new Map();
331
+ for (const unit of units) {
332
+ let current = unit;
333
+ let root = unit.id;
334
+ const seen = /* @__PURE__ */ new Set();
335
+ while (current && !seen.has(current.id)) {
336
+ seen.add(current.id);
337
+ if (current.derived_from === void 0) {
338
+ root = UNKNOWN_LINEAGE;
339
+ break;
340
+ }
341
+ if (current.derived_from === null) {
342
+ root = current.id;
343
+ break;
344
+ }
345
+ root = current.derived_from;
346
+ current = byId.get(current.derived_from);
347
+ }
348
+ roots.set(unit.id, root);
349
+ }
350
+ return roots;
351
+ }
352
+ /** Units with distinct lineage roots. */
353
+ function independentUnitCount(units) {
354
+ return new Set(lineageRoots(units).values()).size;
355
+ }
356
+ /** One entry per unit id, sorted; a later copy that records lineage fills an earlier unknown. */
357
+ function mergeEvidenceUnits(units) {
358
+ const byId = /* @__PURE__ */ new Map();
359
+ for (const unit of units) {
360
+ const existing = byId.get(unit.id);
361
+ if (!existing || existing.derived_from === void 0 && unit.derived_from !== void 0) byId.set(unit.id, { ...unit });
362
+ }
363
+ return [...byId.values()].sort((a, b) => a.id < b.id ? -1 : a.id > b.id ? 1 : 0);
364
+ }
365
+ /** The window spanning every finding's scope window. */
366
+ function spanningWindow(findings) {
367
+ const windows = findings.map((finding) => finding.scope.window);
368
+ return {
369
+ from: windows.map((w) => w.from).reduce((a, b) => Date.parse(b) < Date.parse(a) ? b : a),
370
+ to: windows.map((w) => w.to).reduce((a, b) => Date.parse(b) > Date.parse(a) ? b : a)
371
+ };
372
+ }
373
+ function mostSevere(findings) {
374
+ return ANALYST_SEVERITIES[Math.min(...findings.map((finding) => ANALYST_SEVERITIES.indexOf(finding.severity)))];
375
+ }
376
+ //#endregion
115
377
  //#region src/campaign/external-optimizer-contracts.ts
116
378
  const MAX_TIMER_DELAY_MS$1 = 2147483647;
117
379
  const MAXIMUM_JSON_BYTES = Math.min(constants$1.MAX_LENGTH - 1, constants$1.MAX_STRING_LENGTH);
@@ -226,6 +488,67 @@ function isCredentialKey(key) {
226
488
  function isRecord(value) {
227
489
  return typeof value === "object" && value !== null && !Array.isArray(value);
228
490
  }
491
+ function freezeJsonSnapshot(value, label) {
492
+ assertJsonValue(value, label);
493
+ return deepFreezeCanonicalJson(JSON.parse(canonicalJson(value)));
494
+ }
495
+ //#endregion
496
+ //#region src/campaign/external-optimizer-http.ts
497
+ function listenLocal(server) {
498
+ return new Promise((resolvePromise, reject) => {
499
+ server.once("error", reject);
500
+ server.listen(0, "127.0.0.1", () => {
501
+ server.off("error", reject);
502
+ const address = server.address();
503
+ if (!address || typeof address === "string") {
504
+ reject(/* @__PURE__ */ new Error("external optimizer callback did not bind a TCP port"));
505
+ return;
506
+ }
507
+ resolvePromise(address.port);
508
+ });
509
+ });
510
+ }
511
+ function closeServer(server) {
512
+ return new Promise((resolvePromise, reject) => {
513
+ server.close((error) => error ? reject(error) : resolvePromise());
514
+ });
515
+ }
516
+ function sendJson(response, status, body) {
517
+ response.writeHead(status, { "content-type": "application/json; charset=utf-8" });
518
+ response.end(JSON.stringify(body));
519
+ }
520
+ /**
521
+ * Send a JSON body only while the response can still take one.
522
+ *
523
+ * A handler that lost its client — the request was aborted, or the response
524
+ * already ended — must not write again; Node throws `ERR_STREAM_WRITE_AFTER_END`
525
+ * and the throw escapes into the server's error path rather than the caller's.
526
+ */
527
+ function sendJsonIfOpen(response, status, body) {
528
+ if (response.destroyed || response.writableEnded) return;
529
+ sendJson(response, status, body);
530
+ }
531
+ /**
532
+ * Wait until every in-flight handler has settled.
533
+ *
534
+ * Re-reads the set on each pass: a handler that is still running can register
535
+ * another, so awaiting one snapshot would return while work is outstanding and
536
+ * the caller would close the server under it.
537
+ */
538
+ async function waitForActiveHandlers(activeHandlers) {
539
+ while (activeHandlers.size > 0) await Promise.allSettled([...activeHandlers]);
540
+ }
541
+ //#endregion
542
+ //#region src/campaign/external-optimizer-model-contract.ts
543
+ var RequestBodyTooLargeError = class extends Error {};
544
+ var ProviderResponseTooLargeError = class extends Error {
545
+ constructor() {
546
+ super("optimizer model response exceeds maxResponseBytes");
547
+ }
548
+ };
549
+ var MissingModelExecutionError = class extends Error {};
550
+ var ModelExecutionPersistenceError = class extends Error {};
551
+ var OwnerModelContractError = class extends Error {};
229
552
  //#endregion
230
553
  //#region src/campaign/external-optimizer-anthropic.ts
231
554
  /**
@@ -694,311 +1017,88 @@ function refuse(message) {
694
1017
  return new AnthropicRequestRefusal(400, "invalid_request_error", message);
695
1018
  }
696
1019
  //#endregion
697
- //#region src/campaign/external-optimizer-http.ts
698
- function listenLocal(server) {
699
- return new Promise((resolvePromise, reject) => {
700
- server.once("error", reject);
701
- server.listen(0, "127.0.0.1", () => {
702
- server.off("error", reject);
703
- const address = server.address();
704
- if (!address || typeof address === "string") {
705
- reject(/* @__PURE__ */ new Error("external optimizer callback did not bind a TCP port"));
706
- return;
707
- }
708
- resolvePromise(address.port);
709
- });
710
- });
711
- }
712
- function closeServer(server) {
713
- return new Promise((resolvePromise, reject) => {
714
- server.close((error) => error ? reject(error) : resolvePromise());
715
- });
1020
+ //#region src/campaign/external-optimizer-model-response.ts
1021
+ function encodeAnthropicResponseBody(args) {
1022
+ const message = encodeAnthropicMessage(args.response, args.callId);
1023
+ const body = new TextEncoder().encode(args.stream ? renderAnthropicSseStream(message) : JSON.stringify(message));
1024
+ if (body.byteLength > args.maxBytes) throw new ProviderResponseTooLargeError();
1025
+ return {
1026
+ contentType: args.stream ? "text/event-stream; charset=utf-8" : "application/json",
1027
+ body
1028
+ };
716
1029
  }
717
- function sendJson(response, status, body) {
718
- response.writeHead(status, { "content-type": "application/json; charset=utf-8" });
719
- response.end(JSON.stringify(body));
1030
+ function encodeCanonicalModelResponse(args) {
1031
+ const usage = encodeProtocolUsage(args.path, args.response, args.receipt);
1032
+ const finishReason = args.response.finishReason === void 0 ? "stop" : args.response.finishReason;
1033
+ const body = args.path === "/v1/chat/completions" ? {
1034
+ id: `chatcmpl-${args.callId}`,
1035
+ object: "chat.completion",
1036
+ created: 0,
1037
+ model: args.response.model,
1038
+ choices: [{
1039
+ index: 0,
1040
+ message: {
1041
+ role: "assistant",
1042
+ content: args.response.content
1043
+ },
1044
+ finish_reason: finishReason
1045
+ }],
1046
+ ...usage ? { usage } : {}
1047
+ } : {
1048
+ id: `resp-${args.callId}`,
1049
+ object: "response",
1050
+ created_at: 0,
1051
+ model: args.response.model,
1052
+ status: finishReason === "length" ? "incomplete" : "completed",
1053
+ error: null,
1054
+ incomplete_details: finishReason === "length" ? { reason: "max_output_tokens" } : null,
1055
+ output: [{
1056
+ id: `msg-${args.callId}`,
1057
+ type: "message",
1058
+ status: finishReason === "length" ? "incomplete" : "completed",
1059
+ role: "assistant",
1060
+ content: [{
1061
+ type: "output_text",
1062
+ text: args.response.content,
1063
+ annotations: []
1064
+ }]
1065
+ }],
1066
+ output_text: args.response.content,
1067
+ ...usage ? { usage } : {}
1068
+ };
1069
+ const encoded = new TextEncoder().encode(JSON.stringify(body));
1070
+ if (encoded.byteLength > args.maxBytes) throw new ProviderResponseTooLargeError();
1071
+ return encoded;
720
1072
  }
721
- /**
722
- * Send a JSON body only while the response can still take one.
723
- *
724
- * A handler that lost its client — the request was aborted, or the response
725
- * already ended — must not write again; Node throws `ERR_STREAM_WRITE_AFTER_END`
726
- * and the throw escapes into the server's error path rather than the caller's.
727
- */
728
- function sendJsonIfOpen(response, status, body) {
729
- if (response.destroyed || response.writableEnded) return;
730
- sendJson(response, status, body);
1073
+ function endpointFormat(path) {
1074
+ if (path === "/v1/messages") return "anthropic-messages";
1075
+ return path === "/v1/responses" ? "responses" : "chat-completions";
731
1076
  }
732
- /**
733
- * Wait until every in-flight handler has settled.
734
- *
735
- * Re-reads the set on each pass: a handler that is still running can register
736
- * another, so awaiting one snapshot would return while work is outstanding and
737
- * the caller would close the server under it.
738
- */
739
- async function waitForActiveHandlers(activeHandlers) {
740
- while (activeHandlers.size > 0) await Promise.allSettled([...activeHandlers]);
1077
+ function encodeProtocolUsage(path, response, receipt) {
1078
+ if (response.usage.captured === false) return void 0;
1079
+ const inputDetails = {
1080
+ ...receipt.cachedTokens === void 0 ? {} : { cached_tokens: receipt.cachedTokens },
1081
+ ...receipt.cacheWriteTokens === void 0 ? {} : path === "/v1/chat/completions" ? { cache_creation_tokens: receipt.cacheWriteTokens } : { cache_write_tokens: receipt.cacheWriteTokens }
1082
+ };
1083
+ const outputDetails = { ...receipt.reasoningTokens === void 0 ? {} : { reasoning_tokens: receipt.reasoningTokens } };
1084
+ return path === "/v1/chat/completions" ? {
1085
+ prompt_tokens: response.usage.promptTokens,
1086
+ completion_tokens: response.usage.completionTokens,
1087
+ total_tokens: response.usage.totalTokens,
1088
+ ...Object.keys(inputDetails).length > 0 ? { prompt_tokens_details: inputDetails } : {},
1089
+ ...Object.keys(outputDetails).length > 0 ? { completion_tokens_details: outputDetails } : {},
1090
+ ...receipt.actualCostUsd === void 0 ? {} : { cost: receipt.actualCostUsd }
1091
+ } : {
1092
+ input_tokens: response.usage.promptTokens,
1093
+ output_tokens: response.usage.completionTokens,
1094
+ total_tokens: response.usage.totalTokens,
1095
+ ...Object.keys(inputDetails).length > 0 ? { input_tokens_details: inputDetails } : {},
1096
+ ...Object.keys(outputDetails).length > 0 ? { output_tokens_details: outputDetails } : {},
1097
+ ...receipt.actualCostUsd === void 0 ? {} : { cost: receipt.actualCostUsd }
1098
+ };
741
1099
  }
742
1100
  //#endregion
743
- //#region src/campaign/external-optimizer-model-proxy.ts
744
- const MODEL_PROXY_PATHS = /* @__PURE__ */ new Set(["/v1/chat/completions", "/v1/responses"]);
745
- /**
746
- * Put an OpenAI-compatible optimizer behind the shared cost ledger.
747
- *
748
- * The child process receives only a loopback URL and an ephemeral token. The
749
- * package that owns execution receives a validated immutable request through
750
- * `call`; Eval receives no provider credential. Every request reserves its
751
- * conservative byte-count input bound plus the declared output cap before the
752
- * owner is invoked exactly once.
753
- */
754
- async function startExternalOptimizerModelProxy(args) {
755
- assertModelProxyConfig(args);
756
- args.signal?.throwIfAborted();
757
- const token = randomLocalToken();
758
- let requestCount = 0;
759
- let successfulCompletionCount = 0;
760
- const wireCounts = {
761
- openai: {
762
- requestAttempts: 0,
763
- successfulCompletions: 0
764
- },
765
- anthropic: {
766
- requestAttempts: 0,
767
- successfulCompletions: 0
768
- }
769
- };
770
- let modelCallInvocations = 0;
771
- let executionRecordCount = 0;
772
- let executionSequence = 0;
773
- const failures = [];
774
- let totalRequestCount = args.initialUsage?.requests ?? 0;
775
- let committedForBudget = args.initialUsage?.costUsd ?? 0;
776
- let reservedForBudget = 0;
777
- let accepting = true;
778
- let closePromise;
779
- const activeControllers = /* @__PURE__ */ new Set();
780
- const activeHandlers = /* @__PURE__ */ new Set();
781
- const server = createServer((request, response) => {
782
- if (!accepting) {
783
- sendJsonIfOpen(response, 503, { error: "external optimizer model proxy is closing" });
784
- return;
785
- }
786
- const controller = new AbortController();
787
- const abortRequest = () => {
788
- request.destroy();
789
- response.destroy();
790
- };
791
- activeControllers.add(controller);
792
- controller.signal.addEventListener("abort", abortRequest, { once: true });
793
- let handler;
794
- handler = handleModelProxyRequest({
795
- request,
796
- response,
797
- controller,
798
- token,
799
- args,
800
- nextReservation: (maximumCostUsd, wire) => {
801
- if (totalRequestCount >= args.budget.maxRequests) return {
802
- accepted: false,
803
- reason: "optimizer model request limit reached"
804
- };
805
- if (args.budget.maxCostUsd !== void 0 && maximumCostUsd !== void 0 && committedForBudget + reservedForBudget + maximumCostUsd > args.budget.maxCostUsd + Number.EPSILON) return {
806
- accepted: false,
807
- reason: "optimizer model cost limit reached"
808
- };
809
- requestCount += 1;
810
- wireCounts[wire].requestAttempts += 1;
811
- totalRequestCount += 1;
812
- reservedForBudget += maximumCostUsd ?? 0;
813
- return { accepted: true };
814
- },
815
- settleReservation: (maximumCostUsd, chargedCostUsd) => {
816
- reservedForBudget = Math.max(0, reservedForBudget - (maximumCostUsd ?? 0));
817
- committedForBudget += chargedCostUsd ?? 0;
818
- },
819
- recordSuccessfulCompletion: (wire) => {
820
- successfulCompletionCount += 1;
821
- wireCounts[wire].successfulCompletions += 1;
822
- },
823
- recordExecutionReceipt: (observation) => {
824
- try {
825
- args.recordExecution({
826
- ...observation,
827
- sequence: executionSequence + 1
828
- });
829
- } catch (error) {
830
- throw new ModelExecutionPersistenceError(`optimizer model execution evidence was not persisted: ${toErrorMessage(error)}`);
831
- }
832
- executionSequence += 1;
833
- executionRecordCount += 1;
834
- },
835
- recordModelCallInvocation: () => {
836
- modelCallInvocations += 1;
837
- },
838
- recordFailure: (error) => {
839
- failures.push(error);
840
- }
841
- }).finally(() => {
842
- controller.signal.removeEventListener("abort", abortRequest);
843
- activeControllers.delete(controller);
844
- activeHandlers.delete(handler);
845
- });
846
- activeHandlers.add(handler);
847
- handler.catch(() => void 0);
848
- });
849
- const port = await listenLocal(server);
850
- const close = () => {
851
- closePromise ??= closeModelProxy();
852
- return closePromise;
853
- };
854
- const onAbort = () => {
855
- for (const controller of activeControllers) controller.abort(args.signal?.reason);
856
- close().catch(() => void 0);
857
- };
858
- args.signal?.addEventListener("abort", onAbort, { once: true });
859
- if (args.signal?.aborted) onAbort();
860
- const assertExecutionComplete = () => {
861
- if (executionRecordCount !== modelCallInvocations) throw new Error(`external optimizer model callback returned ${executionRecordCount} execution records for ${modelCallInvocations} invoked calls`);
862
- };
863
- return {
864
- baseUrl: `http://127.0.0.1:${port}/v1`,
865
- apiKey: token,
866
- requestAttempts: () => requestCount,
867
- successfulCompletions: () => successfulCompletionCount,
868
- wireUsage: () => ({
869
- openai: { ...wireCounts.openai },
870
- anthropic: { ...wireCounts.anthropic }
871
- }),
872
- assertExecutionComplete,
873
- failures: () => [...failures],
874
- close
875
- };
876
- async function closeModelProxy() {
877
- args.signal?.removeEventListener("abort", onAbort);
878
- accepting = false;
879
- const closingServer = closeServer(server);
880
- server.closeIdleConnections?.();
881
- const [serverResult] = await Promise.allSettled([closingServer, waitForActiveHandlers(activeHandlers)]);
882
- if (activeControllers.size !== 0 || activeHandlers.size !== 0) throw new Error("external optimizer model proxy closed with active request work");
883
- let executionError;
884
- try {
885
- assertExecutionComplete();
886
- } catch (error) {
887
- executionError = error;
888
- }
889
- if (serverResult?.status === "rejected" && executionError !== void 0) throw new AggregateError([serverResult.reason, executionError], "external optimizer model proxy close and execution evidence both failed");
890
- if (serverResult?.status === "rejected") throw serverResult.reason;
891
- if (executionError !== void 0) throw executionError;
892
- }
893
- }
894
- async function handleModelProxyRequest(args) {
895
- const { controller, request, response } = args;
896
- let wire = "openai";
897
- const respondError = (status, message, errorType) => {
898
- if (wire === "anthropic") {
899
- const mapped = status === 429 ? 402 : status;
900
- sendJsonIfOpen(response, mapped, anthropicErrorEnvelope(errorType ?? anthropicErrorTypeForStatus(mapped), message));
901
- return;
902
- }
903
- sendJsonIfOpen(response, status, { error: message });
904
- };
905
- try {
906
- const path = request.url ? new URL(request.url, "http://127.0.0.1").pathname : "";
907
- const anthropicPath = path === "/v1/messages" && args.args.anthropicEndpoint === true;
908
- if (request.method !== "POST" || !(MODEL_PROXY_PATHS.has(path) || anthropicPath)) {
909
- sendJsonIfOpen(response, 404, { error: "not found" });
910
- return;
911
- }
912
- if (anthropicPath) wire = "anthropic";
913
- const modelPath = path;
914
- if (!(request.headers.authorization === `Bearer ${args.token}` || wire === "anthropic" && request.headers["x-api-key"] === args.token)) {
915
- respondError(401, "unauthorized");
916
- return;
917
- }
918
- const body = await readBody(request, args.args.budget.maxRequestBytes);
919
- const parsed = parseModelProxyRequest(body, modelPath, args.args.model, args.args.budget);
920
- const maximumUsage = conservativeMaximumUsage(body.byteLength, parsed.maxOutputTokens + (args.args.budget.maxReasoningTokensPerRequest ?? 0), args.args.budget.pricing);
921
- const maximumCostUsd = args.args.budget.pricing ? costForTokenPricing(args.args.budget.pricing, maximumUsage) : void 0;
922
- const reservation = args.nextReservation(maximumCostUsd, wire);
923
- if (!reservation.accepted) {
924
- respondError(429, reservation.reason);
925
- return;
926
- }
927
- const timeout = setTimeout(() => controller.abort(), args.args.budget.requestTimeoutMs ?? 3e5);
928
- let chargedForBudget = maximumCostUsd;
929
- try {
930
- const requestTags = wire === "anthropic" ? {
931
- ...args.args.tags ?? {},
932
- wire: "anthropic",
933
- ...parsed.strippedFields === void 0 ? {} : { strippedFields: parsed.strippedFields.join(",") }
934
- } : args.args.tags;
935
- const paid = await args.args.costLedger.runPaidCall({
936
- ...args.args.callId ? { callId: args.args.callId } : {},
937
- channel: args.args.channel ?? "optimizer",
938
- phase: args.args.phase,
939
- actor: args.args.actor,
940
- ...requestTags ? { tags: requestTags } : {},
941
- model: args.args.model,
942
- ...args.args.budget.pricing ? { maximumCharge: {
943
- customTokenPricing: args.args.budget.pricing,
944
- ...maximumUsage
945
- } } : {},
946
- signal: controller.signal,
947
- execute: async (paidCallSignal, paidCallId) => forwardModelProxyRequest({
948
- call: args.args.call,
949
- callId: paidCallId,
950
- callRef: args.args.callRef,
951
- recordExecutionReceipt: args.recordExecutionReceipt,
952
- recordModelCallInvocation: args.recordModelCallInvocation,
953
- path: modelPath,
954
- request: parsed.request,
955
- ...parsed.stream === void 0 ? {} : { anthropicStream: parsed.stream },
956
- model: args.args.model,
957
- allowWithinFamily: args.args.servedModelPolicy === "allow-within-family",
958
- maxOutputTokens: parsed.maxOutputTokens,
959
- ...args.args.budget.maxReasoningTokensPerRequest === void 0 ? {} : { maxReasoningTokens: args.args.budget.maxReasoningTokensPerRequest },
960
- maxResponseBytes: args.args.budget.maxResponseBytes,
961
- signal: paidCallSignal
962
- }),
963
- receipt: (result) => result.receipt,
964
- receiptFromError: () => ({
965
- model: args.args.model,
966
- inputTokens: 0,
967
- outputTokens: 0,
968
- costUnknown: true,
969
- usageUnknown: true
970
- })
971
- });
972
- if (!paid.succeeded) {
973
- args.recordFailure(paid.error);
974
- chargedForBudget = paid.receipt ? paid.receipt.usageUnknown || paid.receipt.costUnknown ? maximumCostUsd : paid.receipt.costUsd : void 0;
975
- respondError(isAbortError(paid.error) ? 504 : paid.error instanceof AnthropicRequestRefusal ? paid.error.status : paid.error instanceof ProviderResponseTooLargeError || paid.error instanceof MissingModelExecutionError || paid.error instanceof ModelExecutionPersistenceError || paid.error instanceof OwnerModelContractError || paid.error instanceof ModelSubstitutionError ? 502 : 429, paid.error.message, paid.error instanceof AnthropicRequestRefusal ? paid.error.errorType : void 0);
976
- return;
977
- }
978
- if (paid.value.modelCallFailed) {
979
- respondError(502, paid.value.modelCallFailed);
980
- return;
981
- }
982
- chargedForBudget = paid.value.usageComplete ? paid.receipt.costUsd : maximumCostUsd;
983
- if (paid.value.usageRejected) {
984
- respondError(502, paid.value.usageRejected);
985
- return;
986
- }
987
- if (paid.value.status >= 200 && paid.value.status < 300) args.recordSuccessfulCompletion(wire);
988
- if (response.destroyed || response.writableEnded) return;
989
- response.writeHead(paid.value.status, {
990
- "content-type": paid.value.contentType,
991
- "content-length": String(paid.value.body.byteLength)
992
- });
993
- response.end(paid.value.body);
994
- } finally {
995
- clearTimeout(timeout);
996
- args.settleReservation(maximumCostUsd, chargedForBudget);
997
- }
998
- } catch (error) {
999
- respondError(error instanceof AnthropicRequestRefusal ? error.status : error instanceof RequestBodyTooLargeError ? 413 : error instanceof Error && isAbortError(error) ? 503 : 400, toErrorMessage(error), error instanceof AnthropicRequestRefusal ? error.errorType : void 0);
1000
- }
1001
- }
1101
+ //#region src/campaign/external-optimizer-model-execution.ts
1002
1102
  async function forwardModelProxyRequest(args) {
1003
1103
  args.recordModelCallInvocation();
1004
1104
  let called;
@@ -1010,14 +1110,14 @@ async function forwardModelProxyRequest(args) {
1010
1110
  signal: args.signal
1011
1111
  });
1012
1112
  } catch (error) {
1013
- throw new MissingModelExecutionError(`optimizer model callback rejected without execution evidence: ${toErrorMessage(error)}`);
1113
+ throw new MissingModelExecutionError(`optimizer model callback rejected without execution evidence: ${errorMessage(error)}`);
1014
1114
  }
1015
1115
  if (!called || typeof called !== "object" || typeof called.succeeded !== "boolean") throw new MissingModelExecutionError("optimizer model callback returned no typed success/failure outcome");
1016
1116
  let execution;
1017
1117
  try {
1018
1118
  execution = freezeJsonSnapshot(called.execution, "optimizer model callback execution evidence");
1019
1119
  } catch (error) {
1020
- throw new MissingModelExecutionError(`optimizer model callback returned invalid execution evidence: ${toErrorMessage(error)}`);
1120
+ throw new MissingModelExecutionError(`optimizer model callback returned invalid execution evidence: ${errorMessage(error)}`);
1021
1121
  }
1022
1122
  if (called.succeeded) {
1023
1123
  let authoritativeReceipt;
@@ -1033,7 +1133,7 @@ async function forwardModelProxyRequest(args) {
1033
1133
  path: args.path,
1034
1134
  model: args.model,
1035
1135
  succeeded: false,
1036
- error: toErrorMessage(error),
1136
+ error: errorMessage(error),
1037
1137
  execution
1038
1138
  });
1039
1139
  throw error;
@@ -1102,7 +1202,7 @@ function snapshotModelReceipt(value, expectedModel, allowWithinFamily) {
1102
1202
  assertJsonValue(value, "optimizer model callback receipt");
1103
1203
  snapshot = JSON.parse(canonicalJson(value));
1104
1204
  } catch (error) {
1105
- throw new OwnerModelContractError(`optimizer model callback returned an invalid receipt: ${toErrorMessage(error)}`);
1205
+ throw new OwnerModelContractError(`optimizer model callback returned an invalid receipt: ${errorMessage(error)}`);
1106
1206
  }
1107
1207
  assertServedModel(expectedModel, snapshot.model, {
1108
1208
  context: "optimizer model callback receipt",
@@ -1110,17 +1210,6 @@ function snapshotModelReceipt(value, expectedModel, allowWithinFamily) {
1110
1210
  });
1111
1211
  return snapshot;
1112
1212
  }
1113
- function freezeJsonSnapshot(value, label) {
1114
- assertJsonValue(value, label);
1115
- return deepFreezeJson(JSON.parse(canonicalJson(value)));
1116
- }
1117
- function deepFreezeJson(value) {
1118
- if (value !== null && typeof value === "object") {
1119
- for (const child of Object.values(value)) deepFreezeJson(child);
1120
- Object.freeze(value);
1121
- }
1122
- return value;
1123
- }
1124
1213
  function assertResponseUsageMatchesReceipt(response, receipt) {
1125
1214
  if (response.model !== receipt.model) throw new OwnerModelContractError("optimizer model response and execution receipt disagree about the served model");
1126
1215
  if (response.usage.captured === false || receipt.usageUnknown === true) {
@@ -1135,29 +1224,99 @@ function assertResponseUsageMatchesReceipt(response, receipt) {
1135
1224
  const receiptCostUsd = receipt.actualCostUsd ?? receipt.estimatedCostUsd ?? (receipt.customTokenPricing && receipt.usageUnknown !== true ? costForTokenPricing(receipt.customTokenPricing, receipt) : null);
1136
1225
  if (response.costUsd !== receiptCostUsd) throw new OwnerModelContractError("optimizer model response billed cost disagrees with the execution receipt");
1137
1226
  }
1138
- function parseModelProxyRequest(body, path, expectedModel, budget) {
1139
- if (path === "/v1/messages") {
1140
- const translated = translateAnthropicMessagesRequest(body, expectedModel, budget.maxOutputTokensPerRequest);
1141
- return {
1142
- maxOutputTokens: translated.maxOutputTokens,
1143
- stream: translated.stream,
1144
- ...translated.strippedFields.length > 0 ? { strippedFields: translated.strippedFields } : {},
1145
- request: freezeJsonSnapshot(translated.request, "optimizer model canonical request")
1146
- };
1147
- }
1148
- let value;
1149
- try {
1150
- value = JSON.parse(Buffer.from(body).toString("utf8"));
1151
- } catch {
1152
- throw new Error("optimizer model request must be valid JSON");
1153
- }
1154
- if (!isRecord(value)) throw new Error("optimizer model request must be a JSON object");
1155
- if (value.model !== expectedModel) throw new Error(`optimizer model request must use configured model '${expectedModel}'`);
1156
- if (value.stream !== void 0 && value.stream !== false) throw new Error("streaming optimizer model requests are not supported");
1227
+ function snapshotChatResponse(value, expectedModel, allowWithinFamily) {
1228
+ if (!isRecord(value)) throw new OwnerModelContractError("optimizer model callback response must be an object");
1229
+ if (typeof value.content !== "string") throw new OwnerModelContractError("optimizer model callback response content must be a string");
1230
+ assertServedModel(expectedModel, typeof value.model === "string" ? value.model : null, {
1231
+ context: "optimizer model callback response",
1232
+ allowWithinFamily
1233
+ });
1234
+ if (!isNonnegativeFiniteNumber(value.durationMs)) throw new OwnerModelContractError("optimizer model callback response durationMs must be finite and non-negative");
1235
+ if (value.costUsd !== null && !isNonnegativeFiniteNumber(value.costUsd)) throw new OwnerModelContractError("optimizer model callback response costUsd must be null or finite and non-negative");
1236
+ if (value.finishReason !== void 0 && value.finishReason !== null && typeof value.finishReason !== "string") throw new OwnerModelContractError("optimizer model callback response finishReason must be a string or null");
1237
+ const toolCalls = snapshotResponseToolCalls(value.toolCalls);
1238
+ if (value.contentEmpty !== void 0 && (typeof value.contentEmpty !== "boolean" || value.contentEmpty !== (value.content.trim().length === 0))) throw new OwnerModelContractError("optimizer model callback response contentEmpty must match content");
1239
+ if (!isRecord(value.raw)) throw new OwnerModelContractError("optimizer model callback response raw must be an object");
1240
+ if (!isRecord(value.usage)) throw new OwnerModelContractError("optimizer model callback response usage must be an object");
1241
+ const usage = value.usage;
1157
1242
  for (const field of [
1158
- "n",
1159
- "best_of",
1160
- "candidate_count",
1243
+ "promptTokens",
1244
+ "completionTokens",
1245
+ "totalTokens"
1246
+ ]) if (!isNonnegativeSafeInteger(usage[field])) throw new OwnerModelContractError(`optimizer model callback response usage.${field} must be a non-negative safe integer`);
1247
+ const promptTokens = usage.promptTokens;
1248
+ const completionTokens = usage.completionTokens;
1249
+ const totalTokens = usage.totalTokens;
1250
+ if (totalTokens !== promptTokens + completionTokens) throw new OwnerModelContractError("optimizer model callback response totalTokens must equal promptTokens plus completionTokens");
1251
+ if (usage.captured !== void 0 && typeof usage.captured !== "boolean") throw new OwnerModelContractError("optimizer model callback response usage.captured must be a boolean");
1252
+ if (usage.cachedPromptTokens !== void 0 && (!isNonnegativeSafeInteger(usage.cachedPromptTokens) || usage.cachedPromptTokens > promptTokens)) throw new OwnerModelContractError("optimizer model callback response cachedPromptTokens must be a subset of promptTokens");
1253
+ if (usage.reasoningTokens !== void 0 && (!isNonnegativeSafeInteger(usage.reasoningTokens) || usage.reasoningTokens > completionTokens)) throw new OwnerModelContractError("optimizer model callback response reasoningTokens must be a subset of completionTokens");
1254
+ let raw;
1255
+ try {
1256
+ raw = freezeJsonSnapshot(value.raw, "optimizer model callback canonical response.raw");
1257
+ } catch (error) {
1258
+ throw new OwnerModelContractError(`optimizer model callback returned invalid raw response evidence: ${errorMessage(error)}`);
1259
+ }
1260
+ return deepFreezeCanonicalJson({
1261
+ content: value.content,
1262
+ ...toolCalls === void 0 ? {} : { toolCalls },
1263
+ usage: {
1264
+ promptTokens,
1265
+ completionTokens,
1266
+ totalTokens,
1267
+ ...usage.captured === void 0 ? {} : { captured: usage.captured },
1268
+ ...usage.reasoningTokens === void 0 ? {} : { reasoningTokens: usage.reasoningTokens },
1269
+ ...usage.cachedPromptTokens === void 0 ? {} : { cachedPromptTokens: usage.cachedPromptTokens }
1270
+ },
1271
+ costUsd: value.costUsd,
1272
+ model: value.model,
1273
+ durationMs: value.durationMs,
1274
+ ...value.finishReason === void 0 ? {} : { finishReason: value.finishReason },
1275
+ ...value.contentEmpty === void 0 ? {} : { contentEmpty: value.contentEmpty },
1276
+ raw
1277
+ });
1278
+ }
1279
+ /** Snapshot the owner's canonical tool calls onto the allowlisted response. */
1280
+ function snapshotResponseToolCalls(value) {
1281
+ if (value === void 0) return void 0;
1282
+ if (!Array.isArray(value) || value.length === 0) throw new OwnerModelContractError("optimizer model callback response toolCalls must be a non-empty array when present");
1283
+ return value.map((entry) => {
1284
+ if (!isRecord(entry) || typeof entry.id !== "string" || !entry.id || typeof entry.name !== "string" || !entry.name || typeof entry.argumentsJson !== "string") throw new OwnerModelContractError("optimizer model callback response toolCalls entries require string id, name, and argumentsJson");
1285
+ return {
1286
+ id: entry.id,
1287
+ name: entry.name,
1288
+ argumentsJson: entry.argumentsJson
1289
+ };
1290
+ });
1291
+ }
1292
+ function isNonnegativeSafeInteger(value) {
1293
+ return Number.isSafeInteger(value) && value >= 0;
1294
+ }
1295
+ //#endregion
1296
+ //#region src/campaign/external-optimizer-model-request.ts
1297
+ function parseModelProxyRequest(body, path, expectedModel, budget) {
1298
+ if (path === "/v1/messages") {
1299
+ const translated = translateAnthropicMessagesRequest(body, expectedModel, budget.maxOutputTokensPerRequest);
1300
+ return {
1301
+ maxOutputTokens: translated.maxOutputTokens,
1302
+ stream: translated.stream,
1303
+ ...translated.strippedFields.length > 0 ? { strippedFields: translated.strippedFields } : {},
1304
+ request: freezeJsonSnapshot(translated.request, "optimizer model canonical request")
1305
+ };
1306
+ }
1307
+ let value;
1308
+ try {
1309
+ value = JSON.parse(Buffer.from(body).toString("utf8"));
1310
+ } catch {
1311
+ throw new Error("optimizer model request must be valid JSON");
1312
+ }
1313
+ if (!isRecord(value)) throw new Error("optimizer model request must be a JSON object");
1314
+ if (value.model !== expectedModel) throw new Error(`optimizer model request must use configured model '${expectedModel}'`);
1315
+ if (value.stream !== void 0 && value.stream !== false) throw new Error("streaming optimizer model requests are not supported");
1316
+ for (const field of [
1317
+ "n",
1318
+ "best_of",
1319
+ "candidate_count",
1161
1320
  "num_candidates"
1162
1321
  ]) if (value[field] !== void 0 && value[field] !== 1) throw new Error(`optimizer model request ${field} must be 1 when supplied`);
1163
1322
  if (value.reasoning !== void 0 || value.reasoning_effort !== void 0) throw new Error("optimizer model reasoning settings belong to the execution AgentProfile");
@@ -1394,169 +1553,309 @@ function assertAllowedKeys(value, allowed, label = "optimizer model request") {
1394
1553
  const unknown = Object.keys(value).filter((key) => !allowedSet.has(key));
1395
1554
  if (unknown.length > 0) throw new Error(`${label} contains unsupported fields: ${unknown.join(", ")}`);
1396
1555
  }
1397
- function snapshotChatResponse(value, expectedModel, allowWithinFamily) {
1398
- if (!isRecord(value)) throw new OwnerModelContractError("optimizer model callback response must be an object");
1399
- if (typeof value.content !== "string") throw new OwnerModelContractError("optimizer model callback response content must be a string");
1400
- assertServedModel(expectedModel, typeof value.model === "string" ? value.model : null, {
1401
- context: "optimizer model callback response",
1402
- allowWithinFamily
1403
- });
1404
- if (!isNonnegativeFiniteNumber(value.durationMs)) throw new OwnerModelContractError("optimizer model callback response durationMs must be finite and non-negative");
1405
- if (value.costUsd !== null && !isNonnegativeFiniteNumber(value.costUsd)) throw new OwnerModelContractError("optimizer model callback response costUsd must be null or finite and non-negative");
1406
- if (value.finishReason !== void 0 && value.finishReason !== null && typeof value.finishReason !== "string") throw new OwnerModelContractError("optimizer model callback response finishReason must be a string or null");
1407
- const toolCalls = snapshotResponseToolCalls(value.toolCalls);
1408
- if (value.contentEmpty !== void 0 && (typeof value.contentEmpty !== "boolean" || value.contentEmpty !== (value.content.trim().length === 0))) throw new OwnerModelContractError("optimizer model callback response contentEmpty must match content");
1409
- if (!isRecord(value.raw)) throw new OwnerModelContractError("optimizer model callback response raw must be an object");
1410
- if (!isRecord(value.usage)) throw new OwnerModelContractError("optimizer model callback response usage must be an object");
1411
- const usage = value.usage;
1412
- for (const field of [
1413
- "promptTokens",
1414
- "completionTokens",
1415
- "totalTokens"
1416
- ]) if (!isNonnegativeSafeInteger(usage[field])) throw new OwnerModelContractError(`optimizer model callback response usage.${field} must be a non-negative safe integer`);
1417
- const promptTokens = usage.promptTokens;
1418
- const completionTokens = usage.completionTokens;
1419
- const totalTokens = usage.totalTokens;
1420
- if (totalTokens !== promptTokens + completionTokens) throw new OwnerModelContractError("optimizer model callback response totalTokens must equal promptTokens plus completionTokens");
1421
- if (usage.captured !== void 0 && typeof usage.captured !== "boolean") throw new OwnerModelContractError("optimizer model callback response usage.captured must be a boolean");
1422
- if (usage.cachedPromptTokens !== void 0 && (!isNonnegativeSafeInteger(usage.cachedPromptTokens) || usage.cachedPromptTokens > promptTokens)) throw new OwnerModelContractError("optimizer model callback response cachedPromptTokens must be a subset of promptTokens");
1423
- if (usage.reasoningTokens !== void 0 && (!isNonnegativeSafeInteger(usage.reasoningTokens) || usage.reasoningTokens > completionTokens)) throw new OwnerModelContractError("optimizer model callback response reasoningTokens must be a subset of completionTokens");
1424
- let raw;
1556
+ //#endregion
1557
+ //#region src/campaign/external-optimizer-model-handler.ts
1558
+ const MODEL_PROXY_PATHS = /* @__PURE__ */ new Set(["/v1/chat/completions", "/v1/responses"]);
1559
+ async function handleModelProxyRequest(args) {
1560
+ const { controller, request, response } = args;
1561
+ let wire = "openai";
1562
+ const respondError = (status, message, errorType) => {
1563
+ if (wire === "anthropic") {
1564
+ const mapped = status === 429 ? 402 : status;
1565
+ sendJsonIfOpen(response, mapped, anthropicErrorEnvelope(errorType ?? anthropicErrorTypeForStatus(mapped), message));
1566
+ return;
1567
+ }
1568
+ sendJsonIfOpen(response, status, { error: message });
1569
+ };
1425
1570
  try {
1426
- raw = freezeJsonSnapshot(value.raw, "optimizer model callback canonical response.raw");
1571
+ const path = request.url ? new URL(request.url, "http://127.0.0.1").pathname : "";
1572
+ const anthropicPath = path === "/v1/messages" && args.args.anthropicEndpoint === true;
1573
+ if (request.method !== "POST" || !(MODEL_PROXY_PATHS.has(path) || anthropicPath)) {
1574
+ sendJsonIfOpen(response, 404, { error: "not found" });
1575
+ return;
1576
+ }
1577
+ if (anthropicPath) wire = "anthropic";
1578
+ const modelPath = path;
1579
+ if (!(request.headers.authorization === `Bearer ${args.token}` || wire === "anthropic" && request.headers["x-api-key"] === args.token)) {
1580
+ respondError(401, "unauthorized");
1581
+ return;
1582
+ }
1583
+ const body = await readBody(request, args.args.budget.maxRequestBytes);
1584
+ const parsed = parseModelProxyRequest(body, modelPath, args.args.model, args.args.budget);
1585
+ const maximumUsage = conservativeMaximumUsage(body.byteLength, parsed.maxOutputTokens + (args.args.budget.maxReasoningTokensPerRequest ?? 0), args.args.budget.pricing);
1586
+ const maximumCostUsd = args.args.budget.pricing ? costForTokenPricing(args.args.budget.pricing, maximumUsage) : void 0;
1587
+ const reservation = args.nextReservation(maximumCostUsd, wire);
1588
+ if (!reservation.accepted) {
1589
+ respondError(429, reservation.reason);
1590
+ return;
1591
+ }
1592
+ const timeout = setTimeout(() => controller.abort(), args.args.budget.requestTimeoutMs ?? 3e5);
1593
+ let chargedForBudget = maximumCostUsd;
1594
+ try {
1595
+ const requestTags = wire === "anthropic" ? {
1596
+ ...args.args.tags ?? {},
1597
+ wire: "anthropic",
1598
+ ...parsed.strippedFields === void 0 ? {} : { strippedFields: parsed.strippedFields.join(",") }
1599
+ } : args.args.tags;
1600
+ const paid = await args.args.costLedger.runPaidCall({
1601
+ ...args.args.callId ? { callId: args.args.callId } : {},
1602
+ channel: args.args.channel ?? "optimizer",
1603
+ phase: args.args.phase,
1604
+ actor: args.args.actor,
1605
+ ...requestTags ? { tags: requestTags } : {},
1606
+ model: args.args.model,
1607
+ ...args.args.budget.pricing ? { maximumCharge: {
1608
+ customTokenPricing: args.args.budget.pricing,
1609
+ ...maximumUsage
1610
+ } } : {},
1611
+ signal: controller.signal,
1612
+ execute: async (paidCallSignal, paidCallId) => forwardModelProxyRequest({
1613
+ call: args.args.call,
1614
+ callId: paidCallId,
1615
+ callRef: args.args.callRef,
1616
+ recordExecutionReceipt: args.recordExecutionReceipt,
1617
+ recordModelCallInvocation: args.recordModelCallInvocation,
1618
+ path: modelPath,
1619
+ request: parsed.request,
1620
+ ...parsed.stream === void 0 ? {} : { anthropicStream: parsed.stream },
1621
+ model: args.args.model,
1622
+ allowWithinFamily: args.args.servedModelPolicy === "allow-within-family",
1623
+ maxOutputTokens: parsed.maxOutputTokens,
1624
+ ...args.args.budget.maxReasoningTokensPerRequest === void 0 ? {} : { maxReasoningTokens: args.args.budget.maxReasoningTokensPerRequest },
1625
+ maxResponseBytes: args.args.budget.maxResponseBytes,
1626
+ signal: paidCallSignal
1627
+ }),
1628
+ receipt: (result) => result.receipt,
1629
+ receiptFromError: () => ({
1630
+ model: args.args.model,
1631
+ inputTokens: 0,
1632
+ outputTokens: 0,
1633
+ costUnknown: true,
1634
+ usageUnknown: true
1635
+ })
1636
+ });
1637
+ if (!paid.succeeded) {
1638
+ args.recordFailure(paid.error);
1639
+ chargedForBudget = paid.receipt ? paid.receipt.usageUnknown || paid.receipt.costUnknown ? maximumCostUsd : paid.receipt.costUsd : void 0;
1640
+ respondError(isAbortError(paid.error) ? 504 : paid.error instanceof AnthropicRequestRefusal ? paid.error.status : paid.error instanceof ProviderResponseTooLargeError || paid.error instanceof MissingModelExecutionError || paid.error instanceof ModelExecutionPersistenceError || paid.error instanceof OwnerModelContractError || paid.error instanceof ModelSubstitutionError ? 502 : 429, paid.error.message, paid.error instanceof AnthropicRequestRefusal ? paid.error.errorType : void 0);
1641
+ return;
1642
+ }
1643
+ if (paid.value.modelCallFailed) {
1644
+ respondError(502, paid.value.modelCallFailed);
1645
+ return;
1646
+ }
1647
+ chargedForBudget = paid.value.usageComplete ? paid.receipt.costUsd : maximumCostUsd;
1648
+ if (paid.value.usageRejected) {
1649
+ respondError(502, paid.value.usageRejected);
1650
+ return;
1651
+ }
1652
+ if (paid.value.status >= 200 && paid.value.status < 300) args.recordSuccessfulCompletion(wire);
1653
+ if (response.destroyed || response.writableEnded) return;
1654
+ response.writeHead(paid.value.status, {
1655
+ "content-type": paid.value.contentType,
1656
+ "content-length": String(paid.value.body.byteLength)
1657
+ });
1658
+ response.end(paid.value.body);
1659
+ } finally {
1660
+ clearTimeout(timeout);
1661
+ args.settleReservation(maximumCostUsd, chargedForBudget);
1662
+ }
1427
1663
  } catch (error) {
1428
- throw new OwnerModelContractError(`optimizer model callback returned invalid raw response evidence: ${toErrorMessage(error)}`);
1664
+ respondError(error instanceof AnthropicRequestRefusal ? error.status : error instanceof RequestBodyTooLargeError ? 413 : error instanceof Error && isAbortError(error) ? 503 : 400, errorMessage(error), error instanceof AnthropicRequestRefusal ? error.errorType : void 0);
1429
1665
  }
1430
- return deepFreezeJson({
1431
- content: value.content,
1432
- ...toolCalls === void 0 ? {} : { toolCalls },
1433
- usage: {
1434
- promptTokens,
1435
- completionTokens,
1436
- totalTokens,
1437
- ...usage.captured === void 0 ? {} : { captured: usage.captured },
1438
- ...usage.reasoningTokens === void 0 ? {} : { reasoningTokens: usage.reasoningTokens },
1439
- ...usage.cachedPromptTokens === void 0 ? {} : { cachedPromptTokens: usage.cachedPromptTokens }
1440
- },
1441
- costUsd: value.costUsd,
1442
- model: value.model,
1443
- durationMs: value.durationMs,
1444
- ...value.finishReason === void 0 ? {} : { finishReason: value.finishReason },
1445
- ...value.contentEmpty === void 0 ? {} : { contentEmpty: value.contentEmpty },
1446
- raw
1447
- });
1448
- }
1449
- /** Snapshot the owner's canonical tool calls onto the allowlisted response. */
1450
- function snapshotResponseToolCalls(value) {
1451
- if (value === void 0) return void 0;
1452
- if (!Array.isArray(value) || value.length === 0) throw new OwnerModelContractError("optimizer model callback response toolCalls must be a non-empty array when present");
1453
- return value.map((entry) => {
1454
- if (!isRecord(entry) || typeof entry.id !== "string" || !entry.id || typeof entry.name !== "string" || !entry.name || typeof entry.argumentsJson !== "string") throw new OwnerModelContractError("optimizer model callback response toolCalls entries require string id, name, and argumentsJson");
1455
- return {
1456
- id: entry.id,
1457
- name: entry.name,
1458
- argumentsJson: entry.argumentsJson
1459
- };
1460
- });
1461
1666
  }
1462
- function encodeAnthropicResponseBody(args) {
1463
- const message = encodeAnthropicMessage(args.response, args.callId);
1464
- const body = new TextEncoder().encode(args.stream ? renderAnthropicSseStream(message) : JSON.stringify(message));
1465
- if (body.byteLength > args.maxBytes) throw new ProviderResponseTooLargeError();
1667
+ function conservativeMaximumUsage(inputTokenUpperBound, outputTokenUpperBound, pricing) {
1668
+ if (pricing === void 0) return {
1669
+ inputTokens: inputTokenUpperBound,
1670
+ outputTokens: outputTokenUpperBound
1671
+ };
1672
+ const inputRates = [pricing.inputUsdPerMillion, pricing.cachedInputUsdPerMillion ?? pricing.inputUsdPerMillion];
1673
+ const mostExpensiveInputClass = inputRates.indexOf(Math.max(...inputRates));
1466
1674
  return {
1467
- contentType: args.stream ? "text/event-stream; charset=utf-8" : "application/json",
1468
- body
1675
+ inputTokens: mostExpensiveInputClass === 0 ? inputTokenUpperBound : 0,
1676
+ ...mostExpensiveInputClass === 1 ? { cachedTokens: inputTokenUpperBound } : {},
1677
+ cacheWriteTokens: inputTokenUpperBound,
1678
+ outputTokens: outputTokenUpperBound
1469
1679
  };
1470
1680
  }
1471
- function encodeCanonicalModelResponse(args) {
1472
- const usage = encodeProtocolUsage(args.path, args.response, args.receipt);
1473
- const finishReason = args.response.finishReason === void 0 ? "stop" : args.response.finishReason;
1474
- const body = args.path === "/v1/chat/completions" ? {
1475
- id: `chatcmpl-${args.callId}`,
1476
- object: "chat.completion",
1477
- created: 0,
1478
- model: args.response.model,
1479
- choices: [{
1480
- index: 0,
1481
- message: {
1482
- role: "assistant",
1483
- content: args.response.content
1484
- },
1485
- finish_reason: finishReason
1486
- }],
1487
- ...usage ? { usage } : {}
1488
- } : {
1489
- id: `resp-${args.callId}`,
1490
- object: "response",
1491
- created_at: 0,
1492
- model: args.response.model,
1493
- status: finishReason === "length" ? "incomplete" : "completed",
1494
- error: null,
1495
- incomplete_details: finishReason === "length" ? { reason: "max_output_tokens" } : null,
1496
- output: [{
1497
- id: `msg-${args.callId}`,
1498
- type: "message",
1499
- status: finishReason === "length" ? "incomplete" : "completed",
1500
- role: "assistant",
1501
- content: [{
1502
- type: "output_text",
1503
- text: args.response.content,
1504
- annotations: []
1505
- }]
1506
- }],
1507
- output_text: args.response.content,
1508
- ...usage ? { usage } : {}
1509
- };
1510
- const encoded = new TextEncoder().encode(JSON.stringify(body));
1511
- if (encoded.byteLength > args.maxBytes) throw new ProviderResponseTooLargeError();
1512
- return encoded;
1681
+ function readBody(request, maximumBytes) {
1682
+ return new Promise((resolvePromise, reject) => {
1683
+ let size = 0;
1684
+ let tooLarge = false;
1685
+ const chunks = [];
1686
+ request.on("data", (chunk) => {
1687
+ if (tooLarge) return;
1688
+ size += chunk.byteLength;
1689
+ if (size > maximumBytes) {
1690
+ tooLarge = true;
1691
+ chunks.length = 0;
1692
+ return;
1693
+ }
1694
+ chunks.push(chunk);
1695
+ });
1696
+ request.on("error", reject);
1697
+ request.on("end", () => {
1698
+ if (tooLarge) {
1699
+ reject(new RequestBodyTooLargeError("optimizer model request body too large"));
1700
+ return;
1701
+ }
1702
+ resolvePromise(new Uint8Array(Buffer.concat(chunks)));
1703
+ });
1704
+ });
1513
1705
  }
1514
- function endpointFormat(path) {
1515
- if (path === "/v1/messages") return "anthropic-messages";
1516
- return path === "/v1/responses" ? "responses" : "chat-completions";
1706
+ function isAbortError(error) {
1707
+ return error.name === "AbortError" || error.message.toLowerCase().includes("abort");
1517
1708
  }
1518
- function encodeProtocolUsage(path, response, receipt) {
1519
- if (response.usage.captured === false) return void 0;
1520
- const inputDetails = {
1521
- ...receipt.cachedTokens === void 0 ? {} : { cached_tokens: receipt.cachedTokens },
1522
- ...receipt.cacheWriteTokens === void 0 ? {} : path === "/v1/chat/completions" ? { cache_creation_tokens: receipt.cacheWriteTokens } : { cache_write_tokens: receipt.cacheWriteTokens }
1709
+ //#endregion
1710
+ //#region src/campaign/external-optimizer-model-proxy.ts
1711
+ /**
1712
+ * Put an OpenAI-compatible optimizer behind the shared cost ledger.
1713
+ *
1714
+ * The child process receives only a loopback URL and an ephemeral token. The
1715
+ * package that owns execution receives a validated immutable request through
1716
+ * `call`; Eval receives no provider credential. Every request reserves its
1717
+ * conservative byte-count input bound plus the declared output cap before the
1718
+ * owner is invoked exactly once.
1719
+ */
1720
+ async function startExternalOptimizerModelProxy(args) {
1721
+ assertModelProxyConfig(args);
1722
+ args.signal?.throwIfAborted();
1723
+ const token = randomLocalToken();
1724
+ let requestCount = 0;
1725
+ let successfulCompletionCount = 0;
1726
+ const wireCounts = {
1727
+ openai: {
1728
+ requestAttempts: 0,
1729
+ successfulCompletions: 0
1730
+ },
1731
+ anthropic: {
1732
+ requestAttempts: 0,
1733
+ successfulCompletions: 0
1734
+ }
1523
1735
  };
1524
- const outputDetails = { ...receipt.reasoningTokens === void 0 ? {} : { reasoning_tokens: receipt.reasoningTokens } };
1525
- return path === "/v1/chat/completions" ? {
1526
- prompt_tokens: response.usage.promptTokens,
1527
- completion_tokens: response.usage.completionTokens,
1528
- total_tokens: response.usage.totalTokens,
1529
- ...Object.keys(inputDetails).length > 0 ? { prompt_tokens_details: inputDetails } : {},
1530
- ...Object.keys(outputDetails).length > 0 ? { completion_tokens_details: outputDetails } : {},
1531
- ...receipt.actualCostUsd === void 0 ? {} : { cost: receipt.actualCostUsd }
1532
- } : {
1533
- input_tokens: response.usage.promptTokens,
1534
- output_tokens: response.usage.completionTokens,
1535
- total_tokens: response.usage.totalTokens,
1536
- ...Object.keys(inputDetails).length > 0 ? { input_tokens_details: inputDetails } : {},
1537
- ...Object.keys(outputDetails).length > 0 ? { output_tokens_details: outputDetails } : {},
1538
- ...receipt.actualCostUsd === void 0 ? {} : { cost: receipt.actualCostUsd }
1736
+ let modelCallInvocations = 0;
1737
+ let executionRecordCount = 0;
1738
+ let executionSequence = 0;
1739
+ const failures = [];
1740
+ let totalRequestCount = args.initialUsage?.requests ?? 0;
1741
+ let committedForBudget = args.initialUsage?.costUsd ?? 0;
1742
+ let reservedForBudget = 0;
1743
+ let accepting = true;
1744
+ let closePromise;
1745
+ const activeControllers = /* @__PURE__ */ new Set();
1746
+ const activeHandlers = /* @__PURE__ */ new Set();
1747
+ const server = createServer((request, response) => {
1748
+ if (!accepting) {
1749
+ sendJsonIfOpen(response, 503, { error: "external optimizer model proxy is closing" });
1750
+ return;
1751
+ }
1752
+ const controller = new AbortController();
1753
+ const abortRequest = () => {
1754
+ request.destroy();
1755
+ response.destroy();
1756
+ };
1757
+ activeControllers.add(controller);
1758
+ controller.signal.addEventListener("abort", abortRequest, { once: true });
1759
+ let handler;
1760
+ handler = handleModelProxyRequest({
1761
+ request,
1762
+ response,
1763
+ controller,
1764
+ token,
1765
+ args,
1766
+ nextReservation: (maximumCostUsd, wire) => {
1767
+ if (totalRequestCount >= args.budget.maxRequests) return {
1768
+ accepted: false,
1769
+ reason: "optimizer model request limit reached"
1770
+ };
1771
+ if (args.budget.maxCostUsd !== void 0 && maximumCostUsd !== void 0 && committedForBudget + reservedForBudget + maximumCostUsd > args.budget.maxCostUsd + Number.EPSILON) return {
1772
+ accepted: false,
1773
+ reason: "optimizer model cost limit reached"
1774
+ };
1775
+ requestCount += 1;
1776
+ wireCounts[wire].requestAttempts += 1;
1777
+ totalRequestCount += 1;
1778
+ reservedForBudget += maximumCostUsd ?? 0;
1779
+ return { accepted: true };
1780
+ },
1781
+ settleReservation: (maximumCostUsd, chargedCostUsd) => {
1782
+ reservedForBudget = Math.max(0, reservedForBudget - (maximumCostUsd ?? 0));
1783
+ committedForBudget += chargedCostUsd ?? 0;
1784
+ },
1785
+ recordSuccessfulCompletion: (wire) => {
1786
+ successfulCompletionCount += 1;
1787
+ wireCounts[wire].successfulCompletions += 1;
1788
+ },
1789
+ recordExecutionReceipt: (observation) => {
1790
+ try {
1791
+ args.recordExecution({
1792
+ ...observation,
1793
+ sequence: executionSequence + 1
1794
+ });
1795
+ } catch (error) {
1796
+ throw new ModelExecutionPersistenceError(`optimizer model execution evidence was not persisted: ${errorMessage(error)}`);
1797
+ }
1798
+ executionSequence += 1;
1799
+ executionRecordCount += 1;
1800
+ },
1801
+ recordModelCallInvocation: () => {
1802
+ modelCallInvocations += 1;
1803
+ },
1804
+ recordFailure: (error) => {
1805
+ failures.push(error);
1806
+ }
1807
+ }).finally(() => {
1808
+ controller.signal.removeEventListener("abort", abortRequest);
1809
+ activeControllers.delete(controller);
1810
+ activeHandlers.delete(handler);
1811
+ });
1812
+ activeHandlers.add(handler);
1813
+ handler.catch(() => void 0);
1814
+ });
1815
+ const port = await listenLocal(server);
1816
+ const close = () => {
1817
+ closePromise ??= closeModelProxy();
1818
+ return closePromise;
1539
1819
  };
1540
- }
1541
- function isNonnegativeFiniteNumber(value) {
1542
- return typeof value === "number" && Number.isFinite(value) && value >= 0;
1543
- }
1544
- function isNonnegativeSafeInteger(value) {
1545
- return Number.isSafeInteger(value) && value >= 0;
1546
- }
1547
- function conservativeMaximumUsage(inputTokenUpperBound, outputTokenUpperBound, pricing) {
1548
- if (pricing === void 0) return {
1549
- inputTokens: inputTokenUpperBound,
1550
- outputTokens: outputTokenUpperBound
1820
+ const onAbort = () => {
1821
+ for (const controller of activeControllers) controller.abort(args.signal?.reason);
1822
+ close().catch(() => void 0);
1823
+ };
1824
+ args.signal?.addEventListener("abort", onAbort, { once: true });
1825
+ if (args.signal?.aborted) onAbort();
1826
+ const assertExecutionComplete = () => {
1827
+ if (executionRecordCount !== modelCallInvocations) throw new Error(`external optimizer model callback returned ${executionRecordCount} execution records for ${modelCallInvocations} invoked calls`);
1551
1828
  };
1552
- const inputRates = [pricing.inputUsdPerMillion, pricing.cachedInputUsdPerMillion ?? pricing.inputUsdPerMillion];
1553
- const mostExpensiveInputClass = inputRates.indexOf(Math.max(...inputRates));
1554
1829
  return {
1555
- inputTokens: mostExpensiveInputClass === 0 ? inputTokenUpperBound : 0,
1556
- ...mostExpensiveInputClass === 1 ? { cachedTokens: inputTokenUpperBound } : {},
1557
- cacheWriteTokens: inputTokenUpperBound,
1558
- outputTokens: outputTokenUpperBound
1830
+ baseUrl: `http://127.0.0.1:${port}/v1`,
1831
+ apiKey: token,
1832
+ requestAttempts: () => requestCount,
1833
+ successfulCompletions: () => successfulCompletionCount,
1834
+ wireUsage: () => ({
1835
+ openai: { ...wireCounts.openai },
1836
+ anthropic: { ...wireCounts.anthropic }
1837
+ }),
1838
+ assertExecutionComplete,
1839
+ failures: () => [...failures],
1840
+ close
1559
1841
  };
1842
+ async function closeModelProxy() {
1843
+ args.signal?.removeEventListener("abort", onAbort);
1844
+ accepting = false;
1845
+ const closingServer = closeServer(server);
1846
+ server.closeIdleConnections?.();
1847
+ const [serverResult] = await Promise.allSettled([closingServer, waitForActiveHandlers(activeHandlers)]);
1848
+ if (activeControllers.size !== 0 || activeHandlers.size !== 0) throw new Error("external optimizer model proxy closed with active request work");
1849
+ let executionError;
1850
+ try {
1851
+ assertExecutionComplete();
1852
+ } catch (error) {
1853
+ executionError = error;
1854
+ }
1855
+ if (serverResult?.status === "rejected" && executionError !== void 0) throw new AggregateError([serverResult.reason, executionError], "external optimizer model proxy close and execution evidence both failed");
1856
+ if (serverResult?.status === "rejected") throw serverResult.reason;
1857
+ if (executionError !== void 0) throw executionError;
1858
+ }
1560
1859
  }
1561
1860
  function assertModelProxyConfig(args) {
1562
1861
  assertServedModelPolicy(args.servedModelPolicy, "external optimizer model proxy: servedModelPolicy");
@@ -1581,49 +1880,9 @@ function assertModelProxyConfig(args) {
1581
1880
  if (args.initialUsage.requests > args.budget.maxRequests || args.budget.maxCostUsd !== void 0 && args.initialUsage.costUsd !== void 0 && args.initialUsage.costUsd > args.budget.maxCostUsd + Number.EPSILON) throw new Error("external optimizer model proxy: initialUsage exceeds the configured budget");
1582
1881
  }
1583
1882
  }
1584
- var RequestBodyTooLargeError = class extends Error {};
1585
- var ProviderResponseTooLargeError = class extends Error {
1586
- constructor() {
1587
- super("optimizer model response exceeds maxResponseBytes");
1588
- }
1589
- };
1590
- var MissingModelExecutionError = class extends Error {};
1591
- var ModelExecutionPersistenceError = class extends Error {};
1592
- var OwnerModelContractError = class extends Error {};
1593
- function readBody(request, maximumBytes) {
1594
- return new Promise((resolvePromise, reject) => {
1595
- let size = 0;
1596
- let tooLarge = false;
1597
- const chunks = [];
1598
- request.on("data", (chunk) => {
1599
- if (tooLarge) return;
1600
- size += chunk.byteLength;
1601
- if (size > maximumBytes) {
1602
- tooLarge = true;
1603
- chunks.length = 0;
1604
- return;
1605
- }
1606
- chunks.push(chunk);
1607
- });
1608
- request.on("error", reject);
1609
- request.on("end", () => {
1610
- if (tooLarge) {
1611
- reject(new RequestBodyTooLargeError("optimizer model request body too large"));
1612
- return;
1613
- }
1614
- resolvePromise(new Uint8Array(Buffer.concat(chunks)));
1615
- });
1616
- });
1617
- }
1618
1883
  function randomLocalToken() {
1619
1884
  return randomBytes(32).toString("hex");
1620
1885
  }
1621
- function isAbortError(error) {
1622
- return error.name === "AbortError" || error.message.toLowerCase().includes("abort");
1623
- }
1624
- function toErrorMessage(error) {
1625
- return error instanceof Error ? error.message : String(error);
1626
- }
1627
1886
  //#endregion
1628
1887
  //#region src/campaign/external-optimizer-resources.ts
1629
1888
  async function runWithCleanup(args) {
@@ -1901,6 +2160,6 @@ function summarizeProcessOutput(capture, max = 4e3) {
1901
2160
  return `${compact.slice(0, headChars)}...[${compact.length - max} chars omitted]...${compact.slice(-tailChars)}`;
1902
2161
  }
1903
2162
  //#endregion
1904
- export { inMemoryCampaignStorage as C, fsCampaignStorage as S, removeCredentialEnvironment as _, closeServer as a, safePathComponent as b, waitForActiveHandlers as c, assertExternalOptimizerModelBudget as d, assertJsonValue as f, isRecord as g, isExternalTextCandidate as h, startExternalOptimizerModelProxy as i, DEFAULT_EXTERNAL_OPTIMIZER_CALLBACK_LIMITS as l, isCandidateText as m, closeExternalOptimizerResources as n, listenLocal as o, assertNoCredentialValues as p, runWithCleanup as r, sendJsonIfOpen as s, runExternalOptimizerProcess as t, DEFAULT_EXTERNAL_OPTIMIZER_PROCESS_LIMITS as u, resolveExternalOptimizerCallbackLimits as v, createRunCostLedger as x, resolveExternalOptimizerProcessLimits as y };
2163
+ export { parseAnalystFinding as A, ProposalFindingSchema as C, lineageRoots as D, independentUnitCount as E, inMemoryCampaignStorage as F, spanningWindow as M, createRunCostLedger as N, mergeEvidenceUnits as O, fsCampaignStorage as P, FINDING_LAYERS as S, findingLayerRank as T, removeCredentialEnvironment as _, closeServer as a, safePathComponent as b, waitForActiveHandlers as c, assertExternalOptimizerModelBudget as d, assertJsonValue as f, isRecord as g, isExternalTextCandidate as h, startExternalOptimizerModelProxy as i, readFindingScope as j, mostSevere as k, DEFAULT_EXTERNAL_OPTIMIZER_CALLBACK_LIMITS as l, isCandidateText as m, closeExternalOptimizerResources as n, listenLocal as o, assertNoCredentialValues as p, runWithCleanup as r, sendJsonIfOpen as s, runExternalOptimizerProcess as t, DEFAULT_EXTERNAL_OPTIMIZER_PROCESS_LIMITS as u, resolveExternalOptimizerCallbackLimits as v, UNKNOWN_LINEAGE as w, AnalystFindingSchema as x, resolveExternalOptimizerProcessLimits as y };
1905
2164
 
1906
- //# sourceMappingURL=external-optimizer-subprocess-BUxifb8g.js.map
2165
+ //# sourceMappingURL=external-optimizer-subprocess-BqW0hHcI.js.map