@amodalai/runtime 0.1.26 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (445) hide show
  1. package/dist/src/__fixtures__/README.md +88 -0
  2. package/dist/src/__fixtures__/e2e.test.js +211 -0
  3. package/dist/src/__fixtures__/e2e.test.js.map +1 -0
  4. package/dist/src/__fixtures__/smoke-agent/amodal.json +11 -0
  5. package/dist/src/__fixtures__/smoke-agent/automations/delivery-callback-test.json +9 -0
  6. package/dist/src/__fixtures__/smoke-agent/automations/test-auto.md +5 -0
  7. package/dist/src/__fixtures__/smoke-agent/connections/mock-api/access.json +11 -0
  8. package/dist/src/__fixtures__/smoke-agent/connections/mock-api/spec.json +4 -0
  9. package/dist/src/__fixtures__/smoke-agent/connections/mock-api/surface.md +9 -0
  10. package/dist/src/__fixtures__/smoke-agent/connections/mock-mcp/access.json +3 -0
  11. package/dist/src/__fixtures__/smoke-agent/connections/mock-mcp/spec.json +8 -0
  12. package/dist/src/__fixtures__/smoke-agent/evals/basic-eval.md +12 -0
  13. package/dist/src/__fixtures__/smoke-agent/knowledge/test-knowledge.md +3 -0
  14. package/dist/src/__fixtures__/smoke-agent/skills/test-skill/SKILL.md +11 -0
  15. package/dist/src/__fixtures__/smoke-agent/stores/test-items.json +11 -0
  16. package/dist/src/__fixtures__/smoke-agent/tools/echo_tool/handler.d.ts +18 -0
  17. package/dist/src/__fixtures__/smoke-agent/tools/echo_tool/handler.js +22 -0
  18. package/dist/src/__fixtures__/smoke-agent/tools/echo_tool/handler.js.map +1 -0
  19. package/dist/src/__fixtures__/smoke-agent/tools/echo_tool/tool.json +17 -0
  20. package/dist/src/__fixtures__/smoke.test.js +1404 -0
  21. package/dist/src/__fixtures__/smoke.test.js.map +1 -0
  22. package/dist/src/__fixtures__/test-env.d.ts +27 -0
  23. package/dist/src/__fixtures__/test-env.js +64 -0
  24. package/dist/src/__fixtures__/test-env.js.map +1 -0
  25. package/dist/src/__fixtures__/test-helpers.d.ts +30 -0
  26. package/dist/src/__fixtures__/test-helpers.js +120 -0
  27. package/dist/src/__fixtures__/test-helpers.js.map +1 -0
  28. package/dist/src/__tests__/test-providers.d.ts +40 -0
  29. package/dist/src/__tests__/test-providers.js +61 -0
  30. package/dist/src/__tests__/test-providers.js.map +1 -0
  31. package/dist/src/agent/agent-types.d.ts +22 -0
  32. package/dist/src/agent/agent-types.js.map +1 -1
  33. package/dist/src/agent/automation-bridge.d.ts +9 -0
  34. package/dist/src/agent/automation-bridge.js +26 -0
  35. package/dist/src/agent/automation-bridge.js.map +1 -1
  36. package/dist/src/agent/automation-bridge.test.js +63 -0
  37. package/dist/src/agent/automation-bridge.test.js.map +1 -1
  38. package/dist/src/agent/local-server.d.ts +1 -8
  39. package/dist/src/agent/local-server.js +398 -163
  40. package/dist/src/agent/local-server.js.map +1 -1
  41. package/dist/src/agent/local-server.test.js +14 -8
  42. package/dist/src/agent/local-server.test.js.map +1 -1
  43. package/dist/src/agent/loop-types.d.ts +254 -0
  44. package/dist/src/agent/loop-types.js +24 -0
  45. package/dist/src/agent/loop-types.js.map +1 -0
  46. package/dist/src/agent/loop.d.ts +31 -0
  47. package/dist/src/agent/loop.js +152 -0
  48. package/dist/src/agent/loop.js.map +1 -0
  49. package/dist/src/agent/loop.test.js +1594 -0
  50. package/dist/src/agent/loop.test.js.map +1 -0
  51. package/dist/src/agent/mcp-config.d.ts +28 -0
  52. package/dist/src/agent/mcp-config.js +57 -0
  53. package/dist/src/agent/mcp-config.js.map +1 -0
  54. package/dist/src/agent/page-builder.js +6 -1
  55. package/dist/src/agent/page-builder.js.map +1 -1
  56. package/dist/src/agent/proactive/delivery-router.d.ts +68 -0
  57. package/dist/src/agent/proactive/delivery-router.js +337 -0
  58. package/dist/src/agent/proactive/delivery-router.js.map +1 -0
  59. package/dist/src/agent/{stores-e2e.test.d.ts → proactive/delivery-router.test.d.ts} +1 -1
  60. package/dist/src/agent/proactive/delivery-router.test.js +455 -0
  61. package/dist/src/agent/proactive/delivery-router.test.js.map +1 -0
  62. package/dist/src/agent/proactive/proactive-runner.d.ts +46 -8
  63. package/dist/src/agent/proactive/proactive-runner.js +67 -37
  64. package/dist/src/agent/proactive/proactive-runner.js.map +1 -1
  65. package/dist/src/agent/proactive/proactive-runner.test.d.ts +1 -1
  66. package/dist/src/agent/proactive/proactive-runner.test.js +73 -87
  67. package/dist/src/agent/proactive/proactive-runner.test.js.map +1 -1
  68. package/dist/src/agent/routes/admin-chat-abort.test.d.ts +6 -0
  69. package/dist/src/agent/routes/admin-chat-abort.test.js +206 -0
  70. package/dist/src/agent/routes/admin-chat-abort.test.js.map +1 -0
  71. package/dist/src/agent/routes/admin-chat.d.ts +15 -3
  72. package/dist/src/agent/routes/admin-chat.js +61 -18
  73. package/dist/src/agent/routes/admin-chat.js.map +1 -1
  74. package/dist/src/agent/routes/automations.js +5 -6
  75. package/dist/src/agent/routes/automations.js.map +1 -1
  76. package/dist/src/agent/routes/evals.d.ts +3 -2
  77. package/dist/src/agent/routes/evals.js +25 -12
  78. package/dist/src/agent/routes/evals.js.map +1 -1
  79. package/dist/src/agent/routes/files.js +7 -9
  80. package/dist/src/agent/routes/files.js.map +1 -1
  81. package/dist/src/agent/routes/inspect.d.ts +6 -2
  82. package/dist/src/agent/routes/inspect.js +31 -17
  83. package/dist/src/agent/routes/inspect.js.map +1 -1
  84. package/dist/src/agent/routes/inspect.test.js +18 -42
  85. package/dist/src/agent/routes/inspect.test.js.map +1 -1
  86. package/dist/src/agent/routes/stores.js +9 -12
  87. package/dist/src/agent/routes/stores.js.map +1 -1
  88. package/dist/src/agent/routes/task.d.ts +15 -3
  89. package/dist/src/agent/routes/task.js +16 -7
  90. package/dist/src/agent/routes/task.js.map +1 -1
  91. package/dist/src/agent/routes/task.test.d.ts +1 -1
  92. package/dist/src/agent/routes/task.test.js +68 -53
  93. package/dist/src/agent/routes/task.test.js.map +1 -1
  94. package/dist/src/agent/routes/webhooks.js +12 -3
  95. package/dist/src/agent/routes/webhooks.js.map +1 -1
  96. package/dist/src/agent/snapshot-server.d.ts +2 -22
  97. package/dist/src/agent/snapshot-server.js +48 -27
  98. package/dist/src/agent/snapshot-server.js.map +1 -1
  99. package/dist/src/agent/states/compacting.d.ts +14 -0
  100. package/dist/src/agent/states/compacting.js +260 -0
  101. package/dist/src/agent/states/compacting.js.map +1 -0
  102. package/dist/src/agent/states/confirming.d.ts +10 -0
  103. package/dist/src/agent/states/confirming.js +79 -0
  104. package/dist/src/agent/states/confirming.js.map +1 -0
  105. package/dist/src/agent/states/dispatching.d.ts +18 -0
  106. package/dist/src/agent/states/dispatching.js +285 -0
  107. package/dist/src/agent/states/dispatching.js.map +1 -0
  108. package/dist/src/agent/states/executing.d.ts +21 -0
  109. package/dist/src/agent/states/executing.js +452 -0
  110. package/dist/src/agent/states/executing.js.map +1 -0
  111. package/dist/src/agent/states/streaming.d.ts +10 -0
  112. package/dist/src/agent/states/streaming.js +169 -0
  113. package/dist/src/agent/states/streaming.js.map +1 -0
  114. package/dist/src/agent/states/thinking.d.ts +13 -0
  115. package/dist/src/agent/states/thinking.js +450 -0
  116. package/dist/src/agent/states/thinking.js.map +1 -0
  117. package/dist/src/agent/token-estimate.d.ts +31 -0
  118. package/dist/src/agent/token-estimate.js +34 -0
  119. package/dist/src/agent/token-estimate.js.map +1 -0
  120. package/dist/src/agent/token-estimate.test.d.ts +6 -0
  121. package/dist/src/agent/token-estimate.test.js +44 -0
  122. package/dist/src/agent/token-estimate.test.js.map +1 -0
  123. package/dist/src/agent/tool-executor-local.js +9 -18
  124. package/dist/src/agent/tool-executor-local.js.map +1 -1
  125. package/dist/src/agent/tool-executor-local.test.js +3 -5
  126. package/dist/src/agent/tool-executor-local.test.js.map +1 -1
  127. package/dist/src/api/create-agent.d.ts +15 -0
  128. package/dist/src/api/create-agent.js +134 -0
  129. package/dist/src/api/create-agent.js.map +1 -0
  130. package/dist/src/api/types.d.ts +66 -0
  131. package/dist/src/api/types.js +7 -0
  132. package/dist/src/api/types.js.map +1 -0
  133. package/dist/src/context/compiler.d.ts +13 -0
  134. package/dist/src/context/compiler.js +358 -0
  135. package/dist/src/context/compiler.js.map +1 -0
  136. package/dist/src/context/compiler.test.d.ts +6 -0
  137. package/dist/src/context/compiler.test.js +532 -0
  138. package/dist/src/context/compiler.test.js.map +1 -0
  139. package/dist/src/context/types.d.ts +110 -0
  140. package/dist/src/context/types.js +7 -0
  141. package/dist/src/context/types.js.map +1 -0
  142. package/dist/src/env-ref.d.ts +13 -0
  143. package/dist/src/env-ref.js +31 -0
  144. package/dist/src/env-ref.js.map +1 -0
  145. package/dist/src/env-ref.test.d.ts +6 -0
  146. package/dist/src/env-ref.test.js +34 -0
  147. package/dist/src/env-ref.test.js.map +1 -0
  148. package/dist/src/errors.d.ts +15 -0
  149. package/dist/src/errors.js +22 -0
  150. package/dist/src/errors.js.map +1 -1
  151. package/dist/src/errors.test.js +2 -2
  152. package/dist/src/errors.test.js.map +1 -1
  153. package/dist/src/events/event-bus.d.ts +54 -0
  154. package/dist/src/events/event-bus.js +84 -0
  155. package/dist/src/events/event-bus.js.map +1 -0
  156. package/dist/src/events/event-bus.test.d.ts +6 -0
  157. package/dist/src/events/event-bus.test.js +112 -0
  158. package/dist/src/events/event-bus.test.js.map +1 -0
  159. package/dist/src/events/events-route.d.ts +36 -0
  160. package/dist/src/events/events-route.js +80 -0
  161. package/dist/src/events/events-route.js.map +1 -0
  162. package/dist/src/events/events-route.test.d.ts +6 -0
  163. package/dist/src/events/events-route.test.js +134 -0
  164. package/dist/src/events/events-route.test.js.map +1 -0
  165. package/dist/src/events/store-event-wrapper.d.ts +19 -0
  166. package/dist/src/events/store-event-wrapper.js +57 -0
  167. package/dist/src/events/store-event-wrapper.js.map +1 -0
  168. package/dist/src/events/store-event-wrapper.test.d.ts +6 -0
  169. package/dist/src/events/store-event-wrapper.test.js +91 -0
  170. package/dist/src/events/store-event-wrapper.test.js.map +1 -0
  171. package/dist/src/index.d.ts +33 -6
  172. package/dist/src/index.js +35 -21
  173. package/dist/src/index.js.map +1 -1
  174. package/dist/src/middleware/auth.d.ts +0 -2
  175. package/dist/src/middleware/auth.js.map +1 -1
  176. package/dist/src/providers/create-provider.d.ts +23 -0
  177. package/dist/src/providers/create-provider.js +185 -0
  178. package/dist/src/providers/create-provider.js.map +1 -0
  179. package/dist/src/providers/create-provider.test.d.ts +6 -0
  180. package/dist/src/providers/create-provider.test.js +95 -0
  181. package/dist/src/providers/create-provider.test.js.map +1 -0
  182. package/dist/src/providers/failover.d.ts +38 -0
  183. package/dist/src/providers/failover.js +147 -0
  184. package/dist/src/providers/failover.js.map +1 -0
  185. package/dist/src/providers/failover.test.d.ts +6 -0
  186. package/dist/src/providers/failover.test.js +169 -0
  187. package/dist/src/providers/failover.test.js.map +1 -0
  188. package/dist/src/providers/search-provider.d.ts +64 -0
  189. package/dist/src/providers/search-provider.js +174 -0
  190. package/dist/src/providers/search-provider.js.map +1 -0
  191. package/dist/src/providers/types.d.ts +118 -0
  192. package/dist/src/providers/types.js +7 -0
  193. package/dist/src/providers/types.js.map +1 -0
  194. package/dist/src/routes/ai-stream.d.ts +28 -10
  195. package/dist/src/routes/ai-stream.js +85 -41
  196. package/dist/src/routes/ai-stream.js.map +1 -1
  197. package/dist/src/routes/chat-new.test.d.ts +6 -0
  198. package/dist/src/routes/chat-new.test.js +107 -0
  199. package/dist/src/routes/chat-new.test.js.map +1 -0
  200. package/dist/src/routes/chat-stream-new.test.d.ts +6 -0
  201. package/dist/src/routes/chat-stream-new.test.js +135 -0
  202. package/dist/src/routes/chat-stream-new.test.js.map +1 -0
  203. package/dist/src/routes/chat-stream.d.ts +20 -4
  204. package/dist/src/routes/chat-stream.js +49 -29
  205. package/dist/src/routes/chat-stream.js.map +1 -1
  206. package/dist/src/routes/chat.d.ts +19 -4
  207. package/dist/src/routes/chat.js +62 -23
  208. package/dist/src/routes/chat.js.map +1 -1
  209. package/dist/src/routes/health.d.ts +3 -2
  210. package/dist/src/routes/health.js.map +1 -1
  211. package/dist/src/routes/route-helpers.d.ts +50 -0
  212. package/dist/src/routes/route-helpers.js +80 -0
  213. package/dist/src/routes/route-helpers.js.map +1 -0
  214. package/dist/src/routes/session-resolver.d.ts +77 -0
  215. package/dist/src/routes/session-resolver.js +109 -0
  216. package/dist/src/routes/session-resolver.js.map +1 -0
  217. package/dist/src/routes/session-resolver.test.d.ts +6 -0
  218. package/dist/src/routes/session-resolver.test.js +207 -0
  219. package/dist/src/routes/session-resolver.test.js.map +1 -0
  220. package/dist/src/routes/webhooks.d.ts +3 -1
  221. package/dist/src/routes/webhooks.js +12 -4
  222. package/dist/src/routes/webhooks.js.map +1 -1
  223. package/dist/src/security/permission-checker.d.ts +80 -0
  224. package/dist/src/security/permission-checker.js +75 -0
  225. package/dist/src/security/permission-checker.js.map +1 -0
  226. package/dist/src/security/permission-checker.test.d.ts +6 -0
  227. package/dist/src/security/permission-checker.test.js +208 -0
  228. package/dist/src/security/permission-checker.test.js.map +1 -0
  229. package/dist/src/server.d.ts +18 -11
  230. package/dist/src/server.js +46 -46
  231. package/dist/src/server.js.map +1 -1
  232. package/dist/src/server.test.d.ts +1 -1
  233. package/dist/src/server.test.js +6 -144
  234. package/dist/src/server.test.js.map +1 -1
  235. package/dist/src/session/drizzle-session-store.d.ts +56 -0
  236. package/dist/src/session/drizzle-session-store.js +203 -0
  237. package/dist/src/session/drizzle-session-store.js.map +1 -0
  238. package/dist/src/session/manager.d.ts +101 -0
  239. package/dist/src/session/manager.js +394 -0
  240. package/dist/src/session/manager.js.map +1 -0
  241. package/dist/src/session/manager.test.d.ts +6 -0
  242. package/dist/src/session/manager.test.js +309 -0
  243. package/dist/src/session/manager.test.js.map +1 -0
  244. package/dist/src/session/pglite-session-store.d.ts +23 -0
  245. package/dist/src/session/pglite-session-store.js +70 -0
  246. package/dist/src/session/pglite-session-store.js.map +1 -0
  247. package/dist/src/session/postgres-session-store.d.ts +44 -0
  248. package/dist/src/session/postgres-session-store.js +138 -0
  249. package/dist/src/session/postgres-session-store.js.map +1 -0
  250. package/dist/src/session/session-builder.d.ts +69 -0
  251. package/dist/src/session/session-builder.js +384 -0
  252. package/dist/src/session/session-builder.js.map +1 -0
  253. package/dist/src/session/session-builder.test.d.ts +6 -0
  254. package/dist/src/session/session-builder.test.js +350 -0
  255. package/dist/src/session/session-builder.test.js.map +1 -0
  256. package/dist/src/session/session-store-selector.d.ts +49 -0
  257. package/dist/src/session/session-store-selector.js +60 -0
  258. package/dist/src/session/session-store-selector.js.map +1 -0
  259. package/dist/src/session/session-store-selector.test.d.ts +6 -0
  260. package/dist/src/session/session-store-selector.test.js +79 -0
  261. package/dist/src/session/session-store-selector.test.js.map +1 -0
  262. package/dist/src/session/store.d.ts +171 -0
  263. package/dist/src/session/store.js +155 -0
  264. package/dist/src/session/store.js.map +1 -0
  265. package/dist/src/session/store.test.d.ts +6 -0
  266. package/dist/src/session/store.test.js +423 -0
  267. package/dist/src/session/store.test.js.map +1 -0
  268. package/dist/src/session/stream-hooks.d.ts +39 -0
  269. package/dist/src/session/stream-hooks.js +7 -0
  270. package/dist/src/session/stream-hooks.js.map +1 -0
  271. package/dist/src/session/tool-context-factory.d.ts +61 -0
  272. package/dist/src/session/tool-context-factory.js +189 -0
  273. package/dist/src/session/tool-context-factory.js.map +1 -0
  274. package/dist/src/session/tool-context-factory.test.d.ts +6 -0
  275. package/dist/src/session/tool-context-factory.test.js +284 -0
  276. package/dist/src/session/tool-context-factory.test.js.map +1 -0
  277. package/dist/src/session/types.d.ts +195 -0
  278. package/dist/src/session/types.js +7 -0
  279. package/dist/src/session/types.js.map +1 -0
  280. package/dist/src/stores/drizzle-store-backend.d.ts +49 -0
  281. package/dist/src/stores/drizzle-store-backend.js +306 -0
  282. package/dist/src/stores/drizzle-store-backend.js.map +1 -0
  283. package/dist/src/stores/drizzle-store-backend.test.d.ts +6 -0
  284. package/dist/src/stores/drizzle-store-backend.test.js +215 -0
  285. package/dist/src/stores/drizzle-store-backend.test.js.map +1 -0
  286. package/dist/src/stores/index.d.ts +4 -0
  287. package/dist/src/stores/index.js +2 -0
  288. package/dist/src/stores/index.js.map +1 -1
  289. package/dist/src/stores/pglite-store-backend.d.ts +16 -19
  290. package/dist/src/stores/pglite-store-backend.js +85 -239
  291. package/dist/src/stores/pglite-store-backend.js.map +1 -1
  292. package/dist/src/stores/postgres-store-backend.d.ts +30 -0
  293. package/dist/src/stores/postgres-store-backend.js +100 -0
  294. package/dist/src/stores/postgres-store-backend.js.map +1 -0
  295. package/dist/src/stores/schema.d.ts +457 -0
  296. package/dist/src/stores/schema.js +59 -0
  297. package/dist/src/stores/schema.js.map +1 -0
  298. package/dist/src/tools/admin-file-tools.d.ts +42 -0
  299. package/dist/src/tools/admin-file-tools.js +714 -0
  300. package/dist/src/tools/admin-file-tools.js.map +1 -0
  301. package/dist/src/tools/admin-file-tools.test.d.ts +6 -0
  302. package/dist/src/tools/admin-file-tools.test.js +521 -0
  303. package/dist/src/tools/admin-file-tools.test.js.map +1 -0
  304. package/dist/src/tools/custom-tool-adapter.d.ts +41 -0
  305. package/dist/src/tools/custom-tool-adapter.js +190 -0
  306. package/dist/src/tools/custom-tool-adapter.js.map +1 -0
  307. package/dist/src/tools/custom-tool-adapter.test.d.ts +6 -0
  308. package/dist/src/tools/custom-tool-adapter.test.js +243 -0
  309. package/dist/src/tools/custom-tool-adapter.test.js.map +1 -0
  310. package/dist/src/tools/dispatch-tool.d.ts +52 -0
  311. package/dist/src/tools/dispatch-tool.js +71 -0
  312. package/dist/src/tools/dispatch-tool.js.map +1 -0
  313. package/dist/src/tools/dispatch-tool.test.d.ts +6 -0
  314. package/dist/src/tools/dispatch-tool.test.js +75 -0
  315. package/dist/src/tools/dispatch-tool.test.js.map +1 -0
  316. package/dist/src/tools/fetch-url-tool.d.ts +23 -0
  317. package/dist/src/tools/fetch-url-tool.js +333 -0
  318. package/dist/src/tools/fetch-url-tool.js.map +1 -0
  319. package/dist/src/tools/fetch-url-tool.test.d.ts +6 -0
  320. package/dist/src/tools/fetch-url-tool.test.js +228 -0
  321. package/dist/src/tools/fetch-url-tool.test.js.map +1 -0
  322. package/dist/src/tools/mcp-tool-adapter.d.ts +18 -0
  323. package/dist/src/tools/mcp-tool-adapter.js +135 -0
  324. package/dist/src/tools/mcp-tool-adapter.js.map +1 -0
  325. package/dist/src/tools/mcp-tool-adapter.test.d.ts +6 -0
  326. package/dist/src/tools/mcp-tool-adapter.test.js +226 -0
  327. package/dist/src/tools/mcp-tool-adapter.test.js.map +1 -0
  328. package/dist/src/tools/registry.d.ts +25 -0
  329. package/dist/src/tools/registry.js +72 -0
  330. package/dist/src/tools/registry.js.map +1 -0
  331. package/dist/src/tools/registry.test.d.ts +6 -0
  332. package/dist/src/tools/registry.test.js +120 -0
  333. package/dist/src/tools/registry.test.js.map +1 -0
  334. package/dist/src/tools/request-tool.d.ts +42 -0
  335. package/dist/src/tools/request-tool.js +190 -0
  336. package/dist/src/tools/request-tool.js.map +1 -0
  337. package/dist/src/tools/request-tool.test.d.ts +6 -0
  338. package/dist/src/tools/request-tool.test.js +253 -0
  339. package/dist/src/tools/request-tool.test.js.map +1 -0
  340. package/dist/src/tools/store-tools.d.ts +29 -0
  341. package/dist/src/tools/store-tools.js +224 -0
  342. package/dist/src/tools/store-tools.js.map +1 -0
  343. package/dist/src/tools/store-tools.test.d.ts +6 -0
  344. package/dist/src/tools/store-tools.test.js +215 -0
  345. package/dist/src/tools/store-tools.test.js.map +1 -0
  346. package/dist/src/tools/types.d.ts +129 -0
  347. package/dist/src/tools/types.js +7 -0
  348. package/dist/src/tools/types.js.map +1 -0
  349. package/dist/src/tools/web-search-tool.d.ts +31 -0
  350. package/dist/src/tools/web-search-tool.js +170 -0
  351. package/dist/src/tools/web-search-tool.js.map +1 -0
  352. package/dist/src/tools/web-search-tool.test.d.ts +6 -0
  353. package/dist/src/tools/web-search-tool.test.js +153 -0
  354. package/dist/src/tools/web-search-tool.test.js.map +1 -0
  355. package/dist/src/tools/web-tools-shared.d.ts +21 -0
  356. package/dist/src/tools/web-tools-shared.js +32 -0
  357. package/dist/src/tools/web-tools-shared.js.map +1 -0
  358. package/dist/src/types.d.ts +40 -12
  359. package/dist/src/types.js +16 -2
  360. package/dist/src/types.js.map +1 -1
  361. package/dist/tsconfig.tsbuildinfo +1 -1
  362. package/package.json +27 -4
  363. package/dist/src/__tests__/sse-contract.test.js +0 -464
  364. package/dist/src/__tests__/sse-contract.test.js.map +0 -1
  365. package/dist/src/__tests__/tools.test.js +0 -583
  366. package/dist/src/__tests__/tools.test.js.map +0 -1
  367. package/dist/src/agent/agent-runner.d.ts +0 -33
  368. package/dist/src/agent/agent-runner.js +0 -1040
  369. package/dist/src/agent/agent-runner.js.map +0 -1
  370. package/dist/src/agent/custom-tools-e2e.test.d.ts +0 -6
  371. package/dist/src/agent/custom-tools-e2e.test.js +0 -566
  372. package/dist/src/agent/custom-tools-e2e.test.js.map +0 -1
  373. package/dist/src/agent/request-helper.d.ts +0 -16
  374. package/dist/src/agent/request-helper.js +0 -96
  375. package/dist/src/agent/request-helper.js.map +0 -1
  376. package/dist/src/agent/session-store.d.ts +0 -62
  377. package/dist/src/agent/session-store.js +0 -151
  378. package/dist/src/agent/session-store.js.map +0 -1
  379. package/dist/src/agent/stores-e2e.test.js +0 -433
  380. package/dist/src/agent/stores-e2e.test.js.map +0 -1
  381. package/dist/src/agent/tool-context-builder.d.ts +0 -11
  382. package/dist/src/agent/tool-context-builder.js +0 -102
  383. package/dist/src/agent/tool-context-builder.js.map +0 -1
  384. package/dist/src/agent/tool-context-builder.test.d.ts +0 -6
  385. package/dist/src/agent/tool-context-builder.test.js +0 -152
  386. package/dist/src/agent/tool-context-builder.test.js.map +0 -1
  387. package/dist/src/agent/write-repo-file.test.js +0 -270
  388. package/dist/src/agent/write-repo-file.test.js.map +0 -1
  389. package/dist/src/cron/heartbeat-runner.d.ts +0 -21
  390. package/dist/src/cron/heartbeat-runner.js +0 -79
  391. package/dist/src/cron/heartbeat-runner.js.map +0 -1
  392. package/dist/src/cron/heartbeat-runner.test.d.ts +0 -6
  393. package/dist/src/cron/heartbeat-runner.test.js +0 -120
  394. package/dist/src/cron/heartbeat-runner.test.js.map +0 -1
  395. package/dist/src/cron/heartbeat-scheduler.d.ts +0 -26
  396. package/dist/src/cron/heartbeat-scheduler.js +0 -55
  397. package/dist/src/cron/heartbeat-scheduler.js.map +0 -1
  398. package/dist/src/cron/heartbeat-scheduler.test.d.ts +0 -6
  399. package/dist/src/cron/heartbeat-scheduler.test.js +0 -61
  400. package/dist/src/cron/heartbeat-scheduler.test.js.map +0 -1
  401. package/dist/src/routes/ai-stream.test.d.ts +0 -6
  402. package/dist/src/routes/ai-stream.test.js +0 -586
  403. package/dist/src/routes/ai-stream.test.js.map +0 -1
  404. package/dist/src/routes/ask-user-response.d.ts +0 -30
  405. package/dist/src/routes/ask-user-response.js +0 -61
  406. package/dist/src/routes/ask-user-response.js.map +0 -1
  407. package/dist/src/routes/ask-user-response.test.d.ts +0 -6
  408. package/dist/src/routes/ask-user-response.test.js +0 -88
  409. package/dist/src/routes/ask-user-response.test.js.map +0 -1
  410. package/dist/src/routes/chat-stream.test.d.ts +0 -6
  411. package/dist/src/routes/chat-stream.test.js +0 -155
  412. package/dist/src/routes/chat-stream.test.js.map +0 -1
  413. package/dist/src/routes/chat.test.d.ts +0 -6
  414. package/dist/src/routes/chat.test.js +0 -99
  415. package/dist/src/routes/chat.test.js.map +0 -1
  416. package/dist/src/routes/widget-actions.d.ts +0 -49
  417. package/dist/src/routes/widget-actions.js +0 -78
  418. package/dist/src/routes/widget-actions.js.map +0 -1
  419. package/dist/src/session/admin-file-tools.d.ts +0 -136
  420. package/dist/src/session/admin-file-tools.js +0 -240
  421. package/dist/src/session/admin-file-tools.js.map +0 -1
  422. package/dist/src/session/custom-tool-adapter.d.ts +0 -74
  423. package/dist/src/session/custom-tool-adapter.js +0 -180
  424. package/dist/src/session/custom-tool-adapter.js.map +0 -1
  425. package/dist/src/session/history-converter.d.ts +0 -21
  426. package/dist/src/session/history-converter.js +0 -59
  427. package/dist/src/session/history-converter.js.map +0 -1
  428. package/dist/src/session/history-converter.test.d.ts +0 -6
  429. package/dist/src/session/history-converter.test.js +0 -130
  430. package/dist/src/session/history-converter.test.js.map +0 -1
  431. package/dist/src/session/session-manager.d.ts +0 -219
  432. package/dist/src/session/session-manager.js +0 -915
  433. package/dist/src/session/session-manager.js.map +0 -1
  434. package/dist/src/session/session-manager.test.d.ts +0 -6
  435. package/dist/src/session/session-manager.test.js +0 -455
  436. package/dist/src/session/session-manager.test.js.map +0 -1
  437. package/dist/src/session/session-runner.d.ts +0 -45
  438. package/dist/src/session/session-runner.js +0 -719
  439. package/dist/src/session/session-runner.js.map +0 -1
  440. package/dist/src/session/session-runner.test.d.ts +0 -6
  441. package/dist/src/session/session-runner.test.js +0 -834
  442. package/dist/src/session/session-runner.test.js.map +0 -1
  443. /package/dist/src/{__tests__/sse-contract.test.d.ts → __fixtures__/e2e.test.d.ts} +0 -0
  444. /package/dist/src/{__tests__/tools.test.d.ts → __fixtures__/smoke.test.d.ts} +0 -0
  445. /package/dist/src/agent/{write-repo-file.test.d.ts → loop.test.d.ts} +0 -0
@@ -0,0 +1,215 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
7
+ import { createStoreWriteTool, createStoreBatchTool, createStoreQueryTool, registerStoreTools, storeToToolName, QUERY_STORE_TOOL_NAME, } from './store-tools.js';
8
+ import { createToolRegistry } from './registry.js';
9
+ import { StoreError } from '../errors.js';
10
+ // ---------------------------------------------------------------------------
11
+ // Fixtures
12
+ // ---------------------------------------------------------------------------
13
+ const ALERTS_STORE = {
14
+ name: 'alerts',
15
+ entity: {
16
+ name: 'Alert',
17
+ key: '{alert_id}',
18
+ schema: {
19
+ alert_id: { type: 'string' },
20
+ severity: { type: 'enum', values: ['P1', 'P2', 'P3'] },
21
+ message: { type: 'string' },
22
+ },
23
+ },
24
+ location: '/tmp/test',
25
+ };
26
+ const mockCtx = {
27
+ request: vi.fn(),
28
+ store: vi.fn(),
29
+ env: vi.fn(),
30
+ log: vi.fn(),
31
+ user: { roles: ['admin'] },
32
+ signal: AbortSignal.timeout(5000),
33
+ sessionId: 'test-session',
34
+ };
35
+ function createMockBackend() {
36
+ const docs = new Map();
37
+ return {
38
+ initialize: vi.fn().mockResolvedValue(undefined),
39
+ get: vi.fn().mockImplementation(async (_appId, _store, key) => docs.get(key) ?? null),
40
+ put: vi.fn().mockImplementation(async (_appId, store, key, payload) => {
41
+ const doc = {
42
+ key,
43
+ appId: 'test',
44
+ store,
45
+ version: 1,
46
+ payload,
47
+ meta: { computedAt: new Date().toISOString(), stale: false },
48
+ };
49
+ docs.set(key, doc);
50
+ const result = { stored: true, key, version: 1 };
51
+ return result;
52
+ }),
53
+ list: vi.fn().mockImplementation(async () => ({ documents: [...docs.values()], total: docs.size, hasMore: false })),
54
+ delete: vi.fn().mockResolvedValue(true),
55
+ history: vi.fn().mockResolvedValue([]),
56
+ purgeExpired: vi.fn().mockResolvedValue(0),
57
+ close: vi.fn().mockResolvedValue(undefined),
58
+ };
59
+ }
60
+ // ---------------------------------------------------------------------------
61
+ // Tests
62
+ // ---------------------------------------------------------------------------
63
+ describe('storeToToolName', () => {
64
+ it('converts kebab-case to snake_case with store_ prefix', () => {
65
+ expect(storeToToolName('active-alerts')).toBe('store_active_alerts');
66
+ expect(storeToToolName('incidents')).toBe('store_incidents');
67
+ });
68
+ });
69
+ describe('createStoreWriteTool', () => {
70
+ let backend;
71
+ beforeEach(() => {
72
+ backend = createMockBackend();
73
+ });
74
+ it('creates a write tool with correct metadata', () => {
75
+ const tool = createStoreWriteTool(ALERTS_STORE, backend, 'test-app');
76
+ expect(tool.description).toContain('Alert');
77
+ expect(tool.description).toContain('alerts');
78
+ expect(tool.readOnly).toBe(false);
79
+ expect(tool.metadata?.category).toBe('store');
80
+ });
81
+ it('writes a document with resolved key', async () => {
82
+ const tool = createStoreWriteTool(ALERTS_STORE, backend, 'test-app');
83
+ const result = await tool.execute({ alert_id: 'a1', severity: 'P1', message: 'disk full' }, mockCtx);
84
+ expect(backend.put).toHaveBeenCalledWith('test-app', 'alerts', 'a1', { alert_id: 'a1', severity: 'P1', message: 'disk full' }, {});
85
+ expect(result).toEqual({ stored: true, key: 'a1', version: 1 });
86
+ });
87
+ it('throws StoreError when key field is missing', async () => {
88
+ const tool = createStoreWriteTool(ALERTS_STORE, backend, 'test-app');
89
+ await expect(tool.execute({ severity: 'P1', message: 'no id' }, mockCtx)).rejects.toThrow(StoreError);
90
+ });
91
+ });
92
+ describe('createStoreBatchTool', () => {
93
+ let backend;
94
+ beforeEach(() => {
95
+ backend = createMockBackend();
96
+ });
97
+ it('creates a batch tool with correct metadata', () => {
98
+ const tool = createStoreBatchTool(ALERTS_STORE, backend, 'test-app');
99
+ expect(tool.description).toContain('multiple');
100
+ expect(tool.readOnly).toBe(false);
101
+ expect(tool.metadata?.category).toBe('store');
102
+ });
103
+ it('writes multiple documents', async () => {
104
+ const tool = createStoreBatchTool(ALERTS_STORE, backend, 'test-app');
105
+ const result = await tool.execute({
106
+ items: [
107
+ { alert_id: 'a1', severity: 'P1', message: 'first' },
108
+ { alert_id: 'a2', severity: 'P2', message: 'second' },
109
+ ],
110
+ }, mockCtx);
111
+ expect(backend.put).toHaveBeenCalledTimes(2);
112
+ expect(result).toMatchObject({ stored: 2, failed: 0, total: 2 });
113
+ });
114
+ it('reports partial failures without throwing', async () => {
115
+ const failBackend = createMockBackend();
116
+ let callCount = 0;
117
+ failBackend.put = vi.fn().mockImplementation(async () => {
118
+ callCount++;
119
+ if (callCount === 2)
120
+ throw new Error('write failed');
121
+ return { stored: true, key: 'k', version: 1 };
122
+ });
123
+ const tool = createStoreBatchTool(ALERTS_STORE, failBackend, 'test-app');
124
+ const result = await tool.execute({
125
+ items: [
126
+ { alert_id: 'a1', severity: 'P1', message: 'ok' },
127
+ { alert_id: 'a2', severity: 'P2', message: 'fail' },
128
+ { alert_id: 'a3', severity: 'P3', message: 'ok' },
129
+ ],
130
+ }, mockCtx);
131
+ expect(result['stored']).toBe(2);
132
+ expect(result['failed']).toBe(1);
133
+ expect(result['errors']).toEqual(['write failed']);
134
+ });
135
+ });
136
+ describe('createStoreQueryTool', () => {
137
+ let backend;
138
+ beforeEach(() => {
139
+ backend = createMockBackend();
140
+ });
141
+ it('creates a query tool that is readOnly', () => {
142
+ const tool = createStoreQueryTool([ALERTS_STORE], backend, 'test-app');
143
+ expect(tool.readOnly).toBe(true);
144
+ expect(tool.metadata?.category).toBe('store');
145
+ });
146
+ it('gets a single document by key', async () => {
147
+ // Pre-populate
148
+ await backend.put('test-app', 'alerts', 'a1', { alert_id: 'a1', severity: 'P1' }, {});
149
+ const tool = createStoreQueryTool([ALERTS_STORE], backend, 'test-app');
150
+ const result = await tool.execute({ store: 'alerts', key: 'a1' }, mockCtx);
151
+ expect(result['found']).toBe(true);
152
+ expect(result['key']).toBe('a1');
153
+ });
154
+ it('returns found: false for missing document', async () => {
155
+ const tool = createStoreQueryTool([ALERTS_STORE], backend, 'test-app');
156
+ const result = await tool.execute({ store: 'alerts', key: 'missing' }, mockCtx);
157
+ expect(result['found']).toBe(false);
158
+ });
159
+ it('lists documents with default limit', async () => {
160
+ await backend.put('test-app', 'alerts', 'a1', { alert_id: 'a1' }, {});
161
+ await backend.put('test-app', 'alerts', 'a2', { alert_id: 'a2' }, {});
162
+ const tool = createStoreQueryTool([ALERTS_STORE], backend, 'test-app');
163
+ const result = await tool.execute({ store: 'alerts' }, mockCtx);
164
+ expect(result).toHaveProperty('documents');
165
+ expect(result).toHaveProperty('total');
166
+ });
167
+ it('passes filter and sort to backend', async () => {
168
+ const tool = createStoreQueryTool([ALERTS_STORE], backend, 'test-app');
169
+ await tool.execute({
170
+ store: 'alerts',
171
+ filter: { severity: 'P1' },
172
+ sort: '-severity',
173
+ limit: 5,
174
+ }, mockCtx);
175
+ expect(backend.list).toHaveBeenCalledWith('test-app', 'alerts', {
176
+ filter: { severity: 'P1' },
177
+ sort: '-severity',
178
+ limit: 5,
179
+ });
180
+ });
181
+ });
182
+ describe('registerStoreTools', () => {
183
+ it('registers write, batch, and query tools for each store', () => {
184
+ const registry = createToolRegistry();
185
+ const backend = createMockBackend();
186
+ registerStoreTools(registry, [ALERTS_STORE], backend, 'test-app');
187
+ expect(registry.names()).toContain('store_alerts');
188
+ expect(registry.names()).toContain('store_alerts_batch');
189
+ expect(registry.names()).toContain(QUERY_STORE_TOOL_NAME);
190
+ expect(registry.size).toBe(3);
191
+ });
192
+ it('registers tools for multiple stores', () => {
193
+ const registry = createToolRegistry();
194
+ const backend = createMockBackend();
195
+ const secondStore = {
196
+ ...ALERTS_STORE,
197
+ name: 'incidents',
198
+ entity: { ...ALERTS_STORE.entity, name: 'Incident', key: '{id}', schema: { id: { type: 'string' } } },
199
+ };
200
+ registerStoreTools(registry, [ALERTS_STORE, secondStore], backend, 'test-app');
201
+ expect(registry.names()).toContain('store_alerts');
202
+ expect(registry.names()).toContain('store_alerts_batch');
203
+ expect(registry.names()).toContain('store_incidents');
204
+ expect(registry.names()).toContain('store_incidents_batch');
205
+ expect(registry.names()).toContain(QUERY_STORE_TOOL_NAME);
206
+ expect(registry.size).toBe(5);
207
+ });
208
+ it('does not register query tool when no stores', () => {
209
+ const registry = createToolRegistry();
210
+ const backend = createMockBackend();
211
+ registerStoreTools(registry, [], backend, 'test-app');
212
+ expect(registry.size).toBe(0);
213
+ });
214
+ });
215
+ //# sourceMappingURL=store-tools.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store-tools.test.js","sourceRoot":"","sources":["../../../src/tools/store-tools.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,129 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ /**
7
+ * Tool system types for the Amodal runtime.
8
+ *
9
+ * Replaces the upstream gemini-cli-core ToolRegistry with our own that
10
+ * holds Vercel AI SDK-compatible tool definitions. Each tool has a Zod
11
+ * schema for parameter validation, an execute function, and metadata
12
+ * for permission/execution decisions.
13
+ */
14
+ import type { z } from 'zod';
15
+ import type { FlexibleSchema } from 'ai';
16
+ import type { SearchProvider } from '../providers/search-provider.js';
17
+ /**
18
+ * Context passed to every tool execute function.
19
+ *
20
+ * This is the runtime's version of the context — it provides access to
21
+ * connections, stores, logging, user info, and cancellation. Specific
22
+ * tool categories (store tools, connection tools) may wrap this with
23
+ * category-specific helpers.
24
+ */
25
+ export interface ToolContext {
26
+ /** Make an HTTP request through a configured connection */
27
+ request(connection: string, endpoint: string, params?: {
28
+ method?: string;
29
+ data?: unknown;
30
+ params?: Record<string, string>;
31
+ }): Promise<unknown>;
32
+ /** Write a document to a store */
33
+ store(storeName: string, payload: Record<string, unknown>): Promise<{
34
+ key: string;
35
+ }>;
36
+ /** Read an environment variable (only if in the tool's env allowlist) */
37
+ env(name: string): string | undefined;
38
+ /** Log a message (emitted as tool_log SSE event) */
39
+ log(message: string): void;
40
+ /** Current user info */
41
+ user: {
42
+ roles: string[];
43
+ [key: string]: unknown;
44
+ };
45
+ /** Abort signal for cancellation/timeout */
46
+ signal: AbortSignal;
47
+ /** Session ID for correlation */
48
+ sessionId: string;
49
+ /**
50
+ * Grounded search provider for `web_search` and `fetch_url` tools.
51
+ * Undefined when `webTools` is not configured in amodal.json — the
52
+ * tools return a friendly "not configured" error in that case.
53
+ */
54
+ searchProvider?: SearchProvider;
55
+ }
56
+ /** Tool category for permission lookup and UI grouping. */
57
+ export type ToolCategory = 'store' | 'connection' | 'custom' | 'mcp' | 'admin' | 'system';
58
+ /**
59
+ * Metadata attached to a tool for permission, routing, and execution decisions.
60
+ */
61
+ export interface ToolMetadata {
62
+ /** Category for permission lookup and UI grouping */
63
+ category: ToolCategory;
64
+ /** Which connection this tool belongs to (for permission lookup) */
65
+ connection?: string;
66
+ /** Source tool name before any prefixing (for MCP tools) */
67
+ originalName?: string;
68
+ }
69
+ /**
70
+ * A registered tool definition.
71
+ *
72
+ * This is what gets passed to the AI SDK's `tools` parameter and also
73
+ * drives our execution pipeline. The `parameters` schema is used both
74
+ * for LLM function calling (converted to JSON Schema) and runtime
75
+ * validation of the LLM's arguments.
76
+ */
77
+ export interface ToolDefinition<TParams = unknown> {
78
+ /** Description shown to the LLM */
79
+ description: string;
80
+ /** Schema for parameter validation — Zod schema or AI SDK jsonSchema() */
81
+ parameters: z.ZodType<TParams> | FlexibleSchema<TParams>;
82
+ /** Execute the tool with validated parameters */
83
+ execute(params: TParams, ctx: ToolContext): Promise<unknown>;
84
+ /**
85
+ * Whether this tool only reads data (no side effects).
86
+ *
87
+ * Used for:
88
+ * - Pre-execution: read-only tools can start during streaming
89
+ * - Parallel execution: read-only tools can run concurrently (Roadmap 2.5)
90
+ * - Confirmation flow: write tools may require user confirmation
91
+ */
92
+ readOnly: boolean;
93
+ /**
94
+ * Whether every call to this tool must be approved by the user.
95
+ *
96
+ * When `true`, the agent loop routes each invocation through the
97
+ * `CONFIRMING` state before executing. Approved calls are tracked per
98
+ * session by `toolCallId`, so a tool does not re-prompt after approval.
99
+ *
100
+ * Connection tools have their own ACL-based confirmation flow via
101
+ * `PermissionChecker` and should leave this undefined. Use this flag on
102
+ * store, admin, or custom tools that need a generic "destructive operation"
103
+ * gate without defining ACL rules.
104
+ */
105
+ requiresConfirmation?: boolean;
106
+ /** Optional metadata for permission, routing, and UI */
107
+ metadata?: ToolMetadata;
108
+ }
109
+ /**
110
+ * Registry holding all available tools for a session.
111
+ *
112
+ * Tools are registered at session creation time and may change across
113
+ * sessions (different agents have different tools). The registry is
114
+ * the single source of truth for what tools the LLM can call.
115
+ */
116
+ export interface ToolRegistry {
117
+ /** Register a tool. Throws if a tool with this name is already registered. */
118
+ register(name: string, def: ToolDefinition): void;
119
+ /** Get a tool by name. Returns undefined if not found. */
120
+ get(name: string): ToolDefinition | undefined;
121
+ /** Get all tools as a Record (for passing to AI SDK streamText/generateText). */
122
+ getTools(): Record<string, ToolDefinition>;
123
+ /** List all registered tool names. */
124
+ names(): string[];
125
+ /** Get a subset of tools by name (for sub-agent dispatch). */
126
+ subset(names: string[]): Record<string, ToolDefinition>;
127
+ /** Number of registered tools. */
128
+ size: number;
129
+ }
@@ -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/tools/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ /**
7
+ * web_search tool — grounded search via Gemini Flash.
8
+ *
9
+ * The tool delegates to `ctx.searchProvider.search()` (a dedicated Gemini
10
+ * provider configured via `webTools` in amodal.json), then formats the
11
+ * synthesized answer with cited source URLs as markdown.
12
+ *
13
+ * Works for agents on any main model (Anthropic/OpenAI/Google) — search
14
+ * always runs through the Gemini backend regardless of main provider.
15
+ */
16
+ import { z } from 'zod';
17
+ import { WEB_SEARCH_TOOL_NAME } from '@amodalai/core';
18
+ import type { ToolDefinition } from './types.js';
19
+ export { WEB_SEARCH_TOOL_NAME };
20
+ declare const WebSearchParamsSchema: z.ZodObject<{
21
+ query: z.ZodString;
22
+ max_results: z.ZodOptional<z.ZodNumber>;
23
+ }, "strip", z.ZodTypeAny, {
24
+ query: string;
25
+ max_results?: number | undefined;
26
+ }, {
27
+ query: string;
28
+ max_results?: number | undefined;
29
+ }>;
30
+ type WebSearchParams = z.infer<typeof WebSearchParamsSchema>;
31
+ export declare function createWebSearchTool(): ToolDefinition<WebSearchParams>;
@@ -0,0 +1,170 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ /**
7
+ * web_search tool — grounded search via Gemini Flash.
8
+ *
9
+ * The tool delegates to `ctx.searchProvider.search()` (a dedicated Gemini
10
+ * provider configured via `webTools` in amodal.json), then formats the
11
+ * synthesized answer with cited source URLs as markdown.
12
+ *
13
+ * Works for agents on any main model (Anthropic/OpenAI/Google) — search
14
+ * always runs through the Gemini backend regardless of main provider.
15
+ */
16
+ import { z } from 'zod';
17
+ import { WEB_SEARCH_TOOL_NAME } from '@amodalai/core';
18
+ import { log } from '../logger.js';
19
+ import { ProviderError, ToolExecutionError } from '../errors.js';
20
+ import { truncateToTokens, MAX_WEB_TOOL_RESULT_TOKENS } from './web-tools-shared.js';
21
+ export { WEB_SEARCH_TOOL_NAME };
22
+ // ---------------------------------------------------------------------------
23
+ // Params schema
24
+ // ---------------------------------------------------------------------------
25
+ const DEFAULT_MAX_RESULTS = 5;
26
+ const MAX_ALLOWED_RESULTS = 10;
27
+ const WebSearchParamsSchema = z.object({
28
+ query: z
29
+ .string()
30
+ .min(1)
31
+ .describe('Search query. Be specific — include dates, names, error messages as relevant.'),
32
+ max_results: z
33
+ .number()
34
+ .int()
35
+ .min(1)
36
+ .max(MAX_ALLOWED_RESULTS)
37
+ .optional()
38
+ .describe(`Maximum source citations to include (default: ${String(DEFAULT_MAX_RESULTS)}, max: ${String(MAX_ALLOWED_RESULTS)}).`),
39
+ });
40
+ /**
41
+ * Map a provider error to an actionable message for the agent. The goal is
42
+ * to let the model know whether retrying will help, so it doesn't burn
43
+ * turns retrying something that's permanently broken.
44
+ */
45
+ function classifyProviderError(err) {
46
+ const status = err.statusCode;
47
+ if (status === 400 || status === 401 || status === 403) {
48
+ return {
49
+ content: 'Web search is not authorized. The Google API key is missing, invalid, or not permitted for this model. ' +
50
+ 'DO NOT retry. Tell the user to check the GOOGLE_API_KEY configured for webTools in amodal.json.',
51
+ retryable: false,
52
+ };
53
+ }
54
+ if (status === 429) {
55
+ return {
56
+ content: 'Web search is rate-limited or the Gemini grounding quota is exhausted. ' +
57
+ 'DO NOT retry this search in the current turn. Continue with other tools or finish the task without search.',
58
+ retryable: false,
59
+ };
60
+ }
61
+ if (status !== undefined && status >= 500) {
62
+ return {
63
+ content: `Web search failed transiently (status ${String(status)}). ` +
64
+ 'You may retry once with the same or a slightly different query. If it fails again, continue without search.',
65
+ retryable: true,
66
+ };
67
+ }
68
+ return {
69
+ content: `Web search failed: ${err.message}. Do not retry without changing the query.`,
70
+ retryable: false,
71
+ };
72
+ }
73
+ // ---------------------------------------------------------------------------
74
+ // Formatting
75
+ // ---------------------------------------------------------------------------
76
+ function formatResult(text, sources, maxResults) {
77
+ const capped = sources.slice(0, maxResults);
78
+ if (capped.length === 0) {
79
+ return `${text}\n\n_(no sources cited)_`;
80
+ }
81
+ const lines = [text.trim(), '', 'Sources:'];
82
+ for (let i = 0; i < capped.length; i++) {
83
+ const source = capped[i];
84
+ if (!source)
85
+ continue;
86
+ const titlePart = source.title ? ` — ${source.title}` : '';
87
+ lines.push(`[${String(i + 1)}] ${source.uri}${titlePart}`);
88
+ }
89
+ return lines.join('\n');
90
+ }
91
+ // ---------------------------------------------------------------------------
92
+ // Factory
93
+ // ---------------------------------------------------------------------------
94
+ export function createWebSearchTool() {
95
+ return {
96
+ description: `Search the web for current information. Use when the user asks about recent events, current versions of libraries, news, or any fact you do not already know with confidence. Returns a synthesized answer with cited source URLs.
97
+
98
+ When to use:
99
+ - User asks "what is the latest/current X"
100
+ - Question about events after your knowledge cutoff
101
+ - Looking up specific facts, documentation, or error messages
102
+ - Verifying a claim with external sources
103
+
104
+ When NOT to use:
105
+ - Questions fully answerable from conversation history or knowledge files
106
+ - Internal agent workflows (use connections instead)
107
+ - Retrieving a specific URL (use fetch_url instead)
108
+
109
+ Query strategy (write queries that steer search toward authoritative sources):
110
+ - Code / library questions → include "github" or the package name (e.g. "nextjs app router github docs")
111
+ - API documentation → include the vendor name + "docs" (e.g. "stripe docs customer object")
112
+ - Version / release lookups → add "release notes" or "changelog" and the repo (e.g. "nodejs release notes site:github.com/nodejs/node")
113
+ - Error messages → paste the exact error text verbatim, no rephrasing
114
+ - Recent events → include the **current year or month** (from the currentDate in your context, not your pretraining era) to anchor the timeframe
115
+ - Ambiguous names → add a qualifier ("Python library", "JavaScript", the vendor) so the model searches the right thing
116
+
117
+ If the first query returns off-topic results, rewrite more specifically and search again — don't guess.`,
118
+ parameters: WebSearchParamsSchema,
119
+ readOnly: true,
120
+ metadata: { category: 'system' },
121
+ async execute(params, ctx) {
122
+ const maxResults = params.max_results ?? DEFAULT_MAX_RESULTS;
123
+ if (!ctx.searchProvider) {
124
+ return {
125
+ status: 'error',
126
+ content: 'Web search is not configured. Set `webTools.apiKey` in amodal.json to enable web_search.',
127
+ };
128
+ }
129
+ const started = Date.now();
130
+ try {
131
+ const result = await ctx.searchProvider.search(params.query, { signal: ctx.signal });
132
+ const formatted = formatResult(result.text, result.sources, maxResults);
133
+ const content = truncateToTokens(formatted, MAX_WEB_TOOL_RESULT_TOKENS);
134
+ log.info('web_search', {
135
+ session: ctx.sessionId,
136
+ query_length: params.query.length,
137
+ result_count: result.sources.length,
138
+ duration_ms: Date.now() - started,
139
+ });
140
+ return {
141
+ status: 'ok',
142
+ content,
143
+ source_count: Math.min(result.sources.length, maxResults),
144
+ };
145
+ }
146
+ catch (err) {
147
+ log.error('web_search_failed', {
148
+ session: ctx.sessionId,
149
+ query_length: params.query.length,
150
+ duration_ms: Date.now() - started,
151
+ status_code: err instanceof ProviderError ? err.statusCode : undefined,
152
+ error: err instanceof Error ? err.message : String(err),
153
+ });
154
+ // Return structured guidance for provider errors so the agent
155
+ // knows whether to retry. Unexpected errors still throw — those
156
+ // are bugs, not runtime conditions.
157
+ if (err instanceof ProviderError) {
158
+ const { content, retryable } = classifyProviderError(err);
159
+ return { status: 'error', content, retryable };
160
+ }
161
+ throw new ToolExecutionError('web_search failed', {
162
+ toolName: WEB_SEARCH_TOOL_NAME,
163
+ callId: ctx.sessionId,
164
+ cause: err,
165
+ });
166
+ }
167
+ },
168
+ };
169
+ }
170
+ //# sourceMappingURL=web-search-tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web-search-tool.js","sourceRoot":"","sources":["../../../src/tools/web-search-tool.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 {};