@amodalai/runtime 0.1.26 → 0.2.0

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 (347) hide show
  1. package/dist/src/__fixtures__/README.md +84 -0
  2. package/dist/src/__fixtures__/smoke-agent/amodal.json +11 -0
  3. package/dist/src/__fixtures__/smoke-agent/automations/test-auto.md +5 -0
  4. package/dist/src/__fixtures__/smoke-agent/connections/mock-api/access.json +11 -0
  5. package/dist/src/__fixtures__/smoke-agent/connections/mock-api/spec.json +4 -0
  6. package/dist/src/__fixtures__/smoke-agent/connections/mock-api/surface.md +9 -0
  7. package/dist/src/__fixtures__/smoke-agent/connections/mock-mcp/access.json +3 -0
  8. package/dist/src/__fixtures__/smoke-agent/connections/mock-mcp/spec.json +8 -0
  9. package/dist/src/__fixtures__/smoke-agent/evals/basic-eval.md +12 -0
  10. package/dist/src/__fixtures__/smoke-agent/knowledge/test-knowledge.md +3 -0
  11. package/dist/src/__fixtures__/smoke-agent/skills/test-skill/SKILL.md +11 -0
  12. package/dist/src/__fixtures__/smoke-agent/stores/test-items.json +11 -0
  13. package/dist/src/__fixtures__/smoke-agent/tools/echo_tool/handler.d.ts +18 -0
  14. package/dist/src/__fixtures__/smoke-agent/tools/echo_tool/handler.js +22 -0
  15. package/dist/src/__fixtures__/smoke-agent/tools/echo_tool/handler.js.map +1 -0
  16. package/dist/src/__fixtures__/smoke-agent/tools/echo_tool/tool.json +17 -0
  17. package/dist/src/__fixtures__/smoke.test.js +718 -0
  18. package/dist/src/__fixtures__/smoke.test.js.map +1 -0
  19. package/dist/src/__tests__/test-providers.d.ts +40 -0
  20. package/dist/src/__tests__/test-providers.js +61 -0
  21. package/dist/src/__tests__/test-providers.js.map +1 -0
  22. package/dist/src/agent/local-server.d.ts +3 -3
  23. package/dist/src/agent/local-server.js +213 -122
  24. package/dist/src/agent/local-server.js.map +1 -1
  25. package/dist/src/agent/loop-types.d.ts +175 -0
  26. package/dist/src/agent/loop-types.js +20 -0
  27. package/dist/src/agent/loop-types.js.map +1 -0
  28. package/dist/src/agent/loop.d.ts +31 -0
  29. package/dist/src/agent/loop.js +139 -0
  30. package/dist/src/agent/loop.js.map +1 -0
  31. package/dist/src/agent/loop.test.js +1030 -0
  32. package/dist/src/agent/loop.test.js.map +1 -0
  33. package/dist/src/agent/mcp-config.d.ts +28 -0
  34. package/dist/src/agent/mcp-config.js +57 -0
  35. package/dist/src/agent/mcp-config.js.map +1 -0
  36. package/dist/src/agent/page-builder.js +6 -1
  37. package/dist/src/agent/page-builder.js.map +1 -1
  38. package/dist/src/agent/proactive/proactive-runner.d.ts +24 -8
  39. package/dist/src/agent/proactive/proactive-runner.js +30 -32
  40. package/dist/src/agent/proactive/proactive-runner.js.map +1 -1
  41. package/dist/src/agent/proactive/proactive-runner.test.d.ts +1 -1
  42. package/dist/src/agent/proactive/proactive-runner.test.js +75 -87
  43. package/dist/src/agent/proactive/proactive-runner.test.js.map +1 -1
  44. package/dist/src/agent/routes/admin-chat.d.ts +15 -3
  45. package/dist/src/agent/routes/admin-chat.js +63 -18
  46. package/dist/src/agent/routes/admin-chat.js.map +1 -1
  47. package/dist/src/agent/routes/automations.js +5 -6
  48. package/dist/src/agent/routes/automations.js.map +1 -1
  49. package/dist/src/agent/routes/evals.d.ts +3 -2
  50. package/dist/src/agent/routes/evals.js +25 -12
  51. package/dist/src/agent/routes/evals.js.map +1 -1
  52. package/dist/src/agent/routes/files.js +7 -9
  53. package/dist/src/agent/routes/files.js.map +1 -1
  54. package/dist/src/agent/routes/inspect.d.ts +6 -2
  55. package/dist/src/agent/routes/inspect.js +31 -17
  56. package/dist/src/agent/routes/inspect.js.map +1 -1
  57. package/dist/src/agent/routes/inspect.test.js +18 -42
  58. package/dist/src/agent/routes/inspect.test.js.map +1 -1
  59. package/dist/src/agent/routes/stores.js +9 -12
  60. package/dist/src/agent/routes/stores.js.map +1 -1
  61. package/dist/src/agent/routes/task.d.ts +15 -3
  62. package/dist/src/agent/routes/task.js +16 -7
  63. package/dist/src/agent/routes/task.js.map +1 -1
  64. package/dist/src/agent/routes/task.test.d.ts +1 -1
  65. package/dist/src/agent/routes/task.test.js +70 -53
  66. package/dist/src/agent/routes/task.test.js.map +1 -1
  67. package/dist/src/agent/routes/webhooks.js +12 -3
  68. package/dist/src/agent/routes/webhooks.js.map +1 -1
  69. package/dist/src/agent/session-store.d.ts +11 -2
  70. package/dist/src/agent/session-store.js +1 -1
  71. package/dist/src/agent/session-store.js.map +1 -1
  72. package/dist/src/agent/snapshot-server.d.ts +2 -22
  73. package/dist/src/agent/snapshot-server.js +50 -27
  74. package/dist/src/agent/snapshot-server.js.map +1 -1
  75. package/dist/src/agent/states/compacting.d.ts +14 -0
  76. package/dist/src/agent/states/compacting.js +258 -0
  77. package/dist/src/agent/states/compacting.js.map +1 -0
  78. package/dist/src/agent/states/confirming.d.ts +10 -0
  79. package/dist/src/agent/states/confirming.js +76 -0
  80. package/dist/src/agent/states/confirming.js.map +1 -0
  81. package/dist/src/agent/states/dispatching.d.ts +18 -0
  82. package/dist/src/agent/states/dispatching.js +241 -0
  83. package/dist/src/agent/states/dispatching.js.map +1 -0
  84. package/dist/src/agent/states/executing.d.ts +21 -0
  85. package/dist/src/agent/states/executing.js +308 -0
  86. package/dist/src/agent/states/executing.js.map +1 -0
  87. package/dist/src/agent/states/streaming.d.ts +10 -0
  88. package/dist/src/agent/states/streaming.js +155 -0
  89. package/dist/src/agent/states/streaming.js.map +1 -0
  90. package/dist/src/agent/states/thinking.d.ts +13 -0
  91. package/dist/src/agent/states/thinking.js +233 -0
  92. package/dist/src/agent/states/thinking.js.map +1 -0
  93. package/dist/src/agent/token-estimate.d.ts +17 -0
  94. package/dist/src/agent/token-estimate.js +13 -0
  95. package/dist/src/agent/token-estimate.js.map +1 -0
  96. package/dist/src/agent/tool-executor-local.js +9 -18
  97. package/dist/src/agent/tool-executor-local.js.map +1 -1
  98. package/dist/src/agent/tool-executor-local.test.js +3 -5
  99. package/dist/src/agent/tool-executor-local.test.js.map +1 -1
  100. package/dist/src/api/create-agent.d.ts +15 -0
  101. package/dist/src/api/create-agent.js +137 -0
  102. package/dist/src/api/create-agent.js.map +1 -0
  103. package/dist/src/api/types.d.ts +68 -0
  104. package/dist/src/api/types.js +7 -0
  105. package/dist/src/api/types.js.map +1 -0
  106. package/dist/src/context/compiler.d.ts +13 -0
  107. package/dist/src/context/compiler.js +358 -0
  108. package/dist/src/context/compiler.js.map +1 -0
  109. package/dist/src/context/compiler.test.js +532 -0
  110. package/dist/src/context/compiler.test.js.map +1 -0
  111. package/dist/src/context/types.d.ts +110 -0
  112. package/dist/src/context/types.js +7 -0
  113. package/dist/src/context/types.js.map +1 -0
  114. package/dist/src/index.d.ts +33 -6
  115. package/dist/src/index.js +35 -21
  116. package/dist/src/index.js.map +1 -1
  117. package/dist/src/providers/create-provider.d.ts +23 -0
  118. package/dist/src/providers/create-provider.js +185 -0
  119. package/dist/src/providers/create-provider.js.map +1 -0
  120. package/dist/src/{agent/stores-e2e.test.d.ts → providers/create-provider.test.d.ts} +1 -1
  121. package/dist/src/providers/create-provider.test.js +95 -0
  122. package/dist/src/providers/create-provider.test.js.map +1 -0
  123. package/dist/src/providers/failover.d.ts +38 -0
  124. package/dist/src/providers/failover.js +147 -0
  125. package/dist/src/providers/failover.js.map +1 -0
  126. package/dist/src/providers/failover.test.d.ts +6 -0
  127. package/dist/src/providers/failover.test.js +169 -0
  128. package/dist/src/providers/failover.test.js.map +1 -0
  129. package/dist/src/providers/types.d.ts +110 -0
  130. package/dist/src/providers/types.js +7 -0
  131. package/dist/src/providers/types.js.map +1 -0
  132. package/dist/src/routes/ai-stream.d.ts +13 -10
  133. package/dist/src/routes/ai-stream.js +76 -41
  134. package/dist/src/routes/ai-stream.js.map +1 -1
  135. package/dist/src/routes/chat-new.test.d.ts +6 -0
  136. package/dist/src/routes/chat-new.test.js +107 -0
  137. package/dist/src/routes/chat-new.test.js.map +1 -0
  138. package/dist/src/routes/chat-stream-new.test.d.ts +6 -0
  139. package/dist/src/routes/chat-stream-new.test.js +135 -0
  140. package/dist/src/routes/chat-stream-new.test.js.map +1 -0
  141. package/dist/src/routes/chat-stream.d.ts +14 -4
  142. package/dist/src/routes/chat-stream.js +47 -29
  143. package/dist/src/routes/chat-stream.js.map +1 -1
  144. package/dist/src/routes/chat.d.ts +13 -4
  145. package/dist/src/routes/chat.js +60 -23
  146. package/dist/src/routes/chat.js.map +1 -1
  147. package/dist/src/routes/health.d.ts +3 -2
  148. package/dist/src/routes/health.js.map +1 -1
  149. package/dist/src/routes/route-helpers.d.ts +50 -0
  150. package/dist/src/routes/route-helpers.js +80 -0
  151. package/dist/src/routes/route-helpers.js.map +1 -0
  152. package/dist/src/routes/session-resolver.d.ts +72 -0
  153. package/dist/src/routes/session-resolver.js +123 -0
  154. package/dist/src/routes/session-resolver.js.map +1 -0
  155. package/dist/src/routes/session-resolver.test.d.ts +6 -0
  156. package/dist/src/routes/session-resolver.test.js +206 -0
  157. package/dist/src/routes/session-resolver.test.js.map +1 -0
  158. package/dist/src/routes/webhooks.d.ts +3 -1
  159. package/dist/src/routes/webhooks.js +12 -4
  160. package/dist/src/routes/webhooks.js.map +1 -1
  161. package/dist/src/security/permission-checker.d.ts +80 -0
  162. package/dist/src/security/permission-checker.js +75 -0
  163. package/dist/src/security/permission-checker.js.map +1 -0
  164. package/dist/src/security/permission-checker.test.d.ts +6 -0
  165. package/dist/src/security/permission-checker.test.js +208 -0
  166. package/dist/src/security/permission-checker.test.js.map +1 -0
  167. package/dist/src/server.d.ts +12 -11
  168. package/dist/src/server.js +44 -46
  169. package/dist/src/server.js.map +1 -1
  170. package/dist/src/server.test.d.ts +1 -1
  171. package/dist/src/server.test.js +6 -144
  172. package/dist/src/server.test.js.map +1 -1
  173. package/dist/src/session/manager.d.ts +98 -0
  174. package/dist/src/session/manager.js +364 -0
  175. package/dist/src/session/manager.js.map +1 -0
  176. package/dist/src/session/manager.test.d.ts +6 -0
  177. package/dist/src/session/manager.test.js +315 -0
  178. package/dist/src/session/manager.test.js.map +1 -0
  179. package/dist/src/session/session-builder.d.ts +71 -0
  180. package/dist/src/session/session-builder.js +364 -0
  181. package/dist/src/session/session-builder.js.map +1 -0
  182. package/dist/src/session/session-builder.test.d.ts +6 -0
  183. package/dist/src/session/session-builder.test.js +352 -0
  184. package/dist/src/session/session-builder.test.js.map +1 -0
  185. package/dist/src/session/store.d.ts +57 -0
  186. package/dist/src/session/store.js +167 -0
  187. package/dist/src/session/store.js.map +1 -0
  188. package/dist/src/session/store.test.d.ts +6 -0
  189. package/dist/src/session/store.test.js +145 -0
  190. package/dist/src/session/store.test.js.map +1 -0
  191. package/dist/src/session/stream-hooks.d.ts +39 -0
  192. package/dist/src/session/stream-hooks.js +7 -0
  193. package/dist/src/session/stream-hooks.js.map +1 -0
  194. package/dist/src/session/tool-context-factory.d.ts +60 -0
  195. package/dist/src/session/tool-context-factory.js +190 -0
  196. package/dist/src/session/tool-context-factory.js.map +1 -0
  197. package/dist/src/session/tool-context-factory.test.d.ts +6 -0
  198. package/dist/src/session/tool-context-factory.test.js +287 -0
  199. package/dist/src/session/tool-context-factory.test.js.map +1 -0
  200. package/dist/src/session/types.d.ts +188 -0
  201. package/dist/src/session/types.js +7 -0
  202. package/dist/src/session/types.js.map +1 -0
  203. package/dist/src/stores/drizzle-store-backend.d.ts +49 -0
  204. package/dist/src/stores/drizzle-store-backend.js +306 -0
  205. package/dist/src/stores/drizzle-store-backend.js.map +1 -0
  206. package/dist/src/stores/drizzle-store-backend.test.d.ts +6 -0
  207. package/dist/src/stores/drizzle-store-backend.test.js +215 -0
  208. package/dist/src/stores/drizzle-store-backend.test.js.map +1 -0
  209. package/dist/src/stores/index.d.ts +4 -0
  210. package/dist/src/stores/index.js +2 -0
  211. package/dist/src/stores/index.js.map +1 -1
  212. package/dist/src/stores/pglite-store-backend.d.ts +16 -19
  213. package/dist/src/stores/pglite-store-backend.js +85 -239
  214. package/dist/src/stores/pglite-store-backend.js.map +1 -1
  215. package/dist/src/stores/postgres-store-backend.d.ts +30 -0
  216. package/dist/src/stores/postgres-store-backend.js +100 -0
  217. package/dist/src/stores/postgres-store-backend.js.map +1 -0
  218. package/dist/src/stores/schema.d.ts +491 -0
  219. package/dist/src/stores/schema.js +57 -0
  220. package/dist/src/stores/schema.js.map +1 -0
  221. package/dist/src/tools/admin-file-tools.d.ts +13 -0
  222. package/dist/src/tools/admin-file-tools.js +200 -0
  223. package/dist/src/tools/admin-file-tools.js.map +1 -0
  224. package/dist/src/tools/admin-file-tools.test.d.ts +6 -0
  225. package/dist/src/tools/admin-file-tools.test.js +152 -0
  226. package/dist/src/tools/admin-file-tools.test.js.map +1 -0
  227. package/dist/src/tools/custom-tool-adapter.d.ts +41 -0
  228. package/dist/src/tools/custom-tool-adapter.js +190 -0
  229. package/dist/src/tools/custom-tool-adapter.js.map +1 -0
  230. package/dist/src/tools/custom-tool-adapter.test.d.ts +6 -0
  231. package/dist/src/tools/custom-tool-adapter.test.js +244 -0
  232. package/dist/src/tools/custom-tool-adapter.test.js.map +1 -0
  233. package/dist/src/tools/dispatch-tool.d.ts +52 -0
  234. package/dist/src/tools/dispatch-tool.js +71 -0
  235. package/dist/src/tools/dispatch-tool.js.map +1 -0
  236. package/dist/src/tools/dispatch-tool.test.d.ts +6 -0
  237. package/dist/src/tools/dispatch-tool.test.js +75 -0
  238. package/dist/src/tools/dispatch-tool.test.js.map +1 -0
  239. package/dist/src/tools/mcp-tool-adapter.d.ts +18 -0
  240. package/dist/src/tools/mcp-tool-adapter.js +135 -0
  241. package/dist/src/tools/mcp-tool-adapter.js.map +1 -0
  242. package/dist/src/tools/mcp-tool-adapter.test.d.ts +6 -0
  243. package/dist/src/tools/mcp-tool-adapter.test.js +227 -0
  244. package/dist/src/tools/mcp-tool-adapter.test.js.map +1 -0
  245. package/dist/src/tools/registry.d.ts +25 -0
  246. package/dist/src/tools/registry.js +72 -0
  247. package/dist/src/tools/registry.js.map +1 -0
  248. package/dist/src/tools/registry.test.d.ts +6 -0
  249. package/dist/src/tools/registry.test.js +121 -0
  250. package/dist/src/tools/registry.test.js.map +1 -0
  251. package/dist/src/tools/request-tool.d.ts +42 -0
  252. package/dist/src/tools/request-tool.js +190 -0
  253. package/dist/src/tools/request-tool.js.map +1 -0
  254. package/dist/src/tools/request-tool.test.d.ts +6 -0
  255. package/dist/src/tools/request-tool.test.js +254 -0
  256. package/dist/src/tools/request-tool.test.js.map +1 -0
  257. package/dist/src/tools/store-tools.d.ts +29 -0
  258. package/dist/src/tools/store-tools.js +224 -0
  259. package/dist/src/tools/store-tools.js.map +1 -0
  260. package/dist/src/tools/store-tools.test.d.ts +6 -0
  261. package/dist/src/tools/store-tools.test.js +216 -0
  262. package/dist/src/tools/store-tools.test.js.map +1 -0
  263. package/dist/src/tools/types.d.ts +111 -0
  264. package/dist/src/tools/types.js +7 -0
  265. package/dist/src/tools/types.js.map +1 -0
  266. package/dist/src/types.d.ts +20 -12
  267. package/dist/src/types.js +3 -2
  268. package/dist/src/types.js.map +1 -1
  269. package/dist/tsconfig.tsbuildinfo +1 -1
  270. package/package.json +13 -4
  271. package/dist/src/__tests__/sse-contract.test.js +0 -464
  272. package/dist/src/__tests__/sse-contract.test.js.map +0 -1
  273. package/dist/src/__tests__/tools.test.js +0 -583
  274. package/dist/src/__tests__/tools.test.js.map +0 -1
  275. package/dist/src/agent/agent-runner.d.ts +0 -33
  276. package/dist/src/agent/agent-runner.js +0 -1040
  277. package/dist/src/agent/agent-runner.js.map +0 -1
  278. package/dist/src/agent/custom-tools-e2e.test.d.ts +0 -6
  279. package/dist/src/agent/custom-tools-e2e.test.js +0 -566
  280. package/dist/src/agent/custom-tools-e2e.test.js.map +0 -1
  281. package/dist/src/agent/request-helper.d.ts +0 -16
  282. package/dist/src/agent/request-helper.js +0 -96
  283. package/dist/src/agent/request-helper.js.map +0 -1
  284. package/dist/src/agent/stores-e2e.test.js +0 -433
  285. package/dist/src/agent/stores-e2e.test.js.map +0 -1
  286. package/dist/src/agent/tool-context-builder.d.ts +0 -11
  287. package/dist/src/agent/tool-context-builder.js +0 -102
  288. package/dist/src/agent/tool-context-builder.js.map +0 -1
  289. package/dist/src/agent/tool-context-builder.test.d.ts +0 -6
  290. package/dist/src/agent/tool-context-builder.test.js +0 -152
  291. package/dist/src/agent/tool-context-builder.test.js.map +0 -1
  292. package/dist/src/agent/write-repo-file.test.js +0 -270
  293. package/dist/src/agent/write-repo-file.test.js.map +0 -1
  294. package/dist/src/cron/heartbeat-runner.d.ts +0 -21
  295. package/dist/src/cron/heartbeat-runner.js +0 -79
  296. package/dist/src/cron/heartbeat-runner.js.map +0 -1
  297. package/dist/src/cron/heartbeat-runner.test.d.ts +0 -6
  298. package/dist/src/cron/heartbeat-runner.test.js +0 -120
  299. package/dist/src/cron/heartbeat-runner.test.js.map +0 -1
  300. package/dist/src/cron/heartbeat-scheduler.d.ts +0 -26
  301. package/dist/src/cron/heartbeat-scheduler.js +0 -55
  302. package/dist/src/cron/heartbeat-scheduler.js.map +0 -1
  303. package/dist/src/cron/heartbeat-scheduler.test.d.ts +0 -6
  304. package/dist/src/cron/heartbeat-scheduler.test.js +0 -61
  305. package/dist/src/cron/heartbeat-scheduler.test.js.map +0 -1
  306. package/dist/src/routes/ai-stream.test.d.ts +0 -6
  307. package/dist/src/routes/ai-stream.test.js +0 -586
  308. package/dist/src/routes/ai-stream.test.js.map +0 -1
  309. package/dist/src/routes/ask-user-response.d.ts +0 -30
  310. package/dist/src/routes/ask-user-response.js +0 -61
  311. package/dist/src/routes/ask-user-response.js.map +0 -1
  312. package/dist/src/routes/ask-user-response.test.d.ts +0 -6
  313. package/dist/src/routes/ask-user-response.test.js +0 -88
  314. package/dist/src/routes/ask-user-response.test.js.map +0 -1
  315. package/dist/src/routes/chat-stream.test.d.ts +0 -6
  316. package/dist/src/routes/chat-stream.test.js +0 -155
  317. package/dist/src/routes/chat-stream.test.js.map +0 -1
  318. package/dist/src/routes/chat.test.d.ts +0 -6
  319. package/dist/src/routes/chat.test.js +0 -99
  320. package/dist/src/routes/chat.test.js.map +0 -1
  321. package/dist/src/routes/widget-actions.d.ts +0 -49
  322. package/dist/src/routes/widget-actions.js +0 -78
  323. package/dist/src/routes/widget-actions.js.map +0 -1
  324. package/dist/src/session/custom-tool-adapter.d.ts +0 -74
  325. package/dist/src/session/custom-tool-adapter.js +0 -180
  326. package/dist/src/session/custom-tool-adapter.js.map +0 -1
  327. package/dist/src/session/history-converter.d.ts +0 -21
  328. package/dist/src/session/history-converter.js +0 -59
  329. package/dist/src/session/history-converter.js.map +0 -1
  330. package/dist/src/session/history-converter.test.d.ts +0 -6
  331. package/dist/src/session/history-converter.test.js +0 -130
  332. package/dist/src/session/history-converter.test.js.map +0 -1
  333. package/dist/src/session/session-manager.d.ts +0 -219
  334. package/dist/src/session/session-manager.js +0 -915
  335. package/dist/src/session/session-manager.js.map +0 -1
  336. package/dist/src/session/session-manager.test.d.ts +0 -6
  337. package/dist/src/session/session-manager.test.js +0 -455
  338. package/dist/src/session/session-manager.test.js.map +0 -1
  339. package/dist/src/session/session-runner.d.ts +0 -45
  340. package/dist/src/session/session-runner.js +0 -719
  341. package/dist/src/session/session-runner.js.map +0 -1
  342. package/dist/src/session/session-runner.test.d.ts +0 -6
  343. package/dist/src/session/session-runner.test.js +0 -834
  344. package/dist/src/session/session-runner.test.js.map +0 -1
  345. /package/dist/src/{__tests__/sse-contract.test.d.ts → __fixtures__/smoke.test.d.ts} +0 -0
  346. /package/dist/src/{__tests__/tools.test.d.ts → agent/loop.test.d.ts} +0 -0
  347. /package/dist/src/{agent/write-repo-file.test.d.ts → context/compiler.test.d.ts} +0 -0
@@ -1,55 +1,73 @@
1
1
  /**
2
2
  * @license
3
- * Copyright 2025 Amodal Labs, Inc.
3
+ * Copyright 2026 Amodal Labs, Inc.
4
4
  * SPDX-License-Identifier: MIT
5
5
  */
6
+ /**
7
+ * Streaming chat route.
8
+ *
9
+ * Accepts POST to /chat and /chat/stream, resolves a session via the
10
+ * standalone session manager, runs the message through the agent loop,
11
+ * and streams SSE events to the client.
12
+ */
6
13
  import { Router } from 'express';
7
14
  import { ChatRequestSchema, SSEEventType } from '../types.js';
8
15
  import { validate } from '../middleware/request-validation.js';
9
16
  import { getAuthContext } from '../middleware/auth.js';
10
- import { streamMessage } from '../session/session-runner.js';
17
+ import { resolveSession } from './session-resolver.js';
18
+ import { adaptOnUsage, asyncHandler, fireDrainHooks, UNKNOWN_TOOL_NAME } from './route-helpers.js';
19
+ // ---------------------------------------------------------------------------
20
+ // Router
21
+ // ---------------------------------------------------------------------------
11
22
  export function createChatStreamRouter(options) {
12
23
  const router = Router();
13
24
  // Mount on both /chat and /chat/stream so the SPA always gets SSE
14
- router.post(['/chat', '/chat/stream'], validate(ChatRequestSchema),
15
- // eslint-disable-next-line @typescript-eslint/no-misused-promises -- TODO: wrap async route handler
16
- async (req, res, next) => {
25
+ router.post(['/chat', '/chat/stream'], validate(ChatRequestSchema), asyncHandler(async (req, res, next) => {
17
26
  try {
18
- const { message, session_id, role, session_type, deploy_id } = req.body;
19
- let session;
20
- if (session_id) {
21
- session = options.sessionManager.get(session_id);
22
- if (!session) {
23
- // Try hydrating from stored conversation history
24
- const auth = getAuthContext(res);
25
- session = await options.sessionManager.hydrate(session_id, role, auth, session_type);
26
- }
27
- if (!session) {
28
- // History not found — create fresh session
29
- const auth = getAuthContext(res);
30
- session = await options.sessionManager.create(role, auth, session_type, undefined, deploy_id);
31
- }
32
- }
33
- else {
34
- const auth = getAuthContext(res);
35
- session = await options.sessionManager.create(role, auth, session_type, undefined, deploy_id);
36
- }
27
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- validated by Zod middleware
28
+ const body = req.body;
29
+ const auth = getAuthContext(res);
30
+ const { session, toolContextFactory } = await resolveSession(body.session_id, {
31
+ sessionManager: options.sessionManager,
32
+ bundleResolver: options.bundleResolver,
33
+ shared: options.shared,
34
+ role: body.role,
35
+ sessionType: body.session_type,
36
+ deployId: body.deploy_id,
37
+ auth,
38
+ });
37
39
  // Set up SSE headers (use setHeader to preserve CORS headers from middleware)
38
40
  res.setHeader('Content-Type', 'text/event-stream');
39
41
  res.setHeader('Cache-Control', 'no-cache');
40
42
  res.setHeader('Connection', 'keep-alive');
41
43
  res.flushHeaders();
42
44
  const controller = new AbortController();
43
- // Abort on client disconnect
44
45
  res.on('close', () => controller.abort());
45
- // Build per-request hooks with auth context
46
- const hooks = options.createStreamHooks?.(getAuthContext(res));
47
- const stream = streamMessage(session, message, controller.signal, hooks, options.sessionManager);
46
+ const hooks = options.createStreamHooks?.(auth);
47
+ const stream = options.sessionManager.runMessage(session.id, body.message, {
48
+ signal: controller.signal,
49
+ buildToolContext: toolContextFactory,
50
+ onUsage: adaptOnUsage(hooks, session),
51
+ });
52
+ // Track tool calls for audit log
53
+ const toolNames = new Map();
54
+ const toolCalls = [];
48
55
  for await (const event of stream) {
49
56
  if (controller.signal.aborted)
50
57
  break;
51
58
  res.write(`data: ${JSON.stringify(event)}\n\n`);
59
+ if (event.type === SSEEventType.ToolCallStart) {
60
+ toolNames.set(event.tool_id, event.tool_name);
61
+ }
62
+ else if (event.type === SSEEventType.ToolCallResult) {
63
+ toolCalls.push({
64
+ tool_name: toolNames.get(event.tool_id) ?? UNKNOWN_TOOL_NAME,
65
+ tool_id: event.tool_id,
66
+ status: event.status,
67
+ });
68
+ }
52
69
  }
70
+ await fireDrainHooks(options.sessionManager, hooks, { session, toolCalls });
53
71
  res.end();
54
72
  }
55
73
  catch (err) {
@@ -67,7 +85,7 @@ export function createChatStreamRouter(options) {
67
85
  next(err);
68
86
  }
69
87
  }
70
- });
88
+ }));
71
89
  return router;
72
90
  }
73
91
  //# sourceMappingURL=chat-stream.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"chat-stream.js","sourceRoot":"","sources":["../../../src/routes/chat-stream.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,QAAQ,EAAE,MAAM,qCAAqC,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAGvD,OAAO,EAAE,aAAa,EAAoB,MAAM,8BAA8B,CAAC;AAQ/E,MAAM,UAAU,sBAAsB,CACpC,OAAgC;IAEhC,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;IAExB,kEAAkE;IAClE,MAAM,CAAC,IAAI,CACT,CAAC,OAAO,EAAE,cAAc,CAAC,EACzB,QAAQ,CAAC,iBAAiB,CAAC;IAC3B,oGAAoG;IACpG,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QACvB,IAAI,CAAC;YACH,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC;YAExE,IAAI,OAAO,CAAC;YACZ,IAAI,UAAU,EAAE,CAAC;gBACf,OAAO,GAAG,OAAO,CAAC,cAAc,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;gBACjD,IAAI,CAAC,OAAO,EAAE,CAAC;oBACb,iDAAiD;oBACjD,MAAM,IAAI,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;oBACjC,OAAO,GAAG,MAAM,OAAO,CAAC,cAAc,CAAC,OAAO,CAAC,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC;gBACvF,CAAC;gBACD,IAAI,CAAC,OAAO,EAAE,CAAC;oBACb,2CAA2C;oBAC3C,MAAM,IAAI,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;oBACjC,OAAO,GAAG,MAAM,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;gBAChG,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;gBACjC,OAAO,GAAG,MAAM,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;YAChG,CAAC;YAED,8EAA8E;YAC9E,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,mBAAmB,CAAC,CAAC;YACnD,GAAG,CAAC,SAAS,CAAC,eAAe,EAAE,UAAU,CAAC,CAAC;YAC3C,GAAG,CAAC,SAAS,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;YAC1C,GAAG,CAAC,YAAY,EAAE,CAAC;YAEnB,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;YAEzC,6BAA6B;YAC7B,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC;YAE1C,4CAA4C;YAC5C,MAAM,KAAK,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC;YAE/D,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;YAEjG,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBACjC,IAAI,UAAU,CAAC,MAAM,CAAC,OAAO;oBAAE,MAAM;gBACrC,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAClD,CAAC;YAED,GAAG,CAAC,GAAG,EAAE,CAAC;QACZ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,kEAAkE;YAClE,IAAI,GAAG,CAAC,WAAW,EAAE,CAAC;gBACpB,MAAM,UAAU,GAAG;oBACjB,IAAI,EAAE,YAAY,CAAC,KAAK;oBACxB,OAAO,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe;oBAC7D,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;iBACpC,CAAC;gBACF,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;gBACrD,GAAG,CAAC,GAAG,EAAE,CAAC;YACZ,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,GAAG,CAAC,CAAC;YACZ,CAAC;QACH,CAAC;IACH,CAAC,CACF,CAAC;IAEF,OAAO,MAAM,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"chat-stream.js","sourceRoot":"","sources":["../../../src/routes/chat-stream.ts"],"names":[],"mappings":"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"}
@@ -1,14 +1,23 @@
1
1
  /**
2
2
  * @license
3
- * Copyright 2025 Amodal Labs, Inc.
3
+ * Copyright 2026 Amodal Labs, Inc.
4
4
  * SPDX-License-Identifier: MIT
5
5
  */
6
+ /**
7
+ * Non-streaming chat route.
8
+ *
9
+ * Accepts POST to /chat/sync, resolves a session, runs the message through
10
+ * the agent loop, collects all events, and returns a JSON ChatResponse.
11
+ */
6
12
  import { Router } from 'express';
7
13
  import type { AuthContext } from '../middleware/auth.js';
8
- import type { SessionManager } from '../session/session-manager.js';
9
- import { type StreamHooks } from '../session/session-runner.js';
14
+ import type { StandaloneSessionManager } from '../session/manager.js';
15
+ import type { StreamHooks } from '../session/stream-hooks.js';
16
+ import type { BundleResolver, SharedResources } from './session-resolver.js';
10
17
  export interface ChatRouterOptions {
11
- sessionManager: SessionManager;
18
+ sessionManager: StandaloneSessionManager;
19
+ bundleResolver: BundleResolver;
20
+ shared: SharedResources;
12
21
  /** Factory that builds per-request stream hooks from the auth context */
13
22
  createStreamHooks?: (auth?: AuthContext) => StreamHooks;
14
23
  }
@@ -1,43 +1,80 @@
1
1
  /**
2
2
  * @license
3
- * Copyright 2025 Amodal Labs, Inc.
3
+ * Copyright 2026 Amodal Labs, Inc.
4
4
  * SPDX-License-Identifier: MIT
5
5
  */
6
+ /**
7
+ * Non-streaming chat route.
8
+ *
9
+ * Accepts POST to /chat/sync, resolves a session, runs the message through
10
+ * the agent loop, collects all events, and returns a JSON ChatResponse.
11
+ */
6
12
  import { Router } from 'express';
7
- import { ChatRequestSchema } from '../types.js';
13
+ import { ChatRequestSchema, SSEEventType } from '../types.js';
8
14
  import { validate } from '../middleware/request-validation.js';
9
- import { AppError } from '../middleware/error-handler.js';
10
15
  import { getAuthContext } from '../middleware/auth.js';
11
- import { runMessage } from '../session/session-runner.js';
16
+ import { resolveSession } from './session-resolver.js';
17
+ import { adaptOnUsage, asyncHandler, fireDrainHooks, UNKNOWN_TOOL_NAME } from './route-helpers.js';
18
+ // ---------------------------------------------------------------------------
19
+ // Router
20
+ // ---------------------------------------------------------------------------
12
21
  export function createChatRouter(options) {
13
22
  const router = Router();
14
- // eslint-disable-next-line @typescript-eslint/no-misused-promises -- TODO: wrap async route handler
15
- router.post('/chat', validate(ChatRequestSchema), async (req, res, next) => {
23
+ router.post('/chat/sync', validate(ChatRequestSchema), asyncHandler(async (req, res, next) => {
16
24
  try {
17
- const { message, session_id, role, deploy_id } = req.body;
18
- // Get or create session
19
- let session;
20
- if (session_id) {
21
- session = options.sessionManager.get(session_id);
22
- if (!session) {
23
- throw new AppError(404, 'SESSION_NOT_FOUND', `Session ${session_id} not found`);
24
- }
25
- }
26
- else {
27
- const auth = getAuthContext(res);
28
- session = await options.sessionManager.create(role, auth, undefined, undefined, deploy_id);
29
- }
25
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- validated by Zod middleware
26
+ const body = req.body;
27
+ const auth = getAuthContext(res);
28
+ const { session, toolContextFactory } = await resolveSession(body.session_id, {
29
+ sessionManager: options.sessionManager,
30
+ bundleResolver: options.bundleResolver,
31
+ shared: options.shared,
32
+ role: body.role,
33
+ sessionType: body.session_type,
34
+ deployId: body.deploy_id,
35
+ auth,
36
+ });
30
37
  const controller = new AbortController();
31
- // Abort on client disconnect
32
38
  res.on('close', () => controller.abort());
33
- const hooks = options.createStreamHooks?.(getAuthContext(res));
34
- const result = await runMessage(session, message, controller.signal, hooks);
39
+ const hooks = options.createStreamHooks?.(auth);
40
+ const stream = options.sessionManager.runMessage(session.id, body.message, {
41
+ signal: controller.signal,
42
+ buildToolContext: toolContextFactory,
43
+ onUsage: adaptOnUsage(hooks, session),
44
+ });
45
+ let responseText = '';
46
+ const toolNames = new Map();
47
+ const toolCalls = [];
48
+ for await (const event of stream) {
49
+ if (controller.signal.aborted)
50
+ break;
51
+ if (event.type === SSEEventType.TextDelta) {
52
+ responseText += event.content;
53
+ }
54
+ else if (event.type === SSEEventType.ToolCallStart) {
55
+ toolNames.set(event.tool_id, event.tool_name);
56
+ }
57
+ else if (event.type === SSEEventType.ToolCallResult) {
58
+ toolCalls.push({
59
+ tool_name: toolNames.get(event.tool_id) ?? UNKNOWN_TOOL_NAME,
60
+ tool_id: event.tool_id,
61
+ status: event.status,
62
+ error: event.error,
63
+ });
64
+ }
65
+ }
66
+ await fireDrainHooks(options.sessionManager, hooks, { session, toolCalls });
67
+ const result = {
68
+ session_id: session.id,
69
+ response: responseText,
70
+ tool_calls: toolCalls,
71
+ };
35
72
  res.json(result);
36
73
  }
37
74
  catch (err) {
38
75
  next(err);
39
76
  }
40
- });
77
+ }));
41
78
  return router;
42
79
  }
43
80
  //# sourceMappingURL=chat.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"chat.js","sourceRoot":"","sources":["../../../src/routes/chat.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,qCAAqC,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAGvD,OAAO,EAAE,UAAU,EAAoB,MAAM,8BAA8B,CAAC;AAQ5E,MAAM,UAAU,gBAAgB,CAAC,OAA0B;IACzD,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;IAExB,oGAAoG;IACpG,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,iBAAiB,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QACzE,IAAI,CAAC;YACH,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC;YAE1D,wBAAwB;YACxB,IAAI,OAAO,CAAC;YACZ,IAAI,UAAU,EAAE,CAAC;gBACf,OAAO,GAAG,OAAO,CAAC,cAAc,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;gBACjD,IAAI,CAAC,OAAO,EAAE,CAAC;oBACb,MAAM,IAAI,QAAQ,CAAC,GAAG,EAAE,mBAAmB,EAAE,WAAW,UAAU,YAAY,CAAC,CAAC;gBAClF,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;gBACjC,OAAO,GAAG,MAAM,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;YAC7F,CAAC;YAED,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;YAEzC,6BAA6B;YAC7B,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC;YAE1C,MAAM,KAAK,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC;YAC/D,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YAC5E,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACnB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,GAAG,CAAC,CAAC;QACZ,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"chat.js","sourceRoot":"","sources":["../../../src/routes/chat.ts"],"names":[],"mappings":"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"}
@@ -4,9 +4,10 @@
4
4
  * SPDX-License-Identifier: MIT
5
5
  */
6
6
  import { Router } from 'express';
7
- import type { SessionManager } from '../session/session-manager.js';
8
7
  export interface HealthRouterOptions {
9
- sessionManager: SessionManager;
8
+ sessionManager: {
9
+ size: number;
10
+ };
10
11
  version?: string;
11
12
  startedAt: number;
12
13
  }
@@ -1 +1 @@
1
- {"version":3,"file":"health.js","sourceRoot":"","sources":["../../../src/routes/health.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AASjC,MAAM,UAAU,kBAAkB,CAAC,OAA4B;IAC7D,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;IAExB,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;QAClC,GAAG,CAAC,IAAI,CAAC;YACP,MAAM,EAAE,IAAI;YACZ,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,SAAS;YACzC,eAAe,EAAE,OAAO,CAAC,cAAc,CAAC,IAAI;SAC7C,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;QACnC,GAAG,CAAC,IAAI,CAAC;YACP,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,SAAS;SACtC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"health.js","sourceRoot":"","sources":["../../../src/routes/health.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAOjC,MAAM,UAAU,kBAAkB,CAAC,OAA4B;IAC7D,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;IAExB,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;QAClC,GAAG,CAAC,IAAI,CAAC;YACP,MAAM,EAAE,IAAI;YACZ,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,SAAS;YACzC,eAAe,EAAE,OAAO,CAAC,cAAc,CAAC,IAAI;SAC7C,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;QACnC,GAAG,CAAC,IAAI,CAAC;YACP,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,SAAS;SACtC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ /**
7
+ * Shared helpers for chat route handlers.
8
+ *
9
+ * Deduplicates post-drain hook logic and session persistence across
10
+ * chat-stream, ai-stream, and chat routes.
11
+ */
12
+ import type { Request, Response, NextFunction, RequestHandler } from 'express';
13
+ import type { StandaloneSessionManager } from '../session/manager.js';
14
+ import type { Session, TurnUsage } from '../session/types.js';
15
+ import type { StreamHooks } from '../session/stream-hooks.js';
16
+ /**
17
+ * Wrap an async Express handler so rejected promises propagate to the error
18
+ * middleware instead of hanging the request.
19
+ *
20
+ * Express doesn't await async handlers — if one throws, the request hangs
21
+ * forever. This wrapper catches the rejection and passes it to `next()`.
22
+ */
23
+ export declare function asyncHandler(fn: (req: Request, res: Response, next: NextFunction) => Promise<void> | Promise<Response>): RequestHandler;
24
+ /** Fallback name for tools where the ToolCallStart event was missed. */
25
+ export declare const UNKNOWN_TOOL_NAME = "unknown";
26
+ /** Audit event name emitted after a message completes. */
27
+ export declare const AUDIT_SESSION_COMPLETED = "session_completed";
28
+ interface DrainContext {
29
+ session: Session;
30
+ toolCalls: Array<{
31
+ tool_name: string;
32
+ tool_id: string;
33
+ status: string;
34
+ }>;
35
+ }
36
+ /**
37
+ * Adapt the old `onUsageReport` hook to the new `TurnUsage` callback
38
+ * expected by `StandaloneSessionManager.runMessage`.
39
+ */
40
+ export declare function adaptOnUsage(hooks: StreamHooks | undefined, session: Session): ((usage: TurnUsage) => void) | undefined;
41
+ /**
42
+ * Fire post-drain hooks and persist the session.
43
+ *
44
+ * Called after the runMessage generator is fully consumed. Handles:
45
+ * - Explicit session persistence (belt-and-suspenders with runMessage's internal persist)
46
+ * - Audit log hook with tool call summary
47
+ * - Session persist hook for hosted-mode analytics
48
+ */
49
+ export declare function fireDrainHooks(sessionManager: StandaloneSessionManager, hooks: StreamHooks | undefined, ctx: DrainContext): Promise<void>;
50
+ export {};
@@ -0,0 +1,80 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ // ---------------------------------------------------------------------------
7
+ // Async handler wrapper
8
+ // ---------------------------------------------------------------------------
9
+ /**
10
+ * Wrap an async Express handler so rejected promises propagate to the error
11
+ * middleware instead of hanging the request.
12
+ *
13
+ * Express doesn't await async handlers — if one throws, the request hangs
14
+ * forever. This wrapper catches the rejection and passes it to `next()`.
15
+ */
16
+ export function asyncHandler(fn) {
17
+ return (req, res, next) => {
18
+ Promise.resolve(fn(req, res, next)).catch(next);
19
+ };
20
+ }
21
+ // ---------------------------------------------------------------------------
22
+ // Constants
23
+ // ---------------------------------------------------------------------------
24
+ /** Fallback name for tools where the ToolCallStart event was missed. */
25
+ export const UNKNOWN_TOOL_NAME = 'unknown';
26
+ /** Audit event name emitted after a message completes. */
27
+ export const AUDIT_SESSION_COMPLETED = 'session_completed';
28
+ /**
29
+ * Adapt the old `onUsageReport` hook to the new `TurnUsage` callback
30
+ * expected by `StandaloneSessionManager.runMessage`.
31
+ */
32
+ export function adaptOnUsage(hooks, session) {
33
+ if (!hooks?.onUsageReport)
34
+ return undefined;
35
+ return (usage) => {
36
+ hooks.onUsageReport?.({
37
+ model: session.model,
38
+ taskAgentRuns: 0,
39
+ tokens: {
40
+ inputTokens: usage.inputTokens,
41
+ outputTokens: usage.outputTokens,
42
+ cachedTokens: usage.cachedInputTokens,
43
+ },
44
+ });
45
+ };
46
+ }
47
+ /**
48
+ * Fire post-drain hooks and persist the session.
49
+ *
50
+ * Called after the runMessage generator is fully consumed. Handles:
51
+ * - Explicit session persistence (belt-and-suspenders with runMessage's internal persist)
52
+ * - Audit log hook with tool call summary
53
+ * - Session persist hook for hosted-mode analytics
54
+ */
55
+ export async function fireDrainHooks(sessionManager, hooks, ctx) {
56
+ const { session, toolCalls } = ctx;
57
+ // Persist session explicitly — runMessage persists internally when a store
58
+ // is configured, but the route also needs to persist when the generator is
59
+ // aborted mid-stream (the generator's post-loop code doesn't run on abort).
60
+ await sessionManager.persist(session);
61
+ if (hooks?.onAuditLog) {
62
+ hooks.onAuditLog({
63
+ event: AUDIT_SESSION_COMPLETED,
64
+ resource_name: session.id,
65
+ details: {
66
+ session_id: session.id,
67
+ tool_calls: toolCalls,
68
+ model: session.model,
69
+ provider: session.providerName,
70
+ },
71
+ });
72
+ }
73
+ if (hooks?.onSessionPersist) {
74
+ hooks.onSessionPersist(session.id, [], 'completed', {
75
+ model: session.model,
76
+ provider: session.providerName,
77
+ });
78
+ }
79
+ }
80
+ //# sourceMappingURL=route-helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-helpers.js","sourceRoot":"","sources":["../../../src/routes/route-helpers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAcH,8EAA8E;AAC9E,wBAAwB;AACxB,8EAA8E;AAE9E;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAC1B,EAA0F;IAE1F,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QACxB,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAClD,CAAC,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,YAAY;AACZ,8EAA8E;AAE9E,wEAAwE;AACxE,MAAM,CAAC,MAAM,iBAAiB,GAAG,SAAS,CAAC;AAE3C,0DAA0D;AAC1D,MAAM,CAAC,MAAM,uBAAuB,GAAG,mBAAmB,CAAC;AAW3D;;;GAGG;AACH,MAAM,UAAU,YAAY,CAC1B,KAA8B,EAC9B,OAAgB;IAEhB,IAAI,CAAC,KAAK,EAAE,aAAa;QAAE,OAAO,SAAS,CAAC;IAC5C,OAAO,CAAC,KAAgB,EAAE,EAAE;QAC1B,KAAK,CAAC,aAAa,EAAE,CAAC;YACpB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,aAAa,EAAE,CAAC;YAChB,MAAM,EAAE;gBACN,WAAW,EAAE,KAAK,CAAC,WAAW;gBAC9B,YAAY,EAAE,KAAK,CAAC,YAAY;gBAChC,YAAY,EAAE,KAAK,CAAC,iBAAiB;aACtC;SACF,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,cAAwC,EACxC,KAA8B,EAC9B,GAAiB;IAEjB,MAAM,EAAC,OAAO,EAAE,SAAS,EAAC,GAAG,GAAG,CAAC;IAEjC,2EAA2E;IAC3E,2EAA2E;IAC3E,4EAA4E;IAC5E,MAAM,cAAc,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAEtC,IAAI,KAAK,EAAE,UAAU,EAAE,CAAC;QACtB,KAAK,CAAC,UAAU,CAAC;YACf,KAAK,EAAE,uBAAuB;YAC9B,aAAa,EAAE,OAAO,CAAC,EAAE;YACzB,OAAO,EAAE;gBACP,UAAU,EAAE,OAAO,CAAC,EAAE;gBACtB,UAAU,EAAE,SAAS;gBACrB,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,QAAQ,EAAE,OAAO,CAAC,YAAY;aAC/B;SACF,CAAC,CAAC;IACL,CAAC;IAED,IAAI,KAAK,EAAE,gBAAgB,EAAE,CAAC;QAC5B,KAAK,CAAC,gBAAgB,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,EAAE,WAAW,EAAE;YAClD,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,QAAQ,EAAE,OAAO,CAAC,YAAY;SAC/B,CAAC,CAAC;IACL,CAAC;AACH,CAAC"}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ /**
7
+ * Session Resolver.
8
+ *
9
+ * Shared session resolution logic for all chat routes. Extracts bundle
10
+ * resolution, session lookup/resume/create into a single function so
11
+ * chat-stream, ai-stream, and chat routes share the same flow.
12
+ */
13
+ import type { AgentBundle, CustomToolExecutor, StoreBackend } from '@amodalai/types';
14
+ import type { McpManager, FieldScrubber } from '@amodalai/core';
15
+ import type { StandaloneSessionManager } from '../session/manager.js';
16
+ import type { Session } from '../session/types.js';
17
+ import type { ToolContext } from '../tools/types.js';
18
+ import type { SessionType } from '../session/session-builder.js';
19
+ import type { AuthContext } from '../middleware/auth.js';
20
+ import type { Logger } from '../logger.js';
21
+ /** How the route resolves an AgentBundle for a given request. */
22
+ export interface BundleResolver {
23
+ /** Static bundle for local dev (used when no deploy_id is provided). */
24
+ staticBundle?: AgentBundle;
25
+ /** Dynamic bundle provider for hosted mode (keyed by deploy_id + auth token). */
26
+ bundleProvider?: (deployId: string, token?: string) => Promise<AgentBundle | null>;
27
+ }
28
+ /** Shared resources injected once at server startup. */
29
+ export interface SharedResources {
30
+ storeBackend: StoreBackend | null;
31
+ mcpManager: McpManager | null;
32
+ logger: Logger;
33
+ toolExecutor?: CustomToolExecutor;
34
+ fieldScrubber?: FieldScrubber;
35
+ }
36
+ /** Result of session resolution — includes the tool context factory for wiring into runMessage. */
37
+ export interface ResolvedSession {
38
+ session: Session;
39
+ toolContextFactory: (callId: string) => ToolContext;
40
+ }
41
+ /** Options for resolving a session. */
42
+ export interface ResolveSessionOptions {
43
+ sessionManager: StandaloneSessionManager;
44
+ bundleResolver: BundleResolver;
45
+ shared: SharedResources;
46
+ role?: string;
47
+ sessionType?: SessionType;
48
+ deployId?: string;
49
+ auth?: AuthContext;
50
+ }
51
+ /**
52
+ * Resolve an AgentBundle from the bundle resolver.
53
+ *
54
+ * Prefers the dynamic bundleProvider when a deploy_id is available (hosted
55
+ * mode). Falls back to the static bundle (local dev).
56
+ */
57
+ export declare function resolveBundle(resolver: BundleResolver, deployId?: string, token?: string): Promise<AgentBundle | null>;
58
+ /**
59
+ * Resolve (lookup, resume, or create) a session for a chat request.
60
+ *
61
+ * Flow:
62
+ * 1. If session_id: try in-memory get → try resume from store → fall through
63
+ * 2. Create new session from resolved bundle
64
+ * 3. Throws SessionError if no bundle is available
65
+ *
66
+ * Bundle is resolved once and reused across resume and create paths to
67
+ * avoid redundant bundleProvider calls in hosted mode.
68
+ *
69
+ * For in-memory sessions, the cached `toolContextFactory` from session
70
+ * creation is reused — no redundant buildSessionComponents call.
71
+ */
72
+ export declare function resolveSession(sessionId: string | undefined, opts: ResolveSessionOptions): Promise<ResolvedSession>;
@@ -0,0 +1,123 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ import { buildSessionComponents } from '../session/session-builder.js';
7
+ import { SessionError } from '../errors.js';
8
+ import { LOCAL_APP_ID } from '../constants.js';
9
+ // ---------------------------------------------------------------------------
10
+ // Constants
11
+ // ---------------------------------------------------------------------------
12
+ const DEFAULT_TENANT_ID = LOCAL_APP_ID;
13
+ const DEFAULT_USER_ID = 'anonymous';
14
+ // ---------------------------------------------------------------------------
15
+ // Bundle resolution
16
+ // ---------------------------------------------------------------------------
17
+ /**
18
+ * Resolve an AgentBundle from the bundle resolver.
19
+ *
20
+ * Prefers the dynamic bundleProvider when a deploy_id is available (hosted
21
+ * mode). Falls back to the static bundle (local dev).
22
+ */
23
+ export async function resolveBundle(resolver, deployId, token) {
24
+ if (deployId && resolver.bundleProvider) {
25
+ return resolver.bundleProvider(deployId, token);
26
+ }
27
+ return resolver.staticBundle ?? null;
28
+ }
29
+ // ---------------------------------------------------------------------------
30
+ // Internal: build components + wire factory
31
+ // ---------------------------------------------------------------------------
32
+ function buildComponents(bundle, shared, opts) {
33
+ return buildSessionComponents({
34
+ bundle,
35
+ storeBackend: shared.storeBackend,
36
+ mcpManager: shared.mcpManager,
37
+ logger: shared.logger,
38
+ toolExecutor: shared.toolExecutor,
39
+ fieldScrubber: shared.fieldScrubber,
40
+ sessionType: opts.sessionType,
41
+ userRoles: opts.userRoles,
42
+ sessionId: opts.sessionId,
43
+ tenantId: opts.tenantId,
44
+ });
45
+ }
46
+ // ---------------------------------------------------------------------------
47
+ // Session resolution
48
+ // ---------------------------------------------------------------------------
49
+ /**
50
+ * Resolve (lookup, resume, or create) a session for a chat request.
51
+ *
52
+ * Flow:
53
+ * 1. If session_id: try in-memory get → try resume from store → fall through
54
+ * 2. Create new session from resolved bundle
55
+ * 3. Throws SessionError if no bundle is available
56
+ *
57
+ * Bundle is resolved once and reused across resume and create paths to
58
+ * avoid redundant bundleProvider calls in hosted mode.
59
+ *
60
+ * For in-memory sessions, the cached `toolContextFactory` from session
61
+ * creation is reused — no redundant buildSessionComponents call.
62
+ */
63
+ export async function resolveSession(sessionId, opts) {
64
+ const { sessionManager, bundleResolver, shared, auth } = opts;
65
+ const tenantId = auth?.orgId ?? DEFAULT_TENANT_ID;
66
+ const userId = auth?.actor ?? DEFAULT_USER_ID;
67
+ const userRoles = opts.role ? [opts.role] : [];
68
+ // 1. In-memory lookup (existing live session)
69
+ if (sessionId) {
70
+ const existing = sessionManager.get(sessionId);
71
+ if (existing && existing.toolContextFactory) {
72
+ return { session: existing, toolContextFactory: existing.toolContextFactory };
73
+ }
74
+ }
75
+ // Resolve bundle once — shared between resume and create paths
76
+ const bundle = await resolveBundle(bundleResolver, opts.deployId, auth?.token);
77
+ // 2. Resume from store (with dedup handled by StandaloneSessionManager)
78
+ if (sessionId && bundle) {
79
+ const components = buildComponents(bundle, shared, {
80
+ sessionType: opts.sessionType,
81
+ userRoles,
82
+ sessionId,
83
+ tenantId,
84
+ });
85
+ const resumed = await sessionManager.resume(sessionId, {
86
+ tenantId,
87
+ userId,
88
+ provider: components.provider,
89
+ toolRegistry: components.toolRegistry,
90
+ permissionChecker: components.permissionChecker,
91
+ systemPrompt: components.systemPrompt,
92
+ userRoles: components.userRoles,
93
+ toolContextFactory: components.toolContextFactory,
94
+ });
95
+ if (resumed) {
96
+ return { session: resumed, toolContextFactory: components.toolContextFactory };
97
+ }
98
+ }
99
+ // 3. Create new session
100
+ if (!bundle) {
101
+ throw new SessionError('No bundle available — provide a deploy_id or configure a static bundle', {
102
+ sessionId: sessionId ?? 'new',
103
+ context: { operation: 'resolveSession', deployId: opts.deployId },
104
+ });
105
+ }
106
+ const components = buildComponents(bundle, shared, {
107
+ sessionType: opts.sessionType,
108
+ userRoles,
109
+ tenantId,
110
+ });
111
+ const session = sessionManager.create({
112
+ tenantId,
113
+ userId,
114
+ provider: components.provider,
115
+ toolRegistry: components.toolRegistry,
116
+ permissionChecker: components.permissionChecker,
117
+ systemPrompt: components.systemPrompt,
118
+ userRoles: components.userRoles,
119
+ toolContextFactory: components.toolContextFactory,
120
+ });
121
+ return { session, toolContextFactory: components.toolContextFactory };
122
+ }
123
+ //# sourceMappingURL=session-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-resolver.js","sourceRoot":"","sources":["../../../src/routes/session-resolver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ export {};