@smthrs/harness 0.0.0-stage → 1.0.0-rc.4

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 (476) hide show
  1. package/CHANGELOG.md +387 -0
  2. package/LICENSE +21 -0
  3. package/README.md +138 -2
  4. package/dist/cjs/AgentEvent.d.ts +3092 -0
  5. package/dist/cjs/AgentEvent.d.ts.map +1 -0
  6. package/dist/cjs/AgentEvent.js +1116 -0
  7. package/dist/cjs/AgentEvent.js.map +7 -0
  8. package/dist/cjs/CallLedger.d.ts +378 -0
  9. package/dist/cjs/CallLedger.d.ts.map +1 -0
  10. package/dist/cjs/CallLedger.js +240 -0
  11. package/dist/cjs/CallLedger.js.map +7 -0
  12. package/dist/cjs/Cell.d.ts +774 -0
  13. package/dist/cjs/Cell.d.ts.map +1 -0
  14. package/dist/cjs/Cell.js +431 -0
  15. package/dist/cjs/Cell.js.map +7 -0
  16. package/dist/cjs/CellCalls.d.ts +115 -0
  17. package/dist/cjs/CellCalls.d.ts.map +1 -0
  18. package/dist/cjs/CellCalls.js +98 -0
  19. package/dist/cjs/CellCalls.js.map +7 -0
  20. package/dist/cjs/CellHistory.d.ts +102 -0
  21. package/dist/cjs/CellHistory.d.ts.map +1 -0
  22. package/dist/cjs/CellHistory.js +54 -0
  23. package/dist/cjs/CellHistory.js.map +7 -0
  24. package/dist/cjs/CellTurn.d.ts +1071 -0
  25. package/dist/cjs/CellTurn.d.ts.map +1 -0
  26. package/dist/cjs/CellTurn.js +2618 -0
  27. package/dist/cjs/CellTurn.js.map +7 -0
  28. package/dist/cjs/CellValidation.d.ts +94 -0
  29. package/dist/cjs/CellValidation.d.ts.map +1 -0
  30. package/dist/cjs/CellValidation.js +218 -0
  31. package/dist/cjs/CellValidation.js.map +7 -0
  32. package/dist/cjs/Compaction.d.ts +158 -0
  33. package/dist/cjs/Compaction.d.ts.map +1 -0
  34. package/dist/cjs/Compaction.js +189 -0
  35. package/dist/cjs/Compaction.js.map +7 -0
  36. package/dist/cjs/CompletionClaim.d.ts +801 -0
  37. package/dist/cjs/CompletionClaim.d.ts.map +1 -0
  38. package/dist/cjs/CompletionClaim.js +303 -0
  39. package/dist/cjs/CompletionClaim.js.map +7 -0
  40. package/dist/cjs/ContextWindow.d.ts +435 -0
  41. package/dist/cjs/ContextWindow.d.ts.map +1 -0
  42. package/dist/cjs/ContextWindow.js +319 -0
  43. package/dist/cjs/ContextWindow.js.map +7 -0
  44. package/dist/cjs/EngineLike.d.ts +546 -0
  45. package/dist/cjs/EngineLike.d.ts.map +1 -0
  46. package/dist/cjs/EngineLike.js +114 -0
  47. package/dist/cjs/EngineLike.js.map +7 -0
  48. package/dist/cjs/ExternalTranscript.d.ts +349 -0
  49. package/dist/cjs/ExternalTranscript.d.ts.map +1 -0
  50. package/dist/cjs/ExternalTranscript.js +826 -0
  51. package/dist/cjs/ExternalTranscript.js.map +7 -0
  52. package/dist/cjs/FailedCall.d.ts +132 -0
  53. package/dist/cjs/FailedCall.d.ts.map +1 -0
  54. package/dist/cjs/FailedCall.js +53 -0
  55. package/dist/cjs/FailedCall.js.map +7 -0
  56. package/dist/cjs/FlowBinding.d.ts +289 -0
  57. package/dist/cjs/FlowBinding.d.ts.map +1 -0
  58. package/dist/cjs/FlowBinding.js +251 -0
  59. package/dist/cjs/FlowBinding.js.map +7 -0
  60. package/dist/cjs/HarnessError.d.ts +57 -0
  61. package/dist/cjs/HarnessError.d.ts.map +1 -0
  62. package/dist/cjs/HarnessError.js +75 -0
  63. package/dist/cjs/HarnessError.js.map +7 -0
  64. package/dist/cjs/Judgement.d.ts +289 -0
  65. package/dist/cjs/Judgement.d.ts.map +1 -0
  66. package/dist/cjs/Judgement.js +240 -0
  67. package/dist/cjs/Judgement.js.map +7 -0
  68. package/dist/cjs/Monitor.d.ts +374 -0
  69. package/dist/cjs/Monitor.d.ts.map +1 -0
  70. package/dist/cjs/Monitor.js +233 -0
  71. package/dist/cjs/Monitor.js.map +7 -0
  72. package/dist/cjs/NarrowedCheck.d.ts +523 -0
  73. package/dist/cjs/NarrowedCheck.d.ts.map +1 -0
  74. package/dist/cjs/NarrowedCheck.js +263 -0
  75. package/dist/cjs/NarrowedCheck.js.map +7 -0
  76. package/dist/cjs/Notifications.d.ts +42 -0
  77. package/dist/cjs/Notifications.d.ts.map +1 -0
  78. package/dist/cjs/Notifications.js +177 -0
  79. package/dist/cjs/Notifications.js.map +7 -0
  80. package/dist/cjs/Plan.d.ts +127 -0
  81. package/dist/cjs/Plan.d.ts.map +1 -0
  82. package/dist/cjs/Plan.js +77 -0
  83. package/dist/cjs/Plan.js.map +7 -0
  84. package/dist/cjs/QuickJSSandbox.d.ts +151 -0
  85. package/dist/cjs/QuickJSSandbox.d.ts.map +1 -0
  86. package/dist/cjs/QuickJSSandbox.js +987 -0
  87. package/dist/cjs/QuickJSSandbox.js.map +7 -0
  88. package/dist/cjs/Relevance.d.ts +213 -0
  89. package/dist/cjs/Relevance.d.ts.map +1 -0
  90. package/dist/cjs/Relevance.js +183 -0
  91. package/dist/cjs/Relevance.js.map +7 -0
  92. package/dist/cjs/Sandbox.d.ts +637 -0
  93. package/dist/cjs/Sandbox.d.ts.map +1 -0
  94. package/dist/cjs/Sandbox.js +260 -0
  95. package/dist/cjs/Sandbox.js.map +7 -0
  96. package/dist/cjs/Steering.d.ts +464 -0
  97. package/dist/cjs/Steering.d.ts.map +1 -0
  98. package/dist/cjs/Steering.js +153 -0
  99. package/dist/cjs/Steering.js.map +7 -0
  100. package/dist/cjs/StructuredOutput.d.ts +252 -0
  101. package/dist/cjs/StructuredOutput.d.ts.map +1 -0
  102. package/dist/cjs/StructuredOutput.js +266 -0
  103. package/dist/cjs/StructuredOutput.js.map +7 -0
  104. package/dist/cjs/Sufficiency.d.ts +195 -0
  105. package/dist/cjs/Sufficiency.d.ts.map +1 -0
  106. package/dist/cjs/Sufficiency.js +110 -0
  107. package/dist/cjs/Sufficiency.js.map +7 -0
  108. package/dist/cjs/Supervisor.d.ts +719 -0
  109. package/dist/cjs/Supervisor.d.ts.map +1 -0
  110. package/dist/cjs/Supervisor.js +313 -0
  111. package/dist/cjs/Supervisor.js.map +7 -0
  112. package/dist/cjs/Tokens.d.ts +86 -0
  113. package/dist/cjs/Tokens.d.ts.map +1 -0
  114. package/dist/cjs/Tokens.js +72 -0
  115. package/dist/cjs/Tokens.js.map +7 -0
  116. package/dist/cjs/Transcript.d.ts +171 -0
  117. package/dist/cjs/Transcript.d.ts.map +1 -0
  118. package/dist/cjs/Transcript.js +342 -0
  119. package/dist/cjs/Transcript.js.map +7 -0
  120. package/dist/cjs/TruncatedOutput.d.ts +186 -0
  121. package/dist/cjs/TruncatedOutput.d.ts.map +1 -0
  122. package/dist/cjs/TruncatedOutput.js +143 -0
  123. package/dist/cjs/TruncatedOutput.js.map +7 -0
  124. package/dist/cjs/UnmovedTree.d.ts +113 -0
  125. package/dist/cjs/UnmovedTree.d.ts.map +1 -0
  126. package/dist/cjs/UnmovedTree.js +38 -0
  127. package/dist/cjs/UnmovedTree.js.map +7 -0
  128. package/dist/cjs/UnresolvedFailure.d.ts +196 -0
  129. package/dist/cjs/UnresolvedFailure.d.ts.map +1 -0
  130. package/dist/cjs/UnresolvedFailure.js +77 -0
  131. package/dist/cjs/UnresolvedFailure.js.map +7 -0
  132. package/dist/cjs/VacuousVerification.d.ts +237 -0
  133. package/dist/cjs/VacuousVerification.d.ts.map +1 -0
  134. package/dist/cjs/VacuousVerification.js +91 -0
  135. package/dist/cjs/VacuousVerification.js.map +7 -0
  136. package/dist/cjs/VariablesPanel.d.ts +117 -0
  137. package/dist/cjs/VariablesPanel.d.ts.map +1 -0
  138. package/dist/cjs/VariablesPanel.js +108 -0
  139. package/dist/cjs/VariablesPanel.js.map +7 -0
  140. package/dist/cjs/index.d.ts +172 -0
  141. package/dist/cjs/index.d.ts.map +1 -0
  142. package/dist/cjs/index.js +99 -0
  143. package/dist/cjs/index.js.map +7 -0
  144. package/dist/cjs/internal/bytes.d.ts +36 -0
  145. package/dist/cjs/internal/bytes.d.ts.map +1 -0
  146. package/dist/cjs/internal/bytes.js +57 -0
  147. package/dist/cjs/internal/bytes.js.map +7 -0
  148. package/dist/cjs/internal/cellPrompt.d.ts +122 -0
  149. package/dist/cjs/internal/cellPrompt.d.ts.map +1 -0
  150. package/dist/cjs/internal/cellPrompt.js +146 -0
  151. package/dist/cjs/internal/cellPrompt.js.map +7 -0
  152. package/dist/cjs/internal/compactable.d.ts +44 -0
  153. package/dist/cjs/internal/compactable.d.ts.map +1 -0
  154. package/dist/cjs/internal/compactable.js +56 -0
  155. package/dist/cjs/internal/compactable.js.map +7 -0
  156. package/dist/cjs/internal/compactionMarks.d.ts +278 -0
  157. package/dist/cjs/internal/compactionMarks.d.ts.map +1 -0
  158. package/dist/cjs/internal/compactionMarks.js +212 -0
  159. package/dist/cjs/internal/compactionMarks.js.map +7 -0
  160. package/dist/cjs/internal/demandText.d.ts +95 -0
  161. package/dist/cjs/internal/demandText.d.ts.map +1 -0
  162. package/dist/cjs/internal/demandText.js +70 -0
  163. package/dist/cjs/internal/demandText.js.map +7 -0
  164. package/dist/cjs/internal/elide.d.ts +109 -0
  165. package/dist/cjs/internal/elide.d.ts.map +1 -0
  166. package/dist/cjs/internal/elide.js +59 -0
  167. package/dist/cjs/internal/elide.js.map +7 -0
  168. package/dist/cjs/internal/frame.d.ts +463 -0
  169. package/dist/cjs/internal/frame.d.ts.map +1 -0
  170. package/dist/cjs/internal/frame.js +514 -0
  171. package/dist/cjs/internal/frame.js.map +7 -0
  172. package/dist/cjs/internal/nonNegativeSafeInt.d.ts +20 -0
  173. package/dist/cjs/internal/nonNegativeSafeInt.d.ts.map +1 -0
  174. package/dist/cjs/internal/nonNegativeSafeInt.js +29 -0
  175. package/dist/cjs/internal/nonNegativeSafeInt.js.map +7 -0
  176. package/dist/cjs/internal/paidUsage.d.ts +52 -0
  177. package/dist/cjs/internal/paidUsage.d.ts.map +1 -0
  178. package/dist/cjs/internal/paidUsage.js +70 -0
  179. package/dist/cjs/internal/paidUsage.js.map +7 -0
  180. package/dist/cjs/internal/printChannel.d.ts +233 -0
  181. package/dist/cjs/internal/printChannel.d.ts.map +1 -0
  182. package/dist/cjs/internal/printChannel.js +165 -0
  183. package/dist/cjs/internal/printChannel.js.map +7 -0
  184. package/dist/cjs/internal/printsObservation.d.ts +26 -0
  185. package/dist/cjs/internal/printsObservation.d.ts.map +1 -0
  186. package/dist/cjs/internal/printsObservation.js +27 -0
  187. package/dist/cjs/internal/printsObservation.js.map +7 -0
  188. package/dist/cjs/internal/refusal.d.ts +40 -0
  189. package/dist/cjs/internal/refusal.d.ts.map +1 -0
  190. package/dist/cjs/internal/refusal.js +45 -0
  191. package/dist/cjs/internal/refusal.js.map +7 -0
  192. package/dist/cjs/internal/supervision.d.ts +174 -0
  193. package/dist/cjs/internal/supervision.d.ts.map +1 -0
  194. package/dist/cjs/internal/supervision.js +402 -0
  195. package/dist/cjs/internal/supervision.js.map +7 -0
  196. package/dist/cjs/internal/unfinishedWork.d.ts +99 -0
  197. package/dist/cjs/internal/unfinishedWork.d.ts.map +1 -0
  198. package/dist/cjs/internal/unfinishedWork.js +80 -0
  199. package/dist/cjs/internal/unfinishedWork.js.map +7 -0
  200. package/dist/cjs/internal/unobservedCall.d.ts +112 -0
  201. package/dist/cjs/internal/unobservedCall.d.ts.map +1 -0
  202. package/dist/cjs/internal/unobservedCall.js +345 -0
  203. package/dist/cjs/internal/unobservedCall.js.map +7 -0
  204. package/dist/cjs/internal/untrustedData.d.ts +14 -0
  205. package/dist/cjs/internal/untrustedData.d.ts.map +1 -0
  206. package/dist/cjs/internal/untrustedData.js +30 -0
  207. package/dist/cjs/internal/untrustedData.js.map +7 -0
  208. package/dist/cjs/package.json +1 -0
  209. package/dist/esm/AgentEvent.d.ts +3092 -0
  210. package/dist/esm/AgentEvent.d.ts.map +1 -0
  211. package/dist/esm/AgentEvent.js +1610 -0
  212. package/dist/esm/AgentEvent.js.map +1 -0
  213. package/dist/esm/CallLedger.d.ts +378 -0
  214. package/dist/esm/CallLedger.d.ts.map +1 -0
  215. package/dist/esm/CallLedger.js +506 -0
  216. package/dist/esm/CallLedger.js.map +1 -0
  217. package/dist/esm/Cell.d.ts +774 -0
  218. package/dist/esm/Cell.d.ts.map +1 -0
  219. package/dist/esm/Cell.js +772 -0
  220. package/dist/esm/Cell.js.map +1 -0
  221. package/dist/esm/CellCalls.d.ts +115 -0
  222. package/dist/esm/CellCalls.d.ts.map +1 -0
  223. package/dist/esm/CellCalls.js +97 -0
  224. package/dist/esm/CellCalls.js.map +1 -0
  225. package/dist/esm/CellHistory.d.ts +102 -0
  226. package/dist/esm/CellHistory.d.ts.map +1 -0
  227. package/dist/esm/CellHistory.js +91 -0
  228. package/dist/esm/CellHistory.js.map +1 -0
  229. package/dist/esm/CellTurn.d.ts +1071 -0
  230. package/dist/esm/CellTurn.d.ts.map +1 -0
  231. package/dist/esm/CellTurn.js +3410 -0
  232. package/dist/esm/CellTurn.js.map +1 -0
  233. package/dist/esm/CellValidation.d.ts +94 -0
  234. package/dist/esm/CellValidation.d.ts.map +1 -0
  235. package/dist/esm/CellValidation.js +335 -0
  236. package/dist/esm/CellValidation.js.map +1 -0
  237. package/dist/esm/Compaction.d.ts +158 -0
  238. package/dist/esm/Compaction.d.ts.map +1 -0
  239. package/dist/esm/Compaction.js +216 -0
  240. package/dist/esm/Compaction.js.map +1 -0
  241. package/dist/esm/CompletionClaim.d.ts +801 -0
  242. package/dist/esm/CompletionClaim.d.ts.map +1 -0
  243. package/dist/esm/CompletionClaim.js +833 -0
  244. package/dist/esm/CompletionClaim.js.map +1 -0
  245. package/dist/esm/ContextWindow.d.ts +435 -0
  246. package/dist/esm/ContextWindow.d.ts.map +1 -0
  247. package/dist/esm/ContextWindow.js +427 -0
  248. package/dist/esm/ContextWindow.js.map +1 -0
  249. package/dist/esm/EngineLike.d.ts +546 -0
  250. package/dist/esm/EngineLike.d.ts.map +1 -0
  251. package/dist/esm/EngineLike.js +218 -0
  252. package/dist/esm/EngineLike.js.map +1 -0
  253. package/dist/esm/ExternalTranscript.d.ts +349 -0
  254. package/dist/esm/ExternalTranscript.d.ts.map +1 -0
  255. package/dist/esm/ExternalTranscript.js +985 -0
  256. package/dist/esm/ExternalTranscript.js.map +1 -0
  257. package/dist/esm/FailedCall.d.ts +132 -0
  258. package/dist/esm/FailedCall.d.ts.map +1 -0
  259. package/dist/esm/FailedCall.js +131 -0
  260. package/dist/esm/FailedCall.js.map +1 -0
  261. package/dist/esm/FlowBinding.d.ts +289 -0
  262. package/dist/esm/FlowBinding.d.ts.map +1 -0
  263. package/dist/esm/FlowBinding.js +376 -0
  264. package/dist/esm/FlowBinding.js.map +1 -0
  265. package/dist/esm/HarnessError.d.ts +57 -0
  266. package/dist/esm/HarnessError.d.ts.map +1 -0
  267. package/dist/esm/HarnessError.js +85 -0
  268. package/dist/esm/HarnessError.js.map +1 -0
  269. package/dist/esm/Judgement.d.ts +289 -0
  270. package/dist/esm/Judgement.d.ts.map +1 -0
  271. package/dist/esm/Judgement.js +305 -0
  272. package/dist/esm/Judgement.js.map +1 -0
  273. package/dist/esm/Monitor.d.ts +374 -0
  274. package/dist/esm/Monitor.d.ts.map +1 -0
  275. package/dist/esm/Monitor.js +370 -0
  276. package/dist/esm/Monitor.js.map +1 -0
  277. package/dist/esm/NarrowedCheck.d.ts +523 -0
  278. package/dist/esm/NarrowedCheck.d.ts.map +1 -0
  279. package/dist/esm/NarrowedCheck.js +612 -0
  280. package/dist/esm/NarrowedCheck.js.map +1 -0
  281. package/dist/esm/Notifications.d.ts +42 -0
  282. package/dist/esm/Notifications.d.ts.map +1 -0
  283. package/dist/esm/Notifications.js +215 -0
  284. package/dist/esm/Notifications.js.map +1 -0
  285. package/dist/esm/Plan.d.ts +127 -0
  286. package/dist/esm/Plan.d.ts.map +1 -0
  287. package/dist/esm/Plan.js +97 -0
  288. package/dist/esm/Plan.js.map +1 -0
  289. package/dist/esm/QuickJSSandbox.d.ts +151 -0
  290. package/dist/esm/QuickJSSandbox.d.ts.map +1 -0
  291. package/dist/esm/QuickJSSandbox.js +1364 -0
  292. package/dist/esm/QuickJSSandbox.js.map +1 -0
  293. package/dist/esm/Relevance.d.ts +213 -0
  294. package/dist/esm/Relevance.d.ts.map +1 -0
  295. package/dist/esm/Relevance.js +254 -0
  296. package/dist/esm/Relevance.js.map +1 -0
  297. package/dist/esm/Sandbox.d.ts +637 -0
  298. package/dist/esm/Sandbox.d.ts.map +1 -0
  299. package/dist/esm/Sandbox.js +464 -0
  300. package/dist/esm/Sandbox.js.map +1 -0
  301. package/dist/esm/Steering.d.ts +464 -0
  302. package/dist/esm/Steering.d.ts.map +1 -0
  303. package/dist/esm/Steering.js +193 -0
  304. package/dist/esm/Steering.js.map +1 -0
  305. package/dist/esm/StructuredOutput.d.ts +252 -0
  306. package/dist/esm/StructuredOutput.d.ts.map +1 -0
  307. package/dist/esm/StructuredOutput.js +430 -0
  308. package/dist/esm/StructuredOutput.js.map +1 -0
  309. package/dist/esm/Sufficiency.d.ts +195 -0
  310. package/dist/esm/Sufficiency.d.ts.map +1 -0
  311. package/dist/esm/Sufficiency.js +207 -0
  312. package/dist/esm/Sufficiency.js.map +1 -0
  313. package/dist/esm/Supervisor.d.ts +719 -0
  314. package/dist/esm/Supervisor.d.ts.map +1 -0
  315. package/dist/esm/Supervisor.js +575 -0
  316. package/dist/esm/Supervisor.js.map +1 -0
  317. package/dist/esm/Tokens.d.ts +86 -0
  318. package/dist/esm/Tokens.d.ts.map +1 -0
  319. package/dist/esm/Tokens.js +92 -0
  320. package/dist/esm/Tokens.js.map +1 -0
  321. package/dist/esm/Transcript.d.ts +171 -0
  322. package/dist/esm/Transcript.d.ts.map +1 -0
  323. package/dist/esm/Transcript.js +424 -0
  324. package/dist/esm/Transcript.js.map +1 -0
  325. package/dist/esm/TruncatedOutput.d.ts +186 -0
  326. package/dist/esm/TruncatedOutput.d.ts.map +1 -0
  327. package/dist/esm/TruncatedOutput.js +257 -0
  328. package/dist/esm/TruncatedOutput.js.map +1 -0
  329. package/dist/esm/UnmovedTree.d.ts +113 -0
  330. package/dist/esm/UnmovedTree.d.ts.map +1 -0
  331. package/dist/esm/UnmovedTree.js +90 -0
  332. package/dist/esm/UnmovedTree.js.map +1 -0
  333. package/dist/esm/UnresolvedFailure.d.ts +196 -0
  334. package/dist/esm/UnresolvedFailure.d.ts.map +1 -0
  335. package/dist/esm/UnresolvedFailure.js +218 -0
  336. package/dist/esm/UnresolvedFailure.js.map +1 -0
  337. package/dist/esm/VacuousVerification.d.ts +237 -0
  338. package/dist/esm/VacuousVerification.d.ts.map +1 -0
  339. package/dist/esm/VacuousVerification.js +245 -0
  340. package/dist/esm/VacuousVerification.js.map +1 -0
  341. package/dist/esm/VariablesPanel.d.ts +117 -0
  342. package/dist/esm/VariablesPanel.d.ts.map +1 -0
  343. package/dist/esm/VariablesPanel.js +142 -0
  344. package/dist/esm/VariablesPanel.js.map +1 -0
  345. package/dist/esm/index.d.ts +172 -0
  346. package/dist/esm/index.d.ts.map +1 -0
  347. package/dist/esm/index.js +172 -0
  348. package/dist/esm/index.js.map +1 -0
  349. package/dist/esm/internal/bytes.d.ts +36 -0
  350. package/dist/esm/internal/bytes.d.ts.map +1 -0
  351. package/dist/esm/internal/bytes.js +70 -0
  352. package/dist/esm/internal/bytes.js.map +1 -0
  353. package/dist/esm/internal/cellPrompt.d.ts +122 -0
  354. package/dist/esm/internal/cellPrompt.d.ts.map +1 -0
  355. package/dist/esm/internal/cellPrompt.js +276 -0
  356. package/dist/esm/internal/cellPrompt.js.map +1 -0
  357. package/dist/esm/internal/compactable.d.ts +44 -0
  358. package/dist/esm/internal/compactable.d.ts.map +1 -0
  359. package/dist/esm/internal/compactable.js +71 -0
  360. package/dist/esm/internal/compactable.js.map +1 -0
  361. package/dist/esm/internal/compactionMarks.d.ts +278 -0
  362. package/dist/esm/internal/compactionMarks.d.ts.map +1 -0
  363. package/dist/esm/internal/compactionMarks.js +317 -0
  364. package/dist/esm/internal/compactionMarks.js.map +1 -0
  365. package/dist/esm/internal/demandText.d.ts +95 -0
  366. package/dist/esm/internal/demandText.d.ts.map +1 -0
  367. package/dist/esm/internal/demandText.js +128 -0
  368. package/dist/esm/internal/demandText.js.map +1 -0
  369. package/dist/esm/internal/elide.d.ts +109 -0
  370. package/dist/esm/internal/elide.d.ts.map +1 -0
  371. package/dist/esm/internal/elide.js +123 -0
  372. package/dist/esm/internal/elide.js.map +1 -0
  373. package/dist/esm/internal/frame.d.ts +463 -0
  374. package/dist/esm/internal/frame.d.ts.map +1 -0
  375. package/dist/esm/internal/frame.js +861 -0
  376. package/dist/esm/internal/frame.js.map +1 -0
  377. package/dist/esm/internal/nonNegativeSafeInt.d.ts +20 -0
  378. package/dist/esm/internal/nonNegativeSafeInt.d.ts.map +1 -0
  379. package/dist/esm/internal/nonNegativeSafeInt.js +20 -0
  380. package/dist/esm/internal/nonNegativeSafeInt.js.map +1 -0
  381. package/dist/esm/internal/paidUsage.d.ts +52 -0
  382. package/dist/esm/internal/paidUsage.d.ts.map +1 -0
  383. package/dist/esm/internal/paidUsage.js +72 -0
  384. package/dist/esm/internal/paidUsage.js.map +1 -0
  385. package/dist/esm/internal/printChannel.d.ts +233 -0
  386. package/dist/esm/internal/printChannel.d.ts.map +1 -0
  387. package/dist/esm/internal/printChannel.js +376 -0
  388. package/dist/esm/internal/printChannel.js.map +1 -0
  389. package/dist/esm/internal/printsObservation.d.ts +26 -0
  390. package/dist/esm/internal/printsObservation.d.ts.map +1 -0
  391. package/dist/esm/internal/printsObservation.js +29 -0
  392. package/dist/esm/internal/printsObservation.js.map +1 -0
  393. package/dist/esm/internal/refusal.d.ts +40 -0
  394. package/dist/esm/internal/refusal.d.ts.map +1 -0
  395. package/dist/esm/internal/refusal.js +47 -0
  396. package/dist/esm/internal/refusal.js.map +1 -0
  397. package/dist/esm/internal/supervision.d.ts +174 -0
  398. package/dist/esm/internal/supervision.d.ts.map +1 -0
  399. package/dist/esm/internal/supervision.js +485 -0
  400. package/dist/esm/internal/supervision.js.map +1 -0
  401. package/dist/esm/internal/unfinishedWork.d.ts +99 -0
  402. package/dist/esm/internal/unfinishedWork.d.ts.map +1 -0
  403. package/dist/esm/internal/unfinishedWork.js +85 -0
  404. package/dist/esm/internal/unfinishedWork.js.map +1 -0
  405. package/dist/esm/internal/unobservedCall.d.ts +112 -0
  406. package/dist/esm/internal/unobservedCall.d.ts.map +1 -0
  407. package/dist/esm/internal/unobservedCall.js +501 -0
  408. package/dist/esm/internal/unobservedCall.js.map +1 -0
  409. package/dist/esm/internal/untrustedData.d.ts +14 -0
  410. package/dist/esm/internal/untrustedData.d.ts.map +1 -0
  411. package/dist/esm/internal/untrustedData.js +15 -0
  412. package/dist/esm/internal/untrustedData.js.map +1 -0
  413. package/docs/README.md +129 -0
  414. package/docs/api.md +1869 -0
  415. package/docs/concepts.md +238 -0
  416. package/docs/external-transcripts.md +245 -0
  417. package/docs/guides/bind-flows.md +167 -0
  418. package/docs/guides/drive-the-loop.md +265 -0
  419. package/docs/guides/run-cells.md +262 -0
  420. package/docs/guides/workerd.md +144 -0
  421. package/docs/installation.md +69 -0
  422. package/docs/quickstart.md +121 -0
  423. package/docs/reference.md +954 -0
  424. package/docs/troubleshooting.md +177 -0
  425. package/package.json +463 -3
  426. package/src/AgentEvent.ts +1772 -0
  427. package/src/CallLedger.ts +560 -0
  428. package/src/Cell.ts +926 -0
  429. package/src/CellCalls.ts +198 -0
  430. package/src/CellHistory.ts +128 -0
  431. package/src/CellTurn.ts +4450 -0
  432. package/src/CellValidation.ts +382 -0
  433. package/src/Compaction.ts +330 -0
  434. package/src/CompletionClaim.ts +1013 -0
  435. package/src/ContextWindow.ts +669 -0
  436. package/src/EngineLike.ts +614 -0
  437. package/src/ExternalTranscript.ts +1142 -0
  438. package/src/FailedCall.ts +163 -0
  439. package/src/FlowBinding.ts +603 -0
  440. package/src/HarnessError.ts +98 -0
  441. package/src/Judgement.ts +526 -0
  442. package/src/Monitor.ts +579 -0
  443. package/src/NarrowedCheck.ts +694 -0
  444. package/src/Notifications.ts +262 -0
  445. package/src/Plan.ts +113 -0
  446. package/src/QuickJSSandbox.ts +1557 -0
  447. package/src/Relevance.ts +352 -0
  448. package/src/Sandbox.ts +908 -0
  449. package/src/Steering.ts +405 -0
  450. package/src/StructuredOutput.ts +484 -0
  451. package/src/Sufficiency.ts +247 -0
  452. package/src/Supervisor.ts +798 -0
  453. package/src/Tokens.ts +108 -0
  454. package/src/Transcript.ts +513 -0
  455. package/src/TruncatedOutput.ts +297 -0
  456. package/src/UnmovedTree.ts +121 -0
  457. package/src/UnresolvedFailure.ts +240 -0
  458. package/src/VacuousVerification.ts +280 -0
  459. package/src/VariablesPanel.ts +165 -0
  460. package/src/index.ts +204 -0
  461. package/src/internal/bytes.ts +70 -0
  462. package/src/internal/cellPrompt.ts +337 -0
  463. package/src/internal/compactable.ts +76 -0
  464. package/src/internal/compactionMarks.ts +454 -0
  465. package/src/internal/demandText.ts +145 -0
  466. package/src/internal/elide.ts +130 -0
  467. package/src/internal/frame.ts +1178 -0
  468. package/src/internal/nonNegativeSafeInt.ts +24 -0
  469. package/src/internal/paidUsage.ts +90 -0
  470. package/src/internal/printChannel.ts +434 -0
  471. package/src/internal/printsObservation.ts +31 -0
  472. package/src/internal/refusal.ts +53 -0
  473. package/src/internal/supervision.ts +652 -0
  474. package/src/internal/unfinishedWork.ts +123 -0
  475. package/src/internal/unobservedCall.ts +536 -0
  476. package/src/internal/untrustedData.ts +19 -0
@@ -0,0 +1,2618 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var CellTurn_exports = {};
30
+ __export(CellTurn_exports, {
31
+ State: () => State,
32
+ defaultClaimDemands: () => defaultClaimDemands,
33
+ defaultMaxCheckpoints: () => defaultMaxCheckpoints,
34
+ defaultMaxFrames: () => defaultMaxFrames,
35
+ defaultModelCallMs: () => defaultModelCallMs,
36
+ defaultNarrowingDemands: () => defaultNarrowingDemands,
37
+ defaultReadOnlyFrames: () => defaultReadOnlyFrames,
38
+ defaultRepeatFrames: () => defaultRepeatFrames,
39
+ defaultRevalidations: () => defaultRevalidations,
40
+ defaultUnmovedDemands: () => defaultUnmovedDemands,
41
+ defaultUnresolvedDemands: () => defaultUnresolvedDemands,
42
+ instructionsSegment: () => instructionsSegment,
43
+ make: () => make,
44
+ memorySegment: () => memorySegment,
45
+ modelCallMsFor: () => modelCallMsFor,
46
+ run: () => run,
47
+ teach: () => teach
48
+ });
49
+ module.exports = __toCommonJS(CellTurn_exports);
50
+ var import_core = require("@smthrs/core");
51
+ var Digest = __toESM(require("@smthrs/core/Digest"), 1);
52
+ var Fault = __toESM(require("@smthrs/flow/Fault"), 1);
53
+ var import_kernel = require("@smthrs/kernel");
54
+ var import_model = require("@smthrs/model");
55
+ var Pricing = __toESM(require("@smthrs/model/Pricing"), 1);
56
+ var import_registry = require("@smthrs/registry");
57
+ var import_effect = require("effect");
58
+ var AgentEvent = __toESM(require("./AgentEvent.js"), 1);
59
+ var CallLedger = __toESM(require("./CallLedger.js"), 1);
60
+ var Cell = __toESM(require("./Cell.js"), 1);
61
+ var CellHistory = __toESM(require("./CellHistory.js"), 1);
62
+ var CellValidation = __toESM(require("./CellValidation.js"), 1);
63
+ var Compaction = __toESM(require("./Compaction.js"), 1);
64
+ var CompletionClaim = __toESM(require("./CompletionClaim.js"), 1);
65
+ var ContextWindow = __toESM(require("./ContextWindow.js"), 1);
66
+ var EngineLike = __toESM(require("./EngineLike.js"), 1);
67
+ var FailedCall = __toESM(require("./FailedCall.js"), 1);
68
+ var import_HarnessError = require("./HarnessError.js");
69
+ var cellPrompt = __toESM(require("./internal/cellPrompt.js"), 1);
70
+ var import_compactable = require("./internal/compactable.js");
71
+ var compactionMarks = __toESM(require("./internal/compactionMarks.js"), 1);
72
+ var elide = __toESM(require("./internal/elide.js"), 1);
73
+ var Frame = __toESM(require("./internal/frame.js"), 1);
74
+ var import_nonNegativeSafeInt = require("./internal/nonNegativeSafeInt.js");
75
+ var import_paidUsage = require("./internal/paidUsage.js");
76
+ var import_printsObservation = require("./internal/printsObservation.js");
77
+ var import_refusal = require("./internal/refusal.js");
78
+ var Supervision = __toESM(require("./internal/supervision.js"), 1);
79
+ var import_untrustedData = require("./internal/untrustedData.js");
80
+ var Judgement = __toESM(require("./Judgement.js"), 1);
81
+ var Monitor = __toESM(require("./Monitor.js"), 1);
82
+ var NarrowedCheck = __toESM(require("./NarrowedCheck.js"), 1);
83
+ var Relevance = __toESM(require("./Relevance.js"), 1);
84
+ var Sandbox = __toESM(require("./Sandbox.js"), 1);
85
+ var Steering = __toESM(require("./Steering.js"), 1);
86
+ var Sufficiency = __toESM(require("./Sufficiency.js"), 1);
87
+ var Supervisor = __toESM(require("./Supervisor.js"), 1);
88
+ var import_Transcript = require("./Transcript.js");
89
+ var TruncatedOutput = __toESM(require("./TruncatedOutput.js"), 1);
90
+ var UnresolvedFailure = __toESM(require("./UnresolvedFailure.js"), 1);
91
+ var VariablesPanel = __toESM(require("./VariablesPanel.js"), 1);
92
+ const repeatedFailureTag = "/harness/CellTurn/RepeatedFailure";
93
+ Fault.register(repeatedFailureTag, "factory");
94
+ const defaultMaxFrames = 100;
95
+ const defaultReadOnlyFrames = 12;
96
+ const defaultModelCallMs = 3e5;
97
+ const modelCallMsFor = (effort) => {
98
+ switch (effort) {
99
+ case "xhigh":
100
+ case "max":
101
+ return 18e5;
102
+ case "high":
103
+ return 9e5;
104
+ default:
105
+ return defaultModelCallMs;
106
+ }
107
+ };
108
+ const defaultRepeatFrames = 4;
109
+ const defaultNarrowingDemands = 1;
110
+ const defaultUnmovedDemands = 1;
111
+ const defaultUnresolvedDemands = 1;
112
+ const defaultClaimDemands = 3;
113
+ const defaultRevalidations = 1;
114
+ const defaultMaxCheckpoints = 8;
115
+ const MaxFrames = import_nonNegativeSafeInt.NonNegativeSafeInt.pipe(
116
+ import_effect.Schema.withConstructorDefault(import_effect.Effect.succeed(defaultMaxFrames)),
117
+ import_effect.Schema.withDecodingDefaultKey(import_effect.Effect.succeed(defaultMaxFrames))
118
+ );
119
+ const ContextWindowTokens = import_nonNegativeSafeInt.NonNegativeSafeInt.pipe(
120
+ import_effect.Schema.withConstructorDefault(import_effect.Effect.succeed(0)),
121
+ import_effect.Schema.withDecodingDefaultKey(import_effect.Effect.succeed(0))
122
+ );
123
+ const eventType = AgentEvent.eventType;
124
+ class State extends import_effect.Schema.Class("flows/harness/CellTurn/State")({
125
+ session: import_effect.Schema.String,
126
+ /** Missing versions decode as legacy so resume refuses before any model call. */
127
+ journalVersion: import_effect.Schema.Number.pipe(
128
+ import_effect.Schema.withConstructorDefault(import_effect.Effect.succeed(import_Transcript.journalVersion)),
129
+ import_effect.Schema.withDecodingDefaultKey(import_effect.Effect.succeed(1))
130
+ ),
131
+ frame: import_nonNegativeSafeInt.NonNegativeSafeInt,
132
+ maxFrames: MaxFrames,
133
+ /**
134
+ * Every name the realm holds, with the frame that last bound it.
135
+ *
136
+ * Freshness is a property of the run: the frame that reads a name is rarely
137
+ * the frame that bound it, and "how old is this" cannot be recovered from the
138
+ * realm itself. See `VariablesPanel`.
139
+ */
140
+ panel: VariablesPanel.Ledger,
141
+ seat: import_effect.Schema.String,
142
+ modelParams: import_model.ModelRequest.GenerationParams,
143
+ layers: import_effect.Schema.Array(import_effect.Schema.String),
144
+ capabilityEnvelope: import_effect.Schema.Array(import_kernel.Capability.CapabilityPattern),
145
+ placement: import_effect.Schema.Option(import_registry.Descriptor.Placement),
146
+ contextWindow: ContextWindow.ContextWindow,
147
+ contextWindowTokens: ContextWindowTokens,
148
+ /**
149
+ * Consecutive read-only frames this run may spend before the controller
150
+ * intervenes. Zero disarms the cap, which is what a conversational run gets.
151
+ */
152
+ readOnlyCap: import_nonNegativeSafeInt.NonNegativeSafeInt.pipe(
153
+ import_effect.Schema.withConstructorDefault(import_effect.Effect.succeed(0)),
154
+ import_effect.Schema.withDecodingDefaultKey(import_effect.Effect.succeed(0))
155
+ ),
156
+ /**
157
+ * Wall-clock milliseconds one model call may spend. Zero disarms the budget.
158
+ *
159
+ * Carried in controller state, and handed to the engine on every sealed
160
+ * step, so the value journaled in `discipline-armed` is the value enforced.
161
+ * See {@link defaultModelCallMs} for where the number comes from.
162
+ */
163
+ modelCallMs: import_nonNegativeSafeInt.NonNegativeSafeInt.pipe(
164
+ import_effect.Schema.withConstructorDefault(import_effect.Effect.succeed(defaultModelCallMs)),
165
+ import_effect.Schema.withDecodingDefaultKey(import_effect.Effect.succeed(defaultModelCallMs))
166
+ ),
167
+ /**
168
+ * Whether {@link State.modelCallMs} was left to the effort's default, so a
169
+ * steered effort moves it. A ceiling the host chose stays through every
170
+ * steer, even one numerically equal to some effort's default. A state
171
+ * decoded from a journal that predates the flag keeps its ceiling.
172
+ */
173
+ modelCallMsFollowsEffort: import_effect.Schema.Boolean.pipe(
174
+ import_effect.Schema.withConstructorDefault(import_effect.Effect.succeed(false)),
175
+ import_effect.Schema.withDecodingDefaultKey(import_effect.Effect.succeed(false))
176
+ ),
177
+ /**
178
+ * Stalled frames settled since the last frame that changed the workspace.
179
+ *
180
+ * Before the run's first write every read-only frame counts: the instance
181
+ * the cap was built for read for 100 frames, made 132 calls and edited
182
+ * nothing. After it, a read-only frame counts only when it stalls, settling
183
+ * no call this run had not already issued: a cell that only printed what the
184
+ * realm holds, a raise, a rejected cell, or a frame that re-asked old
185
+ * questions. A frame that settled a new call holds the count where it was,
186
+ * because a probe of work that exists is debugging. Terminal-Bench 4.0's
187
+ * mp-checkpoint-consolidation needed 36 read-only probes in a row after its
188
+ * first write, and counting them stopped the run at 24 (2026-09-24).
189
+ * Re-asking is still bounded, by {@link State.repeatFrames}.
190
+ *
191
+ * Changed-ness is measured as well as declared: the controller compares the
192
+ * observation the previous frame closed on ({@link State.workspace}) against
193
+ * the one this frame closes on, and a difference is a mutation whoever
194
+ * performed it. The measurement is what a frame's calls cannot say; it is
195
+ * never what overrules them. A frame is read-only when nothing declared a
196
+ * write *and* no complete measurement saw one, because a measurement is
197
+ * rooted, pruned and bounded, and the paths it does not cover are not
198
+ * evidence that a run stopped working.
199
+ *
200
+ * It used to count frames since the last call that *declared* a write, and
201
+ * the difference is not academic. `bash` declares no write set at all — its
202
+ * registry envelope is the conservative empty one and an unhermetic
203
+ * invocation carries no `writes` key, because a shell command's effects do
204
+ * not travel through any boundary the harness can read. On the SWE-bench
205
+ * pytest instance a frame ran `git show <base>:src/_pytest/python.py >
206
+ * src/_pytest/python.py`, destroyed the fix the run had landed six frames
207
+ * earlier, and was counted as read-only; the whole wave made 41 shell calls
208
+ * and not one of them declared a write, so nothing in the harness saw a
209
+ * single one of them.
210
+ *
211
+ * Declared writes are still what the capability envelope is enforced
212
+ * against, still what decides whether the truncated-write refusal applies to
213
+ * a call, still enough on their own to clear this counter, and still
214
+ * journaled beside the measured answer as `declaredWrites`. This is
215
+ * accounting, not permission. A host that measures nothing, or measures only
216
+ * a prefix of its tree, keeps the old rule, and `MutationObserved.basis`
217
+ * says which.
218
+ */
219
+ readOnlyFrames: import_nonNegativeSafeInt.NonNegativeSafeInt.pipe(
220
+ import_effect.Schema.withConstructorDefault(import_effect.Effect.succeed(0)),
221
+ import_effect.Schema.withDecodingDefaultKey(import_effect.Effect.succeed(0))
222
+ ),
223
+ /**
224
+ * Frames the demand stays silent for, bought by an accepted justification.
225
+ *
226
+ * A justification is an escape hatch with a price: it buys `readOnlyCap`
227
+ * quiet frames and never resets {@link State.readOnlyFrames}, so a run that
228
+ * keeps justifying still reaches the hard stop at twice the cap.
229
+ *
230
+ * Only an *answer* buys it. A justification is accepted when the frame that
231
+ * wrote it was handed the demand — {@link State.pendingReadOnlyDemand} is
232
+ * set — and a justification volunteered by a frame that was asked nothing is
233
+ * recorded on its transition and buys zero frames. Otherwise a run can spend
234
+ * the whole allowance without the demand ever being issued: see the
235
+ * read-only intervention in `internal/frame.ts` `discipline`.
236
+ */
237
+ readOnlyGrace: import_nonNegativeSafeInt.NonNegativeSafeInt.pipe(
238
+ import_effect.Schema.withConstructorDefault(import_effect.Effect.succeed(0)),
239
+ import_effect.Schema.withDecodingDefaultKey(import_effect.Effect.succeed(0))
240
+ ),
241
+ /** Intervention waiting to be resolved by the next frame. */
242
+ pendingReadOnlyDemand: import_effect.Schema.optional(import_effect.Schema.Struct({
243
+ streak: import_nonNegativeSafeInt.NonNegativeSafeInt,
244
+ cap: import_nonNegativeSafeInt.NonNegativeSafeInt
245
+ })),
246
+ /**
247
+ * The newest call ordinal a state section already in the window listed.
248
+ *
249
+ * Every frame's section stays in the window (see `frozen`), so the next one
250
+ * lists only calls settled after this. Zero after a compaction, which may
251
+ * have replaced the sections that listed them, and on a state decoded from
252
+ * an older journal, whose window holds none.
253
+ */
254
+ ledgerShown: import_nonNegativeSafeInt.NonNegativeSafeInt.pipe(
255
+ import_effect.Schema.withConstructorDefault(import_effect.Effect.succeed(0)),
256
+ import_effect.Schema.withDecodingDefaultKey(import_effect.Effect.succeed(0))
257
+ ),
258
+ /**
259
+ * Whether the window already ends with this frame's state section.
260
+ *
261
+ * A frame that continues writes the next frame's section into the segment it
262
+ * just appended, so a supervisor reading of that segment reads it whole (see
263
+ * `frozen`). A run's first frame, and a state decoded from an older journal,
264
+ * has none yet, and the frame writes it when it opens.
265
+ */
266
+ sectioned: import_effect.Schema.Boolean.pipe(
267
+ import_effect.Schema.withConstructorDefault(import_effect.Effect.succeed(false)),
268
+ import_effect.Schema.withDecodingDefaultKey(import_effect.Effect.succeed(false))
269
+ ),
270
+ /**
271
+ * How many messages at the end of the window are interventions the next
272
+ * frame is being asked to answer.
273
+ *
274
+ * The controller's own asks, which are the read-only demand, the repeat
275
+ * redirect, the sufficiency observation and the completion review, are
276
+ * appended to the transcript when the frame that earned them closes. The block of run memory
277
+ * is written into the window when the next frame opens, so without this count the ask
278
+ * was always the second-to-last message and a roster of variable names was
279
+ * always the last. {@link stateSection} says what that cost.
280
+ *
281
+ * It is a count rather than a flag because a frame can earn several asks at
282
+ * once, and it is state rather than something recomputed from the window
283
+ * because the messages carry no mark that says which of them is an ask.
284
+ * Zero on a state decoded from an older journal, which puts the block last
285
+ * exactly as that run had it.
286
+ */
287
+ interventions: import_nonNegativeSafeInt.NonNegativeSafeInt.pipe(
288
+ import_effect.Schema.withConstructorDefault(import_effect.Effect.succeed(0)),
289
+ import_effect.Schema.withDecodingDefaultKey(import_effect.Effect.succeed(0))
290
+ ),
291
+ /**
292
+ * Consecutive repeat-observation frames this run may spend before the
293
+ * controller redirects it. Zero disarms the demand.
294
+ *
295
+ * Armed separately from {@link State.readOnlyCap} because the two answer
296
+ * different stalls. The read-only cap watches a run that has written
297
+ * nothing; this watches a run that has written something and keeps
298
+ * confirming it. A run can be in both states at once, and telling one that
299
+ * has already edited to "land an edit" sends it back to the file it is
300
+ * already staring at.
301
+ */
302
+ repeatCap: import_nonNegativeSafeInt.NonNegativeSafeInt.pipe(
303
+ import_effect.Schema.withConstructorDefault(import_effect.Effect.succeed(defaultRepeatFrames)),
304
+ import_effect.Schema.withDecodingDefaultKey(import_effect.Effect.succeed(defaultRepeatFrames))
305
+ ),
306
+ /** Consecutive frames with the same uncorrected cell or call failure. */
307
+ failureFrames: import_nonNegativeSafeInt.NonNegativeSafeInt.pipe(
308
+ import_effect.Schema.withConstructorDefault(import_effect.Effect.succeed(0)),
309
+ import_effect.Schema.withDecodingDefaultKey(import_effect.Effect.succeed(0))
310
+ ),
311
+ /** Bounded identity of the failure being retried. */
312
+ failureKey: import_effect.Schema.String.pipe(
313
+ import_effect.Schema.withConstructorDefault(import_effect.Effect.succeed("")),
314
+ import_effect.Schema.withDecodingDefaultKey(import_effect.Effect.succeed(""))
315
+ ),
316
+ /**
317
+ * Consecutive frames that observed only what this run had already observed.
318
+ *
319
+ * A frame counts when it issued at least one call, issued no call whose
320
+ * signature this run had not already issued, and changed nothing. A frame
321
+ * that issued no call is neither a repeat nor a break: it made no
322
+ * observation, so the counter is carried across it rather than advanced or
323
+ * cleared — a run that thinks for a frame between two identical commands has
324
+ * not stopped repeating itself, and a run planning its next move has not
325
+ * started.
326
+ */
327
+ repeatFrames: import_nonNegativeSafeInt.NonNegativeSafeInt.pipe(
328
+ import_effect.Schema.withConstructorDefault(import_effect.Effect.succeed(0)),
329
+ import_effect.Schema.withDecodingDefaultKey(import_effect.Effect.succeed(0))
330
+ ),
331
+ /**
332
+ * Signatures of the calls this run has issued, oldest first.
333
+ *
334
+ * State rather than a per-frame detail because repetition is a property of
335
+ * the run: the frame that re-runs a check is usually nowhere near the frame
336
+ * that first ran it. It carries digests and no inputs; see
337
+ * {@link signatureOf}.
338
+ */
339
+ callSignatures: import_effect.Schema.Array(import_effect.Schema.String).pipe(
340
+ import_effect.Schema.withConstructorDefault(import_effect.Effect.succeed([])),
341
+ import_effect.Schema.withDecodingDefaultKey(import_effect.Effect.succeed([]))
342
+ ),
343
+ /**
344
+ * Completions this run may have bounced for narrowed evidence. Zero disarms
345
+ * the demand.
346
+ *
347
+ * Armed separately from every other cap because it watches a different
348
+ * moment. The read-only cap and the repeat demand watch a run that is still
349
+ * working and has stopped making progress; this watches the one frame a run
350
+ * gets wrong for free — the last one, where a narrowed check is presented as
351
+ * evidence for a change it never covered. See {@link defaultNarrowingDemands}.
352
+ */
353
+ narrowingCap: import_nonNegativeSafeInt.NonNegativeSafeInt.pipe(
354
+ import_effect.Schema.withConstructorDefault(import_effect.Effect.succeed(defaultNarrowingDemands)),
355
+ import_effect.Schema.withDecodingDefaultKey(import_effect.Effect.succeed(defaultNarrowingDemands))
356
+ ),
357
+ /**
358
+ * Completions this run has already had bounced for narrowed evidence.
359
+ *
360
+ * Counted rather than flagged so the cap reads like the others, and carried
361
+ * in state so a bounce survives the frame that answers it: the run stays
362
+ * responsible for the answer, and the loop stops asking once it has asked.
363
+ */
364
+ narrowingDemands: import_nonNegativeSafeInt.NonNegativeSafeInt.pipe(
365
+ import_effect.Schema.withConstructorDefault(import_effect.Effect.succeed(0)),
366
+ import_effect.Schema.withDecodingDefaultKey(import_effect.Effect.succeed(0))
367
+ ),
368
+ /**
369
+ * Completions this run may have bounced for an unmoved tree. The demand is
370
+ * issued only for a completion the claim brake reads as unsupported, so a
371
+ * `claimCap` of zero disarms it too. Zero disarms the demand. See
372
+ * {@link defaultUnmovedDemands} and `UnmovedTree`.
373
+ */
374
+ unmovedCap: import_nonNegativeSafeInt.NonNegativeSafeInt.pipe(
375
+ import_effect.Schema.withConstructorDefault(import_effect.Effect.succeed(defaultUnmovedDemands)),
376
+ import_effect.Schema.withDecodingDefaultKey(import_effect.Effect.succeed(defaultUnmovedDemands))
377
+ ),
378
+ /** Completions this run has already had bounced for an unmoved tree. */
379
+ unmovedDemands: import_nonNegativeSafeInt.NonNegativeSafeInt.pipe(
380
+ import_effect.Schema.withConstructorDefault(import_effect.Effect.succeed(0)),
381
+ import_effect.Schema.withDecodingDefaultKey(import_effect.Effect.succeed(0))
382
+ ),
383
+ /**
384
+ * Completions this run may have bounced for a failing check it replaced
385
+ * rather than answered. Zero disarms the demand. See
386
+ * {@link defaultUnresolvedDemands} and `UnresolvedFailure`.
387
+ */
388
+ unresolvedCap: import_nonNegativeSafeInt.NonNegativeSafeInt.pipe(
389
+ import_effect.Schema.withConstructorDefault(import_effect.Effect.succeed(defaultUnresolvedDemands)),
390
+ import_effect.Schema.withDecodingDefaultKey(import_effect.Effect.succeed(defaultUnresolvedDemands))
391
+ ),
392
+ /** Completions this run has already had bounced for such a check. */
393
+ unresolvedDemands: import_nonNegativeSafeInt.NonNegativeSafeInt.pipe(
394
+ import_effect.Schema.withConstructorDefault(import_effect.Effect.succeed(0)),
395
+ import_effect.Schema.withDecodingDefaultKey(import_effect.Effect.succeed(0))
396
+ ),
397
+ /**
398
+ * Completions this run has already had bounced for a call their own cell
399
+ * failed before they were written. Capped at `FailedCall.cap`.
400
+ */
401
+ failedCallDemands: import_nonNegativeSafeInt.NonNegativeSafeInt.pipe(
402
+ import_effect.Schema.withConstructorDefault(import_effect.Effect.succeed(0)),
403
+ import_effect.Schema.withDecodingDefaultKey(import_effect.Effect.succeed(0))
404
+ ),
405
+ /**
406
+ * Completions this run has already had bounced for calls their own cell
407
+ * made and never read before completing. Capped at `UnobservedCall.cap`.
408
+ */
409
+ unobservedDemands: import_nonNegativeSafeInt.NonNegativeSafeInt.pipe(
410
+ import_effect.Schema.withConstructorDefault(import_effect.Effect.succeed(0)),
411
+ import_effect.Schema.withDecodingDefaultKey(import_effect.Effect.succeed(0))
412
+ ),
413
+ /**
414
+ * Completions this run has already had handed back for an output that did
415
+ * not fit the host's declared shape. Capped by `Input.output`.
416
+ */
417
+ outputDemands: import_nonNegativeSafeInt.NonNegativeSafeInt.pipe(
418
+ import_effect.Schema.withConstructorDefault(import_effect.Effect.succeed(0)),
419
+ import_effect.Schema.withDecodingDefaultKey(import_effect.Effect.succeed(0))
420
+ ),
421
+ /**
422
+ * Frames this run may be given to prove a claim its own record does not
423
+ * support. Past it an unproven claim fails the run rather than standing.
424
+ * Zero disarms the brake. See {@link defaultClaimDemands} and
425
+ * `CompletionClaim`.
426
+ */
427
+ claimCap: import_nonNegativeSafeInt.NonNegativeSafeInt.pipe(
428
+ import_effect.Schema.withConstructorDefault(import_effect.Effect.succeed(defaultClaimDemands)),
429
+ import_effect.Schema.withDecodingDefaultKey(import_effect.Effect.succeed(defaultClaimDemands))
430
+ ),
431
+ /** Completions this run has already had bounced for such a claim. */
432
+ claimDemands: import_nonNegativeSafeInt.NonNegativeSafeInt.pipe(
433
+ import_effect.Schema.withConstructorDefault(import_effect.Effect.succeed(0)),
434
+ import_effect.Schema.withDecodingDefaultKey(import_effect.Effect.succeed(0))
435
+ ),
436
+ /**
437
+ * Trees this run may pin with `ctx.checkpoint()`. Zero disarms minting.
438
+ *
439
+ * See {@link defaultMaxCheckpoints}. `ctx.base` is not minted and is
440
+ * unaffected by this.
441
+ */
442
+ checkpointCap: import_nonNegativeSafeInt.NonNegativeSafeInt.pipe(
443
+ import_effect.Schema.withConstructorDefault(import_effect.Effect.succeed(defaultMaxCheckpoints)),
444
+ import_effect.Schema.withDecodingDefaultKey(import_effect.Effect.succeed(defaultMaxCheckpoints))
445
+ ),
446
+ /**
447
+ * Ids of the trees this run has already pinned, oldest first.
448
+ *
449
+ * Run state rather than a per-frame count because a checkpoint outlives the
450
+ * frame that minted it: the whole use is a frame taking a reading against a
451
+ * tree some earlier frame pinned, so the bound has to be the run's. The ids
452
+ * rather than a tally, because the one thing worth saying to a run that has
453
+ * reached the bound is which handles it is already holding.
454
+ */
455
+ checkpointIds: import_effect.Schema.Array(import_effect.Schema.String).pipe(
456
+ import_effect.Schema.withConstructorDefault(import_effect.Effect.succeed([])),
457
+ import_effect.Schema.withDecodingDefaultKey(import_effect.Effect.succeed([]))
458
+ ),
459
+ /**
460
+ * Provider-run tools every frame's model call may use (see
461
+ * `ModelRequest.serverTools`). Absent means none.
462
+ */
463
+ serverTools: import_effect.Schema.optionalKey(import_effect.Schema.Array(import_model.ModelRequest.ServerTool)),
464
+ /**
465
+ * Content address of the workspace this run opened on.
466
+ *
467
+ * Recorded once, from the first frame whose opening measurement covered the
468
+ * tree, and never restamped: the whole question `UnmovedTree` asks is whether
469
+ * the tree a completion describes is the tree the run was handed, and an
470
+ * origin that moved with the run could not answer it. Empty means no frame
471
+ * has produced a complete opening measurement, which makes the demand inert
472
+ * rather than wrong.
473
+ */
474
+ openingDigest: import_effect.Schema.String.pipe(
475
+ import_effect.Schema.withConstructorDefault(import_effect.Effect.succeed("")),
476
+ import_effect.Schema.withDecodingDefaultKey(import_effect.Effect.succeed(""))
477
+ ),
478
+ /**
479
+ * Checks this run has run, oldest first, each stamped with the tree it ran
480
+ * over.
481
+ *
482
+ * State rather than a per-frame detail for the same reason
483
+ * {@link State.callSignatures} is: the frame that narrows a check is nowhere
484
+ * near the frame that first ran it. It carries the terms of each input rather
485
+ * than the input, and only for calls that declared no write — a call that
486
+ * changes the workspace is not an observation of it. See `NarrowedCheck`.
487
+ */
488
+ checks: NarrowedCheck.Ledger,
489
+ /**
490
+ * Every call this run has settled, bounded and rendered every frame.
491
+ *
492
+ * State rather than a per-frame detail because the frame that needs to see a
493
+ * result is rarely the frame that fetched it, and a cell is authored before
494
+ * any of its results exist. See `CallLedger`.
495
+ */
496
+ callLedger: CallLedger.Ledger,
497
+ /**
498
+ * Every command this run ran that reported an exit status, as the claim
499
+ * brake lists it. See `CompletionClaim.record`.
500
+ */
501
+ reported: CompletionClaim.Reported,
502
+ /**
503
+ * Checks this run has watched fail, each stamped with the epoch it failed in.
504
+ *
505
+ * Separate from {@link State.checks} because that ledger holds one entry per
506
+ * signature carrying its *latest* run: the moment a failing check is re-run
507
+ * and passes, the failure it reported is gone from it, and the failure is
508
+ * exactly half of what `Sufficiency` needs. See `Sufficiency`.
509
+ */
510
+ failures: Sufficiency.Ledger,
511
+ /**
512
+ * Frames of this run that changed the workspace.
513
+ *
514
+ * The clock `Sufficiency` orders its two halves by. A count rather than a
515
+ * digest, because the fact being established is that something changed
516
+ * between two readings, and a count says that on a host that measures nothing
517
+ * and knows only what its calls declared.
518
+ */
519
+ mutations: import_nonNegativeSafeInt.NonNegativeSafeInt.pipe(
520
+ import_effect.Schema.withConstructorDefault(import_effect.Effect.succeed(0)),
521
+ import_effect.Schema.withDecodingDefaultKey(import_effect.Effect.succeed(0))
522
+ ),
523
+ /**
524
+ * Settled writes this run recorded on trees the workspace walk never sees.
525
+ *
526
+ * A `bash` call routed into a container fingerprints that container's
527
+ * working directory either side of the command and reports a move under
528
+ * the reserved `mutated` key (`@smthrs/std/TreeFingerprint`). Counted apart
529
+ * from {@link State.mutations} because the unmoved-tree demand and the
530
+ * claim judge compare the host's two digests, and a container edit leaves
531
+ * those equal: without this count a run that did its whole task in a
532
+ * container was bounced as unmoved and then refused as "work this run never
533
+ * recorded". Measured on Terminal-Bench 4.0, 2026-09-22.
534
+ */
535
+ remoteMutations: import_nonNegativeSafeInt.NonNegativeSafeInt.pipe(
536
+ import_effect.Schema.withConstructorDefault(import_effect.Effect.succeed(0)),
537
+ import_effect.Schema.withDecodingDefaultKey(import_effect.Effect.succeed(0))
538
+ ),
539
+ /**
540
+ * Whether the sufficiency observation has already been written this run.
541
+ *
542
+ * Once, and only once: it is a statement about the record, the record only
543
+ * grows, and repeating it every frame would turn the one control that is not
544
+ * a demand into nagging. A run that is shown it and keeps working is a run
545
+ * that has decided the evidence is not enough, which is its decision to make.
546
+ */
547
+ sufficiencyStated: import_effect.Schema.Boolean.pipe(
548
+ import_effect.Schema.withConstructorDefault(import_effect.Effect.succeed(false)),
549
+ import_effect.Schema.withDecodingDefaultKey(import_effect.Effect.succeed(false))
550
+ ),
551
+ /**
552
+ * How many times one frame may answer its own unparseable cell before the
553
+ * frame ends. Zero disarms the answer, which restores the old behaviour: a
554
+ * cell that does not parse settles the frame.
555
+ *
556
+ * One, because that is what the evidence asks for. A cell that does not parse
557
+ * is answered by a re-prompt whose whole prefix — teaching, catalog,
558
+ * transcript — is byte-identical to the one just sent, so the retry is paid
559
+ * for at cached-input price plus the output it writes. Two consecutive
560
+ * unparseable answers is a model that has lost the shape rather than
561
+ * mistyped, and that is worth a fresh frame with the failure on the record.
562
+ */
563
+ revalidations: import_nonNegativeSafeInt.NonNegativeSafeInt.pipe(
564
+ import_effect.Schema.withConstructorDefault(import_effect.Effect.succeed(defaultRevalidations)),
565
+ import_effect.Schema.withDecodingDefaultKey(import_effect.Effect.succeed(defaultRevalidations))
566
+ ),
567
+ /**
568
+ * The output of the completion a completion demand handed back, if any.
569
+ *
570
+ * The demand takes a finished answer away and asks for one more frame. It is
571
+ * allowed to do that only because the run gets to answer again — so the one
572
+ * outcome it must never produce is a run that ends holding nothing. Between
573
+ * the bounce and the next completion the run can spend its last frame on a
574
+ * cell that raises, on a refused park, or on more work, and every one of
575
+ * those ends the run on {@link budgetMessage} rather than on a completion.
576
+ * Keeping the bounced output here is what makes the demand recoverable: the
577
+ * budget still ends the run, and the run's own words are still what it ends
578
+ * with. See `NarrowedCheck` for why the demand is issued at all.
579
+ *
580
+ * The measured demands and the unread-call demand keep it; the failed-call
581
+ * demand does not, and neither does a claim demand. The claim brake read the sentence
582
+ * itself and found the record against it, so restoring that sentence on the
583
+ * budget notice hands back the exact answer the brake refused: one live run
584
+ * finished `stop` with a bounced "the tests pass" over a repository whose
585
+ * test exits 1, by this route and no other. A claim demand therefore clears
586
+ * this. See `Frame.CompletionDemand.keeps`.
587
+ */
588
+ bouncedCompletion: import_effect.Schema.optional(import_effect.Schema.String),
589
+ /**
590
+ * The frame a completion demand was handed to, if one is outstanding.
591
+ *
592
+ * The five measured demands end with the same promise: what you return next
593
+ * is the answer that stands. Three of them can fire on one `complete`
594
+ * transition and each carries its own cap, so without this the frame written
595
+ * to answer one demand is judged by the next — and a run that changed nothing and displaced a
596
+ * failing check is told "no" twice about one decision, spending two frames
597
+ * and two model calls on the argument. Recorded as the frame number rather
598
+ * than as a flag because it is then self-clearing: it names one frame, and
599
+ * every frame after that one is a frame the run chose to spend.
600
+ *
601
+ * It governs whether a demand may be *issued*, not whether the claim brake
602
+ * may read. A frame that answers a measured demand and completes is read by
603
+ * the claim brake like any other completion, because an unread completion is
604
+ * the silence this package refuses; what it cannot be handed is a second
605
+ * demand. See `Frame.judgeCompletion`.
606
+ */
607
+ demandedFrame: import_effect.Schema.optional(import_nonNegativeSafeInt.NonNegativeSafeInt),
608
+ /**
609
+ * Whether a human can answer this run, which is what makes a park honorable.
610
+ *
611
+ * A park is durable waiting, and waiting only ends when somebody answers. A
612
+ * run with no approval channel has nobody to answer it, so a park there is
613
+ * not patience: it is the run abandoning a budget it still holds. False —
614
+ * the default — refuses the transition and answers it in the frame that
615
+ * returned it.
616
+ */
617
+ approvalChannel: import_effect.Schema.Boolean.pipe(
618
+ import_effect.Schema.withConstructorDefault(import_effect.Effect.succeed(false)),
619
+ import_effect.Schema.withDecodingDefaultKey(import_effect.Effect.succeed(false))
620
+ ),
621
+ /**
622
+ * The workspace as the last measured frame left it.
623
+ *
624
+ * Carried in state rather than re-measured because one measurement serves
625
+ * two frames: what a frame closes on is what the next frame opens on, and
626
+ * nothing between them touches the tree — the sealed model step in between
627
+ * only produces text. So a run pays one walk per frame, not two, and a
628
+ * resumed run replays the recorded measurement instead of walking a tree
629
+ * that has moved on.
630
+ *
631
+ * Absent means no frame has measured yet; `None` means a frame measured and
632
+ * the host reported it has nothing to measure. The two are kept apart so an
633
+ * unobservable host is asked once and then left alone, instead of paying an
634
+ * opening boundary every frame for an answer that will not change.
635
+ */
636
+ workspace: import_effect.Schema.optional(import_effect.Schema.Option(EngineLike.Observation)),
637
+ /**
638
+ * Catalog flows and skills the run-start relevance reading withheld, and
639
+ * that no call has restored since.
640
+ *
641
+ * State rather than a per-frame detail because the reading is taken once,
642
+ * at frame 0, and every later frame's `ctx.flows` is filtered by it. A call
643
+ * to one of these names is refused as `flow_withheld` and restores it from
644
+ * the next frame. See {@link Input.judged}.
645
+ */
646
+ withheldFlows: import_effect.Schema.Array(import_effect.Schema.String).pipe(
647
+ import_effect.Schema.withConstructorDefault(import_effect.Effect.succeed([])),
648
+ import_effect.Schema.withDecodingDefaultKey(import_effect.Effect.succeed([]))
649
+ ),
650
+ /**
651
+ * Keys of the memory rows the supervisor has shown this run, oldest first,
652
+ * the newest 256 kept.
653
+ *
654
+ * State rather than a supervisor detail because it is folded in from each
655
+ * recorded drain, so a replay rebuilds it, and a row shown once is never
656
+ * asked about or delivered again. See `Supervisor`.
657
+ */
658
+ memoryShown: import_effect.Schema.Array(import_effect.Schema.String).pipe(
659
+ import_effect.Schema.withConstructorDefault(import_effect.Effect.succeed([])),
660
+ import_effect.Schema.withDecodingDefaultKey(import_effect.Effect.succeed([]))
661
+ ),
662
+ /**
663
+ * Each supervisor monitor's streak, deliveries and last delivery, by id.
664
+ *
665
+ * State because it is folded in only from each recorded drain, the one
666
+ * place a reading is gated, so a replay rebuilds it and a resumed run
667
+ * keeps its cooldowns and limits. See `Monitor.gate`.
668
+ */
669
+ monitorLedger: Monitor.Ledger.pipe(
670
+ import_effect.Schema.withConstructorDefault(import_effect.Effect.succeed({})),
671
+ import_effect.Schema.withDecodingDefaultKey(import_effect.Effect.succeed({}))
672
+ ),
673
+ /**
674
+ * What the run knows of its newest transcript segments, one entry each, in
675
+ * window order: the frame that wrote it, whether it carries the person's
676
+ * messages, whether that frame changed files, the checks it ran, and Jev's
677
+ * answer about it once a supervisor reading has marked it.
678
+ *
679
+ * State because a compaction's pins and marks read it long after the frame
680
+ * that wrote a segment; each compaction keeps the entries of the segments
681
+ * it keeps. Answers are folded in only from each recorded drain, so a
682
+ * replay rebuilds them. It is aligned when it describes every transcript
683
+ * segment; a run whose state predates it is not, and compacts every
684
+ * segment into the summary, as runs did before compaction marks.
685
+ */
686
+ segmentFacts: import_effect.Schema.Array(compactionMarks.Facts).pipe(
687
+ import_effect.Schema.withConstructorDefault(import_effect.Effect.succeed([])),
688
+ import_effect.Schema.withDecodingDefaultKey(import_effect.Effect.succeed([]))
689
+ ),
690
+ /**
691
+ * The context triggers a drained supervisor reading fired, which compact the
692
+ * next frame's context whatever the budget says; empty once it has opened.
693
+ *
694
+ * State because it is folded in only from each recorded drain, so a replay
695
+ * compacts the same frame for the same cause.
696
+ */
697
+ compactionDue: import_effect.Schema.Array(AgentEvent.CompactionCause).pipe(
698
+ import_effect.Schema.withConstructorDefault(import_effect.Effect.succeed([])),
699
+ import_effect.Schema.withDecodingDefaultKey(import_effect.Effect.succeed([]))
700
+ ),
701
+ /**
702
+ * Output this run has been handed as a fragment, by digest.
703
+ *
704
+ * The ledger is state rather than a per-frame detail because a cell may store
705
+ * a truncated capture and write it a frame later. It carries no bytes; see
706
+ * `TruncatedOutput`.
707
+ */
708
+ truncatedOutputs: TruncatedOutput.Ledger
709
+ }) {
710
+ }
711
+ const advance = (state, changes) => new State({ ...state, ...changes });
712
+ const memorySegment = (text, digest) => ({
713
+ kind: "system",
714
+ zone: "prefix",
715
+ declaredDigest: digest,
716
+ content: [import_model.ModelRequest.SystemPart.make({ text })]
717
+ });
718
+ const instructionsSegment = (documents, withheld2) => ({
719
+ kind: "system",
720
+ zone: "prefix",
721
+ content: [import_model.ModelRequest.SystemPart.make({ text: Relevance.render(documents, withheld2) })]
722
+ });
723
+ const make = (options) => new State({
724
+ session: options.session,
725
+ frame: options.frame ?? 0,
726
+ maxFrames: options.maxFrames ?? defaultMaxFrames,
727
+ panel: [],
728
+ seat: options.seat,
729
+ modelParams: options.modelParams,
730
+ layers: options.layers,
731
+ capabilityEnvelope: options.capabilityEnvelope,
732
+ placement: options.placement,
733
+ contextWindow: options.contextWindow,
734
+ // The opening transcript is the host's, written before any frame: no
735
+ // person's message, no change and no check.
736
+ segmentFacts: options.contextWindow.segments.flatMap(
737
+ (segment) => segment.kind === "transcript" ? [{ frame: options.frame ?? 0, person: false, mutated: false, checks: [] }] : []
738
+ ),
739
+ contextWindowTokens: options.contextWindowTokens ?? 0,
740
+ readOnlyCap: options.readOnlyCap ?? 0,
741
+ modelCallMs: options.modelCallMs ?? modelCallMsFor(options.modelParams.reasoningEffort),
742
+ modelCallMsFollowsEffort: options.modelCallMs === void 0,
743
+ readOnlyFrames: 0,
744
+ readOnlyGrace: 0,
745
+ pendingReadOnlyDemand: void 0,
746
+ interventions: 0,
747
+ repeatCap: options.repeatCap ?? defaultRepeatFrames,
748
+ repeatFrames: 0,
749
+ failureFrames: 0,
750
+ failureKey: "",
751
+ callSignatures: [],
752
+ narrowingCap: options.narrowingCap ?? defaultNarrowingDemands,
753
+ narrowingDemands: 0,
754
+ unmovedCap: options.unmovedCap ?? defaultUnmovedDemands,
755
+ unmovedDemands: 0,
756
+ unresolvedCap: options.unresolvedCap ?? defaultUnresolvedDemands,
757
+ unresolvedDemands: 0,
758
+ failedCallDemands: 0,
759
+ unobservedDemands: 0,
760
+ outputDemands: 0,
761
+ claimCap: options.claimCap ?? defaultClaimDemands,
762
+ claimDemands: 0,
763
+ openingDigest: "",
764
+ checks: [],
765
+ callLedger: [],
766
+ reported: [],
767
+ failures: [],
768
+ mutations: 0,
769
+ remoteMutations: 0,
770
+ sufficiencyStated: false,
771
+ revalidations: options.revalidations ?? defaultRevalidations,
772
+ approvalChannel: options.approvalChannel ?? false,
773
+ workspace: void 0,
774
+ truncatedOutputs: [],
775
+ checkpointCap: options.checkpointCap ?? defaultMaxCheckpoints,
776
+ checkpointIds: [],
777
+ ...options.serverTools === void 0 || options.serverTools.length === 0 ? {} : {
778
+ serverTools: [
779
+ ...new Map(options.serverTools.map((tool) => [import_model.CanonicalJson.stringify(tool), tool])).values()
780
+ ]
781
+ }
782
+ });
783
+ const teach = (contextWindow, flows, environment, stance) => {
784
+ const projections = {};
785
+ for (const descriptor of flows) {
786
+ projections[descriptor.name] = {
787
+ ...Cell.project(descriptor),
788
+ provenance: descriptor.provenance,
789
+ path: descriptor.path
790
+ };
791
+ }
792
+ const taught = cellPrompt.make(projections, environment, stance).map(
793
+ (section) => ContextWindow.makeSegment({
794
+ kind: "system",
795
+ zone: "prefix",
796
+ declaredDigest: section.digest,
797
+ content: [import_model.ModelRequest.SystemPart.make({ text: section.text })]
798
+ })
799
+ );
800
+ return ContextWindow.make({
801
+ modelId: contextWindow.modelId,
802
+ segments: [...taught, ...contextWindow.segments],
803
+ activeTools: contextWindow.activeTools,
804
+ replaced: contextWindow.replaced
805
+ });
806
+ };
807
+ const modelIdFromSeat = (seat) => {
808
+ const separator = seat.indexOf(":");
809
+ return separator < 0 ? seat : seat.slice(separator + 1);
810
+ };
811
+ const placementFrom = (state) => import_effect.Option.match(state.placement, {
812
+ onNone: () => void 0,
813
+ onSome: (value) => {
814
+ switch (value) {
815
+ case "client":
816
+ return import_core.Placement.client();
817
+ case "local":
818
+ return import_core.Placement.local();
819
+ case "remote":
820
+ return import_core.Placement.remote();
821
+ case "sandbox":
822
+ return import_core.Placement.sandbox();
823
+ }
824
+ }
825
+ });
826
+ const keyMaterialFrom = (state, contextWindow, request) => ({
827
+ version: "flows/key-material/v2",
828
+ kind: "sealed",
829
+ body: { _tag: "ModelCall", request },
830
+ inputs: [{ _tag: "Literal", value: { contextDigest: contextWindow.digest, journalVersion: import_Transcript.journalVersion } }],
831
+ layers: [...new Set(state.layers)].sort(),
832
+ capabilities: [...new Set(state.capabilityEnvelope.map(import_kernel.Capability.format))].sort(),
833
+ effects: import_core.Effects.make({
834
+ reads: [],
835
+ writes: [],
836
+ mode: "hermetic",
837
+ onConflict: "serialize",
838
+ tier: "sealed"
839
+ }),
840
+ placement: placementFrom(state)
841
+ });
842
+ const stateSection = (state) => {
843
+ const settled = CallLedger.render(state.callLedger, state.ledgerShown);
844
+ return [
845
+ VariablesPanel.render({ ledger: state.panel, frame: state.frame - 1 }),
846
+ ...settled === void 0 ? [] : [settled]
847
+ ].join("\n\n");
848
+ };
849
+ const frozen = (contextWindow, state) => {
850
+ try {
851
+ ContextWindow.render(contextWindow);
852
+ return import_effect.Result.succeed(withSection(contextWindow, state));
853
+ } catch (cause) {
854
+ return import_effect.Result.fail(
855
+ new import_HarnessError.HarnessError({ code: "render_failed", message: "Unable to render the context window", cause })
856
+ );
857
+ }
858
+ };
859
+ const withSection = (contextWindow, state) => {
860
+ const section = import_model.ModelRequest.Message.user(stateSection(state));
861
+ const segments = [...contextWindow.segments];
862
+ let asks = state.interventions;
863
+ let index = segments.length - 1;
864
+ let position = index < 0 ? 0 : segments[index].content.length;
865
+ while (index >= 0 && asks > 0) {
866
+ const content = segments[index].content;
867
+ position = content.length;
868
+ for (let item = content.length - 1; item >= 0 && asks > 0; item--) {
869
+ if ("role" in content[item]) {
870
+ asks--;
871
+ position = item;
872
+ }
873
+ }
874
+ if (asks > 0 && index > 0) {
875
+ index--;
876
+ } else break;
877
+ }
878
+ const holder = index < 0 ? void 0 : segments[index];
879
+ if (holder === void 0 || holder.zone !== "tail") {
880
+ segments.push(ContextWindow.makeSegment({ kind: "transcript", zone: "tail", content: [section] }));
881
+ } else {
882
+ segments[index] = ContextWindow.makeSegment({
883
+ kind: holder.kind,
884
+ zone: holder.zone,
885
+ content: [...holder.content.slice(0, position), section, ...holder.content.slice(position)]
886
+ });
887
+ }
888
+ return ContextWindow.make({
889
+ modelId: contextWindow.modelId,
890
+ segments,
891
+ activeTools: contextWindow.activeTools,
892
+ replaced: contextWindow.replaced
893
+ });
894
+ };
895
+ const requestFrom = (state, contextWindow) => {
896
+ let rendered;
897
+ try {
898
+ rendered = ContextWindow.render(contextWindow);
899
+ } catch (cause) {
900
+ return import_effect.Result.fail(
901
+ new import_HarnessError.HarnessError({
902
+ code: "render_failed",
903
+ message: "Unable to render the context window",
904
+ cause
905
+ })
906
+ );
907
+ }
908
+ return import_effect.Result.succeed(
909
+ import_model.ModelRequest.ModelRequest.make({
910
+ modelId: contextWindow.modelId,
911
+ system: rendered.system,
912
+ messages: rendered.messages,
913
+ // A cell-first frame never declares provider tools: the cell is the plan
914
+ // and `ctx.call` is the only invocation path.
915
+ tools: [],
916
+ toolChoice: "none",
917
+ params: state.modelParams,
918
+ // The window only grows between frames (see `frozen`), so the whole
919
+ // request is the next one's prefix and Anthropic's moving breakpoint
920
+ // sits at its end.
921
+ cacheKey: cacheKey(state, rendered.system),
922
+ // Provider-run tools are not declared tools: the model may search
923
+ // inside the call while `ctx.call` stays the only invocation path.
924
+ ...state.serverTools === void 0 ? {} : { serverTools: state.serverTools }
925
+ })
926
+ );
927
+ };
928
+ const cacheKey = (state, system) => {
929
+ const task = system.findIndex((part) => part.text.startsWith("The task for this run:\n\n"));
930
+ const prefix = task < 0 ? system : system.slice(0, task);
931
+ return `smithers-${import_model.CanonicalJson.shortHash(`${state.session}
932
+ ${prefix.map((part) => part.text).join("\n")}`)}`;
933
+ };
934
+ const assistantText = (message) => message.content.filter((part) => part.type === "text").map((part) => part.text).join("\n");
935
+ const encodePermissionRequired = import_effect.Schema.encodeSync(import_kernel.Permission.PermissionRequired);
936
+ const permissionRequired = (error) => {
937
+ if (error instanceof import_kernel.Permission.PermissionRequired) return error;
938
+ if (error instanceof import_HarnessError.HarnessError && error.cause instanceof import_kernel.Permission.PermissionRequired) return error.cause;
939
+ return import_effect.Option.getOrUndefined(
940
+ import_effect.Schema.decodeUnknownOption(import_kernel.Permission.PermissionRequired)(
941
+ error instanceof import_HarnessError.HarnessError ? error.cause : error
942
+ )
943
+ );
944
+ };
945
+ const liveCellEcho = 8192;
946
+ const deadCellEcho = 1024;
947
+ const appended = (contextWindow, assistant, messages, echo) => ContextWindow.make({
948
+ modelId: contextWindow.modelId,
949
+ segments: [
950
+ ...contextWindow.segments,
951
+ ContextWindow.makeSegment({
952
+ kind: "transcript",
953
+ zone: "tail",
954
+ content: [bounded(assistant, echo), ...messages]
955
+ })
956
+ ],
957
+ activeTools: contextWindow.activeTools,
958
+ replaced: contextWindow.replaced
959
+ });
960
+ const observedOn = (contextWindow, assistant, observation, echo) => appended(contextWindow, assistant, [import_model.ModelRequest.Message.user(observation)], echo);
961
+ const memoryShownLimit = 256;
962
+ const shownAfter = (state, drained) => drained.memory === void 0 ? {} : { memoryShown: [...state.memoryShown, ...drained.memory].slice(-memoryShownLimit) };
963
+ const ledgerAfter = (drained) => drained.monitorLedger === void 0 ? {} : { monitorLedger: drained.monitorLedger };
964
+ const marksAfter = (state, drained) => {
965
+ const due = drained.compact === void 0 ? {} : { compactionDue: drained.compact };
966
+ if (drained.marks === void 0) return due;
967
+ const answers = new Map(drained.marks.map(({ digest, ...answer }) => [digest, answer]));
968
+ const transcripts = (0, import_compactable.compactable)(state.contextWindow.segments).filter((segment) => segment.kind === "transcript");
969
+ const missing = transcripts.length - state.segmentFacts.length;
970
+ return {
971
+ segmentFacts: state.segmentFacts.map((facts, at) => {
972
+ const answer = answers.get(transcripts[at + missing].digest);
973
+ return facts.answer !== void 0 || answer === void 0 ? facts : { ...facts, answer };
974
+ }),
975
+ ...due
976
+ };
977
+ };
978
+ const carries = (drained) => drained.inserts.length > 0 || drained.seatChanges.length > 0;
979
+ const steered = (state, changes, resolve) => import_effect.Effect.gen(function* () {
980
+ let seat = state.seat;
981
+ let modelParams = state.modelParams;
982
+ for (const change of changes) {
983
+ if (change._tag === "SeatChange") seat = change.seat;
984
+ else {
985
+ modelParams = import_model.ModelRequest.GenerationParams.make({
986
+ maxTokens: modelParams.maxTokens,
987
+ temperature: modelParams.temperature,
988
+ topP: modelParams.topP,
989
+ topK: modelParams.topK,
990
+ stopSequences: modelParams.stopSequences,
991
+ thinkingBudget: modelParams.thinkingBudget,
992
+ reasoningEffort: change.thinking
993
+ });
994
+ }
995
+ }
996
+ return {
997
+ seat,
998
+ modelParams,
999
+ modelCallMs: state.modelCallMsFollowsEffort ? modelCallMsFor(modelParams.reasoningEffort) : state.modelCallMs,
1000
+ contextWindowTokens: seat === state.seat ? state.contextWindowTokens : resolve === void 0 ? import_model.ModelCatalog.contextWindowTokensFor(modelIdFromSeat(seat)) : yield* resolve(seat)
1001
+ };
1002
+ });
1003
+ const windowOn = (state, seat, context) => seat === state.seat ? context : ContextWindow.make({
1004
+ modelId: modelIdFromSeat(seat),
1005
+ segments: context.segments,
1006
+ activeTools: context.activeTools,
1007
+ replaced: context.replaced
1008
+ });
1009
+ const missedProperty = (message) => {
1010
+ const match = /reading '([^']+)'|read property '([^']+)'/i.exec(message);
1011
+ return match === null ? void 0 : match[1] ?? match[2];
1012
+ };
1013
+ const bindingPathMiss = (message, bindings) => {
1014
+ const property = missedProperty(message);
1015
+ if (property === void 0) return void 0;
1016
+ return bindings.length === 0 ? `If \`${property}\` was meant to come from a name an earlier cell bound: your realm holds no names yet.` : `If \`${property}\` was meant to come from a name an earlier cell bound, these are the names your realm holds: ${elide.head(
1017
+ bindings.map((binding) => binding.name).join(", "),
1018
+ CallLedger.width * 4,
1019
+ "the panel in the frame block lists them all"
1020
+ )}. The panel gives each one's type and size.`;
1021
+ };
1022
+ const revalidationNote = (rejection) => `${rejection.message}
1023
+
1024
+ This reply is not a frame. Nothing ran, nothing changed, and no call was made, so you are being asked again inside the same frame instead of losing it: everything above this line is already in the provider's cache, and only what you write next is paid for. Emit the corrected cell and nothing else.`;
1025
+ const bounded = (assistant, echo) => {
1026
+ const text = assistantText(assistant);
1027
+ const shortened = elide.middle(
1028
+ text,
1029
+ echo,
1030
+ "the reply is not re-read in full; the observation below names what went wrong"
1031
+ );
1032
+ if (shortened === text) return assistant;
1033
+ return import_model.ModelRequest.Message.assistant(shortened, { stopReason: assistant.stopReason });
1034
+ };
1035
+ const clip = (text, width) => elide.head(text, width, "clipped");
1036
+ const salvageSummary = 400;
1037
+ const salvageRecall = "the whole result is still under the name your cell bound it to";
1038
+ const signatureOf = (flow, input, at) => Digest.digest(import_model.CanonicalJson.stringify(at === void 0 ? [flow, input] : [flow, input, at]));
1039
+ const readOnlyCapFailure = (cap, frames) => new import_HarnessError.HarnessError({
1040
+ code: "read_only_cap",
1041
+ message: `The run spent ${frames} consecutive frames without one call that declares a write, twice its read-only budget of ${cap}. It is stopped here rather than allowed to report work it never did.`
1042
+ });
1043
+ const mutating = (descriptor, input) => {
1044
+ if (descriptor.effects.writes.length > 0) return true;
1045
+ const declared = input !== null && typeof input === "object" && !Array.isArray(input) ? input.writes : void 0;
1046
+ return Array.isArray(declared) && declared.length > 0;
1047
+ };
1048
+ const RecordedObservation = import_effect.Schema.Option(EngineLike.Observation);
1049
+ const RecordedCompletion = import_effect.Schema.Struct({
1050
+ observed: import_effect.Schema.NullOr(AgentEvent.ClaimDemanded),
1051
+ demand: import_effect.Schema.NullOr(import_effect.Schema.Struct({
1052
+ event: import_effect.Schema.Union([
1053
+ AgentEvent.UnmovedDemanded,
1054
+ AgentEvent.UnresolvedDemanded,
1055
+ AgentEvent.FailedCallDemanded,
1056
+ AgentEvent.UnobservedDemanded,
1057
+ AgentEvent.NarrowedDemanded,
1058
+ AgentEvent.NarrowOnlyDemanded,
1059
+ AgentEvent.ClaimDemanded
1060
+ ]),
1061
+ note: import_effect.Schema.String,
1062
+ keeps: import_effect.Schema.Boolean,
1063
+ spent: import_effect.Schema.Struct({
1064
+ unmovedDemands: import_effect.Schema.optionalKey(import_nonNegativeSafeInt.NonNegativeSafeInt),
1065
+ unresolvedDemands: import_effect.Schema.optionalKey(import_nonNegativeSafeInt.NonNegativeSafeInt),
1066
+ failedCallDemands: import_effect.Schema.optionalKey(import_nonNegativeSafeInt.NonNegativeSafeInt),
1067
+ unobservedDemands: import_effect.Schema.optionalKey(import_nonNegativeSafeInt.NonNegativeSafeInt),
1068
+ narrowingDemands: import_effect.Schema.optionalKey(import_nonNegativeSafeInt.NonNegativeSafeInt),
1069
+ claimDemands: import_effect.Schema.optionalKey(import_nonNegativeSafeInt.NonNegativeSafeInt)
1070
+ })
1071
+ })),
1072
+ unproven: import_effect.Schema.NullOr(import_HarnessError.HarnessError),
1073
+ // An optional key, not a nullable one: a judgement recorded before decisions
1074
+ // existed has no such member, and it must replay as a judgement with no
1075
+ // decision to report rather than fail to decode.
1076
+ decision: import_effect.Schema.optionalKey(import_effect.Schema.NullOr(AgentEvent.DecisionSettled)),
1077
+ sentenceDecision: import_effect.Schema.optionalKey(import_effect.Schema.NullOr(AgentEvent.DecisionSettled)),
1078
+ unfinishedDecision: import_effect.Schema.optionalKey(import_effect.Schema.NullOr(AgentEvent.DecisionSettled))
1079
+ });
1080
+ const witness = (engine, state, boundary, phase) => engine.record({
1081
+ name: `workspace-${phase}`,
1082
+ // The purpose is folded into the boundary as well as carried in `name`.
1083
+ // `EngineLike.record` keys on `(name, identity)` together, and the
1084
+ // production engine does; an engine that read the contract as keying on
1085
+ // identity alone would replay this frame's opening measurement as its
1086
+ // closing one, and its cell outcome as its steering drain. Folding the
1087
+ // purpose in makes the controller correct under either reading. No released
1088
+ // run database exists at 1.0.0-rc.0, so the labels are free to change now
1089
+ // and will not be again.
1090
+ identity: { session: state.session, frame: state.frame, boundary: `workspace-${phase}:${boundary}` },
1091
+ success: RecordedObservation,
1092
+ execute: engine.observe
1093
+ });
1094
+ const RecordedSnapshot = import_effect.Schema.Option(EngineLike.Snapshot);
1095
+ const pin = (engine, state, cell, ordinal, id, callMs) => engine.record({
1096
+ name: "checkpoint",
1097
+ identity: { session: state.session, frame: state.frame, boundary: `checkpoint:${cell}:${ordinal}` },
1098
+ success: RecordedSnapshot,
1099
+ // The per-call ceiling, applied INSIDE the record for the reason
1100
+ // {@link settled} applies it inside its own: a store that hung past the
1101
+ // budget left the cell told nothing was pinned while the pin itself was
1102
+ // still in flight, so the resumed frame could be handed a snapshot the
1103
+ // original attempt was told it never got. Cut off here, "nothing was
1104
+ // pinned" is what the journal holds and what every later attempt reads.
1105
+ execute: engine.capture({
1106
+ id,
1107
+ identity: { session: state.session, frame: state.frame, boundary: `checkpoint-capture:${cell}` }
1108
+ }).pipe(
1109
+ import_effect.Effect.timeoutOrElse({ duration: callMs, orElse: () => import_effect.Effect.succeed(import_effect.Option.none()) })
1110
+ )
1111
+ });
1112
+ const issued = (engine, state, cell, ordinal, callMs, flow, issue, replaying, call) => import_effect.Effect.gen(function* () {
1113
+ if (replaying) {
1114
+ return yield* engine.record({
1115
+ name: "cell-call",
1116
+ call,
1117
+ identity: { session: state.session, frame: state.frame, boundary: `cell-call:${cell}:${ordinal}` },
1118
+ success: Cell.CallResultVariant,
1119
+ execute: import_effect.Effect.fail(
1120
+ new import_HarnessError.HarnessError({
1121
+ code: "incompatible_journal",
1122
+ message: `The timed-out frame is missing settlement ${ordinal}`
1123
+ })
1124
+ )
1125
+ }).pipe(import_effect.Effect.flatMap(Cell.decodeCallResult));
1126
+ }
1127
+ const refused = engine.admit === void 0 ? void 0 : yield* engine.admit(call);
1128
+ const identity = { session: state.session, frame: state.frame, boundary: `cell-call:${cell}:${ordinal}` };
1129
+ const subject = EngineLike.callSubject(call.identity);
1130
+ const guarded = refused === void 0 ? engine.guard : void 0;
1131
+ if (guarded !== void 0) yield* guarded.admit(subject);
1132
+ const settlement = refused ?? (yield* issue.pipe(
1133
+ import_effect.Effect.timeoutOrElse({ duration: callMs, orElse: () => import_effect.Effect.succeed(Sandbox.callTimedOut(flow, callMs)) }),
1134
+ import_effect.Effect.flatMap(Cell.decodeCallResult)
1135
+ ));
1136
+ if (guarded !== void 0 && settlement.outcome === "failure" && settlement.code === "timeout") {
1137
+ yield* guarded.trip({
1138
+ source: "tool-call",
1139
+ subject,
1140
+ limitMillis: (0, import_refusal.limitOf)(settlement),
1141
+ message: settlement.message ?? `Flow ${flow} timed out.`
1142
+ });
1143
+ }
1144
+ return yield* engine.record({
1145
+ name: "cell-call",
1146
+ call,
1147
+ identity,
1148
+ success: Cell.CallResultVariant,
1149
+ execute: import_effect.Effect.succeed(settlement)
1150
+ }).pipe(import_effect.Effect.flatMap(Cell.decodeCallResult));
1151
+ });
1152
+ const RecordedFrame = import_effect.Schema.Struct({
1153
+ boundary: import_effect.Schema.optional(Sandbox.FrameBoundary),
1154
+ outcome: Cell.Outcome,
1155
+ prints: import_effect.Schema.String,
1156
+ bindings: import_effect.Schema.Array(VariablesPanel.Binding)
1157
+ });
1158
+ const minter = (state, cell, engine, minted, callMs, emit) => (mint) => import_effect.Effect.gen(function* () {
1159
+ const held = state.checkpointIds.length + minted.length;
1160
+ if (held >= state.checkpointCap) {
1161
+ return (0, import_refusal.refusal)(
1162
+ "checkpoint_exhausted",
1163
+ `This run has pinned its ${state.checkpointCap} checkpoints and nothing was pinned here. ${held === 0 ? "" : `The ones you hold are ${[...state.checkpointIds, ...minted].join(", ")}, and `}ctx.base is always the tree this run opened on.`
1164
+ );
1165
+ }
1166
+ const id = `cp-${state.frame}-${mint.ordinal}`;
1167
+ const snapshot = yield* pin(engine, state, cell.digest, mint.ordinal, id, callMs);
1168
+ if (import_effect.Option.isNone(snapshot)) {
1169
+ return (0, import_refusal.refusal)(
1170
+ "checkpoint_unavailable",
1171
+ "This host pins no trees, so nothing was checkpointed. For a baseline, run the check before your edit, then again after it."
1172
+ );
1173
+ }
1174
+ minted.push(id);
1175
+ yield* emit(
1176
+ new AgentEvent.CheckpointMinted({
1177
+ eventType: eventType.checkpointMinted,
1178
+ id: snapshot.value.id,
1179
+ ref: snapshot.value.ref,
1180
+ cell: cell.digest,
1181
+ ordinal: mint.ordinal
1182
+ })
1183
+ );
1184
+ return new Cell.CallResult({ outcome: "success", value: Cell.checkpoint(snapshot.value.id) });
1185
+ });
1186
+ const emitModelProgress = (event, emit) => event.type === "retry" ? emit(
1187
+ new AgentEvent.ModelRetried({
1188
+ eventType: eventType.modelRetried,
1189
+ attempt: event.attempt,
1190
+ code: event.code,
1191
+ delayMillis: event.delayMillis
1192
+ })
1193
+ ) : event.type === "settle" ? import_effect.Effect.void : emit(new AgentEvent.ModelDelta({ eventType: eventType.modelDelta, delta: event }));
1194
+ const invalidProbeKey = "invalidProbe";
1195
+ const invalidProbeOf = (value) => {
1196
+ if (value === null || typeof value !== "object" || Array.isArray(value)) return void 0;
1197
+ const declared = value[invalidProbeKey];
1198
+ if (declared === null || typeof declared !== "object" || Array.isArray(declared)) return void 0;
1199
+ const { message, reason } = declared;
1200
+ return typeof reason === "string" && typeof message === "string" ? { reason, message } : void 0;
1201
+ };
1202
+ const mutatedKey = "mutated";
1203
+ const mutatedOf = (value) => value !== null && typeof value === "object" && !Array.isArray(value) && value[mutatedKey] === true;
1204
+ const frameFailureMessage = (error) => {
1205
+ const row = typeof error === "object" && error !== null ? error : {};
1206
+ const said = typeof row["message"] === "string" ? row["message"].replace(/\s+/g, " ").trim() : "";
1207
+ if (said === "") return "The cell frame failed";
1208
+ const code = typeof row["code"] === "string" && row["code"] !== "" ? `${row["code"].slice(0, 64)}: ` : "";
1209
+ return `The cell frame failed: ${code}${said.slice(0, 1e3)}`;
1210
+ };
1211
+ const budgetMessage = (state) => state.bouncedCompletion === void 0 ? `The frame budget of ${state.maxFrames} is exhausted. The run stops here; the last transition was a request to continue.` : `The frame budget of ${state.maxFrames} is exhausted. This run completed once and had that completion handed back for another frame, so what it reported then stands here rather than being lost:
1212
+
1213
+ ${state.bouncedCompletion}`;
1214
+ const callHandler = (state, cell, descriptors, engine, ledger, performed, restored, tree, live, callMs, replaying, emit) => (invocation) => import_effect.Effect.gen(function* () {
1215
+ if (state.withheldFlows.includes(invocation.flow)) {
1216
+ restored.add(invocation.flow);
1217
+ return (0, import_refusal.refusal)(
1218
+ "flow_withheld",
1219
+ `Flow ${invocation.flow} was withheld for this task. It is in ctx.flows from the next frame; reissue the call.`
1220
+ );
1221
+ }
1222
+ const descriptor = descriptors.get(invocation.flow);
1223
+ if (descriptor === void 0) {
1224
+ return (0, import_refusal.refusal)("unknown_flow", `Unknown flow ${invocation.flow}. Only the flows in ctx.flows are callable.`);
1225
+ }
1226
+ if (!descriptor.modelInvocable) {
1227
+ return (0, import_refusal.refusal)("capability_refused", `Flow ${invocation.flow} is not model-invocable.`);
1228
+ }
1229
+ const envelope = import_kernel.CapabilitySet.fromPatterns(state.capabilityEnvelope);
1230
+ const refused = descriptor.capabilities.filter(
1231
+ (declared) => import_effect.Option.match(import_kernel.Capability.parse(declared), {
1232
+ onNone: () => true,
1233
+ onSome: (capability) => !import_kernel.CapabilitySet.allows(envelope, capability)
1234
+ })
1235
+ );
1236
+ if (refused.length > 0) {
1237
+ return (0, import_refusal.refusal)(
1238
+ "capability_refused",
1239
+ `Flow ${invocation.flow} needs ${refused.join(", ")}, which is outside this run's capability envelope.`
1240
+ );
1241
+ }
1242
+ const changes = mutating(descriptor, invocation.input);
1243
+ if (changes) {
1244
+ const found = TruncatedOutput.reuse(invocation.input, ledger);
1245
+ if (found !== void 0) {
1246
+ return (0, import_refusal.refusal)("truncated_write", TruncatedOutput.refusal(invocation.flow, found));
1247
+ }
1248
+ }
1249
+ let at;
1250
+ if (invocation.at !== void 0) {
1251
+ at = Cell.checkpointOf(invocation.at);
1252
+ if (at === void 0) {
1253
+ return (0, import_refusal.refusal)(
1254
+ "invalid_input",
1255
+ `The at option takes a checkpoint, which is what ctx.checkpoint() resolves with and what ctx.base is. It was given ${elide.head(import_model.CanonicalJson.stringify(invocation.at), 120, "the rest is the same shape")}.`
1256
+ );
1257
+ }
1258
+ if (changes) {
1259
+ return (0, import_refusal.refusal)(
1260
+ "checkpoint_readonly",
1261
+ `Flow ${invocation.flow} declares a write, and a checkpoint is a read-only view of a tree that has already been. Nothing was run. Make the change on the live tree, and keep at for the readings you take against ${at}.`
1262
+ );
1263
+ }
1264
+ }
1265
+ const sealed = descriptor.effects.tier === "sealed";
1266
+ const epoch = sealed && at === void 0 ? {
1267
+ frames: state.mutations,
1268
+ calls: tree.writes,
1269
+ ...tree.chain === void 0 ? {} : { writes: tree.chain },
1270
+ ...live
1271
+ } : void 0;
1272
+ const call = Cell.callOf(descriptor, {
1273
+ input: invocation.input,
1274
+ identity: new Cell.CallIdentity({
1275
+ session: state.session,
1276
+ frame: state.frame,
1277
+ cell: cell.digest,
1278
+ ordinal: invocation.ordinal,
1279
+ declaration: Cell.declarationDigest(descriptor),
1280
+ layers: [...new Set(state.layers)].sort()
1281
+ }),
1282
+ ...at === void 0 ? {} : { at },
1283
+ ...epoch === void 0 ? {} : { epoch }
1284
+ });
1285
+ performed.add(invocation.ordinal);
1286
+ if (!sealed) {
1287
+ tree.writes++;
1288
+ tree.chain = Digest.digest(
1289
+ import_model.CanonicalJson.stringify([tree.chain ?? null, signatureOf(invocation.flow, invocation.input, at)])
1290
+ );
1291
+ }
1292
+ yield* emit(new AgentEvent.CellCallStarted({ eventType: eventType.cellCallStarted, call }));
1293
+ const result = yield* issued(
1294
+ engine,
1295
+ state,
1296
+ cell.digest,
1297
+ invocation.ordinal,
1298
+ callMs,
1299
+ invocation.flow,
1300
+ // A flow that asks Jev journals its receipts into this run.
1301
+ import_effect.Effect.suspend(() => engine.call(call)).pipe(import_effect.Effect.provideService(AgentEvent.Journal, emit)),
1302
+ replaying,
1303
+ call
1304
+ );
1305
+ if (result.outcome === "success") ledger.push(...TruncatedOutput.captures(call.flowName, result.value));
1306
+ yield* emit(
1307
+ new AgentEvent.CellCallSettled({
1308
+ eventType: eventType.cellCallSettled,
1309
+ flowName: call.flowName,
1310
+ identity: call.identity,
1311
+ result
1312
+ })
1313
+ );
1314
+ return result;
1315
+ });
1316
+ const requested = (state, engine, request, purpose, attempt, emit) => import_effect.Effect.gen(function* () {
1317
+ const resolved = yield* EngineLike.resolve(engine, request);
1318
+ if (import_effect.Option.isNone(resolved)) return;
1319
+ yield* emit(
1320
+ new AgentEvent.ModelRequested({
1321
+ eventType: eventType.modelRequested,
1322
+ scope: state.session,
1323
+ frame: state.frame,
1324
+ attempt,
1325
+ purpose,
1326
+ seat: state.seat,
1327
+ binding: import_effect.Option.getOrUndefined(resolved.value.binding),
1328
+ request: resolved.value.request
1329
+ })
1330
+ );
1331
+ });
1332
+ const summarized = (state, engine, emit, step) => import_effect.Effect.gen(function* () {
1333
+ const summaryRequest = yield* Compaction.summaryRequest(state.contextWindow, step).pipe(import_effect.Effect.orDie);
1334
+ const request = import_model.ModelRequest.ModelRequest.make({
1335
+ modelId: summaryRequest.modelId,
1336
+ system: summaryRequest.system,
1337
+ messages: summaryRequest.messages,
1338
+ tools: [],
1339
+ toolChoice: "none",
1340
+ params: summaryRequest.params
1341
+ });
1342
+ yield* requested(state, engine, request, "compaction", 1, emit);
1343
+ const events = yield* import_effect.Stream.runCollect(
1344
+ (engine.sealStepWithEvents?.({
1345
+ request,
1346
+ keyMaterial: keyMaterialFrom(state, state.contextWindow, request),
1347
+ modelCallMs: state.modelCallMs
1348
+ }, emit) ?? engine.sealStep({
1349
+ request,
1350
+ keyMaterial: keyMaterialFrom(state, state.contextWindow, request),
1351
+ modelCallMs: state.modelCallMs
1352
+ })).pipe(
1353
+ import_effect.Stream.tap((event) => emitModelProgress(event, emit))
1354
+ )
1355
+ ).pipe(import_effect.Effect.map((collected) => Array.from(collected)));
1356
+ if (!events.some((event) => event.type === "settle")) {
1357
+ return yield* new import_HarnessError.HarnessError({
1358
+ code: "model_failed",
1359
+ message: "The sealed compaction step ended without a recorded settlement"
1360
+ });
1361
+ }
1362
+ const settled = import_model.ModelEvent.ModelEvent.settledMessage(events);
1363
+ const text = settled.message.content.filter(
1364
+ (part) => part.type === "text"
1365
+ );
1366
+ if (text.length === 0) {
1367
+ return yield* new import_HarnessError.HarnessError({
1368
+ code: "model_failed",
1369
+ message: "The sealed compaction step returned no text summary"
1370
+ });
1371
+ }
1372
+ return import_model.ModelRequest.Message.user(
1373
+ (0, import_untrustedData.untrustedData)(text.map((part) => part.text).join("\n"), "compaction summary of conversation and tool output")
1374
+ );
1375
+ });
1376
+ const messageText = (message) => message.content.filter((part) => part.type === "text").map((part) => part.text).join("\n");
1377
+ const markItem = (segment) => {
1378
+ const messages = segment.content.filter((item) => "role" in item);
1379
+ const said = messages.filter((message) => message.role === "assistant").map(messageText).join("\n");
1380
+ const extracted = Cell.extract(said);
1381
+ return {
1382
+ tokens: segment.tokens.value,
1383
+ cell: extracted._tag === "Success" ? extracted.success.source.text : "",
1384
+ prose: Supervisor.prose(said),
1385
+ observed: messages.filter((message) => message.role !== "assistant").map(messageText).join("\n\n")
1386
+ };
1387
+ };
1388
+ const alignedFacts = (state, segments) => {
1389
+ const transcripts = segments.filter((segment) => segment.kind === "transcript").length;
1390
+ if (transcripts !== state.segmentFacts.length) return void 0;
1391
+ let next = 0;
1392
+ return segments.map((segment) => segment.kind === "transcript" ? state.segmentFacts[next++] : void 0);
1393
+ };
1394
+ const unmarked = (state) => {
1395
+ const segments = (0, import_compactable.compactable)(state.contextWindow.segments);
1396
+ const facts = alignedFacts(state, segments);
1397
+ if (facts === void 0) return [];
1398
+ const open = segments.flatMap((segment, index) => {
1399
+ const known = facts[index];
1400
+ return known === void 0 || known.person || known.answer !== void 0 ? [] : [segment];
1401
+ });
1402
+ return [...new Map(open.map((segment) => [segment.digest, segment])).values()].map((segment) => ({
1403
+ digest: segment.digest,
1404
+ item: markItem(segment)
1405
+ }));
1406
+ };
1407
+ const factsAfter = (state, prefixLength, marks) => {
1408
+ const transcripts = (0, import_compactable.compactable)(state.contextWindow.segments).flatMap(
1409
+ (segment, index) => segment.kind === "transcript" ? [index] : []
1410
+ );
1411
+ const missing = transcripts.length - state.segmentFacts.length;
1412
+ return transcripts.flatMap((index, at) => {
1413
+ const facts = state.segmentFacts[at - missing];
1414
+ return facts !== void 0 && (index >= prefixLength || marks?.[index] === "keep") ? [facts] : [];
1415
+ });
1416
+ };
1417
+ const MarksRecord = import_effect.Schema.Array(compactionMarks.Marked);
1418
+ const marked = (state, facts, prefixLength, engine, emit, taskOf) => import_effect.Effect.gen(function* () {
1419
+ const segments = (0, import_compactable.compactable)(state.contextWindow.segments);
1420
+ const failing = state.checks.filter((check) => check.failing).map((check) => check.label);
1421
+ const pinned = compactionMarks.pins(segments, prefixLength, facts, failing);
1422
+ const open = compactionMarks.unpinned(pinned);
1423
+ const missing = open.filter((index) => facts[index]?.answer === void 0);
1424
+ const budget = {
1425
+ contextWindow: state.contextWindowTokens,
1426
+ reserve: import_compactable.defaultReserve,
1427
+ keepRecent: import_compactable.defaultKeepRecent,
1428
+ suffix: segments.slice(prefixLength).reduce((sum, segment) => sum + segment.tokens.value, 0),
1429
+ tokens: segments.slice(0, prefixLength).map((segment) => segment.tokens.value)
1430
+ };
1431
+ const resolved = (answered) => import_effect.Effect.fromResult(compactionMarks.resolve(open.map((index) => answered.get(index)), pinned, budget)).pipe(
1432
+ import_effect.Effect.orDie
1433
+ );
1434
+ const stored = new Map(open.flatMap((index) => {
1435
+ const answer = facts[index]?.answer;
1436
+ return answer === void 0 ? [] : [[index, answer]];
1437
+ }));
1438
+ if (missing.length === 0) return yield* resolved(stored);
1439
+ const prefix = yield* import_effect.Effect.fromResult(ContextWindow.prefixDigest(state.contextWindow, prefixLength)).pipe(
1440
+ import_effect.Effect.orDie
1441
+ );
1442
+ const record = yield* Judgement.recorded(
1443
+ engine,
1444
+ {
1445
+ name: "compaction-marks",
1446
+ identity: { session: state.session, frame: state.frame, boundary: `compaction-marks:${prefix}` },
1447
+ classifier: "compaction/marks",
1448
+ value: MarksRecord,
1449
+ items: missing.length
1450
+ },
1451
+ compactionMarks.read(
1452
+ { task: Judgement.task(taskOf(state.contextWindow)), failing },
1453
+ missing.map((index) => markItem(segments[index]))
1454
+ ).pipe(import_effect.Effect.flatMap(
1455
+ (reading) => resolved(new Map([...stored, ...missing.map((index, at) => [index, reading.answers[at]])])).pipe(
1456
+ import_effect.Effect.map((value) => ({
1457
+ value,
1458
+ asked: reading.asked,
1459
+ acted: value.some((mark) => mark.mark !== "squash")
1460
+ }))
1461
+ )
1462
+ ))
1463
+ );
1464
+ yield* Judgement.emitRecorded(emit, record);
1465
+ return record.value ?? void 0;
1466
+ });
1467
+ const compacted = (state, engine, emit, judged, taskOf) => import_effect.Effect.gen(function* () {
1468
+ const over = Compaction.shouldCompact({
1469
+ total: state.contextWindow.tokens.total,
1470
+ contextWindow: state.contextWindowTokens
1471
+ });
1472
+ const due = state.compactionDue;
1473
+ const opened = due.length === 0 ? state : advance(state, { compactionDue: [] });
1474
+ if (!over && due.length === 0) return opened;
1475
+ const prefixLength = Compaction.selectPrefix(state.contextWindow);
1476
+ if (prefixLength === 0) return opened;
1477
+ const causes = [...over ? ["budget"] : [], ...due];
1478
+ const facts = judged ? alignedFacts(state, (0, import_compactable.compactable)(state.contextWindow.segments)) : void 0;
1479
+ const unaligned = judged && facts === void 0;
1480
+ const marks = facts === void 0 ? void 0 : yield* marked(state, facts, prefixLength, engine, emit, taskOf);
1481
+ if (!over && marks !== void 0 && marks.every((mark) => mark.mark === "keep")) return opened;
1482
+ const step = yield* Compaction.declare(
1483
+ state.contextWindow,
1484
+ prefixLength,
1485
+ {
1486
+ identity: "flows/harness/CellTurn.compaction",
1487
+ modelId: state.contextWindow.modelId,
1488
+ params: state.modelParams
1489
+ },
1490
+ marks?.map((mark) => mark.mark)
1491
+ ).pipe(import_effect.Effect.orDie);
1492
+ const summary = marks === void 0 || marks.some((mark) => mark.mark === "squash") ? yield* summarized(state, engine, emit, step) : void 0;
1493
+ const contextWindow = yield* Compaction.apply(state.contextWindow, step, summary).pipe(import_effect.Effect.orDie);
1494
+ const segments = (0, import_compactable.compactable)(state.contextWindow.segments);
1495
+ const replaced = segments.slice(0, prefixLength);
1496
+ yield* emit(
1497
+ new AgentEvent.CompactionSettled({
1498
+ eventType: eventType.compactionSettled,
1499
+ replacedPrefixDigest: step.replacedPrefixDigest,
1500
+ retainedMessageCount: segments.slice(prefixLength).flatMap((segment) => segment.content).filter((item) => "role" in item).length,
1501
+ ...summary === void 0 ? {} : { summary },
1502
+ ...unaligned ? { unaligned } : {},
1503
+ causes,
1504
+ ...marks === void 0 ? {} : {
1505
+ kept: replaced.filter((_, index) => marks[index].mark === "keep").flatMap((segment) => segment.content.filter((item) => "role" in item)),
1506
+ marks: replaced.map((segment, index) => ({ digest: segment.digest, ...marks[index] })),
1507
+ removedTokens: replaced.filter((_, index) => marks[index].mark === "remove").reduce((sum, segment) => sum + segment.tokens.value, 0)
1508
+ }
1509
+ })
1510
+ );
1511
+ return advance(opened, {
1512
+ contextWindow,
1513
+ segmentFacts: factsAfter(state, prefixLength, marks?.map((mark) => mark.mark)),
1514
+ // The sections that listed earlier calls may be among what was replaced.
1515
+ ledgerShown: 0
1516
+ });
1517
+ });
1518
+ const parsed = (message) => {
1519
+ if (message.stopReason === "length") {
1520
+ return import_effect.Result.fail(
1521
+ new Cell.Rejected({
1522
+ code: "output_truncated",
1523
+ message: "The model reached its output limit (length) before finishing the response. No blocks ran. Emit a shorter, complete cell."
1524
+ })
1525
+ );
1526
+ }
1527
+ const extracted = Cell.extract(assistantText(message));
1528
+ if (extracted._tag === "Failure") return import_effect.Result.fail(extracted.failure);
1529
+ const validation = CellValidation.validate(extracted.success.source);
1530
+ return validation.rejected === void 0 ? import_effect.Result.succeed({
1531
+ source: extracted.success.source,
1532
+ blocks: extracted.success.blocks,
1533
+ program: validation.compiled
1534
+ }) : import_effect.Result.fail(validation.rejected);
1535
+ };
1536
+ const seal = (state, engine, emit) => import_effect.Effect.gen(function* () {
1537
+ let contextWindow = state.contextWindow;
1538
+ for (let attempt = 0; ; attempt++) {
1539
+ const request = yield* import_effect.Effect.fromResult(requestFrom(state, contextWindow));
1540
+ yield* requested(state, engine, request, "frame", attempt + 1, emit);
1541
+ const startedAt = yield* import_effect.Clock.currentTimeMillis;
1542
+ const events = yield* import_effect.Stream.runCollect(
1543
+ (engine.sealStepWithEvents?.({
1544
+ request,
1545
+ keyMaterial: keyMaterialFrom(state, contextWindow, request),
1546
+ modelCallMs: state.modelCallMs
1547
+ }, emit) ?? engine.sealStep({
1548
+ request,
1549
+ keyMaterial: keyMaterialFrom(state, contextWindow, request),
1550
+ modelCallMs: state.modelCallMs
1551
+ })).pipe(
1552
+ import_effect.Stream.tap((event) => emitModelProgress(event, emit))
1553
+ )
1554
+ ).pipe(import_effect.Effect.map((collected) => Array.from(collected)));
1555
+ const settledAt = yield* import_effect.Clock.currentTimeMillis;
1556
+ if (!events.some((event) => event.type === "settle")) {
1557
+ return yield* new import_HarnessError.HarnessError({
1558
+ code: "model_failed",
1559
+ message: "The sealed model step ended without a recorded settlement"
1560
+ });
1561
+ }
1562
+ const settled = import_model.ModelEvent.ModelEvent.settledMessage(events);
1563
+ const sessionId = events.find((event) => event.type === "settle")?.sessionId;
1564
+ const cost = Pricing.cost(settled.usage, request.modelId, { at: settledAt });
1565
+ yield* emit(
1566
+ new AgentEvent.ModelSettled({
1567
+ eventType: eventType.modelSettled,
1568
+ message: settled.message,
1569
+ usage: settled.usage,
1570
+ ...cost,
1571
+ ...sessionId === void 0 ? {} : { sessionId },
1572
+ durationMillis: settledAt - startedAt
1573
+ })
1574
+ );
1575
+ const cell = parsed(settled.message);
1576
+ if (cell._tag === "Success" || attempt >= state.revalidations) {
1577
+ return { contextWindow, answer: settled.message, cell };
1578
+ }
1579
+ yield* emit(
1580
+ new AgentEvent.CellRejectedInFrame({
1581
+ eventType: eventType.cellRejectedInFrame,
1582
+ attempt: attempt + 1,
1583
+ code: cell.failure.code,
1584
+ message: cell.failure.message
1585
+ })
1586
+ );
1587
+ contextWindow = observedOn(
1588
+ contextWindow,
1589
+ settled.message,
1590
+ revalidationNote(cell.failure),
1591
+ deadCellEcho
1592
+ );
1593
+ }
1594
+ });
1595
+ const evaluate = (input, state, produced, engine, sandbox, realm, opened, steering, emit) => import_effect.Effect.gen(function* () {
1596
+ const cell = produced.source;
1597
+ const descriptors = new Map(input.flows.map((descriptor) => [descriptor.name, descriptor]));
1598
+ const projections = {};
1599
+ for (const descriptor of input.flows) projections[descriptor.name] = Cell.project(descriptor);
1600
+ const captures = [...state.truncatedOutputs];
1601
+ const calls = [];
1602
+ const performed = /* @__PURE__ */ new Set();
1603
+ const restored = /* @__PURE__ */ new Set();
1604
+ const tree = { writes: 0, chain: void 0 };
1605
+ const live = import_effect.Option.isSome(opened) && opened.value.complete ? { tree: opened.value.digest } : { session: state.session, frame: state.frame };
1606
+ const callMs = Sandbox.withDefaults(sandbox.capabilities, input.limits).callMs ?? Sandbox.defaultLimits.callMs;
1607
+ const totalMs = Sandbox.withDefaults(sandbox.capabilities, input.limits).totalMs;
1608
+ let replaying = false;
1609
+ const observing = (invocation) => {
1610
+ const handle = callHandler(
1611
+ state,
1612
+ cell,
1613
+ descriptors,
1614
+ engine,
1615
+ captures,
1616
+ performed,
1617
+ restored,
1618
+ tree,
1619
+ live,
1620
+ callMs,
1621
+ replaying,
1622
+ emit
1623
+ );
1624
+ const pending = engine.record({
1625
+ name: "steering-before-call",
1626
+ identity: {
1627
+ session: state.session,
1628
+ frame: state.frame,
1629
+ boundary: `steering-before-call:${cell.digest}:${invocation.ordinal}`
1630
+ },
1631
+ success: import_effect.Schema.Boolean,
1632
+ execute: steering.read().pipe(import_effect.Effect.map((queue) => queue.items.some((item) => item.delivery === "steer")))
1633
+ });
1634
+ return pending.pipe(
1635
+ import_effect.Effect.flatMap(
1636
+ (blocked) => blocked ? import_effect.Effect.succeed(
1637
+ (0, import_refusal.refusal)(
1638
+ void 0,
1639
+ "Outside changes are pending; finish this cell and re-read the changed files in the next turn."
1640
+ )
1641
+ ) : handle(invocation)
1642
+ ),
1643
+ import_effect.Effect.tap(
1644
+ (result) => import_effect.Effect.sync(() => {
1645
+ const rendered = result.outcome === "success" ? JSON.stringify(result.value) : result.message ?? "failed";
1646
+ const ordinal = CallLedger.settled(state.callLedger) + calls.length + 1;
1647
+ const descriptor = descriptors.get(invocation.flow);
1648
+ const probe = result.outcome === "success" ? invalidProbeOf(result.value) : void 0;
1649
+ const measured = performed.has(invocation.ordinal) && result.outcome === "success" && mutatedOf(result.value);
1650
+ const ranAt = performed.has(invocation.ordinal) && invocation.at !== void 0 ? Cell.checkpointOf(invocation.at) : void 0;
1651
+ calls.push({
1652
+ flow: invocation.flow,
1653
+ ok: result.outcome === "success",
1654
+ summary: elide.head(rendered, salvageSummary, salvageRecall),
1655
+ ordinal,
1656
+ mutates: performed.has(invocation.ordinal) && descriptor !== void 0 && mutating(descriptor, invocation.input) || measured,
1657
+ remote: measured,
1658
+ // Every invocation the cell issued, refused ones included: a
1659
+ // refusal is still a question the run has already asked, and
1660
+ // asking it again learns nothing either.
1661
+ signature: signatureOf(invocation.flow, invocation.input, ranAt),
1662
+ subject: signatureOf(invocation.flow, invocation.input),
1663
+ at: ranAt,
1664
+ input: invocation.input,
1665
+ value: result.value,
1666
+ message: result.message,
1667
+ invalidProbe: probe,
1668
+ failing: result.outcome === "success" && probe === void 0 && UnresolvedFailure.failed(result.value),
1669
+ passing: result.outcome === "success" && probe === void 0 && UnresolvedFailure.passed(result.value)
1670
+ });
1671
+ })
1672
+ )
1673
+ );
1674
+ };
1675
+ const minted = [];
1676
+ const mint = minter(state, cell, engine, minted, callMs, emit);
1677
+ const history = yield* import_effect.Effect.serviceOption(CellHistory.CellHistory);
1678
+ yield* import_effect.Option.match(history, {
1679
+ onNone: () => import_effect.Effect.void,
1680
+ onSome: (recorder) => recorder.record(cell.text)
1681
+ });
1682
+ const settled = yield* import_effect.Effect.gen(function* () {
1683
+ for (let attempt = 0; ; attempt++) {
1684
+ const identity = (slot) => ({
1685
+ session: state.session,
1686
+ frame: state.frame,
1687
+ boundary: `cell-frame:${cell.digest}${slot === 0 ? "" : `:attempt:${slot}`}`
1688
+ });
1689
+ let fresh = false;
1690
+ const recorded = yield* engine.record({
1691
+ name: "cell-frame",
1692
+ identity: identity(attempt),
1693
+ success: import_effect.Schema.NullOr(RecordedFrame),
1694
+ execute: import_effect.Effect.sync(() => {
1695
+ fresh = true;
1696
+ return null;
1697
+ })
1698
+ });
1699
+ if (recorded === null && !fresh) continue;
1700
+ if (recorded !== null && recorded.boundary === void 0 && recorded.outcome._tag === "rejected" && recorded.outcome.code === "limit_exceeded") {
1701
+ return yield* import_effect.Effect.fail(
1702
+ new import_HarnessError.HarnessError({
1703
+ code: "incompatible_journal",
1704
+ message: "Cannot reconstruct a limited frame without its recorded execution frontier"
1705
+ })
1706
+ );
1707
+ }
1708
+ const replay = recorded !== null && recorded.boundary?.terminal === "timeout" ? { boundary: recorded.boundary, outcome: yield* Cell.decodeOutcome(recorded.outcome) } : void 0;
1709
+ replaying = replay !== void 0;
1710
+ const guarded = recorded === null && engine.guard !== void 0 ? engine.guard : void 0;
1711
+ const subject = JSON.stringify({
1712
+ session: state.session,
1713
+ frame: state.frame,
1714
+ boundary: `cell-frame:${cell.digest}`
1715
+ });
1716
+ if (guarded !== void 0) yield* guarded.admit(subject);
1717
+ const frame2 = yield* realm.evaluate({
1718
+ cell,
1719
+ // The boundary parse is the only one this cell gets: the realm runs
1720
+ // what it compiled rather than parsing the same text again.
1721
+ program: produced.program,
1722
+ frame: state.frame,
1723
+ // A judged run's catalog can change without a refresh: the run-start
1724
+ // relevance reading withholds flows and a call restores them.
1725
+ flows: input.refreshFlows === void 0 && input.judged !== true ? void 0 : projections,
1726
+ call: observing,
1727
+ mint,
1728
+ replay,
1729
+ // Settlements are bounded inside their recorded boundaries.
1730
+ bounded: true
1731
+ });
1732
+ if (recorded !== null) return recorded;
1733
+ const outcome = yield* Cell.decodeOutcome(frame2.outcome);
1734
+ if (guarded !== void 0 && frame2.boundary?.terminal === "timeout" && outcome._tag === "rejected" && outcome.code === "limit_exceeded") {
1735
+ yield* guarded.trip({ source: "cell", subject, limitMillis: totalMs, message: outcome.message });
1736
+ }
1737
+ return yield* engine.record({
1738
+ name: "cell-frame",
1739
+ identity: identity(attempt + 1),
1740
+ success: RecordedFrame,
1741
+ execute: import_effect.Effect.succeed({ ...frame2, outcome })
1742
+ });
1743
+ }
1744
+ });
1745
+ return { frame: settled, calls, minted, captures, restored };
1746
+ });
1747
+ const completionTask = (task, instructions) => instructions === "" ? task : `${elide.middle(task, 3584, "the run record has the whole task")}
1748
+
1749
+ The person now says:
1750
+
1751
+ Later instructions accepted during this run, oldest first. Apply these changes to the task above; later changes take precedence:
1752
+
1753
+ ${instructions}`;
1754
+ const drain = (settling, wouldIdle) => import_effect.Effect.gen(function* () {
1755
+ const { boundary, state } = settling;
1756
+ const drained = yield* settling.engine.record({
1757
+ name: "steering-drain",
1758
+ identity: { session: state.session, frame: state.frame, boundary: `steering-drain:${boundary}` },
1759
+ success: Steering.DrainRecord,
1760
+ execute: Frame.hasNextFrame(state) ? settling.steering.drain({ boundary: `${state.frame}:${boundary}`, wouldIdle }).pipe(
1761
+ import_effect.Effect.map(Steering.drainRecord),
1762
+ // The supervisor's nudge rides the same recorded drain, in a field
1763
+ // of its own and only at a boundary the run continues through: a
1764
+ // boundary that would idle is a completion or the last frame, and a
1765
+ // nudge there would turn a finished answer into a follow-up. Inside
1766
+ // the record, so a replayed boundary delivers what it delivered the
1767
+ // first time. Apart from `inserts`, because those are the person's
1768
+ // words and the completion brake reads them as the task; a nudge is
1769
+ // not. See `internal/supervision`.
1770
+ import_effect.Effect.flatMap(
1771
+ (record) => wouldIdle ? import_effect.Effect.succeed(record) : settling.supervision.take(state.frame, {
1772
+ ledger: state.monitorLedger,
1773
+ shown: state.memoryShown,
1774
+ deliver: settling.input.judged ?? false
1775
+ }).pipe(
1776
+ import_effect.Effect.map((taken) => ({
1777
+ ...record,
1778
+ ...taken.messages.length === 0 ? {} : { supervisor: taken.messages },
1779
+ ...taken.memory.length === 0 ? {} : { memory: taken.memory },
1780
+ ...taken.monitor === void 0 ? {} : { monitor: taken.monitor },
1781
+ ...taken.suppressed.length === 0 ? {} : { suppressed: taken.suppressed },
1782
+ ...taken.ledger === void 0 ? {} : { monitorLedger: taken.ledger },
1783
+ ...taken.marks.length === 0 ? {} : { marks: taken.marks },
1784
+ ...taken.compact.length === 0 ? {} : { compact: taken.compact }
1785
+ }))
1786
+ )
1787
+ ),
1788
+ // Executed, not replayed: the one fact that says this frame is the
1789
+ // run's present rather than its past.
1790
+ import_effect.Effect.tap(() => import_effect.Effect.sync(() => void (settling.live.value = true)))
1791
+ ) : import_effect.Effect.succeed({ inserts: [], seatChanges: [], queued: false })
1792
+ });
1793
+ yield* settling.emit(
1794
+ new AgentEvent.SteeringDrained({
1795
+ eventType: eventType.steeringDrained,
1796
+ messages: drained.inserts,
1797
+ ...drained.supervisor === void 0 || drained.supervisor.length === 0 ? {} : { supervisor: drained.supervisor },
1798
+ ...drained.monitor === void 0 ? {} : { monitor: drained.monitor },
1799
+ ...drained.suppressed === void 0 ? {} : { suppressed: drained.suppressed },
1800
+ ...drained.memory === void 0 ? {} : { memory: drained.memory }
1801
+ })
1802
+ );
1803
+ if (settling.live.value && !wouldIdle) yield* settling.offer;
1804
+ return drained;
1805
+ });
1806
+ const close = (settling, outcome, output = budgetMessage(settling.state)) => import_effect.Effect.gen(function* () {
1807
+ yield* settling.emit(
1808
+ new AgentEvent.TurnClosed({
1809
+ eventType: eventType.turnClosed,
1810
+ stopReason: settling.answer.stopReason,
1811
+ outcome
1812
+ })
1813
+ );
1814
+ if (outcome === "resolved") {
1815
+ yield* settling.emit(
1816
+ new AgentEvent.Resolved({
1817
+ eventType: eventType.resolved,
1818
+ message: import_model.ModelRequest.Message.assistant(output, { stopReason: "stop" })
1819
+ })
1820
+ );
1821
+ }
1822
+ });
1823
+ const finish = (settling, step) => close(settling, step._tag === "Done" ? "resolved" : step._tag === "Suspend" ? "suspended" : "continue").pipe(
1824
+ import_effect.Effect.as(step)
1825
+ );
1826
+ const continuing = (settling, contextWindow, person, changes) => {
1827
+ const transcripts = (window) => window.segments.filter((segment) => segment.kind === "transcript").length;
1828
+ const frame2 = settling.state.frame;
1829
+ const reasks = transcripts(contextWindow) - transcripts(settling.state.contextWindow) - 1;
1830
+ const { segmentFacts = settling.state.segmentFacts, ...rest } = changes;
1831
+ const next = advance(settling.state, {
1832
+ frame: frame2 + 1,
1833
+ interventions: 0,
1834
+ // What this frame's section listed; see `frozen`.
1835
+ ledgerShown: CallLedger.settled(settling.state.callLedger),
1836
+ ...settling.facts,
1837
+ contextWindow,
1838
+ segmentFacts: [
1839
+ ...segmentFacts,
1840
+ ...new Array(reasks).fill({ frame: frame2, person: false, mutated: false, checks: [] }),
1841
+ { frame: frame2, person, ...settling.written }
1842
+ ],
1843
+ ...rest
1844
+ });
1845
+ return {
1846
+ _tag: "Continue",
1847
+ state: advance(next, { contextWindow: withSection(next.contextWindow, next), sectioned: true })
1848
+ };
1849
+ };
1850
+ const delivered = (drained) => [
1851
+ ...drained.supervisor ?? [],
1852
+ ...drained.inserts
1853
+ ];
1854
+ const resumed = (settling, drained, changes = {}, text = settling.printed, echo = liveCellEcho, ask) => import_effect.Effect.gen(function* () {
1855
+ const { state } = settling;
1856
+ const settings = yield* steered(state, drained.seatChanges, settling.input.contextWindowTokensFor);
1857
+ const inserts = delivered(drained);
1858
+ const messages = ask === void 0 ? [import_model.ModelRequest.Message.user(text), ...inserts] : inserts.length === 0 ? [import_model.ModelRequest.Message.user(text === "" ? ask : `${text}
1859
+
1860
+ ${ask}`)] : [...text === "" ? [] : [import_model.ModelRequest.Message.user(text)], ...inserts, import_model.ModelRequest.Message.user(ask)];
1861
+ const context = appended(settling.contextWindow, settling.answer, messages, echo);
1862
+ return continuing(settling, windowOn(state, settings.seat, context), drained.inserts.length > 0, {
1863
+ ...settings,
1864
+ ...shownAfter(state, drained),
1865
+ ...ledgerAfter(drained),
1866
+ ...marksAfter(state, drained),
1867
+ ...changes
1868
+ });
1869
+ });
1870
+ const observe = (settling, note, changes = {}, echo = liveCellEcho) => import_effect.Effect.gen(function* () {
1871
+ const next = Frame.hasNextFrame(settling.state);
1872
+ const drained = yield* drain(settling, !next);
1873
+ return next ? yield* resumed(settling, drained, changes, settling.printed, echo, note) : { _tag: "Done" };
1874
+ });
1875
+ const frame = (input, engine, sandbox, realm, steering, emit, readCompletion, supervision, taskOf) => import_effect.Effect.gen(function* () {
1876
+ const compactedState = yield* compacted(input.state, engine, emit, input.judged ?? false, taskOf);
1877
+ const sectioned = compactedState.sectioned ? import_effect.Result.succeed(compactedState.contextWindow) : frozen(compactedState.contextWindow, compactedState);
1878
+ const state = sectioned._tag === "Success" ? advance(compactedState, { contextWindow: sectioned.success, sectioned: true }) : compactedState;
1879
+ yield* emit(
1880
+ new AgentEvent.TurnOpened({
1881
+ eventType: eventType.turnOpened,
1882
+ seat: state.seat,
1883
+ modelParams: state.modelParams,
1884
+ activeToolNames: [],
1885
+ contextDigest: state.contextWindow.digest
1886
+ })
1887
+ );
1888
+ if (sectioned._tag === "Failure") return yield* import_effect.Effect.fail(sectioned.failure);
1889
+ const { answer, cell: sealed, contextWindow } = yield* seal(state, engine, emit);
1890
+ const settling = (boundary, printed2, facts2, written2, offer = import_effect.Effect.void) => ({
1891
+ input,
1892
+ state,
1893
+ engine,
1894
+ steering,
1895
+ supervision,
1896
+ offer,
1897
+ live: { value: false },
1898
+ emit,
1899
+ contextWindow,
1900
+ answer,
1901
+ boundary,
1902
+ printed: printed2,
1903
+ facts: facts2,
1904
+ written: written2
1905
+ });
1906
+ if (sealed._tag === "Failure") {
1907
+ const rejection = sealed.failure;
1908
+ yield* emit(
1909
+ new AgentEvent.CellSettled({
1910
+ eventType: eventType.cellSettled,
1911
+ cell: "",
1912
+ outcome: rejection
1913
+ })
1914
+ );
1915
+ const rejectedFrames = state.readOnlyFrames + 1;
1916
+ if (state.readOnlyCap > 0 && rejectedFrames >= state.readOnlyCap * 2) {
1917
+ return yield* readOnlyCapFailure(state.readOnlyCap, rejectedFrames);
1918
+ }
1919
+ const rejected = settling(contextWindow.digest, "", {
1920
+ truncatedOutputs: TruncatedOutput.retain(state.truncatedOutputs),
1921
+ readOnlyFrames: rejectedFrames
1922
+ }, { mutated: false, checks: [] });
1923
+ const step = yield* observe(rejected, rejection.message, {}, deadCellEcho);
1924
+ return yield* finish(rejected, step);
1925
+ }
1926
+ const cell = sealed.success.source;
1927
+ yield* emit(
1928
+ new AgentEvent.CellProduced({
1929
+ eventType: eventType.cellProduced,
1930
+ cell,
1931
+ blocks: sealed.success.blocks
1932
+ })
1933
+ );
1934
+ const pendingBeforeTool = yield* engine.record({
1935
+ name: "steering-before-tool",
1936
+ identity: { session: state.session, frame: state.frame, boundary: `steering-before-tool:${cell.digest}` },
1937
+ success: import_effect.Schema.Boolean,
1938
+ execute: steering.read().pipe(import_effect.Effect.map((queue) => queue.items.some((item) => item.delivery === "steer")))
1939
+ });
1940
+ if (pendingBeforeTool) {
1941
+ if (!Frame.hasNextFrame(state)) {
1942
+ return yield* new import_HarnessError.HarnessError({
1943
+ code: "engine_failed",
1944
+ message: "Outside changes require another model turn before tools can run"
1945
+ });
1946
+ }
1947
+ const beforeTool = settling(`before-tool:${cell.digest}`, "", {}, { mutated: false, checks: [] });
1948
+ const drained2 = yield* drain(beforeTool, false);
1949
+ if (carries(drained2)) {
1950
+ const step = yield* resumed(beforeTool, drained2, {}, "", deadCellEcho);
1951
+ return yield* finish(beforeTool, step);
1952
+ }
1953
+ }
1954
+ const opened = state.workspace !== void 0 && (import_effect.Option.isNone(state.workspace) || !state.workspace.value.complete) ? state.workspace : yield* witness(engine, state, cell.digest, "open");
1955
+ const ran = yield* evaluate(
1956
+ input,
1957
+ state,
1958
+ sealed.success,
1959
+ engine,
1960
+ sandbox,
1961
+ realm,
1962
+ opened,
1963
+ steering,
1964
+ emit
1965
+ );
1966
+ const outcome = yield* Cell.decodeOutcome(ran.frame.outcome);
1967
+ const printed = (0, import_printsObservation.printsObservation)(ran.frame.prints);
1968
+ yield* emit(
1969
+ new AgentEvent.CellPrinted({
1970
+ eventType: eventType.cellPrinted,
1971
+ cell: cell.digest,
1972
+ text: ran.frame.prints
1973
+ })
1974
+ );
1975
+ const closed = import_effect.Option.isSome(opened) && !opened.value.complete ? opened : yield* witness(engine, state, cell.digest, "close");
1976
+ yield* emit(
1977
+ new AgentEvent.CellSettled({
1978
+ eventType: eventType.cellSettled,
1979
+ cell: cell.digest,
1980
+ outcome,
1981
+ ...ran.frame.boundary === void 0 ? {} : { boundary: ran.frame.boundary }
1982
+ })
1983
+ );
1984
+ const accounting = Frame.account({
1985
+ state,
1986
+ calls: ran.calls,
1987
+ opened,
1988
+ closed,
1989
+ minted: ran.minted,
1990
+ bindings: ran.frame.bindings,
1991
+ captures: ran.captures,
1992
+ source: cell.text
1993
+ });
1994
+ yield* emit(accounting.observed);
1995
+ const written = Supervisor.prose(assistantText(answer));
1996
+ const { mutated } = accounting;
1997
+ const { readOnlyFrames } = accounting.facts;
1998
+ const failed = ran.calls.length > 0 && ran.calls.every((call) => !call.ok || call.failing);
1999
+ const failure = ran.calls.some((call) => call.ok && !call.failing) ? "" : outcome._tag === "raised" ? `cell threw ${outcome.name}: ${outcome.message}` : failed ? ran.calls.map((call) => `${call.flow}: ${call.summary}`).join("; ") : "";
2000
+ const failureKey = failure.slice(0, 1e3);
2001
+ const failureFrames = failureKey === "" ? 0 : failureKey === state.failureKey ? state.failureFrames + 1 : 1;
2002
+ const facts = ran.restored.size === 0 ? accounting.facts : {
2003
+ ...accounting.facts,
2004
+ withheldFlows: state.withheldFlows.filter((name) => !ran.restored.has(name))
2005
+ };
2006
+ const { capped: skillsCapped, ...offered } = Supervision.catalog(input.flows, accounting.facts.callLedger);
2007
+ const exit = settling(
2008
+ cell.digest,
2009
+ printed,
2010
+ { ...facts, failureFrames, failureKey },
2011
+ { mutated, checks: accounting.frameChecks.map((check) => check.label) },
2012
+ supervision.offer({
2013
+ frame: state.frame,
2014
+ digest: cell.digest,
2015
+ current: {
2016
+ frame: state.frame,
2017
+ cell: Supervisor.head(cell.text),
2018
+ prose: Supervisor.head(written),
2019
+ printed: Supervisor.tail(ran.frame.prints),
2020
+ transition: outcome._tag === "settled" ? outcome.transition._tag : outcome._tag,
2021
+ mutated
2022
+ },
2023
+ snapshot: {
2024
+ task: Judgement.task(taskOf(contextWindow)),
2025
+ signals: Supervision.signals(state, accounting.facts, accounting.workspaceDigest, accounting.observed.paths),
2026
+ ...offered
2027
+ },
2028
+ shown: state.memoryShown,
2029
+ recent: Supervisor.head(written),
2030
+ skillsCapped,
2031
+ unmarked: input.judged === true ? unmarked(state) : [],
2032
+ failing: accounting.facts.checks.filter((check) => check.failing).map((check) => check.label)
2033
+ })
2034
+ );
2035
+ const cap = state.readOnlyCap;
2036
+ if (outcome._tag !== "settled") {
2037
+ if (state.pendingReadOnlyDemand !== void 0 && mutated) {
2038
+ yield* emit(
2039
+ new AgentEvent.ReadOnlyDemanded({
2040
+ eventType: eventType.readOnlyDemanded,
2041
+ streak: state.pendingReadOnlyDemand.streak,
2042
+ cap: state.pendingReadOnlyDemand.cap,
2043
+ nextFrame: state.frame,
2044
+ nextAction: "write"
2045
+ })
2046
+ );
2047
+ }
2048
+ if (cap > 0 && readOnlyFrames >= cap * 2) {
2049
+ return yield* readOnlyCapFailure(cap, readOnlyFrames);
2050
+ }
2051
+ const salvage = ran.calls.length === 0 ? "" : `
2052
+ Calls this cell already completed (their results are durable, and each one is still under the name your cell bound it to \u2014 read the name instead of redoing the work):
2053
+ ${ran.calls.map(
2054
+ (call) => `- ${call.ordinal}. ${clip(call.flow, CallLedger.width)} -> ${call.ok ? "ok" : "FAILED"}: ${call.summary}`
2055
+ ).join("\n")}`;
2056
+ const alert = accounting.probeNotice === void 0 ? "" : `
2057
+
2058
+ ${accounting.probeNotice}`;
2059
+ const missed = outcome._tag === "raised" ? bindingPathMiss(outcome.message, ran.frame.bindings) : void 0;
2060
+ const note = outcome._tag === "raised" ? `The cell threw ${outcome.name}: ${outcome.message}. Emit a corrected cell.${missed === void 0 ? "" : `
2061
+ ${missed}`}${salvage}${alert}` : `${outcome.message}${salvage}${alert}`;
2062
+ const step = yield* observe(exit, note);
2063
+ return yield* finish(exit, step);
2064
+ }
2065
+ const transition = outcome.transition;
2066
+ yield* emit(
2067
+ new AgentEvent.TransitionApplied({
2068
+ eventType: eventType.transitionApplied,
2069
+ transition
2070
+ })
2071
+ );
2072
+ if (transition._tag === "park") {
2073
+ if (state.pendingReadOnlyDemand !== void 0) {
2074
+ yield* emit(
2075
+ new AgentEvent.ReadOnlyDemanded({
2076
+ eventType: eventType.readOnlyDemanded,
2077
+ streak: state.pendingReadOnlyDemand.streak,
2078
+ cap: state.pendingReadOnlyDemand.cap,
2079
+ nextFrame: state.frame,
2080
+ nextAction: mutated ? "write" : "park"
2081
+ })
2082
+ );
2083
+ }
2084
+ if (!state.approvalChannel) {
2085
+ return yield* new import_HarnessError.HarnessError({
2086
+ code: "approval_unavailable",
2087
+ message: `The run requires an answer but has no approval channel: ${transition.message}`
2088
+ });
2089
+ }
2090
+ if (!Frame.hasNextFrame(state)) {
2091
+ return yield* finish(exit, {
2092
+ _tag: "Suspend",
2093
+ reason: new EngineLike.SuspendReason({
2094
+ code: transition.reason,
2095
+ message: transition.message
2096
+ })
2097
+ });
2098
+ }
2099
+ const answered = yield* import_effect.Effect.gen(function* () {
2100
+ for (let rung = 0; ; rung++) {
2101
+ const drained2 = yield* steering.drain({
2102
+ boundary: `${state.frame}:${cell.digest}:park:${rung}`,
2103
+ // A park IS the run going idle, which is the condition a queued
2104
+ // follow-up was admitted to wait for. The continue path passes
2105
+ // false because a continuing run is not idle; this is the boundary
2106
+ // that owes those messages their delivery.
2107
+ wouldIdle: true,
2108
+ // What the park asks, so a source with a person on the other end
2109
+ // can put the question to them and answer this drain.
2110
+ park: { reason: transition.reason, message: transition.message }
2111
+ });
2112
+ const record = Steering.drainRecord(drained2);
2113
+ if (carries(record) || !drained2.duplicate) return record;
2114
+ }
2115
+ });
2116
+ if (carries(answered)) {
2117
+ yield* emit(
2118
+ new AgentEvent.SteeringDrained({
2119
+ eventType: eventType.steeringDrained,
2120
+ messages: answered.inserts
2121
+ })
2122
+ );
2123
+ const step = yield* resumed(exit, answered, {
2124
+ pendingReadOnlyDemand: void 0,
2125
+ readOnlyFrames: state.readOnlyFrames
2126
+ });
2127
+ return yield* finish(exit, step);
2128
+ }
2129
+ return yield* finish(exit, {
2130
+ _tag: "Suspend",
2131
+ reason: new EngineLike.SuspendReason({
2132
+ code: transition.reason,
2133
+ message: transition.message
2134
+ })
2135
+ });
2136
+ }
2137
+ if (state.pendingReadOnlyDemand !== void 0) {
2138
+ yield* emit(
2139
+ new AgentEvent.ReadOnlyDemanded({
2140
+ eventType: eventType.readOnlyDemanded,
2141
+ streak: state.pendingReadOnlyDemand.streak,
2142
+ cap: state.pendingReadOnlyDemand.cap,
2143
+ nextFrame: state.frame,
2144
+ nextAction: mutated ? "write" : transition._tag === "continue" && (transition.justification ?? "").trim().length > 0 ? "justification" : "read-only"
2145
+ })
2146
+ );
2147
+ }
2148
+ if (cap > 0 && readOnlyFrames >= cap * 2) {
2149
+ return yield* readOnlyCapFailure(cap, readOnlyFrames);
2150
+ }
2151
+ const drained = yield* drain(exit, transition._tag === "complete" || !Frame.hasNextFrame(state));
2152
+ if (transition._tag === "complete" && carries(drained)) {
2153
+ const step = yield* resumed(
2154
+ exit,
2155
+ drained,
2156
+ { bouncedCompletion: transition.output },
2157
+ `${printed}
2158
+
2159
+ The completed answer before this follow-up:
2160
+ ${transition.output}`
2161
+ );
2162
+ return yield* finish(exit, step);
2163
+ }
2164
+ if (transition._tag === "complete" && input.output !== void 0 && state.outputDemands < input.output.cap && Frame.handBackRoom(state, readOnlyFrames)) {
2165
+ const check = input.output.check;
2166
+ const note = yield* engine.record({
2167
+ name: "output-judgement",
2168
+ identity: {
2169
+ session: state.session,
2170
+ frame: state.frame,
2171
+ boundary: `output-judgement:${cell.digest}`
2172
+ },
2173
+ success: import_effect.Schema.NullOr(import_effect.Schema.String),
2174
+ execute: import_effect.Effect.map(
2175
+ import_effect.Effect.suspend(() => check(transition.output, state.outputDemands, transition.value)),
2176
+ (refused) => refused ?? null
2177
+ )
2178
+ });
2179
+ if (note !== null) {
2180
+ if (exit.live.value) yield* exit.offer;
2181
+ yield* emit(
2182
+ new AgentEvent.OutputDemanded({
2183
+ eventType: eventType.outputDemanded,
2184
+ note,
2185
+ nextFrame: state.frame + 1
2186
+ })
2187
+ );
2188
+ yield* close(exit, "continue");
2189
+ return continuing(
2190
+ exit,
2191
+ appended(
2192
+ contextWindow,
2193
+ answer,
2194
+ [import_model.ModelRequest.Message.user(printed), import_model.ModelRequest.Message.user(note)],
2195
+ liveCellEcho
2196
+ ),
2197
+ false,
2198
+ {
2199
+ interventions: 1,
2200
+ pendingReadOnlyDemand: void 0,
2201
+ outputDemands: state.outputDemands + 1,
2202
+ // An answer the host could not read is not worth restoring.
2203
+ bouncedCompletion: void 0
2204
+ }
2205
+ );
2206
+ }
2207
+ }
2208
+ if (transition._tag === "complete") {
2209
+ const services = yield* import_effect.Effect.context();
2210
+ const judged = yield* engine.record({
2211
+ name: "completion-judgement",
2212
+ identity: {
2213
+ session: state.session,
2214
+ frame: state.frame,
2215
+ boundary: `completion-judgement:${cell.digest}`
2216
+ },
2217
+ success: RecordedCompletion,
2218
+ // The claim brake's reading, whole and by sentence, is paid model
2219
+ // work: the run's budget accounts it like any sealed step (#2681). A
2220
+ // bounce carries the reading as its demand and leaves `observed` empty.
2221
+ usage: (judgement) => (0, import_paidUsage.paidUsage)([
2222
+ (judgement.observed ?? (judgement.demand?.event._tag === "claim-demanded" ? judgement.demand.event : null))?.usage
2223
+ ]),
2224
+ // A replay uses the entire original decision. Re-evaluating even an
2225
+ // accepted claim can invent a demand and execute additional work.
2226
+ execute: Frame.judgeCompletion(
2227
+ state,
2228
+ accounting,
2229
+ contextWindow,
2230
+ transition.output,
2231
+ readCompletion
2232
+ ).pipe(
2233
+ import_effect.Effect.provideContext(services),
2234
+ import_effect.Effect.map((judgement) => ({
2235
+ observed: judgement.observed ?? null,
2236
+ demand: judgement.demand ?? null,
2237
+ unproven: judgement.unproven ?? null,
2238
+ decision: judgement.decision ?? null,
2239
+ sentenceDecision: judgement.sentenceDecision ?? null,
2240
+ unfinishedDecision: judgement.unfinishedDecision ?? null
2241
+ }))
2242
+ )
2243
+ }).pipe(import_effect.Effect.map((judgement) => ({
2244
+ observed: judgement.observed ?? void 0,
2245
+ demand: judgement.demand ?? void 0,
2246
+ unproven: judgement.unproven ?? void 0,
2247
+ decision: judgement.decision ?? void 0,
2248
+ sentenceDecision: judgement.sentenceDecision ?? void 0,
2249
+ unfinishedDecision: judgement.unfinishedDecision ?? void 0
2250
+ })));
2251
+ if (judged.observed !== void 0) yield* emit(judged.observed);
2252
+ if (judged.decision !== void 0) yield* emit(judged.decision);
2253
+ if (judged.sentenceDecision !== void 0) yield* emit(judged.sentenceDecision);
2254
+ if (judged.unfinishedDecision !== void 0) yield* emit(judged.unfinishedDecision);
2255
+ if (judged.unproven !== void 0) return yield* import_effect.Effect.fail(judged.unproven);
2256
+ const demanded = judged.demand;
2257
+ if (demanded !== void 0) {
2258
+ if (exit.live.value) yield* exit.offer;
2259
+ yield* emit(demanded.event);
2260
+ yield* close(exit, "continue");
2261
+ const demandedWindow = demanded.event._tag === "unobserved-demanded" ? appended(
2262
+ contextWindow,
2263
+ answer,
2264
+ [import_model.ModelRequest.Message.user(printed), import_model.ModelRequest.Message.user(demanded.note)],
2265
+ liveCellEcho
2266
+ ) : observedOn(contextWindow, answer, demanded.note, liveCellEcho);
2267
+ return continuing(exit, demandedWindow, false, {
2268
+ // The note is the ask this frame appended; the run's memory goes
2269
+ // above it. See `frozen`.
2270
+ interventions: 1,
2271
+ pendingReadOnlyDemand: void 0,
2272
+ ...demanded.spent,
2273
+ // The answer the demand is taking away, kept so it cannot be lost.
2274
+ // A frame was reserved for the run to answer in, but nothing makes
2275
+ // that frame end in a completion, and a run that spends it and
2276
+ // then runs out of budget would end on the budget notice with its
2277
+ // own answer discarded. See {@link budgetMessage}.
2278
+ //
2279
+ // A claim the brake read and found unsupported is not kept: the
2280
+ // budget notice would hand back the very sentence the brake
2281
+ // refused. See `Frame.CompletionDemand.keeps`.
2282
+ bouncedCompletion: demanded.keeps ? transition.output : void 0,
2283
+ // The frame this demand was handed to, which is the frame that
2284
+ // gets to answer it without being judged again. See
2285
+ // {@link State.demandedFrame}.
2286
+ demandedFrame: state.frame + 1
2287
+ });
2288
+ }
2289
+ yield* close(
2290
+ exit,
2291
+ "resolved",
2292
+ FailedCall.state(
2293
+ transition.output,
2294
+ FailedCall.find(accounting.calls, transition.output, accounting.source)
2295
+ )
2296
+ );
2297
+ return { _tag: "Done" };
2298
+ }
2299
+ if (!Frame.hasNextFrame(state)) {
2300
+ yield* close(exit, "resolved");
2301
+ return { _tag: "Done" };
2302
+ }
2303
+ yield* close(exit, "continue");
2304
+ const { contextWindowTokens, modelCallMs, modelParams, seat } = yield* steered(
2305
+ state,
2306
+ drained.seatChanges,
2307
+ input.contextWindowTokensFor
2308
+ );
2309
+ const disciplined = Frame.discipline(state, accounting, transition.justification);
2310
+ for (const event of disciplined.events) yield* emit(event);
2311
+ const context = appended(
2312
+ contextWindow,
2313
+ answer,
2314
+ [import_model.ModelRequest.Message.user(printed), ...delivered(drained), ...disciplined.messages],
2315
+ liveCellEcho
2316
+ );
2317
+ return continuing(exit, windowOn(state, seat, context), drained.inserts.length > 0, {
2318
+ seat,
2319
+ modelParams,
2320
+ modelCallMs,
2321
+ contextWindowTokens,
2322
+ ...shownAfter(state, drained),
2323
+ ...ledgerAfter(drained),
2324
+ ...marksAfter(state, drained),
2325
+ // Whatever this frame earned is what the next one answers, so the run's
2326
+ // memory goes above it. See `frozen`.
2327
+ interventions: disciplined.messages.length,
2328
+ ...disciplined.changes
2329
+ });
2330
+ });
2331
+ const RelevanceRecord = import_effect.Schema.Struct({ settled: AgentEvent.RelevanceSettled });
2332
+ const withheld = (state, catalog, input, engine, emit, taskOf) => import_effect.Effect.gen(function* () {
2333
+ const pinned = input.pinned ?? [];
2334
+ const documents = input.instructions ?? [];
2335
+ const rows = input.memory?.rows ?? [];
2336
+ const items = [
2337
+ ...catalog.filter((descriptor) => descriptor.modelInvocable && !pinned.includes(descriptor.name)).map(Relevance.flowItem).sort((left, right) => left.id < right.id ? -1 : 1),
2338
+ ...Relevance.chunks(documents).map((chunk) => ({
2339
+ kind: "instruction",
2340
+ id: chunk.id,
2341
+ text: chunk.text
2342
+ })),
2343
+ ...rows.map((row) => ({ kind: "memory", id: row.key, text: row.text }))
2344
+ ];
2345
+ if (items.length === 0) return state;
2346
+ const record = yield* Judgement.recorded(
2347
+ engine,
2348
+ {
2349
+ name: "relevance",
2350
+ identity: { session: state.session, frame: 0, boundary: "relevance" },
2351
+ classifier: "relevance/unnecessary",
2352
+ value: RelevanceRecord,
2353
+ items: items.length
2354
+ },
2355
+ import_effect.Effect.map(Relevance.judge({ task: Judgement.task(taskOf(state.contextWindow)) }, items), (reading) => ({
2356
+ value: { settled: Relevance.settled(reading, { scope: state.session, frame: 0, source: "run" }) },
2357
+ asked: reading.asked,
2358
+ acted: reading.verdicts.some((verdict) => verdict.withheld)
2359
+ }))
2360
+ );
2361
+ yield* Judgement.emitRecorded(emit, record);
2362
+ if (record.value === null) return state;
2363
+ const { settled } = record.value;
2364
+ yield* emit(settled);
2365
+ const judgedChunks = new Set(
2366
+ settled.withheld.filter((item) => item.kind === "instruction").map((item) => `${item.id}\0${item.digest}`)
2367
+ );
2368
+ const chunks = new Set(
2369
+ Relevance.chunks(documents).flatMap(
2370
+ (chunk) => judgedChunks.has(`${chunk.id}\0${Digest.digest(chunk.text)}`) ? [chunk.id] : []
2371
+ )
2372
+ );
2373
+ const dropped = new Set(
2374
+ settled.withheld.filter((item) => item.kind === "memory").map((item) => `${item.id}\0${item.digest}`)
2375
+ );
2376
+ const replaced = /* @__PURE__ */ new Map();
2377
+ if (chunks.size > 0) {
2378
+ const text = Relevance.render(documents, chunks);
2379
+ replaced.set(
2380
+ ContextWindow.makeSegment(instructionsSegment(documents, /* @__PURE__ */ new Set())).digest,
2381
+ text === "" ? [] : [ContextWindow.makeSegment(instructionsSegment(documents, chunks))]
2382
+ );
2383
+ }
2384
+ if (input.memory !== void 0 && dropped.size > 0) {
2385
+ const { digest, render } = input.memory;
2386
+ const text = render(rows.filter((row) => !dropped.has(`${row.key}\0${Digest.digest(row.text)}`)));
2387
+ replaced.set(
2388
+ ContextWindow.makeSegment(memorySegment(render(rows), digest)).digest,
2389
+ text === "" ? [] : [ContextWindow.makeSegment(memorySegment(text, Digest.digest(text)))]
2390
+ );
2391
+ }
2392
+ return advance(state, {
2393
+ withheldFlows: settled.withheld.filter((item) => item.kind === "flow" || item.kind === "skill").map(
2394
+ (item) => item.id
2395
+ ),
2396
+ ...replaced.size === 0 ? {} : {
2397
+ contextWindow: ContextWindow.make({
2398
+ ...state.contextWindow,
2399
+ segments: state.contextWindow.segments.flatMap((segment) => replaced.get(segment.digest) ?? [segment])
2400
+ })
2401
+ }
2402
+ });
2403
+ });
2404
+ const run = (input) => import_effect.Stream.callback((queue) => {
2405
+ let instructions = "";
2406
+ const emit = (event) => import_effect.Effect.flatMap(AgentEvent.Observer, (observe2) => observe2(event)).pipe(
2407
+ import_effect.Effect.andThen(import_effect.Effect.sync(() => {
2408
+ if (event._tag !== "steering-drained") return;
2409
+ const text = event.messages.flatMap((message) => message.content).filter((part) => part.type === "text").map((part) => part.text).join("\n\n");
2410
+ if (text !== "") instructions = CompletionClaim.newest(`${instructions}
2411
+
2412
+ ${text}`.trim());
2413
+ })),
2414
+ import_effect.Effect.andThen(import_effect.Queue.offer(queue, event)),
2415
+ import_effect.Effect.asVoid
2416
+ );
2417
+ const readCompletion = (evidence) => CompletionClaim.read({ ...evidence, task: completionTask(evidence.task, instructions) });
2418
+ const taskOf = (window) => completionTask(Frame.taskText(window), instructions);
2419
+ const monitors = input.monitors ?? Monitor.defaults();
2420
+ const judged = input.judged ?? false;
2421
+ const pinned = input.pinned ?? [];
2422
+ const loop = import_effect.Effect.gen(function* () {
2423
+ const engine = yield* EngineLike.EngineLike;
2424
+ const sandbox = yield* Sandbox.Sandbox;
2425
+ const steering = yield* Steering.Source;
2426
+ let current = input.state;
2427
+ let flows = input.flows.filter((descriptor) => !current.withheldFlows.includes(descriptor.name));
2428
+ if (current.journalVersion !== import_Transcript.journalVersion) {
2429
+ return yield* new import_HarnessError.HarnessError({
2430
+ code: "incompatible_journal",
2431
+ message: `Controller state predates harness journal format ${import_Transcript.journalVersion}; start a new run.`
2432
+ });
2433
+ }
2434
+ if (current.frame === 0) {
2435
+ const limits = Sandbox.withDefaults(sandbox.capabilities, input.limits);
2436
+ yield* emit(
2437
+ new AgentEvent.DisciplineArmed({
2438
+ eventType: eventType.disciplineArmed,
2439
+ readOnlyCap: current.readOnlyCap,
2440
+ maxFrames: current.maxFrames,
2441
+ approvalChannel: current.approvalChannel,
2442
+ modelCallMs: current.modelCallMs,
2443
+ repeatCap: current.repeatCap,
2444
+ narrowingCap: current.narrowingCap,
2445
+ unmovedCap: current.unmovedCap,
2446
+ unresolvedCap: current.unresolvedCap,
2447
+ claimCap: current.claimCap,
2448
+ revalidations: current.revalidations,
2449
+ // Written only when armed, so an unjudged journal keeps the bytes
2450
+ // it had before the switch existed.
2451
+ ...judged ? {
2452
+ judged,
2453
+ relevance: { withholdAt: Relevance.withholdAt, pinned: [...pinned] },
2454
+ monitors: monitors.map(({ at, consecutive, cooldownFrames, id, kind, limit }) => ({
2455
+ id,
2456
+ kind,
2457
+ at,
2458
+ consecutive,
2459
+ cooldownFrames,
2460
+ limit
2461
+ }))
2462
+ } : {},
2463
+ ...input.stance === void 0 ? {} : { stance: input.stance },
2464
+ ...limits
2465
+ })
2466
+ );
2467
+ }
2468
+ const supervision = yield* Supervision.open({
2469
+ session: current.session,
2470
+ engine,
2471
+ emit,
2472
+ monitors,
2473
+ deliver: judged
2474
+ });
2475
+ const realm = yield* import_effect.Effect.suspend(() => {
2476
+ const projections = {};
2477
+ for (const descriptor of input.flows) {
2478
+ projections[descriptor.name] = Cell.project(descriptor);
2479
+ }
2480
+ return sandbox.openRealm === void 0 ? import_effect.Effect.fail(Sandbox.realmUnsupported) : sandbox.openRealm({ flows: projections, limits: input.limits });
2481
+ }).pipe(
2482
+ import_effect.Effect.mapError(
2483
+ (cause) => new import_HarnessError.HarnessError({
2484
+ code: "engine_failed",
2485
+ message: "The run's persistent realm could not be opened",
2486
+ cause
2487
+ })
2488
+ )
2489
+ );
2490
+ for (; ; ) {
2491
+ if (current.failureFrames >= 5) {
2492
+ return yield* new import_HarnessError.HarnessError({
2493
+ code: "model_failed",
2494
+ message: `Runaway guard: ${current.failureFrames} consecutive frames repeated the same failure: ${current.failureKey}`,
2495
+ cause: { _tag: repeatedFailureTag, frames: current.failureFrames }
2496
+ });
2497
+ }
2498
+ if (current.maxFrames > 0 && current.frame >= current.maxFrames) {
2499
+ yield* emit(
2500
+ new AgentEvent.Resolved({
2501
+ eventType: eventType.resolved,
2502
+ message: import_model.ModelRequest.Message.assistant(budgetMessage(current), { stopReason: "stop" })
2503
+ })
2504
+ );
2505
+ return;
2506
+ }
2507
+ const catalog = input.refreshFlows === void 0 ? input.flows : yield* engine.record({
2508
+ name: "flow-catalog",
2509
+ identity: { session: current.session, frame: current.frame, boundary: "flow-catalog" },
2510
+ success: import_effect.Schema.Array(import_registry.Descriptor.FlowDescriptor),
2511
+ execute: input.refreshFlows
2512
+ });
2513
+ current = judged && current.frame === 0 ? yield* withheld(current, catalog, input, engine, emit, taskOf) : current;
2514
+ const shown = catalog.filter((descriptor) => !current.withheldFlows.includes(descriptor.name));
2515
+ if (input.refreshFlows !== void 0 || shown.length !== flows.length) {
2516
+ const previous = teach(ContextWindow.empty(current.contextWindow.modelId), flows, void 0, input.stance);
2517
+ const digests = new Set(previous.segments.map((segment) => segment.digest));
2518
+ current = advance(current, {
2519
+ contextWindow: teach(
2520
+ ContextWindow.make({
2521
+ ...current.contextWindow,
2522
+ segments: current.contextWindow.segments.filter((segment) => !digests.has(segment.digest))
2523
+ }),
2524
+ shown,
2525
+ void 0,
2526
+ input.stance
2527
+ )
2528
+ });
2529
+ flows = shown;
2530
+ }
2531
+ const step = yield* frame(
2532
+ { ...input, state: current, flows },
2533
+ engine,
2534
+ sandbox,
2535
+ realm,
2536
+ steering,
2537
+ emit,
2538
+ readCompletion,
2539
+ supervision,
2540
+ taskOf
2541
+ ).pipe(
2542
+ import_effect.Effect.catch((error) => {
2543
+ const request = permissionRequired(error);
2544
+ if (request === void 0) {
2545
+ return import_effect.Effect.fail(
2546
+ error instanceof import_HarnessError.HarnessError ? error : new import_HarnessError.HarnessError({
2547
+ code: error instanceof Sandbox.SandboxError ? "engine_failed" : "model_failed",
2548
+ message: frameFailureMessage(error),
2549
+ cause: error
2550
+ })
2551
+ );
2552
+ }
2553
+ return import_effect.Effect.gen(function* () {
2554
+ yield* emit(
2555
+ new AgentEvent.PermissionRequired({
2556
+ eventType: eventType.permissionRequired,
2557
+ request
2558
+ })
2559
+ );
2560
+ yield* emit(
2561
+ new AgentEvent.TurnClosed({
2562
+ eventType: eventType.turnClosed,
2563
+ stopReason: "error",
2564
+ outcome: "suspended"
2565
+ })
2566
+ );
2567
+ return {
2568
+ _tag: "Suspend",
2569
+ reason: new EngineLike.SuspendReason({
2570
+ code: "permission-required",
2571
+ message: `Permission ${request.requestId} is required`,
2572
+ // Encoded, not attached: `request` is a class that extends
2573
+ // `Error`, and this reason is journaled inside
2574
+ // `AgentEvent.Suspended`. A live Error there has no JSON form,
2575
+ // so encoding it dies with a schema failure that replaces the
2576
+ // park it was carrying.
2577
+ details: encodePermissionRequired(request)
2578
+ })
2579
+ };
2580
+ });
2581
+ }),
2582
+ import_effect.Effect.onInterrupt(
2583
+ () => import_effect.Effect.gen(function* () {
2584
+ yield* emit(new AgentEvent.Aborted({ eventType: eventType.aborted, reason: "Cell frame interrupted" }));
2585
+ yield* emit(
2586
+ new AgentEvent.TurnClosed({
2587
+ eventType: eventType.turnClosed,
2588
+ stopReason: "aborted",
2589
+ outcome: "aborted"
2590
+ })
2591
+ );
2592
+ })
2593
+ )
2594
+ );
2595
+ if (step._tag === "Done") return;
2596
+ if (step._tag === "Suspend") {
2597
+ yield* emit(new AgentEvent.Suspended({ eventType: eventType.suspended, reason: step.reason }));
2598
+ return yield* engine.suspend(step.reason);
2599
+ }
2600
+ for (const flow of current.withheldFlows) {
2601
+ if (step.state.withheldFlows.includes(flow)) continue;
2602
+ yield* emit(
2603
+ new AgentEvent.RelevanceRestored({
2604
+ eventType: eventType.relevanceRestored,
2605
+ scope: current.session,
2606
+ frame: current.frame,
2607
+ flow
2608
+ })
2609
+ );
2610
+ }
2611
+ current = step.state;
2612
+ }
2613
+ });
2614
+ return import_effect.Effect.onExit(import_effect.Effect.scoped(loop), (exit) => import_effect.Effect.asVoid(
2615
+ exit._tag === "Success" ? import_effect.Queue.end(queue) : import_effect.Queue.failCause(queue, exit.cause)
2616
+ ));
2617
+ });
2618
+ //# sourceMappingURL=CellTurn.js.map