@amodalai/runtime 0.1.26 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (445) hide show
  1. package/dist/src/__fixtures__/README.md +88 -0
  2. package/dist/src/__fixtures__/e2e.test.js +211 -0
  3. package/dist/src/__fixtures__/e2e.test.js.map +1 -0
  4. package/dist/src/__fixtures__/smoke-agent/amodal.json +11 -0
  5. package/dist/src/__fixtures__/smoke-agent/automations/delivery-callback-test.json +9 -0
  6. package/dist/src/__fixtures__/smoke-agent/automations/test-auto.md +5 -0
  7. package/dist/src/__fixtures__/smoke-agent/connections/mock-api/access.json +11 -0
  8. package/dist/src/__fixtures__/smoke-agent/connections/mock-api/spec.json +4 -0
  9. package/dist/src/__fixtures__/smoke-agent/connections/mock-api/surface.md +9 -0
  10. package/dist/src/__fixtures__/smoke-agent/connections/mock-mcp/access.json +3 -0
  11. package/dist/src/__fixtures__/smoke-agent/connections/mock-mcp/spec.json +8 -0
  12. package/dist/src/__fixtures__/smoke-agent/evals/basic-eval.md +12 -0
  13. package/dist/src/__fixtures__/smoke-agent/knowledge/test-knowledge.md +3 -0
  14. package/dist/src/__fixtures__/smoke-agent/skills/test-skill/SKILL.md +11 -0
  15. package/dist/src/__fixtures__/smoke-agent/stores/test-items.json +11 -0
  16. package/dist/src/__fixtures__/smoke-agent/tools/echo_tool/handler.d.ts +18 -0
  17. package/dist/src/__fixtures__/smoke-agent/tools/echo_tool/handler.js +22 -0
  18. package/dist/src/__fixtures__/smoke-agent/tools/echo_tool/handler.js.map +1 -0
  19. package/dist/src/__fixtures__/smoke-agent/tools/echo_tool/tool.json +17 -0
  20. package/dist/src/__fixtures__/smoke.test.js +1404 -0
  21. package/dist/src/__fixtures__/smoke.test.js.map +1 -0
  22. package/dist/src/__fixtures__/test-env.d.ts +27 -0
  23. package/dist/src/__fixtures__/test-env.js +64 -0
  24. package/dist/src/__fixtures__/test-env.js.map +1 -0
  25. package/dist/src/__fixtures__/test-helpers.d.ts +30 -0
  26. package/dist/src/__fixtures__/test-helpers.js +120 -0
  27. package/dist/src/__fixtures__/test-helpers.js.map +1 -0
  28. package/dist/src/__tests__/test-providers.d.ts +40 -0
  29. package/dist/src/__tests__/test-providers.js +61 -0
  30. package/dist/src/__tests__/test-providers.js.map +1 -0
  31. package/dist/src/agent/agent-types.d.ts +22 -0
  32. package/dist/src/agent/agent-types.js.map +1 -1
  33. package/dist/src/agent/automation-bridge.d.ts +9 -0
  34. package/dist/src/agent/automation-bridge.js +26 -0
  35. package/dist/src/agent/automation-bridge.js.map +1 -1
  36. package/dist/src/agent/automation-bridge.test.js +63 -0
  37. package/dist/src/agent/automation-bridge.test.js.map +1 -1
  38. package/dist/src/agent/local-server.d.ts +1 -8
  39. package/dist/src/agent/local-server.js +398 -163
  40. package/dist/src/agent/local-server.js.map +1 -1
  41. package/dist/src/agent/local-server.test.js +14 -8
  42. package/dist/src/agent/local-server.test.js.map +1 -1
  43. package/dist/src/agent/loop-types.d.ts +254 -0
  44. package/dist/src/agent/loop-types.js +24 -0
  45. package/dist/src/agent/loop-types.js.map +1 -0
  46. package/dist/src/agent/loop.d.ts +31 -0
  47. package/dist/src/agent/loop.js +152 -0
  48. package/dist/src/agent/loop.js.map +1 -0
  49. package/dist/src/agent/loop.test.js +1594 -0
  50. package/dist/src/agent/loop.test.js.map +1 -0
  51. package/dist/src/agent/mcp-config.d.ts +28 -0
  52. package/dist/src/agent/mcp-config.js +57 -0
  53. package/dist/src/agent/mcp-config.js.map +1 -0
  54. package/dist/src/agent/page-builder.js +6 -1
  55. package/dist/src/agent/page-builder.js.map +1 -1
  56. package/dist/src/agent/proactive/delivery-router.d.ts +68 -0
  57. package/dist/src/agent/proactive/delivery-router.js +337 -0
  58. package/dist/src/agent/proactive/delivery-router.js.map +1 -0
  59. package/dist/src/agent/{stores-e2e.test.d.ts → proactive/delivery-router.test.d.ts} +1 -1
  60. package/dist/src/agent/proactive/delivery-router.test.js +455 -0
  61. package/dist/src/agent/proactive/delivery-router.test.js.map +1 -0
  62. package/dist/src/agent/proactive/proactive-runner.d.ts +46 -8
  63. package/dist/src/agent/proactive/proactive-runner.js +67 -37
  64. package/dist/src/agent/proactive/proactive-runner.js.map +1 -1
  65. package/dist/src/agent/proactive/proactive-runner.test.d.ts +1 -1
  66. package/dist/src/agent/proactive/proactive-runner.test.js +73 -87
  67. package/dist/src/agent/proactive/proactive-runner.test.js.map +1 -1
  68. package/dist/src/agent/routes/admin-chat-abort.test.d.ts +6 -0
  69. package/dist/src/agent/routes/admin-chat-abort.test.js +206 -0
  70. package/dist/src/agent/routes/admin-chat-abort.test.js.map +1 -0
  71. package/dist/src/agent/routes/admin-chat.d.ts +15 -3
  72. package/dist/src/agent/routes/admin-chat.js +61 -18
  73. package/dist/src/agent/routes/admin-chat.js.map +1 -1
  74. package/dist/src/agent/routes/automations.js +5 -6
  75. package/dist/src/agent/routes/automations.js.map +1 -1
  76. package/dist/src/agent/routes/evals.d.ts +3 -2
  77. package/dist/src/agent/routes/evals.js +25 -12
  78. package/dist/src/agent/routes/evals.js.map +1 -1
  79. package/dist/src/agent/routes/files.js +7 -9
  80. package/dist/src/agent/routes/files.js.map +1 -1
  81. package/dist/src/agent/routes/inspect.d.ts +6 -2
  82. package/dist/src/agent/routes/inspect.js +31 -17
  83. package/dist/src/agent/routes/inspect.js.map +1 -1
  84. package/dist/src/agent/routes/inspect.test.js +18 -42
  85. package/dist/src/agent/routes/inspect.test.js.map +1 -1
  86. package/dist/src/agent/routes/stores.js +9 -12
  87. package/dist/src/agent/routes/stores.js.map +1 -1
  88. package/dist/src/agent/routes/task.d.ts +15 -3
  89. package/dist/src/agent/routes/task.js +16 -7
  90. package/dist/src/agent/routes/task.js.map +1 -1
  91. package/dist/src/agent/routes/task.test.d.ts +1 -1
  92. package/dist/src/agent/routes/task.test.js +68 -53
  93. package/dist/src/agent/routes/task.test.js.map +1 -1
  94. package/dist/src/agent/routes/webhooks.js +12 -3
  95. package/dist/src/agent/routes/webhooks.js.map +1 -1
  96. package/dist/src/agent/snapshot-server.d.ts +2 -22
  97. package/dist/src/agent/snapshot-server.js +48 -27
  98. package/dist/src/agent/snapshot-server.js.map +1 -1
  99. package/dist/src/agent/states/compacting.d.ts +14 -0
  100. package/dist/src/agent/states/compacting.js +260 -0
  101. package/dist/src/agent/states/compacting.js.map +1 -0
  102. package/dist/src/agent/states/confirming.d.ts +10 -0
  103. package/dist/src/agent/states/confirming.js +79 -0
  104. package/dist/src/agent/states/confirming.js.map +1 -0
  105. package/dist/src/agent/states/dispatching.d.ts +18 -0
  106. package/dist/src/agent/states/dispatching.js +285 -0
  107. package/dist/src/agent/states/dispatching.js.map +1 -0
  108. package/dist/src/agent/states/executing.d.ts +21 -0
  109. package/dist/src/agent/states/executing.js +452 -0
  110. package/dist/src/agent/states/executing.js.map +1 -0
  111. package/dist/src/agent/states/streaming.d.ts +10 -0
  112. package/dist/src/agent/states/streaming.js +169 -0
  113. package/dist/src/agent/states/streaming.js.map +1 -0
  114. package/dist/src/agent/states/thinking.d.ts +13 -0
  115. package/dist/src/agent/states/thinking.js +450 -0
  116. package/dist/src/agent/states/thinking.js.map +1 -0
  117. package/dist/src/agent/token-estimate.d.ts +31 -0
  118. package/dist/src/agent/token-estimate.js +34 -0
  119. package/dist/src/agent/token-estimate.js.map +1 -0
  120. package/dist/src/agent/token-estimate.test.d.ts +6 -0
  121. package/dist/src/agent/token-estimate.test.js +44 -0
  122. package/dist/src/agent/token-estimate.test.js.map +1 -0
  123. package/dist/src/agent/tool-executor-local.js +9 -18
  124. package/dist/src/agent/tool-executor-local.js.map +1 -1
  125. package/dist/src/agent/tool-executor-local.test.js +3 -5
  126. package/dist/src/agent/tool-executor-local.test.js.map +1 -1
  127. package/dist/src/api/create-agent.d.ts +15 -0
  128. package/dist/src/api/create-agent.js +134 -0
  129. package/dist/src/api/create-agent.js.map +1 -0
  130. package/dist/src/api/types.d.ts +66 -0
  131. package/dist/src/api/types.js +7 -0
  132. package/dist/src/api/types.js.map +1 -0
  133. package/dist/src/context/compiler.d.ts +13 -0
  134. package/dist/src/context/compiler.js +358 -0
  135. package/dist/src/context/compiler.js.map +1 -0
  136. package/dist/src/context/compiler.test.d.ts +6 -0
  137. package/dist/src/context/compiler.test.js +532 -0
  138. package/dist/src/context/compiler.test.js.map +1 -0
  139. package/dist/src/context/types.d.ts +110 -0
  140. package/dist/src/context/types.js +7 -0
  141. package/dist/src/context/types.js.map +1 -0
  142. package/dist/src/env-ref.d.ts +13 -0
  143. package/dist/src/env-ref.js +31 -0
  144. package/dist/src/env-ref.js.map +1 -0
  145. package/dist/src/env-ref.test.d.ts +6 -0
  146. package/dist/src/env-ref.test.js +34 -0
  147. package/dist/src/env-ref.test.js.map +1 -0
  148. package/dist/src/errors.d.ts +15 -0
  149. package/dist/src/errors.js +22 -0
  150. package/dist/src/errors.js.map +1 -1
  151. package/dist/src/errors.test.js +2 -2
  152. package/dist/src/errors.test.js.map +1 -1
  153. package/dist/src/events/event-bus.d.ts +54 -0
  154. package/dist/src/events/event-bus.js +84 -0
  155. package/dist/src/events/event-bus.js.map +1 -0
  156. package/dist/src/events/event-bus.test.d.ts +6 -0
  157. package/dist/src/events/event-bus.test.js +112 -0
  158. package/dist/src/events/event-bus.test.js.map +1 -0
  159. package/dist/src/events/events-route.d.ts +36 -0
  160. package/dist/src/events/events-route.js +80 -0
  161. package/dist/src/events/events-route.js.map +1 -0
  162. package/dist/src/events/events-route.test.d.ts +6 -0
  163. package/dist/src/events/events-route.test.js +134 -0
  164. package/dist/src/events/events-route.test.js.map +1 -0
  165. package/dist/src/events/store-event-wrapper.d.ts +19 -0
  166. package/dist/src/events/store-event-wrapper.js +57 -0
  167. package/dist/src/events/store-event-wrapper.js.map +1 -0
  168. package/dist/src/events/store-event-wrapper.test.d.ts +6 -0
  169. package/dist/src/events/store-event-wrapper.test.js +91 -0
  170. package/dist/src/events/store-event-wrapper.test.js.map +1 -0
  171. package/dist/src/index.d.ts +33 -6
  172. package/dist/src/index.js +35 -21
  173. package/dist/src/index.js.map +1 -1
  174. package/dist/src/middleware/auth.d.ts +0 -2
  175. package/dist/src/middleware/auth.js.map +1 -1
  176. package/dist/src/providers/create-provider.d.ts +23 -0
  177. package/dist/src/providers/create-provider.js +185 -0
  178. package/dist/src/providers/create-provider.js.map +1 -0
  179. package/dist/src/providers/create-provider.test.d.ts +6 -0
  180. package/dist/src/providers/create-provider.test.js +95 -0
  181. package/dist/src/providers/create-provider.test.js.map +1 -0
  182. package/dist/src/providers/failover.d.ts +38 -0
  183. package/dist/src/providers/failover.js +147 -0
  184. package/dist/src/providers/failover.js.map +1 -0
  185. package/dist/src/providers/failover.test.d.ts +6 -0
  186. package/dist/src/providers/failover.test.js +169 -0
  187. package/dist/src/providers/failover.test.js.map +1 -0
  188. package/dist/src/providers/search-provider.d.ts +64 -0
  189. package/dist/src/providers/search-provider.js +174 -0
  190. package/dist/src/providers/search-provider.js.map +1 -0
  191. package/dist/src/providers/types.d.ts +118 -0
  192. package/dist/src/providers/types.js +7 -0
  193. package/dist/src/providers/types.js.map +1 -0
  194. package/dist/src/routes/ai-stream.d.ts +28 -10
  195. package/dist/src/routes/ai-stream.js +85 -41
  196. package/dist/src/routes/ai-stream.js.map +1 -1
  197. package/dist/src/routes/chat-new.test.d.ts +6 -0
  198. package/dist/src/routes/chat-new.test.js +107 -0
  199. package/dist/src/routes/chat-new.test.js.map +1 -0
  200. package/dist/src/routes/chat-stream-new.test.d.ts +6 -0
  201. package/dist/src/routes/chat-stream-new.test.js +135 -0
  202. package/dist/src/routes/chat-stream-new.test.js.map +1 -0
  203. package/dist/src/routes/chat-stream.d.ts +20 -4
  204. package/dist/src/routes/chat-stream.js +49 -29
  205. package/dist/src/routes/chat-stream.js.map +1 -1
  206. package/dist/src/routes/chat.d.ts +19 -4
  207. package/dist/src/routes/chat.js +62 -23
  208. package/dist/src/routes/chat.js.map +1 -1
  209. package/dist/src/routes/health.d.ts +3 -2
  210. package/dist/src/routes/health.js.map +1 -1
  211. package/dist/src/routes/route-helpers.d.ts +50 -0
  212. package/dist/src/routes/route-helpers.js +80 -0
  213. package/dist/src/routes/route-helpers.js.map +1 -0
  214. package/dist/src/routes/session-resolver.d.ts +77 -0
  215. package/dist/src/routes/session-resolver.js +109 -0
  216. package/dist/src/routes/session-resolver.js.map +1 -0
  217. package/dist/src/routes/session-resolver.test.d.ts +6 -0
  218. package/dist/src/routes/session-resolver.test.js +207 -0
  219. package/dist/src/routes/session-resolver.test.js.map +1 -0
  220. package/dist/src/routes/webhooks.d.ts +3 -1
  221. package/dist/src/routes/webhooks.js +12 -4
  222. package/dist/src/routes/webhooks.js.map +1 -1
  223. package/dist/src/security/permission-checker.d.ts +80 -0
  224. package/dist/src/security/permission-checker.js +75 -0
  225. package/dist/src/security/permission-checker.js.map +1 -0
  226. package/dist/src/security/permission-checker.test.d.ts +6 -0
  227. package/dist/src/security/permission-checker.test.js +208 -0
  228. package/dist/src/security/permission-checker.test.js.map +1 -0
  229. package/dist/src/server.d.ts +18 -11
  230. package/dist/src/server.js +46 -46
  231. package/dist/src/server.js.map +1 -1
  232. package/dist/src/server.test.d.ts +1 -1
  233. package/dist/src/server.test.js +6 -144
  234. package/dist/src/server.test.js.map +1 -1
  235. package/dist/src/session/drizzle-session-store.d.ts +56 -0
  236. package/dist/src/session/drizzle-session-store.js +203 -0
  237. package/dist/src/session/drizzle-session-store.js.map +1 -0
  238. package/dist/src/session/manager.d.ts +101 -0
  239. package/dist/src/session/manager.js +394 -0
  240. package/dist/src/session/manager.js.map +1 -0
  241. package/dist/src/session/manager.test.d.ts +6 -0
  242. package/dist/src/session/manager.test.js +309 -0
  243. package/dist/src/session/manager.test.js.map +1 -0
  244. package/dist/src/session/pglite-session-store.d.ts +23 -0
  245. package/dist/src/session/pglite-session-store.js +70 -0
  246. package/dist/src/session/pglite-session-store.js.map +1 -0
  247. package/dist/src/session/postgres-session-store.d.ts +44 -0
  248. package/dist/src/session/postgres-session-store.js +138 -0
  249. package/dist/src/session/postgres-session-store.js.map +1 -0
  250. package/dist/src/session/session-builder.d.ts +69 -0
  251. package/dist/src/session/session-builder.js +384 -0
  252. package/dist/src/session/session-builder.js.map +1 -0
  253. package/dist/src/session/session-builder.test.d.ts +6 -0
  254. package/dist/src/session/session-builder.test.js +350 -0
  255. package/dist/src/session/session-builder.test.js.map +1 -0
  256. package/dist/src/session/session-store-selector.d.ts +49 -0
  257. package/dist/src/session/session-store-selector.js +60 -0
  258. package/dist/src/session/session-store-selector.js.map +1 -0
  259. package/dist/src/session/session-store-selector.test.d.ts +6 -0
  260. package/dist/src/session/session-store-selector.test.js +79 -0
  261. package/dist/src/session/session-store-selector.test.js.map +1 -0
  262. package/dist/src/session/store.d.ts +171 -0
  263. package/dist/src/session/store.js +155 -0
  264. package/dist/src/session/store.js.map +1 -0
  265. package/dist/src/session/store.test.d.ts +6 -0
  266. package/dist/src/session/store.test.js +423 -0
  267. package/dist/src/session/store.test.js.map +1 -0
  268. package/dist/src/session/stream-hooks.d.ts +39 -0
  269. package/dist/src/session/stream-hooks.js +7 -0
  270. package/dist/src/session/stream-hooks.js.map +1 -0
  271. package/dist/src/session/tool-context-factory.d.ts +61 -0
  272. package/dist/src/session/tool-context-factory.js +189 -0
  273. package/dist/src/session/tool-context-factory.js.map +1 -0
  274. package/dist/src/session/tool-context-factory.test.d.ts +6 -0
  275. package/dist/src/session/tool-context-factory.test.js +284 -0
  276. package/dist/src/session/tool-context-factory.test.js.map +1 -0
  277. package/dist/src/session/types.d.ts +195 -0
  278. package/dist/src/session/types.js +7 -0
  279. package/dist/src/session/types.js.map +1 -0
  280. package/dist/src/stores/drizzle-store-backend.d.ts +49 -0
  281. package/dist/src/stores/drizzle-store-backend.js +306 -0
  282. package/dist/src/stores/drizzle-store-backend.js.map +1 -0
  283. package/dist/src/stores/drizzle-store-backend.test.d.ts +6 -0
  284. package/dist/src/stores/drizzle-store-backend.test.js +215 -0
  285. package/dist/src/stores/drizzle-store-backend.test.js.map +1 -0
  286. package/dist/src/stores/index.d.ts +4 -0
  287. package/dist/src/stores/index.js +2 -0
  288. package/dist/src/stores/index.js.map +1 -1
  289. package/dist/src/stores/pglite-store-backend.d.ts +16 -19
  290. package/dist/src/stores/pglite-store-backend.js +85 -239
  291. package/dist/src/stores/pglite-store-backend.js.map +1 -1
  292. package/dist/src/stores/postgres-store-backend.d.ts +30 -0
  293. package/dist/src/stores/postgres-store-backend.js +100 -0
  294. package/dist/src/stores/postgres-store-backend.js.map +1 -0
  295. package/dist/src/stores/schema.d.ts +457 -0
  296. package/dist/src/stores/schema.js +59 -0
  297. package/dist/src/stores/schema.js.map +1 -0
  298. package/dist/src/tools/admin-file-tools.d.ts +42 -0
  299. package/dist/src/tools/admin-file-tools.js +714 -0
  300. package/dist/src/tools/admin-file-tools.js.map +1 -0
  301. package/dist/src/tools/admin-file-tools.test.d.ts +6 -0
  302. package/dist/src/tools/admin-file-tools.test.js +521 -0
  303. package/dist/src/tools/admin-file-tools.test.js.map +1 -0
  304. package/dist/src/tools/custom-tool-adapter.d.ts +41 -0
  305. package/dist/src/tools/custom-tool-adapter.js +190 -0
  306. package/dist/src/tools/custom-tool-adapter.js.map +1 -0
  307. package/dist/src/tools/custom-tool-adapter.test.d.ts +6 -0
  308. package/dist/src/tools/custom-tool-adapter.test.js +243 -0
  309. package/dist/src/tools/custom-tool-adapter.test.js.map +1 -0
  310. package/dist/src/tools/dispatch-tool.d.ts +52 -0
  311. package/dist/src/tools/dispatch-tool.js +71 -0
  312. package/dist/src/tools/dispatch-tool.js.map +1 -0
  313. package/dist/src/tools/dispatch-tool.test.d.ts +6 -0
  314. package/dist/src/tools/dispatch-tool.test.js +75 -0
  315. package/dist/src/tools/dispatch-tool.test.js.map +1 -0
  316. package/dist/src/tools/fetch-url-tool.d.ts +23 -0
  317. package/dist/src/tools/fetch-url-tool.js +333 -0
  318. package/dist/src/tools/fetch-url-tool.js.map +1 -0
  319. package/dist/src/tools/fetch-url-tool.test.d.ts +6 -0
  320. package/dist/src/tools/fetch-url-tool.test.js +228 -0
  321. package/dist/src/tools/fetch-url-tool.test.js.map +1 -0
  322. package/dist/src/tools/mcp-tool-adapter.d.ts +18 -0
  323. package/dist/src/tools/mcp-tool-adapter.js +135 -0
  324. package/dist/src/tools/mcp-tool-adapter.js.map +1 -0
  325. package/dist/src/tools/mcp-tool-adapter.test.d.ts +6 -0
  326. package/dist/src/tools/mcp-tool-adapter.test.js +226 -0
  327. package/dist/src/tools/mcp-tool-adapter.test.js.map +1 -0
  328. package/dist/src/tools/registry.d.ts +25 -0
  329. package/dist/src/tools/registry.js +72 -0
  330. package/dist/src/tools/registry.js.map +1 -0
  331. package/dist/src/tools/registry.test.d.ts +6 -0
  332. package/dist/src/tools/registry.test.js +120 -0
  333. package/dist/src/tools/registry.test.js.map +1 -0
  334. package/dist/src/tools/request-tool.d.ts +42 -0
  335. package/dist/src/tools/request-tool.js +190 -0
  336. package/dist/src/tools/request-tool.js.map +1 -0
  337. package/dist/src/tools/request-tool.test.d.ts +6 -0
  338. package/dist/src/tools/request-tool.test.js +253 -0
  339. package/dist/src/tools/request-tool.test.js.map +1 -0
  340. package/dist/src/tools/store-tools.d.ts +29 -0
  341. package/dist/src/tools/store-tools.js +224 -0
  342. package/dist/src/tools/store-tools.js.map +1 -0
  343. package/dist/src/tools/store-tools.test.d.ts +6 -0
  344. package/dist/src/tools/store-tools.test.js +215 -0
  345. package/dist/src/tools/store-tools.test.js.map +1 -0
  346. package/dist/src/tools/types.d.ts +129 -0
  347. package/dist/src/tools/types.js +7 -0
  348. package/dist/src/tools/types.js.map +1 -0
  349. package/dist/src/tools/web-search-tool.d.ts +31 -0
  350. package/dist/src/tools/web-search-tool.js +170 -0
  351. package/dist/src/tools/web-search-tool.js.map +1 -0
  352. package/dist/src/tools/web-search-tool.test.d.ts +6 -0
  353. package/dist/src/tools/web-search-tool.test.js +153 -0
  354. package/dist/src/tools/web-search-tool.test.js.map +1 -0
  355. package/dist/src/tools/web-tools-shared.d.ts +21 -0
  356. package/dist/src/tools/web-tools-shared.js +32 -0
  357. package/dist/src/tools/web-tools-shared.js.map +1 -0
  358. package/dist/src/types.d.ts +40 -12
  359. package/dist/src/types.js +16 -2
  360. package/dist/src/types.js.map +1 -1
  361. package/dist/tsconfig.tsbuildinfo +1 -1
  362. package/package.json +27 -4
  363. package/dist/src/__tests__/sse-contract.test.js +0 -464
  364. package/dist/src/__tests__/sse-contract.test.js.map +0 -1
  365. package/dist/src/__tests__/tools.test.js +0 -583
  366. package/dist/src/__tests__/tools.test.js.map +0 -1
  367. package/dist/src/agent/agent-runner.d.ts +0 -33
  368. package/dist/src/agent/agent-runner.js +0 -1040
  369. package/dist/src/agent/agent-runner.js.map +0 -1
  370. package/dist/src/agent/custom-tools-e2e.test.d.ts +0 -6
  371. package/dist/src/agent/custom-tools-e2e.test.js +0 -566
  372. package/dist/src/agent/custom-tools-e2e.test.js.map +0 -1
  373. package/dist/src/agent/request-helper.d.ts +0 -16
  374. package/dist/src/agent/request-helper.js +0 -96
  375. package/dist/src/agent/request-helper.js.map +0 -1
  376. package/dist/src/agent/session-store.d.ts +0 -62
  377. package/dist/src/agent/session-store.js +0 -151
  378. package/dist/src/agent/session-store.js.map +0 -1
  379. package/dist/src/agent/stores-e2e.test.js +0 -433
  380. package/dist/src/agent/stores-e2e.test.js.map +0 -1
  381. package/dist/src/agent/tool-context-builder.d.ts +0 -11
  382. package/dist/src/agent/tool-context-builder.js +0 -102
  383. package/dist/src/agent/tool-context-builder.js.map +0 -1
  384. package/dist/src/agent/tool-context-builder.test.d.ts +0 -6
  385. package/dist/src/agent/tool-context-builder.test.js +0 -152
  386. package/dist/src/agent/tool-context-builder.test.js.map +0 -1
  387. package/dist/src/agent/write-repo-file.test.js +0 -270
  388. package/dist/src/agent/write-repo-file.test.js.map +0 -1
  389. package/dist/src/cron/heartbeat-runner.d.ts +0 -21
  390. package/dist/src/cron/heartbeat-runner.js +0 -79
  391. package/dist/src/cron/heartbeat-runner.js.map +0 -1
  392. package/dist/src/cron/heartbeat-runner.test.d.ts +0 -6
  393. package/dist/src/cron/heartbeat-runner.test.js +0 -120
  394. package/dist/src/cron/heartbeat-runner.test.js.map +0 -1
  395. package/dist/src/cron/heartbeat-scheduler.d.ts +0 -26
  396. package/dist/src/cron/heartbeat-scheduler.js +0 -55
  397. package/dist/src/cron/heartbeat-scheduler.js.map +0 -1
  398. package/dist/src/cron/heartbeat-scheduler.test.d.ts +0 -6
  399. package/dist/src/cron/heartbeat-scheduler.test.js +0 -61
  400. package/dist/src/cron/heartbeat-scheduler.test.js.map +0 -1
  401. package/dist/src/routes/ai-stream.test.d.ts +0 -6
  402. package/dist/src/routes/ai-stream.test.js +0 -586
  403. package/dist/src/routes/ai-stream.test.js.map +0 -1
  404. package/dist/src/routes/ask-user-response.d.ts +0 -30
  405. package/dist/src/routes/ask-user-response.js +0 -61
  406. package/dist/src/routes/ask-user-response.js.map +0 -1
  407. package/dist/src/routes/ask-user-response.test.d.ts +0 -6
  408. package/dist/src/routes/ask-user-response.test.js +0 -88
  409. package/dist/src/routes/ask-user-response.test.js.map +0 -1
  410. package/dist/src/routes/chat-stream.test.d.ts +0 -6
  411. package/dist/src/routes/chat-stream.test.js +0 -155
  412. package/dist/src/routes/chat-stream.test.js.map +0 -1
  413. package/dist/src/routes/chat.test.d.ts +0 -6
  414. package/dist/src/routes/chat.test.js +0 -99
  415. package/dist/src/routes/chat.test.js.map +0 -1
  416. package/dist/src/routes/widget-actions.d.ts +0 -49
  417. package/dist/src/routes/widget-actions.js +0 -78
  418. package/dist/src/routes/widget-actions.js.map +0 -1
  419. package/dist/src/session/admin-file-tools.d.ts +0 -136
  420. package/dist/src/session/admin-file-tools.js +0 -240
  421. package/dist/src/session/admin-file-tools.js.map +0 -1
  422. package/dist/src/session/custom-tool-adapter.d.ts +0 -74
  423. package/dist/src/session/custom-tool-adapter.js +0 -180
  424. package/dist/src/session/custom-tool-adapter.js.map +0 -1
  425. package/dist/src/session/history-converter.d.ts +0 -21
  426. package/dist/src/session/history-converter.js +0 -59
  427. package/dist/src/session/history-converter.js.map +0 -1
  428. package/dist/src/session/history-converter.test.d.ts +0 -6
  429. package/dist/src/session/history-converter.test.js +0 -130
  430. package/dist/src/session/history-converter.test.js.map +0 -1
  431. package/dist/src/session/session-manager.d.ts +0 -219
  432. package/dist/src/session/session-manager.js +0 -915
  433. package/dist/src/session/session-manager.js.map +0 -1
  434. package/dist/src/session/session-manager.test.d.ts +0 -6
  435. package/dist/src/session/session-manager.test.js +0 -455
  436. package/dist/src/session/session-manager.test.js.map +0 -1
  437. package/dist/src/session/session-runner.d.ts +0 -45
  438. package/dist/src/session/session-runner.js +0 -719
  439. package/dist/src/session/session-runner.js.map +0 -1
  440. package/dist/src/session/session-runner.test.d.ts +0 -6
  441. package/dist/src/session/session-runner.test.js +0 -834
  442. package/dist/src/session/session-runner.test.js.map +0 -1
  443. /package/dist/src/{__tests__/sse-contract.test.d.ts → __fixtures__/e2e.test.d.ts} +0 -0
  444. /package/dist/src/{__tests__/tools.test.d.ts → __fixtures__/smoke.test.d.ts} +0 -0
  445. /package/dist/src/agent/{write-repo-file.test.d.ts → loop.test.d.ts} +0 -0
@@ -0,0 +1,260 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ /**
7
+ * COMPACTING state handler.
8
+ *
9
+ * Summarizes older conversation turns to free context space:
10
+ * 1. Keep the last N turns verbatim (active conversation)
11
+ * 2. Send older turns to a cheap model for structured summarization
12
+ * 3. Replace old turns with the summary
13
+ * 4. Circuit breaker: after N consecutive failures, give up and continue
14
+ *
15
+ * The summary is structured as a handoff document with sections for
16
+ * current state, original task, key data, actions taken, errors, and
17
+ * next steps. This preserves the information the agent needs to
18
+ * continue working without the full conversation history.
19
+ */
20
+ import { SSEEventType } from '../../types.js';
21
+ import { CompactionError } from '../../errors.js';
22
+ import { estimateTokenCount } from '../token-estimate.js';
23
+ /** Prefix for the summary message injected after compaction. */
24
+ const COMPACTION_SUMMARY_PREFIX = '[Conversation Summary — older messages compacted]';
25
+ /** Timeout for the compaction generateText call (30 seconds). */
26
+ const COMPACTION_TIMEOUT_MS = 30_000;
27
+ const COMPACTION_PROMPT = `Summarize this conversation as a structured handoff into these sections:
28
+
29
+ 1. **Current State** — what we're working on right now
30
+ 2. **Original Task** — what the user originally asked for
31
+ 3. **Key Data** — important values, IDs, file paths, or facts that must be preserved
32
+ 4. **Actions Taken** — tools called and what they returned (summarized, not verbatim)
33
+ 5. **Errors & Corrections** — what went wrong and what we tried instead
34
+ 6. **Next Steps** — what should happen next
35
+
36
+ Keep each section under 500 tokens. Focus on information the agent needs to continue working. Omit sections that have no content.`;
37
+ /**
38
+ * Handle the COMPACTING state.
39
+ *
40
+ * Splits messages into "old" (to be summarized) and "recent" (kept verbatim).
41
+ * Calls generateText with a cheap model to produce a structured summary.
42
+ * Replaces old messages with a single summary message.
43
+ */
44
+ export async function handleCompacting(state, ctx) {
45
+ const effects = [];
46
+ const { keepRecentTurns, maxSummaryTokens, compactionCircuitBreaker } = ctx.config;
47
+ // Circuit breaker — if we've failed too many times, skip compaction
48
+ if (ctx.compactionFailures >= compactionCircuitBreaker) {
49
+ ctx.logger.warn('compaction_circuit_breaker', {
50
+ session: ctx.sessionId,
51
+ failures: ctx.compactionFailures,
52
+ threshold: compactionCircuitBreaker,
53
+ });
54
+ return {
55
+ next: { type: 'thinking', messages: state.messages },
56
+ effects,
57
+ };
58
+ }
59
+ // Split messages: keep last N turns verbatim, summarize the rest.
60
+ // A "turn" is a user message + assistant response (+ any tool results).
61
+ // We count from the end by counting user messages.
62
+ const splitIndex = findSplitIndex(state.messages, keepRecentTurns);
63
+ if (splitIndex <= 0) {
64
+ // Not enough messages to compact — nothing older than the recent window
65
+ ctx.logger.debug('compaction_skipped_too_few', {
66
+ session: ctx.sessionId,
67
+ messageCount: state.messages.length,
68
+ keepRecentTurns,
69
+ });
70
+ return {
71
+ next: { type: 'thinking', messages: state.messages },
72
+ effects,
73
+ };
74
+ }
75
+ const oldMessages = state.messages.slice(0, splitIndex);
76
+ const recentMessages = state.messages.slice(splitIndex);
77
+ const tokensBefore = state.estimatedTokens;
78
+ effects.push({
79
+ type: SSEEventType.CompactionStart,
80
+ estimated_tokens: tokensBefore,
81
+ threshold: ctx.config.compactThreshold,
82
+ timestamp: new Date().toISOString(),
83
+ });
84
+ ctx.logger.info('compaction_start', {
85
+ session: ctx.sessionId,
86
+ totalMessages: state.messages.length,
87
+ oldMessages: oldMessages.length,
88
+ recentMessages: recentMessages.length,
89
+ tokensBefore,
90
+ });
91
+ const summaryResult = await summarizeMessages(oldMessages, ctx, maxSummaryTokens);
92
+ if (!summaryResult.ok) {
93
+ ctx.compactionFailures++;
94
+ ctx.logger.error('compaction_failed', {
95
+ session: ctx.sessionId,
96
+ error: summaryResult.error.message,
97
+ failure: ctx.compactionFailures,
98
+ circuitBreakerAt: compactionCircuitBreaker,
99
+ });
100
+ // Continue without compaction — the agent can still work, just with
101
+ // a fuller context. Better than crashing the loop.
102
+ return {
103
+ next: { type: 'thinking', messages: state.messages },
104
+ effects,
105
+ };
106
+ }
107
+ // Build the compacted message list: summary + recent turns.
108
+ // Uses 'user' role so it's valid for Anthropic (which rejects system
109
+ // messages after user/assistant turns). The "[Conversation Summary]"
110
+ // prefix makes the provenance clear to the model.
111
+ const summaryMessage = {
112
+ role: 'user',
113
+ content: `${COMPACTION_SUMMARY_PREFIX}\n\n${summaryResult.value.text}`,
114
+ };
115
+ const compactedMessages = [summaryMessage, ...recentMessages];
116
+ // Update context
117
+ ctx.messages = compactedMessages;
118
+ ctx.compactionFailures = 0; // Reset circuit breaker on success
119
+ const tokensAfter = estimateTokenCount(compactedMessages, ctx.provider);
120
+ const compactionTokens = summaryResult.value.usage.inputTokens + summaryResult.value.usage.outputTokens;
121
+ ctx.logger.info('compaction_end', {
122
+ session: ctx.sessionId,
123
+ tokensBefore,
124
+ tokensAfter,
125
+ messagesBefore: state.messages.length,
126
+ messagesAfter: compactedMessages.length,
127
+ });
128
+ effects.push({
129
+ type: SSEEventType.CompactionEnd,
130
+ tokens_before: tokensBefore,
131
+ tokens_after: tokensAfter,
132
+ compaction_tokens: compactionTokens,
133
+ timestamp: new Date().toISOString(),
134
+ });
135
+ return {
136
+ next: { type: 'thinking', messages: compactedMessages },
137
+ effects,
138
+ };
139
+ }
140
+ /**
141
+ * Summarize old messages using generateText.
142
+ * Returns Result to avoid try/catch in the caller.
143
+ */
144
+ async function summarizeMessages(messages, ctx, maxSummaryTokens) {
145
+ // Serialize old messages into a readable conversation format
146
+ const conversationText = messagesToText(messages);
147
+ // Per-call timeout composed with session abort signal — prevents a hung
148
+ // provider from blocking the loop until session-level abort.
149
+ const timeoutSignal = AbortSignal.timeout(COMPACTION_TIMEOUT_MS);
150
+ const combinedSignal = AbortSignal.any([ctx.signal, timeoutSignal]);
151
+ try {
152
+ const result = await ctx.provider.generateText({
153
+ messages: [
154
+ { role: 'user', content: `Here is a conversation to summarize:\n\n${conversationText}` },
155
+ ],
156
+ system: COMPACTION_PROMPT,
157
+ maxOutputTokens: maxSummaryTokens,
158
+ abortSignal: combinedSignal,
159
+ });
160
+ // Track compaction token usage
161
+ ctx.usage.inputTokens += result.usage.inputTokens;
162
+ ctx.usage.outputTokens += result.usage.outputTokens;
163
+ ctx.usage.totalTokens += result.usage.inputTokens + result.usage.outputTokens;
164
+ if (!result.text || result.text.trim().length === 0) {
165
+ return {
166
+ ok: false,
167
+ error: new CompactionError('Summarization returned empty text', {
168
+ stage: 'summarize',
169
+ context: { messageCount: messages.length },
170
+ }),
171
+ };
172
+ }
173
+ return {
174
+ ok: true,
175
+ value: {
176
+ text: result.text,
177
+ usage: { inputTokens: result.usage.inputTokens, outputTokens: result.usage.outputTokens },
178
+ },
179
+ };
180
+ }
181
+ catch (err) {
182
+ // Specific expected failure with specific handling (reason #3):
183
+ // Provider errors during compaction are non-fatal — the caller degrades
184
+ // gracefully by continuing without compaction.
185
+ return {
186
+ ok: false,
187
+ error: new CompactionError(`Summarization failed: ${err instanceof Error ? err.message : String(err)}`, { stage: 'summarize', cause: err, context: { messageCount: messages.length } }),
188
+ };
189
+ }
190
+ }
191
+ /**
192
+ * Convert messages to a readable text format for the summarizer.
193
+ */
194
+ function messagesToText(messages) {
195
+ const lines = [];
196
+ for (const msg of messages) {
197
+ const role = msg.role.toUpperCase();
198
+ if (typeof msg.content === 'string') {
199
+ lines.push(`${role}: ${msg.content}`);
200
+ continue;
201
+ }
202
+ if (!Array.isArray(msg.content))
203
+ continue;
204
+ for (const part of msg.content) {
205
+ if (!('type' in part))
206
+ continue;
207
+ if (part.type === 'text' && 'text' in part) {
208
+ lines.push(`${role}: ${part.text}`);
209
+ }
210
+ else if (part.type === 'tool-call' && 'toolName' in part) {
211
+ const args = 'input' in part ? JSON.stringify(part.input) : '{}';
212
+ lines.push(`${role} [tool_call: ${part.toolName}(${args})]`);
213
+ }
214
+ else if (part.type === 'tool-result' && 'output' in part) {
215
+ const output = extractToolResultText(part.output);
216
+ // Truncate long tool results for the summarizer — it doesn't need 20K
217
+ const truncated = output.length > 2_000
218
+ ? output.slice(0, 2_000) + '... [truncated for summarization]'
219
+ : output;
220
+ lines.push(`TOOL_RESULT: ${truncated}`);
221
+ }
222
+ }
223
+ }
224
+ return lines.join('\n');
225
+ }
226
+ /**
227
+ * Extract text from a tool result output field.
228
+ */
229
+ function extractToolResultText(output) {
230
+ if (typeof output === 'string')
231
+ return output;
232
+ if (typeof output === 'object' && output !== null && 'value' in output) {
233
+ // `in` narrows to `object & Record<'value', unknown>` — safe to access
234
+ return String(output.value);
235
+ }
236
+ return JSON.stringify(output);
237
+ }
238
+ // ---------------------------------------------------------------------------
239
+ // Helpers
240
+ // ---------------------------------------------------------------------------
241
+ /**
242
+ * Find the index to split messages: everything before this index gets
243
+ * summarized, everything at or after is kept verbatim.
244
+ *
245
+ * Counts user messages from the end to find `keepTurns` turn boundaries.
246
+ */
247
+ function findSplitIndex(messages, keepTurns) {
248
+ let userMessagesSeen = 0;
249
+ for (let i = messages.length - 1; i >= 0; i--) {
250
+ if (messages[i].role === 'user') {
251
+ userMessagesSeen++;
252
+ if (userMessagesSeen >= keepTurns) {
253
+ return i;
254
+ }
255
+ }
256
+ }
257
+ // Not enough turns to split — return 0 (don't compact)
258
+ return 0;
259
+ }
260
+ //# sourceMappingURL=compacting.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compacting.js","sourceRoot":"","sources":["../../../../src/agent/states/compacting.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ import type { ConfirmingState, AgentContext, TransitionResult } from '../loop-types.js';
7
+ /**
8
+ * Handle the CONFIRMING state.
9
+ */
10
+ export declare function handleConfirming(state: ConfirmingState, ctx: AgentContext): Promise<TransitionResult>;
@@ -0,0 +1,79 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ /**
7
+ * CONFIRMING state handler.
8
+ *
9
+ * Waits for user confirmation on a tool call (via ctx.waitForConfirmation).
10
+ * - Approved → resume EXECUTING with the confirmed call
11
+ * - Denied → tell the model the tool call was denied, back to THINKING
12
+ */
13
+ import { SSEEventType } from '../../types.js';
14
+ /**
15
+ * Handle the CONFIRMING state.
16
+ */
17
+ export async function handleConfirming(state, ctx) {
18
+ const effects = [];
19
+ ctx.logger.info('tool_confirmation_waiting', {
20
+ tool: state.call.toolName,
21
+ callId: state.call.toolCallId,
22
+ session: ctx.sessionId,
23
+ });
24
+ // Race confirmation against a timeout — don't hang forever if user never responds
25
+ const timeoutMs = ctx.config.confirmationTimeoutMs;
26
+ const timeoutPromise = new Promise((resolve) => {
27
+ setTimeout(() => resolve(false), timeoutMs);
28
+ });
29
+ const approved = await Promise.race([
30
+ ctx.waitForConfirmation(state.call.toolCallId),
31
+ timeoutPromise,
32
+ ]);
33
+ if (approved) {
34
+ ctx.logger.info('tool_confirmation_approved', {
35
+ tool: state.call.toolName,
36
+ callId: state.call.toolCallId,
37
+ session: ctx.sessionId,
38
+ });
39
+ // Mark this call as confirmed so EXECUTING does not re-route it back
40
+ // to CONFIRMING on the next pass (infinite-loop guard).
41
+ ctx.confirmedCallIds.add(state.call.toolCallId);
42
+ effects.push({
43
+ type: SSEEventType.Approved,
44
+ resource_type: 'tool_call',
45
+ preview_id: state.call.toolCallId,
46
+ timestamp: new Date().toISOString(),
47
+ });
48
+ return {
49
+ next: {
50
+ type: 'executing',
51
+ queue: state.remainingQueue,
52
+ current: state.call,
53
+ results: [],
54
+ },
55
+ effects,
56
+ };
57
+ }
58
+ // Denied — inject a tool result message telling the model
59
+ ctx.logger.info('tool_confirmation_denied', {
60
+ tool: state.call.toolName,
61
+ callId: state.call.toolCallId,
62
+ session: ctx.sessionId,
63
+ });
64
+ const denialMessage = {
65
+ role: 'tool',
66
+ content: [{
67
+ type: 'tool-result',
68
+ toolCallId: state.call.toolCallId,
69
+ toolName: state.call.toolName,
70
+ output: { type: 'text', value: 'Tool call denied by user. Do not retry this action without asking the user first.' },
71
+ }],
72
+ };
73
+ ctx.messages = [...ctx.messages, denialMessage];
74
+ return {
75
+ next: { type: 'thinking', messages: ctx.messages },
76
+ effects,
77
+ };
78
+ }
79
+ //# sourceMappingURL=confirming.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"confirming.js","sourceRoot":"","sources":["../../../../src/agent/states/confirming.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;GAMG;AAEH,OAAO,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAQ5C;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,KAAsB,EACtB,GAAiB;IAEjB,MAAM,OAAO,GAAe,EAAE,CAAC;IAE/B,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,2BAA2B,EAAE;QAC3C,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,QAAQ;QACzB,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,UAAU;QAC7B,OAAO,EAAE,GAAG,CAAC,SAAS;KACvB,CAAC,CAAC;IAEH,kFAAkF;IAClF,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,CAAC,qBAAqB,CAAC;IACnD,MAAM,cAAc,GAAG,IAAI,OAAO,CAAQ,CAAC,OAAO,EAAE,EAAE;QACpD,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IACH,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC;QAClC,GAAG,CAAC,mBAAmB,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC;QAC9C,cAAc;KACf,CAAC,CAAC;IAEH,IAAI,QAAQ,EAAE,CAAC;QACb,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,4BAA4B,EAAE;YAC5C,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,QAAQ;YACzB,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,UAAU;YAC7B,OAAO,EAAE,GAAG,CAAC,SAAS;SACvB,CAAC,CAAC;QAEH,qEAAqE;QACrE,wDAAwD;QACxD,GAAG,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAEhD,OAAO,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,YAAY,CAAC,QAAQ;YAC3B,aAAa,EAAE,WAAW;YAC1B,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,UAAU;YACjC,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC,CAAC;QAEH,OAAO;YACL,IAAI,EAAE;gBACJ,IAAI,EAAE,WAAW;gBACjB,KAAK,EAAE,KAAK,CAAC,cAAc;gBAC3B,OAAO,EAAE,KAAK,CAAC,IAAI;gBACnB,OAAO,EAAE,EAAE;aACZ;YACD,OAAO;SACR,CAAC;IACJ,CAAC;IAED,0DAA0D;IAC1D,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,0BAA0B,EAAE;QAC1C,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,QAAQ;QACzB,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,UAAU;QAC7B,OAAO,EAAE,GAAG,CAAC,SAAS;KACvB,CAAC,CAAC;IAEH,MAAM,aAAa,GAA8B;QAC/C,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,CAAC;gBACR,IAAI,EAAE,aAAsB;gBAC5B,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,UAAU;gBACjC,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,QAAQ;gBAC7B,MAAM,EAAE,EAAC,IAAI,EAAE,MAAe,EAAE,KAAK,EAAE,mFAAmF,EAAC;aAC5H,CAAC;KACH,CAAC;IAEF,GAAG,CAAC,QAAQ,GAAG,CAAC,GAAG,GAAG,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;IAEhD,OAAO;QACL,IAAI,EAAE,EAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAC;QAChD,OAAO;KACR,CAAC;AACJ,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ import type { DispatchingState, AgentContext, TransitionResult } from '../loop-types.js';
7
+ /**
8
+ * Handle the DISPATCHING state — run a child agent loop.
9
+ *
10
+ * Creates a child AgentContext with:
11
+ * - Same provider, logger, signal, tenant, user, permission checker
12
+ * - Tool registry subset (only the requested tools, never dispatch_task)
13
+ * - Same buildToolContext factory (child shares parent's connections/stores)
14
+ * - Reduced maxTurns (default 10) and maxContextTokens
15
+ * - Fresh messages (dispatch prompt as user message)
16
+ * - Fresh usage counters (merged back to parent after completion)
17
+ */
18
+ export declare function handleDispatching(state: DispatchingState, ctx: AgentContext): Promise<TransitionResult>;
@@ -0,0 +1,285 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ /**
7
+ * DISPATCHING state handler.
8
+ *
9
+ * Spawns a child agent with a subset of tools and a specific prompt.
10
+ * The child runs its own runAgent() loop; each child event is wrapped
11
+ * as an SSESubagentEvent and yielded as an effect so the client can
12
+ * display real-time sub-agent activity.
13
+ *
14
+ * After the child completes, the handler builds a ToolResult from the
15
+ * child's text response and transitions back through the normal
16
+ * EXECUTING post-result flow (queue, compaction, thinking).
17
+ */
18
+ import { SSEEventType } from '../../types.js';
19
+ import { createToolRegistry } from '../../tools/registry.js';
20
+ import { DEFAULT_LOOP_CONFIG } from '../loop-types.js';
21
+ import { runAgent } from '../loop.js';
22
+ import { nextAfterToolResult } from './executing.js';
23
+ import { DEFAULT_CHILD_MAX_TURNS, DISPATCH_TOOL_NAME } from '../../tools/dispatch-tool.js';
24
+ // ---------------------------------------------------------------------------
25
+ // Constants
26
+ // ---------------------------------------------------------------------------
27
+ const DEFAULT_CHILD_MAX_CONTEXT_TOKENS = 100_000;
28
+ const DEFAULT_CHILD_TIMEOUT_MS = 60_000;
29
+ // ---------------------------------------------------------------------------
30
+ // Handler
31
+ // ---------------------------------------------------------------------------
32
+ /**
33
+ * Handle the DISPATCHING state — run a child agent loop.
34
+ *
35
+ * Creates a child AgentContext with:
36
+ * - Same provider, logger, signal, tenant, user, permission checker
37
+ * - Tool registry subset (only the requested tools, never dispatch_task)
38
+ * - Same buildToolContext factory (child shares parent's connections/stores)
39
+ * - Reduced maxTurns (default 10) and maxContextTokens
40
+ * - Fresh messages (dispatch prompt as user message)
41
+ * - Fresh usage counters (merged back to parent after completion)
42
+ */
43
+ export async function handleDispatching(state, ctx) {
44
+ const { task, toolCallId } = state;
45
+ const effects = [];
46
+ const startedAt = Date.now();
47
+ ctx.logger.info('dispatch_start', {
48
+ session: ctx.sessionId,
49
+ agent: task.agentName,
50
+ tools: task.toolSubset,
51
+ maxTurns: task.maxTurns ?? DEFAULT_CHILD_MAX_TURNS,
52
+ parentToolCallId: toolCallId,
53
+ });
54
+ // Short-circuit: if the parent is already out of budget, don't bother
55
+ // spinning up a child only to have it run one doomed turn. The child
56
+ // would inherit maxSessionTokens=0, burn through its first streaming
57
+ // call, and stop on budget_exceeded anyway. Surface a clean error
58
+ // result to the parent instead.
59
+ if (ctx.maxSessionTokens !== undefined &&
60
+ ctx.usage.totalTokens >= ctx.maxSessionTokens) {
61
+ ctx.logger.warn('dispatch_skipped_budget_exhausted', {
62
+ session: ctx.sessionId,
63
+ agent: task.agentName,
64
+ totalTokens: ctx.usage.totalTokens,
65
+ maxSessionTokens: ctx.maxSessionTokens,
66
+ parentToolCallId: toolCallId,
67
+ });
68
+ const result = {
69
+ callId: toolCallId,
70
+ toolName: DISPATCH_TOOL_NAME,
71
+ status: 'error',
72
+ content: `Sub-agent dispatch skipped: session token budget (${ctx.maxSessionTokens}) already reached.`,
73
+ };
74
+ effects.push({
75
+ type: SSEEventType.ToolCallResult,
76
+ tool_id: toolCallId,
77
+ status: result.status,
78
+ duration_ms: Date.now() - startedAt,
79
+ error: result.content,
80
+ timestamp: new Date().toISOString(),
81
+ });
82
+ const executingState = {
83
+ type: 'executing',
84
+ current: { toolCallId, toolName: DISPATCH_TOOL_NAME, args: {} },
85
+ queue: state.queue,
86
+ results: state.results,
87
+ };
88
+ return nextAfterToolResult(executingState, result, effects, ctx);
89
+ }
90
+ // Build child tool registry from the parent's subset
91
+ const childRegistry = createToolRegistry();
92
+ const subsetTools = ctx.toolRegistry.subset(task.toolSubset);
93
+ for (const [name, def] of Object.entries(subsetTools)) {
94
+ childRegistry.register(name, def);
95
+ }
96
+ // Child-specific timeout — prevents a slow child from starving the parent.
97
+ // Combined with parent's signal so parent abort also stops child.
98
+ const childTimeoutMs = task.timeoutMs ?? DEFAULT_CHILD_TIMEOUT_MS;
99
+ const childSignal = AbortSignal.any([ctx.signal, AbortSignal.timeout(childTimeoutMs)]);
100
+ // Minimal system prompt for the child — the full parent prompt (skills,
101
+ // knowledge, connection docs) is unnecessary for a focused sub-task and
102
+ // wastes tokens. The child gets a task-scoped prompt with available tools.
103
+ const childToolNames = childRegistry.names();
104
+ const childSystemPrompt = buildChildSystemPrompt(task.agentName, task.prompt, childToolNames);
105
+ // Build child context
106
+ const childCtx = {
107
+ provider: ctx.provider,
108
+ toolRegistry: childRegistry,
109
+ permissionChecker: ctx.permissionChecker,
110
+ logger: ctx.logger,
111
+ signal: childSignal,
112
+ sessionId: ctx.sessionId,
113
+ user: ctx.user,
114
+ systemPrompt: childSystemPrompt,
115
+ messages: [],
116
+ usage: { inputTokens: 0, outputTokens: 0, totalTokens: 0 },
117
+ turnCount: 0,
118
+ maxTurns: task.maxTurns ?? DEFAULT_CHILD_MAX_TURNS,
119
+ maxContextTokens: task.maxContextTokens ?? DEFAULT_CHILD_MAX_CONTEXT_TOKENS,
120
+ // Propagate parent's remaining token budget so a child can't blow through
121
+ // more than the parent had left. Child usage merges back into parent after
122
+ // the child completes, so the parent's next budget check catches any
123
+ // overshoot on subsequent turns regardless.
124
+ maxSessionTokens: ctx.maxSessionTokens !== undefined
125
+ ? Math.max(0, ctx.maxSessionTokens - ctx.usage.totalTokens)
126
+ : undefined,
127
+ config: { ...DEFAULT_LOOP_CONFIG },
128
+ compactionFailures: 0,
129
+ preExecutionCache: new Map(),
130
+ confirmedCallIds: new Set(),
131
+ disabledToolsUntilTurn: new Map(),
132
+ waitForConfirmation: ctx.waitForConfirmation,
133
+ buildToolContext: ctx.buildToolContext,
134
+ };
135
+ // Run child agent loop and translate events to SubagentEvents
136
+ let childResponse = '';
137
+ let childFailed = false;
138
+ try {
139
+ for await (const childEvent of runAgent({ messages: [{ role: 'user', content: task.prompt }], context: childCtx })) {
140
+ if (ctx.signal.aborted)
141
+ break;
142
+ // eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check -- intentionally skip child-internal events (Init, Widget, etc.)
143
+ switch (childEvent.type) {
144
+ case SSEEventType.TextDelta:
145
+ childResponse += childEvent.content;
146
+ effects.push({
147
+ type: SSEEventType.SubagentEvent,
148
+ parent_tool_id: toolCallId,
149
+ agent_name: task.agentName,
150
+ event_type: 'thought',
151
+ text: childEvent.content,
152
+ timestamp: childEvent.timestamp,
153
+ });
154
+ break;
155
+ case SSEEventType.ToolCallStart:
156
+ effects.push({
157
+ type: SSEEventType.SubagentEvent,
158
+ parent_tool_id: toolCallId,
159
+ agent_name: task.agentName,
160
+ event_type: 'tool_call_start',
161
+ tool_name: childEvent.tool_name,
162
+ tool_args: childEvent.parameters,
163
+ timestamp: childEvent.timestamp,
164
+ });
165
+ break;
166
+ case SSEEventType.ToolCallResult:
167
+ effects.push({
168
+ type: SSEEventType.SubagentEvent,
169
+ parent_tool_id: toolCallId,
170
+ agent_name: task.agentName,
171
+ event_type: 'tool_call_end',
172
+ tool_name: undefined,
173
+ result: childEvent.status === 'error' ? childEvent.error : undefined,
174
+ timestamp: childEvent.timestamp,
175
+ });
176
+ break;
177
+ case SSEEventType.Error:
178
+ effects.push({
179
+ type: SSEEventType.SubagentEvent,
180
+ parent_tool_id: toolCallId,
181
+ agent_name: task.agentName,
182
+ event_type: 'error',
183
+ error: childEvent.message,
184
+ timestamp: childEvent.timestamp,
185
+ });
186
+ break;
187
+ case SSEEventType.Done:
188
+ effects.push({
189
+ type: SSEEventType.SubagentEvent,
190
+ parent_tool_id: toolCallId,
191
+ agent_name: task.agentName,
192
+ event_type: 'complete',
193
+ timestamp: childEvent.timestamp,
194
+ });
195
+ break;
196
+ default:
197
+ // Skip Init and other events — they're child-internal
198
+ break;
199
+ }
200
+ }
201
+ }
202
+ catch (err) {
203
+ const errorMessage = err instanceof Error ? err.message : String(err);
204
+ ctx.logger.error('dispatch_child_error', {
205
+ session: ctx.sessionId,
206
+ agent: task.agentName,
207
+ error: errorMessage,
208
+ parentToolCallId: toolCallId,
209
+ });
210
+ effects.push({
211
+ type: SSEEventType.SubagentEvent,
212
+ parent_tool_id: toolCallId,
213
+ agent_name: task.agentName,
214
+ event_type: 'error',
215
+ error: errorMessage,
216
+ timestamp: new Date().toISOString(),
217
+ });
218
+ childResponse = `Sub-agent "${task.agentName}" failed: ${errorMessage}`;
219
+ childFailed = true;
220
+ }
221
+ // Merge child usage into parent
222
+ ctx.usage.inputTokens += childCtx.usage.inputTokens;
223
+ ctx.usage.outputTokens += childCtx.usage.outputTokens;
224
+ ctx.usage.totalTokens += childCtx.usage.totalTokens;
225
+ if (childCtx.usage.cachedInputTokens) {
226
+ ctx.usage.cachedInputTokens = (ctx.usage.cachedInputTokens ?? 0) + childCtx.usage.cachedInputTokens;
227
+ }
228
+ if (childCtx.usage.cacheCreationInputTokens) {
229
+ ctx.usage.cacheCreationInputTokens = (ctx.usage.cacheCreationInputTokens ?? 0) + childCtx.usage.cacheCreationInputTokens;
230
+ }
231
+ const duration = Date.now() - startedAt;
232
+ ctx.logger.info('dispatch_complete', {
233
+ session: ctx.sessionId,
234
+ agent: task.agentName,
235
+ childTurns: childCtx.turnCount,
236
+ childUsage: childCtx.usage,
237
+ responseLength: childResponse.length,
238
+ parentToolCallId: toolCallId,
239
+ duration,
240
+ });
241
+ // Build tool result from child response
242
+ const result = {
243
+ callId: toolCallId,
244
+ toolName: DISPATCH_TOOL_NAME,
245
+ status: childFailed ? 'error' : 'success',
246
+ content: childResponse || '(no response from sub-agent)',
247
+ };
248
+ // Emit ToolCallResult for the dispatch_task call
249
+ effects.push({
250
+ type: SSEEventType.ToolCallResult,
251
+ tool_id: toolCallId,
252
+ status: result.status,
253
+ duration_ms: duration,
254
+ ...(result.status === 'error' ? { error: result.content } : {}),
255
+ timestamp: new Date().toISOString(),
256
+ });
257
+ // Use the shared post-result transition logic from EXECUTING.
258
+ // This handles: append tool result message, continue queue, compaction check.
259
+ const executingState = {
260
+ type: 'executing',
261
+ current: { toolCallId, toolName: DISPATCH_TOOL_NAME, args: {} },
262
+ queue: state.queue,
263
+ results: state.results,
264
+ };
265
+ return nextAfterToolResult(executingState, result, effects, ctx);
266
+ }
267
+ // ---------------------------------------------------------------------------
268
+ // Child system prompt
269
+ // ---------------------------------------------------------------------------
270
+ /**
271
+ * Build a minimal system prompt for the child agent.
272
+ *
273
+ * The full parent prompt (30K+ chars of skills, knowledge, connection docs)
274
+ * is wasteful for a focused sub-task. The child gets a concise, task-scoped
275
+ * prompt listing only its available tools.
276
+ */
277
+ function buildChildSystemPrompt(agentName, taskPrompt, toolNames) {
278
+ const toolList = toolNames.length > 0
279
+ ? `\n\nAvailable tools: ${toolNames.join(', ')}`
280
+ : '';
281
+ return `You are "${agentName}", a sub-agent executing a delegated task. Complete the task and return a concise summary of your findings or actions.
282
+
283
+ Do not ask clarifying questions — work with what you have. If you cannot complete the task, explain what went wrong.${toolList}`;
284
+ }
285
+ //# sourceMappingURL=dispatching.js.map