actoviq-agent-sdk 0.4.6 → 0.4.7

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 (637) hide show
  1. package/CHANGELOG.md +203 -0
  2. package/README-zh.md +54 -19
  3. package/README.md +53 -19
  4. package/SECURITY.md +26 -0
  5. package/assets/actoviq-icon.ico +0 -0
  6. package/bin/actoviq-gui.js +28 -3
  7. package/dist/src/buddy/actoviqBuddy.d.ts.map +1 -1
  8. package/dist/src/buddy/actoviqBuddy.js +3 -4
  9. package/dist/src/buddy/actoviqBuddy.js.map +1 -1
  10. package/dist/src/cli/actoviq-react.js +495 -60
  11. package/dist/src/cli/actoviq-react.js.map +1 -1
  12. package/dist/src/compat/diagnostics.d.ts +18 -0
  13. package/dist/src/compat/diagnostics.d.ts.map +1 -0
  14. package/dist/src/compat/diagnostics.js +47 -0
  15. package/dist/src/compat/diagnostics.js.map +1 -0
  16. package/dist/src/compat/index.d.ts +8 -0
  17. package/dist/src/compat/index.d.ts.map +1 -0
  18. package/dist/src/compat/index.js +6 -0
  19. package/dist/src/compat/index.js.map +1 -0
  20. package/dist/src/config/actoviqHome.d.ts +32 -0
  21. package/dist/src/config/actoviqHome.d.ts.map +1 -0
  22. package/dist/src/config/actoviqHome.js +228 -0
  23. package/dist/src/config/actoviqHome.js.map +1 -0
  24. package/dist/src/config/actoviqSettingsStore.d.ts.map +1 -1
  25. package/dist/src/config/actoviqSettingsStore.js +6 -6
  26. package/dist/src/config/actoviqSettingsStore.js.map +1 -1
  27. package/dist/src/config/agentProfiles.d.ts +77 -0
  28. package/dist/src/config/agentProfiles.d.ts.map +1 -0
  29. package/dist/src/config/agentProfiles.js +319 -0
  30. package/dist/src/config/agentProfiles.js.map +1 -0
  31. package/dist/src/config/loadDefaultActoviqSettings.d.ts.map +1 -1
  32. package/dist/src/config/loadDefaultActoviqSettings.js +2 -3
  33. package/dist/src/config/loadDefaultActoviqSettings.js.map +1 -1
  34. package/dist/src/config/projectSessionDirectory.d.ts.map +1 -1
  35. package/dist/src/config/projectSessionDirectory.js +3 -2
  36. package/dist/src/config/projectSessionDirectory.js.map +1 -1
  37. package/dist/src/config/resolveRuntimeConfig.d.ts.map +1 -1
  38. package/dist/src/config/resolveRuntimeConfig.js +13 -2
  39. package/dist/src/config/resolveRuntimeConfig.js.map +1 -1
  40. package/dist/src/core/agent-spec.d.ts +74 -0
  41. package/dist/src/core/agent-spec.d.ts.map +1 -0
  42. package/dist/src/core/agent-spec.js +2 -0
  43. package/dist/src/core/agent-spec.js.map +1 -0
  44. package/dist/src/core/errors.d.ts +42 -0
  45. package/dist/src/core/errors.d.ts.map +1 -0
  46. package/dist/src/core/errors.js +53 -0
  47. package/dist/src/core/errors.js.map +1 -0
  48. package/dist/src/core/index.d.ts +11 -0
  49. package/dist/src/core/index.d.ts.map +1 -0
  50. package/dist/src/core/index.js +4 -0
  51. package/dist/src/core/index.js.map +1 -0
  52. package/dist/src/core/items.d.ts +161 -0
  53. package/dist/src/core/items.d.ts.map +1 -0
  54. package/dist/src/core/items.js +2 -0
  55. package/dist/src/core/items.js.map +1 -0
  56. package/dist/src/core/json.d.ts +20 -0
  57. package/dist/src/core/json.d.ts.map +1 -0
  58. package/dist/src/core/json.js +80 -0
  59. package/dist/src/core/json.js.map +1 -0
  60. package/dist/src/core/model-ref.d.ts +6 -0
  61. package/dist/src/core/model-ref.d.ts.map +1 -0
  62. package/dist/src/core/model-ref.js +2 -0
  63. package/dist/src/core/model-ref.js.map +1 -0
  64. package/dist/src/core/run.d.ts +35 -0
  65. package/dist/src/core/run.d.ts.map +1 -0
  66. package/dist/src/core/run.js +2 -0
  67. package/dist/src/core/run.js.map +1 -0
  68. package/dist/src/core/usage.d.ts +32 -0
  69. package/dist/src/core/usage.d.ts.map +1 -0
  70. package/dist/src/core/usage.js +111 -0
  71. package/dist/src/core/usage.js.map +1 -0
  72. package/dist/src/errors.d.ts +19 -0
  73. package/dist/src/errors.d.ts.map +1 -1
  74. package/dist/src/errors.js +27 -0
  75. package/dist/src/errors.js.map +1 -1
  76. package/dist/src/events/index.d.ts +4 -0
  77. package/dist/src/events/index.d.ts.map +1 -0
  78. package/dist/src/events/index.js +4 -0
  79. package/dist/src/events/index.js.map +1 -0
  80. package/dist/src/events/openTelemetry.d.ts +51 -0
  81. package/dist/src/events/openTelemetry.d.ts.map +1 -0
  82. package/dist/src/events/openTelemetry.js +116 -0
  83. package/dist/src/events/openTelemetry.js.map +1 -0
  84. package/dist/src/events/processors.d.ts +14 -0
  85. package/dist/src/events/processors.d.ts.map +1 -0
  86. package/dist/src/events/processors.js +60 -0
  87. package/dist/src/events/processors.js.map +1 -0
  88. package/dist/src/events/runEvents.d.ts +66 -0
  89. package/dist/src/events/runEvents.d.ts.map +1 -0
  90. package/dist/src/events/runEvents.js +143 -0
  91. package/dist/src/events/runEvents.js.map +1 -0
  92. package/dist/src/gui/actoviqGui.d.ts +15 -0
  93. package/dist/src/gui/actoviqGui.d.ts.map +1 -1
  94. package/dist/src/gui/actoviqGui.js +18034 -1919
  95. package/dist/src/gui/actoviqGui.js.map +1 -1
  96. package/dist/src/gui/contextRailStore.d.ts +47 -0
  97. package/dist/src/gui/contextRailStore.d.ts.map +1 -0
  98. package/dist/src/gui/contextRailStore.js +163 -0
  99. package/dist/src/gui/contextRailStore.js.map +1 -0
  100. package/dist/src/gui/electronMain.js +32 -16
  101. package/dist/src/gui/electronMain.js.map +1 -1
  102. package/dist/src/gui/guiAssets.d.ts +6 -0
  103. package/dist/src/gui/guiAssets.d.ts.map +1 -0
  104. package/dist/src/gui/guiAssets.js +48 -0
  105. package/dist/src/gui/guiAssets.js.map +1 -0
  106. package/dist/src/gui/guiSyntaxHighlight.d.ts +11 -0
  107. package/dist/src/gui/guiSyntaxHighlight.d.ts.map +1 -0
  108. package/dist/src/gui/guiSyntaxHighlight.js +348 -0
  109. package/dist/src/gui/guiSyntaxHighlight.js.map +1 -0
  110. package/dist/src/gui/projectMeta.d.ts +15 -0
  111. package/dist/src/gui/projectMeta.d.ts.map +1 -0
  112. package/dist/src/gui/projectMeta.js +61 -0
  113. package/dist/src/gui/projectMeta.js.map +1 -0
  114. package/dist/src/gui/projectWorkbench.d.ts +73 -0
  115. package/dist/src/gui/projectWorkbench.d.ts.map +1 -0
  116. package/dist/src/gui/projectWorkbench.js +307 -0
  117. package/dist/src/gui/projectWorkbench.js.map +1 -0
  118. package/dist/src/gui/terminalManager.d.ts +33 -0
  119. package/dist/src/gui/terminalManager.d.ts.map +1 -0
  120. package/dist/src/gui/terminalManager.js +206 -0
  121. package/dist/src/gui/terminalManager.js.map +1 -0
  122. package/dist/src/gui/transcript/clientBundle.d.ts +6 -0
  123. package/dist/src/gui/transcript/clientBundle.d.ts.map +1 -0
  124. package/dist/src/gui/transcript/clientBundle.js +978 -0
  125. package/dist/src/gui/transcript/clientBundle.js.map +1 -0
  126. package/dist/src/gui/transcript/index.d.ts +9 -0
  127. package/dist/src/gui/transcript/index.d.ts.map +1 -0
  128. package/dist/src/gui/transcript/index.js +6 -0
  129. package/dist/src/gui/transcript/index.js.map +1 -0
  130. package/dist/src/gui/transcript/parts.d.ts +81 -0
  131. package/dist/src/gui/transcript/parts.d.ts.map +1 -0
  132. package/dist/src/gui/transcript/parts.js +476 -0
  133. package/dist/src/gui/transcript/parts.js.map +1 -0
  134. package/dist/src/gui/transcript/registry.d.ts +8 -0
  135. package/dist/src/gui/transcript/registry.d.ts.map +1 -0
  136. package/dist/src/gui/transcript/registry.js +32 -0
  137. package/dist/src/gui/transcript/registry.js.map +1 -0
  138. package/dist/src/gui/transcript/scroll.d.ts +9 -0
  139. package/dist/src/gui/transcript/scroll.d.ts.map +1 -0
  140. package/dist/src/gui/transcript/scroll.js +13 -0
  141. package/dist/src/gui/transcript/scroll.js.map +1 -0
  142. package/dist/src/gui/transcript/styles.d.ts +3 -0
  143. package/dist/src/gui/transcript/styles.d.ts.map +1 -0
  144. package/dist/src/gui/transcript/styles.js +172 -0
  145. package/dist/src/gui/transcript/styles.js.map +1 -0
  146. package/dist/src/gui/workspaceNote.d.ts +4 -0
  147. package/dist/src/gui/workspaceNote.d.ts.map +1 -0
  148. package/dist/src/gui/workspaceNote.js +21 -0
  149. package/dist/src/gui/workspaceNote.js.map +1 -0
  150. package/dist/src/gui/workspaceRegistry.d.ts +11 -0
  151. package/dist/src/gui/workspaceRegistry.d.ts.map +1 -0
  152. package/dist/src/gui/workspaceRegistry.js +114 -0
  153. package/dist/src/gui/workspaceRegistry.js.map +1 -0
  154. package/dist/src/hooks/userHooks.d.ts +29 -8
  155. package/dist/src/hooks/userHooks.d.ts.map +1 -1
  156. package/dist/src/hooks/userHooks.js +106 -34
  157. package/dist/src/hooks/userHooks.js.map +1 -1
  158. package/dist/src/index.d.ts +24 -6
  159. package/dist/src/index.d.ts.map +1 -1
  160. package/dist/src/index.js +18 -6
  161. package/dist/src/index.js.map +1 -1
  162. package/dist/src/issues/durableIssueCoordinator.d.ts +57 -0
  163. package/dist/src/issues/durableIssueCoordinator.d.ts.map +1 -0
  164. package/dist/src/issues/durableIssueCoordinator.js +128 -0
  165. package/dist/src/issues/durableIssueCoordinator.js.map +1 -0
  166. package/dist/src/issues/issueExecution.d.ts +34 -0
  167. package/dist/src/issues/issueExecution.d.ts.map +1 -0
  168. package/dist/src/issues/issueExecution.js +190 -0
  169. package/dist/src/issues/issueExecution.js.map +1 -0
  170. package/dist/src/issues/issueStore.d.ts +95 -0
  171. package/dist/src/issues/issueStore.d.ts.map +1 -0
  172. package/dist/src/issues/issueStore.js +373 -0
  173. package/dist/src/issues/issueStore.js.map +1 -0
  174. package/dist/src/manager/projectManager.d.ts +103 -0
  175. package/dist/src/manager/projectManager.d.ts.map +1 -0
  176. package/dist/src/manager/projectManager.js +547 -0
  177. package/dist/src/manager/projectManager.js.map +1 -0
  178. package/dist/src/mcp/connectionManager.d.ts +22 -2
  179. package/dist/src/mcp/connectionManager.d.ts.map +1 -1
  180. package/dist/src/mcp/connectionManager.js +153 -41
  181. package/dist/src/mcp/connectionManager.js.map +1 -1
  182. package/dist/src/mcp/mcpServerConfig.d.ts.map +1 -1
  183. package/dist/src/mcp/mcpServerConfig.js +7 -7
  184. package/dist/src/mcp/mcpServerConfig.js.map +1 -1
  185. package/dist/src/memory/actoviqMemory.js +6 -6
  186. package/dist/src/memory/actoviqMemory.js.map +1 -1
  187. package/dist/src/memory/sessionHistory.js +2 -2
  188. package/dist/src/memory/sessionHistory.js.map +1 -1
  189. package/dist/src/node/index.d.ts +5 -0
  190. package/dist/src/node/index.d.ts.map +1 -0
  191. package/dist/src/node/index.js +5 -0
  192. package/dist/src/node/index.js.map +1 -0
  193. package/dist/src/node/sqliteCheckpointAdapter.d.ts +20 -0
  194. package/dist/src/node/sqliteCheckpointAdapter.d.ts.map +1 -0
  195. package/dist/src/node/sqliteCheckpointAdapter.js +163 -0
  196. package/dist/src/node/sqliteCheckpointAdapter.js.map +1 -0
  197. package/dist/src/node/sqliteDurableChildStore.d.ts +21 -0
  198. package/dist/src/node/sqliteDurableChildStore.d.ts.map +1 -0
  199. package/dist/src/node/sqliteDurableChildStore.js +124 -0
  200. package/dist/src/node/sqliteDurableChildStore.js.map +1 -0
  201. package/dist/src/node/sqliteSessionAdapter.d.ts +28 -0
  202. package/dist/src/node/sqliteSessionAdapter.d.ts.map +1 -0
  203. package/dist/src/node/sqliteSessionAdapter.js +99 -0
  204. package/dist/src/node/sqliteSessionAdapter.js.map +1 -0
  205. package/dist/src/orchestration/agentTool.d.ts +50 -0
  206. package/dist/src/orchestration/agentTool.d.ts.map +1 -0
  207. package/dist/src/orchestration/agentTool.js +132 -0
  208. package/dist/src/orchestration/agentTool.js.map +1 -0
  209. package/dist/src/orchestration/background.d.ts +102 -0
  210. package/dist/src/orchestration/background.d.ts.map +1 -0
  211. package/dist/src/orchestration/background.js +310 -0
  212. package/dist/src/orchestration/background.js.map +1 -0
  213. package/dist/src/orchestration/childRunner.d.ts +12 -0
  214. package/dist/src/orchestration/childRunner.d.ts.map +1 -0
  215. package/dist/src/orchestration/childRunner.js +179 -0
  216. package/dist/src/orchestration/childRunner.js.map +1 -0
  217. package/dist/src/orchestration/contracts.d.ts +169 -0
  218. package/dist/src/orchestration/contracts.d.ts.map +1 -0
  219. package/dist/src/orchestration/contracts.js +11 -0
  220. package/dist/src/orchestration/contracts.js.map +1 -0
  221. package/dist/src/orchestration/handoff.d.ts +32 -0
  222. package/dist/src/orchestration/handoff.d.ts.map +1 -0
  223. package/dist/src/orchestration/handoff.js +60 -0
  224. package/dist/src/orchestration/handoff.js.map +1 -0
  225. package/dist/src/orchestration/index.d.ts +9 -0
  226. package/dist/src/orchestration/index.d.ts.map +1 -0
  227. package/dist/src/orchestration/index.js +9 -0
  228. package/dist/src/orchestration/index.js.map +1 -0
  229. package/dist/src/orchestration/presets.d.ts +51 -0
  230. package/dist/src/orchestration/presets.d.ts.map +1 -0
  231. package/dist/src/orchestration/presets.js +78 -0
  232. package/dist/src/orchestration/presets.js.map +1 -0
  233. package/dist/src/orchestration/scope.d.ts +69 -0
  234. package/dist/src/orchestration/scope.d.ts.map +1 -0
  235. package/dist/src/orchestration/scope.js +371 -0
  236. package/dist/src/orchestration/scope.js.map +1 -0
  237. package/dist/src/orchestration/workflowGraph.d.ts +73 -0
  238. package/dist/src/orchestration/workflowGraph.d.ts.map +1 -0
  239. package/dist/src/orchestration/workflowGraph.js +255 -0
  240. package/dist/src/orchestration/workflowGraph.js.map +1 -0
  241. package/dist/src/parity/actoviqCleanBridgeCompatSdk.d.ts.map +1 -1
  242. package/dist/src/parity/actoviqCleanBridgeCompatSdk.js +101 -48
  243. package/dist/src/parity/actoviqCleanBridgeCompatSdk.js.map +1 -1
  244. package/dist/src/parity/bridgeConfigs.d.ts +2 -2
  245. package/dist/src/parity/bridgeConfigs.d.ts.map +1 -1
  246. package/dist/src/parity/bridgeConfigs.js +78 -39
  247. package/dist/src/parity/bridgeConfigs.js.map +1 -1
  248. package/dist/src/parity/bridgeProviders.d.ts +9 -6
  249. package/dist/src/parity/bridgeProviders.d.ts.map +1 -1
  250. package/dist/src/parity/bridgeProviders.js +140 -26
  251. package/dist/src/parity/bridgeProviders.js.map +1 -1
  252. package/dist/src/parity/portableSessions.js +2 -2
  253. package/dist/src/parity/portableSessions.js.map +1 -1
  254. package/dist/src/profiles/index.d.ts +15 -0
  255. package/dist/src/profiles/index.d.ts.map +1 -0
  256. package/dist/src/profiles/index.js +618 -0
  257. package/dist/src/profiles/index.js.map +1 -0
  258. package/dist/src/profiles/types.d.ts +102 -0
  259. package/dist/src/profiles/types.d.ts.map +1 -0
  260. package/dist/src/profiles/types.js +9 -0
  261. package/dist/src/profiles/types.js.map +1 -0
  262. package/dist/src/provider/client.d.ts +1 -1
  263. package/dist/src/provider/client.d.ts.map +1 -1
  264. package/dist/src/provider/openai-model-api.js +1 -1
  265. package/dist/src/provider/openai-model-api.js.map +1 -1
  266. package/dist/src/providers-v2/adapter-base.d.ts +35 -0
  267. package/dist/src/providers-v2/adapter-base.d.ts.map +1 -0
  268. package/dist/src/providers-v2/adapter-base.js +115 -0
  269. package/dist/src/providers-v2/adapter-base.js.map +1 -0
  270. package/dist/src/providers-v2/anthropic.d.ts +15 -0
  271. package/dist/src/providers-v2/anthropic.d.ts.map +1 -0
  272. package/dist/src/providers-v2/anthropic.js +414 -0
  273. package/dist/src/providers-v2/anthropic.js.map +1 -0
  274. package/dist/src/providers-v2/capabilities.d.ts +33 -0
  275. package/dist/src/providers-v2/capabilities.d.ts.map +1 -0
  276. package/dist/src/providers-v2/capabilities.js +218 -0
  277. package/dist/src/providers-v2/capabilities.js.map +1 -0
  278. package/dist/src/providers-v2/index.d.ts +12 -0
  279. package/dist/src/providers-v2/index.d.ts.map +1 -0
  280. package/dist/src/providers-v2/index.js +8 -0
  281. package/dist/src/providers-v2/index.js.map +1 -0
  282. package/dist/src/providers-v2/legacy.d.ts +26 -0
  283. package/dist/src/providers-v2/legacy.d.ts.map +1 -0
  284. package/dist/src/providers-v2/legacy.js +543 -0
  285. package/dist/src/providers-v2/legacy.js.map +1 -0
  286. package/dist/src/providers-v2/mapping.d.ts +34 -0
  287. package/dist/src/providers-v2/mapping.d.ts.map +1 -0
  288. package/dist/src/providers-v2/mapping.js +194 -0
  289. package/dist/src/providers-v2/mapping.js.map +1 -0
  290. package/dist/src/providers-v2/openai-chat.d.ts +16 -0
  291. package/dist/src/providers-v2/openai-chat.d.ts.map +1 -0
  292. package/dist/src/providers-v2/openai-chat.js +318 -0
  293. package/dist/src/providers-v2/openai-chat.js.map +1 -0
  294. package/dist/src/providers-v2/openai-responses.d.ts +15 -0
  295. package/dist/src/providers-v2/openai-responses.d.ts.map +1 -0
  296. package/dist/src/providers-v2/openai-responses.js +356 -0
  297. package/dist/src/providers-v2/openai-responses.js.map +1 -0
  298. package/dist/src/providers-v2/registry.d.ts +39 -0
  299. package/dist/src/providers-v2/registry.d.ts.map +1 -0
  300. package/dist/src/providers-v2/registry.js +101 -0
  301. package/dist/src/providers-v2/registry.js.map +1 -0
  302. package/dist/src/providers-v2/stream.d.ts +14 -0
  303. package/dist/src/providers-v2/stream.d.ts.map +1 -0
  304. package/dist/src/providers-v2/stream.js +115 -0
  305. package/dist/src/providers-v2/stream.js.map +1 -0
  306. package/dist/src/providers-v2/transport.d.ts +36 -0
  307. package/dist/src/providers-v2/transport.d.ts.map +1 -0
  308. package/dist/src/providers-v2/transport.js +337 -0
  309. package/dist/src/providers-v2/transport.js.map +1 -0
  310. package/dist/src/providers-v2/types.d.ts +162 -0
  311. package/dist/src/providers-v2/types.d.ts.map +1 -0
  312. package/dist/src/providers-v2/types.js +8 -0
  313. package/dist/src/providers-v2/types.js.map +1 -0
  314. package/dist/src/router/modelRouter.d.ts.map +1 -1
  315. package/dist/src/router/modelRouter.js +2 -3
  316. package/dist/src/router/modelRouter.js.map +1 -1
  317. package/dist/src/runtime/actoviqAgents.d.ts +5 -0
  318. package/dist/src/runtime/actoviqAgents.d.ts.map +1 -1
  319. package/dist/src/runtime/actoviqAgents.js +22 -4
  320. package/dist/src/runtime/actoviqAgents.js.map +1 -1
  321. package/dist/src/runtime/actoviqBackgroundTasks.d.ts +2 -1
  322. package/dist/src/runtime/actoviqBackgroundTasks.d.ts.map +1 -1
  323. package/dist/src/runtime/actoviqBackgroundTasks.js +4 -2
  324. package/dist/src/runtime/actoviqBackgroundTasks.js.map +1 -1
  325. package/dist/src/runtime/actoviqCompact.d.ts +15 -0
  326. package/dist/src/runtime/actoviqCompact.d.ts.map +1 -1
  327. package/dist/src/runtime/actoviqCompact.js +36 -10
  328. package/dist/src/runtime/actoviqCompact.js.map +1 -1
  329. package/dist/src/runtime/actoviqModelApi.d.ts.map +1 -1
  330. package/dist/src/runtime/actoviqModelApi.js +16 -2
  331. package/dist/src/runtime/actoviqModelApi.js.map +1 -1
  332. package/dist/src/runtime/actoviqPermissions.js +5 -1
  333. package/dist/src/runtime/actoviqPermissions.js.map +1 -1
  334. package/dist/src/runtime/agentClient.d.ts +3 -0
  335. package/dist/src/runtime/agentClient.d.ts.map +1 -1
  336. package/dist/src/runtime/agentClient.js +127 -45
  337. package/dist/src/runtime/agentClient.js.map +1 -1
  338. package/dist/src/runtime/agentRuntimeDiscovery.d.ts +75 -0
  339. package/dist/src/runtime/agentRuntimeDiscovery.d.ts.map +1 -0
  340. package/dist/src/runtime/agentRuntimeDiscovery.js +311 -0
  341. package/dist/src/runtime/agentRuntimeDiscovery.js.map +1 -0
  342. package/dist/src/runtime/agentSession.d.ts +18 -0
  343. package/dist/src/runtime/agentSession.d.ts.map +1 -1
  344. package/dist/src/runtime/agentSession.js +36 -0
  345. package/dist/src/runtime/agentSession.js.map +1 -1
  346. package/dist/src/runtime/asyncQueue.d.ts +99 -8
  347. package/dist/src/runtime/asyncQueue.d.ts.map +1 -1
  348. package/dist/src/runtime/asyncQueue.js +437 -37
  349. package/dist/src/runtime/asyncQueue.js.map +1 -1
  350. package/dist/src/runtime/conversationEngine.d.ts +7 -0
  351. package/dist/src/runtime/conversationEngine.d.ts.map +1 -1
  352. package/dist/src/runtime/conversationEngine.js +278 -18
  353. package/dist/src/runtime/conversationEngine.js.map +1 -1
  354. package/dist/src/runtime/deadline.d.ts +13 -0
  355. package/dist/src/runtime/deadline.d.ts.map +1 -0
  356. package/dist/src/runtime/deadline.js +67 -0
  357. package/dist/src/runtime/deadline.js.map +1 -0
  358. package/dist/src/runtime/messageUtils.d.ts +5 -0
  359. package/dist/src/runtime/messageUtils.d.ts.map +1 -1
  360. package/dist/src/runtime/messageUtils.js +17 -0
  361. package/dist/src/runtime/messageUtils.js.map +1 -1
  362. package/dist/src/runtime/sessionTurnCoordinator.d.ts +12 -0
  363. package/dist/src/runtime/sessionTurnCoordinator.d.ts.map +1 -0
  364. package/dist/src/runtime/sessionTurnCoordinator.js +23 -0
  365. package/dist/src/runtime/sessionTurnCoordinator.js.map +1 -0
  366. package/dist/src/runtime/tools.d.ts.map +1 -1
  367. package/dist/src/runtime/tools.js +1 -0
  368. package/dist/src/runtime/tools.js.map +1 -1
  369. package/dist/src/runtime-v2/agentRuntime.d.ts +136 -0
  370. package/dist/src/runtime-v2/agentRuntime.d.ts.map +1 -0
  371. package/dist/src/runtime-v2/agentRuntime.js +1341 -0
  372. package/dist/src/runtime-v2/agentRuntime.js.map +1 -0
  373. package/dist/src/runtime-v2/index.d.ts +6 -0
  374. package/dist/src/runtime-v2/index.d.ts.map +1 -0
  375. package/dist/src/runtime-v2/index.js +6 -0
  376. package/dist/src/runtime-v2/index.js.map +1 -0
  377. package/dist/src/runtime-v2/middleware/index.d.ts +5 -0
  378. package/dist/src/runtime-v2/middleware/index.d.ts.map +1 -0
  379. package/dist/src/runtime-v2/middleware/index.js +4 -0
  380. package/dist/src/runtime-v2/middleware/index.js.map +1 -0
  381. package/dist/src/runtime-v2/middleware/pipeline.d.ts +56 -0
  382. package/dist/src/runtime-v2/middleware/pipeline.d.ts.map +1 -0
  383. package/dist/src/runtime-v2/middleware/pipeline.js +242 -0
  384. package/dist/src/runtime-v2/middleware/pipeline.js.map +1 -0
  385. package/dist/src/runtime-v2/middleware/registry.d.ts +17 -0
  386. package/dist/src/runtime-v2/middleware/registry.d.ts.map +1 -0
  387. package/dist/src/runtime-v2/middleware/registry.js +46 -0
  388. package/dist/src/runtime-v2/middleware/registry.js.map +1 -0
  389. package/dist/src/runtime-v2/middleware/stages.d.ts +25 -0
  390. package/dist/src/runtime-v2/middleware/stages.d.ts.map +1 -0
  391. package/dist/src/runtime-v2/middleware/stages.js +48 -0
  392. package/dist/src/runtime-v2/middleware/stages.js.map +1 -0
  393. package/dist/src/runtime-v2/middleware/types.d.ts +51 -0
  394. package/dist/src/runtime-v2/middleware/types.d.ts.map +1 -0
  395. package/dist/src/runtime-v2/middleware/types.js +2 -0
  396. package/dist/src/runtime-v2/middleware/types.js.map +1 -0
  397. package/dist/src/runtime-v2/services.d.ts +33 -0
  398. package/dist/src/runtime-v2/services.d.ts.map +1 -0
  399. package/dist/src/runtime-v2/services.js +92 -0
  400. package/dist/src/runtime-v2/services.js.map +1 -0
  401. package/dist/src/runtime-v2/state.d.ts +71 -0
  402. package/dist/src/runtime-v2/state.d.ts.map +1 -0
  403. package/dist/src/runtime-v2/state.js +2 -0
  404. package/dist/src/runtime-v2/state.js.map +1 -0
  405. package/dist/src/runtime-v2/tools.d.ts +124 -0
  406. package/dist/src/runtime-v2/tools.d.ts.map +1 -0
  407. package/dist/src/runtime-v2/tools.js +185 -0
  408. package/dist/src/runtime-v2/tools.js.map +1 -0
  409. package/dist/src/scheduling/durableAgentScheduler.d.ts +46 -0
  410. package/dist/src/scheduling/durableAgentScheduler.d.ts.map +1 -0
  411. package/dist/src/scheduling/durableAgentScheduler.js +97 -0
  412. package/dist/src/scheduling/durableAgentScheduler.js.map +1 -0
  413. package/dist/src/scheduling/index.d.ts +3 -0
  414. package/dist/src/scheduling/index.d.ts.map +1 -1
  415. package/dist/src/scheduling/index.js +2 -0
  416. package/dist/src/scheduling/index.js.map +1 -1
  417. package/dist/src/scheduling/taskPersistence.d.ts +9 -0
  418. package/dist/src/scheduling/taskPersistence.d.ts.map +1 -0
  419. package/dist/src/scheduling/taskPersistence.js +238 -0
  420. package/dist/src/scheduling/taskPersistence.js.map +1 -0
  421. package/dist/src/storage/atomicJsonWrite.d.ts +13 -0
  422. package/dist/src/storage/atomicJsonWrite.d.ts.map +1 -0
  423. package/dist/src/storage/atomicJsonWrite.js +40 -0
  424. package/dist/src/storage/atomicJsonWrite.js.map +1 -0
  425. package/dist/src/storage/backgroundTaskStore.d.ts.map +1 -1
  426. package/dist/src/storage/backgroundTaskStore.js +2 -6
  427. package/dist/src/storage/backgroundTaskStore.js.map +1 -1
  428. package/dist/src/storage/mailboxStore.d.ts.map +1 -1
  429. package/dist/src/storage/mailboxStore.js +2 -6
  430. package/dist/src/storage/mailboxStore.js.map +1 -1
  431. package/dist/src/storage/sessionStore.d.ts +3 -0
  432. package/dist/src/storage/sessionStore.d.ts.map +1 -1
  433. package/dist/src/storage/sessionStore.js +169 -10
  434. package/dist/src/storage/sessionStore.js.map +1 -1
  435. package/dist/src/storage/teammateStore.d.ts.map +1 -1
  436. package/dist/src/storage/teammateStore.js +2 -6
  437. package/dist/src/storage/teammateStore.js.map +1 -1
  438. package/dist/src/storage-v2/contracts.d.ts +36 -0
  439. package/dist/src/storage-v2/contracts.d.ts.map +1 -0
  440. package/dist/src/storage-v2/contracts.js +2 -0
  441. package/dist/src/storage-v2/contracts.js.map +1 -0
  442. package/dist/src/storage-v2/errors.d.ts +21 -0
  443. package/dist/src/storage-v2/errors.d.ts.map +1 -0
  444. package/dist/src/storage-v2/errors.js +44 -0
  445. package/dist/src/storage-v2/errors.js.map +1 -0
  446. package/dist/src/storage-v2/index.d.ts +8 -0
  447. package/dist/src/storage-v2/index.d.ts.map +1 -0
  448. package/dist/src/storage-v2/index.js +8 -0
  449. package/dist/src/storage-v2/index.js.map +1 -0
  450. package/dist/src/storage-v2/legacyJsonV1Items.d.ts +10 -0
  451. package/dist/src/storage-v2/legacyJsonV1Items.d.ts.map +1 -0
  452. package/dist/src/storage-v2/legacyJsonV1Items.js +153 -0
  453. package/dist/src/storage-v2/legacyJsonV1Items.js.map +1 -0
  454. package/dist/src/storage-v2/migration.d.ts +32 -0
  455. package/dist/src/storage-v2/migration.d.ts.map +1 -0
  456. package/dist/src/storage-v2/migration.js +242 -0
  457. package/dist/src/storage-v2/migration.js.map +1 -0
  458. package/dist/src/storage-v2/sqliteDriver.d.ts +24 -0
  459. package/dist/src/storage-v2/sqliteDriver.d.ts.map +1 -0
  460. package/dist/src/storage-v2/sqliteDriver.js +90 -0
  461. package/dist/src/storage-v2/sqliteDriver.js.map +1 -0
  462. package/dist/src/storage-v2/sqliteStorage.d.ts +55 -0
  463. package/dist/src/storage-v2/sqliteStorage.d.ts.map +1 -0
  464. package/dist/src/storage-v2/sqliteStorage.js +905 -0
  465. package/dist/src/storage-v2/sqliteStorage.js.map +1 -0
  466. package/dist/src/storage-v2/types.d.ts +198 -0
  467. package/dist/src/storage-v2/types.d.ts.map +1 -0
  468. package/dist/src/storage-v2/types.js +2 -0
  469. package/dist/src/storage-v2/types.js.map +1 -0
  470. package/dist/src/surfaces/index.d.ts +8 -0
  471. package/dist/src/surfaces/index.d.ts.map +1 -0
  472. package/dist/src/surfaces/index.js +8 -0
  473. package/dist/src/surfaces/index.js.map +1 -0
  474. package/dist/src/surfaces/internal.d.ts +17 -0
  475. package/dist/src/surfaces/internal.d.ts.map +1 -0
  476. package/dist/src/surfaces/internal.js +116 -0
  477. package/dist/src/surfaces/internal.js.map +1 -0
  478. package/dist/src/surfaces/legacyEventAdapter.d.ts +38 -0
  479. package/dist/src/surfaces/legacyEventAdapter.d.ts.map +1 -0
  480. package/dist/src/surfaces/legacyEventAdapter.js +373 -0
  481. package/dist/src/surfaces/legacyEventAdapter.js.map +1 -0
  482. package/dist/src/surfaces/legacySurfacePipeline.d.ts +18 -0
  483. package/dist/src/surfaces/legacySurfacePipeline.d.ts.map +1 -0
  484. package/dist/src/surfaces/legacySurfacePipeline.js +25 -0
  485. package/dist/src/surfaces/legacySurfacePipeline.js.map +1 -0
  486. package/dist/src/surfaces/redaction.d.ts +12 -0
  487. package/dist/src/surfaces/redaction.d.ts.map +1 -0
  488. package/dist/src/surfaces/redaction.js +111 -0
  489. package/dist/src/surfaces/redaction.js.map +1 -0
  490. package/dist/src/surfaces/runEventLegacyCompat.d.ts +26 -0
  491. package/dist/src/surfaces/runEventLegacyCompat.d.ts.map +1 -0
  492. package/dist/src/surfaces/runEventLegacyCompat.js +339 -0
  493. package/dist/src/surfaces/runEventLegacyCompat.js.map +1 -0
  494. package/dist/src/surfaces/runEventProjector.d.ts +44 -0
  495. package/dist/src/surfaces/runEventProjector.d.ts.map +1 -0
  496. package/dist/src/surfaces/runEventProjector.js +404 -0
  497. package/dist/src/surfaces/runEventProjector.js.map +1 -0
  498. package/dist/src/surfaces/runtimeBridgeAdapter.d.ts +30 -0
  499. package/dist/src/surfaces/runtimeBridgeAdapter.d.ts.map +1 -0
  500. package/dist/src/surfaces/runtimeBridgeAdapter.js +38 -0
  501. package/dist/src/surfaces/runtimeBridgeAdapter.js.map +1 -0
  502. package/dist/src/surfaces/types.d.ts +38 -0
  503. package/dist/src/surfaces/types.d.ts.map +1 -0
  504. package/dist/src/surfaces/types.js +2 -0
  505. package/dist/src/surfaces/types.js.map +1 -0
  506. package/dist/src/team/agentPool.d.ts +2 -0
  507. package/dist/src/team/agentPool.d.ts.map +1 -1
  508. package/dist/src/team/agentPool.js +3 -1
  509. package/dist/src/team/agentPool.js.map +1 -1
  510. package/dist/src/team/modelTeam.d.ts +25 -19
  511. package/dist/src/team/modelTeam.d.ts.map +1 -1
  512. package/dist/src/team/modelTeam.js +293 -294
  513. package/dist/src/team/modelTeam.js.map +1 -1
  514. package/dist/src/team/pricing.d.ts.map +1 -1
  515. package/dist/src/team/pricing.js +2 -1
  516. package/dist/src/team/pricing.js.map +1 -1
  517. package/dist/src/team/teamDefinitions.d.ts +28 -1
  518. package/dist/src/team/teamDefinitions.d.ts.map +1 -1
  519. package/dist/src/team/teamDefinitions.js +204 -8
  520. package/dist/src/team/teamDefinitions.js.map +1 -1
  521. package/dist/src/team/teamGraph.d.ts +191 -0
  522. package/dist/src/team/teamGraph.d.ts.map +1 -0
  523. package/dist/src/team/teamGraph.js +616 -0
  524. package/dist/src/team/teamGraph.js.map +1 -0
  525. package/dist/src/team/teamGraphLayout.d.ts +44 -0
  526. package/dist/src/team/teamGraphLayout.d.ts.map +1 -0
  527. package/dist/src/team/teamGraphLayout.js +120 -0
  528. package/dist/src/team/teamGraphLayout.js.map +1 -0
  529. package/dist/src/team/teamGraphScaffold.d.ts +76 -0
  530. package/dist/src/team/teamGraphScaffold.d.ts.map +1 -0
  531. package/dist/src/team/teamGraphScaffold.js +409 -0
  532. package/dist/src/team/teamGraphScaffold.js.map +1 -0
  533. package/dist/src/team/teamGraphV3.d.ts +28 -0
  534. package/dist/src/team/teamGraphV3.d.ts.map +1 -0
  535. package/dist/src/team/teamGraphV3.js +640 -0
  536. package/dist/src/team/teamGraphV3.js.map +1 -0
  537. package/dist/src/team/teamPreferences.d.ts +11 -0
  538. package/dist/src/team/teamPreferences.d.ts.map +1 -0
  539. package/dist/src/team/teamPreferences.js +48 -0
  540. package/dist/src/team/teamPreferences.js.map +1 -0
  541. package/dist/src/team/teamPrompts.d.ts +16 -0
  542. package/dist/src/team/teamPrompts.d.ts.map +1 -0
  543. package/dist/src/team/teamPrompts.js +44 -0
  544. package/dist/src/team/teamPrompts.js.map +1 -0
  545. package/dist/src/team/teamRunView.d.ts +78 -0
  546. package/dist/src/team/teamRunView.d.ts.map +1 -0
  547. package/dist/src/team/teamRunView.js +205 -0
  548. package/dist/src/team/teamRunView.js.map +1 -0
  549. package/dist/src/team/teamRuntime.d.ts +19 -2
  550. package/dist/src/team/teamRuntime.d.ts.map +1 -1
  551. package/dist/src/team/teamRuntime.js +13 -7
  552. package/dist/src/team/teamRuntime.js.map +1 -1
  553. package/dist/src/tools/actoviqCoreTools.d.ts +2 -1
  554. package/dist/src/tools/actoviqCoreTools.d.ts.map +1 -1
  555. package/dist/src/tools/actoviqCoreTools.js +4 -1
  556. package/dist/src/tools/actoviqCoreTools.js.map +1 -1
  557. package/dist/src/tools/actoviqShellTools.d.ts.map +1 -1
  558. package/dist/src/tools/actoviqShellTools.js +10 -0
  559. package/dist/src/tools/actoviqShellTools.js.map +1 -1
  560. package/dist/src/tools/askUserQuestion/AskUserQuestionTool.d.ts.map +1 -1
  561. package/dist/src/tools/askUserQuestion/AskUserQuestionTool.js +2 -0
  562. package/dist/src/tools/askUserQuestion/AskUserQuestionTool.js.map +1 -1
  563. package/dist/src/tools/bash/BashTool.d.ts +33 -2
  564. package/dist/src/tools/bash/BashTool.d.ts.map +1 -1
  565. package/dist/src/tools/bash/BashTool.js +140 -2
  566. package/dist/src/tools/bash/BashTool.js.map +1 -1
  567. package/dist/src/tools/bash/prompt.d.ts +1 -1
  568. package/dist/src/tools/bash/prompt.d.ts.map +1 -1
  569. package/dist/src/tools/bash/prompt.js +1 -0
  570. package/dist/src/tools/bash/prompt.js.map +1 -1
  571. package/dist/src/tools/planMode/PlanModeTools.js +2 -2
  572. package/dist/src/tools/planMode/PlanModeTools.js.map +1 -1
  573. package/dist/src/tools/todo/TodoWriteTool.d.ts +1 -1
  574. package/dist/src/tui/actoviqTui.d.ts.map +1 -1
  575. package/dist/src/tui/actoviqTui.js +522 -97
  576. package/dist/src/tui/actoviqTui.js.map +1 -1
  577. package/dist/src/tui/pluginCatalog.d.ts.map +1 -1
  578. package/dist/src/tui/pluginCatalog.js +3 -1
  579. package/dist/src/tui/pluginCatalog.js.map +1 -1
  580. package/dist/src/types.d.ts +355 -23
  581. package/dist/src/types.d.ts.map +1 -1
  582. package/dist/src/types.js.map +1 -1
  583. package/dist/src/ui/commandSurface.d.ts.map +1 -1
  584. package/dist/src/ui/commandSurface.js +23 -3
  585. package/dist/src/ui/commandSurface.js.map +1 -1
  586. package/dist/src/workflow/workflowPersistence.d.ts.map +1 -1
  587. package/dist/src/workflow/workflowPersistence.js +2 -1
  588. package/dist/src/workflow/workflowPersistence.js.map +1 -1
  589. package/dist/src/workflow/workflowScriptRuntime.d.ts +4 -0
  590. package/dist/src/workflow/workflowScriptRuntime.d.ts.map +1 -1
  591. package/dist/src/workflow/workflowScriptRuntime.js +69 -18
  592. package/dist/src/workflow/workflowScriptRuntime.js.map +1 -1
  593. package/dist/src/workflow-v2/boundary.d.ts +2 -0
  594. package/dist/src/workflow-v2/boundary.d.ts.map +1 -0
  595. package/dist/src/workflow-v2/boundary.js +45 -0
  596. package/dist/src/workflow-v2/boundary.js.map +1 -0
  597. package/dist/src/workflow-v2/capabilities.d.ts +5 -0
  598. package/dist/src/workflow-v2/capabilities.d.ts.map +1 -0
  599. package/dist/src/workflow-v2/capabilities.js +32 -0
  600. package/dist/src/workflow-v2/capabilities.js.map +1 -0
  601. package/dist/src/workflow-v2/errors.d.ts +43 -0
  602. package/dist/src/workflow-v2/errors.d.ts.map +1 -0
  603. package/dist/src/workflow-v2/errors.js +84 -0
  604. package/dist/src/workflow-v2/errors.js.map +1 -0
  605. package/dist/src/workflow-v2/index.d.ts +9 -0
  606. package/dist/src/workflow-v2/index.d.ts.map +1 -0
  607. package/dist/src/workflow-v2/index.js +6 -0
  608. package/dist/src/workflow-v2/index.js.map +1 -0
  609. package/dist/src/workflow-v2/json.d.ts +5 -0
  610. package/dist/src/workflow-v2/json.d.ts.map +1 -0
  611. package/dist/src/workflow-v2/json.js +40 -0
  612. package/dist/src/workflow-v2/json.js.map +1 -0
  613. package/dist/src/workflow-v2/limits.d.ts +15 -0
  614. package/dist/src/workflow-v2/limits.d.ts.map +1 -0
  615. package/dist/src/workflow-v2/limits.js +37 -0
  616. package/dist/src/workflow-v2/limits.js.map +1 -0
  617. package/dist/src/workflow-v2/localIsolatedProcessExecutor.d.ts +25 -0
  618. package/dist/src/workflow-v2/localIsolatedProcessExecutor.d.ts.map +1 -0
  619. package/dist/src/workflow-v2/localIsolatedProcessExecutor.js +423 -0
  620. package/dist/src/workflow-v2/localIsolatedProcessExecutor.js.map +1 -0
  621. package/dist/src/workflow-v2/localProcessChild.d.ts +2 -0
  622. package/dist/src/workflow-v2/localProcessChild.d.ts.map +1 -0
  623. package/dist/src/workflow-v2/localProcessChild.js +305 -0
  624. package/dist/src/workflow-v2/localProcessChild.js.map +1 -0
  625. package/dist/src/workflow-v2/router.d.ts +10 -0
  626. package/dist/src/workflow-v2/router.d.ts.map +1 -0
  627. package/dist/src/workflow-v2/router.js +28 -0
  628. package/dist/src/workflow-v2/router.js.map +1 -0
  629. package/dist/src/workflow-v2/trustedCompatibilityExecutor.d.ts +17 -0
  630. package/dist/src/workflow-v2/trustedCompatibilityExecutor.d.ts.map +1 -0
  631. package/dist/src/workflow-v2/trustedCompatibilityExecutor.js +159 -0
  632. package/dist/src/workflow-v2/trustedCompatibilityExecutor.js.map +1 -0
  633. package/dist/src/workflow-v2/types.d.ts +67 -0
  634. package/dist/src/workflow-v2/types.d.ts.map +1 -0
  635. package/dist/src/workflow-v2/types.js +2 -0
  636. package/dist/src/workflow-v2/types.js.map +1 -0
  637. package/package.json +96 -10
@@ -0,0 +1,1341 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { RunError, UsageAccumulator, assertJsonValue, emptyUsage, } from '../core/index.js';
3
+ import { EventDispatcher, RunEventSequencer, SensitiveDataRedactionProcessor, createRootTraceContext, } from '../events/index.js';
4
+ import { AsyncQueue } from '../runtime/asyncQueue.js';
5
+ import { SessionTurnCoordinator } from '../runtime/sessionTurnCoordinator.js';
6
+ import { MiddlewarePipeline, MiddlewareRegistry, MiddlewareStage, buildMiddlewarePipeline, } from './middleware/index.js';
7
+ import { RuntimeServices } from './services.js';
8
+ import { ToolExecutionError, ToolInterruptionRequiredError, ToolRegistry, ToolRunner, toolEffect, } from './tools.js';
9
+ /** Raised when ordinary middleware attempts to replace a reserved runtime boundary. */
10
+ export class MiddlewareInvariantViolationError extends RunError {
11
+ stage;
12
+ constructor(stage, runId, message, cause) {
13
+ super(message, {
14
+ code: 'MIDDLEWARE_INVARIANT_VIOLATION',
15
+ runId,
16
+ phase: stage === MiddlewareStage.WrapToolCall
17
+ ? 'tool_call'
18
+ : stage === MiddlewareStage.BeforeHandoff
19
+ ? 'handoff'
20
+ : 'model_call',
21
+ cause,
22
+ details: { stage },
23
+ });
24
+ this.stage = stage;
25
+ }
26
+ }
27
+ const DEFAULT_LIMITS = Object.freeze({
28
+ maxTurns: 32,
29
+ runDeadlineMs: 15 * 60_000,
30
+ modelCallTimeoutMs: 120_000,
31
+ toolTimeoutMs: 120_000,
32
+ hookTimeoutMs: 30_000,
33
+ maxParallelTools: 10,
34
+ maxSubagentDepth: 1,
35
+ maxSubagentFanout: 8,
36
+ streamBufferSize: 256,
37
+ maxInputTokens: 1_000_000,
38
+ maxOutputTokens: 64_000,
39
+ maxTotalTokens: 1_000_000,
40
+ maxCostUsd: 100,
41
+ });
42
+ const DEFAULT_MAX_CONCURRENT_RUNS = 64;
43
+ export class AgentRuntime {
44
+ models;
45
+ defaultModel;
46
+ tools;
47
+ toolRunner;
48
+ hasToolPolicy;
49
+ services;
50
+ middleware;
51
+ middlewareRegistry;
52
+ events;
53
+ checkpointStore;
54
+ defaultLimits;
55
+ runConcurrency;
56
+ agents = new Map();
57
+ activeRuns = new Map();
58
+ activeSettlements = new Map();
59
+ agentPipelines = new WeakMap();
60
+ sessionTurns = new SessionTurnCoordinator();
61
+ closed = false;
62
+ constructor(options) {
63
+ this.models = options.models;
64
+ this.runConcurrency = new RunConcurrencyGate(options.maxConcurrentRuns ?? DEFAULT_MAX_CONCURRENT_RUNS);
65
+ this.defaultModel = options.defaultModel;
66
+ this.tools = options.tools ?? new ToolRegistry();
67
+ this.toolRunner = new ToolRunner({ registry: this.tools, policy: options.toolPolicy });
68
+ this.hasToolPolicy = options.toolPolicy !== undefined;
69
+ this.services = options.services ?? new RuntimeServices();
70
+ this.middleware = options.middleware instanceof MiddlewarePipeline
71
+ ? options.middleware
72
+ : buildMiddlewarePipeline(options.middleware ?? []);
73
+ this.middlewareRegistry = options.middlewareRegistry ?? new MiddlewareRegistry();
74
+ this.events = new EventDispatcher({
75
+ processors: [new SensitiveDataRedactionProcessor(), ...(options.eventProcessors ?? [])],
76
+ sinks: options.eventSinks,
77
+ failureMode: options.eventFailureMode,
78
+ });
79
+ this.checkpointStore = options.checkpointStore;
80
+ this.defaultLimits = resolveLimits(DEFAULT_LIMITS, options.defaultLimits);
81
+ for (const agent of options.agents ?? [])
82
+ this.registerAgent(agent);
83
+ }
84
+ registerAgent(agent) {
85
+ assertAgentSpec(agent);
86
+ const current = this.agents.get(agent.id);
87
+ if (current && current !== agent)
88
+ throw new Error(`Agent "${agent.id}" is already registered.`);
89
+ this.agents.set(agent.id, agent);
90
+ return this;
91
+ }
92
+ async run(agent, input, options = {}) {
93
+ this.assertOpen();
94
+ const seed = this.createSeed(agent, input, options);
95
+ const controller = this.claimRun(seed.state.runId, options.signal);
96
+ let current = seed.state;
97
+ const execution = this.executeWithSessionLock(seed, controller.signal, {
98
+ emit: event => this.events.dispatch(event).then(() => undefined),
99
+ update: state => { current = state; },
100
+ });
101
+ this.trackSettlement(seed.state.runId, execution);
102
+ try {
103
+ return await execution;
104
+ }
105
+ finally {
106
+ this.releaseRun(seed.state.runId, controller);
107
+ void current;
108
+ }
109
+ }
110
+ stream(agent, input, options = {}) {
111
+ this.assertOpen();
112
+ const seed = this.createSeed(agent, input, options);
113
+ const limits = resolveLimits(this.defaultLimits, agent.limits);
114
+ const queue = createEventQueue(limits.streamBufferSize);
115
+ const controller = this.claimRun(seed.state.runId, options.signal);
116
+ let current = seed.state;
117
+ const result = Promise.resolve().then(() => this.executeWithSessionLock(seed, controller.signal, {
118
+ emit: async (event) => {
119
+ const processed = await this.events.dispatch(event);
120
+ if (processed)
121
+ queue.push(processed);
122
+ },
123
+ update: state => { current = state; },
124
+ streamModel: true,
125
+ })).finally(() => {
126
+ queue.close();
127
+ this.releaseRun(seed.state.runId, controller);
128
+ });
129
+ void result.catch(() => undefined);
130
+ this.trackSettlement(seed.state.runId, result);
131
+ return new RuntimeRunHandle(seed.state.runId, result, queue, controller, () => cloneState(current));
132
+ }
133
+ resume(state, decisions = []) {
134
+ this.assertOpen();
135
+ validateSerializedState(state);
136
+ const agent = this.agents.get(state.agentId);
137
+ if (!agent) {
138
+ throw new RunError(`Cannot resume run ${state.runId}: agent "${state.agentId}" is not registered.`, {
139
+ code: 'AGENT_NOT_REGISTERED',
140
+ runId: state.runId,
141
+ phase: 'runtime',
142
+ });
143
+ }
144
+ if (state.agentConfigDigest !== agentDigest(agent)) {
145
+ throw new RunError(`Cannot resume run ${state.runId}: agent configuration changed.`, {
146
+ code: 'AGENT_CONFIG_MISMATCH',
147
+ runId: state.runId,
148
+ phase: 'runtime',
149
+ });
150
+ }
151
+ const input = cloneItems(state.input);
152
+ const options = {
153
+ runId: state.runId,
154
+ sessionId: state.sessionId,
155
+ tenantId: state.tenantId,
156
+ expectedSessionRevision: state.expectedSessionRevision,
157
+ workspaceId: state.workspaceId,
158
+ metadata: state.metadata,
159
+ };
160
+ const seed = {
161
+ agent: agent,
162
+ input,
163
+ options,
164
+ state: cloneState({ ...state, status: 'running' }),
165
+ decisions,
166
+ };
167
+ const limits = resolveLimits(this.defaultLimits, agent.limits);
168
+ const queue = createEventQueue(limits.streamBufferSize);
169
+ const controller = this.claimRun(state.runId);
170
+ let current = seed.state;
171
+ const result = Promise.resolve().then(() => this.executeWithSessionLock(seed, controller.signal, {
172
+ emit: async (event) => {
173
+ const processed = await this.events.dispatch(event);
174
+ if (processed)
175
+ queue.push(processed);
176
+ },
177
+ update: next => { current = next; },
178
+ streamModel: true,
179
+ })).finally(() => {
180
+ queue.close();
181
+ this.releaseRun(state.runId, controller);
182
+ });
183
+ void result.catch(() => undefined);
184
+ this.trackSettlement(state.runId, result);
185
+ return new RuntimeRunHandle(state.runId, result, queue, controller, () => cloneState(current));
186
+ }
187
+ inspectMiddleware(agent) {
188
+ return (agent ? this.pipelineFor(agent) : this.middleware).format();
189
+ }
190
+ /**
191
+ * Run the explicit handoff lifecycle stage before orchestration transfers
192
+ * conversation ownership. This keeps orchestration host-driven while making
193
+ * the runtime middleware contract effective on the real handoff path.
194
+ */
195
+ async beforeHandoff(request) {
196
+ this.assertOpen();
197
+ if (!request.sourceAgentId.trim())
198
+ throw new TypeError('Handoff sourceAgentId must not be empty.');
199
+ if (!request.handoffId.trim())
200
+ throw new TypeError('Handoff id must not be empty.');
201
+ if (!request.parentRunId.trim())
202
+ throw new TypeError('Handoff parentRunId must not be empty.');
203
+ assertAgentSpec(request.targetAgent);
204
+ request.signal.throwIfAborted();
205
+ const sourceAgent = this.agents.get(request.sourceAgentId);
206
+ const pipeline = sourceAgent ? this.pipelineFor(sourceAgent) : this.middleware;
207
+ const deadline = request.deadline === undefined
208
+ ? undefined
209
+ : { expiresAt: request.deadline, scope: `handoff:${request.handoffId}` };
210
+ const context = {
211
+ runtime: this,
212
+ services: this.services,
213
+ sourceAgent,
214
+ targetAgent: request.targetAgent,
215
+ sourceAgentId: request.sourceAgentId,
216
+ parentRunId: request.parentRunId,
217
+ handoffId: request.handoffId,
218
+ input: cloneItems(request.input),
219
+ metadata: request.metadata,
220
+ signal: request.signal,
221
+ deadline,
222
+ };
223
+ const prepared = await pipeline.runWithErrorStage(MiddlewareStage.BeforeHandoff, context, stageContext => stageContext.input);
224
+ if (!Array.isArray(prepared)) {
225
+ throw new MiddlewareInvariantViolationError(MiddlewareStage.BeforeHandoff, request.parentRunId, 'beforeHandoff middleware must return canonical input items.');
226
+ }
227
+ return cloneItems(prepared);
228
+ }
229
+ async close() {
230
+ if (this.closed)
231
+ return;
232
+ this.closed = true;
233
+ for (const controller of this.activeRuns.values()) {
234
+ controller.abort(abortError('AgentRuntime closed.'));
235
+ }
236
+ await Promise.allSettled([...this.activeSettlements.values()]);
237
+ this.activeRuns.clear();
238
+ const results = await Promise.allSettled([this.events.close(), this.services.close()]);
239
+ const failures = results
240
+ .filter((result) => result.status === 'rejected')
241
+ .map(result => result.reason);
242
+ if (failures.length > 0)
243
+ throw new AggregateError(failures, 'AgentRuntime close failed.');
244
+ }
245
+ createSeed(agent, input, options) {
246
+ assertAgentSpec(agent);
247
+ this.registerAgent(agent);
248
+ const runId = options.runId ?? randomUUID();
249
+ const trace = options.parentTrace && options.parentRunId
250
+ ? childTrace(runId, options.parentRunId, options.parentTrace)
251
+ : createRootTraceContext(runId);
252
+ const startedAt = new Date().toISOString();
253
+ const limits = resolveLimits(this.defaultLimits, agent.limits);
254
+ const normalizedInput = normalizeInput(input);
255
+ return {
256
+ agent,
257
+ input: normalizedInput,
258
+ options,
259
+ state: {
260
+ schemaVersion: 1,
261
+ runId,
262
+ agentId: agent.id,
263
+ agentConfigDigest: agentDigest(agent),
264
+ status: 'running',
265
+ trace,
266
+ startedAt,
267
+ deadlineAt: new Date(Date.now() + limits.runDeadlineMs).toISOString(),
268
+ turn: 0,
269
+ input: cloneItems(normalizedInput),
270
+ transcript: cloneItems(normalizedInput),
271
+ generatedItems: [],
272
+ usage: emptyUsage(),
273
+ sessionId: options.sessionId,
274
+ tenantId: options.tenantId,
275
+ expectedSessionRevision: options.expectedSessionRevision,
276
+ workspaceId: options.workspaceId,
277
+ childRunIds: [],
278
+ metadata: options.metadata ?? {},
279
+ },
280
+ };
281
+ }
282
+ async execute(seed, parentSignal, observer) {
283
+ const { agent, options } = seed;
284
+ const pipeline = this.pipelineFor(agent);
285
+ const limits = resolveLimits(this.defaultLimits, agent.limits);
286
+ const persistedDeadline = seed.state.deadlineAt === undefined
287
+ ? undefined
288
+ : Date.parse(seed.state.deadlineAt);
289
+ if (persistedDeadline !== undefined && !Number.isFinite(persistedDeadline)) {
290
+ throw new RunError('Serialized run deadline is invalid.', {
291
+ code: 'RUN_DEADLINE_INVALID', runId: seed.state.runId, phase: 'runtime',
292
+ });
293
+ }
294
+ const runTimeoutMs = persistedDeadline === undefined
295
+ ? limits.runDeadlineMs
296
+ : Math.max(0, persistedDeadline - Date.now());
297
+ const boundary = createBoundary(parentSignal, runTimeoutMs, 'Run deadline exceeded.');
298
+ const signal = boundary.signal;
299
+ const usage = new UsageAccumulator(seed.state.usage);
300
+ let state = cloneState(seed.state);
301
+ let lastResponse;
302
+ const sequencer = new RunEventSequencer(state.trace);
303
+ const runContext = {
304
+ runId: state.runId,
305
+ agentId: agent.id,
306
+ context: options.context,
307
+ signal,
308
+ startedAt: state.startedAt,
309
+ deadlineAt: state.deadlineAt,
310
+ sessionId: state.sessionId,
311
+ metadata: state.metadata,
312
+ usage,
313
+ };
314
+ const deadline = {
315
+ expiresAt: Date.parse(state.deadlineAt ?? new Date(Date.now() + limits.runDeadlineMs).toISOString()),
316
+ scope: `run:${state.runId}`,
317
+ };
318
+ const emit = async (type, data) => {
319
+ await observer.emit(sequencer.next(type, data));
320
+ };
321
+ const update = async (patch = {}) => {
322
+ state = cloneState({ ...state, ...patch, usage: usage.snapshot() });
323
+ observer.update(state);
324
+ await this.checkpointStore?.save(state);
325
+ };
326
+ const middlewareContext = (extra = {}) => ({
327
+ runtime: this,
328
+ services: this.services,
329
+ agent: agent,
330
+ run: runContext,
331
+ state,
332
+ signal,
333
+ deadline,
334
+ ...extra,
335
+ });
336
+ await emit(seed.decisions ? 'run.resumed' : 'run.started', { agentId: agent.id });
337
+ try {
338
+ let preparedInput = await pipeline.runWithErrorStage(MiddlewareStage.PrepareInput, middlewareContext({ input: seed.input }), context => Promise.resolve(context.input ?? seed.input));
339
+ if (state.turn === 0 && state.sessionId) {
340
+ const sessionStore = await this.resolveSessionStore(state.runId);
341
+ const loaded = await sessionStore.load({
342
+ tenantId: state.tenantId ?? 'default',
343
+ sessionId: state.sessionId,
344
+ });
345
+ preparedInput = [...loaded.items, ...preparedInput];
346
+ await update({ expectedSessionRevision: loaded.revision });
347
+ await emit('session.loaded', {
348
+ sessionId: state.sessionId,
349
+ revision: loaded.revision,
350
+ itemCount: loaded.items.length,
351
+ });
352
+ }
353
+ if (state.turn > 0 && state.sessionId) {
354
+ const sessionStore = await this.resolveSessionStore(state.runId);
355
+ const current = await sessionStore.load({
356
+ tenantId: state.tenantId ?? 'default',
357
+ sessionId: state.sessionId,
358
+ });
359
+ if (state.expectedSessionRevision !== current.revision) {
360
+ throw new RunError(`Session "${state.sessionId}" changed while run "${state.runId}" was interrupted.`, {
361
+ code: 'SESSION_REVISION_CONFLICT',
362
+ runId: state.runId,
363
+ phase: 'runtime',
364
+ details: {
365
+ expectedRevision: state.expectedSessionRevision ?? null,
366
+ actualRevision: current.revision,
367
+ },
368
+ });
369
+ }
370
+ }
371
+ const instructions = await resolveInstructions(agent, runContext);
372
+ if (instructions) {
373
+ preparedInput = [
374
+ { type: 'text', role: 'system', text: instructions },
375
+ ...preparedInput,
376
+ ];
377
+ }
378
+ if (state.turn === 0 && state.generatedItems.length === 0) {
379
+ await runInputGuardrails(agent, runContext, preparedInput);
380
+ await update({ transcript: cloneItems(preparedInput) });
381
+ await pipeline.runWithErrorStage(MiddlewareStage.BeforeRun, middlewareContext({ input: preparedInput }), () => undefined);
382
+ }
383
+ const pendingBeforeResume = state.pendingTool;
384
+ const resumed = await this.resumePendingTool(seed.decisions ?? [], state, runContext, update, emit);
385
+ if (resumed)
386
+ state = resumed;
387
+ const approval = pendingBeforeResume?.interruptionId
388
+ ? seed.decisions?.find(item => item.interruptionId === pendingBeforeResume.interruptionId)
389
+ : undefined;
390
+ if (state.pendingTool?.status === 'prepared' && approval?.outcome === 'approve') {
391
+ await this.executeToolCall(state.pendingTool.call, state, runContext, limits, pipeline, middlewareContext, update, emit, approval);
392
+ await update({ pendingTool: undefined });
393
+ }
394
+ while (state.turn < limits.maxTurns) {
395
+ signal.throwIfAborted();
396
+ const model = agent.model ?? this.defaultModel;
397
+ if (!model) {
398
+ throw new RunError(`Agent "${agent.id}" does not declare a model and no default model exists.`, {
399
+ code: 'MODEL_REQUIRED', runId: state.runId, phase: 'model_call',
400
+ });
401
+ }
402
+ const request = this.createModelRequest(agent, model, state.transcript, limits);
403
+ await emit('model.requested', { turn: state.turn + 1, model });
404
+ const modelBoundary = createBoundary(signal, limits.modelCallTimeoutMs, 'Model call deadline exceeded.');
405
+ let response;
406
+ let modelTerminalCompleted = false;
407
+ try {
408
+ response = await pipeline.runWithErrorStage(MiddlewareStage.WrapModelCall, { ...middlewareContext({ modelRequest: request }), signal: modelBoundary.signal }, async () => {
409
+ const value = await raceWithSignal(this.callModel(request, {
410
+ runId: state.runId,
411
+ traceId: state.trace.traceId,
412
+ spanId: state.trace.spanId,
413
+ signal: modelBoundary.signal,
414
+ deadline: Math.min(deadline.expiresAt, Date.now() + limits.modelCallTimeoutMs),
415
+ }, observer, emit), modelBoundary.signal);
416
+ modelTerminalCompleted = true;
417
+ return value;
418
+ });
419
+ }
420
+ finally {
421
+ modelBoundary.dispose();
422
+ }
423
+ if (!modelTerminalCompleted) {
424
+ throw new MiddlewareInvariantViolationError(MiddlewareStage.WrapModelCall, state.runId, 'wrapModelCall middleware cannot replace the provider/capability boundary; call next().');
425
+ }
426
+ response = validateModelResponse(response, state.runId);
427
+ usage.add(response.usage.requests > 0 ? response.usage : { ...response.usage, requests: 1 });
428
+ enforceUsageLimits(usage, limits, state.runId);
429
+ response = await pipeline.runWithErrorStage(MiddlewareStage.AfterModelResponse, middlewareContext({ modelRequest: request, modelResponse: response }), context => context.modelResponse);
430
+ response = validateModelResponse(response, state.runId);
431
+ lastResponse = response;
432
+ const nextGenerated = [...state.generatedItems, ...response.output];
433
+ const nextTranscript = [...state.transcript, ...response.output];
434
+ await update({
435
+ turn: state.turn + 1,
436
+ generatedItems: nextGenerated,
437
+ transcript: nextTranscript,
438
+ });
439
+ await emit('model.completed', {
440
+ turn: state.turn,
441
+ finishReason: response.finishReason,
442
+ usage: response.usage,
443
+ });
444
+ const toolCalls = response.output.filter((item) => item.type === 'tool_call');
445
+ if (toolCalls.length === 0)
446
+ break;
447
+ for (let index = 0; index < toolCalls.length;) {
448
+ const call = toolCalls[index];
449
+ if (this.canParallelizeReadTool(call) && limits.maxParallelTools > 1) {
450
+ const batch = [];
451
+ while (index < toolCalls.length
452
+ && batch.length < limits.maxParallelTools
453
+ && this.canParallelizeReadTool(toolCalls[index])) {
454
+ batch.push(toolCalls[index]);
455
+ index += 1;
456
+ }
457
+ const results = await Promise.all(batch.map(item => this.executeReadToolCall(item, state, runContext, limits, pipeline, middlewareContext, emit)));
458
+ await update({
459
+ generatedItems: [...state.generatedItems, ...results],
460
+ transcript: [...state.transcript, ...results],
461
+ });
462
+ continue;
463
+ }
464
+ await this.executeToolCall(call, state, runContext, limits, pipeline, middlewareContext, update, emit);
465
+ await update({ pendingTool: undefined });
466
+ index += 1;
467
+ }
468
+ await pipeline.runWithErrorStage(MiddlewareStage.AfterTurn, middlewareContext(), () => undefined);
469
+ }
470
+ if (!lastResponse && state.status !== 'running') {
471
+ return this.interruptedResult(agent, state);
472
+ }
473
+ if (!lastResponse) {
474
+ throw new RunError('Run has no model response.', {
475
+ code: 'EMPTY_MODEL_RESPONSE', runId: state.runId, phase: 'finalize_output',
476
+ });
477
+ }
478
+ if (state.turn >= limits.maxTurns && lastResponse.output.some(item => item.type === 'tool_call')) {
479
+ throw new RunError(`Run exceeded maxTurns=${limits.maxTurns}.`, {
480
+ code: 'MAX_TURNS_EXCEEDED', runId: state.runId, phase: 'runtime',
481
+ });
482
+ }
483
+ let output = await pipeline.runWithErrorStage(MiddlewareStage.FinalizeOutput, middlewareContext({ modelResponse: lastResponse }), () => finalizeOutput(agent, lastResponse));
484
+ await runOutputGuardrails(agent, runContext, output);
485
+ if (state.sessionId) {
486
+ const sessionStore = await this.resolveSessionStore(state.runId);
487
+ const committed = await sessionStore.append({
488
+ tenantId: state.tenantId ?? 'default',
489
+ sessionId: state.sessionId,
490
+ items: [...state.input, ...state.generatedItems],
491
+ expectedRevision: state.expectedSessionRevision ?? '0',
492
+ });
493
+ await update({ expectedSessionRevision: committed.revision });
494
+ await emit('session.committed', {
495
+ sessionId: state.sessionId,
496
+ revision: committed.revision,
497
+ });
498
+ }
499
+ const completedAt = new Date().toISOString();
500
+ let result = {
501
+ runId: state.runId,
502
+ agentId: agent.id,
503
+ status: 'completed',
504
+ output,
505
+ items: state.generatedItems,
506
+ usage: usage.snapshot(),
507
+ startedAt: state.startedAt,
508
+ completedAt,
509
+ sessionId: state.sessionId,
510
+ metadata: state.metadata,
511
+ };
512
+ result = await pipeline.runWithErrorStage(MiddlewareStage.AfterRun, middlewareContext({ result }), context => context.result);
513
+ await update({ status: 'completed' });
514
+ await emit('run.completed', { status: result.status, usage: result.usage });
515
+ await this.checkpointStore?.delete(state.runId);
516
+ return result;
517
+ }
518
+ catch (error) {
519
+ if (error instanceof ToolInterruptionRequiredError) {
520
+ await update({ status: 'interrupted' });
521
+ await emit('run.interrupted', {
522
+ interruptionId: error.decision.interruptionId,
523
+ reason: error.decision.reason,
524
+ });
525
+ return this.interruptedResult(agent, state);
526
+ }
527
+ if (signal.aborted) {
528
+ await update({ status: 'cancelled' });
529
+ await emit('run.cancelled', { reason: errorMessage(signal.reason ?? error) });
530
+ return {
531
+ ...this.interruptedResult(agent, state),
532
+ status: 'cancelled',
533
+ };
534
+ }
535
+ await update({ status: 'failed' });
536
+ await emit('run.failed', { error: serializeError(error) });
537
+ throw error;
538
+ }
539
+ finally {
540
+ boundary.dispose();
541
+ }
542
+ }
543
+ createModelRequest(agent, model, input, limits) {
544
+ const tools = [];
545
+ for (const ref of agent.tools ?? []) {
546
+ const name = typeof ref === 'string' ? ref : ref.id;
547
+ const tool = this.tools.resolve(name);
548
+ if (!tool)
549
+ throw new RunError(`Agent "${agent.id}" references unknown tool "${name}".`, {
550
+ code: 'TOOL_NOT_FOUND', phase: 'before_run',
551
+ });
552
+ tools.push({
553
+ name: tool.descriptor.name,
554
+ description: tool.descriptor.description,
555
+ inputSchema: (tool.descriptor.input.jsonSchema ?? {}),
556
+ });
557
+ }
558
+ return {
559
+ model,
560
+ input,
561
+ tools: tools.length > 0 ? tools : undefined,
562
+ toolPolicy: tools.length > 0 ? 'auto' : 'none',
563
+ outputSchema: agent.output
564
+ ? {
565
+ name: agent.output.name,
566
+ schema: agent.output.schema,
567
+ description: agent.output.description,
568
+ strict: agent.output.strict,
569
+ }
570
+ : undefined,
571
+ maxOutputTokens: Math.min(limits.maxOutputTokens, 64_000),
572
+ };
573
+ }
574
+ async callModel(request, context, observer, emit) {
575
+ if (!observer.streamModel)
576
+ return this.models.generate(request, context);
577
+ const stream = this.models.stream(request, context);
578
+ const onAbort = () => stream.cancel(context.signal?.reason);
579
+ context.signal?.addEventListener('abort', onAbort, { once: true });
580
+ try {
581
+ for await (const event of stream) {
582
+ await emitModelStreamEvent(event, emit);
583
+ }
584
+ return await stream.finalResponse();
585
+ }
586
+ finally {
587
+ context.signal?.removeEventListener('abort', onAbort);
588
+ if (context.signal?.aborted)
589
+ stream.cancel(context.signal.reason);
590
+ }
591
+ }
592
+ async executeToolCall(call, state, runContext, limits, pipeline, middlewareContext, update, emit, approval) {
593
+ const definition = this.tools.resolve(call.name);
594
+ const effect = definition ? toolEffect(definition.descriptor) : 'side-effect';
595
+ const pending = { call, effect, status: 'prepared' };
596
+ await update({ pendingTool: pending });
597
+ await pipeline.runWithErrorStage(MiddlewareStage.BeforeToolCall, middlewareContext({ toolCall: call }), () => undefined);
598
+ await update({ pendingTool: { ...pending, status: 'started' } });
599
+ await emit('tool.started', { callId: call.id, name: call.name, effect });
600
+ try {
601
+ let toolTerminalCompleted = false;
602
+ let toolTerminalOutput;
603
+ const output = await pipeline.runWithErrorStage(MiddlewareStage.WrapToolCall, middlewareContext({ toolCall: call }), async () => {
604
+ const value = await this.toolRunner.execute(call.name, call.input, {
605
+ runId: state.runId,
606
+ callId: call.id,
607
+ signal: runContext.signal,
608
+ deadline: Date.now() + limits.toolTimeoutMs,
609
+ context: runContext.context,
610
+ idempotencyKey: effect === 'idempotent-write' ? `${state.runId}:${call.id}` : undefined,
611
+ approval: approval
612
+ ? {
613
+ interruptionId: approval.interruptionId,
614
+ outcome: 'approve',
615
+ metadata: approval.metadata,
616
+ }
617
+ : undefined,
618
+ workspaceId: state.workspaceId,
619
+ metadata: state.metadata,
620
+ });
621
+ toolTerminalOutput = freezeToolOutput(validateToolTerminalOutput(definition, value, call, state.runId));
622
+ toolTerminalCompleted = true;
623
+ return toolTerminalOutput;
624
+ });
625
+ if (!toolTerminalCompleted) {
626
+ throw new MiddlewareInvariantViolationError(MiddlewareStage.WrapToolCall, state.runId, 'wrapToolCall middleware cannot replace ToolRunner policy/schema validation; call next().');
627
+ }
628
+ if (output !== toolTerminalOutput) {
629
+ throw new MiddlewareInvariantViolationError(MiddlewareStage.WrapToolCall, state.runId, 'wrapToolCall middleware must return the validated ToolRunner output unchanged.');
630
+ }
631
+ const validatedOutput = output;
632
+ const normalizedOutput = toJsonValue(validatedOutput.value, call.name);
633
+ const result = {
634
+ type: 'tool_result',
635
+ callId: call.id,
636
+ name: call.name,
637
+ status: 'success',
638
+ output: normalizedOutput,
639
+ };
640
+ await pipeline.runWithErrorStage(MiddlewareStage.AfterToolCall, middlewareContext({ toolCall: call, toolOutput: validatedOutput }), () => undefined);
641
+ await update({
642
+ pendingTool: { ...pending, status: 'committed', result },
643
+ generatedItems: [...state.generatedItems, result],
644
+ transcript: [...state.transcript, result],
645
+ });
646
+ await emit('tool.completed', {
647
+ callId: call.id,
648
+ name: call.name,
649
+ artifacts: validatedOutput.artifacts,
650
+ });
651
+ }
652
+ catch (error) {
653
+ if (error instanceof ToolInterruptionRequiredError) {
654
+ await update({
655
+ pendingTool: {
656
+ ...pending,
657
+ status: 'awaiting_approval',
658
+ interruptionId: error.decision.interruptionId,
659
+ },
660
+ });
661
+ throw error;
662
+ }
663
+ if (!(error instanceof ToolExecutionError))
664
+ throw error;
665
+ const result = {
666
+ type: 'tool_result',
667
+ callId: call.id,
668
+ name: call.name,
669
+ status: 'error',
670
+ output: {
671
+ kind: error.failure.kind,
672
+ message: this.toolRunner.formatFailure(error),
673
+ retryable: error.failure.retryable,
674
+ },
675
+ };
676
+ await update({
677
+ pendingTool: { ...pending, status: 'committed', result },
678
+ generatedItems: [...state.generatedItems, result],
679
+ transcript: [...state.transcript, result],
680
+ });
681
+ await emit('tool.failed', { callId: call.id, name: call.name, failure: error.failure });
682
+ }
683
+ }
684
+ canParallelizeReadTool(call) {
685
+ if (this.hasToolPolicy)
686
+ return false;
687
+ const tool = this.tools.resolve(call.name);
688
+ return tool !== undefined
689
+ && toolEffect(tool.descriptor) === 'read'
690
+ && tool.descriptor.behavior?.requiresApproval !== true;
691
+ }
692
+ async executeReadToolCall(call, state, runContext, limits, pipeline, middlewareContext, emit) {
693
+ const definition = this.tools.resolve(call.name);
694
+ await pipeline.runWithErrorStage(MiddlewareStage.BeforeToolCall, middlewareContext({ toolCall: call }), () => undefined);
695
+ await emit('tool.started', { callId: call.id, name: call.name, effect: 'read' });
696
+ try {
697
+ let toolTerminalCompleted = false;
698
+ let toolTerminalOutput;
699
+ const output = await pipeline.runWithErrorStage(MiddlewareStage.WrapToolCall, middlewareContext({ toolCall: call }), async () => {
700
+ const value = await this.toolRunner.execute(call.name, call.input, {
701
+ runId: state.runId,
702
+ callId: call.id,
703
+ signal: runContext.signal,
704
+ deadline: Date.now() + limits.toolTimeoutMs,
705
+ context: runContext.context,
706
+ workspaceId: state.workspaceId,
707
+ metadata: state.metadata,
708
+ });
709
+ toolTerminalOutput = freezeToolOutput(validateToolTerminalOutput(definition, value, call, state.runId));
710
+ toolTerminalCompleted = true;
711
+ return toolTerminalOutput;
712
+ });
713
+ if (!toolTerminalCompleted) {
714
+ throw new MiddlewareInvariantViolationError(MiddlewareStage.WrapToolCall, state.runId, 'wrapToolCall middleware cannot replace ToolRunner schema validation; call next().');
715
+ }
716
+ if (output !== toolTerminalOutput) {
717
+ throw new MiddlewareInvariantViolationError(MiddlewareStage.WrapToolCall, state.runId, 'wrapToolCall middleware must return the validated ToolRunner output unchanged.');
718
+ }
719
+ const validatedOutput = output;
720
+ await pipeline.runWithErrorStage(MiddlewareStage.AfterToolCall, middlewareContext({ toolCall: call, toolOutput: validatedOutput }), () => undefined);
721
+ const result = {
722
+ type: 'tool_result',
723
+ callId: call.id,
724
+ name: call.name,
725
+ status: 'success',
726
+ output: toJsonValue(validatedOutput.value, call.name),
727
+ };
728
+ await emit('tool.completed', {
729
+ callId: call.id,
730
+ name: call.name,
731
+ artifacts: validatedOutput.artifacts,
732
+ });
733
+ return result;
734
+ }
735
+ catch (error) {
736
+ if (!(error instanceof ToolExecutionError))
737
+ throw error;
738
+ const result = toolFailureResult(call, error, this.toolRunner.formatFailure(error));
739
+ await emit('tool.failed', { callId: call.id, name: call.name, failure: error.failure });
740
+ return result;
741
+ }
742
+ }
743
+ async resumePendingTool(decisions, state, runContext, update, emit) {
744
+ const pending = state.pendingTool;
745
+ if (!pending)
746
+ return undefined;
747
+ if (pending.status === 'committed' && pending.result) {
748
+ const alreadyPresent = state.transcript.some(item => item.type === 'tool_result' && item.callId === pending.call.id);
749
+ if (!alreadyPresent) {
750
+ const next = cloneState({
751
+ ...state,
752
+ transcript: [...state.transcript, pending.result],
753
+ generatedItems: [...state.generatedItems, pending.result],
754
+ pendingTool: undefined,
755
+ });
756
+ await update(next);
757
+ return next;
758
+ }
759
+ await update({ pendingTool: undefined });
760
+ return cloneState({ ...state, pendingTool: undefined });
761
+ }
762
+ if (pending.status === 'started' && pending.effect === 'side-effect') {
763
+ throw new ToolInterruptionRequiredError({
764
+ type: 'interrupt',
765
+ interruptionId: pending.interruptionId ?? `${state.runId}:${pending.call.id}:reconcile`,
766
+ reason: `Side-effect tool "${pending.call.name}" may have started; manual reconciliation is required.`,
767
+ }, pending.call.name, pending.call.id);
768
+ }
769
+ if (pending.status !== 'awaiting_approval' || !pending.interruptionId)
770
+ return undefined;
771
+ const decision = decisions.find(item => item.interruptionId === pending.interruptionId);
772
+ if (!decision) {
773
+ throw new ToolInterruptionRequiredError({
774
+ type: 'interrupt',
775
+ interruptionId: pending.interruptionId,
776
+ reason: `Tool "${pending.call.name}" still requires a decision.`,
777
+ }, pending.call.name, pending.call.id);
778
+ }
779
+ if (decision.outcome === 'reject') {
780
+ const result = {
781
+ type: 'tool_result', callId: pending.call.id, name: pending.call.name, status: 'error',
782
+ output: { kind: 'denied', message: decision.reason ?? 'Approval rejected.', retryable: false },
783
+ };
784
+ const next = cloneState({
785
+ ...state,
786
+ pendingTool: undefined,
787
+ transcript: [...state.transcript, result],
788
+ generatedItems: [...state.generatedItems, result],
789
+ });
790
+ await update(next);
791
+ await emit('tool.rejected', { callId: pending.call.id, name: pending.call.name });
792
+ return next;
793
+ }
794
+ await update({ pendingTool: { ...pending, status: 'prepared' } });
795
+ void runContext;
796
+ return cloneState({ ...state, pendingTool: { ...pending, status: 'prepared' } });
797
+ }
798
+ interruptedResult(agent, state) {
799
+ return {
800
+ runId: state.runId,
801
+ agentId: agent.id,
802
+ status: state.status === 'cancelled' ? 'cancelled' : 'interrupted',
803
+ output: '',
804
+ items: state.generatedItems,
805
+ usage: state.usage,
806
+ startedAt: state.startedAt,
807
+ completedAt: new Date().toISOString(),
808
+ sessionId: state.sessionId,
809
+ metadata: state.metadata,
810
+ };
811
+ }
812
+ claimRun(runId, externalSignal) {
813
+ if (this.activeRuns.has(runId))
814
+ throw new Error(`Run "${runId}" is already active.`);
815
+ const controller = new AbortController();
816
+ if (externalSignal?.aborted)
817
+ controller.abort(externalSignal.reason);
818
+ else
819
+ externalSignal?.addEventListener('abort', () => controller.abort(externalSignal.reason), { once: true });
820
+ this.activeRuns.set(runId, controller);
821
+ return controller;
822
+ }
823
+ releaseRun(runId, controller) {
824
+ if (this.activeRuns.get(runId) === controller)
825
+ this.activeRuns.delete(runId);
826
+ }
827
+ trackSettlement(runId, operation) {
828
+ const settlement = operation.then(() => undefined, () => undefined);
829
+ this.activeSettlements.set(runId, settlement);
830
+ void settlement.then(() => {
831
+ if (this.activeSettlements.get(runId) === settlement) {
832
+ this.activeSettlements.delete(runId);
833
+ }
834
+ });
835
+ }
836
+ assertOpen() {
837
+ if (this.closed)
838
+ throw new Error('AgentRuntime is closed.');
839
+ }
840
+ executeWithSessionLock(seed, signal, observer) {
841
+ const execute = () => this.runConcurrency.run(() => this.execute(seed, signal, observer), signal);
842
+ if (!seed.state.sessionId)
843
+ return execute();
844
+ const key = `${seed.state.tenantId ?? 'default'}\u0000${seed.state.sessionId}`;
845
+ // Serialize a session before taking a global run permit. Otherwise many
846
+ // turns for one busy session could occupy every permit while waiting for
847
+ // the same session lock and starve unrelated sessions.
848
+ return this.sessionTurns.runExclusive(key, execute);
849
+ }
850
+ pipelineFor(agent) {
851
+ if (!agent.middleware || agent.middleware.length === 0)
852
+ return this.middleware;
853
+ const cached = this.agentPipelines.get(agent);
854
+ if (cached)
855
+ return cached;
856
+ const pipeline = buildMiddlewarePipeline([
857
+ ...this.middleware.definitions(),
858
+ ...this.middlewareRegistry.resolve(agent.middleware),
859
+ ]);
860
+ this.agentPipelines.set(agent, pipeline);
861
+ return pipeline;
862
+ }
863
+ async resolveSessionStore(runId) {
864
+ if (!this.services.has('sessions')) {
865
+ throw new RunError('A sessionId was provided but no sessions service is registered.', {
866
+ code: 'SESSION_SERVICE_REQUIRED', runId, phase: 'runtime',
867
+ });
868
+ }
869
+ return this.services.resolve('sessions');
870
+ }
871
+ }
872
+ class RuntimeRunHandle {
873
+ runId;
874
+ result;
875
+ queue;
876
+ controller;
877
+ snapshotState;
878
+ constructor(runId, result, queue, controller, snapshotState) {
879
+ this.runId = runId;
880
+ this.result = result;
881
+ this.queue = queue;
882
+ this.controller = controller;
883
+ this.snapshotState = snapshotState;
884
+ }
885
+ cancel(reason) {
886
+ if (!this.controller.signal.aborted)
887
+ this.controller.abort(abortError(reason ?? 'Run cancelled.'));
888
+ }
889
+ snapshot() {
890
+ return Promise.resolve(this.snapshotState());
891
+ }
892
+ [Symbol.asyncIterator]() {
893
+ const iterator = this.queue[Symbol.asyncIterator]();
894
+ return {
895
+ next: () => iterator.next(),
896
+ return: async () => {
897
+ try {
898
+ await iterator.return?.();
899
+ }
900
+ finally {
901
+ this.cancel('Run event consumer stopped.');
902
+ }
903
+ return { done: true, value: undefined };
904
+ },
905
+ throw: async (error) => {
906
+ try {
907
+ await iterator.throw?.(error);
908
+ }
909
+ finally {
910
+ this.cancel('Run event consumer failed.');
911
+ }
912
+ throw error;
913
+ },
914
+ };
915
+ }
916
+ }
917
+ function createEventQueue(capacity) {
918
+ return new AsyncQueue({
919
+ capacity,
920
+ overflowStrategy: 'drop-oldest',
921
+ priorityReserve: 1,
922
+ isPriority: event => event.type.startsWith('run.') && event.type !== 'run.started',
923
+ coalesce: coalesceRunEventDelta,
924
+ });
925
+ }
926
+ function coalesceRunEventDelta(previous, incoming) {
927
+ if (previous.runId !== incoming.runId || previous.type !== incoming.type)
928
+ return undefined;
929
+ if (incoming.type !== 'model.text.delta' && incoming.type !== 'model.reasoning.delta')
930
+ return undefined;
931
+ const previousData = asRecord(previous.data);
932
+ const incomingData = asRecord(incoming.data);
933
+ const left = typeof previousData?.delta === 'string' ? previousData.delta : '';
934
+ const right = typeof incomingData?.delta === 'string' ? incomingData.delta : '';
935
+ if (!left || !right)
936
+ return undefined;
937
+ return { ...incoming, data: { ...incomingData, delta: left + right } };
938
+ }
939
+ async function emitModelStreamEvent(event, emit) {
940
+ switch (event.type) {
941
+ case 'text.delta':
942
+ await emit('model.text.delta', {
943
+ delta: event.delta,
944
+ outputIndex: event.outputIndex,
945
+ });
946
+ return;
947
+ case 'tool_call.delta':
948
+ await emit('model.tool_call.delta', {
949
+ callId: event.callId,
950
+ name: event.name,
951
+ argumentsDelta: event.argumentsDelta,
952
+ outputIndex: event.outputIndex,
953
+ });
954
+ return;
955
+ case 'reasoning.delta':
956
+ await emit('model.reasoning.delta', {
957
+ delta: event.delta,
958
+ opaque: event.opaque,
959
+ outputIndex: event.outputIndex,
960
+ });
961
+ return;
962
+ case 'usage':
963
+ await emit('model.usage', { usage: event.usage });
964
+ return;
965
+ case 'provider.event':
966
+ await emit('model.provider.event', {
967
+ provider: event.provider,
968
+ event: event.event,
969
+ });
970
+ return;
971
+ case 'response.completed':
972
+ await emit('model.response.completed', {
973
+ responseId: event.response.id,
974
+ finishReason: event.response.finishReason,
975
+ });
976
+ return;
977
+ }
978
+ }
979
+ function asRecord(value) {
980
+ return typeof value === 'object' && value !== null && !Array.isArray(value)
981
+ ? value
982
+ : undefined;
983
+ }
984
+ function normalizeInput(input) {
985
+ if (typeof input === 'string')
986
+ return [{ type: 'text', role: 'user', text: input }];
987
+ return cloneItems(Array.isArray(input) ? input : [input]);
988
+ }
989
+ function cloneItems(items) {
990
+ return structuredClone(items);
991
+ }
992
+ function cloneState(state) {
993
+ return structuredClone(state);
994
+ }
995
+ function resolveLimits(base, patch) {
996
+ const limits = { ...base, ...patch };
997
+ for (const [name, value] of Object.entries(limits)) {
998
+ if (!Number.isFinite(value) || value <= 0) {
999
+ throw new RangeError(`Run limit ${name} must be a positive finite number.`);
1000
+ }
1001
+ }
1002
+ for (const name of ['maxTurns', 'maxParallelTools', 'maxSubagentDepth', 'maxSubagentFanout', 'streamBufferSize']) {
1003
+ if (!Number.isSafeInteger(limits[name]))
1004
+ throw new RangeError(`Run limit ${name} must be a safe integer.`);
1005
+ }
1006
+ if (limits.streamBufferSize < 2)
1007
+ throw new RangeError('streamBufferSize must be at least 2.');
1008
+ return Object.freeze(limits);
1009
+ }
1010
+ function assertAgentSpec(agent) {
1011
+ if (!agent.id.trim())
1012
+ throw new TypeError('Agent id must not be empty.');
1013
+ if (!agent.name.trim())
1014
+ throw new TypeError('Agent name must not be empty.');
1015
+ if (typeof agent.instructions !== 'string' && typeof agent.instructions !== 'function') {
1016
+ throw new TypeError(`Agent "${agent.id}" instructions must be a string or function.`);
1017
+ }
1018
+ }
1019
+ async function resolveInstructions(agent, context) {
1020
+ const instructions = typeof agent.instructions === 'function'
1021
+ ? await agent.instructions(context)
1022
+ : agent.instructions;
1023
+ if (typeof instructions !== 'string')
1024
+ throw new TypeError('Agent instructions must resolve to a string.');
1025
+ return instructions;
1026
+ }
1027
+ async function runInputGuardrails(agent, context, input) {
1028
+ for (const guardrail of agent.inputGuardrails ?? []) {
1029
+ const decision = await guardrail.evaluate(context, input);
1030
+ if (!decision.allowed)
1031
+ throw new RunError(decision.reason ?? `Input guardrail ${guardrail.id} rejected input.`, {
1032
+ code: 'INPUT_GUARDRAIL_REJECTED', runId: context.runId, phase: 'prepare_input',
1033
+ });
1034
+ }
1035
+ }
1036
+ async function runOutputGuardrails(agent, context, output) {
1037
+ for (const guardrail of agent.outputGuardrails ?? []) {
1038
+ const decision = await guardrail.evaluate(context, output);
1039
+ if (!decision.allowed)
1040
+ throw new RunError(decision.reason ?? `Output guardrail ${guardrail.id} rejected output.`, {
1041
+ code: 'OUTPUT_GUARDRAIL_REJECTED', runId: context.runId, phase: 'finalize_output',
1042
+ });
1043
+ }
1044
+ }
1045
+ function finalizeOutput(agent, response) {
1046
+ if (agent.output) {
1047
+ if (response.structuredOutput === undefined)
1048
+ throw new RunError(`Model did not return structured output for schema "${agent.output.name}".`, { code: 'STRUCTURED_OUTPUT_MISSING', phase: 'finalize_output' });
1049
+ return agent.output.parse
1050
+ ? agent.output.parse(response.structuredOutput)
1051
+ : response.structuredOutput;
1052
+ }
1053
+ return response.output
1054
+ .filter(item => item.type === 'text' && item.role === 'assistant')
1055
+ .map(item => item.type === 'text' ? item.text : '')
1056
+ .join('');
1057
+ }
1058
+ function enforceUsageLimits(usage, limits, runId) {
1059
+ const value = usage.snapshot();
1060
+ if (value.totalTokens > limits.maxTotalTokens || value.costUsd > limits.maxCostUsd) {
1061
+ throw new RunError('Run usage budget exceeded.', {
1062
+ code: 'USAGE_LIMIT_EXCEEDED', runId, phase: 'model_call',
1063
+ details: { totalTokens: value.totalTokens, costUsd: value.costUsd },
1064
+ });
1065
+ }
1066
+ }
1067
+ const MODEL_FINISH_REASONS = new Set([
1068
+ 'stop',
1069
+ 'length',
1070
+ 'tool_calls',
1071
+ 'content_filter',
1072
+ 'refusal',
1073
+ 'cancelled',
1074
+ 'error',
1075
+ 'unknown',
1076
+ ]);
1077
+ const OUTPUT_ITEM_TYPES = new Set([
1078
+ 'text',
1079
+ 'image',
1080
+ 'audio',
1081
+ 'document',
1082
+ 'artifact_ref',
1083
+ 'tool_call',
1084
+ 'tool_result',
1085
+ 'handoff_call',
1086
+ 'handoff_result',
1087
+ 'reasoning',
1088
+ 'raw',
1089
+ 'structured',
1090
+ 'refusal',
1091
+ 'error',
1092
+ ]);
1093
+ function validateModelResponse(response, runId) {
1094
+ try {
1095
+ if (!response || typeof response !== 'object')
1096
+ throw new TypeError('response must be an object');
1097
+ if (typeof response.id !== 'string' || response.id.trim().length === 0) {
1098
+ throw new TypeError('response.id must be a non-empty string');
1099
+ }
1100
+ if (!response.model
1101
+ || typeof response.model.providerId !== 'string'
1102
+ || response.model.providerId.trim().length === 0
1103
+ || typeof response.model.modelId !== 'string'
1104
+ || response.model.modelId.trim().length === 0) {
1105
+ throw new TypeError('response.model must identify a provider and model');
1106
+ }
1107
+ if (!MODEL_FINISH_REASONS.has(response.finishReason)) {
1108
+ throw new TypeError(`response.finishReason is invalid: ${String(response.finishReason)}`);
1109
+ }
1110
+ if (!Array.isArray(response.output))
1111
+ throw new TypeError('response.output must be an array');
1112
+ assertJsonValue(response.output, 'Model response output');
1113
+ for (const item of response.output) {
1114
+ if (!item || typeof item !== 'object' || !OUTPUT_ITEM_TYPES.has(item.type)) {
1115
+ throw new TypeError(`response.output contains an unknown item type: ${String(item?.type)}`);
1116
+ }
1117
+ }
1118
+ if (response.structuredOutput !== undefined) {
1119
+ assertJsonValue(response.structuredOutput, 'Model structured output');
1120
+ }
1121
+ if (response.rawResponse !== undefined) {
1122
+ assertJsonValue(response.rawResponse, 'Raw model response');
1123
+ }
1124
+ const validatedUsage = new UsageAccumulator(response.usage).snapshot();
1125
+ return { ...response, usage: validatedUsage };
1126
+ }
1127
+ catch (cause) {
1128
+ throw new MiddlewareInvariantViolationError(MiddlewareStage.WrapModelCall, runId, 'Model middleware returned a response that violates the canonical response contract.', cause);
1129
+ }
1130
+ }
1131
+ function validateToolTerminalOutput(definition, output, call, runId) {
1132
+ try {
1133
+ if (!definition)
1134
+ throw new TypeError(`Unknown tool "${call.name}".`);
1135
+ if (!output || typeof output !== 'object' || !Object.hasOwn(output, 'value')) {
1136
+ throw new TypeError('tool middleware must return a ToolOutput object');
1137
+ }
1138
+ const candidate = output;
1139
+ assertJsonValue(candidate.value, `Output from tool "${call.name}"`);
1140
+ if (candidate.modelText !== undefined && typeof candidate.modelText !== 'string') {
1141
+ throw new TypeError('ToolOutput.modelText must be a string');
1142
+ }
1143
+ if (candidate.artifacts !== undefined) {
1144
+ if (!Array.isArray(candidate.artifacts))
1145
+ throw new TypeError('ToolOutput.artifacts must be an array');
1146
+ for (const artifact of candidate.artifacts) {
1147
+ if (!artifact || typeof artifact.id !== 'string' || artifact.id.trim().length === 0) {
1148
+ throw new TypeError('Every tool artifact must have a non-empty id');
1149
+ }
1150
+ }
1151
+ }
1152
+ return candidate;
1153
+ }
1154
+ catch (cause) {
1155
+ throw new MiddlewareInvariantViolationError(MiddlewareStage.WrapToolCall, runId, `Tool middleware returned invalid output for "${call.name}".`, cause);
1156
+ }
1157
+ }
1158
+ function freezeToolOutput(output) {
1159
+ deepFreezeJson(output.value);
1160
+ if (output.artifacts) {
1161
+ for (const artifact of output.artifacts)
1162
+ Object.freeze(artifact);
1163
+ Object.freeze(output.artifacts);
1164
+ }
1165
+ return Object.freeze(output);
1166
+ }
1167
+ function deepFreezeJson(value) {
1168
+ if (value === null || typeof value !== 'object' || Object.isFrozen(value))
1169
+ return;
1170
+ for (const child of Array.isArray(value) ? value : Object.values(value)) {
1171
+ deepFreezeJson(child);
1172
+ }
1173
+ Object.freeze(value);
1174
+ }
1175
+ function toJsonValue(value, toolName) {
1176
+ assertJsonValue(value, `Output from tool "${toolName}"`);
1177
+ return value;
1178
+ }
1179
+ function toolFailureResult(call, error, formatted) {
1180
+ return {
1181
+ type: 'tool_result',
1182
+ callId: call.id,
1183
+ name: call.name,
1184
+ status: 'error',
1185
+ output: {
1186
+ kind: error.failure.kind,
1187
+ message: formatted,
1188
+ retryable: error.failure.retryable,
1189
+ },
1190
+ };
1191
+ }
1192
+ /** Fair, abort-aware gate for top-level runtime work. */
1193
+ class RunConcurrencyGate {
1194
+ capacity;
1195
+ waiters = [];
1196
+ active = 0;
1197
+ constructor(capacity) {
1198
+ this.capacity = capacity;
1199
+ if (!Number.isSafeInteger(capacity) || capacity < 1) {
1200
+ throw new RangeError('maxConcurrentRuns must be a positive safe integer.');
1201
+ }
1202
+ }
1203
+ async run(operation, signal) {
1204
+ try {
1205
+ await this.acquire(signal);
1206
+ }
1207
+ catch (error) {
1208
+ // Runtime cancellation is a normal terminal result, not a rejected
1209
+ // top-level run. Let the state machine emit/return that result without
1210
+ // consuming a permit when cancellation happens in the wait queue.
1211
+ if (signal.aborted)
1212
+ return operation();
1213
+ throw error;
1214
+ }
1215
+ try {
1216
+ return await operation();
1217
+ }
1218
+ finally {
1219
+ this.release();
1220
+ }
1221
+ }
1222
+ acquire(signal) {
1223
+ if (signal.aborted) {
1224
+ return Promise.reject(signal.reason ?? abortError('Run cancelled before execution.'));
1225
+ }
1226
+ if (this.active < this.capacity) {
1227
+ this.active += 1;
1228
+ return Promise.resolve();
1229
+ }
1230
+ return new Promise((resolve, reject) => {
1231
+ let waiter;
1232
+ const onAbort = () => {
1233
+ const index = this.waiters.indexOf(waiter);
1234
+ if (index >= 0)
1235
+ this.waiters.splice(index, 1);
1236
+ reject(signal.reason ?? abortError('Run cancelled while waiting for execution.'));
1237
+ };
1238
+ waiter = { signal, resolve, reject, onAbort };
1239
+ this.waiters.push(waiter);
1240
+ signal.addEventListener('abort', onAbort, { once: true });
1241
+ if (signal.aborted)
1242
+ onAbort();
1243
+ });
1244
+ }
1245
+ release() {
1246
+ this.active -= 1;
1247
+ while (this.waiters.length > 0) {
1248
+ const waiter = this.waiters.shift();
1249
+ waiter.signal.removeEventListener('abort', waiter.onAbort);
1250
+ if (waiter.signal.aborted) {
1251
+ waiter.reject(waiter.signal.reason ?? abortError('Run cancelled while waiting for execution.'));
1252
+ continue;
1253
+ }
1254
+ this.active += 1;
1255
+ waiter.resolve();
1256
+ return;
1257
+ }
1258
+ }
1259
+ }
1260
+ function createBoundary(parent, timeoutMs, message) {
1261
+ const controller = new AbortController();
1262
+ const onAbort = () => controller.abort(parent.reason);
1263
+ parent.addEventListener('abort', onAbort, { once: true });
1264
+ if (parent.aborted)
1265
+ onAbort();
1266
+ let timer;
1267
+ if (!controller.signal.aborted && timeoutMs <= 0) {
1268
+ controller.abort(abortError(message));
1269
+ }
1270
+ else if (!controller.signal.aborted) {
1271
+ timer = setTimeout(() => controller.abort(abortError(message)), timeoutMs);
1272
+ timer.unref?.();
1273
+ }
1274
+ return {
1275
+ signal: controller.signal,
1276
+ dispose: () => {
1277
+ if (timer)
1278
+ clearTimeout(timer);
1279
+ parent.removeEventListener('abort', onAbort);
1280
+ },
1281
+ };
1282
+ }
1283
+ function raceWithSignal(operation, signal) {
1284
+ if (signal.aborted)
1285
+ return Promise.reject(signal.reason ?? abortError('Operation aborted.'));
1286
+ return new Promise((resolve, reject) => {
1287
+ const onAbort = () => reject(signal.reason ?? abortError('Operation aborted.'));
1288
+ signal.addEventListener('abort', onAbort, { once: true });
1289
+ operation.then(value => { signal.removeEventListener('abort', onAbort); resolve(value); }, error => { signal.removeEventListener('abort', onAbort); reject(error); });
1290
+ });
1291
+ }
1292
+ function abortError(message) {
1293
+ const error = new Error(message);
1294
+ error.name = 'AbortError';
1295
+ return error;
1296
+ }
1297
+ function errorMessage(error) {
1298
+ return error instanceof Error ? error.message : String(error);
1299
+ }
1300
+ function serializeError(error) {
1301
+ return error instanceof Error
1302
+ ? { name: error.name, message: error.message }
1303
+ : { name: 'Error', message: String(error) };
1304
+ }
1305
+ function validateSerializedState(state) {
1306
+ if (state.schemaVersion !== 1)
1307
+ throw new TypeError(`Unsupported run state version ${state.schemaVersion}.`);
1308
+ if (!state.runId || !state.agentId)
1309
+ throw new TypeError('Serialized run state is missing identity.');
1310
+ }
1311
+ function agentDigest(agent) {
1312
+ const value = JSON.stringify({
1313
+ id: agent.id,
1314
+ name: agent.name,
1315
+ description: agent.description,
1316
+ instructions: typeof agent.instructions === 'string' ? agent.instructions : '[function]',
1317
+ model: agent.model,
1318
+ tools: agent.tools,
1319
+ handoffs: agent.handoffs?.map(handoff => ({ id: handoff.id, targetAgentId: handoff.targetAgentId })),
1320
+ output: agent.output ? { name: agent.output.name, schema: agent.output.schema, strict: agent.output.strict } : undefined,
1321
+ limits: agent.limits,
1322
+ metadata: agent.metadata,
1323
+ });
1324
+ let hash = 2166136261;
1325
+ for (let index = 0; index < value.length; index += 1) {
1326
+ hash ^= value.charCodeAt(index);
1327
+ hash = Math.imul(hash, 16777619);
1328
+ }
1329
+ return `fnv1a32:${(hash >>> 0).toString(16).padStart(8, '0')}`;
1330
+ }
1331
+ function childTrace(runId, parentRunId, parent) {
1332
+ const trace = createRootTraceContext(runId);
1333
+ return {
1334
+ runId,
1335
+ parentRunId,
1336
+ traceId: parent.traceId,
1337
+ spanId: trace.spanId,
1338
+ parentSpanId: parent.spanId,
1339
+ };
1340
+ }
1341
+ //# sourceMappingURL=agentRuntime.js.map