@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
@@ -0,0 +1,38 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ /**
7
+ * Provider failover chain.
8
+ *
9
+ * Tries each provider in sequence. On failure, logs the error and moves
10
+ * to the next provider. No retries or backoff within a single provider —
11
+ * the chain itself IS the retry strategy. If you want retries on the
12
+ * primary, put the same provider config twice in the chain.
13
+ *
14
+ * All providers exhausted → throws ProviderError with context about
15
+ * every attempt.
16
+ */
17
+ import type { Logger } from '@amodalai/core';
18
+ import type { LLMProvider, ProviderConfig } from './types.js';
19
+ export interface FailoverChainConfig {
20
+ /** Primary provider (always first in the chain) */
21
+ primary: ProviderConfig;
22
+ /** Fallback providers, tried in order after primary fails */
23
+ fallbacks?: ProviderConfig[];
24
+ /** Logger for structured events */
25
+ logger: Logger;
26
+ /** Session ID for log context */
27
+ sessionId?: string;
28
+ }
29
+ /**
30
+ * Create an LLMProvider that tries a chain of providers in order.
31
+ *
32
+ * For generateText: tries each provider sequentially until one succeeds.
33
+ * For streamText: wraps the fullStream so that if a provider's stream
34
+ * fails before yielding any events, the next provider is tried. Once
35
+ * events have been yielded, mid-stream errors propagate (can't restart
36
+ * a partial stream).
37
+ */
38
+ export declare function createFailoverProvider(config: FailoverChainConfig): LLMProvider;
@@ -0,0 +1,147 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ import { createProvider } from './create-provider.js';
7
+ import { ProviderError } from '../errors.js';
8
+ // ---------------------------------------------------------------------------
9
+ // createFailoverProvider
10
+ // ---------------------------------------------------------------------------
11
+ /**
12
+ * Create an LLMProvider that tries a chain of providers in order.
13
+ *
14
+ * For generateText: tries each provider sequentially until one succeeds.
15
+ * For streamText: wraps the fullStream so that if a provider's stream
16
+ * fails before yielding any events, the next provider is tried. Once
17
+ * events have been yielded, mid-stream errors propagate (can't restart
18
+ * a partial stream).
19
+ */
20
+ export function createFailoverProvider(config) {
21
+ const chain = [config.primary, ...(config.fallbacks ?? [])];
22
+ const providers = chain.map((c) => createProvider(c));
23
+ const primary = providers[0];
24
+ function logFailure(idx, errorMsg, failedAttempts) {
25
+ failedAttempts.push({
26
+ provider: chain[idx].provider,
27
+ model: chain[idx].model,
28
+ error: errorMsg,
29
+ });
30
+ config.logger.error('provider_call_failed', {
31
+ session: config.sessionId,
32
+ provider: `${chain[idx].provider}/${chain[idx].model}`,
33
+ error: errorMsg,
34
+ willRetry: idx < providers.length - 1,
35
+ });
36
+ }
37
+ function logSuccess(idx, failedAttempts) {
38
+ if (idx > 0) {
39
+ config.logger.warn('provider_failover_used', {
40
+ session: config.sessionId,
41
+ failed: failedAttempts.map((a) => `${a.provider}/${a.model}`),
42
+ succeeded: `${chain[idx].provider}/${chain[idx].model}`,
43
+ });
44
+ }
45
+ }
46
+ function throwAllFailed(failedAttempts, cause) {
47
+ throw new ProviderError('All providers failed', {
48
+ provider: 'failover',
49
+ context: { attempts: failedAttempts },
50
+ cause,
51
+ });
52
+ }
53
+ return {
54
+ model: primary.model,
55
+ provider: primary.provider,
56
+ languageModel: primary.languageModel,
57
+ streamText(opts) {
58
+ // Deferred promises for usage and text — resolved when stream completes.
59
+ let resolveUsage;
60
+ let rejectUsage;
61
+ const usagePromise = new Promise((res, rej) => {
62
+ resolveUsage = res;
63
+ rejectUsage = rej;
64
+ });
65
+ let resolveText;
66
+ let rejectText;
67
+ const textPromise = new Promise((res, rej) => {
68
+ resolveText = res;
69
+ rejectText = rej;
70
+ });
71
+ const failedAttempts = [];
72
+ const fullStream = (async function* () {
73
+ let lastUsage;
74
+ const textChunks = [];
75
+ for (let i = 0; i < providers.length; i++) {
76
+ let yieldedAny = false;
77
+ try {
78
+ const result = providers[i].streamText(opts);
79
+ for await (const event of result.fullStream) {
80
+ yieldedAny = true;
81
+ if (event.type === 'finish')
82
+ lastUsage = event.usage;
83
+ if (event.type === 'text-delta')
84
+ textChunks.push(event.textDelta);
85
+ yield event;
86
+ }
87
+ // Stream completed successfully
88
+ logSuccess(i, failedAttempts);
89
+ resolveUsage(lastUsage ?? { inputTokens: 0, outputTokens: 0, totalTokens: 0 });
90
+ resolveText(textChunks.join(''));
91
+ return;
92
+ }
93
+ catch (err) {
94
+ const errorMsg = err instanceof Error ? err.message : String(err);
95
+ // If we already yielded events, we can't retry — log and propagate
96
+ if (yieldedAny) {
97
+ logFailure(i, errorMsg, failedAttempts);
98
+ rejectUsage(err);
99
+ rejectText(err);
100
+ throw err;
101
+ }
102
+ logFailure(i, errorMsg, failedAttempts);
103
+ if (i === providers.length - 1) {
104
+ rejectUsage(err);
105
+ rejectText(err);
106
+ throwAllFailed(failedAttempts, err);
107
+ }
108
+ // Try next provider
109
+ }
110
+ }
111
+ })();
112
+ return {
113
+ fullStream,
114
+ // textStream derived from fullStream — consumers should use one or the other
115
+ textStream: (async function* () {
116
+ for await (const event of fullStream) {
117
+ if (event.type === 'text-delta') {
118
+ yield event.textDelta;
119
+ }
120
+ }
121
+ })(),
122
+ usage: usagePromise,
123
+ text: textPromise,
124
+ };
125
+ },
126
+ async generateText(opts) {
127
+ const failedAttempts = [];
128
+ for (let i = 0; i < providers.length; i++) {
129
+ try {
130
+ const result = await providers[i].generateText(opts);
131
+ logSuccess(i, failedAttempts);
132
+ return result;
133
+ }
134
+ catch (err) {
135
+ const errorMsg = err instanceof Error ? err.message : String(err);
136
+ logFailure(i, errorMsg, failedAttempts);
137
+ if (i === providers.length - 1) {
138
+ throwAllFailed(failedAttempts, err);
139
+ }
140
+ }
141
+ }
142
+ // Unreachable — TypeScript needs this
143
+ throw new ProviderError('No providers configured', { provider: 'failover' });
144
+ },
145
+ };
146
+ }
147
+ //# sourceMappingURL=failover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"failover.js","sourceRoot":"","sources":["../../../src/providers/failover.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 {};
@@ -0,0 +1,169 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ /**
7
+ * Provider Failover Tests
8
+ *
9
+ * Integration tests against real providers (skipped when API keys are
10
+ * not available). No mocks — calls the real AI SDK through the real
11
+ * createProvider → createFailoverProvider chain.
12
+ *
13
+ * Scenarios:
14
+ * 1. Primary with invalid key + fallback with valid key → response from fallback
15
+ * 2. Valid primary → uses primary, no fallback
16
+ * 3. All providers fail → throws ProviderError with context about all attempts
17
+ */
18
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
19
+ import { createFailoverProvider } from './failover.js';
20
+ import { ProviderError } from '../errors.js';
21
+ import { testProviders, hasAnyProvider } from '../__tests__/test-providers.js';
22
+ // ---------------------------------------------------------------------------
23
+ // Helpers
24
+ // ---------------------------------------------------------------------------
25
+ function makeMockLogger() {
26
+ return {
27
+ trace: vi.fn(),
28
+ debug: vi.fn(),
29
+ info: vi.fn(),
30
+ warn: vi.fn(),
31
+ error: vi.fn(),
32
+ fatal: vi.fn(),
33
+ child: vi.fn().mockReturnThis(),
34
+ };
35
+ }
36
+ // ---------------------------------------------------------------------------
37
+ // Unit tests (no API calls)
38
+ // ---------------------------------------------------------------------------
39
+ describe('createFailoverProvider (unit)', () => {
40
+ let logger;
41
+ beforeEach(() => {
42
+ logger = makeMockLogger();
43
+ });
44
+ it('exposes primary model and provider on the returned object', () => {
45
+ const provider = createFailoverProvider({
46
+ primary: { provider: 'anthropic', model: 'claude-sonnet-4-20250514', apiKey: 'fake' },
47
+ fallbacks: [{ provider: 'openai', model: 'gpt-4o', apiKey: 'fake' }],
48
+ logger,
49
+ });
50
+ expect(provider.model).toBe('claude-sonnet-4-20250514');
51
+ expect(provider.provider).toBe('anthropic');
52
+ expect(provider.languageModel).toBeDefined();
53
+ expect(typeof provider.streamText).toBe('function');
54
+ expect(typeof provider.generateText).toBe('function');
55
+ });
56
+ it('works with a single provider (no fallbacks)', () => {
57
+ const provider = createFailoverProvider({
58
+ primary: { provider: 'anthropic', model: 'claude-sonnet-4-20250514', apiKey: 'fake' },
59
+ logger,
60
+ });
61
+ expect(provider.model).toBe('claude-sonnet-4-20250514');
62
+ });
63
+ });
64
+ // ---------------------------------------------------------------------------
65
+ // Integration tests (real API calls — skipped without keys)
66
+ // ---------------------------------------------------------------------------
67
+ describe.skipIf(!hasAnyProvider)('createFailoverProvider (integration)', () => {
68
+ let logger;
69
+ beforeEach(() => {
70
+ logger = makeMockLogger();
71
+ });
72
+ // ── 1. Primary fails (invalid key) + fallback succeeds ────────────────
73
+ it('uses fallback when primary has invalid API key', async () => {
74
+ const fallback = testProviders.cheapest();
75
+ const invalid = testProviders.invalid(fallback.provider);
76
+ const provider = createFailoverProvider({
77
+ primary: invalid,
78
+ fallbacks: [fallback],
79
+ logger,
80
+ sessionId: 'test-failover',
81
+ });
82
+ const result = await provider.generateText({
83
+ messages: [{ role: 'user', content: [{ type: 'text', text: 'Reply with exactly: pong' }] }],
84
+ maxOutputTokens: 10,
85
+ });
86
+ expect(result.text.toLowerCase()).toContain('pong');
87
+ expect(result.usage.inputTokens).toBeGreaterThan(0);
88
+ expect(result.usage.outputTokens).toBeGreaterThan(0);
89
+ expect(logger.error).toHaveBeenCalledWith('provider_call_failed', expect.objectContaining({ session: 'test-failover', willRetry: true }));
90
+ expect(logger.warn).toHaveBeenCalledWith('provider_failover_used', expect.objectContaining({
91
+ succeeded: `${fallback.provider}/${fallback.model}`,
92
+ }));
93
+ }, 30000);
94
+ // ── 2. Valid primary → uses primary, no fallback ──────────────────────
95
+ it('uses primary when it succeeds — fallback not touched', async () => {
96
+ const primary = testProviders.cheapest();
97
+ const provider = createFailoverProvider({
98
+ primary,
99
+ // Fallback has invalid key — would fail if reached
100
+ fallbacks: [testProviders.invalid(primary.provider)],
101
+ logger,
102
+ });
103
+ const result = await provider.generateText({
104
+ messages: [{ role: 'user', content: [{ type: 'text', text: 'Reply with exactly: ping' }] }],
105
+ maxOutputTokens: 10,
106
+ });
107
+ expect(result.text.toLowerCase()).toContain('ping');
108
+ expect(logger.error).not.toHaveBeenCalled();
109
+ expect(logger.warn).not.toHaveBeenCalled();
110
+ }, 30000);
111
+ // ── 3. All providers fail → ProviderError with all attempts ───────────
112
+ it('throws ProviderError with context about all failed attempts', async () => {
113
+ const provider = createFailoverProvider({
114
+ primary: testProviders.invalid('anthropic'),
115
+ fallbacks: [testProviders.invalid('openai')],
116
+ logger,
117
+ sessionId: 'test-all-fail',
118
+ });
119
+ try {
120
+ await provider.generateText({
121
+ messages: [{ role: 'user', content: [{ type: 'text', text: 'hello' }] }],
122
+ maxOutputTokens: 10,
123
+ });
124
+ expect.unreachable('should have thrown');
125
+ }
126
+ catch (err) {
127
+ expect(err).toBeInstanceOf(ProviderError);
128
+ const pe = err;
129
+ expect(pe.message).toBe('All providers failed');
130
+ expect(pe.provider).toBe('failover');
131
+ const attempts = pe.context['attempts'];
132
+ expect(attempts).toHaveLength(2);
133
+ expect(attempts[0].provider).toBe('anthropic');
134
+ expect(attempts[1].provider).toBe('openai');
135
+ }
136
+ expect(logger.error).toHaveBeenCalledTimes(2);
137
+ expect(logger.error).toHaveBeenCalledWith('provider_call_failed', expect.objectContaining({ session: 'test-all-fail', willRetry: true }));
138
+ expect(logger.error).toHaveBeenCalledWith('provider_call_failed', expect.objectContaining({ willRetry: false }));
139
+ }, 30000);
140
+ // ── 4. Streaming failover ─────────────────────────────────────────────
141
+ it('streaming: uses fallback when primary stream fails', async () => {
142
+ const fallback = testProviders.cheapest();
143
+ const invalid = testProviders.invalid(fallback.provider);
144
+ const provider = createFailoverProvider({
145
+ primary: invalid,
146
+ fallbacks: [fallback],
147
+ logger,
148
+ });
149
+ const result = provider.streamText({
150
+ messages: [{ role: 'user', content: [{ type: 'text', text: 'Reply with exactly: stream-ok' }] }],
151
+ maxOutputTokens: 10,
152
+ });
153
+ const events = [];
154
+ for await (const event of result.fullStream) {
155
+ events.push(event);
156
+ }
157
+ const textDeltas = events.filter((e) => e.type === 'text-delta');
158
+ expect(textDeltas.length).toBeGreaterThan(0);
159
+ const text = await result.text;
160
+ expect(text.length).toBeGreaterThan(0);
161
+ const usage = await result.usage;
162
+ expect(usage.inputTokens).toBeGreaterThan(0);
163
+ expect(logger.error).toHaveBeenCalledWith('provider_call_failed', expect.objectContaining({ willRetry: true }));
164
+ expect(logger.warn).toHaveBeenCalledWith('provider_failover_used', expect.objectContaining({
165
+ succeeded: `${fallback.provider}/${fallback.model}`,
166
+ }));
167
+ }, 30000);
168
+ });
169
+ //# sourceMappingURL=failover.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"failover.test.js","sourceRoot":"","sources":["../../../src/providers/failover.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,110 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ /**
7
+ * Provider abstraction wrapping the Vercel AI SDK.
8
+ *
9
+ * This is the boundary between Amodal code and the AI SDK. The rest of
10
+ * the runtime talks to LLMProvider, never to the SDK directly. This lets
11
+ * us swap SDK versions, add new providers, or intercept calls (logging,
12
+ * retries, cost tracking) in one place.
13
+ */
14
+ import type { LanguageModel, ModelMessage, Tool, ToolChoice, ToolSet } from 'ai';
15
+ export interface StreamTextOptions {
16
+ messages: ModelMessage[];
17
+ system?: string;
18
+ tools?: Record<string, Tool>;
19
+ toolChoice?: ToolChoice<ToolSet>;
20
+ maxOutputTokens?: number;
21
+ temperature?: number;
22
+ abortSignal?: AbortSignal;
23
+ }
24
+ export interface GenerateTextOptions {
25
+ messages: ModelMessage[];
26
+ system?: string;
27
+ tools?: Record<string, Tool>;
28
+ toolChoice?: ToolChoice<ToolSet>;
29
+ maxOutputTokens?: number;
30
+ temperature?: number;
31
+ abortSignal?: AbortSignal;
32
+ }
33
+ export interface TokenUsage {
34
+ inputTokens: number;
35
+ outputTokens: number;
36
+ cachedInputTokens?: number;
37
+ cacheCreationInputTokens?: number;
38
+ totalTokens: number;
39
+ }
40
+ export interface StreamTextResult {
41
+ /** The full text stream — yields string chunks */
42
+ textStream: AsyncIterable<string>;
43
+ /** The full event stream — yields structured events including tool calls */
44
+ fullStream: AsyncIterable<StreamEvent>;
45
+ /** Resolves when the stream is complete with final usage */
46
+ usage: PromiseLike<TokenUsage>;
47
+ /** Resolves with the complete response text */
48
+ text: PromiseLike<string>;
49
+ }
50
+ export type StreamEvent = {
51
+ type: 'text-delta';
52
+ textDelta: string;
53
+ } | {
54
+ type: 'tool-call';
55
+ toolCallId: string;
56
+ toolName: string;
57
+ args: Record<string, unknown>;
58
+ } | {
59
+ type: 'tool-result';
60
+ toolCallId: string;
61
+ toolName: string;
62
+ result: unknown;
63
+ } | {
64
+ type: 'finish';
65
+ usage: TokenUsage;
66
+ } | {
67
+ type: 'error';
68
+ error: unknown;
69
+ };
70
+ export interface GenerateTextResult {
71
+ text: string;
72
+ toolCalls: Array<{
73
+ toolCallId: string;
74
+ toolName: string;
75
+ args: Record<string, unknown>;
76
+ }>;
77
+ usage: TokenUsage;
78
+ finishReason: 'stop' | 'length' | 'content-filter' | 'tool-calls' | 'error' | 'other';
79
+ }
80
+ /**
81
+ * Unified LLM provider interface.
82
+ *
83
+ * Wraps the Vercel AI SDK so the rest of the runtime never imports `ai`
84
+ * directly. Implementations exist for Anthropic, OpenAI, Google, and
85
+ * any OpenAI-compatible provider (DeepSeek, Groq, Mistral, etc.).
86
+ */
87
+ export interface LLMProvider {
88
+ /** Stream a text/tool response from the LLM */
89
+ streamText(opts: StreamTextOptions): StreamTextResult;
90
+ /** Generate a complete text response (non-streaming) */
91
+ generateText(opts: GenerateTextOptions): Promise<GenerateTextResult>;
92
+ /** The model identifier (e.g., 'claude-sonnet-4-20250514') */
93
+ readonly model: string;
94
+ /** The provider name (e.g., 'anthropic', 'openai', 'google') */
95
+ readonly provider: string;
96
+ /** The underlying AI SDK LanguageModel instance (for advanced use) */
97
+ readonly languageModel: LanguageModel;
98
+ }
99
+ export interface ProviderConfig {
100
+ /** Provider name: 'anthropic', 'openai', 'google', 'deepseek', etc. */
101
+ provider: string;
102
+ /** Model name: 'claude-sonnet-4-20250514', 'gpt-4o', etc. */
103
+ model: string;
104
+ /** API key (resolved from env or credentials) */
105
+ apiKey?: string;
106
+ /** Custom base URL (for self-hosted or proxy endpoints) */
107
+ baseUrl?: string;
108
+ /** AWS region (for Bedrock) */
109
+ region?: string;
110
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/providers/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
@@ -1,14 +1,14 @@
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
6
  /**
7
7
  * Vercel AI SDK UI Message Stream Protocol adapter.
8
8
  *
9
9
  * Accepts requests in the Vercel AI SDK format, feeds the user message into
10
- * the existing `streamMessage()` async generator, and translates every
11
- * `SSEEvent` into the UI Message Stream Protocol that `@ai-sdk/react`'s
10
+ * the standalone session manager's `runMessage()` generator, and translates
11
+ * every `SSEEvent` into the UI Message Stream Protocol that `@ai-sdk/react`'s
12
12
  * `useChat` hook expects.
13
13
  *
14
14
  * Protocol spec: events are newline-delimited JSON objects prefixed with
@@ -18,9 +18,10 @@
18
18
  import { Router } from 'express';
19
19
  import { z } from 'zod';
20
20
  import type { AuthContext } from '../middleware/auth.js';
21
- import type { SessionManager } from '../session/session-manager.js';
22
- import { type StreamHooks } from '../session/session-runner.js';
21
+ import type { StandaloneSessionManager } from '../session/manager.js';
22
+ import type { StreamHooks } from '../session/stream-hooks.js';
23
23
  import { type SSEEvent } from '../types.js';
24
+ import type { BundleResolver, SharedResources } from './session-resolver.js';
24
25
  export declare const AIStreamRequestSchema: z.ZodObject<{
25
26
  messages: z.ZodArray<z.ZodObject<{
26
27
  role: z.ZodEnum<["user", "assistant", "system"]>;
@@ -36,14 +37,14 @@ export declare const AIStreamRequestSchema: z.ZodObject<{
36
37
  }>, "many">>;
37
38
  content: z.ZodOptional<z.ZodString>;
38
39
  }, "strip", z.ZodTypeAny, {
39
- role: "user" | "assistant" | "system";
40
+ role: "system" | "user" | "assistant";
40
41
  content?: string | undefined;
41
42
  parts?: {
42
43
  type: string;
43
44
  text?: string | undefined;
44
45
  }[] | undefined;
45
46
  }, {
46
- role: "user" | "assistant" | "system";
47
+ role: "system" | "user" | "assistant";
47
48
  content?: string | undefined;
48
49
  parts?: {
49
50
  type: string;
@@ -55,7 +56,7 @@ export declare const AIStreamRequestSchema: z.ZodObject<{
55
56
  deploy_id: z.ZodOptional<z.ZodString>;
56
57
  }, "strip", z.ZodTypeAny, {
57
58
  messages: {
58
- role: "user" | "assistant" | "system";
59
+ role: "system" | "user" | "assistant";
59
60
  content?: string | undefined;
60
61
  parts?: {
61
62
  type: string;
@@ -67,7 +68,7 @@ export declare const AIStreamRequestSchema: z.ZodObject<{
67
68
  deploy_id?: string | undefined;
68
69
  }, {
69
70
  messages: {
70
- role: "user" | "assistant" | "system";
71
+ role: "system" | "user" | "assistant";
71
72
  content?: string | undefined;
72
73
  parts?: {
73
74
  type: string;
@@ -152,7 +153,9 @@ interface AdapterState {
152
153
  export declare function translateEvent(event: SSEEvent, state: AdapterState): UIStreamEvent[];
153
154
  export declare function extractUserMessage(messages: AIStreamRequest['messages']): string;
154
155
  export interface AIStreamRouterOptions {
155
- sessionManager: SessionManager;
156
+ sessionManager: StandaloneSessionManager;
157
+ bundleResolver: BundleResolver;
158
+ shared: SharedResources;
156
159
  /** Factory that builds per-request stream hooks from the auth context */
157
160
  createStreamHooks?: (auth?: AuthContext) => StreamHooks;
158
161
  }