@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,145 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ /**
7
+ * Tests for PGLiteSessionStore.
8
+ *
9
+ * Uses a real in-memory PGLite instance — no mocks.
10
+ */
11
+ import { describe, it, expect, beforeAll, afterAll } from 'vitest';
12
+ import { PGLiteSessionStore } from './store.js';
13
+ import { createLogger } from '../logger.js';
14
+ const logger = createLogger({ component: 'test:session-store' });
15
+ function makeSession(overrides = {}) {
16
+ return {
17
+ version: 1,
18
+ id: `sess-${Math.random().toString(36).slice(2, 10)}`,
19
+ tenantId: 'tenant-1',
20
+ userId: 'user-1',
21
+ messages: [{ role: 'user', content: 'Hello' }],
22
+ tokenUsage: { inputTokens: 100, outputTokens: 50, totalTokens: 150 },
23
+ metadata: {},
24
+ createdAt: new Date(),
25
+ updatedAt: new Date(),
26
+ ...overrides,
27
+ };
28
+ }
29
+ describe('PGLiteSessionStore', () => {
30
+ let store;
31
+ beforeAll(async () => {
32
+ store = new PGLiteSessionStore({ logger });
33
+ await store.initialize();
34
+ });
35
+ afterAll(async () => {
36
+ await store.close();
37
+ });
38
+ it('save and load a session', async () => {
39
+ const session = makeSession();
40
+ await store.save(session);
41
+ const loaded = await store.load(session.id);
42
+ expect(loaded).not.toBeNull();
43
+ expect(loaded.id).toBe(session.id);
44
+ expect(loaded.tenantId).toBe(session.tenantId);
45
+ expect(loaded.userId).toBe(session.userId);
46
+ expect(loaded.version).toBe(1);
47
+ expect(loaded.messages).toEqual(session.messages);
48
+ expect(loaded.tokenUsage).toEqual(session.tokenUsage);
49
+ });
50
+ it('load returns null for missing session', async () => {
51
+ const loaded = await store.load('nonexistent');
52
+ expect(loaded).toBeNull();
53
+ });
54
+ it('save updates existing session (upsert)', async () => {
55
+ const session = makeSession();
56
+ await store.save(session);
57
+ // Update messages and re-save
58
+ session.messages = [
59
+ { role: 'user', content: 'Hello' },
60
+ { role: 'assistant', content: 'Hi there' },
61
+ ];
62
+ session.tokenUsage = { inputTokens: 200, outputTokens: 100, totalTokens: 300 };
63
+ session.updatedAt = new Date();
64
+ await store.save(session);
65
+ const loaded = await store.load(session.id);
66
+ expect(loaded.messages).toHaveLength(2);
67
+ expect(loaded.tokenUsage.totalTokens).toBe(300);
68
+ });
69
+ it('list sessions filtered by tenant, newest first', async () => {
70
+ const tenantId = `tenant-list-${Date.now()}`;
71
+ const older = makeSession({
72
+ tenantId,
73
+ updatedAt: new Date('2026-01-01'),
74
+ });
75
+ const newer = makeSession({
76
+ tenantId,
77
+ updatedAt: new Date('2026-03-01'),
78
+ });
79
+ await store.save(older);
80
+ await store.save(newer);
81
+ const sessions = await store.list(tenantId);
82
+ expect(sessions.length).toBeGreaterThanOrEqual(2);
83
+ // Newest first
84
+ const ids = sessions.map((s) => s.id);
85
+ expect(ids.indexOf(newer.id)).toBeLessThan(ids.indexOf(older.id));
86
+ });
87
+ it('list does not return sessions from other tenants', async () => {
88
+ const tenantA = `tenant-a-${Date.now()}`;
89
+ const tenantB = `tenant-b-${Date.now()}`;
90
+ await store.save(makeSession({ tenantId: tenantA }));
91
+ await store.save(makeSession({ tenantId: tenantB }));
92
+ const sessionsA = await store.list(tenantA);
93
+ expect(sessionsA.every((s) => s.tenantId === tenantA)).toBe(true);
94
+ });
95
+ it('delete removes a session', async () => {
96
+ const session = makeSession();
97
+ await store.save(session);
98
+ const deleted = await store.delete(session.id);
99
+ expect(deleted).toBe(true);
100
+ const loaded = await store.load(session.id);
101
+ expect(loaded).toBeNull();
102
+ });
103
+ it('delete returns false for missing session', async () => {
104
+ const deleted = await store.delete('nonexistent');
105
+ expect(deleted).toBe(false);
106
+ });
107
+ it('cleanup removes sessions older than cutoff', async () => {
108
+ const tenantId = `tenant-cleanup-${Date.now()}`;
109
+ const old = makeSession({
110
+ tenantId,
111
+ updatedAt: new Date('2020-01-01'),
112
+ });
113
+ const recent = makeSession({
114
+ tenantId,
115
+ updatedAt: new Date(),
116
+ });
117
+ await store.save(old);
118
+ await store.save(recent);
119
+ const cleaned = await store.cleanup(new Date('2025-01-01'));
120
+ expect(cleaned).toBeGreaterThanOrEqual(1);
121
+ // Old session gone
122
+ const loaded = await store.load(old.id);
123
+ expect(loaded).toBeNull();
124
+ // Recent session still there
125
+ const loadedRecent = await store.load(recent.id);
126
+ expect(loadedRecent).not.toBeNull();
127
+ });
128
+ it('metadata is preserved through save/load', async () => {
129
+ const session = makeSession({
130
+ metadata: {
131
+ title: 'Test Session',
132
+ model: 'claude-sonnet-4-20250514',
133
+ provider: 'anthropic',
134
+ appId: 'my-app',
135
+ },
136
+ });
137
+ await store.save(session);
138
+ const loaded = await store.load(session.id);
139
+ expect(loaded.metadata.title).toBe('Test Session');
140
+ expect(loaded.metadata.model).toBe('claude-sonnet-4-20250514');
141
+ expect(loaded.metadata.provider).toBe('anthropic');
142
+ expect(loaded.metadata.appId).toBe('my-app');
143
+ });
144
+ });
145
+ //# sourceMappingURL=store.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.test.js","sourceRoot":"","sources":["../../../src/session/store.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ /**
7
+ * Stream hooks type.
8
+ *
9
+ * These callbacks are invoked by route handlers after runMessage() drains.
10
+ * Hosted-mode consumers use them for audit logging, usage reporting, and
11
+ * external persistence.
12
+ */
13
+ export interface TokenCounts {
14
+ inputTokens: number;
15
+ outputTokens: number;
16
+ cachedTokens: number;
17
+ }
18
+ /**
19
+ * Hooks invoked by chat route handlers after the message stream completes.
20
+ */
21
+ export interface StreamHooks {
22
+ /** Log an audit event */
23
+ onAuditLog?: (entry: {
24
+ event: string;
25
+ resource_name: string;
26
+ details?: Record<string, unknown>;
27
+ }) => void;
28
+ /** Report token usage after each turn (fire-and-forget) */
29
+ onUsageReport?: (usage: {
30
+ model: string;
31
+ taskAgentRuns: number;
32
+ tokens: TokenCounts;
33
+ }) => void;
34
+ /** Persist session history (fire-and-forget). Messages array is empty for new-stack sessions. */
35
+ onSessionPersist?: (sessionId: string, messages: unknown[], status: 'active' | 'completed' | 'error', meta?: {
36
+ model?: string;
37
+ provider?: string;
38
+ }) => void;
39
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=stream-hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream-hooks.js","sourceRoot":"","sources":["../../../src/session/stream-hooks.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ /**
7
+ * Tool Context Factory.
8
+ *
9
+ * Builds a ToolContext from session-level dependencies. This is the bridge
10
+ * between the agent loop and tool implementations.
11
+ *
12
+ * Replaces the old `buildToolContext()` in agent/tool-context-builder.ts
13
+ * which depended on the legacy AgentSession type. This factory takes
14
+ * explicit dependencies and returns a factory function matching the
15
+ * `AgentContext.buildToolContext` signature: `(callId: string) => ToolContext`.
16
+ */
17
+ import type { LoadedStore, StoreBackend } from '@amodalai/types';
18
+ import type { FieldScrubber } from '@amodalai/core';
19
+ import type { ConnectionsMap } from '../tools/request-tool.js';
20
+ import type { ToolContext } from '../tools/types.js';
21
+ import type { Logger } from '../logger.js';
22
+ /** Dependencies for creating tool contexts. */
23
+ export interface ToolContextFactoryOptions {
24
+ /** Connection configs (base_url, auth headers, etc.) */
25
+ connectionsMap: ConnectionsMap;
26
+ /** Shared store backend for ctx.store() */
27
+ storeBackend: StoreBackend;
28
+ /** Store definitions for key resolution */
29
+ storeDefinitions: LoadedStore[];
30
+ /** App ID for store isolation */
31
+ appId: string;
32
+ /** Allowlisted env vars: name → value. Only these are exposed via ctx.env(). */
33
+ envAllowlist: Record<string, string | undefined>;
34
+ /** Session-scoped logger */
35
+ logger: Logger;
36
+ /** Field scrubber for response sanitization (optional) */
37
+ fieldScrubber?: FieldScrubber | null;
38
+ /** User info */
39
+ user: {
40
+ roles: string[];
41
+ [key: string]: unknown;
42
+ };
43
+ /** Session ID for correlation */
44
+ sessionId: string;
45
+ /** Tenant ID for multi-tenant isolation */
46
+ tenantId: string;
47
+ }
48
+ /**
49
+ * Create a factory function that builds ToolContext instances for tool execution.
50
+ *
51
+ * The returned factory is passed as `AgentContext.buildToolContext`. The EXECUTING
52
+ * state handler calls it once per tool execution with the tool call ID.
53
+ *
54
+ * The EXECUTING handler composes its own AbortSignal (session + per-tool timeout)
55
+ * and overrides `ctx.signal` via object spread before passing to the tool's
56
+ * execute function. Methods on this context read `ctx.signal` at call time
57
+ * (not at creation time) so that the overridden signal propagates to HTTP
58
+ * requests and other async operations.
59
+ */
60
+ export declare function createToolContextFactory(opts: ToolContextFactoryOptions): (callId: string) => ToolContext;
@@ -0,0 +1,190 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ import { ConnectionError, StoreError } from '../errors.js';
7
+ import { resolveKey } from '../stores/key-resolver.js';
8
+ // ---------------------------------------------------------------------------
9
+ // Request implementation (internalized from request-helper.ts)
10
+ // ---------------------------------------------------------------------------
11
+ const REQUEST_TIMEOUT_MS = 30_000;
12
+ /**
13
+ * Resolve auth template variables: "Bearer {{API_KEY}}" → "Bearer token123"
14
+ */
15
+ function resolveAuthTemplate(template, connectionConfig) {
16
+ return template.replace(/\{\{(\w+)\}\}/g, (_match, varName) => {
17
+ const value = connectionConfig[varName];
18
+ return value !== undefined ? String(value) : '';
19
+ });
20
+ }
21
+ async function makeRequest(opts, connection, endpoint, params, signal) {
22
+ const method = params?.method ?? 'GET';
23
+ const connConfig = opts.connectionsMap[connection];
24
+ if (!connConfig) {
25
+ const available = Object.keys(opts.connectionsMap);
26
+ const suggestion = available.find((n) => n.toLowerCase() === connection.toLowerCase())
27
+ ?? available.find((n) => connection.toLowerCase().includes(n.toLowerCase()) || n.toLowerCase().includes(connection.toLowerCase()));
28
+ throw new ConnectionError(`Connection "${connection}" not found. Available: ${available.join(', ') || '(none)'}${suggestion ? `. Did you mean "${suggestion}"?` : ''}`, { connection, action: `${method} ${endpoint}` });
29
+ }
30
+ const baseUrl = connConfig.base_url;
31
+ if (!baseUrl) {
32
+ throw new ConnectionError(`Connection "${connection}" has no base_url`, { connection, action: `${method} ${endpoint}` });
33
+ }
34
+ let url = `${baseUrl.replace(/\/$/, '')}/${endpoint.replace(/^\//, '')}`;
35
+ // Add query params
36
+ if (params?.params) {
37
+ const searchParams = new URLSearchParams();
38
+ for (const [k, v] of Object.entries(params.params)) {
39
+ searchParams.set(k, v);
40
+ }
41
+ const qs = searchParams.toString();
42
+ if (qs) {
43
+ url += `?${qs}`;
44
+ }
45
+ }
46
+ // Build headers
47
+ const headers = { 'Content-Type': 'application/json' };
48
+ const reqConfig = connConfig._request_config;
49
+ if (reqConfig?.auth) {
50
+ for (const entry of reqConfig.auth) {
51
+ headers[entry.header] = resolveAuthTemplate(entry.value_template, connConfig);
52
+ }
53
+ }
54
+ if (reqConfig?.default_headers) {
55
+ for (const [k, v] of Object.entries(reqConfig.default_headers)) {
56
+ headers[k] = v;
57
+ }
58
+ }
59
+ const requestSignal = signal ?? AbortSignal.timeout(REQUEST_TIMEOUT_MS);
60
+ const fetchOpts = { method, headers, signal: requestSignal };
61
+ if (params?.data && (method === 'POST' || method === 'PUT' || method === 'PATCH')) {
62
+ fetchOpts.body = JSON.stringify(params.data);
63
+ }
64
+ const response = await fetch(url, fetchOpts);
65
+ const text = await response.text();
66
+ // Field scrubbing — only attempt on valid JSON; scrubber errors propagate
67
+ let output = text;
68
+ if (opts.fieldScrubber) {
69
+ let parsed;
70
+ try {
71
+ parsed = JSON.parse(text);
72
+ }
73
+ catch {
74
+ // Not JSON — skip scrubbing, return text as-is
75
+ parsed = undefined;
76
+ }
77
+ if (parsed !== undefined) {
78
+ const scrubResult = opts.fieldScrubber.scrub(parsed, connection, endpoint);
79
+ output = JSON.stringify(scrubResult.data);
80
+ }
81
+ }
82
+ if (!response.ok) {
83
+ if (response.status === 401 || response.status === 403) {
84
+ throw new ConnectionError(`Authentication failed (${String(response.status)}) for connection "${connection}". Check credentials.`, { connection, action: `${method} ${endpoint}` });
85
+ }
86
+ throw new ConnectionError(`HTTP ${String(response.status)} from "${connection}" ${method} ${endpoint}: ${output.substring(0, 500)}`, { connection, action: `${method} ${endpoint}` });
87
+ }
88
+ // Parse JSON response if possible
89
+ try {
90
+ return JSON.parse(output);
91
+ }
92
+ catch {
93
+ return output;
94
+ }
95
+ }
96
+ // ---------------------------------------------------------------------------
97
+ // Factory
98
+ // ---------------------------------------------------------------------------
99
+ /**
100
+ * Create a factory function that builds ToolContext instances for tool execution.
101
+ *
102
+ * The returned factory is passed as `AgentContext.buildToolContext`. The EXECUTING
103
+ * state handler calls it once per tool execution with the tool call ID.
104
+ *
105
+ * The EXECUTING handler composes its own AbortSignal (session + per-tool timeout)
106
+ * and overrides `ctx.signal` via object spread before passing to the tool's
107
+ * execute function. Methods on this context read `ctx.signal` at call time
108
+ * (not at creation time) so that the overridden signal propagates to HTTP
109
+ * requests and other async operations.
110
+ */
111
+ export function createToolContextFactory(opts) {
112
+ return (callId) => {
113
+ // Build ctx as a named object so methods can reference ctx.signal at
114
+ // call time. When EXECUTING does `{...toolCtx, signal: combined}`, the
115
+ // spread creates a new object — but the closures still capture `ctx`.
116
+ // To fix this, EXECUTING must mutate `toolCtx.signal` directly instead
117
+ // of spreading. The default signal here is a safety net in case
118
+ // the caller doesn't override.
119
+ const ctx = {
120
+ async request(connection, endpoint, params) {
121
+ opts.logger.debug('tool_context_request', {
122
+ callId,
123
+ connection,
124
+ endpoint,
125
+ method: params?.method ?? 'GET',
126
+ session: opts.sessionId,
127
+ });
128
+ return makeRequest(opts, connection, endpoint, params, ctx.signal);
129
+ },
130
+ async store(storeName, payload) {
131
+ const storeDef = opts.storeDefinitions.find((s) => s.name === storeName);
132
+ if (!storeDef) {
133
+ const available = opts.storeDefinitions.map((s) => s.name).join(', ');
134
+ throw new StoreError(`Store "${storeName}" not found. Available: ${available || '(none)'}`, {
135
+ store: storeName,
136
+ operation: 'put',
137
+ context: { available, session: opts.sessionId },
138
+ });
139
+ }
140
+ const key = resolveKey(storeDef.entity.key, payload);
141
+ opts.logger.debug('tool_context_store_write', {
142
+ callId,
143
+ store: storeName,
144
+ key,
145
+ session: opts.sessionId,
146
+ });
147
+ // Race against abort signal so a hung PGLite doesn't block forever
148
+ await Promise.race([
149
+ opts.storeBackend.put(opts.appId, storeName, key, payload, {}),
150
+ new Promise((_resolve, reject) => {
151
+ if (ctx.signal.aborted) {
152
+ reject(new StoreError('Store write timed out', { store: storeName, operation: 'put', context: { callId, key } }));
153
+ return;
154
+ }
155
+ ctx.signal.addEventListener('abort', () => {
156
+ reject(new StoreError('Store write timed out', { store: storeName, operation: 'put', context: { callId, key } }));
157
+ }, { once: true });
158
+ }),
159
+ ]);
160
+ opts.logger.debug('tool_context_store_complete', {
161
+ callId,
162
+ store: storeName,
163
+ key,
164
+ session: opts.sessionId,
165
+ });
166
+ return { key };
167
+ },
168
+ env(name) {
169
+ if (!(name in opts.envAllowlist)) {
170
+ return undefined;
171
+ }
172
+ return opts.envAllowlist[name];
173
+ },
174
+ log(message) {
175
+ opts.logger.info('tool_log', {
176
+ callId,
177
+ message,
178
+ session: opts.sessionId,
179
+ tenant: opts.tenantId,
180
+ });
181
+ },
182
+ user: opts.user,
183
+ signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
184
+ sessionId: opts.sessionId,
185
+ tenantId: opts.tenantId,
186
+ };
187
+ return ctx;
188
+ };
189
+ }
190
+ //# sourceMappingURL=tool-context-factory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-context-factory.js","sourceRoot":"","sources":["../../../src/session/tool-context-factory.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAmBH,OAAO,EAAC,eAAe,EAAE,UAAU,EAAC,MAAM,cAAc,CAAC;AACzD,OAAO,EAAC,UAAU,EAAC,MAAM,2BAA2B,CAAC;AA8BrD,8EAA8E;AAC9E,+DAA+D;AAC/D,8EAA8E;AAE9E,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAElC;;GAEG;AACH,SAAS,mBAAmB,CAAC,QAAgB,EAAE,gBAAyC;IACtF,OAAO,QAAQ,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC,MAAM,EAAE,OAAe,EAAE,EAAE;QACpE,MAAM,KAAK,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;QACxC,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAClD,CAAC,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,WAAW,CACxB,IAA+B,EAC/B,UAAkB,EAClB,QAAgB,EAChB,MAA2E,EAC3E,MAAoB;IAEpB,MAAM,MAAM,GAAG,MAAM,EAAE,MAAM,IAAI,KAAK,CAAC;IAEvC,MAAM,UAAU,GAAG,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;IACnD,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACnD,MAAM,UAAU,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,UAAU,CAAC,WAAW,EAAE,CAAC;eACjF,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;QACrI,MAAM,IAAI,eAAe,CACvB,eAAe,UAAU,2BAA2B,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,QAAQ,GAAG,UAAU,CAAC,CAAC,CAAC,mBAAmB,UAAU,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,EAC5I,EAAC,UAAU,EAAE,MAAM,EAAE,GAAG,MAAM,IAAI,QAAQ,EAAE,EAAC,CAC9C,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,UAAU,CAAC,QAAQ,CAAC;IACpC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,eAAe,CAAC,eAAe,UAAU,mBAAmB,EAAE,EAAC,UAAU,EAAE,MAAM,EAAE,GAAG,MAAM,IAAI,QAAQ,EAAE,EAAC,CAAC,CAAC;IACzH,CAAC;IACD,IAAI,GAAG,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,CAAC;IAEzE,mBAAmB;IACnB,IAAI,MAAM,EAAE,MAAM,EAAE,CAAC;QACnB,MAAM,YAAY,GAAG,IAAI,eAAe,EAAE,CAAC;QAC3C,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;YACnD,YAAY,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACzB,CAAC;QACD,MAAM,EAAE,GAAG,YAAY,CAAC,QAAQ,EAAE,CAAC;QACnC,IAAI,EAAE,EAAE,CAAC;YACP,GAAG,IAAI,IAAI,EAAE,EAAE,CAAC;QAClB,CAAC;IACH,CAAC;IAED,gBAAgB;IAChB,MAAM,OAAO,GAA2B,EAAC,cAAc,EAAE,kBAAkB,EAAC,CAAC;IAC7E,MAAM,SAAS,GAAG,UAAU,CAAC,eAAe,CAAC;IAC7C,IAAI,SAAS,EAAE,IAAI,EAAE,CAAC;QACpB,KAAK,MAAM,KAAK,IAAI,SAAS,CAAC,IAAI,EAAE,CAAC;YACnC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,mBAAmB,CAAC,KAAK,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;QAChF,CAAC;IACH,CAAC;IACD,IAAI,SAAS,EAAE,eAAe,EAAE,CAAC;QAC/B,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,eAAe,CAAC,EAAE,CAAC;YAC/D,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACjB,CAAC;IACH,CAAC;IAED,MAAM,aAAa,GAAG,MAAM,IAAI,WAAW,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAExE,MAAM,SAAS,GAAgB,EAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAC,CAAC;IACxE,IAAI,MAAM,EAAE,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,IAAI,MAAM,KAAK,KAAK,IAAI,MAAM,KAAK,OAAO,CAAC,EAAE,CAAC;QAClF,SAAS,CAAC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC/C,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAC7C,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IAEnC,0EAA0E;IAC1E,IAAI,MAAM,GAAG,IAAI,CAAC;IAClB,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;QACvB,IAAI,MAAe,CAAC;QACpB,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;QAAC,MAAM,CAAC;YACP,+CAA+C;YAC/C,MAAM,GAAG,SAAS,CAAC;QACrB,CAAC;QACD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YAEzB,MAAM,WAAW,GAAG,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,MAAM,EAAE,UAAU,EAAE,QAAQ,CAAoB,CAAC;YAC9F,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YACvD,MAAM,IAAI,eAAe,CACvB,0BAA0B,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,qBAAqB,UAAU,uBAAuB,EACvG,EAAC,UAAU,EAAE,MAAM,EAAE,GAAG,MAAM,IAAI,QAAQ,EAAE,EAAC,CAC9C,CAAC;QACJ,CAAC;QACD,MAAM,IAAI,eAAe,CACvB,QAAQ,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,UAAU,KAAK,MAAM,IAAI,QAAQ,KAAK,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,EACzG,EAAC,UAAU,EAAE,MAAM,EAAE,GAAG,MAAM,IAAI,QAAQ,EAAE,EAAC,CAC9C,CAAC;IACJ,CAAC;IAED,kCAAkC;IAClC,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAY,CAAC;IACvC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,MAAM,CAAC;IAChB,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,wBAAwB,CACtC,IAA+B;IAE/B,OAAO,CAAC,MAAc,EAAe,EAAE;QACrC,qEAAqE;QACrE,uEAAuE;QACvE,sEAAsE;QACtE,uEAAuE;QACvE,gEAAgE;QAChE,+BAA+B;QAC/B,MAAM,GAAG,GAAgB;YACvB,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,QAAQ,EAAE,MAAM;gBACxC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,sBAAsB,EAAE;oBACxC,MAAM;oBACN,UAAU;oBACV,QAAQ;oBACR,MAAM,EAAE,MAAM,EAAE,MAAM,IAAI,KAAK;oBAC/B,OAAO,EAAE,IAAI,CAAC,SAAS;iBACxB,CAAC,CAAC;gBACH,OAAO,WAAW,CAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;YACrE,CAAC;YAED,KAAK,CAAC,KAAK,CAAC,SAAS,EAAE,OAAO;gBAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;gBACzE,IAAI,CAAC,QAAQ,EAAE,CAAC;oBACd,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBACtE,MAAM,IAAI,UAAU,CAAC,UAAU,SAAS,2BAA2B,SAAS,IAAI,QAAQ,EAAE,EAAE;wBAC1F,KAAK,EAAE,SAAS;wBAChB,SAAS,EAAE,KAAK;wBAChB,OAAO,EAAE,EAAC,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,SAAS,EAAC;qBAC9C,CAAC,CAAC;gBACL,CAAC;gBACD,MAAM,GAAG,GAAG,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;gBAErD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,0BAA0B,EAAE;oBAC5C,MAAM;oBACN,KAAK,EAAE,SAAS;oBAChB,GAAG;oBACH,OAAO,EAAE,IAAI,CAAC,SAAS;iBACxB,CAAC,CAAC;gBAEH,mEAAmE;gBACnE,MAAM,OAAO,CAAC,IAAI,CAAC;oBACjB,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,CAAC;oBAC9D,IAAI,OAAO,CAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE;wBACtC,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;4BACvB,MAAM,CAAC,IAAI,UAAU,CAAC,uBAAuB,EAAE,EAAC,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,EAAC,MAAM,EAAE,GAAG,EAAC,EAAC,CAAC,CAAC,CAAC;4BAC9G,OAAO;wBACT,CAAC;wBACD,GAAG,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE;4BACxC,MAAM,CAAC,IAAI,UAAU,CAAC,uBAAuB,EAAE,EAAC,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,EAAC,MAAM,EAAE,GAAG,EAAC,EAAC,CAAC,CAAC,CAAC;wBAChH,CAAC,EAAE,EAAC,IAAI,EAAE,IAAI,EAAC,CAAC,CAAC;oBACnB,CAAC,CAAC;iBACH,CAAC,CAAC;gBAEH,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,6BAA6B,EAAE;oBAC/C,MAAM;oBACN,KAAK,EAAE,SAAS;oBAChB,GAAG;oBACH,OAAO,EAAE,IAAI,CAAC,SAAS;iBACxB,CAAC,CAAC;gBACH,OAAO,EAAC,GAAG,EAAC,CAAC;YACf,CAAC;YAED,GAAG,CAAC,IAAI;gBACN,IAAI,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC;oBACjC,OAAO,SAAS,CAAC;gBACnB,CAAC;gBACD,OAAO,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;YACjC,CAAC;YAED,GAAG,CAAC,OAAO;gBACT,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE;oBAC3B,MAAM;oBACN,OAAO;oBACP,OAAO,EAAE,IAAI,CAAC,SAAS;oBACvB,MAAM,EAAE,IAAI,CAAC,QAAQ;iBACtB,CAAC,CAAC;YACL,CAAC;YAED,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,kBAAkB,CAAC;YAC/C,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,QAAQ,EAAE,IAAI,CAAC,QAAQ;SACxB,CAAC;QACF,OAAO,GAAG,CAAC;IACb,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ export {};