effect-agent 0.1.0-beta.85 → 0.1.0-beta.86

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 (751) hide show
  1. package/dist/Agent-CN0EWRsR.d.mts +226 -0
  2. package/dist/Agent-RklVROrm.mjs +83 -0
  3. package/dist/Agent-RklVROrm.mjs.map +1 -0
  4. package/dist/AgentError-CggcAQ7V.d.mts +101 -0
  5. package/dist/AgentPolicy-CetmQrf3.d.mts +96 -0
  6. package/dist/AgentRuntime-BLyETCPo.mjs +4562 -0
  7. package/dist/AgentRuntime-BLyETCPo.mjs.map +1 -0
  8. package/dist/AgentRuntime-uxR_a4VM.d.mts +346 -0
  9. package/dist/AgentUpdates-DMJ-_xow.d.mts +53 -0
  10. package/dist/ContextCompactor-Dxu5zhOL.d.mts +161 -0
  11. package/dist/ContextWindow-DRQ5Mbm2.d.mts +58 -0
  12. package/dist/DurableAgentRuntime-sOrBVu4B.mjs +6366 -0
  13. package/dist/DurableAgentRuntime-sOrBVu4B.mjs.map +1 -0
  14. package/dist/DurableFailpoint-Oinuuedm.d.mts +41 -0
  15. package/dist/DurableStep-Cry_iol4.d.mts +103 -0
  16. package/dist/Ephemeral.d.mts +22 -0
  17. package/dist/Ephemeral.mjs +22 -0
  18. package/dist/Ephemeral.mjs.map +1 -0
  19. package/dist/EventSource-OqS_P9ug.d.mts +51 -0
  20. package/dist/Identifiers-CN2s30fF.d.mts +40 -0
  21. package/dist/MemoryNamespace-BbRW5p71.d.mts +36 -0
  22. package/dist/MemoryReference-B8Q3UJoJ.d.mts +79 -0
  23. package/dist/Messaging-CkcIdt4I.d.mts +490 -0
  24. package/dist/MessagingHost-CRk0kXzT.d.mts +246 -0
  25. package/dist/MessagingHost-CWi_PP3g.mjs +137 -0
  26. package/dist/MessagingHost-CWi_PP3g.mjs.map +1 -0
  27. package/dist/OperationAuthorizer-TzcQtpX5.d.mts +61 -0
  28. package/dist/Output-D6SkedVx.d.mts +25 -0
  29. package/dist/PageCapture-Df8Xwskw.d.mts +583 -0
  30. package/dist/PageScreenshot-BpgZKAxl.d.mts +48 -0
  31. package/dist/PreparedInputAdmission-C4HbjHgl.d.mts +38 -0
  32. package/dist/Receipt-BAHyigAF.d.mts +33 -0
  33. package/dist/Records-BAGkekt8.d.mts +3570 -0
  34. package/dist/RunEvent-DIrzkjLr.d.mts +460 -0
  35. package/dist/RunEventSink-D5aVhISG.d.mts +108 -0
  36. package/dist/RunJournal-Cgg1kNvc.mjs +825 -0
  37. package/dist/RunJournal-Cgg1kNvc.mjs.map +1 -0
  38. package/dist/RunOptions-g1aigcKI.d.mts +915 -0
  39. package/dist/RunPolicyUsage-ClZxyR46.d.mts +21 -0
  40. package/dist/Sandbox-CEsDWBLq.d.mts +173 -0
  41. package/dist/Schedule-H3SEYX9g.d.mts +842 -0
  42. package/dist/Scheduling-C9aIP8zT.mjs +691 -0
  43. package/dist/Scheduling-C9aIP8zT.mjs.map +1 -0
  44. package/dist/Subagent-Cy_hU1tv.mjs +1469 -0
  45. package/dist/Subagent-Cy_hU1tv.mjs.map +1 -0
  46. package/dist/Subagent-DyfzHNdv.d.mts +826 -0
  47. package/dist/SubagentContract-DdT7Cqe6.d.mts +116 -0
  48. package/dist/SubagentHost-CJUBQlcc.d.mts +140 -0
  49. package/dist/Subscription-BEP8oQO5.d.mts +921 -0
  50. package/dist/SubscriptionInput-vAAOBrK7.d.mts +41 -0
  51. package/dist/Thread-DOBQ0QUY.d.mts +96 -0
  52. package/dist/ThreadHistory-tS1KwxHR.d.mts +60 -0
  53. package/dist/ToolBroker-DWs4tZra.d.mts +133 -0
  54. package/dist/ToolExposure-9uF_Yo0T.mjs +10 -0
  55. package/dist/ToolExposure-9uF_Yo0T.mjs.map +1 -0
  56. package/dist/ToolExposure-C93U1sPu.mjs +30 -0
  57. package/dist/ToolExposure-C93U1sPu.mjs.map +1 -0
  58. package/dist/ToolExposure-UCN12eCd.d.mts +39 -0
  59. package/dist/ToolExposure-r2eOWk4F.d.mts +46 -0
  60. package/dist/ToolExposure.d.mts +6 -5
  61. package/dist/ToolExposure.mjs +17 -9
  62. package/dist/ToolExposure.mjs.map +1 -1
  63. package/dist/ToolReconciler-DQVaJfpE.d.mts +76 -0
  64. package/dist/ToolResult-DmmgoChv.d.mts +61 -0
  65. package/dist/Usage-Dx0aknfk.d.mts +121 -0
  66. package/dist/WakeScheduler-EjUF-GhC.d.mts +56 -0
  67. package/dist/Worker-CaPYykpe.d.mts +228 -0
  68. package/dist/agent-registration-CWDMOAZA.mjs +172 -0
  69. package/dist/agent-registration-CWDMOAZA.mjs.map +1 -0
  70. package/dist/capabilities/Approval.d.mts +114 -0
  71. package/dist/capabilities/Approval.mjs +226 -0
  72. package/dist/capabilities/Approval.mjs.map +1 -0
  73. package/dist/capabilities/Budget.d.mts +112 -0
  74. package/dist/capabilities/Budget.mjs +346 -0
  75. package/dist/capabilities/Budget.mjs.map +1 -0
  76. package/dist/capabilities/CodeMode.d.mts +157 -0
  77. package/dist/capabilities/CodeMode.mjs +522 -0
  78. package/dist/capabilities/CodeMode.mjs.map +1 -0
  79. package/dist/capabilities/Commands.d.mts +55 -0
  80. package/dist/capabilities/Commands.mjs +57 -0
  81. package/dist/capabilities/Commands.mjs.map +1 -0
  82. package/dist/capabilities/ContextTools.d.mts +321 -0
  83. package/dist/capabilities/ContextTools.mjs +126 -0
  84. package/dist/capabilities/ContextTools.mjs.map +1 -0
  85. package/dist/capabilities/Mcp.d.mts +108 -0
  86. package/dist/capabilities/Mcp.mjs +260 -0
  87. package/dist/capabilities/Mcp.mjs.map +1 -0
  88. package/dist/capabilities/McpClient.d.mts +115 -0
  89. package/dist/capabilities/McpClient.mjs +506 -0
  90. package/dist/capabilities/McpClient.mjs.map +1 -0
  91. package/dist/capabilities/MemoryNotes.d.mts +424 -0
  92. package/dist/capabilities/MemoryNotes.mjs +128 -0
  93. package/dist/capabilities/MemoryNotes.mjs.map +1 -0
  94. package/dist/capabilities/Messaging.d.mts +3 -0
  95. package/dist/capabilities/Messaging.mjs +151 -0
  96. package/dist/capabilities/Messaging.mjs.map +1 -0
  97. package/dist/capabilities/ModelContext.d.mts +89 -0
  98. package/dist/capabilities/ModelContext.mjs +168 -0
  99. package/dist/capabilities/ModelContext.mjs.map +1 -0
  100. package/dist/capabilities/Redaction.d.mts +37 -0
  101. package/dist/capabilities/Redaction.mjs +104 -0
  102. package/dist/capabilities/Redaction.mjs.map +1 -0
  103. package/dist/capabilities/Remembering.d.mts +434 -0
  104. package/dist/capabilities/Remembering.mjs +290 -0
  105. package/dist/capabilities/Remembering.mjs.map +1 -0
  106. package/dist/capabilities/RunHooks.d.mts +82 -0
  107. package/dist/capabilities/RunHooks.mjs +144 -0
  108. package/dist/capabilities/RunHooks.mjs.map +1 -0
  109. package/dist/capabilities/SemanticMemory.d.mts +431 -0
  110. package/dist/capabilities/SemanticMemory.mjs +315 -0
  111. package/dist/capabilities/SemanticMemory.mjs.map +1 -0
  112. package/dist/capabilities/Subagent.d.mts +4 -0
  113. package/dist/capabilities/Subagent.mjs +5 -0
  114. package/dist/capabilities/SubagentReservations.d.mts +186 -0
  115. package/dist/capabilities/SubagentReservations.mjs +479 -0
  116. package/dist/capabilities/SubagentReservations.mjs.map +1 -0
  117. package/dist/capabilities/ToolDiscovery.d.mts +109 -0
  118. package/dist/capabilities/ToolDiscovery.mjs +211 -0
  119. package/dist/capabilities/ToolDiscovery.mjs.map +1 -0
  120. package/dist/capabilities/WebCapture.d.mts +163 -0
  121. package/dist/capabilities/WebCapture.mjs +335 -0
  122. package/dist/capabilities/WebCapture.mjs.map +1 -0
  123. package/dist/capabilities/WebSearch.d.mts +71 -0
  124. package/dist/capabilities/WebSearch.mjs +112 -0
  125. package/dist/capabilities/WebSearch.mjs.map +1 -0
  126. package/dist/compaction-C2OTceKw.mjs +505 -0
  127. package/dist/compaction-C2OTceKw.mjs.map +1 -0
  128. package/dist/core/Agent.d.mts +2 -0
  129. package/dist/core/Agent.mjs +2 -0
  130. package/dist/core/AgentError.d.mts +2 -0
  131. package/dist/core/AgentError.mjs +117 -0
  132. package/dist/core/AgentError.mjs.map +1 -0
  133. package/dist/core/AgentPolicy.d.mts +2 -0
  134. package/dist/core/AgentPolicy.mjs +94 -0
  135. package/dist/core/AgentPolicy.mjs.map +1 -0
  136. package/dist/core/AgentUpdates.d.mts +2 -0
  137. package/dist/core/AgentUpdates.mjs +63 -0
  138. package/dist/core/AgentUpdates.mjs.map +1 -0
  139. package/dist/core/IdGenerator.d.mts +26 -0
  140. package/dist/core/IdGenerator.mjs +27 -0
  141. package/dist/core/IdGenerator.mjs.map +1 -0
  142. package/dist/core/Identifiers.d.mts +2 -0
  143. package/dist/core/Identifiers.mjs +43 -0
  144. package/dist/core/Identifiers.mjs.map +1 -0
  145. package/dist/core/Memory.d.mts +57 -0
  146. package/dist/core/Memory.mjs +203 -0
  147. package/dist/core/Memory.mjs.map +1 -0
  148. package/dist/core/MemoryNamespace.d.mts +2 -0
  149. package/dist/core/MemoryNamespace.mjs +116 -0
  150. package/dist/core/MemoryNamespace.mjs.map +1 -0
  151. package/dist/core/MemoryReference.d.mts +2 -0
  152. package/dist/core/MemoryReference.mjs +109 -0
  153. package/dist/core/MemoryReference.mjs.map +1 -0
  154. package/dist/core/MemoryRevalidation.d.mts +65 -0
  155. package/dist/core/MemoryRevalidation.mjs +126 -0
  156. package/dist/core/MemoryRevalidation.mjs.map +1 -0
  157. package/dist/core/MemoryStore.d.mts +186 -0
  158. package/dist/core/MemoryStore.mjs +243 -0
  159. package/dist/core/MemoryStore.mjs.map +1 -0
  160. package/dist/core/Receipt.d.mts +2 -0
  161. package/dist/core/Receipt.mjs +36 -0
  162. package/dist/core/Receipt.mjs.map +1 -0
  163. package/dist/core/RememberingStore.d.mts +1562 -0
  164. package/dist/core/RememberingStore.mjs +190 -0
  165. package/dist/core/RememberingStore.mjs.map +1 -0
  166. package/dist/core/RunEvent.d.mts +2 -0
  167. package/dist/core/RunEvent.mjs +337 -0
  168. package/dist/core/RunEvent.mjs.map +1 -0
  169. package/dist/core/RunPolicyUsage.d.mts +2 -0
  170. package/dist/core/RunPolicyUsage.mjs +21 -0
  171. package/dist/core/RunPolicyUsage.mjs.map +1 -0
  172. package/dist/core/SemanticMemoryIndex.d.mts +826 -0
  173. package/dist/core/SemanticMemoryIndex.mjs +185 -0
  174. package/dist/core/SemanticMemoryIndex.mjs.map +1 -0
  175. package/dist/core/SemanticMemoryRevalidation.d.mts +45 -0
  176. package/dist/core/SemanticMemoryRevalidation.mjs +191 -0
  177. package/dist/core/SemanticMemoryRevalidation.mjs.map +1 -0
  178. package/dist/core/SubagentContract.d.mts +2 -0
  179. package/dist/core/SubagentContract.mjs +148 -0
  180. package/dist/core/SubagentContract.mjs.map +1 -0
  181. package/dist/core/Thread.d.mts +2 -0
  182. package/dist/core/Thread.mjs +250 -0
  183. package/dist/core/Thread.mjs.map +1 -0
  184. package/dist/core/ToolResult.d.mts +2 -0
  185. package/dist/core/ToolResult.mjs +140 -0
  186. package/dist/core/ToolResult.mjs.map +1 -0
  187. package/dist/core/Usage.d.mts +2 -0
  188. package/dist/core/Usage.mjs +319 -0
  189. package/dist/core/Usage.mjs.map +1 -0
  190. package/dist/core/Worker.d.mts +3 -0
  191. package/dist/core/Worker.mjs +147 -0
  192. package/dist/core/Worker.mjs.map +1 -0
  193. package/dist/durable/ActivityStore.d.mts +116 -0
  194. package/dist/durable/ActivityStore.mjs +131 -0
  195. package/dist/durable/ActivityStore.mjs.map +1 -0
  196. package/dist/durable/Admin.d.mts +2 -0
  197. package/dist/durable/Admin.mjs +328 -0
  198. package/dist/durable/Admin.mjs.map +1 -0
  199. package/dist/durable/AgentRegistration.d.mts +2 -0
  200. package/dist/durable/AgentRegistration.mjs +14 -0
  201. package/dist/durable/AgentRegistration.mjs.map +1 -0
  202. package/dist/durable/Certification.d.mts +111 -0
  203. package/dist/durable/Certification.mjs +159 -0
  204. package/dist/durable/Certification.mjs.map +1 -0
  205. package/dist/durable/CommittedActivity.d.mts +62 -0
  206. package/dist/durable/CommittedActivity.mjs +159 -0
  207. package/dist/durable/CommittedActivity.mjs.map +1 -0
  208. package/dist/durable/Digest.d.mts +2 -0
  209. package/dist/durable/Digest.mjs +50 -0
  210. package/dist/durable/Digest.mjs.map +1 -0
  211. package/dist/durable/DurableAgentRuntime.d.mts +3 -0
  212. package/dist/durable/DurableAgentRuntime.mjs +3 -0
  213. package/dist/durable/DurableFailpoint.d.mts +2 -0
  214. package/dist/durable/DurableFailpoint.mjs +94 -0
  215. package/dist/durable/DurableFailpoint.mjs.map +1 -0
  216. package/dist/durable/DurableFailpointTestControl.d.mts +15 -0
  217. package/dist/durable/DurableFailpointTestControl.mjs +19 -0
  218. package/dist/durable/DurableFailpointTestControl.mjs.map +1 -0
  219. package/dist/durable/EventSource.d.mts +2 -0
  220. package/dist/durable/EventSource.mjs +65 -0
  221. package/dist/durable/EventSource.mjs.map +1 -0
  222. package/dist/durable/GitHubWorkflowSource.d.mts +144 -0
  223. package/dist/durable/GitHubWorkflowSource.mjs +209 -0
  224. package/dist/durable/GitHubWorkflowSource.mjs.map +1 -0
  225. package/dist/durable/MessageDelivery.d.mts +492 -0
  226. package/dist/durable/MessageDelivery.mjs +495 -0
  227. package/dist/durable/MessageDelivery.mjs.map +1 -0
  228. package/dist/durable/MessageDeliveryStoreConformance.d.mts +358 -0
  229. package/dist/durable/MessageDeliveryStoreConformance.mjs +243 -0
  230. package/dist/durable/MessageDeliveryStoreConformance.mjs.map +1 -0
  231. package/dist/durable/OperationAuthorizer.d.mts +2 -0
  232. package/dist/durable/OperationAuthorizer.mjs +70 -0
  233. package/dist/durable/OperationAuthorizer.mjs.map +1 -0
  234. package/dist/durable/PersistentHistory.d.mts +16 -0
  235. package/dist/durable/PersistentHistory.mjs +125 -0
  236. package/dist/durable/PersistentHistory.mjs.map +1 -0
  237. package/dist/durable/PreparedInputAdmission.d.mts +2 -0
  238. package/dist/durable/PreparedInputAdmission.mjs +34 -0
  239. package/dist/durable/PreparedInputAdmission.mjs.map +1 -0
  240. package/dist/durable/Records.d.mts +2 -0
  241. package/dist/durable/Records.mjs +795 -0
  242. package/dist/durable/Records.mjs.map +1 -0
  243. package/dist/durable/Recovery.d.mts +2 -0
  244. package/dist/durable/Recovery.mjs +739 -0
  245. package/dist/durable/Recovery.mjs.map +1 -0
  246. package/dist/durable/RunJournal.d.mts +2 -0
  247. package/dist/durable/RunJournal.mjs +2 -0
  248. package/dist/durable/Schedule.d.mts +2 -0
  249. package/dist/durable/Schedule.mjs +382 -0
  250. package/dist/durable/Schedule.mjs.map +1 -0
  251. package/dist/durable/ScheduleStoreConformance.d.mts +18 -0
  252. package/dist/durable/ScheduleStoreConformance.mjs +420 -0
  253. package/dist/durable/ScheduleStoreConformance.mjs.map +1 -0
  254. package/dist/durable/ScheduleTransition.d.mts +24 -0
  255. package/dist/durable/ScheduleTransition.mjs +180 -0
  256. package/dist/durable/ScheduleTransition.mjs.map +1 -0
  257. package/dist/durable/Scheduling.d.mts +54 -0
  258. package/dist/durable/Scheduling.mjs +2 -0
  259. package/dist/durable/SqlMemoryStore.d.mts +30 -0
  260. package/dist/durable/SqlMemoryStore.mjs +435 -0
  261. package/dist/durable/SqlMemoryStore.mjs.map +1 -0
  262. package/dist/durable/SqlMessageDeliveryStore.d.mts +40 -0
  263. package/dist/durable/SqlMessageDeliveryStore.mjs +167 -0
  264. package/dist/durable/SqlMessageDeliveryStore.mjs.map +1 -0
  265. package/dist/durable/SqlStorageV2Upgrade.d.mts +22 -0
  266. package/dist/durable/SqlStorageV2Upgrade.mjs +459 -0
  267. package/dist/durable/SqlStorageV2Upgrade.mjs.map +1 -0
  268. package/dist/durable/SqlSubscriptionStore.d.mts +63 -0
  269. package/dist/durable/SqlSubscriptionStore.mjs +751 -0
  270. package/dist/durable/SqlSubscriptionStore.mjs.map +1 -0
  271. package/dist/durable/SubmissionLedger.d.mts +3 -0
  272. package/dist/durable/SubmissionLedger.mjs +914 -0
  273. package/dist/durable/SubmissionLedger.mjs.map +1 -0
  274. package/dist/durable/SubmissionLedgerConformance.d.mts +30 -0
  275. package/dist/durable/SubmissionLedgerConformance.mjs +1986 -0
  276. package/dist/durable/SubmissionLedgerConformance.mjs.map +1 -0
  277. package/dist/durable/SubmissionStatus.d.mts +2 -0
  278. package/dist/durable/SubmissionStatus.mjs +18 -0
  279. package/dist/durable/SubmissionStatus.mjs.map +1 -0
  280. package/dist/durable/Subscription.d.mts +2 -0
  281. package/dist/durable/Subscription.mjs +360 -0
  282. package/dist/durable/Subscription.mjs.map +1 -0
  283. package/dist/durable/SubscriptionInput.d.mts +2 -0
  284. package/dist/durable/SubscriptionInput.mjs +52 -0
  285. package/dist/durable/SubscriptionInput.mjs.map +1 -0
  286. package/dist/durable/SubscriptionStoreConformance.d.mts +17 -0
  287. package/dist/durable/SubscriptionStoreConformance.mjs +625 -0
  288. package/dist/durable/SubscriptionStoreConformance.mjs.map +1 -0
  289. package/dist/durable/SubscriptionTools.d.mts +273 -0
  290. package/dist/durable/SubscriptionTools.mjs +190 -0
  291. package/dist/durable/SubscriptionTools.mjs.map +1 -0
  292. package/dist/durable/SubscriptionTransition.d.mts +21 -0
  293. package/dist/durable/SubscriptionTransition.mjs +148 -0
  294. package/dist/durable/SubscriptionTransition.mjs.map +1 -0
  295. package/dist/durable/Subscriptions.d.mts +73 -0
  296. package/dist/durable/Subscriptions.mjs +627 -0
  297. package/dist/durable/Subscriptions.mjs.map +1 -0
  298. package/dist/durable/ThreadContextHistory.d.mts +32 -0
  299. package/dist/durable/ThreadContextHistory.mjs +152 -0
  300. package/dist/durable/ThreadContextHistory.mjs.map +1 -0
  301. package/dist/durable/ThreadContextHistoryProjection.d.mts +60 -0
  302. package/dist/durable/ThreadContextHistoryProjection.mjs +149 -0
  303. package/dist/durable/ThreadContextHistoryProjection.mjs.map +1 -0
  304. package/dist/durable/ThreadInvariants.d.mts +74 -0
  305. package/dist/durable/ThreadInvariants.mjs +200 -0
  306. package/dist/durable/ThreadInvariants.mjs.map +1 -0
  307. package/dist/durable/ThreadProjection.d.mts +78 -0
  308. package/dist/durable/ThreadProjection.mjs +158 -0
  309. package/dist/durable/ThreadProjection.mjs.map +1 -0
  310. package/dist/durable/ThreadProjectionMaintenance.d.mts +49 -0
  311. package/dist/durable/ThreadProjectionMaintenance.mjs +33 -0
  312. package/dist/durable/ThreadProjectionMaintenance.mjs.map +1 -0
  313. package/dist/durable/ThreadStore.d.mts +2 -0
  314. package/dist/durable/ThreadStore.mjs +147 -0
  315. package/dist/durable/ThreadStore.mjs.map +1 -0
  316. package/dist/durable/ThreadStoreConformance.d.mts +29 -0
  317. package/dist/durable/ThreadStoreConformance.mjs +248 -0
  318. package/dist/durable/ThreadStoreConformance.mjs.map +1 -0
  319. package/dist/durable/ToolReconciler.d.mts +2 -0
  320. package/dist/durable/ToolReconciler.mjs +81 -0
  321. package/dist/durable/ToolReconciler.mjs.map +1 -0
  322. package/dist/durable/WakeScheduler.d.mts +2 -0
  323. package/dist/durable/WakeScheduler.mjs +85 -0
  324. package/dist/durable/WakeScheduler.mjs.map +1 -0
  325. package/dist/durable/WorkerHost.d.mts +129 -0
  326. package/dist/durable/WorkerHost.mjs +77 -0
  327. package/dist/durable/WorkerHost.mjs.map +1 -0
  328. package/dist/engine/AgentRuntime.d.mts +2 -0
  329. package/dist/engine/AgentRuntime.mjs +2 -0
  330. package/dist/engine/Compaction.d.mts +7 -0
  331. package/dist/engine/Compaction.mjs +16 -0
  332. package/dist/engine/Compaction.mjs.map +1 -0
  333. package/dist/engine/ContextCompactor.d.mts +2 -0
  334. package/dist/engine/ContextCompactor.mjs +119 -0
  335. package/dist/engine/ContextCompactor.mjs.map +1 -0
  336. package/dist/engine/ContextHistory.d.mts +65 -0
  337. package/dist/engine/ContextHistory.mjs +76 -0
  338. package/dist/engine/ContextHistory.mjs.map +1 -0
  339. package/dist/engine/ContextWindow.d.mts +2 -0
  340. package/dist/engine/ContextWindow.mjs +59 -0
  341. package/dist/engine/ContextWindow.mjs.map +1 -0
  342. package/dist/engine/DurableStep.d.mts +2 -0
  343. package/dist/engine/DurableStep.mjs +62 -0
  344. package/dist/engine/DurableStep.mjs.map +1 -0
  345. package/dist/engine/MessagingHost.d.mts +2 -0
  346. package/dist/engine/MessagingHost.mjs +2 -0
  347. package/dist/engine/Output.d.mts +2 -0
  348. package/dist/engine/Output.mjs +8 -0
  349. package/dist/engine/Output.mjs.map +1 -0
  350. package/dist/engine/RunEventSink.d.mts +2 -0
  351. package/dist/engine/RunEventSink.mjs +22 -0
  352. package/dist/engine/RunEventSink.mjs.map +1 -0
  353. package/dist/engine/RunOptions.d.mts +2 -0
  354. package/dist/engine/RunOptions.mjs +122 -0
  355. package/dist/engine/RunOptions.mjs.map +1 -0
  356. package/dist/engine/SubagentHost.d.mts +2 -0
  357. package/dist/engine/SubagentHost.mjs +72 -0
  358. package/dist/engine/SubagentHost.mjs.map +1 -0
  359. package/dist/engine/ThreadHistory.d.mts +2 -0
  360. package/dist/engine/ThreadHistory.mjs +67 -0
  361. package/dist/engine/ThreadHistory.mjs.map +1 -0
  362. package/dist/engine/ToolBroker.d.mts +2 -0
  363. package/dist/engine/ToolBroker.mjs +42 -0
  364. package/dist/engine/ToolBroker.mjs.map +1 -0
  365. package/dist/foreign-diagnostic-DBQ1XHKh.mjs +37 -0
  366. package/dist/foreign-diagnostic-DBQ1XHKh.mjs.map +1 -0
  367. package/dist/index.d.mts +88 -54
  368. package/dist/index.mjs +97 -54
  369. package/dist/output-contract-BC7tjlGw.mjs +84 -0
  370. package/dist/output-contract-BC7tjlGw.mjs.map +1 -0
  371. package/dist/rolldown-runtime-D7D4PA-g.mjs +13 -0
  372. package/dist/sandbox/CodeExecutor.d.mts +194 -0
  373. package/dist/sandbox/CodeExecutor.mjs +278 -0
  374. package/dist/sandbox/CodeExecutor.mjs.map +1 -0
  375. package/dist/sandbox/InteractiveBrowser.d.mts +142 -0
  376. package/dist/sandbox/InteractiveBrowser.mjs +165 -0
  377. package/dist/sandbox/InteractiveBrowser.mjs.map +1 -0
  378. package/dist/sandbox/PageCapture.d.mts +2 -0
  379. package/dist/sandbox/PageCapture.mjs +450 -0
  380. package/dist/sandbox/PageCapture.mjs.map +1 -0
  381. package/dist/sandbox/PageCrawl.d.mts +88 -0
  382. package/dist/sandbox/PageCrawl.mjs +124 -0
  383. package/dist/sandbox/PageCrawl.mjs.map +1 -0
  384. package/dist/sandbox/PageScreenshot.d.mts +2 -0
  385. package/dist/sandbox/PageScreenshot.mjs +53 -0
  386. package/dist/sandbox/PageScreenshot.mjs.map +1 -0
  387. package/dist/sandbox/ProtectedBrowser.d.mts +252 -0
  388. package/dist/sandbox/ProtectedBrowser.mjs +270 -0
  389. package/dist/sandbox/ProtectedBrowser.mjs.map +1 -0
  390. package/dist/sandbox/Sandbox.d.mts +2 -0
  391. package/dist/sandbox/Sandbox.mjs +208 -0
  392. package/dist/sandbox/Sandbox.mjs.map +1 -0
  393. package/dist/utf8-BYfhEkcj.mjs +11 -0
  394. package/dist/utf8-BYfhEkcj.mjs.map +1 -0
  395. package/dist/utf8-DchGZRBd.mjs +23 -0
  396. package/dist/utf8-DchGZRBd.mjs.map +1 -0
  397. package/package.json +1 -1
  398. package/src/Ephemeral.ts +17 -0
  399. package/src/ToolExposure.ts +2 -2
  400. package/src/capabilities/Approval.ts +352 -0
  401. package/src/capabilities/Budget.ts +536 -0
  402. package/src/capabilities/CodeMode.ts +1090 -0
  403. package/src/capabilities/Commands.ts +86 -0
  404. package/src/capabilities/ContextTools.ts +184 -0
  405. package/src/capabilities/Mcp.ts +427 -0
  406. package/src/capabilities/McpClient.ts +967 -0
  407. package/src/capabilities/MemoryNotes.ts +174 -0
  408. package/src/capabilities/Messaging.ts +261 -0
  409. package/src/capabilities/ModelContext.ts +354 -0
  410. package/src/capabilities/Redaction.ts +157 -0
  411. package/src/capabilities/Remembering.ts +550 -0
  412. package/src/capabilities/RunHooks.ts +280 -0
  413. package/src/capabilities/SemanticMemory.ts +447 -0
  414. package/src/capabilities/Subagent.ts +2277 -0
  415. package/src/capabilities/SubagentReservations.ts +850 -0
  416. package/src/capabilities/ToolDiscovery.ts +339 -0
  417. package/src/capabilities/WebCapture.ts +722 -0
  418. package/src/capabilities/WebSearch.ts +184 -0
  419. package/src/capabilities/internal/subagent-background.ts +1106 -0
  420. package/src/capabilities/internal/subagent-contract.ts +142 -0
  421. package/src/capabilities/internal/subagent-policy.ts +235 -0
  422. package/src/capabilities/internal/subagent-reporting.ts +261 -0
  423. package/src/capabilities/internal/utf8.ts +10 -0
  424. package/src/core/Agent.ts +575 -0
  425. package/src/core/AgentError.ts +152 -0
  426. package/src/core/AgentPolicy.ts +153 -0
  427. package/src/core/AgentUpdates.ts +100 -0
  428. package/src/core/IdGenerator.ts +39 -0
  429. package/src/core/Identifiers.ts +48 -0
  430. package/src/core/Memory.ts +290 -0
  431. package/src/core/MemoryNamespace.ts +196 -0
  432. package/src/core/MemoryReference.ts +121 -0
  433. package/src/core/MemoryRevalidation.ts +185 -0
  434. package/src/core/MemoryStore.ts +368 -0
  435. package/src/core/Messaging.ts +90 -0
  436. package/src/core/Receipt.ts +42 -0
  437. package/src/core/RememberingStore.ts +300 -0
  438. package/src/core/RunEvent.ts +366 -0
  439. package/src/core/RunPolicyUsage.ts +17 -0
  440. package/src/core/SemanticMemoryIndex.ts +250 -0
  441. package/src/core/SemanticMemoryRevalidation.ts +254 -0
  442. package/src/core/SubagentContract.ts +196 -0
  443. package/src/core/Thread.ts +371 -0
  444. package/src/core/ToolExposure.ts +74 -0
  445. package/src/core/ToolResult.ts +170 -0
  446. package/src/core/Usage.ts +529 -0
  447. package/src/core/Worker.ts +173 -0
  448. package/src/core/internal/agent-updates.ts +32 -0
  449. package/src/core/internal/utf8.ts +23 -0
  450. package/src/durable/ActivityStore.ts +160 -0
  451. package/src/durable/Admin.ts +496 -0
  452. package/src/durable/AgentRegistration.ts +13 -0
  453. package/src/durable/Certification.ts +210 -0
  454. package/src/durable/CommittedActivity.ts +296 -0
  455. package/src/durable/Digest.ts +93 -0
  456. package/src/durable/DurableAgentRuntime.ts +10328 -0
  457. package/src/durable/DurableFailpoint.ts +103 -0
  458. package/src/durable/DurableFailpointTestControl.ts +39 -0
  459. package/src/durable/EventSource.ts +172 -0
  460. package/src/durable/GitHubWorkflowSource.ts +453 -0
  461. package/src/durable/MessageDelivery.ts +708 -0
  462. package/src/durable/MessageDeliveryStoreConformance.ts +363 -0
  463. package/src/durable/OperationAuthorizer.ts +85 -0
  464. package/src/durable/PersistentHistory.ts +260 -0
  465. package/src/durable/PreparedInputAdmission.ts +44 -0
  466. package/src/durable/Records.ts +1010 -0
  467. package/src/durable/Recovery.ts +1018 -0
  468. package/src/durable/RunJournal.ts +1479 -0
  469. package/src/durable/Schedule.ts +504 -0
  470. package/src/durable/ScheduleStoreConformance.ts +638 -0
  471. package/src/durable/ScheduleTransition.ts +265 -0
  472. package/src/durable/Scheduling.ts +1077 -0
  473. package/src/durable/SqlMemoryStore.ts +774 -0
  474. package/src/durable/SqlMessageDeliveryStore.ts +302 -0
  475. package/src/durable/SqlStorageV2Upgrade.ts +500 -0
  476. package/src/durable/SqlSubscriptionStore.ts +1440 -0
  477. package/src/durable/SubmissionLedger.ts +1201 -0
  478. package/src/durable/SubmissionLedgerConformance.ts +4579 -0
  479. package/src/durable/SubmissionStatus.ts +14 -0
  480. package/src/durable/Subscription.ts +544 -0
  481. package/src/durable/SubscriptionInput.ts +144 -0
  482. package/src/durable/SubscriptionStoreConformance.ts +945 -0
  483. package/src/durable/SubscriptionTools.ts +327 -0
  484. package/src/durable/SubscriptionTransition.ts +302 -0
  485. package/src/durable/Subscriptions.ts +1210 -0
  486. package/src/durable/ThreadContextHistory.ts +227 -0
  487. package/src/durable/ThreadContextHistoryProjection.ts +216 -0
  488. package/src/durable/ThreadInvariants.ts +442 -0
  489. package/src/durable/ThreadProjection.ts +269 -0
  490. package/src/durable/ThreadProjectionMaintenance.ts +67 -0
  491. package/src/durable/ThreadStore.ts +242 -0
  492. package/src/durable/ThreadStoreConformance.ts +710 -0
  493. package/src/durable/ToolReconciler.ts +105 -0
  494. package/src/durable/WakeScheduler.ts +134 -0
  495. package/src/durable/WorkerHost.ts +171 -0
  496. package/src/durable/internal/agent-registration.ts +525 -0
  497. package/src/durable/internal/agent-updates.ts +302 -0
  498. package/src/durable/internal/foreign-diagnostic.ts +47 -0
  499. package/src/durable/internal/journal-checkpoint.ts +104 -0
  500. package/src/durable/internal/journal-metadata.ts +107 -0
  501. package/src/durable/internal/messaging-host.ts +608 -0
  502. package/src/durable/internal/schedule-time.ts +303 -0
  503. package/src/durable/internal/storage-v2-layout.ts +163 -0
  504. package/src/durable/internal/storage-v2.ts +73 -0
  505. package/src/durable/internal/worker-host.ts +2467 -0
  506. package/src/durable/internal/worker-runtime.ts +9 -0
  507. package/src/engine/AgentRuntime.ts +37 -0
  508. package/src/engine/Compaction.ts +11 -0
  509. package/src/engine/ContextCompactor.ts +277 -0
  510. package/src/engine/ContextHistory.ts +73 -0
  511. package/src/engine/ContextWindow.ts +72 -0
  512. package/src/engine/DurableStep.ts +132 -0
  513. package/src/engine/MessagingHost.ts +110 -0
  514. package/src/engine/Output.ts +2 -0
  515. package/src/engine/RunEventSink.ts +132 -0
  516. package/src/engine/RunOptions.ts +1077 -0
  517. package/src/engine/SubagentHost.ts +181 -0
  518. package/src/engine/ThreadHistory.ts +120 -0
  519. package/src/engine/ToolBroker.ts +157 -0
  520. package/src/engine/ToolExposure.ts +48 -0
  521. package/src/engine/internal/agent-runtime.ts +10117 -0
  522. package/src/engine/internal/bounded-value.ts +315 -0
  523. package/src/engine/internal/compaction.ts +678 -0
  524. package/src/engine/internal/error-diagnostic.ts +39 -0
  525. package/src/engine/internal/output-contract.ts +173 -0
  526. package/src/engine/internal/primitive-delta.ts +80 -0
  527. package/src/engine/internal/provider-result-staging.ts +211 -0
  528. package/src/engine/internal/tool-derivative.ts +106 -0
  529. package/src/engine/internal/tool-exposure.ts +224 -0
  530. package/src/engine/internal/tool-telemetry.ts +484 -0
  531. package/src/index.ts +96 -53
  532. package/src/sandbox/CodeExecutor.ts +352 -0
  533. package/src/sandbox/InteractiveBrowser.ts +257 -0
  534. package/src/sandbox/PageCapture.ts +692 -0
  535. package/src/sandbox/PageCrawl.ts +148 -0
  536. package/src/sandbox/PageScreenshot.ts +81 -0
  537. package/src/sandbox/ProtectedBrowser.ts +413 -0
  538. package/src/sandbox/Sandbox.ts +241 -0
  539. package/dist/Agent.d.mts +0 -5
  540. package/dist/Agent.mjs +0 -10
  541. package/dist/Agent.mjs.map +0 -1
  542. package/dist/AgentError.d.mts +0 -5
  543. package/dist/AgentError.mjs +0 -10
  544. package/dist/AgentError.mjs.map +0 -1
  545. package/dist/AgentPolicy.d.mts +0 -5
  546. package/dist/AgentPolicy.mjs +0 -10
  547. package/dist/AgentPolicy.mjs.map +0 -1
  548. package/dist/AgentRuntime.d.mts +0 -5
  549. package/dist/AgentRuntime.mjs +0 -10
  550. package/dist/AgentRuntime.mjs.map +0 -1
  551. package/dist/AgentUpdates.d.mts +0 -5
  552. package/dist/AgentUpdates.mjs +0 -10
  553. package/dist/AgentUpdates.mjs.map +0 -1
  554. package/dist/Approval.d.mts +0 -5
  555. package/dist/Approval.mjs +0 -10
  556. package/dist/Approval.mjs.map +0 -1
  557. package/dist/Budget.d.mts +0 -5
  558. package/dist/Budget.mjs +0 -10
  559. package/dist/Budget.mjs.map +0 -1
  560. package/dist/CodeMode.d.mts +0 -5
  561. package/dist/CodeMode.mjs +0 -10
  562. package/dist/CodeMode.mjs.map +0 -1
  563. package/dist/Commands.d.mts +0 -5
  564. package/dist/Commands.mjs +0 -10
  565. package/dist/Commands.mjs.map +0 -1
  566. package/dist/Compaction.d.mts +0 -5
  567. package/dist/Compaction.mjs +0 -10
  568. package/dist/Compaction.mjs.map +0 -1
  569. package/dist/ContextCompactor.d.mts +0 -5
  570. package/dist/ContextCompactor.mjs +0 -10
  571. package/dist/ContextCompactor.mjs.map +0 -1
  572. package/dist/ContextHistory.d.mts +0 -5
  573. package/dist/ContextHistory.mjs +0 -10
  574. package/dist/ContextHistory.mjs.map +0 -1
  575. package/dist/ContextTools.d.mts +0 -5
  576. package/dist/ContextTools.mjs +0 -10
  577. package/dist/ContextTools.mjs.map +0 -1
  578. package/dist/ContextWindow.d.mts +0 -5
  579. package/dist/ContextWindow.mjs +0 -10
  580. package/dist/ContextWindow.mjs.map +0 -1
  581. package/dist/DurableStep.d.mts +0 -5
  582. package/dist/DurableStep.mjs +0 -10
  583. package/dist/DurableStep.mjs.map +0 -1
  584. package/dist/EphemeralThreads.d.mts +0 -5
  585. package/dist/EphemeralThreads.mjs +0 -10
  586. package/dist/EphemeralThreads.mjs.map +0 -1
  587. package/dist/IdGenerator.d.mts +0 -5
  588. package/dist/IdGenerator.mjs +0 -10
  589. package/dist/IdGenerator.mjs.map +0 -1
  590. package/dist/Identifiers.d.mts +0 -5
  591. package/dist/Identifiers.mjs +0 -10
  592. package/dist/Identifiers.mjs.map +0 -1
  593. package/dist/Mcp.d.mts +0 -5
  594. package/dist/Mcp.mjs +0 -10
  595. package/dist/Mcp.mjs.map +0 -1
  596. package/dist/McpClient.d.mts +0 -5
  597. package/dist/McpClient.mjs +0 -10
  598. package/dist/McpClient.mjs.map +0 -1
  599. package/dist/Memory.d.mts +0 -5
  600. package/dist/Memory.mjs +0 -10
  601. package/dist/Memory.mjs.map +0 -1
  602. package/dist/MemoryNamespace.d.mts +0 -5
  603. package/dist/MemoryNamespace.mjs +0 -10
  604. package/dist/MemoryNamespace.mjs.map +0 -1
  605. package/dist/MemoryNotes.d.mts +0 -5
  606. package/dist/MemoryNotes.mjs +0 -10
  607. package/dist/MemoryNotes.mjs.map +0 -1
  608. package/dist/MemoryReference.d.mts +0 -5
  609. package/dist/MemoryReference.mjs +0 -10
  610. package/dist/MemoryReference.mjs.map +0 -1
  611. package/dist/MemoryRevalidation.d.mts +0 -5
  612. package/dist/MemoryRevalidation.mjs +0 -10
  613. package/dist/MemoryRevalidation.mjs.map +0 -1
  614. package/dist/MemoryStore.d.mts +0 -5
  615. package/dist/MemoryStore.mjs +0 -10
  616. package/dist/MemoryStore.mjs.map +0 -1
  617. package/dist/Messaging.d.mts +0 -5
  618. package/dist/Messaging.mjs +0 -10
  619. package/dist/Messaging.mjs.map +0 -1
  620. package/dist/MessagingHost.d.mts +0 -5
  621. package/dist/MessagingHost.mjs +0 -10
  622. package/dist/MessagingHost.mjs.map +0 -1
  623. package/dist/ModelContext.d.mts +0 -5
  624. package/dist/ModelContext.mjs +0 -10
  625. package/dist/ModelContext.mjs.map +0 -1
  626. package/dist/Receipt.d.mts +0 -5
  627. package/dist/Receipt.mjs +0 -10
  628. package/dist/Receipt.mjs.map +0 -1
  629. package/dist/Redaction.d.mts +0 -5
  630. package/dist/Redaction.mjs +0 -10
  631. package/dist/Redaction.mjs.map +0 -1
  632. package/dist/Remembering.d.mts +0 -5
  633. package/dist/Remembering.mjs +0 -10
  634. package/dist/Remembering.mjs.map +0 -1
  635. package/dist/RememberingStore.d.mts +0 -5
  636. package/dist/RememberingStore.mjs +0 -10
  637. package/dist/RememberingStore.mjs.map +0 -1
  638. package/dist/RunEvent.d.mts +0 -5
  639. package/dist/RunEvent.mjs +0 -10
  640. package/dist/RunEvent.mjs.map +0 -1
  641. package/dist/RunEventSink.d.mts +0 -5
  642. package/dist/RunEventSink.mjs +0 -10
  643. package/dist/RunEventSink.mjs.map +0 -1
  644. package/dist/RunHooks.d.mts +0 -5
  645. package/dist/RunHooks.mjs +0 -10
  646. package/dist/RunHooks.mjs.map +0 -1
  647. package/dist/RunOptions.d.mts +0 -5
  648. package/dist/RunOptions.mjs +0 -10
  649. package/dist/RunOptions.mjs.map +0 -1
  650. package/dist/RunPolicyUsage.d.mts +0 -5
  651. package/dist/RunPolicyUsage.mjs +0 -10
  652. package/dist/RunPolicyUsage.mjs.map +0 -1
  653. package/dist/SemanticMemory.d.mts +0 -5
  654. package/dist/SemanticMemory.mjs +0 -10
  655. package/dist/SemanticMemory.mjs.map +0 -1
  656. package/dist/SemanticMemoryIndex.d.mts +0 -5
  657. package/dist/SemanticMemoryIndex.mjs +0 -10
  658. package/dist/SemanticMemoryIndex.mjs.map +0 -1
  659. package/dist/SemanticMemoryRevalidation.d.mts +0 -5
  660. package/dist/SemanticMemoryRevalidation.mjs +0 -10
  661. package/dist/SemanticMemoryRevalidation.mjs.map +0 -1
  662. package/dist/Subagent.d.mts +0 -5
  663. package/dist/Subagent.mjs +0 -10
  664. package/dist/Subagent.mjs.map +0 -1
  665. package/dist/SubagentContract.d.mts +0 -5
  666. package/dist/SubagentContract.mjs +0 -10
  667. package/dist/SubagentContract.mjs.map +0 -1
  668. package/dist/SubagentHost.d.mts +0 -5
  669. package/dist/SubagentHost.mjs +0 -10
  670. package/dist/SubagentHost.mjs.map +0 -1
  671. package/dist/SubagentReservations.d.mts +0 -5
  672. package/dist/SubagentReservations.mjs +0 -10
  673. package/dist/SubagentReservations.mjs.map +0 -1
  674. package/dist/ThreadHistory.d.mts +0 -5
  675. package/dist/ThreadHistory.mjs +0 -10
  676. package/dist/ThreadHistory.mjs.map +0 -1
  677. package/dist/ToolBroker.d.mts +0 -5
  678. package/dist/ToolBroker.mjs +0 -10
  679. package/dist/ToolBroker.mjs.map +0 -1
  680. package/dist/ToolDiscovery.d.mts +0 -5
  681. package/dist/ToolDiscovery.mjs +0 -10
  682. package/dist/ToolDiscovery.mjs.map +0 -1
  683. package/dist/ToolResult.d.mts +0 -5
  684. package/dist/ToolResult.mjs +0 -10
  685. package/dist/ToolResult.mjs.map +0 -1
  686. package/dist/Usage.d.mts +0 -5
  687. package/dist/Usage.mjs +0 -10
  688. package/dist/Usage.mjs.map +0 -1
  689. package/dist/WebCapture.d.mts +0 -5
  690. package/dist/WebCapture.mjs +0 -10
  691. package/dist/WebCapture.mjs.map +0 -1
  692. package/dist/WebSearch.d.mts +0 -5
  693. package/dist/WebSearch.mjs +0 -10
  694. package/dist/WebSearch.mjs.map +0 -1
  695. package/dist/Worker.d.mts +0 -5
  696. package/dist/Worker.mjs +0 -10
  697. package/dist/Worker.mjs.map +0 -1
  698. package/dist/rolldown-runtime-BBjsoOtd.mjs +0 -27
  699. package/src/Agent.ts +0 -1
  700. package/src/AgentError.ts +0 -1
  701. package/src/AgentPolicy.ts +0 -1
  702. package/src/AgentRuntime.ts +0 -1
  703. package/src/AgentUpdates.ts +0 -1
  704. package/src/Approval.ts +0 -1
  705. package/src/Budget.ts +0 -1
  706. package/src/CodeMode.ts +0 -1
  707. package/src/Commands.ts +0 -1
  708. package/src/Compaction.ts +0 -1
  709. package/src/ContextCompactor.ts +0 -1
  710. package/src/ContextHistory.ts +0 -1
  711. package/src/ContextTools.ts +0 -1
  712. package/src/ContextWindow.ts +0 -1
  713. package/src/DurableStep.ts +0 -1
  714. package/src/EphemeralThreads.ts +0 -1
  715. package/src/IdGenerator.ts +0 -1
  716. package/src/Identifiers.ts +0 -1
  717. package/src/Mcp.ts +0 -1
  718. package/src/McpClient.ts +0 -1
  719. package/src/Memory.ts +0 -1
  720. package/src/MemoryNamespace.ts +0 -1
  721. package/src/MemoryNotes.ts +0 -1
  722. package/src/MemoryReference.ts +0 -1
  723. package/src/MemoryRevalidation.ts +0 -1
  724. package/src/MemoryStore.ts +0 -1
  725. package/src/Messaging.ts +0 -1
  726. package/src/MessagingHost.ts +0 -1
  727. package/src/ModelContext.ts +0 -1
  728. package/src/Receipt.ts +0 -1
  729. package/src/Redaction.ts +0 -1
  730. package/src/Remembering.ts +0 -1
  731. package/src/RememberingStore.ts +0 -1
  732. package/src/RunEvent.ts +0 -1
  733. package/src/RunEventSink.ts +0 -1
  734. package/src/RunHooks.ts +0 -1
  735. package/src/RunOptions.ts +0 -1
  736. package/src/RunPolicyUsage.ts +0 -1
  737. package/src/SemanticMemory.ts +0 -1
  738. package/src/SemanticMemoryIndex.ts +0 -1
  739. package/src/SemanticMemoryRevalidation.ts +0 -1
  740. package/src/Subagent.ts +0 -1
  741. package/src/SubagentContract.ts +0 -1
  742. package/src/SubagentHost.ts +0 -1
  743. package/src/SubagentReservations.ts +0 -1
  744. package/src/ThreadHistory.ts +0 -1
  745. package/src/ToolBroker.ts +0 -1
  746. package/src/ToolDiscovery.ts +0 -1
  747. package/src/ToolResult.ts +0 -1
  748. package/src/Usage.ts +0 -1
  749. package/src/WebCapture.ts +0 -1
  750. package/src/WebSearch.ts +0 -1
  751. package/src/Worker.ts +0 -1
@@ -0,0 +1,4562 @@
1
+ import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
2
+ import { n as utf8ByteLength } from "./utf8-DchGZRBd.mjs";
3
+ import { applyToolResultBounds, unserializableToolResult } from "./core/ToolResult.mjs";
4
+ import { ReceiptId, RunId, SubmissionId, ThreadId, ToolCallId } from "./core/Identifiers.mjs";
5
+ import { IdempotencyKey } from "./core/Receipt.mjs";
6
+ import { Emitter, Update, UpdateError } from "./core/AgentUpdates.mjs";
7
+ import { AgentApprovalDenied, AgentApprovalPending, AgentInputError, AgentOutputError, AgentPolicyError, AgentRunDispositionError, AgentToolAuthorizationDenied, ContextBudgetError, ContextOverflowError, ModelProtocolError } from "./core/AgentError.mjs";
8
+ import { IdGenerator as IdGenerator$1 } from "./core/IdGenerator.mjs";
9
+ import { DelegationDepth, SubagentParentLink, getToolExecutionKind, isSubagentToolAllowed } from "./core/SubagentContract.mjs";
10
+ import { a as PinnedTool, c as ToolNames, i as Limits, l as ToolNamespace, n as DiscoveryTool, o as Selection, r as IncludesCatalogDocumentation, s as Snapshot, t as AdditionalToolCatalog } from "./ToolExposure-C93U1sPu.mjs";
11
+ import { InputTokenUsage, ModelCallUsage, ModelResponseIdentity, OutputTokenUsage, RunTotals, RunUsageReport, emptyRunTotals, sumRunTotals, unknownRunTotals } from "./core/Usage.mjs";
12
+ import { AgentUpdateEmitted, ApprovalRequested, BudgetWarning, CompactionPerformed, ModelStarted, ReasoningDelta, RunCompleted, RunFailed, RunStarted, RunSuspended, SubagentCompleted, SubagentFailed, SubagentInterrupted, SubagentJoined, SubagentProgress, SubagentRequested, SubagentStarted, TextDelta, ToolCallDeclared, ToolCallFailed, ToolCallStarted, ToolCallSucceeded, ToolProgress, TurnCompleted, TurnStarted } from "./core/RunEvent.mjs";
13
+ import { FrameworkMessage } from "./core/Worker.mjs";
14
+ import { t as MessagingHost } from "./MessagingHost-CWi_PP3g.mjs";
15
+ import { SubagentHost } from "./engine/SubagentHost.mjs";
16
+ import { ThreadHistory, ThreadHistoryError } from "./engine/ThreadHistory.mjs";
17
+ import { n as RunToolVisibility, t as CurrentToolCatalog } from "./ToolExposure-9uF_Yo0T.mjs";
18
+ import { n as isTextOutput, r as outputSchemaContract, t as insertOutputContract } from "./output-contract-BC7tjlGw.mjs";
19
+ import { _ as initialCompactionState, b as boundedCanonicalJsonSnapshot, d as collectCoveredMessages, f as contextWindowId, g as evaluateMessageTokenEstimates, h as estimatePromptTokens, s as buildCompactedView, v as isContextOverflowMessage, x as boundedJsonSnapshot } from "./compaction-C2OTceKw.mjs";
20
+ import { ContextRolloverRequest, ContextRolloverSelection, ContextRolloverTool, ContextWindow, ContextWindowStatus, ModelCallContext } from "./engine/ContextWindow.mjs";
21
+ import { DurableStep, DurableStepError, getToolExecutionClass } from "./engine/DurableStep.mjs";
22
+ import { CompactionDecision, CompactionError, ContextCompactor } from "./engine/ContextCompactor.mjs";
23
+ import { RunEventSink, RunEventSinkClosedError } from "./engine/RunEventSink.mjs";
24
+ import { AgentUpdateAcceptance, CurrentToolFailureObserver, ModelUsageAccounting, RunContextPreparation, RunResumeUsageSchema, RunToolAuthorization, RunToolScheduling, RunTurnResumeSettledCallSchema } from "./engine/RunOptions.mjs";
25
+ import { ToolBroker, ToolBrokerConfigurationError, ToolBrokerUnavailableError } from "./engine/ToolBroker.mjs";
26
+ import { AiError, LanguageModel, Model, Prompt, Response, Tool, Toolkit } from "effect/unstable/ai";
27
+ import { Cause, Channel, Clock, Context, DateTime, Duration, Effect, Equal, ErrorReporter, Exit, Fiber, Layer, Metric, Option, PubSub, Queue, Redacted, Result, Schema, Scope, Semaphore, Stream, Tracer } from "effect";
28
+ //#region src/engine/internal/bounded-value.ts
29
+ const DEFAULT_MAX_DEPTH = 128;
30
+ const OBJECT_OVERHEAD_BYTES = 32;
31
+ const PROPERTY_OVERHEAD_BYTES = 8;
32
+ const dateTimeUtcPrototype = Object.getPrototypeOf(DateTime.makeUnsafe(0));
33
+ const redactedPrototype = Object.getPrototypeOf(Redacted.make(void 0));
34
+ const intrinsicViewPrototypes = /* @__PURE__ */ new Set([
35
+ DataView.prototype,
36
+ Int8Array.prototype,
37
+ Uint8Array.prototype,
38
+ Uint8ClampedArray.prototype,
39
+ Int16Array.prototype,
40
+ Uint16Array.prototype,
41
+ Int32Array.prototype,
42
+ Uint32Array.prototype,
43
+ Float32Array.prototype,
44
+ Float64Array.prototype,
45
+ BigInt64Array.prototype,
46
+ BigUint64Array.prototype
47
+ ]);
48
+ const arrayBufferByteLengthGetter = Object.getOwnPropertyDescriptor(ArrayBuffer.prototype, "byteLength")?.get;
49
+ const typedArrayPrototype = Object.getPrototypeOf(Uint8Array.prototype);
50
+ const typedArrayBufferGetter = Object.getOwnPropertyDescriptor(typedArrayPrototype, "buffer")?.get;
51
+ const typedArrayLengthGetter = Object.getOwnPropertyDescriptor(typedArrayPrototype, "length")?.get;
52
+ const dataViewBufferGetter = Object.getOwnPropertyDescriptor(DataView.prototype, "buffer")?.get;
53
+ const urlConstructor = Reflect.get(globalThis, "URL");
54
+ const urlPrototypeDescriptor = typeof urlConstructor === "function" ? Object.getOwnPropertyDescriptor(urlConstructor, "prototype") : void 0;
55
+ const urlHrefGetter = urlPrototypeDescriptor !== void 0 && "value" in urlPrototypeDescriptor && urlPrototypeDescriptor.value !== null && typeof urlPrototypeDescriptor.value === "object" ? Object.getOwnPropertyDescriptor(urlPrototypeDescriptor.value, "href")?.get : void 0;
56
+ const urlPrototype = urlPrototypeDescriptor !== void 0 && "value" in urlPrototypeDescriptor && urlPrototypeDescriptor.value !== null && typeof urlPrototypeDescriptor.value === "object" ? urlPrototypeDescriptor.value : void 0;
57
+ const intrinsicArrayBufferByteLength = (value) => {
58
+ if (arrayBufferByteLengthGetter === void 0) return void 0;
59
+ try {
60
+ const byteLength = Reflect.apply(arrayBufferByteLengthGetter, value, []);
61
+ return Number.isSafeInteger(byteLength) && byteLength >= 0 ? byteLength : void 0;
62
+ } catch {
63
+ return;
64
+ }
65
+ };
66
+ const intrinsicViewBackingByteLength = (value) => {
67
+ const getters = [typedArrayBufferGetter, dataViewBufferGetter];
68
+ for (const getter of getters) {
69
+ if (getter === void 0) continue;
70
+ try {
71
+ const buffer = Reflect.apply(getter, value, []);
72
+ if (buffer !== null && typeof buffer === "object") return intrinsicArrayBufferByteLength(buffer);
73
+ } catch {}
74
+ }
75
+ };
76
+ const intrinsicTypedArrayLength = (value) => {
77
+ if (typedArrayLengthGetter === void 0) return void 0;
78
+ try {
79
+ const length = Reflect.apply(typedArrayLengthGetter, value, []);
80
+ return Number.isSafeInteger(length) && length >= 0 ? length : void 0;
81
+ } catch {
82
+ return;
83
+ }
84
+ };
85
+ const intrinsicUrlByteLength = (value) => {
86
+ if (urlHrefGetter === void 0) return void 0;
87
+ try {
88
+ const href = Reflect.apply(urlHrefGetter, value, []);
89
+ return typeof href === "string" ? utf8ByteLength(href) + 2 : void 0;
90
+ } catch {
91
+ return;
92
+ }
93
+ };
94
+ const inspectPrototype = (prototype, isArray, knownSafePrototypes) => {
95
+ if (prototype === null) return true;
96
+ if (isArray) return prototype === Array.prototype;
97
+ return prototype === Object.prototype || prototype === dateTimeUtcPrototype || knownSafePrototypes.has(prototype);
98
+ };
99
+ const isCanonicalArrayIndex = (key) => {
100
+ const index = Number(key);
101
+ return Number.isInteger(index) && index >= 0 && index < 4294967295 && String(index) === key;
102
+ };
103
+ /**
104
+ * Conservatively measure one retained, engine-owned JavaScript value without invoking getters,
105
+ * coercion, or `toJSON`. `undefined` means the value exceeded the allowance or its shape could not
106
+ * be measured without executing an accessor.
107
+ *
108
+ * This is a memory-retention guard, not an untrusted wire boundary. Callers must first canonicalize
109
+ * provider values into owned data because JavaScript offers no portable, trap-free Proxy test.
110
+ * Object and property overheads deliberately make the estimate larger than the visible primitive
111
+ * payload for ordinary response values.
112
+ */
113
+ const boundedValueFootprint = (root, maxBytes, knownSafePrototypes = /* @__PURE__ */ new Set(), maxDepth = DEFAULT_MAX_DEPTH) => {
114
+ if (!Number.isSafeInteger(maxBytes) || maxBytes < 0 || !Number.isSafeInteger(maxDepth) || maxDepth < 0) return;
115
+ let total = 0;
116
+ const ancestors = /* @__PURE__ */ new WeakSet();
117
+ const add = (bytes) => {
118
+ if (!Number.isSafeInteger(bytes) || bytes < 0 || bytes > maxBytes - total) return false;
119
+ total += bytes;
120
+ return true;
121
+ };
122
+ const canMaterializeIndexedKeys = (count) => {
123
+ if (!Number.isSafeInteger(count) || count < 0) return false;
124
+ if (count === 0) return true;
125
+ const largestKeyBytes = utf8ByteLength(String(count - 1));
126
+ const temporaryBytesPerKey = PROPERTY_OVERHEAD_BYTES + largestKeyBytes;
127
+ return count <= Math.floor((maxBytes - total) / temporaryBytesPerKey);
128
+ };
129
+ const visit = (value, depth) => {
130
+ if (depth > maxDepth) return false;
131
+ if (value === null) return add(4);
132
+ switch (typeof value) {
133
+ case "string": return add(utf8ByteLength(value) + 2);
134
+ case "boolean": return add(4);
135
+ case "number": return add(16);
136
+ case "bigint":
137
+ case "symbol": return false;
138
+ case "undefined": return add(16);
139
+ case "function": return false;
140
+ case "object": {
141
+ if (ancestors.has(value) || !add(OBJECT_OVERHEAD_BYTES)) return false;
142
+ const prototype = Object.getPrototypeOf(value);
143
+ let skipIndexedProperties = false;
144
+ let indexedPropertyCount = 0;
145
+ let supportedSpecialObject = false;
146
+ if (ArrayBuffer.isView(value)) {
147
+ if (!intrinsicViewPrototypes.has(prototype)) return false;
148
+ const byteLength = intrinsicViewBackingByteLength(value);
149
+ if (byteLength === void 0 || !add(byteLength)) return false;
150
+ if (prototype !== DataView.prototype) {
151
+ const length = intrinsicTypedArrayLength(value);
152
+ if (length === void 0) return false;
153
+ indexedPropertyCount = length;
154
+ }
155
+ skipIndexedProperties = true;
156
+ supportedSpecialObject = true;
157
+ }
158
+ if (!supportedSpecialObject) {
159
+ const bufferByteLength = intrinsicArrayBufferByteLength(value);
160
+ if (bufferByteLength !== void 0) {
161
+ if (prototype !== ArrayBuffer.prototype) return false;
162
+ if (!add(bufferByteLength)) return false;
163
+ supportedSpecialObject = true;
164
+ }
165
+ }
166
+ if (!supportedSpecialObject) {
167
+ const urlByteLength = intrinsicUrlByteLength(value);
168
+ if (urlByteLength !== void 0) {
169
+ if (prototype !== urlPrototype) return false;
170
+ if (!add(urlByteLength)) return false;
171
+ supportedSpecialObject = true;
172
+ }
173
+ }
174
+ let redactedValue;
175
+ let isRedacted = false;
176
+ if (prototype === redactedPrototype) {
177
+ const labelDescriptor = Object.getOwnPropertyDescriptor(value, "label");
178
+ if (labelDescriptor !== void 0 && !("value" in labelDescriptor)) return false;
179
+ try {
180
+ redactedValue = Redacted.value(value);
181
+ isRedacted = true;
182
+ } catch {
183
+ return false;
184
+ }
185
+ }
186
+ const isArray = Array.isArray(value);
187
+ if (!supportedSpecialObject && !isRedacted && !inspectPrototype(prototype, isArray, knownSafePrototypes)) return false;
188
+ if (isArray) {
189
+ const lengthDescriptor = Object.getOwnPropertyDescriptor(value, "length");
190
+ if (lengthDescriptor === void 0 || !("value" in lengthDescriptor) || !Number.isSafeInteger(lengthDescriptor.value) || lengthDescriptor.value < 0 || !add(lengthDescriptor.value)) return false;
191
+ indexedPropertyCount = lengthDescriptor.value;
192
+ }
193
+ if (!canMaterializeIndexedKeys(indexedPropertyCount)) return false;
194
+ ancestors.add(value);
195
+ try {
196
+ if (isRedacted && !visit(redactedValue, depth + 1)) return false;
197
+ for (const key of Reflect.ownKeys(value)) {
198
+ if (key === "length" && isArray) continue;
199
+ if (typeof key === "symbol") return false;
200
+ if (skipIndexedProperties && isCanonicalArrayIndex(key)) continue;
201
+ if (!add(PROPERTY_OVERHEAD_BYTES)) return false;
202
+ if (!add(utf8ByteLength(key))) return false;
203
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
204
+ if (descriptor === void 0) return false;
205
+ if ("value" in descriptor) {
206
+ if (!visit(descriptor.value, depth + 1)) return false;
207
+ } else return false;
208
+ }
209
+ return true;
210
+ } finally {
211
+ ancestors.delete(value);
212
+ }
213
+ }
214
+ }
215
+ return false;
216
+ };
217
+ try {
218
+ return visit(root, 0) ? total : void 0;
219
+ } catch {
220
+ return;
221
+ }
222
+ };
223
+ //#endregion
224
+ //#region src/engine/internal/primitive-delta.ts
225
+ const keys = [
226
+ "~effect/ai/Content/Part",
227
+ "type",
228
+ "id",
229
+ "delta",
230
+ "metadata"
231
+ ];
232
+ const decode = Schema.decodeUnknownOption(Schema.toType(Schema.Union([Response.TextDeltaPart, Response.ReasoningDeltaPart])));
233
+ const overhead = (type) => ({
234
+ source: boundedValueFootprint(Response.makePart(type, {
235
+ id: "",
236
+ delta: ""
237
+ }), Number.MAX_SAFE_INTEGER),
238
+ encoded: boundedValueFootprint({
239
+ type,
240
+ id: "",
241
+ delta: "",
242
+ metadata: {}
243
+ }, Number.MAX_SAFE_INTEGER)
244
+ });
245
+ const overheads = {
246
+ "text-delta": overhead("text-delta"),
247
+ "reasoning-delta": overhead("reasoning-delta")
248
+ };
249
+ /**
250
+ * Copy the common primitive delta into owned data before native Schema validation.
251
+ * Descriptor checks select this optimization; they do not replace the native codec.
252
+ * Extra fields, accessors, and nonempty metadata use the general ownership path.
253
+ * No provider object survives, including an empty metadata object's hidden storage.
254
+ * Unlike a generic footprint shortcut, this cannot retain an exotic backing buffer.
255
+ */
256
+ const ownPrimitiveDelta = (part, maxBytes) => {
257
+ try {
258
+ if (part === null || typeof part !== "object") return void 0;
259
+ if (Array.isArray(part) || ArrayBuffer.isView(part)) return void 0;
260
+ const prototype = Object.getPrototypeOf(part);
261
+ if (prototype !== Object.prototype && prototype !== null) return void 0;
262
+ if (Reflect.ownKeys(part).length !== keys.length) return void 0;
263
+ const snapshot = {};
264
+ for (const key of keys) {
265
+ const descriptor = Object.getOwnPropertyDescriptor(part, key);
266
+ if (descriptor === void 0 || !("value" in descriptor)) return void 0;
267
+ snapshot[key] = descriptor.value;
268
+ }
269
+ const { type, id, delta, metadata } = snapshot;
270
+ if (type !== "text-delta" && type !== "reasoning-delta") return void 0;
271
+ if (typeof id !== "string" || typeof delta !== "string") return void 0;
272
+ if (metadata === null || typeof metadata !== "object") return void 0;
273
+ if (Array.isArray(metadata) || ArrayBuffer.isView(metadata)) return void 0;
274
+ const metadataPrototype = Object.getPrototypeOf(metadata);
275
+ if (metadataPrototype !== Object.prototype && metadataPrototype !== null) return void 0;
276
+ if (Reflect.ownKeys(metadata).length !== 0) return void 0;
277
+ const fixed = overheads[type];
278
+ if (fixed.source === void 0 || fixed.encoded === void 0) return void 0;
279
+ const bytes = utf8ByteLength(id) + utf8ByteLength(delta);
280
+ if (bytes + fixed.source > maxBytes || bytes + fixed.encoded > maxBytes) return void 0;
281
+ snapshot.metadata = {};
282
+ const validated = decode(snapshot);
283
+ if (Option.isNone(validated)) return void 0;
284
+ return {
285
+ ownedPart: validated.value,
286
+ retainedBytes: bytes + fixed.encoded
287
+ };
288
+ } catch {
289
+ return;
290
+ }
291
+ };
292
+ //#endregion
293
+ //#region src/engine/internal/tool-derivative.ts
294
+ /** @internal Only the explicitly installed trusted observer sees this live value. */
295
+ const deliverToolFailure = (observer, observation) => isolateToolDerivative(Effect.suspend(() => observer.observe(observation)));
296
+ /**
297
+ * Report failures of derivative work without consuming external interruption. Reporter defects
298
+ * are isolated too. Neither observer delivery nor telemetry owns the authoritative Tool outcome.
299
+ */
300
+ const reportDerivativeCause = (cause) => {
301
+ const reportableReasons = [];
302
+ const interruptionReasons = [];
303
+ for (const reason of cause.reasons) if (Cause.isInterruptReason(reason)) interruptionReasons.push(reason);
304
+ else reportableReasons.push(reason);
305
+ const reportExit = reportableReasons.length === 0 ? Effect.succeed(Exit.succeed(void 0)) : Effect.exit(ErrorReporter.report(Cause.fromReasons(reportableReasons)));
306
+ return Effect.flatMap(reportExit, (exit) => {
307
+ if (Exit.isFailure(exit)) {
308
+ for (const reason of exit.cause.reasons) if (Cause.isInterruptReason(reason)) interruptionReasons.push(reason);
309
+ }
310
+ return interruptionReasons.length === 0 ? Effect.void : Effect.failCause(Cause.fromReasons(interruptionReasons));
311
+ });
312
+ };
313
+ /** @internal Isolate reporting defects independently of Logger/Tracer configuration. */
314
+ const isolateToolDerivative = (effect) => effect.pipe(Effect.catchCause(reportDerivativeCause));
315
+ /**
316
+ * @internal Emit one authoritative value, then run derivative work from either the next pull or
317
+ * structured finalization on early close. Telemetry and application observation share this one
318
+ * owner. A started action is never retried after interruption.
319
+ */
320
+ const emitThenAfter = (event, after) => Stream.unwrap(Effect.sync(() => {
321
+ let firstPull = true;
322
+ let afterPhase = "unarmed";
323
+ const runAfter = Effect.suspend(() => {
324
+ if (afterPhase !== "pending") return Effect.void;
325
+ afterPhase = "running";
326
+ return after.pipe(Effect.onExit(() => Effect.sync(() => {
327
+ afterPhase = "completed";
328
+ })));
329
+ });
330
+ const pull = Effect.suspend(() => {
331
+ if (firstPull) return Effect.map(event, (value) => {
332
+ firstPull = false;
333
+ afterPhase = "pending";
334
+ return [value];
335
+ });
336
+ return Effect.andThen(runAfter, Cause.done());
337
+ });
338
+ return Stream.fromPull(Effect.succeed(pull)).pipe(Stream.ensuring(Effect.exit(Effect.interruptible(runAfter)).pipe(Effect.flatMap((exit) => {
339
+ if (Exit.isSuccess(exit)) return Effect.void;
340
+ return reportDerivativeCause(exit.cause);
341
+ }))));
342
+ }));
343
+ //#endregion
344
+ //#region src/engine/internal/tool-exposure.ts
345
+ const invalid = (message) => ModelProtocolError.make({ message });
346
+ const decodeSelection = (value) => Schema.decodeUnknownEffect(Selection)(value).pipe(Effect.mapError(() => invalid("Invalid Tool exposure selection")));
347
+ const decodeSnapshot = (value) => Schema.decodeUnknownEffect(Snapshot)(value).pipe(Effect.mapError(() => invalid("Invalid recorded Tool exposure snapshot")), Effect.map((snapshot) => Object.freeze(Snapshot.make({
348
+ exposedToolNames: Object.freeze([...snapshot.exposedToolNames]),
349
+ ...snapshot.selection === void 0 ? {} : { selection: Object.freeze(Selection.make({ toolNames: Object.freeze([...snapshot.selection.toolNames]) })) }
350
+ }))));
351
+ const eligibleCatalog = Effect.fn("ToolExposure.eligibleCatalog")(function* (definition, request, grant, depth) {
352
+ const visibility = yield* RunToolVisibility;
353
+ const entries = [];
354
+ for (const tool of Object.values(definition.toolkit.tools)) {
355
+ if (Context.get(tool.annotations, DiscoveryTool) && (getToolExecutionKind(tool.annotations) !== "ordinary" || getToolExecutionClass(tool) !== "readonly")) return yield* invalid("Discovery requires ordinary readonly Tools");
356
+ const namespace = Context.get(tool.annotations, ToolNamespace);
357
+ entries.push({
358
+ kind: "native",
359
+ tool,
360
+ nativeToolName: tool.name,
361
+ ...namespace === void 0 ? {} : { namespace }
362
+ });
363
+ for (const extra of Context.get(tool.annotations, AdditionalToolCatalog)) entries.push({
364
+ kind: "code-mode",
365
+ ...extra,
366
+ nativeToolName: tool.name
367
+ });
368
+ }
369
+ const names = [...new Set(entries.map((entry) => entry.tool.name))];
370
+ const visible = visibility === void 0 ? names : yield* visibility.visible({
371
+ ...request,
372
+ toolNames: names
373
+ });
374
+ const checked = visibility === void 0 ? visible : yield* Schema.decodeEffect(ToolNames)(visible).pipe(Effect.mapError(() => invalid("Host Tool visibility returned invalid names")));
375
+ if (checked.some((name) => !names.includes(name))) return yield* invalid("Host Tool visibility returned an unregistered name");
376
+ const allowed = new Set(checked);
377
+ const permits = (tool) => allowed.has(tool.name) && isSubagentToolAllowed(grant, depth, tool.name, tool.annotations);
378
+ for (const outer of Object.values(definition.toolkit.tools)) if (permits(outer) && Context.get(outer.annotations, IncludesCatalogDocumentation) && Context.get(outer.annotations, AdditionalToolCatalog).some((entry) => !permits(entry.tool))) return yield* invalid("A Tool description includes hidden catalogue declarations; configure includeDeclarations: false");
379
+ return Object.freeze(entries.filter((entry) => {
380
+ const outer = definition.toolkit.tools[entry.nativeToolName];
381
+ return outer !== void 0 && permits(outer) && permits(entry.tool);
382
+ }).map((entry) => Object.freeze(entry)));
383
+ });
384
+ const validateSelection = Effect.fn("ToolExposure.validateSelection")(function* (value, definition, entries, requireEligible = true) {
385
+ const selection = yield* decodeSelection(value);
386
+ const eligible = new Set(entries.filter((entry) => entry.kind === "native").map((entry) => entry.nativeToolName));
387
+ if (selection.toolNames.some((name) => !Object.hasOwn(definition.toolkit.tools, name) || requireEligible && !eligible.has(name))) return yield* invalid("Tool selection names a Tool outside the eligible registered toolkit");
388
+ return Selection.make({ toolNames: Object.freeze([...selection.toolNames]) });
389
+ });
390
+ const exposureSnapshot = Effect.fn("ToolExposure.exposureSnapshot")(function* (definition, selection, entries, transformer, only) {
391
+ const native = entries.filter((entry) => entry.kind === "native").map((entry) => entry.tool);
392
+ const progressive = definition.toolExposure !== void 0 || selection !== void 0;
393
+ const mandatory = Object.values(definition.toolkit.tools).filter((tool) => Context.get(tool.annotations, DiscoveryTool) || Context.get(tool.annotations, ContextRolloverTool) || definition.completion?.required === true && definition.completion.tool === tool.name);
394
+ if (progressive && mandatory.some((tool) => !native.some((candidate) => candidate.name === tool.name))) return yield* invalid("A mandatory Tool is excluded by host visibility or the inherited grant");
395
+ const pinned = native.filter((tool) => Context.get(tool.annotations, PinnedTool) || mandatory.includes(tool));
396
+ if (selection !== void 0) yield* validateSelection(selection, definition, entries, false);
397
+ const selected = selection === void 0 ? void 0 : new Set(selection.toolNames);
398
+ const names = native.filter((tool) => selected === void 0 || selected.has(tool.name) || pinned.includes(tool)).map((tool) => tool.name).filter((name) => only === void 0 || only.includes(name));
399
+ if (progressive) {
400
+ const limits = yield* Schema.decodeEffect(Limits)({
401
+ maxTools: definition.toolExposure?.maxTools ?? 64,
402
+ maxSchemaBytes: definition.toolExposure?.maxSchemaBytes ?? 262144
403
+ }).pipe(Effect.mapError(() => invalid("Invalid Tool exposure bounds")));
404
+ if (names.length > limits.maxTools) return yield* invalid("Tool exposure exceeds the configured Tool count bound");
405
+ if ((yield* Effect.try({
406
+ try: () => utf8ByteLength(JSON.stringify(names.map((name) => {
407
+ const tool = definition.toolkit.tools[name];
408
+ if (tool === void 0) throw new Error("Selected Tool is unavailable");
409
+ return Tool.isProviderDefined(tool) ? {
410
+ type: tool.providerName,
411
+ args: tool.args
412
+ } : {
413
+ name,
414
+ description: Tool.getDescription(tool),
415
+ parameters: Tool.getJsonSchema(tool, { transformer })
416
+ };
417
+ }))),
418
+ catch: () => invalid("A selected Tool schema cannot be rendered")
419
+ })) > limits.maxSchemaBytes) return yield* invalid("Tool exposure exceeds the configured schema byte bound");
420
+ }
421
+ return yield* decodeSnapshot({
422
+ exposedToolNames: names,
423
+ ...selection === void 0 ? {} : { selection }
424
+ });
425
+ });
426
+ //#endregion
427
+ //#region src/engine/internal/tool-telemetry.ts
428
+ /**
429
+ * @internal Payload-free control signal used only to close the canonical Tool span with a failed
430
+ * Exit. It is removed immediately outside that span and never enters the public error channel.
431
+ */
432
+ var ToolSpanFailure = class ToolSpanFailure extends AiError.AiError.extend("@effect-agent/engine/ToolSpanFailure")({}) {
433
+ name = "ToolCallFailed";
434
+ /** Schema-safe factory retaining the generated constructor required by Effect Schema. */
435
+ static marker() {
436
+ return ToolSpanFailure.make({
437
+ module: "effect-agent",
438
+ method: "execute_tool",
439
+ reason: AiError.UnknownError.make({ description: "Tool execution reached a failed terminal state" })
440
+ });
441
+ }
442
+ };
443
+ const TOOL_SPAN_FAILURE_MARKER_ATTRIBUTE = "@effect-agent/engine/ToolSpanFailureMarker";
444
+ const terminalOutcomeTokens = /* @__PURE__ */ new WeakMap();
445
+ /** @internal Annotate one completed attempt and hand its existing marker to the isolated span. */
446
+ const annotateToolSpanTerminalOutcome = (outcome, failureMarker, failureHandling, failureMode) => {
447
+ const token = {};
448
+ terminalOutcomeTokens.set(token, {
449
+ outcome,
450
+ failureMarker,
451
+ failureHandling,
452
+ failureMode
453
+ });
454
+ return Effect.annotateCurrentSpan({
455
+ "effect_agent.tool.outcome": outcome,
456
+ [TOOL_SPAN_FAILURE_MARKER_ATTRIBUTE]: token
457
+ });
458
+ };
459
+ const stripToolSpanFailures = (cause, marker) => {
460
+ if (!cause.reasons.some((reason) => Cause.isFailReason(reason) && reason.error === marker)) return {
461
+ found: false,
462
+ residual: cause
463
+ };
464
+ const reasons = cause.reasons.filter((reason) => {
465
+ if (Cause.isFailReason(reason) && reason.error === marker) return false;
466
+ return true;
467
+ });
468
+ return {
469
+ found: true,
470
+ residual: Cause.fromReasons(reasons)
471
+ };
472
+ };
473
+ /** @internal Remove only the private marker and restore the saved Cause plus every residual. */
474
+ const restoreToolSpanFailureCause = (cause, marker, original) => {
475
+ const { found, residual } = stripToolSpanFailures(cause, marker);
476
+ return {
477
+ found,
478
+ restored: original === void 0 ? residual : Cause.combine(original, residual)
479
+ };
480
+ };
481
+ const MAX_REPORTED_SPAN_LIFECYCLE_DEFECTS = 16;
482
+ /** Content-free marker used only to close a delegate that cannot be wrapped safely. */
483
+ var ToolSpanLifecycleFailure = class extends Error {
484
+ name = "ToolSpanLifecycleFailure";
485
+ constructor() {
486
+ super("Tool span lifecycle failed");
487
+ }
488
+ };
489
+ /**
490
+ * @internal Guard one host span so synchronous exporter defects cannot alter Tool execution.
491
+ * The wrapper retains the span contract for Effect while forwarding every measurement to the host.
492
+ */
493
+ var IsolatedToolSpan = class {
494
+ _tag = "Span";
495
+ name;
496
+ spanId;
497
+ traceId;
498
+ parent;
499
+ annotations;
500
+ attributes = /* @__PURE__ */ new Map();
501
+ links;
502
+ sampled;
503
+ kind;
504
+ status;
505
+ #delegate;
506
+ #recordDefect;
507
+ #terminalOutcome;
508
+ #terminalFailure;
509
+ #terminalFailureHandling;
510
+ #terminalFailureMode;
511
+ constructor(delegate, options, recordDefect) {
512
+ this.#delegate = delegate;
513
+ this.#recordDefect = recordDefect;
514
+ this.name = options.name;
515
+ this.spanId = delegate.spanId;
516
+ this.traceId = delegate.traceId;
517
+ this.parent = options.parent;
518
+ this.annotations = options.annotations;
519
+ this.links = [...options.links];
520
+ this.sampled = delegate.sampled;
521
+ this.kind = options.kind;
522
+ this.status = {
523
+ _tag: "Started",
524
+ startTime: options.startTime
525
+ };
526
+ }
527
+ end(endTime, exit) {
528
+ if (this.status._tag === "Ended") return;
529
+ const exportedExit = this.#terminalOutcome === "failure" ? Exit.fail(this.#terminalFailure ?? new ToolSpanLifecycleFailure()) : this.#terminalOutcome === "success" ? Exit.succeed(void 0) : exit;
530
+ this.status = {
531
+ _tag: "Ended",
532
+ startTime: this.status.startTime,
533
+ endTime,
534
+ exit: exportedExit
535
+ };
536
+ if (this.#terminalOutcome !== void 0) {
537
+ this.attributes.set("effect_agent.tool.outcome", this.#terminalOutcome);
538
+ try {
539
+ this.#delegate.attribute("effect_agent.tool.outcome", this.#terminalOutcome);
540
+ } catch (defect) {
541
+ this.#recordDefect(defect);
542
+ }
543
+ }
544
+ for (const [key, value] of [["effect_agent.tool.failure_mode", this.#terminalFailureMode], ["effect_agent.tool.failure_handling", this.#terminalFailureHandling]]) if (value !== void 0) {
545
+ this.attributes.set(key, value);
546
+ try {
547
+ this.#delegate.attribute(key, value);
548
+ } catch (defect) {
549
+ this.#recordDefect(defect);
550
+ }
551
+ } else if (key === "effect_agent.tool.failure_handling") this.attributes.delete(key);
552
+ try {
553
+ this.#delegate.end(endTime, exportedExit);
554
+ } catch (defect) {
555
+ this.#recordDefect(defect);
556
+ }
557
+ }
558
+ attribute(key, value) {
559
+ if (key === TOOL_SPAN_FAILURE_MARKER_ATTRIBUTE) {
560
+ if (typeof value === "object" && value !== null) {
561
+ const terminal = terminalOutcomeTokens.get(value);
562
+ if (terminal !== void 0) {
563
+ this.#terminalOutcome = terminal.outcome;
564
+ this.#terminalFailure = terminal.failureMarker;
565
+ this.#terminalFailureHandling = terminal.failureHandling;
566
+ this.#terminalFailureMode = terminal.failureMode;
567
+ }
568
+ }
569
+ return;
570
+ }
571
+ if (key === "effect_agent.tool.failure_handling") return;
572
+ this.attributes.set(key, value);
573
+ try {
574
+ this.#delegate.attribute(key, value);
575
+ } catch (defect) {
576
+ this.#recordDefect(defect);
577
+ }
578
+ }
579
+ event(name, startTime, attributes) {
580
+ try {
581
+ this.#delegate.event(name, startTime, attributes);
582
+ } catch (defect) {
583
+ this.#recordDefect(defect);
584
+ }
585
+ }
586
+ addLinks(links) {
587
+ this.links.push(...links);
588
+ try {
589
+ this.#delegate.addLinks(links);
590
+ } catch (defect) {
591
+ this.#recordDefect(defect);
592
+ }
593
+ }
594
+ };
595
+ /**
596
+ * @internal Isolate the complete canonical span lifecycle. A creation defect receives a local,
597
+ * non-exported span so the handler still runs; delegate method/finalization defects are retained
598
+ * as bounded reporter diagnostics and never enter the handler stream Cause.
599
+ */
600
+ const makeIsolatedToolTracer = (delegate) => {
601
+ const defects = [];
602
+ const recordDefect = (defect) => {
603
+ if (defects.length < MAX_REPORTED_SPAN_LIFECYCLE_DEFECTS) defects.push(defect);
604
+ };
605
+ let delegateContext;
606
+ try {
607
+ delegateContext = delegate.context?.bind(delegate);
608
+ } catch (defect) {
609
+ recordDefect(defect);
610
+ delegateContext = void 0;
611
+ }
612
+ const context = delegateContext === void 0 ? void 0 : (primitive, fiber) => {
613
+ let evaluation = { _tag: "Pending" };
614
+ const currentEvaluation = () => evaluation;
615
+ const evaluate = (currentFiber) => {
616
+ switch (evaluation._tag) {
617
+ case "Succeeded": return evaluation.value;
618
+ case "Failed": throw evaluation.error;
619
+ case "Pending": try {
620
+ const value = primitive["~effect/Effect/evaluate"](currentFiber);
621
+ evaluation = {
622
+ _tag: "Succeeded",
623
+ value
624
+ };
625
+ return value;
626
+ } catch (error) {
627
+ evaluation = {
628
+ _tag: "Failed",
629
+ error
630
+ };
631
+ throw error;
632
+ }
633
+ }
634
+ };
635
+ const guardedPrimitive = { ["~effect/Effect/evaluate"]: evaluate };
636
+ try {
637
+ delegateContext(guardedPrimitive, fiber);
638
+ } catch (defect) {
639
+ const observed = currentEvaluation();
640
+ switch (observed._tag) {
641
+ case "Failed": throw observed.error;
642
+ case "Succeeded":
643
+ recordDefect(defect);
644
+ return observed.value;
645
+ case "Pending":
646
+ recordDefect(defect);
647
+ return evaluate(fiber);
648
+ }
649
+ }
650
+ const observed = currentEvaluation();
651
+ switch (observed._tag) {
652
+ case "Failed": throw observed.error;
653
+ case "Succeeded": return observed.value;
654
+ case "Pending": return evaluate(fiber);
655
+ }
656
+ };
657
+ return {
658
+ tracer: Tracer.make({
659
+ context,
660
+ span(options) {
661
+ let delegateSpan;
662
+ try {
663
+ delegateSpan = delegate.span(options);
664
+ } catch (defect) {
665
+ recordDefect(defect);
666
+ return new Tracer.NativeSpan(options);
667
+ }
668
+ try {
669
+ return new IsolatedToolSpan(delegateSpan, options, recordDefect);
670
+ } catch (defect) {
671
+ recordDefect(defect);
672
+ try {
673
+ delegateSpan.end(options.startTime, Exit.fail(new ToolSpanLifecycleFailure()));
674
+ } catch (closeDefect) {
675
+ recordDefect(closeDefect);
676
+ }
677
+ return new Tracer.NativeSpan(options);
678
+ }
679
+ }
680
+ }),
681
+ reportLifecycleDefects: Effect.suspend(() => {
682
+ const pending = defects.splice(0);
683
+ return Effect.forEach(pending, (defect) => isolateToolDerivative(ErrorReporter.report(Cause.die(defect))), { discard: true });
684
+ })
685
+ };
686
+ };
687
+ /**
688
+ * @internal Engine-owned span-lifecycle policy. The AgentRuntime composition boundary builds this
689
+ * capability from the host's ambient Tracer; Tool execution consumes it without selecting,
690
+ * decorating, or locally providing a Tracer implementation.
691
+ */
692
+ var ToolSpanTelemetry = class ToolSpanTelemetry extends Context.Service()("@effect-agent/engine/ToolSpanTelemetry") {
693
+ static layer = Layer.effect(ToolSpanTelemetry, Effect.map(Tracer.Tracer, (delegate) => ToolSpanTelemetry.of({
694
+ isolateEffectSpanLifecycle: (effect) => Effect.suspend(() => {
695
+ const isolated = makeIsolatedToolTracer(delegate);
696
+ return effect.pipe(Effect.provideService(Tracer.Tracer, isolated.tracer), Effect.ensuring(isolated.reportLifecycleDefects));
697
+ }),
698
+ isolateToolkitHandle: (effect) => Effect.currentSpan.pipe(Effect.option, Effect.flatMap((parentOption) => {
699
+ if (Option.isNone(parentOption)) return effect;
700
+ const parent = parentOption.value;
701
+ const local = new Tracer.NativeSpan({
702
+ name: "AgentRuntime.toolkit.handle",
703
+ parent: Option.some(parent),
704
+ annotations: Context.add(Context.empty(), Tracer.DisablePropagation, true),
705
+ links: [],
706
+ startTime: 0n,
707
+ kind: "internal",
708
+ sampled: parent.sampled
709
+ });
710
+ return effect.pipe(Effect.withParentSpan(local), Effect.onExit((exit) => Effect.sync(() => {
711
+ local.end(0n, exit);
712
+ })));
713
+ })),
714
+ isolateSpanLifecycle: (stream) => Stream.unwrap(Effect.sync(() => {
715
+ const isolated = makeIsolatedToolTracer(delegate);
716
+ return stream.pipe(Stream.provideService(Tracer.Tracer, isolated.tracer), Stream.ensuring(isolated.reportLifecycleDefects));
717
+ }))
718
+ })));
719
+ };
720
+ //#endregion
721
+ //#region src/engine/internal/error-diagnostic.ts
722
+ const DIAGNOSTIC_MESSAGE_LIMIT = 4096;
723
+ const DIAGNOSTIC_TAG_LIMIT = 128;
724
+ const boundedDiagnostic = (value, maxCharacters) => value.length <= maxCharacters ? value : value.slice(0, maxCharacters);
725
+ const ownStringDiagnostic = (input, key, maxCharacters) => {
726
+ if (input === null || typeof input !== "object" && typeof input !== "function") return;
727
+ try {
728
+ const descriptor = Object.getOwnPropertyDescriptor(input, key);
729
+ return descriptor !== void 0 && "value" in descriptor && typeof descriptor.value === "string" ? boundedDiagnostic(descriptor.value, maxCharacters) : void 0;
730
+ } catch {
731
+ return;
732
+ }
733
+ };
734
+ /** Total, bounded projection for opaque failures. It never invokes arbitrary coercion hooks. */
735
+ const errorMessage = (error) => {
736
+ const message = ownStringDiagnostic(error, "message", DIAGNOSTIC_MESSAGE_LIMIT);
737
+ if (message !== void 0) return message;
738
+ return typeof error === "string" ? boundedDiagnostic(error, DIAGNOSTIC_MESSAGE_LIMIT) : "Unknown error";
739
+ };
740
+ /** Total, bounded tag projection for opaque failures. */
741
+ const errorTag = (error) => ownStringDiagnostic(error, "_tag", DIAGNOSTIC_TAG_LIMIT) ?? "UnknownError";
742
+ //#endregion
743
+ //#region src/engine/internal/agent-runtime.ts
744
+ /** Schema factory for the terminal value produced by reducing a completed agent event stream. */
745
+ const AgentResultSchema = (output) => Schema.Struct({
746
+ output,
747
+ threadId: ThreadId,
748
+ runId: RunId,
749
+ turns: Schema.Int.check(Schema.isGreaterThan(0)),
750
+ finishReason: Schema.Literals([
751
+ "completed",
752
+ "model-stop",
753
+ "budget-exhausted"
754
+ ]),
755
+ /** Dimension that bound when the Run settled budget-exhausted (RUN-025; the grant-flow marker). */
756
+ exhausted: Schema.optionalKey(Schema.Literals([
757
+ "tokens",
758
+ "tool-calls",
759
+ "turns"
760
+ ])),
761
+ /** Schema-encoded application disposition declared for an ordinary completed Run. */
762
+ runDisposition: Schema.optionalKey(Schema.Json),
763
+ /** Cumulative spend for the Run, as reported on its terminal event. */
764
+ usage: Schema.optionalKey(RunTotals),
765
+ /** Disjoint usage of attached descendants, including nested and failed children. */
766
+ delegatedUsage: Schema.optionalKey(RunTotals)
767
+ }).check(Schema.makeFilter((result) => !("runDisposition" in result) || result.runDisposition === void 0 || !("finishReason" in result) || result.finishReason !== "budget-exhausted", { expected: "runDisposition only when finishReason is not budget-exhausted" }));
768
+ /** Direct usage only: budget counters never absorb descendant consumption. */
769
+ const runTotalsOf = (context) => RunTotals.make({
770
+ modelCalls: context.modelCalls,
771
+ inputTokens: context.inputTokens,
772
+ outputTokens: context.outputTokens,
773
+ costMicrousd: context.costMicrousd,
774
+ usageStatus: context.usageStatus,
775
+ pricingStatus: context.pricingStatus,
776
+ unobservedModelCalls: context.unobservedModelCalls
777
+ });
778
+ const usageReportOf = Effect.fn("AgentRuntime.usageReport")(function* (context) {
779
+ const contributions = [];
780
+ for (const read of context.childUsage.values()) {
781
+ const report = yield* read;
782
+ contributions.push(report.usage, report.delegatedUsage);
783
+ }
784
+ const delegatedUsage = yield* sumRunTotals(contributions).pipe(Effect.catchTag("UsageAggregationError", () => Effect.succeed(unknownRunTotals())));
785
+ return RunUsageReport.make({
786
+ usage: runTotalsOf(context),
787
+ delegatedUsage
788
+ });
789
+ });
790
+ const noteIncompleteUsage = Effect.fn("AgentRuntime.noteIncompleteUsage")(function* (context, turn) {
791
+ const accounting = yield* ModelUsageAccounting;
792
+ context.unobservedModelCalls += 1;
793
+ context.usageStatus = context.usageStatus === "unknown" || context.modelCalls === 0 ? "unknown" : "partial";
794
+ context.pricingStatus = context.pricingStatus === "unknown" || context.modelCalls === 0 ? "unknown" : "partial";
795
+ yield* accounting.noteIncompleteUsage(turn);
796
+ });
797
+ const runCounter = Metric.counter("effect_agent_runs_total", { description: "Agent runs started; no content or high-cardinality identifiers are recorded." });
798
+ const modelCounter = Metric.counter("effect_agent_model_calls_total", { description: "Agent model calls started; no content or high-cardinality identifiers are recorded." });
799
+ const toolCounter = Metric.counter("effect_agent_tool_calls_total", { description: "Agent tool handlers started; no content or high-cardinality identifiers are recorded." });
800
+ const MAX_STAGED_PROVIDER_EVENTS = 256;
801
+ const MAX_STAGED_PROVIDER_BYTES = 1048576;
802
+ const DEFAULT_RUN_BUFFER_LIMITS = {
803
+ maxModelResponseParts: 16384,
804
+ maxModelResponseBytes: 8388608,
805
+ maxRunEvents: 65536,
806
+ maxToolProgressBytes: 8388608,
807
+ maxSubagentEventsPerBatch: 1024
808
+ };
809
+ const tighteningBufferLimit = (configured, ceiling, minimum) => configured === void 0 || !Number.isFinite(configured) ? ceiling : Math.min(ceiling, Math.max(minimum, Math.floor(configured)));
810
+ const effectiveRunBufferLimits = (configured) => ({
811
+ maxModelResponseParts: tighteningBufferLimit(configured?.maxModelResponseParts, DEFAULT_RUN_BUFFER_LIMITS.maxModelResponseParts, 1),
812
+ maxModelResponseBytes: tighteningBufferLimit(configured?.maxModelResponseBytes, DEFAULT_RUN_BUFFER_LIMITS.maxModelResponseBytes, 1),
813
+ maxRunEvents: tighteningBufferLimit(configured?.maxRunEvents, DEFAULT_RUN_BUFFER_LIMITS.maxRunEvents, 2),
814
+ maxToolProgressBytes: tighteningBufferLimit(configured?.maxToolProgressBytes, DEFAULT_RUN_BUFFER_LIMITS.maxToolProgressBytes, 1),
815
+ maxSubagentEventsPerBatch: tighteningBufferLimit(configured?.maxSubagentEventsPerBatch, DEFAULT_RUN_BUFFER_LIMITS.maxSubagentEventsPerBatch, 1)
816
+ });
817
+ const structuredCloneFunction = Reflect.get(globalThis, "structuredClone");
818
+ const knownSafeModelResponsePrototypes = /* @__PURE__ */ new Set([Response.Usage.prototype]);
819
+ const schemaClassPrototype = (schema) => {
820
+ if (typeof schema !== "function" || !Schema.isSchema(schema)) return void 0;
821
+ const descriptor = Object.getOwnPropertyDescriptor(schema, "prototype");
822
+ return descriptor !== void 0 && "value" in descriptor && descriptor.value !== null && typeof descriptor.value === "object" ? descriptor.value : void 0;
823
+ };
824
+ /**
825
+ * Build the bounded preflight view for a decoded Tool payload whose root is an
826
+ * application-selected Schema class. The class instance is deliberately omitted:
827
+ * its complete canonical encoding is measured before cloning, and it is never
828
+ * retained in the Turn trace. Every other response field remains in the preflight.
829
+ */
830
+ const schemaClassToolPartPreflight = (part, toolkit) => {
831
+ try {
832
+ if (part === null || typeof part !== "object") return void 0;
833
+ const read = (key) => {
834
+ const descriptor = Object.getOwnPropertyDescriptor(part, key);
835
+ if (descriptor === void 0 || !("value" in descriptor)) throw new TypeError(`response part ${key} must be an own data property`);
836
+ return descriptor.value;
837
+ };
838
+ const type = read("type");
839
+ if (type !== "tool-call" && type !== "tool-result") return void 0;
840
+ const name = read("name");
841
+ if (typeof name !== "string" || !hasTool(toolkit.tools, name)) return void 0;
842
+ const tool = toolkit.tools[name];
843
+ const payload = read(type === "tool-call" ? "params" : "result");
844
+ if (payload === null || typeof payload !== "object") return void 0;
845
+ const payloadPrototype = Object.getPrototypeOf(payload);
846
+ if (!(type === "tool-call" ? [tool.parametersSchema] : [tool.successSchema, tool.failureSchema]).some((schema) => schemaClassPrototype(schema) === payloadPrototype)) return;
847
+ const preflight = {};
848
+ const retainedKeys = type === "tool-call" ? [
849
+ "type",
850
+ "id",
851
+ "name",
852
+ "providerExecuted",
853
+ "metadata"
854
+ ] : [
855
+ "type",
856
+ "id",
857
+ "name",
858
+ "isFailure",
859
+ "providerExecuted",
860
+ "preliminary",
861
+ "metadata",
862
+ "encodedResult"
863
+ ];
864
+ for (const key of retainedKeys) preflight[key] = read(key);
865
+ return preflight;
866
+ } catch {
867
+ return;
868
+ }
869
+ };
870
+ const inspectModelResponsePartCapacity = (usage, part, limits, knownSafePrototypes = knownSafeModelResponsePrototypes) => Effect.suspend(() => {
871
+ const bytes = boundedValueFootprint(part, limits.maxModelResponseBytes - usage.responsePartBytes, knownSafePrototypes);
872
+ return bytes === void 0 ? Effect.fail(ModelProtocolError.make({ message: `Model response exceeded the ${limits.maxModelResponseBytes}-byte retained response limit` })) : Effect.succeed(bytes);
873
+ });
874
+ /**
875
+ * `disableToolCallResolution` keeps model Tool Call parameters in their
876
+ * encoded wire form. Build the response ownership codec from those encoded
877
+ * parameter Schemas; the engine decodes and canonically re-encodes each call
878
+ * against the Definition-owned Schema before it enters history or executes.
879
+ */
880
+ const encodedToolParameterToolkit = (toolkit) => Toolkit.make(...Object.values(toolkit.tools).map((tool) => tool.setParameters(Schema.toEncoded(tool.parametersSchema))));
881
+ const makeModelResponseCodec = (toolkit) => Schema.toCodecJson(Response.StreamPart(encodedToolParameterToolkit(toolkit)));
882
+ const modelResponseCodecs = /* @__PURE__ */ new WeakMap();
883
+ const modelResponseCodecFor = (toolkit) => {
884
+ const cached = modelResponseCodecs.get(toolkit);
885
+ if (cached !== void 0) return cached;
886
+ const codec = makeModelResponseCodec(toolkit);
887
+ modelResponseCodecs.set(toolkit, codec);
888
+ return codec;
889
+ };
890
+ const ownModelResponsePartGeneral = Effect.fn("AgentRuntime.ownModelResponsePart")(function* (part, toolkit, usage, limits) {
891
+ if (usage.responsePartCount >= limits.maxModelResponseParts) return yield* ModelProtocolError.make({ message: `Model response exceeded the ${limits.maxModelResponseParts}-part response limit` });
892
+ if (boundedValueFootprint(part, limits.maxModelResponseBytes - usage.responsePartBytes, knownSafeModelResponsePrototypes) === void 0) {
893
+ const preflight = schemaClassToolPartPreflight(part, toolkit);
894
+ yield* inspectModelResponsePartCapacity(usage, preflight ?? part, limits);
895
+ }
896
+ const codec = modelResponseCodecFor(toolkit);
897
+ const encodingFailure = ModelProtocolError.make({ message: "Model response part failed canonical encoding" });
898
+ const encoded = yield* Schema.encodeUnknownEffect(codec)(part).pipe(Effect.mapError(() => encodingFailure));
899
+ const retainedBytes = yield* inspectModelResponsePartCapacity(usage, encoded, limits);
900
+ const ownedEncoded = yield* Effect.try({
901
+ try: () => {
902
+ if (typeof structuredCloneFunction !== "function") throw new TypeError("structuredClone is unavailable");
903
+ return Reflect.apply(structuredCloneFunction, globalThis, [encoded]);
904
+ },
905
+ catch: () => ModelProtocolError.make({ message: "Model response part could not be converted into engine-owned data" })
906
+ });
907
+ const decodingFailure = ModelProtocolError.make({ message: "Model response part failed canonical decoding" });
908
+ return {
909
+ ownedPart: yield* Schema.decodeUnknownEffect(codec)(ownedEncoded).pipe(Effect.mapError(() => decodingFailure)),
910
+ retainedBytes
911
+ };
912
+ });
913
+ const ownModelResponsePart = (part, toolkit, usage, limits) => Effect.suspend(() => {
914
+ const primitive = usage.responsePartCount < limits.maxModelResponseParts ? ownPrimitiveDelta(part, limits.maxModelResponseBytes - usage.responsePartBytes) : void 0;
915
+ return primitive === void 0 ? ownModelResponsePartGeneral(part, toolkit, usage, limits) : Effect.succeed(primitive);
916
+ });
917
+ const consumeModelResponsePart = (usage, retainedBytes, limits) => Effect.suspend(() => {
918
+ if (usage.responsePartCount >= limits.maxModelResponseParts || !Number.isSafeInteger(retainedBytes) || retainedBytes < 0 || retainedBytes > limits.maxModelResponseBytes - usage.responsePartBytes) return Effect.fail(ModelProtocolError.make({ message: usage.responsePartCount >= limits.maxModelResponseParts ? `Model response exceeded the ${limits.maxModelResponseParts}-part response limit` : `Model response exceeded the ${limits.maxModelResponseBytes}-byte retained response limit` }));
919
+ return Effect.sync(() => {
920
+ usage.responsePartCount += 1;
921
+ usage.responsePartBytes += retainedBytes;
922
+ });
923
+ });
924
+ const withSemaphorePermit = (semaphore, stream) => Stream.scoped(Stream.fromEffect(Effect.acquireRelease(semaphore.take(1), (permits) => semaphore.release(permits).pipe(Effect.asVoid))).pipe(Stream.flatMap(() => stream)));
925
+ const hasTool = (tools, name) => Object.hasOwn(tools, name);
926
+ const startPart = (parts, id, description) => {
927
+ if (parts.has(id)) return Effect.fail(ModelProtocolError.make({ message: `Model response repeated ${description} start for ${id}` }));
928
+ parts.set(id, "open");
929
+ return Effect.void;
930
+ };
931
+ const continuePart = (parts, id, description) => parts.get(id) === "open" ? Effect.void : Effect.fail(ModelProtocolError.make({ message: `Model response emitted ${description} for inactive part ${id}` }));
932
+ const endPart = (parts, id, description) => continuePart(parts, id, `${description} end`).pipe(Effect.tap(() => Effect.sync(() => parts.set(id, "closed"))));
933
+ const firstOpenPart = (trace) => {
934
+ for (const [id, state] of trace.textParts) if (state === "open") return `text part ${id}`;
935
+ for (const [id, state] of trace.reasoningParts) if (state === "open") return `reasoning part ${id}`;
936
+ for (const [id, part] of trace.toolParameterParts) if (part.state === "open") return `Tool parameter part ${id}`;
937
+ };
938
+ /** Canonically encode already-decoded Tool Call parameters for history and execution. */
939
+ const encodeToolCallParameters = (tool, toolName, decodedParams) => {
940
+ return Schema.encodeUnknownEffect(tool.parametersSchema)(decodedParams).pipe(Effect.mapError((cause) => ModelProtocolError.make({ message: `Invalid parameters for Tool ${toolName}: ${cause.message}` })));
941
+ };
942
+ /**
943
+ * Decode canonically recorded Tool parameters for policy and authorization.
944
+ * The private assertion restores the correlation lost by dynamic record
945
+ * lookup only around a successful Schema decode.
946
+ */
947
+ const decodeToolCallParameters = (tool, toolName, encodedParams, boundary = "execution") => {
948
+ return Schema.decodeUnknownEffect(tool.parametersSchema)(encodedParams).pipe(Effect.mapError((cause) => ModelProtocolError.make({ message: `Recorded parameters for Tool ${toolName} failed validation${boundary === "resume" ? " on resume" : ""}: ${cause.message}` })));
949
+ };
950
+ /**
951
+ * Decode canonical parameters for approval while retaining their encoded
952
+ * form for the native `Toolkit.handle` boundary.
953
+ */
954
+ const prepareToolCall = (toolkit, call, declarationIndex) => {
955
+ const name = call.name;
956
+ if (!hasTool(toolkit.tools, name)) return Effect.fail(ModelProtocolError.make({ message: `Model requested unknown Tool ${call.name}` }));
957
+ const tool = toolkit.tools[name];
958
+ return decodeToolCallId(call.id).pipe(Effect.flatMap((toolCallId) => decodeToolCallParameters(tool, call.name, call.params).pipe(Effect.map((decodedParams) => ({
959
+ call,
960
+ name,
961
+ toolCallId,
962
+ decodedParams,
963
+ tool,
964
+ declarationIndex
965
+ })))));
966
+ };
967
+ /**
968
+ * Re-validate one canonically recorded Tool Call's encoded parameters through
969
+ * the owning parameter Schema before a resumed batch may execute anything.
970
+ * Declarations were validated when they entered the log (RUN-004), but a
971
+ * resumed Attempt re-validates on read (STORE-006); a decode failure is a
972
+ * strict no-start boundary. The same private assertion contract as
973
+ * `encodeToolCallParameters` applies: correlation lost by dynamic record
974
+ * lookup is restored only around a successful Schema decode.
975
+ */
976
+ /**
977
+ * Effective Run bounds (RUN-021): per-Run allowances tighten the Agent
978
+ * Policy's Turn and Tool Call ceilings but can never widen them — the
979
+ * effective limit is `min(policy bound, max(1, floor(allowance)))`. The
980
+ * `onExhaustion` resolution (RUN-018/RUN-019) keys off these effective
981
+ * limits, which is how an orchestrator grants a delegated child a budget
982
+ * extension by re-invoking with a larger allowance below the Definition's
983
+ * ceiling.
984
+ */
985
+ const CurrentSubagentAuthority = Context.Reference("@effect-agent/engine/internal/CurrentSubagentAuthority", { defaultValue: () => void 0 });
986
+ const boundedAllowance = (policyBound, allowance) => allowance === void 0 || !Number.isFinite(allowance) ? policyBound : Math.min(policyBound, Math.max(1, Math.floor(allowance)));
987
+ const effectiveRunBounds = (policy, options) => ({
988
+ maxTurns: boundedAllowance(policy.maxTurns, options.turnAllowance),
989
+ maxToolCalls: boundedAllowance(policy.maxToolCalls, options.toolCallAllowance)
990
+ });
991
+ const decodeResumedSettledCall = Effect.fn("AgentRuntime.decodeResumedSettledCall")((input, maxResultBytes, providerCallIds) => Effect.gen(function* () {
992
+ const raw = yield* Effect.try({
993
+ try: () => {
994
+ if (input === null || typeof input !== "object") throw new TypeError("settled Tool Call must be an object");
995
+ const readOwnDataProperty = (key) => {
996
+ const descriptor = Object.getOwnPropertyDescriptor(input, key);
997
+ if (descriptor === void 0 || !("value" in descriptor)) throw new TypeError(`settled Tool Call ${key} must be an own data property`);
998
+ return descriptor.value;
999
+ };
1000
+ const selection = Object.getOwnPropertyDescriptor(input, "toolSelection");
1001
+ if (selection !== void 0 && !("value" in selection)) throw new TypeError("settled Tool selection must be an own data property");
1002
+ const rejected = Object.getOwnPropertyDescriptor(input, "budgetRejected");
1003
+ if (rejected !== void 0 && !("value" in rejected)) throw new TypeError("settled Tool Call budgetRejected must be an own data property");
1004
+ return {
1005
+ id: readOwnDataProperty("id"),
1006
+ result: readOwnDataProperty("result"),
1007
+ isFailure: readOwnDataProperty("isFailure"),
1008
+ ...rejected === void 0 ? {} : { budgetRejected: rejected.value },
1009
+ ...selection === void 0 ? {} : { toolSelection: selection.value }
1010
+ };
1011
+ },
1012
+ catch: () => ModelProtocolError.make({ message: "Turn resume contains an invalid settled Tool Call" })
1013
+ });
1014
+ const result = boundedCanonicalJsonSnapshot(raw.result, typeof raw.id === "string" && providerCallIds.has(raw.id) ? MAX_STAGED_PROVIDER_BYTES : maxResultBytes);
1015
+ if (result === void 0) return yield* ModelProtocolError.make({ message: "Turn resume settled Tool result is not bounded canonical JSON" });
1016
+ return yield* Schema.decodeUnknownEffect(RunTurnResumeSettledCallSchema)({
1017
+ ...raw,
1018
+ result: result.value
1019
+ }).pipe(Effect.mapError(() => ModelProtocolError.make({ message: "Turn resume contains an invalid settled Tool Call" })));
1020
+ }));
1021
+ const snapshotResumedSettledCalls = Effect.fn("AgentRuntime.snapshotResumedSettledCalls")((resume, maximum) => Effect.try({
1022
+ try: () => {
1023
+ if (resume === null || typeof resume !== "object") throw new TypeError("Turn resume must be an object");
1024
+ const settledDescriptor = Object.getOwnPropertyDescriptor(resume, "settled");
1025
+ if (settledDescriptor === void 0 || !("value" in settledDescriptor)) throw new TypeError("Turn resume settled must be an own data property");
1026
+ const settled = settledDescriptor.value;
1027
+ if (!Array.isArray(settled)) throw new TypeError("Turn resume settled must be an array");
1028
+ const lengthDescriptor = Object.getOwnPropertyDescriptor(settled, "length");
1029
+ if (lengthDescriptor === void 0 || !("value" in lengthDescriptor) || !Number.isSafeInteger(lengthDescriptor.value) || lengthDescriptor.value < 0 || lengthDescriptor.value > maximum) throw new TypeError("Turn resume settled has an invalid length");
1030
+ const snapshot = [];
1031
+ for (let index = 0; index < lengthDescriptor.value; index += 1) {
1032
+ const entryDescriptor = Object.getOwnPropertyDescriptor(settled, String(index));
1033
+ if (entryDescriptor === void 0 || !("value" in entryDescriptor)) throw new TypeError("Turn resume settled entries must be own data properties");
1034
+ snapshot.push(entryDescriptor.value);
1035
+ }
1036
+ return snapshot;
1037
+ },
1038
+ catch: () => ModelProtocolError.make({ message: "Turn resume contains an invalid settled Tool Call collection" })
1039
+ }));
1040
+ const decodeResumeUsage = Effect.fn("AgentRuntime.decodeResumeUsage")((input) => Effect.gen(function* () {
1041
+ const snapshot = yield* Effect.try({
1042
+ try: () => {
1043
+ if (input === null || typeof input !== "object") throw new TypeError("Run resume usage must be an object");
1044
+ const read = (key, optional = false) => {
1045
+ const descriptor = Object.getOwnPropertyDescriptor(input, key);
1046
+ if (descriptor === void 0 && optional) return void 0;
1047
+ if (descriptor === void 0 || !("value" in descriptor)) throw new TypeError(`Run resume usage ${key} must be an own data property`);
1048
+ return descriptor.value;
1049
+ };
1050
+ return {
1051
+ ...Object.fromEntries([
1052
+ "usageStatus",
1053
+ "pricingStatus",
1054
+ "unobservedModelCalls",
1055
+ "children"
1056
+ ].map((key) => [key, read(key, true)]).filter(([, value]) => value !== void 0)),
1057
+ modelCalls: read("modelCalls"),
1058
+ inputTokens: read("inputTokens"),
1059
+ outputTokens: read("outputTokens"),
1060
+ lastInputTokens: read("lastInputTokens"),
1061
+ lastOutputTokens: read("lastOutputTokens"),
1062
+ costMicrousd: read("costMicrousd"),
1063
+ committedTurns: read("committedTurns"),
1064
+ toolCalls: read("toolCalls"),
1065
+ programmaticToolCalls: read("programmaticToolCalls"),
1066
+ consecutiveToolFailures: read("consecutiveToolFailures"),
1067
+ finalizationUsed: read("finalizationUsed")
1068
+ };
1069
+ },
1070
+ catch: () => ModelProtocolError.make({ message: "Run resume usage requires own data properties with non-negative safe-integer totals and last-call tokens no greater than their cumulative totals" })
1071
+ });
1072
+ return yield* Schema.decodeUnknownEffect(RunResumeUsageSchema)(snapshot).pipe(Effect.mapError(() => ModelProtocolError.make({ message: "Run resume usage requires own data properties with non-negative safe-integer totals and last-call tokens no greater than their cumulative totals" })));
1073
+ }));
1074
+ const makeToolFailedEvent = Effect.fn("AgentRuntime.makeToolFailedEvent")(function* (context, turnId, call, error, failureHandling, budgetRejected) {
1075
+ const toolCallId = yield* decodeToolCallId(call.id);
1076
+ const tools = context.definition.toolkit.tools;
1077
+ return ToolCallFailed.make({
1078
+ ...yield* eventBase(context),
1079
+ turnId,
1080
+ toolCallId,
1081
+ toolName: call.name,
1082
+ errorTag: errorTag(error),
1083
+ message: errorMessage(error),
1084
+ providerExecuted: false,
1085
+ failureHandling,
1086
+ ...Object.hasOwn(tools, call.name) ? { failureMode: tools[call.name].failureMode } : {},
1087
+ ...budgetRejected === void 0 ? {} : { budgetRejected }
1088
+ });
1089
+ });
1090
+ /**
1091
+ * Settle a rejected Tool batch without starting any handler: every open
1092
+ * application call receives the encoded failure as its model-visible result.
1093
+ * Only budget rejections (RUN-018) are exempt from repeated-failure folding;
1094
+ * correctable model declarations count as ordinary failed calls. Emit one
1095
+ * `ToolCallFailed` per call with no `ToolCallStarted` (the
1096
+ * approval-denied precedent). The caller hands the trace to
1097
+ * `toolBatchContinuation`, so the synthetic results advance history through
1098
+ * the ordinary tool message and — under a durable coordinator that never saw
1099
+ * a response commit for this Turn — settle canonically via the single-batch
1100
+ * Turn commit.
1101
+ */
1102
+ const settleRejectedBatch = Effect.fn("AgentRuntime.settleRejectedBatch")(function* (context, turnId, trace, error, alreadySettled) {
1103
+ const budgetRejected = error._tag === "AgentPolicyError" ? true : void 0;
1104
+ const encodedResult = {
1105
+ _tag: error._tag,
1106
+ ...error._tag === "AgentPolicyError" ? { limit: error.limit } : {},
1107
+ message: error.message
1108
+ };
1109
+ const events = [];
1110
+ for (const [index, call] of trace.applicationToolCalls.entries()) {
1111
+ if (alreadySettled?.has(call.id) === true) continue;
1112
+ trace.finalToolResultIds.add(call.id);
1113
+ trace.applicationToolResults[index] = {
1114
+ id: call.id,
1115
+ name: call.name,
1116
+ encodedResult,
1117
+ isFailure: true,
1118
+ ...budgetRejected === void 0 ? {} : { budgetRejected }
1119
+ };
1120
+ events.push(yield* makeToolFailedEvent(context, turnId, call, error, "returned-to-model", budgetRejected));
1121
+ }
1122
+ return events;
1123
+ });
1124
+ const stampSubagentEvent = Effect.fn("AgentRuntime.stampSubagentEvent")(function* (context, turnId, payload) {
1125
+ if (payload._tag === "AgentUpdateEmitted") return AgentUpdateEmitted.make({
1126
+ ...yield* eventBase(context),
1127
+ turnId,
1128
+ update: payload.update
1129
+ });
1130
+ const shared = {
1131
+ ...yield* eventBase(context),
1132
+ turnId,
1133
+ toolCallId: payload.toolCallId,
1134
+ delegationId: payload.delegationId,
1135
+ childThreadId: payload.childThreadId,
1136
+ childRunId: payload.childRunId,
1137
+ targetAgentId: payload.targetAgentId,
1138
+ depth: payload.depth
1139
+ };
1140
+ const report = "usage" in payload ? {
1141
+ ...payload.usage === void 0 ? {} : { usage: payload.usage },
1142
+ ...payload.delegatedUsage === void 0 ? {} : { delegatedUsage: payload.delegatedUsage }
1143
+ } : {};
1144
+ switch (payload._tag) {
1145
+ case "SubagentRequested": return SubagentRequested.make(shared);
1146
+ case "SubagentStarted": return SubagentStarted.make(shared);
1147
+ case "SubagentProgress": return SubagentProgress.make({
1148
+ ...shared,
1149
+ summary: payload.summary
1150
+ });
1151
+ case "SubagentCompleted": return SubagentCompleted.make({
1152
+ ...shared,
1153
+ turns: payload.turns,
1154
+ finishReason: payload.finishReason,
1155
+ ...payload.exhausted !== void 0 ? { exhausted: payload.exhausted } : {},
1156
+ ...report
1157
+ });
1158
+ case "SubagentFailed": return SubagentFailed.make({
1159
+ ...shared,
1160
+ ...report,
1161
+ errorTag: payload.errorTag,
1162
+ message: payload.message
1163
+ });
1164
+ case "SubagentInterrupted": return SubagentInterrupted.make({
1165
+ ...shared,
1166
+ ...report,
1167
+ reason: payload.reason
1168
+ });
1169
+ case "SubagentJoined": return SubagentJoined.make({
1170
+ ...shared,
1171
+ ...report
1172
+ });
1173
+ }
1174
+ });
1175
+ const approvalDecision = (context, turnId, prepared, options) => Effect.gen(function* () {
1176
+ const approval = prepared.tool.needsApproval;
1177
+ if (approval === void 0 || approval === false) return { required: false };
1178
+ if (!(typeof approval === "function" ? yield* Effect.suspend(() => {
1179
+ const result = approval(prepared.decodedParams, {
1180
+ toolCallId: prepared.call.id,
1181
+ messages: context.history.content
1182
+ });
1183
+ return Effect.isEffect(result) ? result : Effect.succeed(result);
1184
+ }) : approval)) return { required: false };
1185
+ const request = Response.makePart("tool-approval-request", {
1186
+ approvalId: `${context.runId}:${prepared.call.id}`,
1187
+ toolCallId: prepared.call.id
1188
+ });
1189
+ if (options.approval === void 0) return {
1190
+ required: true,
1191
+ request,
1192
+ decision: {
1193
+ _tag: "unresolved",
1194
+ reason: "No approval decision hook is available"
1195
+ }
1196
+ };
1197
+ const toolCallId = yield* decodeToolCallId(prepared.call.id);
1198
+ return {
1199
+ required: true,
1200
+ request,
1201
+ decision: yield* options.approval.request({
1202
+ request,
1203
+ threadId: context.threadId,
1204
+ runId: context.runId,
1205
+ turnId,
1206
+ toolCallId,
1207
+ toolName: prepared.call.name,
1208
+ parameters: prepared.decodedParams
1209
+ })
1210
+ };
1211
+ });
1212
+ /**
1213
+ * Resolve every native Effect AI approval before the handler scheduler starts.
1214
+ * Concatenating this preflight stream ahead of handler streams makes denied or
1215
+ * unresolved batches a strict no-start boundary.
1216
+ */
1217
+ const preflightApproval = (context, turnId, prepared, options) => Stream.unwrap(approvalDecision(context, turnId, prepared, options).pipe(Effect.flatMap((approval) => {
1218
+ if (!approval.required) return Effect.succeed(Stream.empty);
1219
+ return Effect.gen(function* () {
1220
+ const toolCallId = yield* decodeToolCallId(prepared.call.id);
1221
+ const requested = ApprovalRequested.make({
1222
+ ...yield* eventBase(context),
1223
+ turnId,
1224
+ toolCallId,
1225
+ toolName: prepared.call.name
1226
+ });
1227
+ switch (approval.decision._tag) {
1228
+ case "approved": return Stream.succeed(requested);
1229
+ case "denied": {
1230
+ const denied = AgentApprovalDenied.make({
1231
+ toolCallId: prepared.call.id,
1232
+ toolName: prepared.call.name,
1233
+ message: approval.decision.reason ?? "Tool approval was denied"
1234
+ });
1235
+ const failed = ToolCallFailed.make({
1236
+ ...yield* eventBase(context),
1237
+ turnId,
1238
+ toolCallId,
1239
+ toolName: prepared.call.name,
1240
+ errorTag: denied._tag,
1241
+ message: denied.message,
1242
+ providerExecuted: false,
1243
+ failureMode: prepared.tool.failureMode,
1244
+ failureHandling: "propagated"
1245
+ });
1246
+ return Stream.fromIterable([requested, failed]).pipe(Stream.concat(Stream.fail(denied)));
1247
+ }
1248
+ case "unresolved": {
1249
+ const pending = AgentApprovalPending.make({
1250
+ approvalId: approval.request.approvalId,
1251
+ toolCallId: prepared.call.id,
1252
+ toolName: prepared.call.name,
1253
+ message: approval.decision.reason ?? "Tool approval remains unresolved"
1254
+ });
1255
+ return Stream.succeed(requested).pipe(Stream.concat(Stream.fail(pending)));
1256
+ }
1257
+ }
1258
+ });
1259
+ })));
1260
+ /**
1261
+ * Recheck host-owned Tool authority after approval and before durable preparation or scheduling.
1262
+ * Every call in the executable batch is authorized in declaration order before ANY Handler may
1263
+ * start, so a later denial leaves this Attempt's complete batch at zero application side effects.
1264
+ */
1265
+ const preflightToolAuthorization = (context, turnId, turn, call, options, annotations) => {
1266
+ const authorization = isSubagentToolAllowed(options.subagentGrant, options.delegationDepth ?? options.parentLink?.depth ?? 0, call.toolName, annotations) ? options.toolAuthorization : { authorize: () => Effect.succeed({
1267
+ _tag: "denied",
1268
+ reason: "Tool exceeds the inherited subagent grant"
1269
+ }) };
1270
+ if (authorization === void 0) return Stream.empty;
1271
+ return Stream.unwrap(authorization.authorize({
1272
+ threadId: context.threadId,
1273
+ runId: context.runId,
1274
+ turnId,
1275
+ turn,
1276
+ input: context.input,
1277
+ call
1278
+ }).pipe(Effect.map((decision) => {
1279
+ if (decision._tag === "allowed") return Stream.empty;
1280
+ const denied = AgentToolAuthorizationDenied.make({
1281
+ toolCallId: call.toolCallId,
1282
+ toolName: call.toolName,
1283
+ message: decision.reason
1284
+ });
1285
+ return Stream.fromEffect(Effect.map(eventBase(context), (base) => ToolCallFailed.make({
1286
+ ...base,
1287
+ turnId,
1288
+ toolCallId: call.toolCallId,
1289
+ toolName: call.toolName,
1290
+ errorTag: denied._tag,
1291
+ message: denied.message,
1292
+ providerExecuted: false,
1293
+ failureMode: context.definition.toolkit.tools[call.toolName].failureMode,
1294
+ failureHandling: "propagated"
1295
+ }))).pipe(Stream.concat(Stream.fail(denied)));
1296
+ })));
1297
+ };
1298
+ const ProviderResponsePartId = Schema.String.check(Schema.isMaxLength(128), Schema.isPattern(/^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/));
1299
+ const ProviderToolCallId = ToolCallId.check(Schema.isMaxLength(128), Schema.isPattern(/^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/));
1300
+ const isTelemetryToolCallId = Schema.is(ProviderToolCallId);
1301
+ /** One bounded identity surface shared by canonical Tool spans and terminal logs. */
1302
+ const toolTelemetryAttributes = (descriptor) => ({
1303
+ "gen_ai.operation.name": "execute_tool",
1304
+ "gen_ai.tool.name": descriptor.toolName,
1305
+ "gen_ai.tool.type": "function",
1306
+ ...descriptor.toolCallId === void 0 ? {} : {
1307
+ "gen_ai.tool.call.id": descriptor.toolCallId,
1308
+ toolCallId: descriptor.toolCallId
1309
+ },
1310
+ "gen_ai.agent.name": descriptor.context.agentId,
1311
+ "gen_ai.conversation.id": descriptor.context.threadId,
1312
+ "effect_agent.tool.execution_class": descriptor.executionClass,
1313
+ "effect_agent.tool.invocation_kind": descriptor.invocationKind,
1314
+ "effect_agent.tool.failure_mode": descriptor.failureMode,
1315
+ ...descriptor.parentToolCallId === void 0 ? {} : {
1316
+ "effect_agent.tool.parent_call.id": descriptor.parentToolCallId,
1317
+ parentToolCallId: descriptor.parentToolCallId
1318
+ },
1319
+ ...descriptor.sequenceIndex === void 0 ? {} : {
1320
+ "effect_agent.tool.sequence_index": descriptor.sequenceIndex,
1321
+ sequenceIndex: descriptor.sequenceIndex
1322
+ },
1323
+ agentId: descriptor.context.agentId,
1324
+ threadId: descriptor.context.threadId,
1325
+ runId: descriptor.context.runId,
1326
+ turnId: descriptor.turnId,
1327
+ toolName: descriptor.toolName
1328
+ });
1329
+ /** Canonical content-free terminal signal for any application Tool handler attempt. */
1330
+ const terminalToolTelemetry = (descriptor, outcome, failureMarker, failureHandling) => annotateToolSpanTerminalOutcome(outcome, failureMarker, failureHandling, descriptor.failureMode).pipe(Effect.andThen((outcome === "success" ? Effect.logInfo("agent tool execution completed") : Effect.logWarning("agent tool execution failed")).pipe(Effect.annotateLogs({
1331
+ ...toolTelemetryAttributes(descriptor),
1332
+ "effect_agent.tool.outcome": outcome,
1333
+ ...failureHandling === void 0 ? {} : { "effect_agent.tool.failure_handling": failureHandling },
1334
+ toolExecutionClass: descriptor.executionClass,
1335
+ toolOutcome: outcome
1336
+ }))));
1337
+ /** Bound only the observer's diagnostic; broker/public diagnostic policy is a separate contract. */
1338
+ const toolFailureMessage = (message) => {
1339
+ let bytes = 0;
1340
+ let end = 0;
1341
+ for (const character of message) {
1342
+ const size = utf8ByteLength(character);
1343
+ if (bytes + size > 4096) break;
1344
+ bytes += size;
1345
+ end += character.length;
1346
+ }
1347
+ return message.slice(0, end);
1348
+ };
1349
+ const executePreparedToolCall = (context, turnId, toolkit, prepared, trace, resultBounds, onWaiting) => {
1350
+ const call = prepared.call;
1351
+ const observer = context.toolFailureObserver;
1352
+ const telemetryToolCallId = isTelemetryToolCallId(call.id) ? call.id : void 0;
1353
+ const executionClass = getToolExecutionClass(prepared.tool);
1354
+ const telemetryDescriptor = {
1355
+ context,
1356
+ turnId,
1357
+ toolCallId: telemetryToolCallId,
1358
+ toolName: call.name,
1359
+ executionClass,
1360
+ invocationKind: "model",
1361
+ failureMode: prepared.tool.failureMode
1362
+ };
1363
+ const toolSpanFailure = ToolSpanFailure.marker();
1364
+ let terminal = false;
1365
+ let terminalResultCommitted = false;
1366
+ let terminalOutcome;
1367
+ let terminalResult;
1368
+ let propagatedFailure;
1369
+ let failureObservation;
1370
+ const terminalTelemetry = (outcome, failureHandling) => terminalToolTelemetry(telemetryDescriptor, outcome, outcome === "failure" ? toolSpanFailure : void 0, failureHandling);
1371
+ const isolatedTerminalTelemetry = (outcome, failureHandling) => isolateToolDerivative(terminalTelemetry(outcome, failureHandling));
1372
+ /**
1373
+ * The authoritative event reaches the downstream Run stream before derivative work starts.
1374
+ * Telemetry and observation share one owner across the next-pull/early-close race, under this
1375
+ * call's batch permit. A returned failure still fails a normal second pull with the span marker.
1376
+ */
1377
+ const terminalEventThenAfter = (event, outcome, failSpan, failureHandling) => {
1378
+ const telemetry = isolatedTerminalTelemetry(outcome, failureHandling);
1379
+ const after = observer === void 0 ? telemetry : telemetry.pipe(Effect.andThen(Effect.suspend(() => failureObservation === void 0 ? Effect.void : deliverToolFailure(observer, failureObservation))));
1380
+ return emitThenAfter(event, after.pipe(Effect.andThen(failSpan ? Effect.fail(toolSpanFailure) : Effect.void)));
1381
+ };
1382
+ const started = Stream.fromEffect(Effect.gen(function* () {
1383
+ const toolCallId = yield* decodeToolCallId(call.id);
1384
+ yield* Effect.logDebug("agent tool handler started").pipe(Effect.annotateLogs({
1385
+ agentId: context.agentId,
1386
+ runId: context.runId,
1387
+ turnId,
1388
+ ...telemetryToolCallId === void 0 ? {} : { toolCallId: telemetryToolCallId },
1389
+ toolName: call.name
1390
+ }));
1391
+ yield* Metric.update(toolCounter, 1);
1392
+ return ToolCallStarted.make({
1393
+ ...yield* eventBase(context),
1394
+ turnId,
1395
+ toolCallId,
1396
+ toolName: call.name
1397
+ });
1398
+ }).pipe(Effect.withLogSpan("AgentRuntime.tool")));
1399
+ const handle = toolkit.handle;
1400
+ const results = Stream.unwrap(Effect.flatMap(ToolSpanTelemetry, ({ isolateToolkitHandle }) => isolateToolkitHandle(handle.call(toolkit, prepared.name, call.params, call.id)))).pipe(Stream.mapEffect((result) => Effect.gen(function* () {
1401
+ if (terminal || trace.finalToolResultIds.has(call.id)) return yield* ModelProtocolError.make({ message: `Tool Call ${call.id} produced more than one terminal result` });
1402
+ const toolCallId = yield* decodeToolCallId(call.id);
1403
+ if (result.preliminary) {
1404
+ const owned = yield* ownApplicationToolProgress(context, result.encodedResult);
1405
+ return ToolProgress.make({
1406
+ ...yield* eventBase(context),
1407
+ turnId,
1408
+ toolCallId,
1409
+ toolName: call.name,
1410
+ result: owned,
1411
+ providerExecuted: false
1412
+ });
1413
+ }
1414
+ terminal = true;
1415
+ terminalOutcome = result.isFailure ? "failure" : "success";
1416
+ terminalResult = {
1417
+ encodedResult: result.encodedResult,
1418
+ isFailure: result.isFailure,
1419
+ result: result.result
1420
+ };
1421
+ })), Stream.filter((event) => event !== void 0));
1422
+ const commitTerminalResult = Effect.suspend(() => {
1423
+ if (!terminal || terminalOutcome === void 0 || terminalResult === void 0) return Effect.fail(ModelProtocolError.make({ message: `Tool Call ${call.id} completed without a terminal result` }));
1424
+ const result = terminalResult;
1425
+ return Effect.gen(function* () {
1426
+ const toolCallId = yield* decodeToolCallId(call.id);
1427
+ let toolSelection;
1428
+ if (!result.isFailure && Context.get(prepared.tool.annotations, DiscoveryTool)) {
1429
+ toolSelection = yield* validateSelection(result.result, context.definition, context.toolCatalog);
1430
+ yield* exposureSnapshot(context.definition, toolSelection, context.toolCatalog, context.toolSchemaTransformer);
1431
+ }
1432
+ const encodedResult = boundEncodedToolResult(result.encodedResult, resultBounds);
1433
+ const event = result.isFailure ? ToolCallFailed.make({
1434
+ ...yield* eventBase(context),
1435
+ turnId,
1436
+ toolCallId,
1437
+ toolName: call.name,
1438
+ errorTag: errorTag(result.result),
1439
+ message: errorMessage(result.result),
1440
+ providerExecuted: false,
1441
+ failureMode: prepared.tool.failureMode,
1442
+ failureHandling: "returned-to-model"
1443
+ }) : ToolCallSucceeded.make({
1444
+ ...yield* eventBase(context),
1445
+ turnId,
1446
+ toolCallId,
1447
+ toolName: call.name,
1448
+ result: yield* decodeEventJson(encodedResult, "Tool result"),
1449
+ ...toolSelection === void 0 ? {} : { toolSelection },
1450
+ providerExecuted: false
1451
+ });
1452
+ trace.finalToolResultIds.add(call.id);
1453
+ trace.applicationToolResults[prepared.declarationIndex] = {
1454
+ ...toolSelection === void 0 ? {} : { toolSelection },
1455
+ id: call.id,
1456
+ name: call.name,
1457
+ encodedResult,
1458
+ isFailure: result.isFailure
1459
+ };
1460
+ terminalResultCommitted = true;
1461
+ if (observer !== void 0 && event._tag === "ToolCallFailed") failureObservation = {
1462
+ _tag: "ModelToolFailure",
1463
+ kind: "declared-failure",
1464
+ agentId: context.agentId,
1465
+ threadId: context.threadId,
1466
+ runId: context.runId,
1467
+ turnId,
1468
+ toolCallId,
1469
+ toolName: call.name,
1470
+ executionClass,
1471
+ tag: event.errorTag
1472
+ };
1473
+ return event;
1474
+ });
1475
+ });
1476
+ const finalizeTerminalResult = Stream.unwrap(Effect.sync(() => terminalEventThenAfter(commitTerminalResult, terminalOutcome ?? "failure", terminalOutcome === "failure", terminalOutcome === "failure" ? "returned-to-model" : void 0)));
1477
+ const failTerminalResult = (cause) => {
1478
+ terminal = true;
1479
+ terminalOutcome = "failure";
1480
+ terminalResult = void 0;
1481
+ propagatedFailure = cause;
1482
+ return terminalEventThenAfter(makeToolFailedEvent(context, turnId, call, Cause.squash(cause), "propagated").pipe(Effect.tap(() => Effect.sync(() => {
1483
+ trace.finalToolResultIds.add(call.id);
1484
+ terminalResultCommitted = true;
1485
+ }))), "failure", true, "propagated");
1486
+ };
1487
+ const measured = started.pipe(Stream.concat(results), Stream.concat(finalizeTerminalResult), Stream.catchCause((cause) => {
1488
+ const { found: hasToolSpanFailure, residual: toolCause } = stripToolSpanFailures(cause, toolSpanFailure);
1489
+ if (hasToolSpanFailure) return Stream.failCause(cause);
1490
+ if (terminalResultCommitted) return Stream.failCause(toolCause);
1491
+ if (toolCause.reasons.length > 0 && toolCause.reasons.every(Cause.isInterruptReason)) return Stream.failCause(toolCause);
1492
+ const waiting = waitingFromCause(toolCause);
1493
+ if (waiting !== void 0) {
1494
+ if (terminal || trace.finalToolResultIds.has(call.id)) return failTerminalResult(Cause.fail(ModelProtocolError.make({ message: `Tool Call ${call.id} raised the waiting signal after its terminal result` })));
1495
+ onWaiting(waiting);
1496
+ return Stream.empty;
1497
+ }
1498
+ return failTerminalResult(toolCause);
1499
+ }), Stream.withSpan(`execute_tool ${call.name}`, {
1500
+ kind: "internal",
1501
+ attributes: toolTelemetryAttributes(telemetryDescriptor)
1502
+ }));
1503
+ return Stream.unwrap(Effect.map(ToolSpanTelemetry, ({ isolateSpanLifecycle }) => isolateSpanLifecycle(measured))).pipe(Stream.catchCause((cause) => {
1504
+ const { found, restored } = restoreToolSpanFailureCause(cause, toolSpanFailure, propagatedFailure);
1505
+ if (!found) return Stream.failCause(restored);
1506
+ return restored.reasons.length === 0 ? Stream.empty : Stream.failCause(restored);
1507
+ }));
1508
+ };
1509
+ /**
1510
+ * Execute a wholly preflighted native Toolkit batch under one finite engine
1511
+ * semaphore.
1512
+ *
1513
+ * The engine provides this batch's `RunEventSink` locally to the handler
1514
+ * streams, bound to the batch's Turn. Sink emissions are drained into the
1515
+ * batch stream and stamped through `eventBase`; the batch settles (including
1516
+ * by failure) only after every already-emitted Subagent event has surfaced.
1517
+ * The public exclusion of engine-provided services happens once at the Run
1518
+ * boundary in `stream`, so this signature keeps the naked handler services.
1519
+ */
1520
+ const executeToolBatch = (context, turnId, turn, toolkit, calls, trace, concurrency, options, brokerAccounting, resultBounds, settledCallIds) => Stream.unwrap(Effect.gen(function* () {
1521
+ const exposed = context.toolExposure?.exposedToolNames;
1522
+ const visibility = yield* RunToolVisibility;
1523
+ const eligible = new Set(context.toolCatalog.filter((entry) => entry.kind === "native").map((entry) => entry.nativeToolName));
1524
+ if (calls.some((call) => exposed !== void 0 && !exposed.includes(call.name) || visibility !== void 0 && !settledCallIds?.has(call.id) && !eligible.has(call.name))) return yield* ModelProtocolError.make({ message: "Tool batch calls a Tool outside its request exposure or current visibility" });
1525
+ const prepared = yield* Effect.forEach(calls, (call, declarationIndex) => prepareToolCall(toolkit, call, declarationIndex));
1526
+ if (prepared.some((call) => Context.get(call.tool.annotations, ContextRolloverTool)) && trace.toolCalls.size !== 1) return yield* ModelProtocolError.make({ message: "A context rollover Tool must be the only Tool Call in its batch" });
1527
+ const semaphore = yield* Semaphore.make(concurrency);
1528
+ const approvalPreflight = prepared.reduce((stream, call) => stream.pipe(Stream.concat(preflightApproval(context, turnId, call, options))), Stream.empty);
1529
+ const descriptors = trace.applicationCallDescriptors;
1530
+ const durability = options.durability;
1531
+ const hookServices = yield* Effect.context();
1532
+ const executable = settledCallIds === void 0 ? prepared : prepared.filter((call) => !settledCallIds.has(call.call.id));
1533
+ const authorizationPreflight = (settledCallIds === void 0 ? descriptors : descriptors.filter((call) => !settledCallIds.has(call.toolCallId))).reduce((stream, call) => stream.pipe(Stream.concat(preflightToolAuthorization(context, turnId, turn, call, options, toolkit.tools[call.toolName]?.annotations ?? Context.empty()))), Stream.empty);
1534
+ const preparation = durability === void 0 ? Stream.empty : Stream.fromEffect(Effect.suspend(() => {
1535
+ const preparedDescriptors = descriptors.filter((call) => call.executionClass !== "readonly" || call.executionKind !== "ordinary");
1536
+ return preparedDescriptors.length === 0 ? Effect.void : durability.prepareToolCalls(preparedDescriptors);
1537
+ })).pipe(Stream.drain);
1538
+ const stepServiceFor = (call) => durability === void 0 ? passthroughDurableStep() : makeDurableStepService(call.toolCallId, durability.step, hookServices);
1539
+ const subagentHook = options.subagent;
1540
+ const batchSubagentDurability = subagentHook === void 0 ? ephemeralSubagentDurability : makeSubagentDurabilityService(subagentHook, hookServices);
1541
+ const waitingByDeclaration = /* @__PURE__ */ new Map();
1542
+ const scheduling = options.scheduling ?? (yield* RunToolScheduling);
1543
+ const groups = [];
1544
+ let parallel = [];
1545
+ for (const call of executable) if (scheduling.toolRequiresSequential?.(call.name) === true) {
1546
+ if (parallel.length > 0) {
1547
+ groups.push(parallel);
1548
+ parallel = [];
1549
+ }
1550
+ groups.push([call]);
1551
+ } else parallel.push(call);
1552
+ if (parallel.length > 0) groups.push(parallel);
1553
+ const handlers = groups.reduce((stream, group) => {
1554
+ const channels = group.map((call) => withSemaphorePermit(semaphore, Stream.unwrap(Effect.gen(function* () {
1555
+ const subagentHost = yield* SubagentHost.forTool;
1556
+ const messagingHost = yield* MessagingHost.forTool;
1557
+ const source = {
1558
+ _tag: "tool",
1559
+ agentId: context.agentId,
1560
+ threadId: context.threadId,
1561
+ runId: context.runId,
1562
+ toolCallId: call.toolCallId
1563
+ };
1564
+ const broker = yield* makeToolBrokerService({
1565
+ context,
1566
+ turnId,
1567
+ outerToolCallId: call.toolCallId,
1568
+ turn,
1569
+ maxToolCalls: brokerAccounting.maxToolCalls,
1570
+ declaredToolCalls: brokerAccounting.declaredToolCalls,
1571
+ budget: options.budget,
1572
+ reservePolicyUsage: options.durability?.reservePolicyUsage,
1573
+ hookServices
1574
+ });
1575
+ return executePreparedToolCall(context, turnId, toolkit, call, trace, resultBounds, (waiting) => {
1576
+ waitingByDeclaration.set(call.declarationIndex, waiting);
1577
+ }).pipe(Stream.provideService(DurableStep, stepServiceFor(call)), Stream.provideService(SubagentHost, subagentHost(source)), Stream.provideService(MessagingHost, messagingHost(source)), Stream.provideService(ToolBroker, broker.service), Stream.provideService(CurrentToolCatalog, { entries: context.toolCatalog }), Stream.ensuring(Effect.sync(() => broker.close())));
1578
+ }))).channel);
1579
+ const next = Stream.fromChannel(Channel.mergeAll(Channel.fromIterable(channels), { concurrency }));
1580
+ return stream.pipe(Stream.concat(next));
1581
+ }, Stream.empty);
1582
+ const sinkQueue = yield* Queue.bounded(context.bufferLimits.maxSubagentEventsPerBatch);
1583
+ const batchSink = { emit: (payload) => ![
1584
+ "SubagentRequested",
1585
+ "SubagentStarted",
1586
+ "SubagentProgress",
1587
+ "SubagentCompleted",
1588
+ "SubagentFailed",
1589
+ "SubagentInterrupted",
1590
+ "SubagentJoined"
1591
+ ].includes(payload._tag) ? Effect.fail(new RunEventSinkClosedError({ message: "Unsupported Tool event payload" })) : Queue.offer(sinkQueue, payload).pipe(Effect.flatMap((accepted) => accepted ? Effect.sync(() => {
1592
+ if (context.liveChildren.has(payload.childRunId)) return;
1593
+ if ("usage" in payload && payload.usage !== void 0) context.childUsage.set(payload.childRunId, Effect.succeed(RunUsageReport.make({
1594
+ usage: payload.usage,
1595
+ delegatedUsage: payload.delegatedUsage ?? unknownRunTotals()
1596
+ })));
1597
+ else if (payload._tag === "SubagentStarted" && !context.childUsage.has(payload.childRunId)) context.childUsage.set(payload.childRunId, Effect.succeed(RunUsageReport.make({
1598
+ usage: unknownRunTotals(),
1599
+ delegatedUsage: unknownRunTotals()
1600
+ })));
1601
+ }) : Effect.fail(RunEventSinkClosedError.make({ message: `Subagent event ${payload._tag} was emitted after its Tool batch settled` })))) };
1602
+ const updateAcceptance = yield* AgentUpdateAcceptance;
1603
+ let updatesOpen = true;
1604
+ const updateEmitter = { emit: (request) => context.updatePermits.withPermit(Effect.gen(function* () {
1605
+ if (!updatesOpen) return yield* new UpdateError({ reason: "unavailable" });
1606
+ if (request.target.id !== context.agentId || request.target.updates !== context.definition.updates || context.definition.updates === void 0) return yield* new UpdateError({ reason: "identity" });
1607
+ const updateId = yield* Schema.decodeEffect(IdempotencyKey)(request.updateId).pipe(Effect.mapError(() => new UpdateError({ reason: "validation" })));
1608
+ const value = yield* Schema.decodeEffect(Schema.fromJsonString(Schema.Json))(JSON.stringify(request.value)).pipe(Effect.mapError(() => new UpdateError({ reason: "validation" })));
1609
+ yield* context.validateUpdate(value);
1610
+ const existing = context.updates.get(updateId);
1611
+ if (existing !== void 0) {
1612
+ if (!Schema.toEquivalence(Schema.Json)(existing.value, value)) return yield* new UpdateError({ reason: "conflict" });
1613
+ return existing;
1614
+ }
1615
+ const bytes = utf8ByteLength(JSON.stringify(value));
1616
+ const maxCount = options.updates?.maxCount ?? 32;
1617
+ const maxBytes = options.updates?.maxBytes ?? 16384;
1618
+ if (!Number.isSafeInteger(maxCount) || maxCount < 1 || !Number.isSafeInteger(maxBytes) || maxBytes < 1 || context.updates.size >= maxCount || context.updateBytes + bytes > maxBytes) return yield* new UpdateError({ reason: "capacity" });
1619
+ const snapshot = boundedCanonicalJsonSnapshot(value, bytes);
1620
+ if (snapshot === void 0) return yield* new UpdateError({ reason: "validation" });
1621
+ const accepted = yield* updateAcceptance.accept(Object.freeze(Update.make({
1622
+ schemaVersion: 1,
1623
+ agentId: context.agentId,
1624
+ threadId: context.threadId,
1625
+ runId: context.runId,
1626
+ updateId,
1627
+ sequence: context.updates.size + 1,
1628
+ value: snapshot.value
1629
+ })));
1630
+ const validated = yield* Schema.decodeEffect(Update)(accepted).pipe(Effect.mapError(() => new UpdateError({ reason: "validation" })));
1631
+ if (validated.agentId !== context.agentId || validated.threadId !== context.threadId || validated.runId !== context.runId || validated.updateId !== request.updateId || !Schema.toEquivalence(Schema.Json)(validated.value, value)) return yield* new UpdateError({ reason: "identity" });
1632
+ const update = Object.freeze(Update.make({
1633
+ ...validated,
1634
+ value: snapshot.value
1635
+ }));
1636
+ context.updates.set(request.updateId, update);
1637
+ context.updateBytes += bytes;
1638
+ if (!(yield* Queue.offer(sinkQueue, {
1639
+ _tag: "AgentUpdateEmitted",
1640
+ update
1641
+ }))) return yield* new UpdateError({ reason: "unavailable" });
1642
+ return update;
1643
+ })) };
1644
+ let settledCause;
1645
+ const settling = handlers.pipe(Stream.provideService(RunEventSink, batchSink), Stream.provideService(Emitter, updateEmitter), Stream.provideService(SubagentDurability, batchSubagentDurability), Stream.catchCause((cause) => {
1646
+ settledCause = cause;
1647
+ return Stream.empty;
1648
+ }), Stream.ensuring(Effect.sync(() => {
1649
+ updatesOpen = false;
1650
+ }).pipe(Effect.andThen(Queue.end(sinkQueue)))));
1651
+ const sinkEvents = Stream.fromQueue(sinkQueue).pipe(Stream.mapEffect((payload) => stampSubagentEvent(context, turnId, payload)));
1652
+ const settled = Stream.merge(settling, sinkEvents).pipe(Stream.concat(Stream.fromEffect(Effect.suspend(() => {
1653
+ if (settledCause !== void 0) return Effect.failCause(settledCause);
1654
+ const waiting = [...waitingByDeclaration.entries()].sort(([left], [right]) => left - right).map(([, signal]) => signal);
1655
+ const [first, ...rest] = waiting;
1656
+ if (first === void 0) return Effect.void;
1657
+ const child = (signal) => ({
1658
+ toolCallId: signal.toolCallId,
1659
+ childThreadId: signal.childThreadId,
1660
+ childSubmissionId: signal.childSubmissionId,
1661
+ childRunId: signal.childRunId
1662
+ });
1663
+ return Effect.fail(AgentChildPending.make({
1664
+ children: [child(first), ...rest.map(child)],
1665
+ message: `${waiting.length} durable delegation ${waiting.length === 1 ? "call is" : "calls are"} waiting on attached children; the Run suspended without settling`
1666
+ }));
1667
+ })).pipe(Stream.drain)));
1668
+ return approvalPreflight.pipe(Stream.concat(authorizationPreflight), Stream.concat(preparation), Stream.concat(settled));
1669
+ }));
1670
+ const schedulingConcurrency = Effect.fn("AgentRuntime.schedulingConcurrency")(function* (configured, explicit) {
1671
+ const override = (explicit ?? (yield* RunToolScheduling)).runOverride;
1672
+ if (override === void 0) return configured;
1673
+ if (override.mode === "sequential") return 1;
1674
+ if (!Number.isInteger(override.concurrency) || override.concurrency <= 0) return yield* AgentPolicyError.make({
1675
+ limit: "usage",
1676
+ message: "Run Tool concurrency override must be a positive integer"
1677
+ });
1678
+ return Math.min(configured, override.concurrency);
1679
+ });
1680
+ /**
1681
+ * One terminal outcome per declared Tool Call of the completed Turn, in
1682
+ * declaration order. Provider-executed results are read from the response
1683
+ * parts; application results from the settled batch.
1684
+ */
1685
+ const turnToolFailures = (trace) => {
1686
+ const outcomes = [];
1687
+ for (const [id, call] of trace.toolCalls) {
1688
+ if (call.providerExecuted) {
1689
+ for (const part of trace.parts) if (part.type === "tool-result" && part.id === id && part.preliminary !== true) {
1690
+ outcomes.push(part.isFailure);
1691
+ break;
1692
+ }
1693
+ continue;
1694
+ }
1695
+ const result = trace.applicationToolResults.find((candidate) => candidate?.id === id);
1696
+ if (result !== void 0 && result.budgetRejected !== true) outcomes.push(result.isFailure);
1697
+ }
1698
+ return outcomes;
1699
+ };
1700
+ /**
1701
+ * Fold the completed Turn's terminal Tool outcomes into the Run's
1702
+ * consecutive-failure counter in declaration order, then enforce the
1703
+ * repeated-failure Stop Policy before the next model request. A terminal
1704
+ * success resets the counter; a `repeatedFailureLimit` of `0` disables the
1705
+ * bound.
1706
+ */
1707
+ const applyRepeatedFailurePolicy = (context, trace, repeatedFailureLimit) => Effect.suspend(() => {
1708
+ for (const isFailure of turnToolFailures(trace)) context.consecutiveToolFailures = isFailure ? context.consecutiveToolFailures + 1 : 0;
1709
+ if (repeatedFailureLimit > 0 && context.consecutiveToolFailures >= repeatedFailureLimit) return Effect.fail(AgentPolicyError.make({
1710
+ limit: "repeated-failures",
1711
+ message: `Agent reached its ${repeatedFailureLimit} consecutive Tool Call failure limit`
1712
+ }));
1713
+ return Effect.void;
1714
+ });
1715
+ const inputsToPrompt = (inputs) => Effect.try({
1716
+ try: () => Prompt.fromMessages(inputs.flatMap((input) => Prompt.make(input).content)),
1717
+ catch: (cause) => AgentInputError.make({ message: `Unable to materialize queued Run input: ${errorMessage(cause)}` })
1718
+ });
1719
+ /** Validate live reference context before it reaches budgeting or provider I/O. */
1720
+ const transientInputToPrompt = (input) => Effect.try({
1721
+ try: () => Prompt.make(input),
1722
+ catch: (cause) => AgentInputError.make({ message: `Unable to materialize transient Run context: ${errorMessage(cause)}` })
1723
+ }).pipe(Effect.flatMap((prompt) => Schema.decodeEffect(Prompt.Prompt)({ content: prompt.content }).pipe(Effect.mapError((cause) => AgentInputError.make({ message: `Unable to materialize transient Run context: ${errorMessage(cause)}` })))));
1724
+ const advanceHistory = (context, history, options) => Effect.gen(function* () {
1725
+ context.history = history;
1726
+ if (options.onHistory !== void 0) yield* options.onHistory(history);
1727
+ });
1728
+ const drainInputs = (context, options) => Effect.gen(function* () {
1729
+ if (options.input === void 0) return [];
1730
+ const commands = yield* options.input.drain(options.commandDrainPolicy ?? "one");
1731
+ const steering = [];
1732
+ for (const command of commands) if (command.kind === "steering") steering.push(command.input);
1733
+ else context.pendingFollowUps.push(command.input);
1734
+ return steering;
1735
+ });
1736
+ const takeFollowUps = (context, policy) => {
1737
+ if (context.pendingFollowUps.length === 0) return [];
1738
+ if (policy === "one") {
1739
+ const input = context.pendingFollowUps.shift();
1740
+ return input === void 0 ? [] : [input];
1741
+ }
1742
+ return context.pendingFollowUps.splice(0, context.pendingFollowUps.length);
1743
+ };
1744
+ const appendInputs = (context, source, inputs, options) => Effect.gen(function* () {
1745
+ if (inputs.length === 0) return source;
1746
+ const additions = yield* inputsToPrompt(inputs);
1747
+ const history = Prompt.fromMessages([...source.content, ...additions.content]);
1748
+ yield* advanceHistory(context, history, options);
1749
+ return history;
1750
+ });
1751
+ /**
1752
+ * RUN-022: bound one application Tool result at the settle seam. The bounded
1753
+ * value is what official history, the settled record, and the success event
1754
+ * all carry, so every downstream surface agrees; a within-bounds result
1755
+ * passes through with its identity preserved.
1756
+ */
1757
+ const boundEncodedToolResult = (encodedResult, bounds) => {
1758
+ let text;
1759
+ try {
1760
+ text = JSON.stringify(encodedResult);
1761
+ } catch (cause) {
1762
+ return unserializableToolResult(cause);
1763
+ }
1764
+ if (text === void 0) return unserializableToolResult("the encoded result is not a JSON value");
1765
+ const bounded = applyToolResultBounds(text, bounds);
1766
+ try {
1767
+ return Schema.decodeSync(Schema.fromJsonString(Schema.Unknown))(bounded);
1768
+ } catch (cause) {
1769
+ return unserializableToolResult(cause);
1770
+ }
1771
+ };
1772
+ const RUN_STATUS_WARNING = " · WARNING: approaching limits — converge and deliver your final result now.";
1773
+ /** Fraction checks use `consumed * 5 >= limit * 4` so the 80% threshold stays integer-exact. */
1774
+ const nearingLimit = (consumed, limit) => consumed * 5 >= limit * 4;
1775
+ /**
1776
+ * RUN-024: render the derived run-status message appended to each outgoing
1777
+ * model request. The format is pinned here — tests target this function.
1778
+ */
1779
+ const formatRunStatus = (view) => {
1780
+ const researchBudget = view.tokenBudget === void 0 ? void 0 : Math.max(0, view.tokenBudget - (view.completionReserveTokens ?? 0));
1781
+ const remainingResearch = researchBudget === void 0 ? void 0 : Math.max(0, researchBudget - view.tokensConsumed);
1782
+ const warn = nearingLimit(view.turn, view.maxTurns) || nearingLimit(view.toolCallsUsed, view.maxToolCalls) || researchBudget !== void 0 && (nearingLimit(view.tokensConsumed, researchBudget) || view.lastInputTokens > 0 && (remainingResearch ?? 0) <= view.lastInputTokens) || nearingLimit(view.elapsedSeconds, view.maxDurationSeconds);
1783
+ const reserveStatus = view.tokenBudget === void 0 ? "" : ` · research-remaining ${remainingResearch} · completion-reserve ${view.completionReserveTokens ?? 0}`;
1784
+ return `<run-status>turn ${view.turn}/${view.maxTurns} · tool-calls ${view.toolCallsUsed}/${view.maxToolCalls} · tokens ${view.tokensConsumed}/${view.tokenBudget ?? "unbounded"}${reserveStatus} · last-context ${view.lastInputTokens} · elapsed ${view.elapsedSeconds}s/${view.maxDurationSeconds}s${warn ? RUN_STATUS_WARNING : ""}</run-status>`;
1785
+ };
1786
+ /**
1787
+ * The run-status message is derived per request and appended only to the
1788
+ * OUTGOING prompt: official history and durable commits never carry it, so it
1789
+ * can never accumulate or replay.
1790
+ */
1791
+ const outgoingModelPrompt = (policy, context, prepared, turn, declaredToolCalls) => Effect.gen(function* () {
1792
+ if (policy.runStatus !== "appended") return prepared;
1793
+ const now = yield* Clock.currentTimeMillis;
1794
+ const status = formatRunStatus({
1795
+ turn,
1796
+ maxTurns: policy.maxTurns,
1797
+ toolCallsUsed: declaredToolCalls + context.programmaticToolCalls,
1798
+ maxToolCalls: policy.maxToolCalls,
1799
+ tokensConsumed: context.inputTokens + context.outputTokens,
1800
+ tokenBudget: policy.tokenBudget,
1801
+ completionReserveTokens: policy.completionReserveTokens,
1802
+ lastInputTokens: context.lastInputTokens,
1803
+ elapsedSeconds: Math.max(0, Math.floor((now - context.startedAtMillis) / 1e3)),
1804
+ maxDurationSeconds: Math.floor(Duration.toMillis(policy.maxDuration) / 1e3)
1805
+ });
1806
+ return Prompt.fromMessages([...prepared.content, Prompt.makeMessage("user", { content: [Prompt.makePart("text", { text: status })] })]);
1807
+ });
1808
+ const ProviderUsage = Schema.Struct({
1809
+ inputTokens: Schema.Struct({
1810
+ uncached: Schema.optional(Schema.Natural),
1811
+ total: Schema.optional(Schema.Natural),
1812
+ cacheRead: Schema.optional(Schema.Natural),
1813
+ cacheWrite: Schema.optional(Schema.Natural)
1814
+ }),
1815
+ outputTokens: Schema.Struct({
1816
+ total: Schema.optional(Schema.Natural),
1817
+ text: Schema.optional(Schema.Natural),
1818
+ reasoning: Schema.optional(Schema.Natural)
1819
+ })
1820
+ });
1821
+ const invalidProviderUsage = () => ModelProtocolError.make({ message: "Model response usage fields and derived totals must be non-negative safe integers" });
1822
+ const decodeProviderUsageTotal = (value) => Schema.decodeEffect(Schema.Natural)(value).pipe(Effect.mapError(() => invalidProviderUsage()));
1823
+ const consumeUsage = (agent, context, usage, toolCallCount, turn, options, response = {}) => Effect.gen(function* () {
1824
+ if (usage === void 0) return yield* AgentPolicyError.make({
1825
+ limit: "usage",
1826
+ message: "A completed model response did not report usage"
1827
+ });
1828
+ const providerUsage = yield* Schema.decodeEffect(ProviderUsage)(usage).pipe(Effect.mapError(() => invalidProviderUsage()));
1829
+ const reportedUncached = providerUsage.inputTokens.uncached ?? 0;
1830
+ const cacheRead = providerUsage.inputTokens.cacheRead ?? 0;
1831
+ const cacheWrite = providerUsage.inputTokens.cacheWrite ?? 0;
1832
+ const reportedText = providerUsage.outputTokens.text ?? 0;
1833
+ const reasoning = providerUsage.outputTokens.reasoning ?? 0;
1834
+ const reportedInputTotal = providerUsage.inputTokens.total;
1835
+ const reportedInputWithoutWrite = yield* decodeProviderUsageTotal(reportedUncached + cacheRead);
1836
+ const disjointReportedUncached = reportedUncached - (reportedInputTotal !== void 0 && providerUsage.inputTokens.uncached !== void 0 && providerUsage.inputTokens.cacheWrite !== void 0 && cacheWrite <= reportedUncached && reportedInputWithoutWrite <= reportedInputTotal && cacheWrite > reportedInputTotal - reportedInputWithoutWrite ? cacheWrite : 0);
1837
+ const reportedInputComponents = yield* decodeProviderUsageTotal(disjointReportedUncached + cacheRead + cacheWrite);
1838
+ const allInputComponentsReported = providerUsage.inputTokens.uncached !== void 0 && providerUsage.inputTokens.cacheRead !== void 0 && providerUsage.inputTokens.cacheWrite !== void 0;
1839
+ if (reportedInputTotal !== void 0 && (reportedInputTotal < reportedInputComponents || allInputComponentsReported && reportedInputTotal !== reportedInputComponents)) return yield* invalidProviderUsage();
1840
+ const inputTokens = reportedInputTotal ?? reportedInputComponents;
1841
+ const reportedOutputComponents = yield* decodeProviderUsageTotal(reportedText + reasoning);
1842
+ const reportedOutputTotal = providerUsage.outputTokens.total;
1843
+ const allOutputComponentsReported = providerUsage.outputTokens.text !== void 0 && providerUsage.outputTokens.reasoning !== void 0;
1844
+ if (reportedOutputTotal !== void 0 && (reportedOutputTotal < reportedOutputComponents || allOutputComponentsReported && reportedOutputTotal !== reportedOutputComponents)) return yield* invalidProviderUsage();
1845
+ const outputTokens = reportedOutputTotal ?? reportedOutputComponents;
1846
+ const inputRemainder = inputTokens - reportedInputComponents;
1847
+ const outputRemainder = outputTokens - reportedOutputComponents;
1848
+ const uncached = disjointReportedUncached + (providerUsage.inputTokens.uncached === void 0 ? inputRemainder : 0);
1849
+ const normalizedCacheRead = cacheRead + (providerUsage.inputTokens.uncached !== void 0 && providerUsage.inputTokens.cacheRead === void 0 ? inputRemainder : 0);
1850
+ const normalizedCacheWrite = cacheWrite + (providerUsage.inputTokens.uncached !== void 0 && providerUsage.inputTokens.cacheRead !== void 0 && providerUsage.inputTokens.cacheWrite === void 0 ? inputRemainder : 0);
1851
+ const text = reportedText + (providerUsage.outputTokens.text === void 0 ? outputRemainder : 0);
1852
+ const normalizedReasoning = reasoning + (providerUsage.outputTokens.text !== void 0 && providerUsage.outputTokens.reasoning === void 0 ? outputRemainder : 0);
1853
+ const totalTokens = yield* decodeProviderUsageTotal(inputTokens + outputTokens);
1854
+ const provider = yield* Model.ProviderName;
1855
+ const model = yield* Model.ModelName;
1856
+ const estimate = options.estimateCostMicrousd === void 0 ? 0 : yield* options.estimateCostMicrousd(usage, {
1857
+ provider,
1858
+ model,
1859
+ usage,
1860
+ ...response
1861
+ });
1862
+ const costMicrousd = typeof estimate === "number" ? estimate : estimate.costMicrousd;
1863
+ if (!Number.isSafeInteger(costMicrousd) || costMicrousd < 0) return yield* AgentPolicyError.make({
1864
+ limit: "cost",
1865
+ message: "Model cost estimation must produce a non-negative integer number of microdollars"
1866
+ });
1867
+ const serviceTier = typeof estimate === "number" ? void 0 : estimate.serviceTier;
1868
+ const pricingVersion = typeof estimate === "number" ? void 0 : estimate.pricingVersion;
1869
+ const pricingStatus = options.estimateCostMicrousd === void 0 ? "unknown" : typeof estimate === "number" ? "estimated" : estimate.pricingStatus ?? "estimated";
1870
+ const validPricingIdentity = (value) => value === void 0 || value.length > 0 && value.length <= 256;
1871
+ if (!validPricingIdentity(serviceTier) || !validPricingIdentity(pricingVersion)) return yield* AgentPolicyError.make({
1872
+ limit: "cost",
1873
+ message: "Model cost estimation returned an invalid service tier or pricing version"
1874
+ });
1875
+ const modelUsage = ModelCallUsage.make({
1876
+ provider,
1877
+ model,
1878
+ ...response.response === void 0 ? {} : { response: ModelResponseIdentity.make(response.response) },
1879
+ purpose: response.purpose ?? "turn",
1880
+ usageStatus: Object.values(providerUsage.inputTokens).every((value) => value === void 0) && Object.values(providerUsage.outputTokens).every((value) => value === void 0) ? "unknown" : [
1881
+ providerUsage.inputTokens.uncached,
1882
+ providerUsage.inputTokens.cacheRead,
1883
+ providerUsage.inputTokens.cacheWrite,
1884
+ providerUsage.outputTokens.text,
1885
+ providerUsage.outputTokens.reasoning
1886
+ ].every((value) => value !== void 0) ? "complete" : "partial",
1887
+ pricingStatus,
1888
+ ...serviceTier === void 0 ? {} : { serviceTier },
1889
+ ...pricingVersion === void 0 ? {} : { pricingVersion },
1890
+ inputTokens: InputTokenUsage.make({
1891
+ total: inputTokens,
1892
+ uncached,
1893
+ cacheRead: normalizedCacheRead,
1894
+ cacheWrite: normalizedCacheWrite
1895
+ }),
1896
+ outputTokens: OutputTokenUsage.make({
1897
+ total: outputTokens,
1898
+ text,
1899
+ reasoning: normalizedReasoning
1900
+ }),
1901
+ costMicrousd
1902
+ });
1903
+ const modelCalls = yield* decodeProviderUsageTotal(context.modelCalls + 1);
1904
+ const cumulativeInputTokens = yield* decodeProviderUsageTotal(context.inputTokens + inputTokens);
1905
+ const cumulativeOutputTokens = yield* decodeProviderUsageTotal(context.outputTokens + outputTokens);
1906
+ const cumulativeCostMicrousd = context.costMicrousd + costMicrousd;
1907
+ if (!Number.isSafeInteger(cumulativeCostMicrousd)) return yield* AgentPolicyError.make({
1908
+ limit: "cost",
1909
+ message: "Cumulative model cost exceeds safe-integer accounting capacity"
1910
+ });
1911
+ const firstObserved = context.modelCalls === 0 && context.unobservedModelCalls === 0;
1912
+ const combineStatus = (prior, next) => firstObserved && prior === "complete" ? next : prior === next ? prior : "partial";
1913
+ context.usageStatus = combineStatus(context.usageStatus, modelUsage.usageStatus ?? "unknown");
1914
+ context.pricingStatus = combineStatus(context.pricingStatus, pricingStatus === "estimated" ? "complete" : "unknown");
1915
+ context.modelCalls = modelCalls;
1916
+ context.inputTokens = cumulativeInputTokens;
1917
+ context.outputTokens = cumulativeOutputTokens;
1918
+ context.lastInputTokens = inputTokens;
1919
+ context.lastOutputTokens = outputTokens;
1920
+ context.costMicrousd = cumulativeCostMicrousd;
1921
+ context.lastCostMicrousd = costMicrousd;
1922
+ if (options.durability !== void 0) yield* options.durability.noteTurnUsage({
1923
+ turn,
1924
+ usage: modelUsage
1925
+ });
1926
+ const policy = agent.definition.policy;
1927
+ const consumedTokens = context.inputTokens + context.outputTokens;
1928
+ const tokenBudget = policy.tokenBudget;
1929
+ let breach;
1930
+ if (!context.finalizing && !context.tokenExhausted && tokenBudget !== void 0 && consumedTokens > tokenBudget) {
1931
+ breach = AgentPolicyError.make({
1932
+ limit: "tokens",
1933
+ message: `Agent exceeded its ${tokenBudget} token budget`
1934
+ });
1935
+ if (policy.onExhaustion === "fail") return yield* breach;
1936
+ context.tokenExhausted = true;
1937
+ context.exhaustedDimension ??= "tokens";
1938
+ }
1939
+ const costBudget = policy.costBudgetMicrousd;
1940
+ if (costBudget !== void 0) {
1941
+ if (options.estimateCostMicrousd === void 0) return yield* AgentPolicyError.make({
1942
+ limit: "cost",
1943
+ message: "Agent cost budget requires a model cost estimator"
1944
+ });
1945
+ if (pricingStatus === "unknown") return yield* AgentPolicyError.make({
1946
+ limit: "cost",
1947
+ message: "Agent cost budget requires a known model cost estimate"
1948
+ });
1949
+ if (context.costMicrousd > costBudget) return yield* AgentPolicyError.make({
1950
+ limit: "cost",
1951
+ message: `Agent exceeded its ${costBudget} microdollar cost budget`
1952
+ });
1953
+ }
1954
+ if (options.budget !== void 0) {
1955
+ const delta = {
1956
+ modelCalls: 1,
1957
+ inputTokens,
1958
+ outputTokens,
1959
+ totalTokens,
1960
+ toolCalls: toolCallCount,
1961
+ costMicrousd,
1962
+ usage,
1963
+ modelUsage
1964
+ };
1965
+ yield* options.budget.consume(delta);
1966
+ }
1967
+ const warnings = [];
1968
+ if (tokenBudget !== void 0 && !context.warnedLimits.has("tokens") && nearingLimit(consumedTokens, tokenBudget)) {
1969
+ context.warnedLimits.add("tokens");
1970
+ warnings.push(BudgetWarning.make({
1971
+ ...yield* eventBase(context),
1972
+ limit: "tokens",
1973
+ consumed: consumedTokens,
1974
+ limitValue: tokenBudget
1975
+ }));
1976
+ }
1977
+ return {
1978
+ breach,
1979
+ warnings,
1980
+ modelUsage
1981
+ };
1982
+ });
1983
+ const eventBaseFor = Effect.fnUntraced(function* (context, terminal) {
1984
+ const ceiling = terminal ? context.bufferLimits.maxRunEvents : context.bufferLimits.maxRunEvents - 1;
1985
+ if (context.sequence >= ceiling) return yield* ModelProtocolError.make({ message: `Run exceeded the ${context.bufferLimits.maxRunEvents}-event buffer limit` });
1986
+ const timestamp = DateTime.makeUnsafe(yield* Clock.currentTimeMillis);
1987
+ const sequence = context.sequence;
1988
+ context.sequence += 1;
1989
+ return {
1990
+ eventVersion: 1,
1991
+ runId: context.runId,
1992
+ threadId: context.threadId,
1993
+ agentId: context.agentId,
1994
+ sequence,
1995
+ timestamp
1996
+ };
1997
+ });
1998
+ const eventBase = (context) => eventBaseFor(context, false);
1999
+ /** The ordinary event budget always reserves one slot for this typed terminal projection. */
2000
+ const terminalEventBase = (context) => eventBaseFor(context, true);
2001
+ const toolProgressLimitError = (context) => ModelProtocolError.make({ message: `Run exceeded the ${context.bufferLimits.maxToolProgressBytes}-byte Tool progress limit or received invalid progress JSON` });
2002
+ const admitToolProgress = (context, snapshot) => Effect.suspend(() => {
2003
+ if (snapshot.bytes > context.bufferLimits.maxToolProgressBytes - context.toolProgressBytes) return Effect.fail(toolProgressLimitError(context));
2004
+ context.toolProgressBytes += snapshot.bytes;
2005
+ return Effect.succeed(snapshot.value);
2006
+ });
2007
+ const ownApplicationToolProgress = (context, result) => Effect.suspend(() => {
2008
+ const snapshot = boundedCanonicalJsonSnapshot(result, context.bufferLimits.maxToolProgressBytes - context.toolProgressBytes);
2009
+ return snapshot === void 0 ? Effect.fail(toolProgressLimitError(context)) : admitToolProgress(context, snapshot);
2010
+ });
2011
+ const snapshotStagedProviderEvent = (trace, payload) => Effect.suspend(() => {
2012
+ if (trace.providerResultPayloads.length + (trace.turnCompletion === void 0 ? 0 : 1) >= MAX_STAGED_PROVIDER_EVENTS) return Effect.fail(ModelProtocolError.make({ message: `Model response exceeded the ${MAX_STAGED_PROVIDER_EVENTS}-event staged provider event limit` }));
2013
+ const snapshot = boundedJsonSnapshot(payload, MAX_STAGED_PROVIDER_BYTES - trace.providerStagedPayloadBytes);
2014
+ if (snapshot === void 0) return Effect.fail(ModelProtocolError.make({ message: `Model response exceeded the ${MAX_STAGED_PROVIDER_BYTES}-byte staged provider event limit` }));
2015
+ return Effect.succeed(snapshot);
2016
+ });
2017
+ const stageProviderResultPayload = (trace, payload) => Effect.gen(function* () {
2018
+ const snapshot = yield* snapshotStagedProviderEvent(trace, payload);
2019
+ const snapshotObject = snapshot.value;
2020
+ if (snapshotObject === null || typeof snapshotObject !== "object" || Array.isArray(snapshotObject) || Object.getPrototypeOf(snapshotObject) !== null) return yield* ModelProtocolError.make({ message: "Provider Tool result could not be normalized as JSON" });
2021
+ const resultDescriptor = Object.getOwnPropertyDescriptor(snapshotObject, "result");
2022
+ const normalizedResult = resultDescriptor !== void 0 && "value" in resultDescriptor ? Schema.decodeUnknownOption(Schema.Json)(resultDescriptor.value) : Option.none();
2023
+ if (payload._tag !== "ToolCallFailed" && Option.isNone(normalizedResult)) return yield* ModelProtocolError.make({ message: "Provider Tool result could not be normalized as JSON" });
2024
+ const normalized = payload._tag === "ToolCallFailed" ? Object.freeze({ ...payload }) : Object.freeze({
2025
+ ...payload,
2026
+ result: Option.getOrThrow(normalizedResult)
2027
+ });
2028
+ trace.providerResultPayloads.push(normalized);
2029
+ trace.providerStagedPayloadBytes += snapshot.bytes;
2030
+ });
2031
+ const ProviderToolResultSnapshot = Schema.Struct({
2032
+ result: Schema.Json,
2033
+ metadata: Schema.Record(Schema.String, Schema.Json)
2034
+ });
2035
+ const snapshotProviderToolResultPart = Effect.fnUntraced(function* (trace, part) {
2036
+ const snapshot = boundedJsonSnapshot({
2037
+ result: part.encodedResult,
2038
+ metadata: part.metadata
2039
+ }, MAX_STAGED_PROVIDER_BYTES - trace.providerStagedPayloadBytes);
2040
+ if (snapshot === void 0) return yield* ModelProtocolError.make({ message: `Model response exceeded the ${MAX_STAGED_PROVIDER_BYTES}-byte staged provider event limit` });
2041
+ const normalized = yield* Schema.decodeUnknownEffect(ProviderToolResultSnapshot)(snapshot.value).pipe(Effect.mapError(() => ModelProtocolError.make({ message: "Provider Tool result could not be normalized as JSON" })));
2042
+ trace.providerStagedPayloadBytes += snapshot.bytes;
2043
+ return normalized;
2044
+ });
2045
+ const stampProviderResultEvent = (context, turnId, payload) => Effect.gen(function* () {
2046
+ if (payload._tag === "ToolProgress") {
2047
+ const text = yield* Schema.encodeEffect(Schema.fromJsonString(Schema.Json))(payload.result).pipe(Effect.mapError(() => toolProgressLimitError(context)));
2048
+ yield* admitToolProgress(context, {
2049
+ value: payload.result,
2050
+ bytes: utf8ByteLength(text)
2051
+ });
2052
+ }
2053
+ const base = yield* eventBase(context);
2054
+ switch (payload._tag) {
2055
+ case "ToolProgress": return ToolProgress.make({
2056
+ ...base,
2057
+ turnId,
2058
+ ...payload
2059
+ });
2060
+ case "ToolCallSucceeded": return ToolCallSucceeded.make({
2061
+ ...base,
2062
+ turnId,
2063
+ ...payload
2064
+ });
2065
+ case "ToolCallFailed": return ToolCallFailed.make({
2066
+ ...base,
2067
+ turnId,
2068
+ ...payload,
2069
+ failureHandling: "returned-to-model"
2070
+ });
2071
+ }
2072
+ });
2073
+ /**
2074
+ * RUN-026: deterministic estimate of the NEXT model call's live context.
2075
+ * Anchored on the last provider-reported call when the view has only grown
2076
+ * since then; a fresh Run or a just-compacted view falls back to the full
2077
+ * chars/4 estimate.
2078
+ */
2079
+ const estimateContextTokens = Effect.fn("AgentRuntime.estimateContextTokens")(function* (messages, messageTokenEstimator) {
2080
+ const compactor = yield* ContextCompactor;
2081
+ const estimate = messageTokenEstimator === void 0 ? Option.some(compactor.estimate(messages)) : evaluateMessageTokenEstimates(messageTokenEstimator, (estimate) => estimatePromptTokens(messages, estimate));
2082
+ if (Option.isNone(estimate)) return yield* CompactionError.make({ message: "Message token estimator returned an invalid token count" });
2083
+ return yield* Schema.decodeEffect(Schema.Natural)(estimate.value).pipe(Effect.mapError((cause) => CompactionError.make({
2084
+ message: "Compactor returned an invalid token estimate",
2085
+ cause
2086
+ })));
2087
+ });
2088
+ const nextContextEstimate = Effect.fn("AgentRuntime.nextContextEstimate")(function* (context, view) {
2089
+ const state = context.compaction;
2090
+ if (context.lastInputTokens > 0 && state.lastViewLength >= 0 && state.lastViewLength <= view.length) return context.lastInputTokens + context.lastOutputTokens + (yield* estimateContextTokens(view.slice(state.lastViewLength)));
2091
+ return yield* estimateContextTokens(view);
2092
+ });
2093
+ const snapshotCompactionMessages = Effect.fnUntraced(function* (messages) {
2094
+ return yield* Effect.try({
2095
+ try: () => messages.map((message) => Schema.decodeUnknownSync(Schema.Json)(JSON.parse(JSON.stringify(Schema.encodeSync(Prompt.Message)(message))))),
2096
+ catch: (cause) => CompactionError.make({
2097
+ message: "Could not snapshot prepared compaction history",
2098
+ cause
2099
+ })
2100
+ });
2101
+ });
2102
+ /** Text a provider overflow classification matches against (message + reason). */
2103
+ const overflowText = (error) => `${error.message} ${error.reason.message}`;
2104
+ /**
2105
+ * Consume the installed strategy under engine-owned bounds. Validate each decision, commit it,
2106
+ * then update the disposable view. Summary model calls retain the Run's response-buffer and
2107
+ * budget guards; default summaries also obey the captured Model's input allowance. Pricing
2108
+ * reads the selected Model's identity inside the same provision scope.
2109
+ */
2110
+ const compactContext = (agent, context, source, turn, options, resolvedModelInputLimit, messageTokenEstimator, targetTokens, trigger, modelCallAllowed = true, requested) => Effect.gen(function* () {
2111
+ const state = context.compaction;
2112
+ const events = [];
2113
+ const messages = source.content;
2114
+ const allowance = context.compactionTurn;
2115
+ const preparedSource = context.preparedCompactionSource;
2116
+ const preparedSnapshot = preparedSource === void 0 ? void 0 : yield* snapshotCompactionMessages(messages);
2117
+ if (preparedSource !== void 0 && preparedSnapshot !== void 0) {
2118
+ let start = -1;
2119
+ let end = 0;
2120
+ let mapped = true;
2121
+ const positions = [];
2122
+ const originalPositions = preparedSource.protectedReferences.map((message) => messages.indexOf(message));
2123
+ const originalMapping = preparedSource.protectedReferences.every((message, position) => {
2124
+ const index = originalPositions[position];
2125
+ return index !== void 0 && index >= 0 && index > (originalPositions[position - 1] ?? -1) && messages.lastIndexOf(message) === index && Equal.equals(preparedSnapshot[index], preparedSource.protectedMessages[position]);
2126
+ });
2127
+ for (let position = 0; !originalMapping && position < preparedSource.protectedMessages.length; position += 1) {
2128
+ const protectedMessage = preparedSource.protectedMessages[position];
2129
+ const index = preparedSnapshot.findIndex((message, index) => index >= end && Equal.equals(message, protectedMessage));
2130
+ if (index < 0) {
2131
+ mapped = false;
2132
+ break;
2133
+ }
2134
+ if (start < 0) start = index;
2135
+ end = index + 1;
2136
+ positions.push(index);
2137
+ }
2138
+ let reverseEnd = preparedSnapshot.length;
2139
+ for (let position = preparedSource.protectedMessages.length - 1; !originalMapping && mapped && position >= 0; position -= 1) {
2140
+ const protectedMessage = preparedSource.protectedMessages[position];
2141
+ const index = preparedSnapshot.findLastIndex((message, index) => index < reverseEnd && Equal.equals(message, protectedMessage));
2142
+ if (index !== positions[position]) mapped = false;
2143
+ reverseEnd = index;
2144
+ }
2145
+ if (originalMapping) {
2146
+ mapped = true;
2147
+ start = originalPositions[0] ?? -1;
2148
+ end = (originalPositions.at(-1) ?? -1) + 1;
2149
+ }
2150
+ if (!mapped) return yield* CompactionError.make({ message: "Prepared context cannot map the protected instructions and input for compaction" });
2151
+ state.protectedStart = mapped ? start : -1;
2152
+ state.protectedEnd = mapped ? end : -1;
2153
+ state.protectSystemMessages = true;
2154
+ }
2155
+ const resolvedRequest = requested === void 0 ? void 0 : {
2156
+ ...requested,
2157
+ through: requested.through ?? Math.max(0, state.protectedStart)
2158
+ };
2159
+ if (requested !== void 0 && requested.through === void 0 && resolvedRequest !== void 0 && (resolvedRequest.through <= (state.replacement?.through ?? 0) || collectCoveredMessages(messages, state, resolvedRequest.through).length === 0)) return { events };
2160
+ if (allowance.turn !== turn) {
2161
+ allowance.turn = turn;
2162
+ allowance.summaryCalls = 0;
2163
+ allowance.applied.clear();
2164
+ }
2165
+ if (allowance.applied.has("summarize") || allowance.applied.has("rollover")) return yield* CompactionError.make({ message: "Compaction already replaced this Turn's context" });
2166
+ const before = yield* estimateContextTokens(buildCompactedView(messages, state), messageTokenEstimator);
2167
+ const summarize = (summarizerPrompt, model) => {
2168
+ const generate = Effect.gen(function* () {
2169
+ if (allowance.summaryCalls++ > 0 || !modelCallAllowed) return yield* CompactionError.make({ message: "Compaction exceeded its summary-call allowance" });
2170
+ if (model === void 0 && resolvedModelInputLimit !== void 0 && (yield* estimateContextTokens(summarizerPrompt.content, messageTokenEstimator)) > resolvedModelInputLimit) return yield* CompactionError.make({ message: "Compaction summary request exceeds the resolved model input limit" });
2171
+ const pieces = [];
2172
+ const responseUsage = {
2173
+ responsePartCount: 0,
2174
+ responsePartBytes: 0
2175
+ };
2176
+ let summaryUsage;
2177
+ let summaryResponse;
2178
+ let summaryFinishMetadata;
2179
+ let summaryFinished = false;
2180
+ let summaryFailure;
2181
+ const textParts = /* @__PURE__ */ new Map();
2182
+ const reasoningParts = /* @__PURE__ */ new Map();
2183
+ const summaryExit = yield* guardBudgetStream(LanguageModel.streamText({ prompt: summarizerPrompt }), options.budget).pipe(Stream.runForEach((part) => Effect.gen(function* () {
2184
+ const owned = yield* ownModelResponsePart(part, Toolkit.empty, responseUsage, context.bufferLimits);
2185
+ yield* consumeModelResponsePart(responseUsage, owned.retainedBytes, context.bufferLimits);
2186
+ const ownedPart = owned.ownedPart;
2187
+ if (ownedPart.type === "text-delta") pieces.push(ownedPart.delta);
2188
+ else if (ownedPart.type === "finish") {
2189
+ if (summaryUsage === void 0) {
2190
+ summaryUsage = ownedPart.usage;
2191
+ summaryFinishMetadata = ownedPart.metadata;
2192
+ }
2193
+ } else if (ownedPart.type === "response-metadata") summaryResponse = yield* responseIdentity(ownedPart, summaryResponse);
2194
+ yield* Effect.gen(function* () {
2195
+ if (summaryFinished) return yield* ModelProtocolError.make({ message: "Compaction response emitted content after its finish part" });
2196
+ switch (ownedPart.type) {
2197
+ case "text-start": return yield* startPart(textParts, ownedPart.id, "compaction text");
2198
+ case "text-delta": return yield* continuePart(textParts, ownedPart.id, "compaction text delta");
2199
+ case "text-end": return yield* endPart(textParts, ownedPart.id, "compaction text");
2200
+ case "reasoning-start": return yield* startPart(reasoningParts, ownedPart.id, "compaction reasoning");
2201
+ case "reasoning-delta": return yield* continuePart(reasoningParts, ownedPart.id, "compaction reasoning delta");
2202
+ case "reasoning-end": return yield* endPart(reasoningParts, ownedPart.id, "compaction reasoning");
2203
+ case "finish":
2204
+ summaryFinished = true;
2205
+ if (ownedPart.reason !== "stop" || [...textParts.values(), ...reasoningParts.values()].includes("open")) return yield* ModelProtocolError.make({ message: "Compaction response did not finish with complete text and a stop reason" });
2206
+ return;
2207
+ case "tool-params-start":
2208
+ case "tool-params-delta":
2209
+ case "tool-params-end":
2210
+ case "tool-approval-request":
2211
+ case "error": return yield* ModelProtocolError.make({ message: `Compaction response contained an unusable ${ownedPart.type} part` });
2212
+ case "file":
2213
+ case "response-metadata":
2214
+ case "source": return;
2215
+ }
2216
+ }).pipe(Effect.catch((error) => Effect.sync(() => {
2217
+ summaryFailure ??= error;
2218
+ })));
2219
+ })), Effect.exit);
2220
+ if (summaryUsage === void 0) {
2221
+ yield* noteIncompleteUsage(context, turn);
2222
+ if (Exit.isFailure(summaryExit)) return yield* Effect.failCause(summaryExit.cause);
2223
+ if (!summaryFinished) return yield* ModelProtocolError.make({ message: "Compaction response ended without a finish part" });
2224
+ }
2225
+ const wasFinalizing = context.finalizing;
2226
+ const priorSummaryModelCalls = context.modelCalls;
2227
+ context.finalizing = true;
2228
+ const consumedExit = yield* consumeUsage(agent, context, summaryUsage, 0, turn, options, {
2229
+ response: summaryResponse,
2230
+ finishMetadata: summaryFinishMetadata,
2231
+ purpose: "summary"
2232
+ }).pipe(Effect.tapCause(() => summaryUsage !== void 0 && context.modelCalls === priorSummaryModelCalls ? noteIncompleteUsage(context, turn) : Effect.void), Effect.ensuring(Effect.sync(() => {
2233
+ context.finalizing = wasFinalizing;
2234
+ })), Effect.exit);
2235
+ if (Exit.isFailure(summaryExit)) return yield* Effect.failCause(summaryExit.cause);
2236
+ if (Exit.isFailure(consumedExit)) return yield* Effect.failCause(consumedExit.cause);
2237
+ events.push(...consumedExit.value.warnings);
2238
+ if (!summaryFinished) return yield* ModelProtocolError.make({ message: "Compaction response ended without a finish part" });
2239
+ const summary = pieces.join("").trim();
2240
+ if (summaryFailure !== void 0) return yield* summaryFailure;
2241
+ if (summary.length === 0) return yield* ModelProtocolError.make({ message: "Compaction response requires non-whitespace text and a valid finish part" });
2242
+ return summary;
2243
+ });
2244
+ return model === void 0 ? generate : Effect.provide(generate, model);
2245
+ };
2246
+ const applied = allowance.applied;
2247
+ yield* (yield* ContextCompactor).compact({
2248
+ source,
2249
+ state: Object.freeze({
2250
+ ...state,
2251
+ replacement: state.replacement === void 0 ? void 0 : Object.freeze({ ...state.replacement })
2252
+ }),
2253
+ policy: agent.definition.policy.compaction,
2254
+ targetTokens,
2255
+ threadId: context.threadId,
2256
+ runId: context.runId,
2257
+ turn,
2258
+ trigger,
2259
+ modelCallAllowed,
2260
+ ...messageTokenEstimator === void 0 ? {} : { estimateMessageTokens: messageTokenEstimator },
2261
+ ...resolvedRequest === void 0 ? {} : { requested: resolvedRequest },
2262
+ summarize
2263
+ }).pipe(Stream.runForEach((candidate) => Effect.gen(function* () {
2264
+ const decision = yield* Schema.decodeEffect(CompactionDecision)(candidate).pipe(Effect.mapError((cause) => CompactionError.make({
2265
+ message: "Invalid compaction decision",
2266
+ cause
2267
+ })));
2268
+ if (applied.has(decision.kind) || applied.has("summarize") || applied.has("rollover")) return yield* CompactionError.make({ message: "Compaction exceeded its decision allowance" });
2269
+ const next = {
2270
+ ...state,
2271
+ lastViewLength: -1
2272
+ };
2273
+ if (resolvedRequest !== void 0 && (decision.kind !== "rollover" || decision.through !== resolvedRequest.through)) return yield* CompactionError.make({ message: "Requested rollover must cover exactly its selected source boundary" });
2274
+ if (decision.kind === "rollover") {
2275
+ if (decision.through <= (state.replacement?.through ?? 0) || decision.through > messages.length || messages[decision.through]?.role === "tool" || collectCoveredMessages(messages, state, decision.through).length === 0) return yield* CompactionError.make({ message: "Rollover must advance coverage without splitting Tool pairs or discarding protected input" });
2276
+ next.replacement = {
2277
+ kind: "rollover",
2278
+ through: decision.through,
2279
+ windowId: contextWindowId(context.runId, turn),
2280
+ ...decision.handoff === void 0 ? {} : { handoff: decision.handoff }
2281
+ };
2282
+ } else if (decision.kind === "summarize") {
2283
+ if (utf8ByteLength(decision.summary) > context.bufferLimits.maxModelResponseBytes) return yield* CompactionError.make({ message: "Compaction summary exceeded the response-buffer limit" });
2284
+ if (decision.through <= (state.replacement?.through ?? 0) || decision.through >= messages.length || messages[decision.through]?.role === "tool" || collectCoveredMessages(messages, state, decision.through).length === 0) return yield* CompactionError.make({ message: "Compaction must advance coverage without splitting Tool pairs or removing the recent tail" });
2285
+ next.replacement = {
2286
+ kind: "summarize",
2287
+ through: decision.through,
2288
+ summary: decision.summary
2289
+ };
2290
+ } else {
2291
+ const newestTool = messages.findLastIndex((message) => message.role === "tool");
2292
+ if (decision.through <= state.clearedThrough || decision.through > newestTool) return yield* CompactionError.make({ message: "Compaction must advance pruning while retaining the newest Tool result" });
2293
+ next.clearedThrough = decision.through;
2294
+ }
2295
+ const after = yield* estimateContextTokens(buildCompactedView(messages, next), messageTokenEstimator);
2296
+ if (decision.kind === "rollover" && trigger !== "requested" && after >= before) return yield* CompactionError.make({ message: "Automatic rollover did not reduce context" });
2297
+ const commit = {
2298
+ turn,
2299
+ source,
2300
+ through: decision.through,
2301
+ kind: decision.kind,
2302
+ ...decision.kind === "summarize" ? { summary: decision.summary } : {},
2303
+ ...decision.kind === "rollover" && decision.handoff !== void 0 ? { handoff: decision.handoff } : {},
2304
+ tokensBeforeEstimate: before,
2305
+ tokensAfterEstimate: after
2306
+ };
2307
+ if (options.durability !== void 0) yield* options.durability.commitCompaction(commit);
2308
+ Object.assign(state, next);
2309
+ if (next.replacement?.kind === "rollover") context.windowId = next.replacement.windowId;
2310
+ if (preparedSource !== void 0 && preparedSnapshot !== void 0) preparedSource.prefix = preparedSnapshot.slice(0, Math.max(next.clearedThrough, next.replacement?.through ?? 0));
2311
+ applied.add(decision.kind);
2312
+ events.push(CompactionPerformed.make({
2313
+ ...yield* eventBase(context),
2314
+ turn,
2315
+ kind: decision.kind,
2316
+ tokensBeforeEstimate: before,
2317
+ tokensAfterEstimate: after
2318
+ }));
2319
+ })));
2320
+ if (requested !== void 0 && !applied.has("rollover")) return yield* CompactionError.make({ message: "Compaction strategy did not honor the requested rollover" });
2321
+ return { events };
2322
+ });
2323
+ const decodeInput = Effect.fn("AgentRuntime.decodeInput")((agent, input) => Schema.decodeUnknownEffect(agent.definition.input)(input).pipe(Effect.mapError((cause) => AgentInputError.make({ message: cause.message }))));
2324
+ const evaluateInstructions = Effect.fn("AgentRuntime.evaluateInstructions")((instructions, input) => Effect.suspend(() => {
2325
+ const result = typeof instructions === "function" ? instructions(input) : instructions;
2326
+ return Effect.isEffect(result) ? result : Effect.succeed(result);
2327
+ }));
2328
+ const encodeInput = Effect.fn("AgentRuntime.encodeInput")((agent, input) => Schema.encodeEffect(agent.definition.input)(input).pipe(Effect.mapError((cause) => AgentInputError.make({ message: `Unable to encode Agent input: ${cause.message}` }))));
2329
+ const renderInputPromptEffect = Effect.fn("AgentRuntime.renderInputPrompt")((inputPrompt, decodedInput, encodedInput) => inputPrompt === void 0 ? Effect.try({
2330
+ try: () => {
2331
+ const encoded = JSON.stringify(encodedInput);
2332
+ if (encoded === void 0) throw new Error("Agent input cannot be represented as JSON");
2333
+ return encoded;
2334
+ },
2335
+ catch: (cause) => AgentInputError.make({ message: `Unable to materialize Agent input: ${errorMessage(cause)}` })
2336
+ }) : Effect.suspend(() => {
2337
+ const result = inputPrompt(decodedInput);
2338
+ return Effect.isEffect(result) ? result : Effect.succeed(result);
2339
+ }));
2340
+ function renderInputPrompt(inputPrompt, decodedInput, encodedInput) {
2341
+ return renderInputPromptEffect(inputPrompt, decodedInput, encodedInput);
2342
+ }
2343
+ const makeInitialPrompt = Effect.fn("AgentRuntime.makeInitialPrompt")((instructions, inputPrompt, history) => Effect.try({
2344
+ try: () => {
2345
+ const instructionPrompt = typeof instructions === "string" ? Prompt.fromMessages([Prompt.makeMessage("system", { content: instructions })]) : Prompt.make(instructions);
2346
+ return Prompt.fromMessages([
2347
+ ...history.content,
2348
+ ...instructionPrompt.content,
2349
+ ...Prompt.make(inputPrompt).content
2350
+ ]);
2351
+ },
2352
+ catch: (cause) => AgentInputError.make({ message: `Unable to materialize Agent input: ${errorMessage(cause)}` })
2353
+ }));
2354
+ const decodeToolCallId = Effect.fn((id) => Schema.decodeEffect(ToolCallId)(id).pipe(Effect.mapError((cause) => ModelProtocolError.make({ message: `Invalid Tool Call ID: ${cause.message}` }))));
2355
+ const decodeProviderToolCallId = Effect.fn((id) => Schema.decodeEffect(ProviderToolCallId)(id).pipe(Effect.mapError(() => ModelProtocolError.make({ message: "Model supplied an invalid Tool Call ID; expected 1-128 ASCII letters, digits, dots, underscores, colons, or hyphens" }))));
2356
+ const decodeProviderResponsePartId = Effect.fn((id) => Schema.decodeEffect(ProviderResponsePartId)(id).pipe(Effect.mapError(() => ModelProtocolError.make({ message: "Model supplied an invalid response part ID; expected 1-128 ASCII letters, digits, dots, underscores, colons, or hyphens" }))));
2357
+ const validateProviderPartIdentifiers = Effect.fnUntraced(function* (part) {
2358
+ switch (part.type) {
2359
+ case "text-start":
2360
+ case "text-delta":
2361
+ case "text-end":
2362
+ case "reasoning-start":
2363
+ case "reasoning-delta":
2364
+ case "reasoning-end":
2365
+ case "source":
2366
+ yield* decodeProviderResponsePartId(part.id);
2367
+ return;
2368
+ case "response-metadata":
2369
+ if (part.id !== void 0) yield* decodeProviderResponsePartId(part.id);
2370
+ return;
2371
+ case "tool-params-start":
2372
+ case "tool-params-delta":
2373
+ case "tool-params-end":
2374
+ case "tool-call":
2375
+ case "tool-result":
2376
+ yield* decodeProviderToolCallId(part.id);
2377
+ return;
2378
+ case "tool-approval-request":
2379
+ yield* decodeProviderResponsePartId(part.approvalId);
2380
+ yield* decodeProviderToolCallId(part.toolCallId);
2381
+ return;
2382
+ case "error":
2383
+ case "file":
2384
+ case "finish":
2385
+ case "reasoning":
2386
+ case "text": return;
2387
+ }
2388
+ });
2389
+ const responseIdentity = (part, previous) => Schema.decodeEffect(ModelResponseIdentity)({
2390
+ ...previous,
2391
+ ...part.id === void 0 ? {} : { id: part.id },
2392
+ ...part.modelId === void 0 ? {} : { model: part.modelId }
2393
+ }).pipe(Effect.mapError(() => ModelProtocolError.make({ message: "Invalid provider response identity" })), Effect.filterOrFail(() => !(previous?.id !== void 0 && part.id !== void 0 && previous.id !== part.id || previous?.model !== void 0 && part.modelId !== void 0 && previous.model !== part.modelId), () => ModelProtocolError.make({ message: "Provider response identity changed within one call" })));
2394
+ const decodeEventJson = Effect.fn("AgentRuntime.decodeEventJson")((value, label) => Schema.decodeUnknownEffect(Schema.Json)(value).pipe(Effect.mapError((cause) => ModelProtocolError.make({ message: `${label} is not JSON: ${cause.message}` }))));
2395
+ /**
2396
+ * Preserves provider-executed results as assistant content while application
2397
+ * handler results remain Tool messages for the next model request.
2398
+ */
2399
+ const promptFromTurnParts = (trace) => {
2400
+ if (trace.replayedResponse !== void 0) return trace.replayedResponse;
2401
+ const responsePrompt = Prompt.fromResponseParts(trace.parts.filter((part) => !(part.type === "tool-result" && part.providerExecuted)));
2402
+ const providerResults = trace.parts.flatMap((part) => part.type === "tool-result" && part.providerExecuted && !part.preliminary ? [Prompt.makePart("tool-result", {
2403
+ id: part.id,
2404
+ name: part.name,
2405
+ isFailure: part.isFailure,
2406
+ result: part.encodedResult,
2407
+ providerExecuted: true
2408
+ })] : []);
2409
+ if (providerResults.length === 0) return responsePrompt;
2410
+ const messages = [];
2411
+ let attachedProviderResults = false;
2412
+ for (const message of responsePrompt.content) {
2413
+ if (message.role === "assistant") {
2414
+ messages.push(Prompt.makeMessage("assistant", {
2415
+ content: [...message.content, ...providerResults],
2416
+ options: message.options
2417
+ }));
2418
+ attachedProviderResults = true;
2419
+ continue;
2420
+ }
2421
+ if (message.role === "tool") continue;
2422
+ messages.push(message);
2423
+ }
2424
+ if (!attachedProviderResults) messages.push(Prompt.makeMessage("assistant", { content: providerResults }));
2425
+ return Prompt.fromMessages(messages);
2426
+ };
2427
+ const eventsForPart = Effect.fnUntraced(function* (context, turnId, turn, tools, trace, part, retainedBytes) {
2428
+ yield* consumeModelResponsePart(trace, retainedBytes, context.bufferLimits);
2429
+ if (part.type === "finish" && trace.usage === void 0) {
2430
+ trace.usage = part.usage;
2431
+ trace.finishMetadata = part.metadata;
2432
+ }
2433
+ if (trace.finished) return yield* ModelProtocolError.make({ message: "Model response emitted content after its finish part" });
2434
+ yield* validateProviderPartIdentifiers(part);
2435
+ if (part.type === "response-metadata") trace.response = yield* responseIdentity(part, trace.response);
2436
+ if (part.type !== "tool-call" && part.type !== "tool-result") trace.parts.push(part);
2437
+ switch (part.type) {
2438
+ case "text-start":
2439
+ yield* startPart(trace.textParts, part.id, "text");
2440
+ return [];
2441
+ case "text-delta":
2442
+ yield* continuePart(trace.textParts, part.id, "text delta");
2443
+ trace.text.push(part.delta);
2444
+ return [TextDelta.make({
2445
+ ...yield* eventBase(context),
2446
+ turnId,
2447
+ text: part.delta
2448
+ })];
2449
+ case "text-end":
2450
+ yield* endPart(trace.textParts, part.id, "text");
2451
+ return [];
2452
+ case "reasoning-start":
2453
+ yield* startPart(trace.reasoningParts, part.id, "reasoning");
2454
+ return [];
2455
+ case "reasoning-delta":
2456
+ yield* continuePart(trace.reasoningParts, part.id, "reasoning delta");
2457
+ return [ReasoningDelta.make({
2458
+ ...yield* eventBase(context),
2459
+ turnId,
2460
+ text: part.delta
2461
+ })];
2462
+ case "reasoning-end":
2463
+ yield* endPart(trace.reasoningParts, part.id, "reasoning");
2464
+ return [];
2465
+ case "tool-params-start":
2466
+ if (trace.toolParameterParts.has(part.id)) return yield* ModelProtocolError.make({ message: `Model response repeated Tool parameter start for ${part.id}` });
2467
+ trace.toolParameterParts.set(part.id, {
2468
+ name: part.name,
2469
+ providerExecuted: part.providerExecuted,
2470
+ state: "open"
2471
+ });
2472
+ return [];
2473
+ case "tool-params-delta":
2474
+ if (trace.toolParameterParts.get(part.id)?.state !== "open") return yield* ModelProtocolError.make({ message: `Model response emitted Tool parameter delta for inactive part ${part.id}` });
2475
+ return [];
2476
+ case "tool-params-end": {
2477
+ const parameterPart = trace.toolParameterParts.get(part.id);
2478
+ if (parameterPart?.state !== "open") return yield* ModelProtocolError.make({ message: `Model response emitted Tool parameter end for inactive part ${part.id}` });
2479
+ parameterPart.state = "closed";
2480
+ return [];
2481
+ }
2482
+ case "tool-call": {
2483
+ if (!hasTool(tools, part.name)) return yield* ModelProtocolError.make({ message: `Model requested unknown Tool ${part.name}` });
2484
+ if (trace.toolCalls.has(part.id)) return yield* ModelProtocolError.make({ message: `Model response repeated Tool Call ID ${part.id}` });
2485
+ const parameterPart = trace.toolParameterParts.get(part.id);
2486
+ if (parameterPart?.state === "open") return yield* ModelProtocolError.make({ message: `Model response declared Tool Call ${part.id} before its parameters completed` });
2487
+ if (parameterPart !== void 0 && (parameterPart.name !== part.name || parameterPart.providerExecuted !== part.providerExecuted)) return yield* ModelProtocolError.make({ message: `Completed Tool parameters did not match Tool Call ${part.id}` });
2488
+ const toolCallId = yield* decodeToolCallId(part.id);
2489
+ const tool = tools[part.name];
2490
+ const decodedParameters = yield* decodeToolCallParameters(tool, part.name, part.params);
2491
+ const encodedParameters = yield* encodeToolCallParameters(tool, part.name, decodedParameters);
2492
+ const parameters = yield* decodeEventJson(encodedParameters, "Tool parameters");
2493
+ const canonicalCall = Response.makePart("tool-call", {
2494
+ id: part.id,
2495
+ name: part.name,
2496
+ params: parameters,
2497
+ providerExecuted: part.providerExecuted,
2498
+ metadata: part.metadata
2499
+ });
2500
+ trace.parts.push(canonicalCall);
2501
+ trace.toolCalls.set(part.id, {
2502
+ name: part.name,
2503
+ providerExecuted: part.providerExecuted
2504
+ });
2505
+ if (!part.providerExecuted) {
2506
+ trace.applicationToolCalls.push(canonicalCall);
2507
+ trace.applicationCallDescriptors.push({
2508
+ toolCallId,
2509
+ toolName: part.name,
2510
+ parameters,
2511
+ executionClass: getToolExecutionClass(tool),
2512
+ executionKind: getToolExecutionKind(tool.annotations)
2513
+ });
2514
+ }
2515
+ return [ToolCallDeclared.make({
2516
+ ...yield* eventBase(context),
2517
+ turnId,
2518
+ toolCallId,
2519
+ toolName: part.name,
2520
+ parameters,
2521
+ providerExecuted: part.providerExecuted
2522
+ })];
2523
+ }
2524
+ case "tool-result": {
2525
+ const declaredCall = trace.toolCalls.get(part.id);
2526
+ if (declaredCall === void 0) return yield* ModelProtocolError.make({ message: `Model response returned an unrequested Tool result ${part.id}` });
2527
+ if (declaredCall.name !== part.name) return yield* ModelProtocolError.make({ message: `Tool result name did not match Tool Call ${part.id}: expected ${declaredCall.name}, received ${part.name}` });
2528
+ if (declaredCall.providerExecuted !== part.providerExecuted) return yield* ModelProtocolError.make({ message: `Tool result execution boundary did not match Tool Call ${part.id}` });
2529
+ if (!part.providerExecuted) return yield* ModelProtocolError.make({ message: `Model response included an application Tool result before engine execution for ${part.id}` });
2530
+ const toolCallId = yield* decodeToolCallId(part.id);
2531
+ const normalized = yield* snapshotProviderToolResultPart(trace, part);
2532
+ const result = normalized.result;
2533
+ if (part.preliminary === true) {
2534
+ yield* stageProviderResultPayload(trace, {
2535
+ _tag: "ToolProgress",
2536
+ toolCallId,
2537
+ toolName: part.name,
2538
+ result,
2539
+ providerExecuted: true
2540
+ });
2541
+ trace.parts.push(Response.toolResultPart({
2542
+ id: part.id,
2543
+ name: part.name,
2544
+ isFailure: part.isFailure,
2545
+ result,
2546
+ encodedResult: result,
2547
+ providerExecuted: true,
2548
+ preliminary: true,
2549
+ metadata: normalized.metadata
2550
+ }));
2551
+ return [];
2552
+ }
2553
+ if (trace.finalToolResultIds.has(part.id)) return yield* ModelProtocolError.make({ message: `Tool Call ${part.id} produced more than one terminal result` });
2554
+ if (part.isFailure) yield* stageProviderResultPayload(trace, {
2555
+ _tag: "ToolCallFailed",
2556
+ toolCallId,
2557
+ toolName: part.name,
2558
+ errorTag: errorTag(result),
2559
+ message: errorMessage(result),
2560
+ providerExecuted: true
2561
+ });
2562
+ else yield* stageProviderResultPayload(trace, {
2563
+ _tag: "ToolCallSucceeded",
2564
+ toolCallId,
2565
+ toolName: part.name,
2566
+ result,
2567
+ providerExecuted: true
2568
+ });
2569
+ trace.finalToolResultIds.add(part.id);
2570
+ trace.parts.push(Response.toolResultPart({
2571
+ id: part.id,
2572
+ name: part.name,
2573
+ isFailure: part.isFailure,
2574
+ result,
2575
+ encodedResult: result,
2576
+ providerExecuted: true,
2577
+ preliminary: false,
2578
+ metadata: normalized.metadata
2579
+ }));
2580
+ return [];
2581
+ }
2582
+ case "finish": {
2583
+ const openPart = firstOpenPart(trace);
2584
+ if (openPart !== void 0) return yield* ModelProtocolError.make({ message: `Model response finished before completing ${openPart}` });
2585
+ trace.finished = true;
2586
+ trace.finishReason = part.reason;
2587
+ trace.usage = part.usage;
2588
+ if (Array.from(trace.toolCalls.values()).some(({ providerExecuted }) => providerExecuted)) {
2589
+ const turnCompletion = { finishReason: part.reason };
2590
+ const snapshot = yield* snapshotStagedProviderEvent(trace, {
2591
+ _tag: "TurnCompleted",
2592
+ ...turnCompletion
2593
+ });
2594
+ trace.turnCompletion = turnCompletion;
2595
+ trace.providerStagedPayloadBytes += snapshot.bytes;
2596
+ return [];
2597
+ }
2598
+ return [TurnCompleted.make({
2599
+ ...yield* eventBase(context),
2600
+ turnId,
2601
+ turn,
2602
+ finishReason: part.reason
2603
+ })];
2604
+ }
2605
+ case "error": return yield* ModelProtocolError.make({ message: `Model response failed: ${errorMessage(part.error)}` });
2606
+ case "file":
2607
+ case "reasoning":
2608
+ case "response-metadata":
2609
+ case "source":
2610
+ case "text":
2611
+ case "tool-approval-request": return [];
2612
+ }
2613
+ });
2614
+ const decodeFinalOutput = Effect.fn("AgentRuntime.decodeFinalOutput")(function* (agent, text) {
2615
+ const eventJson = isTextOutput(agent.definition.output) ? text : yield* Schema.decodeEffect(Schema.fromJsonString(Schema.Json))(text).pipe(Effect.mapError((cause) => AgentOutputError.make({ message: `Agent output is not valid JSON: ${cause.message}` })));
2616
+ const candidateOutput = eventJson;
2617
+ return {
2618
+ encoded: eventJson,
2619
+ decoded: yield* Schema.decodeUnknownEffect(agent.definition.output)(candidateOutput).pipe(Effect.mapError((cause) => AgentOutputError.make({ message: cause.message })))
2620
+ };
2621
+ });
2622
+ const encodeOutputCandidate = Effect.fn("AgentRuntime.encodeOutputCandidate")(function* (agent, candidate) {
2623
+ const encoded = yield* Schema.encodeUnknownEffect(agent.definition.output)(candidate).pipe(Effect.mapError((cause) => AgentOutputError.make({ message: `Completion Tool output failed Schema encoding: ${cause.message}` })));
2624
+ const decoded = yield* Schema.decodeUnknownEffect(agent.definition.output)(encoded).pipe(Effect.mapError((cause) => AgentOutputError.make({ message: `Completion Tool output failed canonical decoding: ${cause.message}` })));
2625
+ return {
2626
+ encoded: yield* Schema.decodeUnknownEffect(Schema.Json)(encoded).pipe(Effect.mapError((cause) => AgentOutputError.make({ message: `Completion Tool output did not encode as durable JSON: ${cause.message}` }))),
2627
+ decoded
2628
+ };
2629
+ });
2630
+ const projectToolResult = Effect.fn("AgentRuntime.projectToolResult")(function* (agent, declaration, parameters, result) {
2631
+ const tool = agent.definition.toolkit.tools[declaration.tool];
2632
+ if (tool === void 0) return yield* ModelProtocolError.make({ message: `Agent completion declaration references unknown Tool ${declaration.tool}` });
2633
+ const decodedParameters = yield* Schema.decodeUnknownEffect(tool.parametersSchema)(parameters).pipe(Effect.mapError((cause) => AgentOutputError.make({ message: `Completion Tool parameters failed canonical decoding: ${cause.message}` })));
2634
+ const decodedResult = yield* Schema.decodeUnknownEffect(tool.successSchema)(result).pipe(Effect.mapError((cause) => AgentOutputError.make({ message: `Completion Tool result failed canonical decoding: ${cause.message}` })));
2635
+ return yield* Effect.try({
2636
+ try: () => declaration.project({
2637
+ parameters: decodedParameters,
2638
+ result: decodedResult
2639
+ }),
2640
+ catch: (cause) => AgentOutputError.make({ message: `Completion Tool projector failed: ${cause instanceof Error ? cause.message : String(cause)}` })
2641
+ });
2642
+ });
2643
+ const projectCompletionOutput = Effect.fn("AgentRuntime.projectCompletionOutput")(function* (agent, declaration, parameters, result) {
2644
+ return yield* encodeOutputCandidate(agent, yield* projectToolResult(agent, declaration, parameters, result));
2645
+ });
2646
+ /** Reconstruct optional action completion identically for live execution and canonical recovery. */
2647
+ const projectCompletionFromToolOutput = Effect.fn("AgentRuntime.projectCompletionFromToolOutput")(function* (agent, declaration, parameters, result) {
2648
+ const projected = yield* projectToolResult(agent, declaration, parameters, result);
2649
+ if (!Option.isOption(projected)) return yield* AgentOutputError.make({ message: "Action completion projector did not return an Option" });
2650
+ if (Option.isNone(projected)) return Option.none();
2651
+ return Option.some(yield* encodeOutputCandidate(agent, projected.value));
2652
+ });
2653
+ const encodeRunDispositionCandidate = Effect.fn("AgentRuntime.encodeRunDisposition")(function* (declaration, output) {
2654
+ const selected = yield* Effect.try({
2655
+ try: () => declaration.fromOutput(output),
2656
+ catch: (cause) => AgentRunDispositionError.make({
2657
+ cause,
2658
+ message: "Run disposition selector failed"
2659
+ })
2660
+ });
2661
+ if (selected === void 0) return void 0;
2662
+ const encoded = yield* Schema.encodeUnknownEffect(declaration.schema)(selected).pipe(Effect.mapError((cause) => AgentRunDispositionError.make({
2663
+ cause,
2664
+ message: "Run disposition failed Schema encoding"
2665
+ })));
2666
+ return yield* Schema.decodeUnknownEffect(Schema.Json)(encoded).pipe(Effect.mapError((cause) => AgentRunDispositionError.make({
2667
+ cause,
2668
+ message: "Run disposition did not encode as durable JSON"
2669
+ })));
2670
+ });
2671
+ function encodeRunDisposition(agent, output) {
2672
+ const declaration = agent.definition.runDisposition;
2673
+ return declaration === void 0 ? Effect.void : encodeRunDispositionCandidate(declaration, output);
2674
+ }
2675
+ const decodeRunDispositionCandidate = Effect.fn("AgentRuntime.decodeRunDisposition")(function* (declaration, encoded) {
2676
+ return yield* Schema.decodeEffect(declaration.schema)(encoded).pipe(Effect.mapError((cause) => AgentRunDispositionError.make({
2677
+ cause,
2678
+ message: cause.message
2679
+ })));
2680
+ });
2681
+ function decodeRunDisposition(agent, encoded) {
2682
+ const declaration = agent.definition.runDisposition;
2683
+ return declaration === void 0 ? Effect.fail(ModelProtocolError.make({ message: "RunCompleted declared a run disposition without a definition-owned Schema" })) : decodeRunDispositionCandidate(declaration, encoded);
2684
+ }
2685
+ const nextTurn = (prompt, turn, toolCalls) => Stream.succeed({
2686
+ _tag: "NextTurn",
2687
+ prompt,
2688
+ turn,
2689
+ toolCalls
2690
+ });
2691
+ const makeTurn = (agent, context, prompt, turn, priorToolCalls, options) => Stream.unwrap(Effect.gen(function* () {
2692
+ const policy = agent.definition.policy;
2693
+ const bounds = effectiveRunBounds(policy, options);
2694
+ if (options.beforeTurn !== void 0) yield* options.beforeTurn();
2695
+ if ((yield* Clock.currentTimeMillis) >= context.durationDeadlineMillis) return failRunEventStream(durationLimitError(agent.definition.policy));
2696
+ if (policy.onExhaustion === "fail" && turn > bounds.maxTurns) return failRunEventStream(AgentPolicyError.make({
2697
+ limit: "turns",
2698
+ message: `Agent exceeded its ${bounds.maxTurns} Turn limit`
2699
+ }));
2700
+ if (context.finalizationUsed) return failRunEventStream(AgentPolicyError.make({
2701
+ limit: turn > bounds.maxTurns ? "turns" : priorToolCalls + context.programmaticToolCalls > bounds.maxToolCalls ? "tool-calls" : "tokens",
2702
+ message: "Agent already used its one grace finalization"
2703
+ }));
2704
+ const turnId = yield* (yield* IdGenerator$1).nextTurnId;
2705
+ const outputContract = outputSchemaContract(agent.definition);
2706
+ const outputContractMessage = outputContract._tag === "rendered" ? outputContract.message : void 0;
2707
+ const contextRequest = {
2708
+ threadId: context.threadId,
2709
+ runId: context.runId,
2710
+ turnId,
2711
+ turn,
2712
+ source: prompt,
2713
+ ...outputContractMessage === void 0 ? {} : { outputContract: outputContractMessage }
2714
+ };
2715
+ const modelContext = options.context === void 0 ? { prompt } : yield* options.context.prepare(contextRequest);
2716
+ const callContext = modelContext.modelCall === void 0 ? void 0 : yield* Schema.decodeEffect(ModelCallContext)(modelContext.modelCall.context).pipe(Effect.mapError((cause) => CompactionError.make({
2717
+ message: "Invalid resolved model context bounds",
2718
+ cause
2719
+ })));
2720
+ const contextTokenLimit = callContext === void 0 ? policy.contextTokenLimit : Math.max(0, Math.min(policy.contextTokenLimit ?? Infinity, callContext.maxInputTokens ?? Infinity, callContext.contextCapacity - callContext.outputReserveTokens) - callContext.uncountedOverheadTokens);
2721
+ context.windowContextTokenLimit = contextTokenLimit;
2722
+ const toolSchemaTransformer = modelContext.modelCall?.toolSchemaTransformer;
2723
+ const messageTokenEstimator = modelContext.modelCall?.estimateMessageTokens;
2724
+ const visibility = yield* RunToolVisibility;
2725
+ const catalog = yield* eligibleCatalog(agent.definition, {
2726
+ threadId: context.threadId,
2727
+ runId: context.runId,
2728
+ turn,
2729
+ input: context.input
2730
+ }, options.subagentGrant, options.delegationDepth ?? options.parentLink?.depth ?? 0);
2731
+ if (modelContext.toolSelection !== void 0) context.toolSelection = yield* validateSelection(modelContext.toolSelection, agent.definition, catalog);
2732
+ let snapshot = agent.definition.toolExposure === void 0 && context.toolSelection === void 0 && visibility === void 0 ? void 0 : yield* exposureSnapshot(agent.definition, context.toolSelection, catalog, toolSchemaTransformer);
2733
+ const selectionSnapshot = snapshot;
2734
+ context.toolSchemaTransformer = toolSchemaTransformer;
2735
+ context.toolCatalog = catalog;
2736
+ context.toolExposure = snapshot;
2737
+ const modelToolkit = Toolkit.make(...snapshot === void 0 ? catalog.filter((entry) => entry.kind === "native").map((entry) => entry.tool) : catalog.filter((entry) => entry.kind === "native" && snapshot?.exposedToolNames.includes(entry.nativeToolName)).map((entry) => entry.tool));
2738
+ if (options.durability !== void 0 && snapshot !== void 0) {
2739
+ if (options.durability.noteToolExposure === void 0 && context.toolSelection !== void 0) return yield* ModelProtocolError.make({ message: "Durable Tool exposure requires a request snapshot staging hook" });
2740
+ }
2741
+ const estimateCallTokens = (messages) => estimateContextTokens(messages, messageTokenEstimator);
2742
+ const modelServices = modelContext.modelCall === void 0 ? void 0 : yield* Layer.build(Layer.fresh(modelContext.modelCall.model));
2743
+ const withCallModel = (operation) => modelServices === void 0 ? operation : Effect.provide(operation, modelServices);
2744
+ const priorCompactionPrefix = context.preparedCompactionSource?.prefix;
2745
+ if (priorCompactionPrefix !== void 0 && priorCompactionPrefix.length > 0) {
2746
+ const preparedPrefix = yield* snapshotCompactionMessages(modelContext.prompt.content.slice(0, priorCompactionPrefix.length));
2747
+ if (!Equal.equals(preparedPrefix, priorCompactionPrefix)) return yield* CompactionError.make({ message: "Prepared context changed a prefix already covered by compaction" });
2748
+ }
2749
+ const trace = {
2750
+ responsePartCount: 0,
2751
+ responsePartBytes: 0,
2752
+ parts: [],
2753
+ text: [],
2754
+ textParts: /* @__PURE__ */ new Map(),
2755
+ reasoningParts: /* @__PURE__ */ new Map(),
2756
+ toolParameterParts: /* @__PURE__ */ new Map(),
2757
+ toolCalls: /* @__PURE__ */ new Map(),
2758
+ finalToolResultIds: /* @__PURE__ */ new Set(),
2759
+ providerResultPayloads: [],
2760
+ providerStagedPayloadBytes: 0,
2761
+ turnCompletion: void 0,
2762
+ applicationToolCalls: [],
2763
+ applicationCallDescriptors: [],
2764
+ applicationToolResults: [],
2765
+ finished: false,
2766
+ finishReason: void 0,
2767
+ usage: void 0
2768
+ };
2769
+ const started = Stream.fromEffect(Effect.gen(function* () {
2770
+ yield* Metric.update(modelCounter, 1);
2771
+ yield* Effect.logDebug("agent model call started").pipe(Effect.annotateLogs({
2772
+ agentId: context.agentId,
2773
+ runId: context.runId,
2774
+ turnId
2775
+ }));
2776
+ return [TurnStarted.make({
2777
+ ...yield* eventBase(context),
2778
+ turnId,
2779
+ turn
2780
+ }), ModelStarted.make({
2781
+ ...yield* eventBase(context),
2782
+ turnId,
2783
+ turn
2784
+ })];
2785
+ }).pipe(Effect.withLogSpan("AgentRuntime.model"))).pipe(Stream.flatMap(Stream.fromIterable));
2786
+ let finalAnswerOnly = policy.onExhaustion !== "fail" && (turn > bounds.maxTurns || priorToolCalls + context.programmaticToolCalls > bounds.maxToolCalls || context.tokenExhausted);
2787
+ const modelToolChoice = () => {
2788
+ return finalAnswerOnly || agent.definition.completion?.required === true && policy.onExhaustion === "fail" && turn === bounds.maxTurns ? agent.definition.completion === void 0 || agent.definition.completion.required !== true && !catalog.some((entry) => entry.kind === "native" && entry.nativeToolName === agent.definition.completion?.tool) ? "none" : agent.definition.completion.required === true ? { tool: agent.definition.completion.tool } : {
2789
+ mode: "auto",
2790
+ oneOf: [agent.definition.completion.tool]
2791
+ } : agent.definition.completion?.required === true ? "required" : void 0;
2792
+ };
2793
+ if (finalAnswerOnly && context.exhaustedDimension === void 0) context.exhaustedDimension = turn > bounds.maxTurns ? "turns" : priorToolCalls + context.programmaticToolCalls > bounds.maxToolCalls ? "tool-calls" : "tokens";
2794
+ if (outputContract._tag === "unrenderable" && turn === 1) yield* Effect.logWarning("Agent output schema cannot render to JSON Schema; the model-visible final output contract is omitted").pipe(Effect.annotateLogs({
2795
+ agentId: context.agentId,
2796
+ runId: context.runId,
2797
+ reason: outputContract.reason
2798
+ }));
2799
+ const admissionRequired = contextTokenLimit !== void 0 || !context.finalizing && !finalAnswerOnly && policy.tokenBudget !== void 0;
2800
+ const outputContractTokens = !admissionRequired || outputContractMessage === void 0 ? 0 : yield* estimateCallTokens([Prompt.makeMessage("system", { content: outputContractMessage })]);
2801
+ const canonicalDecoration = !admissionRequired ? Prompt.empty : yield* outgoingModelPrompt(policy, context, Prompt.empty, turn, priorToolCalls);
2802
+ const estimateToolSchemaTokens = Effect.suspend(() => {
2803
+ const choice = modelToolChoice();
2804
+ const tools = typeof choice === "object" && "oneOf" in choice ? catalog.filter((entry) => entry.kind === "native" && choice.oneOf.includes(entry.nativeToolName)).map((entry) => entry.tool) : Object.values(modelToolkit.tools);
2805
+ return callContext === void 0 || tools.length === 0 ? Effect.succeed(0) : Effect.try({
2806
+ try: () => JSON.stringify(tools.map((tool) => Tool.isProviderDefined(tool) ? {
2807
+ type: tool.providerName,
2808
+ args: tool.args
2809
+ } : {
2810
+ name: tool.name,
2811
+ description: Tool.getDescription(tool),
2812
+ parameters: Tool.getJsonSchema(tool, { transformer: toolSchemaTransformer })
2813
+ })),
2814
+ catch: (cause) => CompactionError.make({
2815
+ message: "Could not estimate native Tool schemas",
2816
+ cause
2817
+ })
2818
+ }).pipe(Effect.flatMap((content) => estimateCallTokens([Prompt.makeMessage("system", { content })])));
2819
+ });
2820
+ let toolSchemaTokens = yield* estimateToolSchemaTokens;
2821
+ const canonicalDecorationPromptTokens = !admissionRequired ? 0 : outputContractTokens + (yield* estimateCallTokens(canonicalDecoration.content));
2822
+ const canonicalDecorationTokens = () => toolSchemaTokens + canonicalDecorationPromptTokens;
2823
+ const estimateSourceContext = (view) => options.context === void 0 && options.transientContext === void 0 ? nextContextEstimate(context, view) : estimateCallTokens(view);
2824
+ let prepared = buildCompactedView(modelContext.prompt.content, context.compaction);
2825
+ let sourceTokens;
2826
+ const preparedSourceTokens = Effect.suspend(() => sourceTokens === void 0 ? estimateSourceContext(prepared).pipe(Effect.tap((tokens) => Effect.sync(() => {
2827
+ sourceTokens = tokens;
2828
+ }))) : Effect.succeed(sourceTokens));
2829
+ const refreshPrepared = () => {
2830
+ prepared = buildCompactedView(modelContext.prompt.content, context.compaction);
2831
+ sourceTokens = void 0;
2832
+ };
2833
+ let preEvents = [];
2834
+ if (modelContext.rollover !== void 0) {
2835
+ if (context.pendingContextToolCallId !== void 0) return yield* CompactionError.make({ message: "Host and Tool rollover requests cannot share a Turn" });
2836
+ const requested = yield* Schema.decodeEffect(ContextRolloverSelection)(modelContext.rollover).pipe(Effect.mapError((cause) => CompactionError.make({
2837
+ message: "Invalid host context rollover",
2838
+ cause
2839
+ })));
2840
+ const outcome = yield* compactContext(agent, context, modelContext.prompt, turn, options, callContext === void 0 ? void 0 : contextTokenLimit, messageTokenEstimator, contextTokenLimit === void 0 ? void 0 : Math.max(0, contextTokenLimit - canonicalDecorationTokens()), "requested", false, requested).pipe(withCallModel);
2841
+ if (outcome.events.some((event) => event._tag === "CompactionPerformed")) context.compaction.lastCompactionTurn = turn;
2842
+ preEvents = outcome.events;
2843
+ refreshPrepared();
2844
+ }
2845
+ const lastToolIndex = context.pendingContextToolCallId === void 0 ? -1 : modelContext.prompt.content.findLastIndex((message) => message.role === "tool" && message.content.some((part) => part.type === "tool-result" && part.id === context.pendingContextToolCallId));
2846
+ if (context.pendingContextToolCallId !== void 0 && lastToolIndex < 0) return yield* CompactionError.make({ message: "Prepared context omitted the pending context Tool result" });
2847
+ const lastTool = modelContext.prompt.content[lastToolIndex];
2848
+ if (context.pendingContextToolCallId !== void 0 && (lastTool?.role !== "tool" || lastTool.content.length !== 1)) return yield* CompactionError.make({ message: "Prepared context changed the pending context Tool batch" });
2849
+ if (lastTool?.role === "tool" && lastTool.content.length === 1) {
2850
+ const result = lastTool.content[0];
2851
+ if (result?.type === "tool-result" && !result.isFailure && result.providerExecuted !== true && result.id === context.pendingContextToolCallId && hasTool(agent.definition.toolkit.tools, result.name) && Context.get(agent.definition.toolkit.tools[result.name].annotations, ContextRolloverTool)) {
2852
+ const request = yield* Schema.decodeUnknownEffect(ContextRolloverRequest, { onExcessProperty: "error" })(result.result).pipe(Effect.mapError((cause) => CompactionError.make({
2853
+ message: "Invalid context rollover Tool result",
2854
+ cause
2855
+ })));
2856
+ const outcome = yield* compactContext(agent, context, modelContext.prompt, turn, options, callContext === void 0 ? void 0 : contextTokenLimit, messageTokenEstimator, contextTokenLimit === void 0 ? void 0 : Math.max(0, contextTokenLimit - canonicalDecorationTokens()), "requested", false, {
2857
+ ...request,
2858
+ through: lastToolIndex + 1
2859
+ }).pipe(withCallModel);
2860
+ context.compaction.lastCompactionTurn = turn;
2861
+ preEvents = outcome.events;
2862
+ refreshPrepared();
2863
+ }
2864
+ }
2865
+ context.pendingContextToolCallId = void 0;
2866
+ if (!context.finalizing && admissionRequired) {
2867
+ const consumedTokens = context.inputTokens + context.outputTokens;
2868
+ const tokenCallTarget = policy.tokenBudget === void 0 || finalAnswerOnly ? void 0 : Math.max(0, policy.tokenBudget - consumedTokens - policy.completionReserveTokens);
2869
+ const contextCallTarget = contextTokenLimit;
2870
+ const fullTarget = tokenCallTarget === void 0 ? contextCallTarget : contextCallTarget === void 0 ? tokenCallTarget : Math.min(tokenCallTarget, contextCallTarget);
2871
+ const sourceTarget = fullTarget === void 0 ? void 0 : Math.max(0, fullTarget - canonicalDecorationTokens());
2872
+ const estimate = (yield* preparedSourceTokens) + canonicalDecorationTokens();
2873
+ const contextPressure = contextCallTarget !== void 0 && estimate > contextCallTarget;
2874
+ const tokenPressure = tokenCallTarget !== void 0 && estimate > tokenCallTarget;
2875
+ if ((contextPressure || tokenPressure) && sourceTarget !== void 0 && sourceTarget > 0 && context.compaction.lastCompactionTurn !== turn) {
2876
+ context.compaction.lastCompactionTurn = turn;
2877
+ const outcome = yield* compactContext(agent, context, modelContext.prompt, turn, options, callContext === void 0 ? void 0 : contextTokenLimit, messageTokenEstimator, sourceTarget, "pressure", !tokenPressure).pipe(withCallModel);
2878
+ preEvents = [...preEvents, ...outcome.events];
2879
+ if (outcome.events.some((event) => event._tag === "CompactionPerformed")) refreshPrepared();
2880
+ }
2881
+ if (context.tokenExhausted) {
2882
+ finalAnswerOnly = true;
2883
+ toolSchemaTokens = yield* estimateToolSchemaTokens;
2884
+ }
2885
+ const preparedTokenCallTarget = policy.tokenBudget === void 0 || finalAnswerOnly ? void 0 : Math.max(0, policy.tokenBudget - (context.inputTokens + context.outputTokens) - policy.completionReserveTokens);
2886
+ let preparedEstimate = (yield* preparedSourceTokens) + canonicalDecorationTokens();
2887
+ if ((callContext !== void 0 || contextCallTarget === void 0 || preparedEstimate <= contextCallTarget) && preparedTokenCallTarget !== void 0 && preparedEstimate > preparedTokenCallTarget) {
2888
+ const error = AgentPolicyError.make({
2889
+ limit: "tokens",
2890
+ message: `The next research call would consume this Run's ${policy.completionReserveTokens} token completion reserve`
2891
+ });
2892
+ if (policy.onExhaustion === "fail") return yield* error;
2893
+ context.tokenExhausted = true;
2894
+ context.exhaustedDimension ??= "tokens";
2895
+ finalAnswerOnly = true;
2896
+ toolSchemaTokens = yield* estimateToolSchemaTokens;
2897
+ preparedEstimate = (yield* preparedSourceTokens) + canonicalDecorationTokens();
2898
+ }
2899
+ if (contextCallTarget !== void 0 && preparedEstimate > contextCallTarget) return yield* ContextBudgetError.make({
2900
+ message: `Compaction could not fit the next model prompt inside the ${contextCallTarget} token context target`,
2901
+ estimatedTokens: preparedEstimate,
2902
+ targetTokens: contextCallTarget,
2903
+ completionReserveTokens: policy.completionReserveTokens
2904
+ });
2905
+ }
2906
+ const transientContext = options.transientContext === void 0 ? Prompt.empty : yield* options.transientContext.load(contextRequest).pipe(Effect.flatMap(transientInputToPrompt));
2907
+ const derivedPrompt = options.transientContext === void 0 ? canonicalDecoration : yield* outgoingModelPrompt(policy, context, transientContext, turn, priorToolCalls);
2908
+ const derivedPromptContentTokens = !admissionRequired ? 0 : options.transientContext === void 0 ? canonicalDecorationPromptTokens : outputContractTokens + (yield* estimateCallTokens(derivedPrompt.content));
2909
+ const derivedPromptTokens = () => toolSchemaTokens + derivedPromptContentTokens;
2910
+ if (!context.finalizing && admissionRequired && options.transientContext !== void 0) {
2911
+ const tokenCallTarget = policy.tokenBudget === void 0 || finalAnswerOnly ? void 0 : Math.max(0, policy.tokenBudget - (context.inputTokens + context.outputTokens) - policy.completionReserveTokens);
2912
+ const fullTarget = tokenCallTarget === void 0 ? contextTokenLimit : contextTokenLimit === void 0 ? tokenCallTarget : Math.min(tokenCallTarget, contextTokenLimit);
2913
+ const sourceTarget = fullTarget === void 0 ? void 0 : Math.max(0, fullTarget - derivedPromptTokens());
2914
+ let preparedEstimate = (yield* preparedSourceTokens) + derivedPromptTokens();
2915
+ const contextPressure = contextTokenLimit !== void 0 && preparedEstimate > contextTokenLimit;
2916
+ const tokenPressure = tokenCallTarget !== void 0 && preparedEstimate > tokenCallTarget;
2917
+ const currentCompactionAllowance = context.compactionTurn.turn === turn;
2918
+ const summarizedThisTurn = currentCompactionAllowance && (context.compactionTurn.applied.has("summarize") || context.compactionTurn.applied.has("rollover"));
2919
+ const prunedThisTurn = currentCompactionAllowance && context.compactionTurn.applied.has("clear-tool-results");
2920
+ const canCompact = !summarizedThisTurn && (!prunedThisTurn || !tokenPressure && policy.compaction.mode !== "prune");
2921
+ if ((contextPressure || tokenPressure) && sourceTarget !== void 0 && sourceTarget > 0 && canCompact) {
2922
+ context.compaction.lastCompactionTurn = turn;
2923
+ const outcome = yield* compactContext(agent, context, modelContext.prompt, turn, options, callContext === void 0 ? void 0 : contextTokenLimit, messageTokenEstimator, sourceTarget, "pressure", !tokenPressure).pipe(withCallModel);
2924
+ preEvents = [...preEvents, ...outcome.events];
2925
+ if (outcome.events.some((event) => event._tag === "CompactionPerformed")) refreshPrepared();
2926
+ preparedEstimate = (yield* preparedSourceTokens) + derivedPromptTokens();
2927
+ }
2928
+ if (context.tokenExhausted) {
2929
+ finalAnswerOnly = true;
2930
+ toolSchemaTokens = yield* estimateToolSchemaTokens;
2931
+ }
2932
+ const preparedTokenCallTarget = policy.tokenBudget === void 0 || finalAnswerOnly ? void 0 : Math.max(0, policy.tokenBudget - (context.inputTokens + context.outputTokens) - policy.completionReserveTokens);
2933
+ if ((callContext !== void 0 || contextTokenLimit === void 0 || preparedEstimate <= contextTokenLimit) && preparedTokenCallTarget !== void 0 && preparedEstimate > preparedTokenCallTarget) {
2934
+ const error = AgentPolicyError.make({
2935
+ limit: "tokens",
2936
+ message: `The next research call would consume this Run's ${policy.completionReserveTokens} token completion reserve`
2937
+ });
2938
+ if (policy.onExhaustion === "fail") return yield* error;
2939
+ context.tokenExhausted = true;
2940
+ context.exhaustedDimension ??= "tokens";
2941
+ finalAnswerOnly = true;
2942
+ toolSchemaTokens = yield* estimateToolSchemaTokens;
2943
+ }
2944
+ preparedEstimate = (yield* preparedSourceTokens) + derivedPromptTokens();
2945
+ if (contextTokenLimit !== void 0 && preparedEstimate > contextTokenLimit) return yield* ContextBudgetError.make({
2946
+ message: `Transient context could not fit the next model prompt inside the ${contextTokenLimit} token context target`,
2947
+ estimatedTokens: preparedEstimate,
2948
+ targetTokens: contextTokenLimit,
2949
+ completionReserveTokens: policy.completionReserveTokens
2950
+ });
2951
+ }
2952
+ if (finalAnswerOnly) yield* context.policyReservations.withPermit(Effect.gen(function* () {
2953
+ context.finalizationUsed = true;
2954
+ if (options.durability?.reservePolicyUsage !== void 0) yield* options.durability.reservePolicyUsage({
2955
+ programmaticToolCalls: context.programmaticToolCalls,
2956
+ finalizationUsed: true
2957
+ });
2958
+ }));
2959
+ /** The model-visible view of the Turn basis under current compaction state. */
2960
+ const compactedOutgoing = () => {
2961
+ context.compaction.lastViewLength = prepared.length;
2962
+ return Prompt.fromMessages(prepared);
2963
+ };
2964
+ const consumeTurnUsage = (toolCallCount) => Effect.suspend(() => {
2965
+ trace.usageConsumed = true;
2966
+ const priorModelCalls = context.modelCalls;
2967
+ return consumeUsage(agent, context, trace.usage, toolCallCount, turn, options, {
2968
+ response: trace.response,
2969
+ finishMetadata: trace.finishMetadata,
2970
+ purpose: "turn"
2971
+ }).pipe(withCallModel, Effect.tapCause(() => context.modelCalls === priorModelCalls ? noteIncompleteUsage(context, turn) : Effect.void));
2972
+ });
2973
+ const retainFailedUsage = Effect.fn("AgentRuntime.retainFailedUsage")(function* () {
2974
+ if (trace.usageConsumed) return;
2975
+ trace.usageConsumed = true;
2976
+ if (trace.usage === void 0) return yield* noteIncompleteUsage(context, turn);
2977
+ yield* consumeTurnUsage(0).pipe(Effect.exit);
2978
+ });
2979
+ const attempt = (basis) => Stream.unwrap(outgoingModelPrompt(policy, context, Prompt.fromMessages([...basis.content, ...transientContext.content]), turn, priorToolCalls).pipe(Effect.flatMap((outgoing) => Effect.gen(function* () {
2980
+ const toolChoice = modelToolChoice();
2981
+ let requestToolkit = modelToolkit;
2982
+ snapshot = selectionSnapshot;
2983
+ if (selectionSnapshot !== void 0 && typeof toolChoice === "object" && "oneOf" in toolChoice) {
2984
+ const finalSelection = yield* validateSelection({ toolNames: toolChoice.oneOf }, agent.definition, catalog);
2985
+ const selected = yield* exposureSnapshot(agent.definition, finalSelection, catalog, toolSchemaTransformer, toolChoice.oneOf);
2986
+ requestToolkit = Toolkit.make(...catalog.filter((entry) => entry.kind === "native" && selected.exposedToolNames.includes(entry.nativeToolName)).map((entry) => entry.tool));
2987
+ snapshot = Object.freeze(Snapshot.make({
2988
+ ...selectionSnapshot,
2989
+ exposedToolNames: selected.exposedToolNames
2990
+ }));
2991
+ }
2992
+ context.toolExposure = snapshot;
2993
+ const providerPrompt = outputContract._tag !== "rendered" ? outgoing : insertOutputContract(outgoing, outputContract.part);
2994
+ return yield* estimateCallTokens(providerPrompt.content).pipe(Effect.map((tokens) => tokens + toolSchemaTokens), Effect.tap((estimatedTokens) => contextTokenLimit !== void 0 && (options.context !== void 0 || options.transientContext !== void 0) && estimatedTokens > contextTokenLimit ? ContextBudgetError.make({
2995
+ message: `Prepared context could not fit the next model prompt inside the ${contextTokenLimit} token context target`,
2996
+ estimatedTokens,
2997
+ targetTokens: contextTokenLimit,
2998
+ completionReserveTokens: policy.completionReserveTokens
2999
+ }) : Effect.void), Effect.tap((tokens) => Effect.sync(() => {
3000
+ context.windowTokens = tokens;
3001
+ })), Effect.tap(() => snapshot === void 0 || options.durability?.noteToolExposure === void 0 ? Effect.void : options.durability.noteToolExposure(turn, snapshot)), Effect.as(guardBudgetStream(LanguageModel.streamText({
3002
+ prompt: providerPrompt,
3003
+ toolkit: requestToolkit,
3004
+ disableToolCallResolution: true,
3005
+ ...toolChoice === void 0 ? {} : { toolChoice }
3006
+ }), options.budget).pipe(Stream.onStart(Effect.sync(() => {
3007
+ trace.usageConsumed = false;
3008
+ })), Stream.mapEffect((part) => ownModelResponsePart(part, agent.definition.toolkit, trace, context.bufferLimits).pipe(Effect.flatMap((owned) => eventsForPart(context, turnId, turn, agent.definition.toolkit.tools, trace, owned.ownedPart, owned.retainedBytes)))), Stream.flatMap(Stream.fromIterable), Stream.tapCause(() => retainFailedUsage()))));
3009
+ }))));
3010
+ const response = attempt(compactedOutgoing()).pipe(Stream.catch((error) => {
3011
+ if (!(error instanceof AiError.AiError) || !isContextOverflowMessage(overflowText(error))) return Stream.fail(error);
3012
+ const message = overflowText(error);
3013
+ if (trace.parts.length > 0 || contextTokenLimit === void 0) return Stream.fail(ContextOverflowError.make({
3014
+ message,
3015
+ retried: false
3016
+ }));
3017
+ if (context.compaction.overflowRetryTurn === turn) return Stream.fail(ContextOverflowError.make({
3018
+ message,
3019
+ retried: true
3020
+ }));
3021
+ context.compaction.overflowRetryTurn = turn;
3022
+ context.compaction.lastCompactionTurn = turn;
3023
+ return Stream.unwrap(Effect.gen(function* () {
3024
+ const outcome = yield* compactContext(agent, context, modelContext.prompt, turn, options, callContext === void 0 ? void 0 : contextTokenLimit, messageTokenEstimator, Math.max(0, contextTokenLimit - derivedPromptTokens()), "overflow").pipe(withCallModel).pipe(Effect.mapError((inner) => inner instanceof AiError.AiError && isContextOverflowMessage(overflowText(inner)) ? ContextOverflowError.make({
3025
+ message: overflowText(inner),
3026
+ retried: true
3027
+ }) : inner));
3028
+ if (outcome.events.some((event) => event._tag === "CompactionPerformed")) refreshPrepared();
3029
+ const retryEstimate = (yield* preparedSourceTokens) + derivedPromptTokens();
3030
+ if (retryEstimate > contextTokenLimit) return yield* ContextBudgetError.make({
3031
+ message: `Overflow compaction could not fit the retry inside the ${contextTokenLimit} token context target`,
3032
+ estimatedTokens: retryEstimate,
3033
+ targetTokens: contextTokenLimit,
3034
+ completionReserveTokens: policy.completionReserveTokens
3035
+ });
3036
+ const retried = attempt(compactedOutgoing()).pipe(Stream.catch((again) => again instanceof AiError.AiError && isContextOverflowMessage(overflowText(again)) ? Stream.fail(ContextOverflowError.make({
3037
+ message: overflowText(again),
3038
+ retried: true
3039
+ })) : Stream.fail(again)));
3040
+ return Stream.fromIterable(outcome.events).pipe(Stream.concat(retried));
3041
+ }));
3042
+ }), Stream.withSpan("AgentRuntime.model", { attributes: {
3043
+ agentId: context.agentId,
3044
+ runId: context.runId,
3045
+ turnId
3046
+ } }));
3047
+ const continuation = Stream.unwrap(Effect.sync(() => {
3048
+ if (!trace.finished) return failRunEventStream(ModelProtocolError.make({ message: "Model response ended without a finish part" }));
3049
+ const hasProviderCalls = Array.from(trace.toolCalls.values()).some(({ providerExecuted }) => providerExecuted);
3050
+ const turnCompletion = trace.turnCompletion;
3051
+ if (hasProviderCalls && turnCompletion === void 0) return failRunEventStream(ModelProtocolError.make({ message: "Model response omitted staged Turn completion" }));
3052
+ const completionTool = agent.definition.completion?.tool;
3053
+ const declaresCompletion = completionTool !== void 0 && trace.applicationToolCalls.some((call) => call.name === completionTool);
3054
+ const declaresActionCompletion = trace.applicationToolCalls.some((call) => agent.definition.completionFromTools?.some((declaration) => declaration.tool === call.name));
3055
+ if (trace.applicationToolCalls.some((call) => hasTool(agent.definition.toolkit.tools, call.name) && Context.get(agent.definition.toolkit.tools[call.name].annotations, ContextRolloverTool)) && (trace.toolCalls.size !== 1 || declaresCompletion || declaresActionCompletion)) return failRunEventStream(ModelProtocolError.make({ message: "A context rollover Tool must be the only Tool Call and cannot complete the Run" }));
3056
+ const completionBatchError = (declaresCompletion || declaresActionCompletion) && trace.applicationToolCalls.length !== 1 ? ModelProtocolError.make({ message: declaresCompletion ? `Completion Tool ${completionTool} must be the only application Tool Call in its batch` : "An action completion Tool must be the only application Tool Call in its batch" }) : void 0;
3057
+ if (completionBatchError !== void 0 && finalAnswerOnly) return failRunEventStream(completionBatchError);
3058
+ const completionBatch = declaresCompletion && trace.applicationToolCalls.length === 1;
3059
+ if (finalAnswerOnly && trace.toolCalls.size > 0 && (hasProviderCalls || !completionBatch)) return failRunEventStream(ModelProtocolError.make({ message: completionTool === void 0 ? `Model declared ${trace.toolCalls.size} Tool Call(s) under toolChoice "none" after budget exhaustion` : `Model declared ${trace.toolCalls.size} non-completion Tool Call(s) after budget exhaustion` }));
3060
+ const providerOnly = trace.toolCalls.size > 0 && Array.from(trace.toolCalls.values()).every(({ providerExecuted }) => providerExecuted);
3061
+ const missingProviderResult = Array.from(trace.toolCalls.entries()).find(([id, call]) => call.providerExecuted && !trace.finalToolResultIds.has(id));
3062
+ if (missingProviderResult !== void 0) return failRunEventStream(ModelProtocolError.make({ message: `Provider-executed Tool Call ${missingProviderResult[0]} completed without a terminal result` }));
3063
+ const toolCalls = priorToolCalls + trace.toolCalls.size;
3064
+ const overToolBudget = toolCalls + context.programmaticToolCalls > bounds.maxToolCalls;
3065
+ if (overToolBudget && policy.onExhaustion === "fail") return failRunEventStream(AgentPolicyError.make({
3066
+ limit: "tool-calls",
3067
+ message: `Agent exceeded its ${bounds.maxToolCalls} Tool Call limit`
3068
+ }));
3069
+ if (agent.definition.completion?.required === true && trace.toolCalls.size === 0) return failRunEventStream(ModelProtocolError.make({ message: `Model stopped without required completion Tool ${agent.definition.completion.tool}` }));
3070
+ const stagedResponse = Stream.fromIterable(trace.providerResultPayloads).pipe(Stream.mapEffect((payload) => stampProviderResultEvent(context, turnId, payload)), Stream.concat(turnCompletion === void 0 ? Stream.empty : Stream.fromEffect(Effect.map(eventBase(context), (base) => TurnCompleted.make({
3071
+ ...base,
3072
+ turnId,
3073
+ turn,
3074
+ finishReason: turnCompletion.finishReason
3075
+ })))));
3076
+ /** Official history advanced through this Turn's response, plus any Tool message. */
3077
+ const historyWithResponse = (...additions) => Prompt.fromMessages([
3078
+ ...prompt.content,
3079
+ ...promptFromTurnParts(trace).content,
3080
+ ...additions
3081
+ ]);
3082
+ const afterValidatedResponse = (next) => stagedResponse.pipe(Stream.concat(Stream.unwrap(Effect.gen(function* () {
3083
+ const consumed = yield* consumeTurnUsage(trace.toolCalls.size);
3084
+ const pre = [...consumed.warnings];
3085
+ if (!context.warnedLimits.has("tool-calls") && nearingLimit(toolCalls + context.programmaticToolCalls, bounds.maxToolCalls)) {
3086
+ context.warnedLimits.add("tool-calls");
3087
+ pre.push(BudgetWarning.make({
3088
+ ...yield* eventBase(context),
3089
+ limit: "tool-calls",
3090
+ consumed: toolCalls + context.programmaticToolCalls,
3091
+ limitValue: bounds.maxToolCalls
3092
+ }));
3093
+ }
3094
+ if (!context.warnedLimits.has("turns") && nearingLimit(turn, bounds.maxTurns)) {
3095
+ context.warnedLimits.add("turns");
3096
+ pre.push(BudgetWarning.make({
3097
+ ...yield* eventBase(context),
3098
+ limit: "turns",
3099
+ consumed: turn,
3100
+ limitValue: bounds.maxTurns
3101
+ }));
3102
+ }
3103
+ const emitThen = (nextStream) => pre.length === 0 ? nextStream : Stream.fromIterable(pre).pipe(Stream.concat(nextStream));
3104
+ if (consumed.breach !== void 0) {
3105
+ if (agent.definition.completion?.required !== true && trace.applicationToolCalls.length === 0 && trace.finishReason === "stop") {
3106
+ const output = yield* decodeFinalOutput(agent, trace.text.join("")).pipe(Effect.map(Option.some), Effect.catch(() => Effect.succeed(Option.none())));
3107
+ if (Option.isSome(output)) {
3108
+ yield* advanceHistory(context, historyWithResponse(), options);
3109
+ const completionUsage = yield* usageReportOf(context);
3110
+ return emitThen(Stream.fromEffect(Effect.map(eventBase(context), (base) => RunCompleted.make({
3111
+ ...base,
3112
+ output: output.value.encoded,
3113
+ turns: turn,
3114
+ finishReason: "budget-exhausted",
3115
+ exhausted: "tokens",
3116
+ ...completionUsage
3117
+ }))));
3118
+ }
3119
+ }
3120
+ if (trace.applicationToolCalls.length > 0 && !completionBatch) {
3121
+ const rejection = yield* settleRejectedBatch(context, turnId, trace, AgentPolicyError.make({
3122
+ limit: "tokens",
3123
+ message: `Token budget exhausted: this Run's ${policy.tokenBudget ?? 0} token budget was reached, so this call was rejected without executing. Do not request more tools; produce your final answer now from the information you already have.`
3124
+ }));
3125
+ return emitThen(Stream.fromIterable(rejection).pipe(Stream.concat(toolBatchContinuation(agent, context, trace, prompt, turn, toolCalls, options))));
3126
+ }
3127
+ }
3128
+ return emitThen(yield* next);
3129
+ }))));
3130
+ /**
3131
+ * Advance official history for a Turn that always continues, drain
3132
+ * steering at the safe seam, and start the next Turn. The `maxTurns`
3133
+ * guard already ran for these Tool Call sites.
3134
+ */
3135
+ const continueTurn = (history) => Effect.gen(function* () {
3136
+ yield* advanceHistory(context, history, options);
3137
+ const steering = yield* drainInputs(context, options);
3138
+ const nextPrompt = yield* appendInputs(context, history, steering, options);
3139
+ return nextTurn(nextPrompt, turn + 1, toolCalls);
3140
+ });
3141
+ /**
3142
+ * The otherwise-stop seam: advance official history, drain steering,
3143
+ * fall back to buffered follow-ups, then either start the next Turn
3144
+ * under the `maxTurns` and repeated-failure Stop Policy bounds or
3145
+ * complete the Run with the Turn's decoded final output.
3146
+ */
3147
+ const settleOrFollowUp = (history) => Effect.gen(function* () {
3148
+ yield* advanceHistory(context, history, options);
3149
+ const steering = yield* drainInputs(context, options);
3150
+ const queued = steering.length > 0 ? steering : takeFollowUps(context, options.commandDrainPolicy ?? "one");
3151
+ if (queued.length > 0) {
3152
+ if (policy.onExhaustion === "fail" ? turn >= bounds.maxTurns : turn > bounds.maxTurns) return failRunEventStream(AgentPolicyError.make({
3153
+ limit: "turns",
3154
+ message: `Agent exceeded its ${bounds.maxTurns} Turn limit`
3155
+ }));
3156
+ yield* applyRepeatedFailurePolicy(context, trace, agent.definition.policy.repeatedFailureLimit);
3157
+ const nextPrompt = yield* appendInputs(context, history, queued, options);
3158
+ return nextTurn(nextPrompt, turn + 1, toolCalls);
3159
+ }
3160
+ const output = yield* decodeFinalOutput(agent, trace.text.join(""));
3161
+ const declaration = agent.definition.runDisposition;
3162
+ const runDisposition = finalAnswerOnly || declaration === void 0 ? void 0 : yield* encodeRunDisposition(agent, output.decoded);
3163
+ const completionUsage = yield* usageReportOf(context);
3164
+ return Stream.fromEffect(Effect.map(eventBase(context), (base) => RunCompleted.make({
3165
+ ...base,
3166
+ output: output.encoded,
3167
+ ...runDisposition === void 0 ? {} : { runDisposition },
3168
+ turns: turn,
3169
+ finishReason: finalAnswerOnly ? "budget-exhausted" : "model-stop",
3170
+ ...finalAnswerOnly && context.exhaustedDimension !== void 0 ? { exhausted: context.exhaustedDimension } : {},
3171
+ ...completionUsage
3172
+ })));
3173
+ });
3174
+ if (providerOnly && trace.finishReason === "stop") {
3175
+ if (agent.definition.completion?.required === true) {
3176
+ if (policy.onExhaustion === "fail" ? turn >= bounds.maxTurns : turn > bounds.maxTurns) return failRunEventStream(AgentPolicyError.make({
3177
+ limit: "turns",
3178
+ message: `Agent exceeded its ${bounds.maxTurns} Turn limit`
3179
+ }));
3180
+ }
3181
+ return afterValidatedResponse(agent.definition.completion?.required === true ? continueTurn(historyWithResponse()) : settleOrFollowUp(historyWithResponse()));
3182
+ }
3183
+ if (trace.toolCalls.size > 0) {
3184
+ if (trace.finishReason !== "tool-calls") return failRunEventStream(ModelProtocolError.make({ message: `Model declared Tool Calls with incompatible finish reason ${trace.finishReason}` }));
3185
+ if (turn > bounds.maxTurns && !(turn === bounds.maxTurns + 1 && finalAnswerOnly && completionBatch) || policy.onExhaustion === "fail" && turn === bounds.maxTurns && !completionBatch) return failRunEventStream(AgentPolicyError.make({
3186
+ limit: "turns",
3187
+ message: `Agent exceeded its ${bounds.maxTurns} Turn limit`
3188
+ }));
3189
+ const batchRejection = overToolBudget && trace.applicationToolCalls.length > 0 && !(completionBatch && policy.onExhaustion === "final-answer") ? AgentPolicyError.make({
3190
+ limit: "tool-calls",
3191
+ message: `Tool Call budget exhausted: this Run's ${bounds.maxToolCalls} Tool Call limit was reached, so this call was rejected without executing. Do not request more tools; produce your final answer now from the information you already have.`
3192
+ }) : completionBatchError === void 0 ? void 0 : ModelProtocolError.make({ message: `${completionBatchError.message}. ` + (hasProviderCalls ? "The application batch was rejected before execution; none of its application tools ran. Completed provider results are retained. " : "The entire batch was rejected before execution; none of its tools ran. ") + "Request any needed ordinary tools first, wait for their results, then call a completion tool alone." });
3193
+ if (batchRejection !== void 0) return afterValidatedResponse(Effect.gen(function* () {
3194
+ const rejection = yield* settleRejectedBatch(context, turnId, trace, batchRejection);
3195
+ return Stream.fromIterable(rejection).pipe(Stream.concat(toolBatchContinuation(agent, context, trace, prompt, turn, toolCalls, options)));
3196
+ }));
3197
+ if (trace.applicationToolCalls.length === 0) return afterValidatedResponse(Effect.gen(function* () {
3198
+ const history = historyWithResponse();
3199
+ yield* advanceHistory(context, history, options);
3200
+ yield* applyRepeatedFailurePolicy(context, trace, agent.definition.policy.repeatedFailureLimit);
3201
+ const steering = yield* drainInputs(context, options);
3202
+ const nextPrompt = yield* appendInputs(context, history, steering, options);
3203
+ return nextTurn(nextPrompt, turn + 1, toolCalls);
3204
+ }));
3205
+ return afterValidatedResponse(Effect.gen(function* () {
3206
+ const toolkit = yield* agent.definition.toolkit;
3207
+ const concurrency = yield* schedulingConcurrency(agent.definition.policy.toolConcurrency, options.scheduling);
3208
+ if (options.durability !== void 0) yield* options.durability.commitResponse({
3209
+ turn,
3210
+ turnId,
3211
+ responseMessages: promptFromTurnParts(trace),
3212
+ calls: trace.applicationCallDescriptors,
3213
+ toolExposure: snapshot
3214
+ });
3215
+ return guardBudgetStream(executeToolBatch(context, turnId, turn, toolkit, trace.applicationToolCalls, trace, concurrency, options, {
3216
+ maxToolCalls: bounds.maxToolCalls,
3217
+ declaredToolCalls: toolCalls
3218
+ }, agent.definition.policy.toolResultBounds), options.budget).pipe(Stream.concat(toolBatchContinuation(agent, context, trace, prompt, turn, toolCalls, options)));
3219
+ }));
3220
+ }
3221
+ if (trace.finishReason !== "stop") return failRunEventStream(ModelProtocolError.make({ message: `Model stopped without a final answer (${trace.finishReason})` }));
3222
+ return afterValidatedResponse(settleOrFollowUp(historyWithResponse()));
3223
+ }));
3224
+ const events = Stream.fromIterable(preEvents).pipe(Stream.concat(started), Stream.concat(response), Stream.concat(continuation.pipe(Stream.tapCause(() => retainFailedUsage()))));
3225
+ return modelServices === void 0 ? events : Stream.provideContext(events, modelServices);
3226
+ }));
3227
+ /**
3228
+ * Settle a completed application Tool batch and continue the Run: verify one
3229
+ * final result per declared call, fold outcomes into the repeated-failure
3230
+ * Stop Policy, advance official history with the Tool message in declaration
3231
+ * order, drain steering at the safe seam, and start the next Turn. Shared by
3232
+ * the ordinary model-declared path (`makeTurn`) and the durable batch-resume
3233
+ * path (`makeResumeTurn`).
3234
+ */
3235
+ const toolBatchContinuation = (agent, context, trace, prompt, turn, toolCalls, options) => Stream.unwrap(Effect.gen(function* () {
3236
+ if (trace.finalToolResultIds.size !== trace.toolCalls.size) return failRunEventStream(ModelProtocolError.make({ message: "A Tool Call turn completed without one final result per Tool Call" }));
3237
+ const orderedResults = [];
3238
+ for (const call of trace.applicationToolCalls) {
3239
+ const result = trace.applicationToolResults.find((candidate) => candidate?.id === call.id);
3240
+ if (result === void 0) return failRunEventStream(ModelProtocolError.make({ message: "Tool batch did not settle completely" }));
3241
+ orderedResults.push(result);
3242
+ }
3243
+ for (const result of orderedResults) if (!result.isFailure && result.toolSelection !== void 0) context.toolSelection = result.toolSelection;
3244
+ const toolMessage = Prompt.makeMessage("tool", { content: orderedResults.map((result) => Prompt.makePart("tool-result", {
3245
+ id: result.id,
3246
+ name: result.name,
3247
+ result: result.encodedResult,
3248
+ isFailure: result.isFailure,
3249
+ providerExecuted: false
3250
+ })) });
3251
+ const history = Prompt.fromMessages([
3252
+ ...prompt.content,
3253
+ ...promptFromTurnParts(trace).content,
3254
+ toolMessage
3255
+ ]);
3256
+ yield* advanceHistory(context, history, options);
3257
+ yield* applyRepeatedFailurePolicy(context, trace, agent.definition.policy.repeatedFailureLimit);
3258
+ const rolloverResult = orderedResults.length === 1 ? orderedResults[0] : void 0;
3259
+ if (rolloverResult !== void 0 && !rolloverResult.isFailure && hasTool(agent.definition.toolkit.tools, rolloverResult.name) && Context.get(agent.definition.toolkit.tools[rolloverResult.name].annotations, ContextRolloverTool)) context.pendingContextToolCallId = rolloverResult.id;
3260
+ const completion = agent.definition.completion;
3261
+ const successfulResult = trace.applicationToolCalls.length === 1 && orderedResults.length === 1 && orderedResults[0]?.isFailure === false ? orderedResults[0] : void 0;
3262
+ const actionCompletion = agent.definition.completionFromTools?.find((declaration) => declaration.tool === successfulResult?.name);
3263
+ let selectedOutput = Option.none();
3264
+ if (successfulResult !== void 0 && (successfulResult.name === completion?.tool || actionCompletion !== void 0)) {
3265
+ const call = trace.applicationCallDescriptors[0];
3266
+ if (call === void 0) return failRunEventStream(ModelProtocolError.make({ message: "Completion Tool has no canonical call descriptor" }));
3267
+ if (actionCompletion !== void 0) selectedOutput = yield* projectCompletionFromToolOutput(agent, actionCompletion, call.parameters, successfulResult.encodedResult);
3268
+ else if (completion !== void 0) selectedOutput = Option.some(yield* projectCompletionOutput(agent, completion, call.parameters, successfulResult.encodedResult));
3269
+ }
3270
+ if (Option.isSome(selectedOutput)) {
3271
+ const output = selectedOutput.value;
3272
+ const bounds = effectiveRunBounds(agent.definition.policy, options);
3273
+ const exhausted = context.tokenExhausted ? "tokens" : turn > bounds.maxTurns ? "turns" : toolCalls + context.programmaticToolCalls > bounds.maxToolCalls ? "tool-calls" : context.exhaustedDimension;
3274
+ if (exhausted !== void 0 && context.exhaustedDimension === void 0) context.exhaustedDimension = exhausted;
3275
+ const declaration = agent.definition.runDisposition;
3276
+ const runDisposition = exhausted !== void 0 || declaration === void 0 ? void 0 : yield* encodeRunDisposition(agent, output.decoded);
3277
+ const completionUsage = yield* usageReportOf(context);
3278
+ return Stream.fromEffect(Effect.map(eventBase(context), (base) => RunCompleted.make({
3279
+ ...base,
3280
+ output: output.encoded,
3281
+ ...runDisposition === void 0 ? {} : { runDisposition },
3282
+ turns: turn,
3283
+ finishReason: exhausted === void 0 ? "completed" : "budget-exhausted",
3284
+ ...exhausted === void 0 ? {} : { exhausted },
3285
+ ...completionUsage
3286
+ })));
3287
+ }
3288
+ const steering = yield* drainInputs(context, options);
3289
+ const nextPrompt = yield* appendInputs(context, history, steering, options);
3290
+ return nextTurn(nextPrompt, turn + 1, toolCalls);
3291
+ }));
3292
+ /**
3293
+ * Resume one canonically declared Tool batch without re-invoking the model
3294
+ * (the durable batch-resume seam consumed via `RunOptions.resume`).
3295
+ *
3296
+ * The declared calls are re-validated through their Tool parameter Schemas
3297
+ * before anything executes; a decode failure is a strict no-start boundary
3298
+ * (RUN-004/STORE-006). The resumed Turn's response messages are rebuilt in
3299
+ * canonical encoded form so official history matches the recorded response.
3300
+ * Calls listed in `settled` are injected as final results without starting
3301
+ * their handlers — recorded Tool outcomes never rerun — while approval
3302
+ * preflight and durable preparation still cover the complete declared batch.
3303
+ * No model request is made and no usage is consumed for the resumed Turn.
3304
+ */
3305
+ const makeResumeTurn = (agent, context, prompt, resume, countedToolCalls, options) => Stream.unwrap(Effect.gen(function* () {
3306
+ const tools = agent.definition.toolkit.tools;
3307
+ const turn = resume.turn;
3308
+ const turnId = resume.turnId;
3309
+ const visibility = yield* RunToolVisibility;
3310
+ if (resume.toolExposure === void 0 && (agent.definition.toolExposure !== void 0 || context.toolSelection !== void 0 || visibility !== void 0)) return yield* ModelProtocolError.make({ message: "Resumed progressive Turn is missing its original Tool exposure" });
3311
+ context.toolCatalog = yield* eligibleCatalog(agent.definition, {
3312
+ threadId: context.threadId,
3313
+ runId: context.runId,
3314
+ turn,
3315
+ input: context.input
3316
+ }, options.subagentGrant, options.delegationDepth ?? options.parentLink?.depth ?? 0);
3317
+ context.toolExposure = resume.toolExposure === void 0 ? void 0 : yield* decodeSnapshot(resume.toolExposure);
3318
+ const originalExposure = context.toolExposure;
3319
+ if (originalExposure !== void 0) {
3320
+ yield* validateSelection({ toolNames: originalExposure.exposedToolNames }, agent.definition, context.toolCatalog, false);
3321
+ if (originalExposure.selection !== void 0) yield* validateSelection(originalExposure.selection, agent.definition, context.toolCatalog, false);
3322
+ if (resume.calls.some((call) => !originalExposure.exposedToolNames.includes(call.name))) return yield* ModelProtocolError.make({ message: "Resumed Tool call was not exposed in its original model request" });
3323
+ context.toolSelection = originalExposure.selection;
3324
+ }
3325
+ if (!Number.isInteger(turn) || turn <= 0) return failRunEventStream(ModelProtocolError.make({ message: "Turn resume requires a positive integer turn number" }));
3326
+ if (resume.calls.length === 0) return failRunEventStream(ModelProtocolError.make({ message: "Turn resume requires at least one declared Tool Call" }));
3327
+ const trace = {
3328
+ replayedResponse: resume.responseMessages,
3329
+ responsePartCount: 0,
3330
+ responsePartBytes: 0,
3331
+ parts: [],
3332
+ text: [],
3333
+ textParts: /* @__PURE__ */ new Map(),
3334
+ reasoningParts: /* @__PURE__ */ new Map(),
3335
+ toolParameterParts: /* @__PURE__ */ new Map(),
3336
+ toolCalls: /* @__PURE__ */ new Map(),
3337
+ finalToolResultIds: /* @__PURE__ */ new Set(),
3338
+ providerResultPayloads: [],
3339
+ providerStagedPayloadBytes: 0,
3340
+ turnCompletion: void 0,
3341
+ applicationToolCalls: [],
3342
+ applicationCallDescriptors: [],
3343
+ applicationToolResults: [],
3344
+ finished: true,
3345
+ finishReason: "tool-calls",
3346
+ usage: void 0
3347
+ };
3348
+ const declarationByCallId = /* @__PURE__ */ new Map();
3349
+ for (const call of resume.calls) {
3350
+ if (!hasTool(tools, call.name)) return failRunEventStream(ModelProtocolError.make({ message: `Turn resume declared unknown Tool ${call.name}` }));
3351
+ if (trace.toolCalls.has(call.id)) return failRunEventStream(ModelProtocolError.make({ message: `Turn resume repeated Tool Call ID ${call.id}` }));
3352
+ const tool = tools[call.name];
3353
+ const toolCallId = yield* decodeToolCallId(call.id);
3354
+ yield* decodeToolCallParameters(tool, call.name, call.params, "resume");
3355
+ const parameters = yield* decodeEventJson(call.params, "Tool parameters");
3356
+ const providerExecuted = call.providerExecuted === true;
3357
+ declarationByCallId.set(call.id, {
3358
+ index: trace.applicationToolCalls.length,
3359
+ name: call.name,
3360
+ providerExecuted
3361
+ });
3362
+ trace.parts.push(Response.makePart("tool-call", {
3363
+ id: call.id,
3364
+ name: call.name,
3365
+ params: parameters,
3366
+ providerExecuted
3367
+ }));
3368
+ trace.toolCalls.set(call.id, {
3369
+ name: call.name,
3370
+ providerExecuted
3371
+ });
3372
+ if (providerExecuted) continue;
3373
+ trace.applicationToolCalls.push(Response.makePart("tool-call", {
3374
+ id: call.id,
3375
+ name: call.name,
3376
+ params: parameters,
3377
+ providerExecuted: false
3378
+ }));
3379
+ trace.applicationCallDescriptors.push({
3380
+ toolCallId,
3381
+ toolName: call.name,
3382
+ parameters,
3383
+ executionClass: getToolExecutionClass(tool),
3384
+ executionKind: getToolExecutionKind(tool.annotations)
3385
+ });
3386
+ }
3387
+ const completionTool = agent.definition.completion?.tool;
3388
+ const actionCompletionCall = trace.applicationToolCalls.find((call) => agent.definition.completionFromTools?.some((declaration) => declaration.tool === call.name));
3389
+ if ((actionCompletionCall !== void 0 || completionTool !== void 0 && trace.applicationToolCalls.some((call) => call.name === completionTool)) && trace.applicationToolCalls.length !== 1) return failRunEventStream(ModelProtocolError.make({ message: "A completion Tool must be the only application Tool Call in its batch" }));
3390
+ const completionBatch = completionTool !== void 0 && trace.applicationToolCalls.length === 1 && trace.applicationToolCalls[0]?.name === completionTool;
3391
+ if (completionBatch && completionTool !== void 0 && Context.get(tools[completionTool].annotations, ContextRolloverTool) || actionCompletionCall !== void 0 && Context.get(tools[actionCompletionCall.name].annotations, ContextRolloverTool)) return failRunEventStream(ModelProtocolError.make({ message: "A context rollover Tool cannot complete the Run" }));
3392
+ if (context.finalizationUsed && (!completionBatch || trace.toolCalls.size !== 1)) return failRunEventStream(ModelProtocolError.make({ message: "A resumed grace finalization may only execute the completion Tool" }));
3393
+ const settledIds = /* @__PURE__ */ new Set();
3394
+ const providerCallIds = new Set([...declarationByCallId].filter(([, call]) => call.providerExecuted).map(([id]) => id));
3395
+ const settledInputs = yield* snapshotResumedSettledCalls(resume, declarationByCallId.size);
3396
+ for (const settledInput of settledInputs) {
3397
+ const settledCall = yield* decodeResumedSettledCall(settledInput, agent.definition.policy.toolResultBounds.maxBytes, providerCallIds);
3398
+ const declared = declarationByCallId.get(settledCall.id);
3399
+ if (declared === void 0) return failRunEventStream(ModelProtocolError.make({ message: `Turn resume settled an undeclared Tool Call ${settledCall.id}` }));
3400
+ if (settledIds.has(settledCall.id)) return failRunEventStream(ModelProtocolError.make({ message: `Turn resume settled Tool Call ${settledCall.id} more than once` }));
3401
+ settledIds.add(settledCall.id);
3402
+ trace.finalToolResultIds.add(settledCall.id);
3403
+ if (declared.providerExecuted) {
3404
+ trace.parts.push(Response.makePart("tool-result", {
3405
+ id: settledCall.id,
3406
+ name: declared.name,
3407
+ result: settledCall.result,
3408
+ encodedResult: settledCall.result,
3409
+ isFailure: settledCall.isFailure,
3410
+ providerExecuted: true,
3411
+ preliminary: false
3412
+ }));
3413
+ continue;
3414
+ }
3415
+ trace.applicationToolResults[declared.index] = {
3416
+ ...settledCall.toolSelection === void 0 ? {} : { toolSelection: yield* validateSelection(settledCall.toolSelection, agent.definition, context.toolCatalog, false) },
3417
+ id: settledCall.id,
3418
+ name: declared.name,
3419
+ encodedResult: settledCall.result,
3420
+ isFailure: settledCall.isFailure,
3421
+ ...settledCall.budgetRejected === void 0 ? {} : { budgetRejected: settledCall.budgetRejected }
3422
+ };
3423
+ }
3424
+ const policy = agent.definition.policy;
3425
+ const bounds = effectiveRunBounds(policy, options);
3426
+ const toolCalls = countedToolCalls;
3427
+ for (const [id, call] of declarationByCallId) if (call.providerExecuted && !settledIds.has(id)) return failRunEventStream(ModelProtocolError.make({ message: `Turn resume lacks the canonical provider result for ${id}` }));
3428
+ const overToolBudget = toolCalls + context.programmaticToolCalls > bounds.maxToolCalls;
3429
+ if (overToolBudget && policy.onExhaustion === "fail") return failRunEventStream(AgentPolicyError.make({
3430
+ limit: "tool-calls",
3431
+ message: `Agent exceeded its ${bounds.maxToolCalls} Tool Call limit`
3432
+ }));
3433
+ if (turn > bounds.maxTurns && !(policy.onExhaustion === "final-answer" && turn === bounds.maxTurns + 1 && context.finalizationUsed && completionBatch) || policy.onExhaustion === "fail" && turn === bounds.maxTurns && !completionBatch) return failRunEventStream(AgentPolicyError.make({
3434
+ limit: "turns",
3435
+ message: `Agent exceeded its ${bounds.maxTurns} Turn limit`
3436
+ }));
3437
+ const toolkit = yield* agent.definition.toolkit;
3438
+ const concurrency = yield* schedulingConcurrency(agent.definition.policy.toolConcurrency, options.scheduling);
3439
+ const leading = resume.leadingMessages;
3440
+ const resumedPrompt = leading === void 0 || leading.content.length === 0 ? prompt : Prompt.fromMessages([...prompt.content, ...leading.content]);
3441
+ if (resumedPrompt !== prompt) yield* advanceHistory(context, resumedPrompt, options);
3442
+ const started = Stream.fromEffect(Effect.gen(function* () {
3443
+ yield* Effect.logDebug("agent resumed a declared Tool batch").pipe(Effect.annotateLogs({
3444
+ agentId: context.agentId,
3445
+ runId: context.runId,
3446
+ turnId
3447
+ }));
3448
+ return [TurnStarted.make({
3449
+ ...yield* eventBase(context),
3450
+ turnId,
3451
+ turn
3452
+ }), TurnCompleted.make({
3453
+ ...yield* eventBase(context),
3454
+ turnId,
3455
+ turn,
3456
+ finishReason: "tool-calls"
3457
+ })];
3458
+ }).pipe(Effect.withLogSpan("AgentRuntime.resume"))).pipe(Stream.flatMap(Stream.fromIterable));
3459
+ const continueAfterBatch = () => toolBatchContinuation(agent, context, trace, resumedPrompt, turn, toolCalls, options);
3460
+ if (overToolBudget && !(completionBatch && policy.onExhaustion === "final-answer")) {
3461
+ const rejection = yield* settleRejectedBatch(context, turnId, trace, AgentPolicyError.make({
3462
+ limit: "tool-calls",
3463
+ message: `Tool Call budget exhausted: this Run's ${bounds.maxToolCalls} Tool Call limit was reached, so this call was rejected without executing. Do not request more tools; produce your final answer now from the information you already have.`
3464
+ }), settledIds);
3465
+ return started.pipe(Stream.concat(Stream.fromIterable(rejection)), Stream.concat(continueAfterBatch()));
3466
+ }
3467
+ const toolResults = guardBudgetStream(executeToolBatch(context, turnId, turn, toolkit, trace.applicationToolCalls, trace, concurrency, options, {
3468
+ maxToolCalls: bounds.maxToolCalls,
3469
+ declaredToolCalls: toolCalls
3470
+ }, agent.definition.policy.toolResultBounds, settledIds), options.budget);
3471
+ return started.pipe(Stream.concat(toolResults), Stream.concat(continueAfterBatch()));
3472
+ }));
3473
+ const failRunEventStream = (error) => Stream.fail(error);
3474
+ const durationLimitError = (policy) => AgentPolicyError.make({
3475
+ limit: "duration",
3476
+ message: `Agent exceeded its ${Duration.format(policy.maxDuration)} duration limit`
3477
+ });
3478
+ const enforceDurationDeadline = (execution, durationDeadlineMillis, durationLimit) => Stream.unwrap(Effect.gen(function* () {
3479
+ const remaining = durationDeadlineMillis - (yield* Clock.currentTimeMillis);
3480
+ if (remaining <= 0) return Stream.fail(durationLimit);
3481
+ return execution.pipe(Stream.interruptWhen(Effect.sleep(remaining).pipe(Effect.andThen(Effect.fail(durationLimit)))));
3482
+ }));
3483
+ const guardBudgetStream = (stream, budget) => budget === void 0 ? stream : Stream.transformPull(stream, (pull) => Effect.succeed(budget.guard(pull)));
3484
+ function streamWithCompletion(agentValue, input, runOptions = {}, onCompleted, onUsage) {
3485
+ const agent = { definition: "definition" in agentValue ? agentValue.definition : agentValue };
3486
+ const model = "definition" in agentValue ? agentValue.model : void 0;
3487
+ return Stream.unwrap(Effect.gen(function* () {
3488
+ const history = yield* ThreadHistory;
3489
+ const preparation = yield* Effect.serviceOption(RunContextPreparation).pipe(Effect.map(Option.getOrElse(() => RunContextPreparation.of({}))));
3490
+ const authorization = yield* Effect.serviceOption(RunToolAuthorization).pipe(Effect.map(Option.getOrUndefined));
3491
+ const visibility = yield* RunToolVisibility;
3492
+ const ids = yield* IdGenerator$1;
3493
+ const threadId = runOptions.threadId ?? (yield* ids.nextThreadId);
3494
+ const runId = runOptions.runId ?? (yield* ids.nextRunId);
3495
+ const retained = history.retention === "incremental" && runOptions.durability !== void 0 ? void 0 : yield* history.open({
3496
+ threadId,
3497
+ runId
3498
+ });
3499
+ if (history.retention === "on-success" && (runOptions.history !== void 0 || runOptions.onHistory !== void 0 || runOptions.input !== void 0 || runOptions.durability !== void 0 || runOptions.subagent !== void 0 || runOptions.resume !== void 0 || runOptions.resumeUsage !== void 0)) return yield* ThreadHistoryError.make({
3500
+ threadId,
3501
+ reason: "incompatible",
3502
+ message: "Provided history cannot share ownership with explicit history, input queues, or durable recovery hooks"
3503
+ });
3504
+ const initialHistory = runOptions.history ?? retained?.prompt;
3505
+ if (retained !== void 0 && runOptions.history !== void 0) yield* retained.stageHistory(runOptions.history);
3506
+ const options = {
3507
+ ...runOptions,
3508
+ context: runOptions.context ?? preparation.hook,
3509
+ transientContext: runOptions.transientContext ?? preparation.transientContext,
3510
+ toolAuthorization: runOptions.toolAuthorization ?? authorization,
3511
+ threadId,
3512
+ runId,
3513
+ ...retained === void 0 ? {} : {
3514
+ history: initialHistory,
3515
+ onHistory: (next) => retained.stageHistory(next).pipe(Effect.andThen(() => runOptions.onHistory?.(next) ?? Effect.void))
3516
+ }
3517
+ };
3518
+ const programmaticAuthorization = Layer.effect(ProgrammaticToolAuthorization, Effect.gen(function* () {
3519
+ const services = yield* Effect.context();
3520
+ const selected = options.toolAuthorization;
3521
+ return ProgrammaticToolAuthorization.of({ authorize: (request) => selected === void 0 ? Effect.succeed({ _tag: "allowed" }) : provideHookServices(selected.authorize(request), services).pipe(Effect.catchCauseFilter(Cause.findError, (error, cause) => Effect.fail(new BrokerCallFailure(error, cause)))) });
3522
+ }));
3523
+ const interpreted = Stream.unwrap(Effect.gen(function* () {
3524
+ const resumed = options.resume === void 0 ? void 0 : {
3525
+ batch: options.resume,
3526
+ usage: yield* decodeResumeUsage(options.resumeUsage)
3527
+ };
3528
+ const resumeUsage = resumed?.usage ?? (options.resumeUsage === void 0 ? void 0 : yield* decodeResumeUsage(options.resumeUsage));
3529
+ if (resumed !== void 0 && (resumed.usage.committedTurns !== resumed.batch.turn || resumed.usage.toolCalls < resumed.batch.calls.length || resumed.usage.consecutiveToolFailures > resumed.usage.toolCalls - resumed.batch.calls.length)) return yield* ModelProtocolError.make({ message: "Run resume accounting conflicts with the pending Turn and declared Tool Calls" });
3530
+ const attemptStartedAtMillis = yield* Clock.currentTimeMillis;
3531
+ const attemptDeadlineMillis = attemptStartedAtMillis + Duration.toMillis(agent.definition.policy.maxDuration);
3532
+ const durationDeadlineMillis = options.durationDeadline === void 0 ? attemptDeadlineMillis : Math.min(attemptDeadlineMillis, DateTime.toEpochMillis(options.durationDeadline));
3533
+ const startedAtMillis = options.runStartedAt === void 0 ? attemptStartedAtMillis : DateTime.toEpochMillis(options.runStartedAt);
3534
+ const compactor = yield* Effect.serviceOption(ContextCompactor).pipe(Effect.flatMap(Option.match({
3535
+ onSome: Effect.succeed,
3536
+ onNone: () => Effect.provide(ContextCompactor, ContextCompactor.layer)
3537
+ })));
3538
+ const initialToolSelection = options.toolSelection ?? (agent.definition.toolExposure === void 0 ? void 0 : { toolNames: agent.definition.toolExposure.initialToolNames ?? [] });
3539
+ const updateSchema = agent.definition.updates;
3540
+ const updateContext = yield* Effect.context();
3541
+ const context = {
3542
+ validateUpdate: updateSchema === void 0 ? () => Effect.fail(new UpdateError({ reason: "unavailable" })) : (value) => Schema.decodeEffect(updateSchema)(value).pipe(Effect.provide(updateContext), Effect.asVoid, Effect.mapError(() => new UpdateError({ reason: "validation" }))),
3543
+ updates: /* @__PURE__ */ new Map(),
3544
+ updateBytes: 0,
3545
+ updatePermits: yield* Semaphore.make(1),
3546
+ definition: agent.definition,
3547
+ toolSelection: initialToolSelection === void 0 ? void 0 : yield* decodeSelection(initialToolSelection),
3548
+ toolCatalog: [],
3549
+ toolExposure: void 0,
3550
+ toolSchemaTransformer: void 0,
3551
+ agentId: agent.definition.id,
3552
+ threadId,
3553
+ runId,
3554
+ toolFailureObserver: yield* CurrentToolFailureObserver,
3555
+ input: void 0,
3556
+ pendingFollowUps: [],
3557
+ startedAtMillis,
3558
+ durationDeadlineMillis,
3559
+ history: options.history ?? Prompt.empty,
3560
+ modelCalls: resumeUsage?.modelCalls ?? 0,
3561
+ usageStatus: resumeUsage?.usageStatus ?? (resumeUsage === void 0 ? "complete" : "unknown"),
3562
+ pricingStatus: resumeUsage?.pricingStatus ?? (resumeUsage === void 0 ? "complete" : "unknown"),
3563
+ unobservedModelCalls: resumeUsage?.unobservedModelCalls ?? 0,
3564
+ childUsage: new Map((resumeUsage?.children ?? []).map((child) => [child.runId, Effect.succeed(child.report)])),
3565
+ liveChildren: /* @__PURE__ */ new Set(),
3566
+ consecutiveToolFailures: resumeUsage?.consecutiveToolFailures ?? 0,
3567
+ inputTokens: resumeUsage?.inputTokens ?? 0,
3568
+ outputTokens: resumeUsage?.outputTokens ?? 0,
3569
+ lastInputTokens: resumeUsage?.lastInputTokens ?? 0,
3570
+ lastOutputTokens: resumeUsage?.lastOutputTokens ?? 0,
3571
+ costMicrousd: resumeUsage?.costMicrousd ?? 0,
3572
+ lastCostMicrousd: 0,
3573
+ warnedLimits: /* @__PURE__ */ new Set(),
3574
+ finalizing: false,
3575
+ tokenExhausted: false,
3576
+ exhaustedDimension: void 0,
3577
+ compaction: initialCompactionState(),
3578
+ preparedCompactionSource: void 0,
3579
+ compactionTurn: {
3580
+ turn: 0,
3581
+ summaryCalls: 0,
3582
+ applied: /* @__PURE__ */ new Set()
3583
+ },
3584
+ windowId: options.initialContextWindowId ?? contextWindowId(runId, 0),
3585
+ windowTokens: resumeUsage?.lastInputTokens ?? 0,
3586
+ windowContextTokenLimit: agent.definition.policy.contextTokenLimit,
3587
+ pendingContextToolCallId: options.pendingContextToolCallId,
3588
+ bufferLimits: effectiveRunBufferLimits(options.bufferLimits),
3589
+ sequence: 0,
3590
+ toolProgressBytes: 0,
3591
+ programmaticToolCalls: resumeUsage?.programmaticToolCalls ?? 0,
3592
+ finalizationUsed: resumeUsage?.finalizationUsed ?? false,
3593
+ policyReservations: yield* Semaphore.make(1)
3594
+ };
3595
+ onUsage?.(usageReportOf(context));
3596
+ if (resumeUsage !== void 0) {
3597
+ const bounds = effectiveRunBounds(agent.definition.policy, options);
3598
+ if (context.finalizationUsed) context.exhaustedDimension = resumeUsage.committedTurns > bounds.maxTurns ? "turns" : resumeUsage.toolCalls + context.programmaticToolCalls > bounds.maxToolCalls ? "tool-calls" : "tokens";
3599
+ if (agent.definition.policy.onExhaustion === "fail" && resumeUsage.toolCalls + context.programmaticToolCalls > bounds.maxToolCalls) return failRunEventStream(AgentPolicyError.make({
3600
+ limit: "tool-calls",
3601
+ message: `Agent exceeded its ${bounds.maxToolCalls} Tool Call limit`
3602
+ }));
3603
+ const failureLimit = agent.definition.policy.repeatedFailureLimit;
3604
+ if (failureLimit > 0 && context.consecutiveToolFailures >= failureLimit) return failRunEventStream(AgentPolicyError.make({
3605
+ limit: "repeated-failures",
3606
+ message: `Agent reached its ${failureLimit} consecutive Tool Call failure limit`
3607
+ }));
3608
+ const seededCostBudget = agent.definition.policy.costBudgetMicrousd;
3609
+ if (seededCostBudget !== void 0 && context.costMicrousd > seededCostBudget) return failRunEventStream(AgentPolicyError.make({
3610
+ limit: "cost",
3611
+ message: `Agent exceeded its ${seededCostBudget} microdollar cost budget`
3612
+ }));
3613
+ const seededBudget = agent.definition.policy.tokenBudget;
3614
+ if (seededBudget !== void 0 && context.inputTokens + context.outputTokens > seededBudget) {
3615
+ if (agent.definition.policy.onExhaustion === "fail") return failRunEventStream(AgentPolicyError.make({
3616
+ limit: "tokens",
3617
+ message: `Agent exceeded its ${seededBudget} token budget`
3618
+ }));
3619
+ context.tokenExhausted = true;
3620
+ context.exhaustedDimension ??= "tokens";
3621
+ }
3622
+ }
3623
+ if (options.input?.start !== void 0) yield* options.input.start();
3624
+ const started = Stream.fromEffect(Effect.gen(function* () {
3625
+ yield* Metric.update(runCounter, 1);
3626
+ yield* Effect.logDebug("agent run started").pipe(Effect.annotateLogs({
3627
+ agentId: context.agentId,
3628
+ runId: context.runId
3629
+ }));
3630
+ return yield* eventBase(context).pipe(Effect.map((base) => RunStarted.make(base)));
3631
+ }).pipe(Effect.withLogSpan("AgentRuntime.run")));
3632
+ const execution = Stream.unwrap(Effect.gen(function* () {
3633
+ const decodedInput = yield* decodeInput(agent, input);
3634
+ const instructions = yield* evaluateInstructions(agent.definition.instructions, decodedInput);
3635
+ const encodedInput = yield* encodeInput(agent, decodedInput);
3636
+ context.input = encodedInput;
3637
+ if (retained !== void 0) yield* retained.stageInput(encodedInput);
3638
+ const inputPrompt = options.frameworkMessage === void 0 ? yield* renderInputPrompt(agent.definition.inputPrompt, decodedInput, encodedInput) : yield* Schema.encodeEffect(Schema.fromJsonString(FrameworkMessage))(options.frameworkMessage).pipe(Effect.mapError(() => AgentInputError.make({ message: "Invalid worker message" })));
3639
+ const priorHistoryLength = context.history.content.length;
3640
+ const prompt = yield* makeInitialPrompt(instructions, inputPrompt, context.history);
3641
+ if (options.context === void 0) {
3642
+ context.compaction.protectedStart = priorHistoryLength;
3643
+ context.compaction.protectedEnd = prompt.content.length;
3644
+ } else context.preparedCompactionSource = {
3645
+ protectedReferences: options.protectedContext?.content ?? prompt.content.slice(priorHistoryLength),
3646
+ protectedMessages: yield* snapshotCompactionMessages(options.protectedContext?.content ?? prompt.content.slice(priorHistoryLength)),
3647
+ prefix: []
3648
+ };
3649
+ yield* advanceHistory(context, prompt, options);
3650
+ let pending;
3651
+ if (resumed !== void 0) pending = {
3652
+ prompt,
3653
+ turn: resumed.batch.turn,
3654
+ toolCalls: resumed.usage.toolCalls,
3655
+ resume: resumed.batch
3656
+ };
3657
+ else {
3658
+ const steering = yield* drainInputs(context, options);
3659
+ pending = {
3660
+ prompt: yield* appendInputs(context, prompt, steering, options),
3661
+ turn: (resumeUsage?.committedTurns ?? 0) + 1,
3662
+ toolCalls: resumeUsage?.toolCalls ?? 0
3663
+ };
3664
+ }
3665
+ return Stream.fromEffectRepeat(Effect.suspend(() => {
3666
+ const current = pending;
3667
+ pending = void 0;
3668
+ return current === void 0 ? Cause.done() : Effect.succeed(current);
3669
+ })).pipe(Stream.flatMap((request) => request.resume === void 0 ? makeTurn(agent, context, request.prompt, request.turn, request.toolCalls, options) : makeResumeTurn(agent, context, request.prompt, request.resume, request.toolCalls, options)), Stream.filterMapEffect((output) => Effect.sync(() => {
3670
+ if (output._tag === "NextTurn") {
3671
+ pending = output;
3672
+ return Result.fail(void 0);
3673
+ }
3674
+ return Result.succeed(output);
3675
+ })));
3676
+ }));
3677
+ const durationLimit = durationLimitError(agent.definition.policy);
3678
+ const deadline = enforceDurationDeadline(execution, durationDeadlineMillis, durationLimit);
3679
+ const nativeUpdateTool = agent.definition.toolkit.tools.emit_update;
3680
+ const updateHandlers = agent.definition.updates === void 0 || nativeUpdateTool === void 0 ? Context.empty() : yield* Toolkit.make(nativeUpdateTool).toHandlers({ emit_update: (parameters, call) => Effect.gen(function* () {
3681
+ if (call.toolCallId === void 0) return yield* new UpdateError({ reason: "unavailable" });
3682
+ const decoded = yield* Schema.decodeUnknownEffect(Schema.Struct({ value: Schema.Unknown }))(parameters).pipe(Effect.mapError(() => new UpdateError({ reason: "validation" })));
3683
+ const value = yield* Schema.encodeUnknownEffect(agent.definition.updates)(decoded.value).pipe(Effect.flatMap(Schema.decodeUnknownEffect(Schema.Json)), Effect.mapError(() => new UpdateError({ reason: "validation" })));
3684
+ const updateId = yield* Schema.decodeEffect(IdempotencyKey)(`tool:${context.runId}:${call.toolCallId}`).pipe(Effect.mapError(() => new UpdateError({ reason: "validation" })));
3685
+ yield* (yield* Emitter).emit({
3686
+ target: agent.definition,
3687
+ updateId,
3688
+ value
3689
+ });
3690
+ }) });
3691
+ const engineToolServices = Context.make(AgentSpawner, makeAgentSpawner({
3692
+ agentId: context.agentId,
3693
+ threadId: context.threadId,
3694
+ runId: context.runId
3695
+ }, options.delegationDepth ?? options.parentLink?.depth ?? 0, history, preparation, agent.definition.policy, options.subagentGrant, options.subagentBudget, options.subagentBudgetScope, (childRunId, read) => {
3696
+ context.liveChildren.add(childRunId);
3697
+ context.childUsage.set(childRunId, read);
3698
+ })).pipe(Context.add(ContextWindow, { status: Effect.sync(() => {
3699
+ const estimatedTokens = Math.min(Number.MAX_SAFE_INTEGER, context.windowTokens + context.lastOutputTokens);
3700
+ const contextTokenLimit = context.windowContextTokenLimit ?? null;
3701
+ return ContextWindowStatus.make({
3702
+ threadId: context.threadId,
3703
+ runId: context.runId,
3704
+ windowId: context.windowId,
3705
+ estimatedTokens,
3706
+ contextTokenLimit,
3707
+ remainingTokens: contextTokenLimit === null ? null : Math.max(0, contextTokenLimit - estimatedTokens)
3708
+ });
3709
+ }) }), Context.merge(updateHandlers), Context.add(Emitter, { emit: () => Effect.fail(new UpdateError({ reason: "unavailable" })) }), Context.add(CurrentToolCatalog, { entries: [] }), Context.add(RunToolVisibility, visibility), Context.add(RunEventSink, closedRunEventSink), Context.add(DurableStep, closedDurableStep), Context.add(SubagentDurability, closedSubagentDurability), Context.add(SubagentHost, SubagentHost.unavailable), Context.add(MessagingHost, MessagingHost.unavailable), Context.add(CurrentSubagentAuthority, options.subagentGrant === void 0 ? void 0 : {
3710
+ grant: options.subagentGrant,
3711
+ depth: options.delegationDepth ?? options.parentLink?.depth ?? 0
3712
+ }), Context.add(ToolBroker, closedToolBroker));
3713
+ return started.pipe(Stream.concat(deadline), Stream.catch((error) => {
3714
+ return Stream.fromEffect(Effect.gen(function* () {
3715
+ if (error instanceof AgentApprovalPending || error instanceof AgentChildPending) return RunSuspended.make({
3716
+ ...yield* terminalEventBase(context),
3717
+ reason: error.message,
3718
+ ...yield* usageReportOf(context)
3719
+ });
3720
+ return RunFailed.make({
3721
+ ...yield* terminalEventBase(context),
3722
+ ...yield* usageReportOf(context),
3723
+ errorTag: errorTag(error),
3724
+ message: errorMessage(error)
3725
+ });
3726
+ })).pipe(Stream.concat(Stream.fail(error)));
3727
+ }), Stream.withSpan("AgentRuntime.run", { attributes: {
3728
+ agentId: context.agentId,
3729
+ runId: context.runId
3730
+ } }), Stream.provide(engineToolServices), Stream.provideService(ContextCompactor, compactor));
3731
+ }));
3732
+ const finalized = options.input?.end === void 0 ? interpreted : interpreted.pipe(Stream.ensuring(options.input.end()));
3733
+ const events = (model === void 0 ? finalized : finalized.pipe(Stream.provide(model, { local: true }))).pipe(Stream.provide(ToolSpanTelemetry.layer), Stream.provide(programmaticAuthorization));
3734
+ if (retained === void 0 && onCompleted === void 0) return events;
3735
+ let completed;
3736
+ return events.pipe(Stream.filter((event) => {
3737
+ if (event._tag !== "RunCompleted") return true;
3738
+ completed = event;
3739
+ return false;
3740
+ }), Stream.scoped, Stream.concat(Stream.unwrap(Effect.gen(function* () {
3741
+ const terminal = completed;
3742
+ if (terminal === void 0) return yield* ModelProtocolError.make({ message: "Agent stream ended without RunCompleted" });
3743
+ return Stream.fromEffect(Effect.gen(function* () {
3744
+ if (onCompleted !== void 0) yield* onCompleted(terminal);
3745
+ if (retained !== void 0) yield* retained.commit(terminal);
3746
+ return terminal;
3747
+ })).pipe(Stream.catch((error) => Stream.make(RunFailed.make({
3748
+ eventVersion: terminal.eventVersion,
3749
+ threadId: terminal.threadId,
3750
+ runId: terminal.runId,
3751
+ agentId: terminal.agentId,
3752
+ usage: terminal.usage,
3753
+ delegatedUsage: terminal.delegatedUsage,
3754
+ sequence: terminal.sequence,
3755
+ timestamp: terminal.timestamp,
3756
+ errorTag: errorTag(error),
3757
+ message: errorMessage(error)
3758
+ })).pipe(Stream.concat(Stream.fail(error)))));
3759
+ }))));
3760
+ }));
3761
+ }
3762
+ /** Validate the terminal result before the stream commits history and publishes completion. */
3763
+ const reduceRunEvents = (agent, events) => Effect.gen(function* () {
3764
+ let result;
3765
+ yield* Stream.runDrain(events((completed) => Effect.gen(function* () {
3766
+ const candidateOutput = completed.output;
3767
+ const output = yield* Schema.decodeUnknownEffect(agent.definition.output)(candidateOutput).pipe(Effect.mapError((cause) => AgentOutputError.make({ message: cause.message })));
3768
+ const declaration = agent.definition.runDisposition;
3769
+ const runDisposition = completed.runDisposition === void 0 ? void 0 : completed.finishReason === "budget-exhausted" ? yield* ModelProtocolError.make({ message: "A budget-exhausted RunCompleted event cannot declare a run disposition" }) : declaration === void 0 ? yield* ModelProtocolError.make({ message: "RunCompleted declared a run disposition without a definition-owned Schema" }) : yield* decodeRunDisposition(agent, completed.runDisposition);
3770
+ result = {
3771
+ output,
3772
+ threadId: completed.threadId,
3773
+ runId: completed.runId,
3774
+ turns: completed.turns,
3775
+ finishReason: completed.finishReason,
3776
+ ...completed.exhausted !== void 0 ? { exhausted: completed.exhausted } : {},
3777
+ ...runDisposition === void 0 ? {} : { runDisposition: completed.runDisposition },
3778
+ ...completed.usage === void 0 ? {} : { usage: completed.usage },
3779
+ ...completed.delegatedUsage === void 0 ? {} : { delegatedUsage: completed.delegatedUsage }
3780
+ };
3781
+ })));
3782
+ if (result === void 0) return yield* ModelProtocolError.make({ message: "Agent stream ended without RunCompleted" });
3783
+ return result;
3784
+ });
3785
+ /**
3786
+ * Complete execution and close run-owned resources before returning the decoded result.
3787
+ * Caller-contributed requirements, including Scope, remain visible; services supplied by
3788
+ * application Layers retain their application's lifetime.
3789
+ */
3790
+ const runProgram = Effect.fn("AgentRuntime.run")(function* (agent, events) {
3791
+ return yield* reduceRunEvents(agent, events);
3792
+ });
3793
+ const startProgram = Effect.fn("AgentRuntime.start")(function* (agent, events, options) {
3794
+ yield* Scope.Scope;
3795
+ const bufferLimits = Object.freeze(effectiveRunBufferLimits(options.bufferLimits));
3796
+ const executionOptionDescriptors = {
3797
+ ...Object.getOwnPropertyDescriptors(options),
3798
+ bufferLimits: {
3799
+ configurable: false,
3800
+ enumerable: true,
3801
+ value: bufferLimits,
3802
+ writable: false
3803
+ }
3804
+ };
3805
+ const executionOptions = Object.create(Object.getPrototypeOf(options), executionOptionDescriptors);
3806
+ const captured = [];
3807
+ const observationCapacity = bufferLimits.maxRunEvents + 1;
3808
+ const pubsub = yield* PubSub.dropping({
3809
+ capacity: observationCapacity,
3810
+ replay: observationCapacity
3811
+ });
3812
+ yield* Effect.addFinalizer(() => PubSub.shutdown(pubsub));
3813
+ let readUsage = Effect.succeed(RunUsageReport.make({
3814
+ usage: emptyRunTotals(),
3815
+ delegatedUsage: emptyRunTotals()
3816
+ }));
3817
+ const fiber = yield* reduceRunEvents(agent, (onCompleted) => events(executionOptions, onCompleted, (read) => {
3818
+ readUsage = read;
3819
+ }).pipe(Stream.tap((event) => Effect.suspend(() => {
3820
+ captured.push(event);
3821
+ return PubSub.publish(pubsub, [event]);
3822
+ })))).pipe(Effect.onExit(() => Effect.suspend(() => readUsage).pipe(Effect.flatMap((report) => Effect.sync(() => {
3823
+ readUsage = Effect.succeed(report);
3824
+ })))), Effect.ensuring(PubSub.publish(pubsub, Exit.void))).pipe(Effect.forkScoped);
3825
+ return {
3826
+ await: Fiber.join(fiber),
3827
+ events: Fiber.await(fiber).pipe(Effect.andThen(Effect.sync(() => captured.slice()))),
3828
+ observe: Stream.fromPubSubTake(pubsub),
3829
+ usageReport: Effect.suspend(() => readUsage)
3830
+ };
3831
+ });
3832
+ /** Decode external input before instructions or model execution. */
3833
+ const streamUnknown = (agent, input, options) => streamWithCompletion(agent, input, options).pipe(Stream.provide(Layer.mergeAll(ModelUsageAccounting.layerEphemeral, AgentUpdateAcceptance.layerEphemeral)));
3834
+ /**
3835
+ * Host interpreter entry point with Attempt-local usage accounting and update acceptance in R.
3836
+ * Durable coordinators provide these services alongside their recovery hooks;
3837
+ * ordinary callers use streamUnknown's explicit ephemeral composition.
3838
+ */
3839
+ const streamWithUsageAccountingUnknown = (agent, input, options) => streamWithCompletion(agent, input, options);
3840
+ /** Accept schema-encoded input, retaining runtime validation. Use streamUnknown for external data. */
3841
+ const stream = (agent, input, options) => streamUnknown(agent, input, options);
3842
+ function runUnknown(agent, input, options = {}) {
3843
+ const program = "definition" in agent ? agent : { definition: agent };
3844
+ return runProgram(program, (onCompleted) => streamWithCompletion(agent, input, options, onCompleted).pipe(Stream.provide(Layer.mergeAll(ModelUsageAccounting.layerEphemeral, AgentUpdateAcceptance.layerEphemeral))));
3845
+ }
3846
+ /** Accept schema-encoded input, retaining runtime validation. Use runUnknown for external data. */
3847
+ const run = (agent, input, options) => runUnknown(agent, input, options);
3848
+ function startUnknown(agent, input, options = {}) {
3849
+ const program = "definition" in agent ? agent : { definition: agent };
3850
+ return startProgram(program, (executionOptions, onCompleted, onUsage) => streamWithCompletion(agent, input, executionOptions, onCompleted, onUsage).pipe(Stream.provide(Layer.mergeAll(ModelUsageAccounting.layerEphemeral, AgentUpdateAcceptance.layerEphemeral))), options);
3851
+ }
3852
+ /** Accept schema-encoded input, retaining runtime validation. Use startUnknown for external data. */
3853
+ const start = (agent, input, options) => startUnknown(agent, input, options);
3854
+ /**
3855
+ * Fail-closed Run-level `RunEventSink` default. Each Tool batch shadows it
3856
+ * with a live sink; any emission outside an active Tool batch fails with the
3857
+ * same typed error as emitting after a batch settled.
3858
+ */
3859
+ const closedRunEventSink = { emit: (payload) => Effect.fail(RunEventSinkClosedError.make({ message: `Subagent event ${payload._tag} was emitted outside an active Tool batch` })) };
3860
+ /**
3861
+ * Fail-closed Run-level `DurableStep` default. Every executable Tool Call
3862
+ * shadows it with a live per-call service; a Step executed outside an active
3863
+ * Tool Call fails typed instead of silently running unrecorded.
3864
+ */
3865
+ const closedDurableStep = { do: (name) => Effect.fail(DurableStepError.make({
3866
+ stepName: name,
3867
+ reason: "no-active-tool-call",
3868
+ message: "Durable Step was executed outside an active Tool Call"
3869
+ })) };
3870
+ /**
3871
+ * Fail-closed Run-level `ToolBroker` default. Every executable Tool Call
3872
+ * shadows it with a live per-call service bound to that call's identity and
3873
+ * held permit; opening a pass outside an active Tool Call fails typed.
3874
+ */
3875
+ const closedToolBroker = { openPass: () => Effect.fail(ToolBrokerUnavailableError.make({ message: "The programmatic Tool broker was used outside an active Tool Call" })) };
3876
+ const programmaticOutcomeError = (index, tag, message) => ({
3877
+ _tag: "ProgrammaticCallError",
3878
+ index,
3879
+ errorTag: tag,
3880
+ message
3881
+ });
3882
+ /** A call's typed failure captured as a value so defects stay defects. */
3883
+ var BrokerCallFailure = class {
3884
+ error;
3885
+ cause;
3886
+ constructor(error, cause) {
3887
+ this.error = error;
3888
+ this.cause = cause;
3889
+ }
3890
+ };
3891
+ /** Run-owned authorization with typed override failures preserved for broker projection. */
3892
+ var ProgrammaticToolAuthorization = class extends Context.Service()("@effect-agent/engine/internal/ProgrammaticToolAuthorization") {};
3893
+ /**
3894
+ * Measure one started programmatic handler with the same canonical span semantics as a
3895
+ * model-declared handler. A private marker gives value-level failures a failed exported status;
3896
+ * the marker is removed before the broker outcome returns, while an original Effect Cause is
3897
+ * restored unchanged outside the span.
3898
+ */
3899
+ const stripProgrammaticToolSpanFailure = (cause, marker) => {
3900
+ let found = false;
3901
+ const residual = [];
3902
+ for (const reason of cause.reasons) if (Cause.isFailReason(reason)) {
3903
+ if (reason.error === marker) found = true;
3904
+ else residual.push(Cause.makeDieReason(reason.error));
3905
+ } else residual.push(reason);
3906
+ return {
3907
+ found,
3908
+ residual: Cause.fromReasons(residual)
3909
+ };
3910
+ };
3911
+ const measureProgrammaticToolCall = (telemetry, descriptor, effect) => Effect.suspend(() => {
3912
+ const marker = ToolSpanFailure.marker();
3913
+ let terminalResult;
3914
+ let propagatedFailure;
3915
+ const measured = Effect.exit(effect).pipe(Effect.flatMap((exit) => {
3916
+ if (Exit.isFailure(exit)) {
3917
+ if (exit.cause.reasons.length > 0 && exit.cause.reasons.every(Cause.isInterruptReason)) return Effect.failCause(exit.cause);
3918
+ propagatedFailure = exit.cause;
3919
+ return isolateToolDerivative(terminalToolTelemetry(descriptor, "failure", marker, "propagated")).pipe(Effect.andThen(Effect.fail(marker)));
3920
+ }
3921
+ terminalResult = exit.value;
3922
+ const outcome = exit.value._tag === "ProgrammaticCallSuccess" ? "success" : "failure";
3923
+ return isolateToolDerivative(terminalToolTelemetry(descriptor, outcome, outcome === "failure" ? marker : void 0, outcome === "failure" ? "returned-to-caller" : void 0)).pipe(Effect.andThen(outcome === "failure" ? Effect.fail(marker) : Effect.succeed(exit.value)));
3924
+ }), Effect.withSpan(`execute_tool ${descriptor.toolName}`, {
3925
+ kind: "internal",
3926
+ attributes: toolTelemetryAttributes(descriptor)
3927
+ }));
3928
+ return telemetry.isolateEffectSpanLifecycle(measured).pipe(Effect.catchCause((cause) => {
3929
+ const { found, residual } = stripProgrammaticToolSpanFailure(cause, marker);
3930
+ const restored = propagatedFailure === void 0 ? residual : Cause.combine(propagatedFailure, residual);
3931
+ if (!found) return Effect.failCause(restored);
3932
+ if (restored.reasons.length > 0) return Effect.failCause(restored);
3933
+ return terminalResult === void 0 ? Effect.die("Programmatic Tool telemetry completed without a terminal result") : Effect.succeed(terminalResult);
3934
+ }));
3935
+ });
3936
+ const brokerSerializeJson = (value) => {
3937
+ try {
3938
+ const text = JSON.stringify(value);
3939
+ return text === void 0 ? void 0 : {
3940
+ text,
3941
+ bytes: utf8ByteLength(text)
3942
+ };
3943
+ } catch {
3944
+ return;
3945
+ }
3946
+ };
3947
+ const emptyProgrammaticUsage = Response.Usage.make({
3948
+ inputTokens: {},
3949
+ outputTokens: {}
3950
+ });
3951
+ /** Hostile values can throw from trap getters mid-decode; stay fail-closed. */
3952
+ const brokerDecodeJson = (value) => {
3953
+ try {
3954
+ return Schema.decodeUnknownOption(Schema.Json)(value);
3955
+ } catch {
3956
+ return Option.none();
3957
+ }
3958
+ };
3959
+ /**
3960
+ * Live per-outer-call `ToolBroker` (runtime spec §12.1; RUN-016, RUN-017).
3961
+ * The pass executes under the outer Tool Call's already-held scheduling
3962
+ * permit — invocations run in caller-owned structured fibers and acquire a finite
3963
+ * per-pass Semaphore, never the outer batch permit again. Execution indices are
3964
+ * allocated in invocation order before preflight, with gaps for rejected calls,
3965
+ * and every started call consumes the Run's Tool-call budgets before its
3966
+ * handler is invoked. Inner calls produce no Run events and no Canonical
3967
+ * Records. Trusted applications may explicitly observe non-propagating failures (RUN-036).
3968
+ */
3969
+ const makeToolBrokerService = Effect.fnUntraced(function* (binding) {
3970
+ const toolSpanTelemetry = yield* ToolSpanTelemetry;
3971
+ const authorization = yield* ProgrammaticToolAuthorization;
3972
+ const lifecycle = { closed: false };
3973
+ const observer = binding.context.toolFailureObserver;
3974
+ const preflightObserver = observer === void 0 ? void 0 : {
3975
+ observer,
3976
+ permits: Semaphore.makeUnsafe(1)
3977
+ };
3978
+ return {
3979
+ service: { openPass: (toolkit, passOptions) => Effect.gen(function* () {
3980
+ const inheritedAuthority = yield* CurrentSubagentAuthority;
3981
+ if (lifecycle.closed) return yield* ToolBrokerUnavailableError.make({ message: "The outer Tool Call for this broker has already settled" });
3982
+ if (passOptions === void 0 || !Number.isSafeInteger(passOptions.maxResultBytes) || passOptions.maxResultBytes <= 0) return yield* ToolBrokerConfigurationError.make({ message: `maxResultBytes must be a positive safe integer; received ${String(passOptions?.maxResultBytes)}` });
3983
+ const handlerServices = yield* Effect.context();
3984
+ const concurrency = passOptions.concurrency ?? 4;
3985
+ if (!Number.isSafeInteger(concurrency) || concurrency < 1 || concurrency > 64) return yield* ToolBrokerConfigurationError.make({ message: "concurrency must be an integer between 1 and 64" });
3986
+ const permits = yield* Semaphore.make(concurrency);
3987
+ const records = [];
3988
+ const preflightFailure = (input, kind, tag, message, cause) => {
3989
+ const outcome = programmaticOutcomeError(void 0, tag, message);
3990
+ if (preflightObserver === void 0) return Effect.succeed(outcome);
3991
+ return deliverToolFailure(preflightObserver.observer, {
3992
+ _tag: "ProgrammaticPreflightFailure",
3993
+ agentId: binding.context.agentId,
3994
+ threadId: binding.context.threadId,
3995
+ runId: binding.context.runId,
3996
+ turnId: binding.turnId,
3997
+ parentToolCallId: binding.outerToolCallId,
3998
+ toolName: input.toolName,
3999
+ ...hasTool(toolkit.tools, input.toolName) ? { executionClass: getToolExecutionClass(toolkit.tools[input.toolName]) } : {},
4000
+ kind,
4001
+ tag,
4002
+ message: toolFailureMessage(message),
4003
+ ...cause === void 0 ? {} : { cause }
4004
+ }).pipe(preflightObserver.permits.withPermits(1), Effect.as(outcome));
4005
+ };
4006
+ const body = (input, sequenceIndex) => Effect.gen(function* () {
4007
+ if (!hasTool(toolkit.tools, input.toolName)) return yield* preflightFailure(input, "infrastructure", "ProgrammaticToolUnknownError", `Tool ${input.toolName} is not part of this pass's allowlisted Toolkit`);
4008
+ const tool = toolkit.tools[input.toolName];
4009
+ if (Object.values(binding.context.definition.toolkit.tools).some((outer) => Context.get(outer.annotations, AdditionalToolCatalog).some((entry) => entry.tool.name === input.toolName)) && !binding.context.toolCatalog.some((entry) => entry.kind === "code-mode" && entry.tool.name === input.toolName)) return yield* preflightFailure(input, "infrastructure", "ProgrammaticToolAuthorizationDenied", "Tool is excluded by the current host visibility policy");
4010
+ if (!isSubagentToolAllowed(inheritedAuthority?.grant, inheritedAuthority?.depth ?? 0, input.toolName, tool.annotations)) return yield* preflightFailure(input, "infrastructure", "ProgrammaticToolAuthorizationDenied", "Tool exceeds the inherited subagent grant");
4011
+ if (Context.get(tool.annotations, ContextRolloverTool)) return yield* preflightFailure(input, "infrastructure", "ProgrammaticContextRolloverUnsupportedError", "Context rollover requires a direct, singleton model Tool Call");
4012
+ const approval = tool.needsApproval;
4013
+ if (approval !== void 0 && approval !== false) return yield* preflightFailure(input, "infrastructure", "ProgrammaticApprovalUnsupportedError", `Tool ${input.toolName} requires approval; approval-requiring Tools never start programmatically in the ephemeral slice`);
4014
+ const invalidParameters = yield* Schema.decodeUnknownEffect(tool.parametersSchema)(input.encodedArguments).pipe(Effect.map(() => void 0), Effect.catchCauseFilter(Cause.findError, (error, cause) => preflightFailure(input, "protocol", "ModelProtocolError", `Invalid parameters for Tool ${input.toolName}: ${error.message}`, cause)));
4015
+ if (invalidParameters !== void 0) return invalidParameters;
4016
+ const handleId = ToolCallId.make(`${binding.outerToolCallId}#${sequenceIndex}`);
4017
+ const denied = yield* authorization.authorize({
4018
+ threadId: binding.context.threadId,
4019
+ runId: binding.context.runId,
4020
+ turnId: binding.turnId,
4021
+ turn: binding.turn,
4022
+ input: binding.context.input,
4023
+ programmatic: {
4024
+ parentToolCallId: binding.outerToolCallId,
4025
+ sequenceIndex
4026
+ },
4027
+ call: {
4028
+ toolCallId: handleId,
4029
+ toolName: input.toolName,
4030
+ parameters: input.encodedArguments,
4031
+ executionClass: getToolExecutionClass(tool),
4032
+ executionKind: getToolExecutionKind(tool.annotations)
4033
+ }
4034
+ }).pipe(Effect.flatMap((decision) => decision._tag === "allowed" ? Effect.succeed(void 0) : preflightFailure(input, "infrastructure", "ProgrammaticToolAuthorizationDenied", decision.reason)), Effect.catch((failure) => preflightFailure(input, "infrastructure", errorTag(failure.error), errorMessage(failure.error), failure.cause)));
4035
+ if (denied !== void 0) return denied;
4036
+ const rejected = yield* binding.context.policyReservations.withPermit(Effect.gen(function* () {
4037
+ if (binding.declaredToolCalls + binding.context.programmaticToolCalls + 1 > binding.maxToolCalls) return yield* preflightFailure(input, "infrastructure", "AgentPolicyError", `Agent exceeded its ${binding.maxToolCalls} Tool Call limit`);
4038
+ if (binding.budget !== void 0) {
4039
+ const exhausted = yield* provideHookServices(binding.budget.consume({
4040
+ modelCalls: 0,
4041
+ inputTokens: 0,
4042
+ outputTokens: 0,
4043
+ totalTokens: 0,
4044
+ toolCalls: 1,
4045
+ costMicrousd: 0,
4046
+ usage: emptyProgrammaticUsage
4047
+ }), binding.hookServices).pipe(Effect.map(() => void 0), Effect.catchCauseFilter(Cause.findError, (error, cause) => Effect.succeed({
4048
+ error,
4049
+ cause
4050
+ })));
4051
+ if (exhausted !== void 0) return yield* preflightFailure(input, "infrastructure", errorTag(exhausted.error), errorMessage(exhausted.error), exhausted.cause);
4052
+ }
4053
+ binding.context.programmaticToolCalls += 1;
4054
+ if (binding.reservePolicyUsage !== void 0) return yield* provideHookServices(binding.reservePolicyUsage({
4055
+ programmaticToolCalls: binding.context.programmaticToolCalls,
4056
+ finalizationUsed: binding.context.finalizationUsed
4057
+ }), binding.hookServices).pipe(Effect.as(void 0), Effect.catchCauseFilter(Cause.findError, (error, cause) => preflightFailure(input, "infrastructure", errorTag(error), errorMessage(error), cause)));
4058
+ }));
4059
+ if (rejected !== void 0) return rejected;
4060
+ const index = sequenceIndex;
4061
+ records[sequenceIndex] = {
4062
+ sequenceIndex,
4063
+ toolName: input.toolName,
4064
+ status: "uncertain"
4065
+ };
4066
+ const executionClass = getToolExecutionClass(tool);
4067
+ let failureObservation;
4068
+ const startedFailure = (kind, tag, message) => {
4069
+ const outcome = programmaticOutcomeError(index, tag, message);
4070
+ if (observer === void 0) return Effect.succeed(outcome);
4071
+ failureObservation = {
4072
+ _tag: "ProgrammaticToolFailure",
4073
+ agentId: binding.context.agentId,
4074
+ threadId: binding.context.threadId,
4075
+ runId: binding.context.runId,
4076
+ turnId: binding.turnId,
4077
+ toolCallId: handleId,
4078
+ parentToolCallId: binding.outerToolCallId,
4079
+ sequenceIndex: index,
4080
+ toolName: input.toolName,
4081
+ executionClass,
4082
+ kind,
4083
+ tag,
4084
+ message: toolFailureMessage(message)
4085
+ };
4086
+ return Effect.succeed(outcome);
4087
+ };
4088
+ const telemetryDescriptor = {
4089
+ context: binding.context,
4090
+ turnId: binding.turnId,
4091
+ toolCallId: handleId,
4092
+ toolName: input.toolName,
4093
+ executionClass,
4094
+ invocationKind: "programmatic",
4095
+ failureMode: tool.failureMode,
4096
+ parentToolCallId: binding.outerToolCallId,
4097
+ sequenceIndex: index
4098
+ };
4099
+ const recorded = measureProgrammaticToolCall(toolSpanTelemetry, telemetryDescriptor, Effect.gen(function* () {
4100
+ yield* Effect.logDebug("agent programmatic tool handler started").pipe(Effect.annotateLogs({
4101
+ agentId: binding.context.agentId,
4102
+ runId: binding.context.runId,
4103
+ turnId: binding.turnId,
4104
+ toolCallId: handleId,
4105
+ parentToolCallId: binding.outerToolCallId,
4106
+ toolName: input.toolName,
4107
+ sequenceIndex: index
4108
+ }));
4109
+ yield* Metric.update(toolCounter, 1);
4110
+ let terminal;
4111
+ let resultAfterTerminal = false;
4112
+ const handlerFailed = yield* Stream.unwrap(toolSpanTelemetry.isolateToolkitHandle(toolkit.handle(input.toolName, input.encodedArguments, handleId))).pipe(Stream.runForEach((result) => Effect.sync(() => {
4113
+ if (terminal !== void 0) {
4114
+ resultAfterTerminal = true;
4115
+ return;
4116
+ }
4117
+ if (!result.preliminary) terminal = {
4118
+ encodedResult: result.encodedResult,
4119
+ isFailure: result.isFailure,
4120
+ tag: observer === void 0 || !result.isFailure ? void 0 : errorTag(result.result)
4121
+ };
4122
+ })), Effect.map(() => void 0), Effect.catchCauseFilter(Cause.findError, (error, cause) => Effect.succeed(new BrokerCallFailure(error, cause))));
4123
+ if (handlerFailed instanceof BrokerCallFailure) {
4124
+ const tag = errorTag(handlerFailed.error);
4125
+ if (observer !== void 0) failureObservation = {
4126
+ _tag: "ProgrammaticToolFailure",
4127
+ agentId: binding.context.agentId,
4128
+ threadId: binding.context.threadId,
4129
+ runId: binding.context.runId,
4130
+ turnId: binding.turnId,
4131
+ toolCallId: handleId,
4132
+ parentToolCallId: binding.outerToolCallId,
4133
+ sequenceIndex: index,
4134
+ toolName: input.toolName,
4135
+ executionClass,
4136
+ kind: "handler-error",
4137
+ tag,
4138
+ cause: handlerFailed.cause
4139
+ };
4140
+ return programmaticOutcomeError(index, tag, errorMessage(handlerFailed.error));
4141
+ }
4142
+ if (resultAfterTerminal) return yield* startedFailure("protocol", "ModelProtocolError", `Tool Call ${handleId} produced more than one terminal result`);
4143
+ if (terminal === void 0) return yield* startedFailure("protocol", "ModelProtocolError", `Tool Call ${handleId} completed without a terminal result`);
4144
+ if (terminal.isFailure) {
4145
+ if (observer !== void 0) failureObservation = {
4146
+ _tag: "ProgrammaticToolFailure",
4147
+ agentId: binding.context.agentId,
4148
+ threadId: binding.context.threadId,
4149
+ runId: binding.context.runId,
4150
+ turnId: binding.turnId,
4151
+ toolCallId: handleId,
4152
+ parentToolCallId: binding.outerToolCallId,
4153
+ sequenceIndex: index,
4154
+ toolName: input.toolName,
4155
+ executionClass,
4156
+ kind: "declared-failure",
4157
+ tag: terminal.tag ?? "UnknownError"
4158
+ };
4159
+ return {
4160
+ _tag: "ProgrammaticCallFailure",
4161
+ index,
4162
+ encodedResult: terminal.encodedResult
4163
+ };
4164
+ }
4165
+ if (Option.isNone(brokerDecodeJson(terminal.encodedResult))) return yield* startedFailure("protocol", "ModelProtocolError", `Tool ${input.toolName} produced a success encoding outside JSON`);
4166
+ let encodedResult = terminal.encodedResult;
4167
+ if (passOptions.redactResult !== void 0) {
4168
+ const redacted = brokerDecodeJson(yield* passOptions.redactResult(encodedResult));
4169
+ if (Option.isNone(redacted)) return yield* startedFailure("protocol", "ModelProtocolError", `The redacted result for Tool ${input.toolName} is outside the JSON surface`);
4170
+ encodedResult = redacted.value;
4171
+ }
4172
+ const snapshot = brokerSerializeJson(encodedResult);
4173
+ if (snapshot === void 0 || snapshot.bytes > passOptions.maxResultBytes) return yield* startedFailure("infrastructure", "ProgrammaticResultLimitError", `Tool ${input.toolName} result of ${snapshot?.bytes ?? "unencodable"} bytes exceeds the ${passOptions.maxResultBytes}-byte broker bound`);
4174
+ const owned = Schema.decodeOption(Schema.fromJsonString(Schema.Json))(snapshot.text);
4175
+ if (Option.isNone(owned)) return yield* startedFailure("protocol", "ModelProtocolError", `Tool ${input.toolName} produced a success encoding outside JSON`);
4176
+ return {
4177
+ _tag: "ProgrammaticCallSuccess",
4178
+ index,
4179
+ encodedResult: owned.value
4180
+ };
4181
+ })).pipe(Effect.tap((outcome) => Effect.sync(() => {
4182
+ records[sequenceIndex] = {
4183
+ sequenceIndex,
4184
+ toolName: input.toolName,
4185
+ status: outcome._tag === "ProgrammaticCallSuccess" ? "succeeded" : outcome._tag === "ProgrammaticCallFailure" ? "failed" : "uncertain",
4186
+ ...outcome._tag === "ProgrammaticCallError" ? { errorTag: outcome.errorTag } : {}
4187
+ };
4188
+ })));
4189
+ return yield* observer === void 0 ? recorded : recorded.pipe(Effect.tap(() => failureObservation === void 0 ? Effect.void : deliverToolFailure(observer, failureObservation)));
4190
+ }).pipe(Effect.provideContext(handlerServices));
4191
+ return {
4192
+ snapshot: Effect.sync(() => records.map((record) => ({ ...record }))),
4193
+ invoke: (input) => Effect.suspend(() => {
4194
+ const sequenceIndex = records.length;
4195
+ records.push({
4196
+ sequenceIndex,
4197
+ toolName: input.toolName,
4198
+ status: "not-started"
4199
+ });
4200
+ return permits.withPermit(Effect.suspend(() => lifecycle.closed ? preflightFailure(input, "infrastructure", "ToolBrokerUnavailableError", "The outer Tool Call for this pass has already settled") : body(input, sequenceIndex))).pipe(Effect.tap((outcome) => Effect.sync(() => {
4201
+ if (outcome._tag === "ProgrammaticCallError" && outcome.index === void 0) records[sequenceIndex] = {
4202
+ sequenceIndex,
4203
+ toolName: input.toolName,
4204
+ status: "not-started",
4205
+ errorTag: outcome.errorTag
4206
+ };
4207
+ })));
4208
+ })
4209
+ };
4210
+ }) },
4211
+ close: () => {
4212
+ lifecycle.closed = true;
4213
+ }
4214
+ };
4215
+ });
4216
+ /**
4217
+ * Ephemeral pass-through `DurableStep` provided when `RunOptions.durability`
4218
+ * is absent: each Step body executes exactly once in-process and nothing is
4219
+ * recorded. Durable Tools stay runnable on the ephemeral runtime with honest
4220
+ * (weaker) semantics — the durable claim attaches to the runtime, not the
4221
+ * Tool. Duplicate Step names remain the same typed identity conflict as under
4222
+ * the durable service so authoring bugs fail identically on both runtimes.
4223
+ */
4224
+ const passthroughDurableStep = () => {
4225
+ const usedNames = /* @__PURE__ */ new Set();
4226
+ return { do: (name, _output, execute) => Effect.suspend(() => {
4227
+ if (usedNames.has(name)) return Effect.fail(DurableStepError.make({
4228
+ stepName: name,
4229
+ reason: "duplicate-step-name",
4230
+ message: "Durable Step name was reused within one Tool Call"
4231
+ }));
4232
+ usedNames.add(name);
4233
+ return execute;
4234
+ }) };
4235
+ };
4236
+ /**
4237
+ * Durable `DurableStep` service bound to one Tool Call over the coordinator's
4238
+ * `RunStepHook`.
4239
+ *
4240
+ * Semantics per durability §11: a committed result decodes through the
4241
+ * declared output Schema and returns without executing the body
4242
+ * (exactly-once-recorded); otherwise the body runs (at-least-once-executed —
4243
+ * a crash mid-body re-executes on the next Attempt and duplicate external
4244
+ * effects stay observable), the success is encoded through the Schema, and
4245
+ * only then committed. Failures are never recorded: a failing body fails the
4246
+ * Step call into the handler's error channel and re-entry re-executes it.
4247
+ * Step names must be deterministic and unique within one Tool Call; reuse is
4248
+ * a typed identity conflict because the second call would silently replay the
4249
+ * first call's recorded result. Hook failures and codec conflicts surface as
4250
+ * `DurableStepError` without widening the handler's error channel.
4251
+ */
4252
+ /**
4253
+ * Provide a captured hook Context to a hook effect. TypeScript cannot reduce
4254
+ * the deferred conditional `Exclude<HookRequirements, HookRequirements>` on
4255
+ * an unresolved generic, so this private assertion pins the identity that
4256
+ * providing `Context<R>` to an `Effect<_, _, R>` leaves no requirements; it
4257
+ * never bypasses validation.
4258
+ */
4259
+ const provideHookServices = (effect, services) => effect.pipe(Effect.provideContext(services));
4260
+ const makeDurableStepService = (toolCallId, hook, hookServices) => {
4261
+ const usedNames = /* @__PURE__ */ new Set();
4262
+ return { do: (name, output, execute) => Effect.gen(function* () {
4263
+ if (usedNames.has(name)) return yield* DurableStepError.make({
4264
+ toolCallId,
4265
+ stepName: name,
4266
+ reason: "duplicate-step-name",
4267
+ message: "Durable Step name was reused within one Tool Call"
4268
+ });
4269
+ usedNames.add(name);
4270
+ const key = {
4271
+ toolCallId,
4272
+ stepName: name
4273
+ };
4274
+ const recorded = yield* provideHookServices(hook.lookup(key), hookServices).pipe(Effect.mapError((cause) => DurableStepError.make({
4275
+ toolCallId,
4276
+ stepName: name,
4277
+ reason: "lookup-failed",
4278
+ message: "Durable Step lookup failed",
4279
+ cause
4280
+ })));
4281
+ if (Option.isSome(recorded)) return yield* Schema.decodeUnknownEffect(output)(recorded.value.encodedOutput).pipe(Effect.mapError(() => DurableStepError.make({
4282
+ toolCallId,
4283
+ stepName: name,
4284
+ reason: "recorded-result-invalid",
4285
+ message: "Recorded Durable Step result failed the declared output Schema"
4286
+ })));
4287
+ const value = yield* execute;
4288
+ const encodedOutput = yield* Schema.encodeEffect(output)(value).pipe(Effect.mapError(() => DurableStepError.make({
4289
+ toolCallId,
4290
+ stepName: name,
4291
+ reason: "output-encoding-failed",
4292
+ message: "Durable Step output failed the declared output Schema"
4293
+ })));
4294
+ yield* provideHookServices(hook.commit(key, encodedOutput), hookServices).pipe(Effect.mapError((cause) => DurableStepError.make({
4295
+ toolCallId,
4296
+ stepName: name,
4297
+ reason: "commit-failed",
4298
+ message: "Durable Step commit failed",
4299
+ cause
4300
+ })));
4301
+ return value;
4302
+ }) };
4303
+ };
4304
+ /**
4305
+ * Typed engine-owned suspension signal raised by a delegation Tool handler
4306
+ * through the per-batch `SubagentDurability` service when its durable child
4307
+ * is established but not settled (S2 plan §2). It is NOT a Tool failure: the
4308
+ * batch executor treats the raising call as "stays open" — no terminal
4309
+ * result, no `ToolCallFailed`, no batch failure policy, no sibling
4310
+ * interruption — and terminates the Run with `AgentChildPending` after every
4311
+ * non-waiting sibling handler settled.
4312
+ */
4313
+ var ToolCallWaiting = class extends Schema.TaggedError()("ToolCallWaiting", {
4314
+ toolCallId: ToolCallId,
4315
+ childThreadId: ThreadId,
4316
+ childSubmissionId: SubmissionId,
4317
+ childRunId: RunId,
4318
+ receiptId: ReceiptId,
4319
+ message: Schema.String
4320
+ }) {};
4321
+ /**
4322
+ * The Run suspended `waitingForChild`: at least one durable delegation call
4323
+ * of the last Tool batch is waiting on its attached child.
4324
+ * Mirrors `AgentApprovalPending`: the engine emits
4325
+ * `RunSuspended` and then fails the Run stream with this error; the durable
4326
+ * coordinator catches it and ends the Attempt's ownership period without
4327
+ * settling. `children` is listed in declaration order, deterministically.
4328
+ */
4329
+ var AgentChildPending = class extends Schema.TaggedError()("AgentChildPending", {
4330
+ children: Schema.NonEmptyArray(Schema.Struct({
4331
+ toolCallId: ToolCallId,
4332
+ childThreadId: ThreadId,
4333
+ childSubmissionId: SubmissionId,
4334
+ childRunId: RunId
4335
+ })),
4336
+ message: Schema.String
4337
+ }) {};
4338
+ /**
4339
+ * Typed failure of the engine-provided `SubagentDurability` operations.
4340
+ * `hook-failed` wraps a coordinator hook failure without leaking the hook's
4341
+ * error type into handler signatures (the `DurableStepError` precedent);
4342
+ * `no-active-tool-batch` is the fail-closed Run-level default — establishment
4343
+ * outside an active Tool batch never silently degrades to ephemeral spawning.
4344
+ */
4345
+ var SubagentDurabilityError = class extends Schema.TaggedError()("SubagentDurabilityError", {
4346
+ operation: Schema.Literals([
4347
+ "establish",
4348
+ "join",
4349
+ "waiting"
4350
+ ]),
4351
+ reason: Schema.Literals(["hook-failed", "no-active-tool-batch"]),
4352
+ message: Schema.String.check(Schema.isMaxLength(4096)),
4353
+ toolCallId: Schema.optionalKey(ToolCallId),
4354
+ /** Diagnostic cause for the live Effect only; Run events retain the fixed public message. */
4355
+ cause: Schema.optionalKey(Schema.Defect())
4356
+ }) {};
4357
+ /**
4358
+ * Engine-owned durable-Subagent seam provided locally to every Tool batch,
4359
+ * constructed from `RunOptions.subagent` when present and the explicit
4360
+ * ephemeral-mode default when absent. Like the other engine-provided Tool
4361
+ * services it is excluded from the runtime's public requirements and MUST NOT
4362
+ * be satisfied from an application Layer; handlers resolve it per call (the
4363
+ * S1 innermost re-provide pattern) so a Layer built inside another Run's
4364
+ * batch never captures a stale mode.
4365
+ */
4366
+ var SubagentDurability = class extends Context.Service()("@effect-agent/engine/SubagentDurability") {};
4367
+ /** The one explicit ephemeral-mode value: absence of a durable coordinator is stated, not inferred. */
4368
+ const ephemeralSubagentDurability = { mode: "ephemeral" };
4369
+ const closedSubagentDurabilityFailure = (operation, toolCallId) => SubagentDurabilityError.make({
4370
+ operation,
4371
+ reason: "no-active-tool-batch",
4372
+ message: `Durable Subagent ${operation} was invoked outside an active Tool batch`,
4373
+ ...toolCallId === void 0 ? {} : { toolCallId }
4374
+ });
4375
+ /**
4376
+ * Fail-closed Run-level `SubagentDurability` default. Each Tool batch shadows
4377
+ * it with its live per-batch service; resolving the seam outside an active
4378
+ * Tool batch fails typed instead of silently spawning an ephemeral child
4379
+ * under a durable coordinator.
4380
+ */
4381
+ const closedSubagentDurability = {
4382
+ mode: "durable",
4383
+ establish: (request) => Effect.fail(closedSubagentDurabilityFailure("establish", request.toolCallId)),
4384
+ join: (request) => Effect.fail(closedSubagentDurabilityFailure("join", request.toolCallId)),
4385
+ waiting: (toolCallId) => Effect.fail(closedSubagentDurabilityFailure("waiting", toolCallId))
4386
+ };
4387
+ /**
4388
+ * Durable `SubagentDurability` service bound to one Tool batch over the
4389
+ * coordinator's `RunSubagentHook`. Hook failures surface as typed
4390
+ * `SubagentDurabilityError` values without widening handler error channels
4391
+ * (the coordinator keeps its own halt side channel, exactly like the Step
4392
+ * hook); `waiting` constructs the engine-owned `ToolCallWaiting` signal so a
4393
+ * handler can never counterfeit a foreign child identity shape.
4394
+ */
4395
+ const makeSubagentDurabilityService = (hook, hookServices) => ({
4396
+ mode: "durable",
4397
+ establish: (request) => provideHookServices(hook.establish(request), hookServices).pipe(Effect.mapError((cause) => SubagentDurabilityError.make({
4398
+ operation: "establish",
4399
+ reason: "hook-failed",
4400
+ toolCallId: request.toolCallId,
4401
+ message: "Durable child establishment failed",
4402
+ cause
4403
+ }))),
4404
+ join: (request) => provideHookServices(hook.join(request), hookServices).pipe(Effect.mapError((cause) => SubagentDurabilityError.make({
4405
+ operation: "join",
4406
+ reason: "hook-failed",
4407
+ toolCallId: request.toolCallId,
4408
+ message: "Durable child join failed",
4409
+ cause
4410
+ }))),
4411
+ waiting: (toolCallId, child) => Effect.fail(ToolCallWaiting.make({
4412
+ toolCallId,
4413
+ childThreadId: child.childThreadId,
4414
+ childSubmissionId: child.childSubmissionId,
4415
+ childRunId: child.childRunId,
4416
+ receiptId: child.receiptId,
4417
+ message: `Tool Call ${toolCallId} is waiting on durable attached child ${child.childSubmissionId}`
4418
+ }))
4419
+ });
4420
+ /**
4421
+ * Extract the waiting suspension signal from a handler cause. It normally
4422
+ * travels as a typed failure through the native `Toolkit.handle` error
4423
+ * channel; the squash fallback also recognizes it inside a defect so a
4424
+ * wrapped signal still suspends instead of manufacturing a Tool failure.
4425
+ */
4426
+ const waitingFromCause = (cause) => {
4427
+ const failure = Cause.findErrorOption(cause);
4428
+ if (Option.isSome(failure) && failure.value instanceof ToolCallWaiting) return failure.value;
4429
+ const squashed = Cause.squash(cause);
4430
+ return squashed instanceof ToolCallWaiting ? squashed : void 0;
4431
+ };
4432
+ /**
4433
+ * Run one child Agent Binding through the same interpreter as a top-level
4434
+ * Run.
4435
+ *
4436
+ * The spawner allocates a fresh child `ThreadId` and `RunId` through
4437
+ * `IdGenerator` (guaranteeing a fresh child Thread per invocation, with
4438
+ * no Thread reuse), constructs the immutable Parent Link at
4439
+ * `depth + 1`, and starts the child eagerly with `AgentRuntime.start` inside
4440
+ * the caller-provided Scope, so parent interruption always reaches the child
4441
+ * and its finalizers. Preflight policy (including S1's normative
4442
+ * subtree reservation and inherited-grant checks) belongs to the delegation capability and runs
4443
+ * before `spawn` is called. Children inherit the parent Run's provided history and context
4444
+ * services; delegation handlers do not select separate host policies.
4445
+ */
4446
+ const spawnWithParent = (parent, depth, history, preparation, onChild) => Effect.fn("AgentSpawner.spawn")(function* (binding, input, delegation, options) {
4447
+ const ids = yield* IdGenerator$1;
4448
+ const threadId = yield* ids.nextThreadId;
4449
+ const runId = yield* ids.nextRunId;
4450
+ const childDepth = yield* Schema.decodeEffect(DelegationDepth)(depth + 1).pipe(Effect.orDie);
4451
+ const parentLink = SubagentParentLink.make({
4452
+ delegationId: delegation.delegationId,
4453
+ parentAgentId: parent.agentId,
4454
+ parentThreadId: parent.threadId,
4455
+ parentRunId: parent.runId,
4456
+ parentToolCallId: delegation.parentToolCallId,
4457
+ depth: childDepth
4458
+ });
4459
+ const child = yield* startUnknown(binding, input, {
4460
+ ...options,
4461
+ threadId,
4462
+ runId,
4463
+ parentLink
4464
+ }).pipe(Effect.provide(Context.make(ThreadHistory, history).pipe(Context.add(RunContextPreparation, preparation))));
4465
+ onChild(runId, child.usageReport);
4466
+ return {
4467
+ ...child,
4468
+ threadId,
4469
+ runId,
4470
+ parentLink
4471
+ };
4472
+ });
4473
+ /**
4474
+ * Engine-owned service contract through which a declared delegation Tool
4475
+ * runs an Attached Child on the same interpreter.
4476
+ *
4477
+ * The engine provides this service locally to every Run, bound to the Run's
4478
+ * immutable identity and delegation depth; it is never satisfied from an
4479
+ * application Layer, is excluded from the runtime's public requirements, and
4480
+ * exposes neither the engine's mutable Run state nor any root Layer Context.
4481
+ */
4482
+ var AgentSpawner = class extends Context.Service()("@effect-agent/engine/AgentSpawner") {};
4483
+ const makeAgentSpawner = (parent, depth, history, preparation, policy, grant, budget, budgetScope, onChild = () => {}) => ({
4484
+ ...grant === void 0 ? {} : { grant },
4485
+ ...budget === void 0 ? {} : { budget },
4486
+ ...budgetScope === void 0 ? {} : { budgetScope },
4487
+ policy,
4488
+ depth,
4489
+ parent,
4490
+ spawn: spawnWithParent(parent, depth, history, preparation, onChild)
4491
+ });
4492
+ /** Bound applied to the rendered defect message of `withTerminalDefectEvent` (SEC-013). */
4493
+ const DEFECT_MESSAGE_LIMIT = 2048;
4494
+ /**
4495
+ * Opt-in boundary combinator (P7 §7(h), decision point 8): the engine keeps defects as
4496
+ * defects — `RunFailed` covers EXPECTED failures only, and a defect still fails the event
4497
+ * stream with its full Cause (AGENTS.md: errors are never silently widened, and a defect is
4498
+ * never converted into a typed failure by default). A host boundary that forwards Run Events
4499
+ * to a UI or transport can wrap the stream with this helper to append ONE bounded terminal
4500
+ * `RunFailed { errorTag: "Defect" }` event before the original cause is rethrown, so a viewer
4501
+ * always observes a terminal event even when the Run dies.
4502
+ *
4503
+ * Event contract:
4504
+ *
4505
+ * - typed failures and interruptions pass through untouched — the engine already emitted
4506
+ * their terminal event, so nothing is duplicated;
4507
+ * - a cause carrying a defect first emits `RunFailed` with `errorTag: "Defect"` and a
4508
+ * bounded string rendering of the defect (never the raw value; hosts owning stricter
4509
+ * redaction apply it downstream), then RETHROWS the original cause unchanged;
4510
+ * - identity fields come from the last event already streamed (`sequence` advances by one);
4511
+ * a defect BEFORE the first event has no Run identity to attribute, so it is rethrown
4512
+ * without an event — the helper never fabricates identities.
4513
+ */
4514
+ const withTerminalDefectEvent = (events) => Stream.suspend(() => {
4515
+ let last;
4516
+ return events.pipe(Stream.tap((event) => Effect.sync(() => {
4517
+ last = event;
4518
+ })), Stream.catchCause((cause) => {
4519
+ const base = last;
4520
+ if (base === void 0 || !Cause.hasDies(cause) || Cause.hasInterruptsOnly(cause)) return Stream.failCause(cause);
4521
+ return Stream.fromEffect(Effect.gen(function* () {
4522
+ const timestamp = DateTime.makeUnsafe(yield* Clock.currentTimeMillis);
4523
+ return RunFailed.make({
4524
+ eventVersion: 1,
4525
+ runId: base.runId,
4526
+ threadId: base.threadId,
4527
+ agentId: base.agentId,
4528
+ sequence: base.sequence + 1,
4529
+ timestamp,
4530
+ errorTag: "Defect",
4531
+ message: errorMessage(Cause.squash(cause)).slice(0, DEFECT_MESSAGE_LIMIT)
4532
+ });
4533
+ })).pipe(Stream.concat(Stream.failCause(cause)));
4534
+ }));
4535
+ });
4536
+ //#endregion
4537
+ //#region src/engine/AgentRuntime.ts
4538
+ var AgentRuntime_exports = /* @__PURE__ */ __exportAll({
4539
+ AgentChildPending: () => AgentChildPending,
4540
+ AgentResultSchema: () => AgentResultSchema,
4541
+ AgentSpawner: () => AgentSpawner,
4542
+ SubagentDurability: () => SubagentDurability,
4543
+ SubagentDurabilityError: () => SubagentDurabilityError,
4544
+ ToolCallWaiting: () => ToolCallWaiting,
4545
+ decodeFinalOutput: () => decodeFinalOutput,
4546
+ encodeRunDisposition: () => encodeRunDisposition,
4547
+ projectCompletionFromToolOutput: () => projectCompletionFromToolOutput,
4548
+ projectCompletionOutput: () => projectCompletionOutput,
4549
+ renderInputPrompt: () => renderInputPrompt,
4550
+ run: () => run,
4551
+ runUnknown: () => runUnknown,
4552
+ start: () => start,
4553
+ startUnknown: () => startUnknown,
4554
+ stream: () => stream,
4555
+ streamUnknown: () => streamUnknown,
4556
+ streamWithUsageAccountingUnknown: () => streamWithUsageAccountingUnknown,
4557
+ withTerminalDefectEvent: () => withTerminalDefectEvent
4558
+ });
4559
+ //#endregion
4560
+ export { stream as _, SubagentDurability as a, withTerminalDefectEvent as b, decodeFinalOutput as c, projectCompletionOutput as d, renderInputPrompt as f, startUnknown as g, start as h, AgentSpawner as i, encodeRunDisposition as l, runUnknown as m, AgentChildPending as n, SubagentDurabilityError as o, run as p, AgentResultSchema as r, ToolCallWaiting as s, AgentRuntime_exports as t, projectCompletionFromToolOutput as u, streamUnknown as v, streamWithUsageAccountingUnknown as y };
4561
+
4562
+ //# sourceMappingURL=AgentRuntime-BLyETCPo.mjs.map