@m4ike1/ion-coding-agent 0.1.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 (1126) hide show
  1. package/CHANGELOG.md +5747 -0
  2. package/README.md +738 -0
  3. package/dist/bun/cli.d.ts +5 -0
  4. package/dist/bun/cli.d.ts.map +1 -0
  5. package/dist/bun/cli.js +5 -0
  6. package/dist/bun/cli.js.map +1 -0
  7. package/dist/bun/restore-sandbox-env.d.ts +17 -0
  8. package/dist/bun/restore-sandbox-env.d.ts.map +1 -0
  9. package/dist/bun/restore-sandbox-env.js +36 -0
  10. package/dist/bun/restore-sandbox-env.js.map +1 -0
  11. package/dist/bun/runtime-setup.d.ts +2 -0
  12. package/dist/bun/runtime-setup.d.ts.map +1 -0
  13. package/dist/bun/runtime-setup.js +9 -0
  14. package/dist/bun/runtime-setup.js.map +1 -0
  15. package/dist/bun/sandbox-env-setup.d.ts +2 -0
  16. package/dist/bun/sandbox-env-setup.d.ts.map +1 -0
  17. package/dist/bun/sandbox-env-setup.js +4 -0
  18. package/dist/bun/sandbox-env-setup.js.map +1 -0
  19. package/dist/bundle/chunks/anthropic-messages-RPVA4Z4Y.js +6 -0
  20. package/dist/bundle/chunks/anthropic.js +75 -0
  21. package/dist/bundle/chunks/azure-openai-responses-AJS3XTKL.js +2 -0
  22. package/dist/bundle/chunks/bedrock-converse-stream.js +78 -0
  23. package/dist/bundle/chunks/chunk-2MOZ6JBC.js +2 -0
  24. package/dist/bundle/chunks/chunk-3BIJ3AQO.js +12 -0
  25. package/dist/bundle/chunks/chunk-47K3I3YT.js +6 -0
  26. package/dist/bundle/chunks/chunk-4BN67GCJ.js +1664 -0
  27. package/dist/bundle/chunks/chunk-4PN6UIWX.js +2 -0
  28. package/dist/bundle/chunks/chunk-4TQA6ATT.js +4 -0
  29. package/dist/bundle/chunks/chunk-5NVSYJOG.js +2 -0
  30. package/dist/bundle/chunks/chunk-7OJL7DR5.js +2 -0
  31. package/dist/bundle/chunks/chunk-BEER2HEL.js +2 -0
  32. package/dist/bundle/chunks/chunk-CQX3HQAT.js +2 -0
  33. package/dist/bundle/chunks/chunk-FBMFFBV2.js +2 -0
  34. package/dist/bundle/chunks/chunk-GAZIWLQB.js +2 -0
  35. package/dist/bundle/chunks/chunk-HFYRAIWC.js +44 -0
  36. package/dist/bundle/chunks/chunk-IH7HUXWH.js +2 -0
  37. package/dist/bundle/chunks/chunk-LPP2XRBR.js +11 -0
  38. package/dist/bundle/chunks/chunk-LUTYILPM.js +25 -0
  39. package/dist/bundle/chunks/chunk-Q3ZNVFWD.js +42 -0
  40. package/dist/bundle/chunks/chunk-QNBVCBN3.js +2 -0
  41. package/dist/bundle/chunks/chunk-SWVWKUIA.js +2 -0
  42. package/dist/bundle/chunks/chunk-SY4QP6EI.js +2 -0
  43. package/dist/bundle/chunks/chunk-TVAWBPPS.js +2 -0
  44. package/dist/bundle/chunks/chunk-WPN6KEON.js +2 -0
  45. package/dist/bundle/chunks/chunk-WRID246J.js +2 -0
  46. package/dist/bundle/chunks/github-copilot.js +2 -0
  47. package/dist/bundle/chunks/google-generative-ai-S7SD5HC7.js +2 -0
  48. package/dist/bundle/chunks/google-vertex-NUNHA7QM.js +2 -0
  49. package/dist/bundle/chunks/https-proxy-agent-O2332S4O.js +13 -0
  50. package/dist/bundle/chunks/image-resize-worker.js +2 -0
  51. package/dist/bundle/chunks/ion-messages-KTW6MD7U.js +8 -0
  52. package/dist/bundle/chunks/kimi-coding.js +2 -0
  53. package/dist/bundle/chunks/lib-D4EQQPRR.js +9 -0
  54. package/dist/bundle/chunks/mistral-conversations-C7I3G2LA.js +5 -0
  55. package/dist/bundle/chunks/multipart-parser-PL2BXRDT.js +3 -0
  56. package/dist/bundle/chunks/node-7OQEATQA.js +2 -0
  57. package/dist/bundle/chunks/node-QIUI6CIW.js +16 -0
  58. package/dist/bundle/chunks/openai-codex-responses-2KRULDYR.js +10 -0
  59. package/dist/bundle/chunks/openai-codex.js +75 -0
  60. package/dist/bundle/chunks/openai-completions-64KX63FN.js +7 -0
  61. package/dist/bundle/chunks/openai-responses-QF3PPSTS.js +2 -0
  62. package/dist/bundle/chunks/openrouter-images-GQVXT3PO.js +2 -0
  63. package/dist/bundle/chunks/openrouter.js +75 -0
  64. package/dist/bundle/chunks/radius.js +75 -0
  65. package/dist/bundle/chunks/src-AZ7LBHGY.js +4 -0
  66. package/dist/bundle/chunks/xai.js +2 -0
  67. package/dist/bundle/cli.js +3 -0
  68. package/dist/bundle/index.js +2 -0
  69. package/dist/bundle/rpc-entry.js +3 -0
  70. package/dist/cli/args.d.ts +61 -0
  71. package/dist/cli/args.d.ts.map +1 -0
  72. package/dist/cli/args.js +440 -0
  73. package/dist/cli/args.js.map +1 -0
  74. package/dist/cli/auth-check.d.ts +19 -0
  75. package/dist/cli/auth-check.d.ts.map +1 -0
  76. package/dist/cli/auth-check.js +50 -0
  77. package/dist/cli/auth-check.js.map +1 -0
  78. package/dist/cli/auth-command.d.ts +24 -0
  79. package/dist/cli/auth-command.d.ts.map +1 -0
  80. package/dist/cli/auth-command.js +103 -0
  81. package/dist/cli/auth-command.js.map +1 -0
  82. package/dist/cli/config-selector.d.ts +16 -0
  83. package/dist/cli/config-selector.d.ts.map +1 -0
  84. package/dist/cli/config-selector.js +32 -0
  85. package/dist/cli/config-selector.js.map +1 -0
  86. package/dist/cli/credential-print.d.ts +13 -0
  87. package/dist/cli/credential-print.d.ts.map +1 -0
  88. package/dist/cli/credential-print.js +76 -0
  89. package/dist/cli/credential-print.js.map +1 -0
  90. package/dist/cli/file-processor.d.ts +15 -0
  91. package/dist/cli/file-processor.d.ts.map +1 -0
  92. package/dist/cli/file-processor.js +71 -0
  93. package/dist/cli/file-processor.js.map +1 -0
  94. package/dist/cli/initial-message.d.ts +18 -0
  95. package/dist/cli/initial-message.d.ts.map +1 -0
  96. package/dist/cli/initial-message.js +22 -0
  97. package/dist/cli/initial-message.js.map +1 -0
  98. package/dist/cli/list-models.d.ts +9 -0
  99. package/dist/cli/list-models.d.ts.map +1 -0
  100. package/dist/cli/list-models.js +98 -0
  101. package/dist/cli/list-models.js.map +1 -0
  102. package/dist/cli/project-trust.d.ts +10 -0
  103. package/dist/cli/project-trust.d.ts.map +1 -0
  104. package/dist/cli/project-trust.js +48 -0
  105. package/dist/cli/project-trust.js.map +1 -0
  106. package/dist/cli/session-picker.d.ts +10 -0
  107. package/dist/cli/session-picker.d.ts.map +1 -0
  108. package/dist/cli/session-picker.js +36 -0
  109. package/dist/cli/session-picker.js.map +1 -0
  110. package/dist/cli/setup.d.ts +2 -0
  111. package/dist/cli/setup.d.ts.map +1 -0
  112. package/dist/cli/setup.js +12 -0
  113. package/dist/cli/setup.js.map +1 -0
  114. package/dist/cli/startup-ui.d.ts +20 -0
  115. package/dist/cli/startup-ui.d.ts.map +1 -0
  116. package/dist/cli/startup-ui.js +185 -0
  117. package/dist/cli/startup-ui.js.map +1 -0
  118. package/dist/cli.d.ts +3 -0
  119. package/dist/cli.d.ts.map +1 -0
  120. package/dist/cli.js +6 -0
  121. package/dist/cli.js.map +1 -0
  122. package/dist/config.d.ts +122 -0
  123. package/dist/config.d.ts.map +1 -0
  124. package/dist/config.js +609 -0
  125. package/dist/config.js.map +1 -0
  126. package/dist/core/agent-session-runtime.d.ts +119 -0
  127. package/dist/core/agent-session-runtime.d.ts.map +1 -0
  128. package/dist/core/agent-session-runtime.js +317 -0
  129. package/dist/core/agent-session-runtime.js.map +1 -0
  130. package/dist/core/agent-session-services.d.ts +86 -0
  131. package/dist/core/agent-session-services.d.ts.map +1 -0
  132. package/dist/core/agent-session-services.js +134 -0
  133. package/dist/core/agent-session-services.js.map +1 -0
  134. package/dist/core/agent-session.d.ts +725 -0
  135. package/dist/core/agent-session.d.ts.map +1 -0
  136. package/dist/core/agent-session.js +2968 -0
  137. package/dist/core/agent-session.js.map +1 -0
  138. package/dist/core/auth-guidance.d.ts +5 -0
  139. package/dist/core/auth-guidance.d.ts.map +1 -0
  140. package/dist/core/auth-guidance.js +21 -0
  141. package/dist/core/auth-guidance.js.map +1 -0
  142. package/dist/core/auth-storage.d.ts +72 -0
  143. package/dist/core/auth-storage.d.ts.map +1 -0
  144. package/dist/core/auth-storage.js +426 -0
  145. package/dist/core/auth-storage.js.map +1 -0
  146. package/dist/core/bash-executor.d.ts +32 -0
  147. package/dist/core/bash-executor.d.ts.map +1 -0
  148. package/dist/core/bash-executor.js +111 -0
  149. package/dist/core/bash-executor.js.map +1 -0
  150. package/dist/core/cache-stats.d.ts +49 -0
  151. package/dist/core/cache-stats.d.ts.map +1 -0
  152. package/dist/core/cache-stats.js +101 -0
  153. package/dist/core/cache-stats.js.map +1 -0
  154. package/dist/core/compaction/branch-summarization.d.ts +98 -0
  155. package/dist/core/compaction/branch-summarization.d.ts.map +1 -0
  156. package/dist/core/compaction/branch-summarization.js +251 -0
  157. package/dist/core/compaction/branch-summarization.js.map +1 -0
  158. package/dist/core/compaction/compaction.d.ts +145 -0
  159. package/dist/core/compaction/compaction.d.ts.map +1 -0
  160. package/dist/core/compaction/compaction.js +690 -0
  161. package/dist/core/compaction/compaction.js.map +1 -0
  162. package/dist/core/compaction/index.d.ts +7 -0
  163. package/dist/core/compaction/index.d.ts.map +1 -0
  164. package/dist/core/compaction/index.js +7 -0
  165. package/dist/core/compaction/index.js.map +1 -0
  166. package/dist/core/compaction/utils.d.ts +38 -0
  167. package/dist/core/compaction/utils.d.ts.map +1 -0
  168. package/dist/core/compaction/utils.js +142 -0
  169. package/dist/core/compaction/utils.js.map +1 -0
  170. package/dist/core/defaults.d.ts +4 -0
  171. package/dist/core/defaults.d.ts.map +1 -0
  172. package/dist/core/defaults.js +11 -0
  173. package/dist/core/defaults.js.map +1 -0
  174. package/dist/core/diagnostics.d.ts +15 -0
  175. package/dist/core/diagnostics.d.ts.map +1 -0
  176. package/dist/core/diagnostics.js +2 -0
  177. package/dist/core/diagnostics.js.map +1 -0
  178. package/dist/core/event-bus.d.ts +9 -0
  179. package/dist/core/event-bus.d.ts.map +1 -0
  180. package/dist/core/event-bus.js +25 -0
  181. package/dist/core/event-bus.js.map +1 -0
  182. package/dist/core/exec.d.ts +29 -0
  183. package/dist/core/exec.d.ts.map +1 -0
  184. package/dist/core/exec.js +75 -0
  185. package/dist/core/exec.js.map +1 -0
  186. package/dist/core/experimental.d.ts +2 -0
  187. package/dist/core/experimental.d.ts.map +1 -0
  188. package/dist/core/experimental.js +4 -0
  189. package/dist/core/experimental.js.map +1 -0
  190. package/dist/core/export-html/ansi-to-html.d.ts +22 -0
  191. package/dist/core/export-html/ansi-to-html.d.ts.map +1 -0
  192. package/dist/core/export-html/ansi-to-html.js +249 -0
  193. package/dist/core/export-html/ansi-to-html.js.map +1 -0
  194. package/dist/core/export-html/index.d.ts +37 -0
  195. package/dist/core/export-html/index.d.ts.map +1 -0
  196. package/dist/core/export-html/index.js +226 -0
  197. package/dist/core/export-html/index.js.map +1 -0
  198. package/dist/core/export-html/template.css +1066 -0
  199. package/dist/core/export-html/template.html +55 -0
  200. package/dist/core/export-html/template.js +1871 -0
  201. package/dist/core/export-html/tool-renderer.d.ts +34 -0
  202. package/dist/core/export-html/tool-renderer.d.ts.map +1 -0
  203. package/dist/core/export-html/tool-renderer.js +108 -0
  204. package/dist/core/export-html/tool-renderer.js.map +1 -0
  205. package/dist/core/export-html/vendor/highlight.min.js +1213 -0
  206. package/dist/core/export-html/vendor/marked.min.js +78 -0
  207. package/dist/core/extensions/index.d.ts +12 -0
  208. package/dist/core/extensions/index.d.ts.map +1 -0
  209. package/dist/core/extensions/index.js +9 -0
  210. package/dist/core/extensions/index.js.map +1 -0
  211. package/dist/core/extensions/loader.d.ts +23 -0
  212. package/dist/core/extensions/loader.d.ts.map +1 -0
  213. package/dist/core/extensions/loader.js +655 -0
  214. package/dist/core/extensions/loader.js.map +1 -0
  215. package/dist/core/extensions/runner.d.ts +178 -0
  216. package/dist/core/extensions/runner.d.ts.map +1 -0
  217. package/dist/core/extensions/runner.js +1011 -0
  218. package/dist/core/extensions/runner.js.map +1 -0
  219. package/dist/core/extensions/types.d.ts +1375 -0
  220. package/dist/core/extensions/types.d.ts.map +1 -0
  221. package/dist/core/extensions/types.js +54 -0
  222. package/dist/core/extensions/types.js.map +1 -0
  223. package/dist/core/extensions/wrapper.d.ts +20 -0
  224. package/dist/core/extensions/wrapper.d.ts.map +1 -0
  225. package/dist/core/extensions/wrapper.js +41 -0
  226. package/dist/core/extensions/wrapper.js.map +1 -0
  227. package/dist/core/footer-data-provider.d.ts +64 -0
  228. package/dist/core/footer-data-provider.d.ts.map +1 -0
  229. package/dist/core/footer-data-provider.js +338 -0
  230. package/dist/core/footer-data-provider.js.map +1 -0
  231. package/dist/core/http-dispatcher.d.ts +22 -0
  232. package/dist/core/http-dispatcher.d.ts.map +1 -0
  233. package/dist/core/http-dispatcher.js +98 -0
  234. package/dist/core/http-dispatcher.js.map +1 -0
  235. package/dist/core/index.d.ts +13 -0
  236. package/dist/core/index.d.ts.map +1 -0
  237. package/dist/core/index.js +13 -0
  238. package/dist/core/index.js.map +1 -0
  239. package/dist/core/ion-manifest.d.ts +8 -0
  240. package/dist/core/ion-manifest.d.ts.map +1 -0
  241. package/dist/core/ion-manifest.js +26 -0
  242. package/dist/core/ion-manifest.js.map +1 -0
  243. package/dist/core/keybindings.d.ts +475 -0
  244. package/dist/core/keybindings.d.ts.map +1 -0
  245. package/dist/core/keybindings.js +321 -0
  246. package/dist/core/keybindings.js.map +1 -0
  247. package/dist/core/messages.d.ts +77 -0
  248. package/dist/core/messages.d.ts.map +1 -0
  249. package/dist/core/messages.js +123 -0
  250. package/dist/core/messages.js.map +1 -0
  251. package/dist/core/model-config.d.ts +591 -0
  252. package/dist/core/model-config.d.ts.map +1 -0
  253. package/dist/core/model-config.js +259 -0
  254. package/dist/core/model-config.js.map +1 -0
  255. package/dist/core/model-registry.d.ts +49 -0
  256. package/dist/core/model-registry.d.ts.map +1 -0
  257. package/dist/core/model-registry.js +115 -0
  258. package/dist/core/model-registry.js.map +1 -0
  259. package/dist/core/model-resolver.d.ts +124 -0
  260. package/dist/core/model-resolver.d.ts.map +1 -0
  261. package/dist/core/model-resolver.js +591 -0
  262. package/dist/core/model-resolver.js.map +1 -0
  263. package/dist/core/model-runtime.d.ts +101 -0
  264. package/dist/core/model-runtime.d.ts.map +1 -0
  265. package/dist/core/model-runtime.js +606 -0
  266. package/dist/core/model-runtime.js.map +1 -0
  267. package/dist/core/models-store.d.ts +22 -0
  268. package/dist/core/models-store.d.ts.map +1 -0
  269. package/dist/core/models-store.js +115 -0
  270. package/dist/core/models-store.js.map +1 -0
  271. package/dist/core/output-guard.d.ts +7 -0
  272. package/dist/core/output-guard.d.ts.map +1 -0
  273. package/dist/core/output-guard.js +89 -0
  274. package/dist/core/output-guard.js.map +1 -0
  275. package/dist/core/package-manager.d.ts +216 -0
  276. package/dist/core/package-manager.d.ts.map +1 -0
  277. package/dist/core/package-manager.js +2207 -0
  278. package/dist/core/package-manager.js.map +1 -0
  279. package/dist/core/project-trust.d.ts +15 -0
  280. package/dist/core/project-trust.d.ts.map +1 -0
  281. package/dist/core/project-trust.js +59 -0
  282. package/dist/core/project-trust.js.map +1 -0
  283. package/dist/core/prompt-templates.d.ts +54 -0
  284. package/dist/core/prompt-templates.d.ts.map +1 -0
  285. package/dist/core/prompt-templates.js +236 -0
  286. package/dist/core/prompt-templates.js.map +1 -0
  287. package/dist/core/provider-attribution.d.ts +4 -0
  288. package/dist/core/provider-attribution.d.ts.map +1 -0
  289. package/dist/core/provider-attribution.js +72 -0
  290. package/dist/core/provider-attribution.js.map +1 -0
  291. package/dist/core/provider-composer.d.ts +58 -0
  292. package/dist/core/provider-composer.d.ts.map +1 -0
  293. package/dist/core/provider-composer.js +402 -0
  294. package/dist/core/provider-composer.js.map +1 -0
  295. package/dist/core/radius.d.ts +2 -0
  296. package/dist/core/radius.d.ts.map +1 -0
  297. package/dist/core/radius.js +2 -0
  298. package/dist/core/radius.js.map +1 -0
  299. package/dist/core/remote-catalog-provider.d.ts +5 -0
  300. package/dist/core/remote-catalog-provider.d.ts.map +1 -0
  301. package/dist/core/remote-catalog-provider.js +137 -0
  302. package/dist/core/remote-catalog-provider.js.map +1 -0
  303. package/dist/core/resolve-config-value.d.ts +30 -0
  304. package/dist/core/resolve-config-value.d.ts.map +1 -0
  305. package/dist/core/resolve-config-value.js +247 -0
  306. package/dist/core/resolve-config-value.js.map +1 -0
  307. package/dist/core/resource-loader.d.ts +221 -0
  308. package/dist/core/resource-loader.d.ts.map +1 -0
  309. package/dist/core/resource-loader.js +875 -0
  310. package/dist/core/resource-loader.js.map +1 -0
  311. package/dist/core/runtime-credentials.d.ts +15 -0
  312. package/dist/core/runtime-credentials.d.ts.map +1 -0
  313. package/dist/core/runtime-credentials.js +39 -0
  314. package/dist/core/runtime-credentials.js.map +1 -0
  315. package/dist/core/sdk.d.ts +108 -0
  316. package/dist/core/sdk.d.ts.map +1 -0
  317. package/dist/core/sdk.js +285 -0
  318. package/dist/core/sdk.js.map +1 -0
  319. package/dist/core/session-cwd.d.ts +19 -0
  320. package/dist/core/session-cwd.d.ts.map +1 -0
  321. package/dist/core/session-cwd.js +38 -0
  322. package/dist/core/session-cwd.js.map +1 -0
  323. package/dist/core/session-export.d.ts +4 -0
  324. package/dist/core/session-export.d.ts.map +1 -0
  325. package/dist/core/session-export.js +32 -0
  326. package/dist/core/session-export.js.map +1 -0
  327. package/dist/core/session-index.d.ts +67 -0
  328. package/dist/core/session-index.d.ts.map +1 -0
  329. package/dist/core/session-index.js +376 -0
  330. package/dist/core/session-index.js.map +1 -0
  331. package/dist/core/session-manager.d.ts +376 -0
  332. package/dist/core/session-manager.d.ts.map +1 -0
  333. package/dist/core/session-manager.js +1587 -0
  334. package/dist/core/session-manager.js.map +1 -0
  335. package/dist/core/session-naming-runtime.d.ts +153 -0
  336. package/dist/core/session-naming-runtime.d.ts.map +1 -0
  337. package/dist/core/session-naming-runtime.js +336 -0
  338. package/dist/core/session-naming-runtime.js.map +1 -0
  339. package/dist/core/settings-diagnostics.d.ts +9 -0
  340. package/dist/core/settings-diagnostics.d.ts.map +1 -0
  341. package/dist/core/settings-diagnostics.js +21 -0
  342. package/dist/core/settings-diagnostics.js.map +1 -0
  343. package/dist/core/settings-manager.d.ts +375 -0
  344. package/dist/core/settings-manager.d.ts.map +1 -0
  345. package/dist/core/settings-manager.js +1110 -0
  346. package/dist/core/settings-manager.js.map +1 -0
  347. package/dist/core/skills.d.ts +60 -0
  348. package/dist/core/skills.d.ts.map +1 -0
  349. package/dist/core/skills.js +412 -0
  350. package/dist/core/skills.js.map +1 -0
  351. package/dist/core/slash-commands.d.ts +17 -0
  352. package/dist/core/slash-commands.d.ts.map +1 -0
  353. package/dist/core/slash-commands.js +33 -0
  354. package/dist/core/slash-commands.js.map +1 -0
  355. package/dist/core/source-info.d.ts +18 -0
  356. package/dist/core/source-info.d.ts.map +1 -0
  357. package/dist/core/source-info.js +19 -0
  358. package/dist/core/source-info.js.map +1 -0
  359. package/dist/core/system-prompt.d.ts +28 -0
  360. package/dist/core/system-prompt.d.ts.map +1 -0
  361. package/dist/core/system-prompt.js +118 -0
  362. package/dist/core/system-prompt.js.map +1 -0
  363. package/dist/core/telemetry.d.ts +3 -0
  364. package/dist/core/telemetry.d.ts.map +1 -0
  365. package/dist/core/telemetry.js +9 -0
  366. package/dist/core/telemetry.js.map +1 -0
  367. package/dist/core/timings.d.ts +10 -0
  368. package/dist/core/timings.d.ts.map +1 -0
  369. package/dist/core/timings.js +41 -0
  370. package/dist/core/timings.js.map +1 -0
  371. package/dist/core/tools/bash.d.ts +87 -0
  372. package/dist/core/tools/bash.d.ts.map +1 -0
  373. package/dist/core/tools/bash.js +295 -0
  374. package/dist/core/tools/bash.js.map +1 -0
  375. package/dist/core/tools/edit-diff.d.ts +101 -0
  376. package/dist/core/tools/edit-diff.d.ts.map +1 -0
  377. package/dist/core/tools/edit-diff.js +421 -0
  378. package/dist/core/tools/edit-diff.js.map +1 -0
  379. package/dist/core/tools/edit.d.ts +44 -0
  380. package/dist/core/tools/edit.d.ts.map +1 -0
  381. package/dist/core/tools/edit.js +147 -0
  382. package/dist/core/tools/edit.js.map +1 -0
  383. package/dist/core/tools/file-mutation-queue.d.ts +6 -0
  384. package/dist/core/tools/file-mutation-queue.d.ts.map +1 -0
  385. package/dist/core/tools/file-mutation-queue.js +52 -0
  386. package/dist/core/tools/file-mutation-queue.js.map +1 -0
  387. package/dist/core/tools/find.d.ts +42 -0
  388. package/dist/core/tools/find.d.ts.map +1 -0
  389. package/dist/core/tools/find.js +251 -0
  390. package/dist/core/tools/find.js.map +1 -0
  391. package/dist/core/tools/grep.d.ts +53 -0
  392. package/dist/core/tools/grep.d.ts.map +1 -0
  393. package/dist/core/tools/grep.js +463 -0
  394. package/dist/core/tools/grep.js.map +1 -0
  395. package/dist/core/tools/index.d.ts +49 -0
  396. package/dist/core/tools/index.d.ts.map +1 -0
  397. package/dist/core/tools/index.js +147 -0
  398. package/dist/core/tools/index.js.map +1 -0
  399. package/dist/core/tools/ls.d.ts +48 -0
  400. package/dist/core/tools/ls.d.ts.map +1 -0
  401. package/dist/core/tools/ls.js +224 -0
  402. package/dist/core/tools/ls.js.map +1 -0
  403. package/dist/core/tools/output-accumulator.d.ts +52 -0
  404. package/dist/core/tools/output-accumulator.d.ts.map +1 -0
  405. package/dist/core/tools/output-accumulator.js +184 -0
  406. package/dist/core/tools/output-accumulator.js.map +1 -0
  407. package/dist/core/tools/path-utils.d.ts +10 -0
  408. package/dist/core/tools/path-utils.d.ts.map +1 -0
  409. package/dist/core/tools/path-utils.js +99 -0
  410. package/dist/core/tools/path-utils.js.map +1 -0
  411. package/dist/core/tools/powershell.d.ts +16 -0
  412. package/dist/core/tools/powershell.d.ts.map +1 -0
  413. package/dist/core/tools/powershell.js +39 -0
  414. package/dist/core/tools/powershell.js.map +1 -0
  415. package/dist/core/tools/read.d.ts +39 -0
  416. package/dist/core/tools/read.d.ts.map +1 -0
  417. package/dist/core/tools/read.js +165 -0
  418. package/dist/core/tools/read.js.map +1 -0
  419. package/dist/core/tools/render-utils.d.ts +24 -0
  420. package/dist/core/tools/render-utils.d.ts.map +1 -0
  421. package/dist/core/tools/render-utils.js +65 -0
  422. package/dist/core/tools/render-utils.js.map +1 -0
  423. package/dist/core/tools/renderers/bash.d.ts +12 -0
  424. package/dist/core/tools/renderers/bash.d.ts.map +1 -0
  425. package/dist/core/tools/renderers/bash.js +130 -0
  426. package/dist/core/tools/renderers/bash.js.map +1 -0
  427. package/dist/core/tools/renderers/edit.d.ts +23 -0
  428. package/dist/core/tools/renderers/edit.d.ts.map +1 -0
  429. package/dist/core/tools/renderers/edit.js +167 -0
  430. package/dist/core/tools/renderers/edit.js.map +1 -0
  431. package/dist/core/tools/renderers/find.d.ts +10 -0
  432. package/dist/core/tools/renderers/find.d.ts.map +1 -0
  433. package/dist/core/tools/renderers/find.js +64 -0
  434. package/dist/core/tools/renderers/find.js.map +1 -0
  435. package/dist/core/tools/renderers/grep.d.ts +10 -0
  436. package/dist/core/tools/renderers/grep.d.ts.map +1 -0
  437. package/dist/core/tools/renderers/grep.js +69 -0
  438. package/dist/core/tools/renderers/grep.js.map +1 -0
  439. package/dist/core/tools/renderers/index.d.ts +29 -0
  440. package/dist/core/tools/renderers/index.d.ts.map +1 -0
  441. package/dist/core/tools/renderers/index.js +50 -0
  442. package/dist/core/tools/renderers/index.js.map +1 -0
  443. package/dist/core/tools/renderers/ls.d.ts +10 -0
  444. package/dist/core/tools/renderers/ls.d.ts.map +1 -0
  445. package/dist/core/tools/renderers/ls.js +66 -0
  446. package/dist/core/tools/renderers/ls.js.map +1 -0
  447. package/dist/core/tools/renderers/read.d.ts +11 -0
  448. package/dist/core/tools/renderers/read.d.ts.map +1 -0
  449. package/dist/core/tools/renderers/read.js +129 -0
  450. package/dist/core/tools/renderers/read.js.map +1 -0
  451. package/dist/core/tools/renderers/webfetch.d.ts +11 -0
  452. package/dist/core/tools/renderers/webfetch.d.ts.map +1 -0
  453. package/dist/core/tools/renderers/webfetch.js +89 -0
  454. package/dist/core/tools/renderers/webfetch.js.map +1 -0
  455. package/dist/core/tools/renderers/write.d.ts +10 -0
  456. package/dist/core/tools/renderers/write.d.ts.map +1 -0
  457. package/dist/core/tools/renderers/write.js +153 -0
  458. package/dist/core/tools/renderers/write.js.map +1 -0
  459. package/dist/core/tools/tool-definition-wrapper.d.ts +14 -0
  460. package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -0
  461. package/dist/core/tools/tool-definition-wrapper.js +36 -0
  462. package/dist/core/tools/tool-definition-wrapper.js.map +1 -0
  463. package/dist/core/tools/truncate.d.ts +70 -0
  464. package/dist/core/tools/truncate.d.ts.map +1 -0
  465. package/dist/core/tools/truncate.js +215 -0
  466. package/dist/core/tools/truncate.js.map +1 -0
  467. package/dist/core/tools/webextract.d.ts +36 -0
  468. package/dist/core/tools/webextract.d.ts.map +1 -0
  469. package/dist/core/tools/webextract.js +130 -0
  470. package/dist/core/tools/webextract.js.map +1 -0
  471. package/dist/core/tools/webfetch.d.ts +104 -0
  472. package/dist/core/tools/webfetch.d.ts.map +1 -0
  473. package/dist/core/tools/webfetch.js +231 -0
  474. package/dist/core/tools/webfetch.js.map +1 -0
  475. package/dist/core/tools/write.d.ts +30 -0
  476. package/dist/core/tools/write.d.ts.map +1 -0
  477. package/dist/core/tools/write.js +61 -0
  478. package/dist/core/tools/write.js.map +1 -0
  479. package/dist/core/trust-manager.d.ts +36 -0
  480. package/dist/core/trust-manager.d.ts.map +1 -0
  481. package/dist/core/trust-manager.js +203 -0
  482. package/dist/core/trust-manager.js.map +1 -0
  483. package/dist/core/usage-totals.d.ts +19 -0
  484. package/dist/core/usage-totals.d.ts.map +1 -0
  485. package/dist/core/usage-totals.js +52 -0
  486. package/dist/core/usage-totals.js.map +1 -0
  487. package/dist/core/webfetch/backend-exa.d.ts +65 -0
  488. package/dist/core/webfetch/backend-exa.d.ts.map +1 -0
  489. package/dist/core/webfetch/backend-exa.js +282 -0
  490. package/dist/core/webfetch/backend-exa.js.map +1 -0
  491. package/dist/core/webfetch/backend-firecrawl.d.ts +59 -0
  492. package/dist/core/webfetch/backend-firecrawl.d.ts.map +1 -0
  493. package/dist/core/webfetch/backend-firecrawl.js +339 -0
  494. package/dist/core/webfetch/backend-firecrawl.js.map +1 -0
  495. package/dist/core/webfetch/backend-undici.d.ts +21 -0
  496. package/dist/core/webfetch/backend-undici.d.ts.map +1 -0
  497. package/dist/core/webfetch/backend-undici.js +109 -0
  498. package/dist/core/webfetch/backend-undici.js.map +1 -0
  499. package/dist/core/webfetch/backend.d.ts +45 -0
  500. package/dist/core/webfetch/backend.d.ts.map +1 -0
  501. package/dist/core/webfetch/backend.js +9 -0
  502. package/dist/core/webfetch/backend.js.map +1 -0
  503. package/dist/core/webfetch/doc-store.d.ts +45 -0
  504. package/dist/core/webfetch/doc-store.d.ts.map +1 -0
  505. package/dist/core/webfetch/doc-store.js +57 -0
  506. package/dist/core/webfetch/doc-store.js.map +1 -0
  507. package/dist/core/webfetch/guardrails.d.ts +75 -0
  508. package/dist/core/webfetch/guardrails.d.ts.map +1 -0
  509. package/dist/core/webfetch/guardrails.js +195 -0
  510. package/dist/core/webfetch/guardrails.js.map +1 -0
  511. package/dist/core/webfetch/robots.d.ts +46 -0
  512. package/dist/core/webfetch/robots.d.ts.map +1 -0
  513. package/dist/core/webfetch/robots.js +153 -0
  514. package/dist/core/webfetch/robots.js.map +1 -0
  515. package/dist/core/webfetch/search-intent.d.ts +59 -0
  516. package/dist/core/webfetch/search-intent.d.ts.map +1 -0
  517. package/dist/core/webfetch/search-intent.js +89 -0
  518. package/dist/core/webfetch/search-intent.js.map +1 -0
  519. package/dist/core/webfetch/search-tags.d.ts +23 -0
  520. package/dist/core/webfetch/search-tags.d.ts.map +1 -0
  521. package/dist/core/webfetch/search-tags.js +118 -0
  522. package/dist/core/webfetch/search-tags.js.map +1 -0
  523. package/dist/env-compat.d.ts +2 -0
  524. package/dist/env-compat.d.ts.map +1 -0
  525. package/dist/env-compat.js +17 -0
  526. package/dist/env-compat.js.map +1 -0
  527. package/dist/extensions/cue/autocomplete.d.ts +126 -0
  528. package/dist/extensions/cue/autocomplete.d.ts.map +1 -0
  529. package/dist/extensions/cue/autocomplete.js +744 -0
  530. package/dist/extensions/cue/autocomplete.js.map +1 -0
  531. package/dist/extensions/cue/index.d.ts +3 -0
  532. package/dist/extensions/cue/index.d.ts.map +1 -0
  533. package/dist/extensions/cue/index.js +341 -0
  534. package/dist/extensions/cue/index.js.map +1 -0
  535. package/dist/extensions/index.d.ts +13 -0
  536. package/dist/extensions/index.d.ts.map +1 -0
  537. package/dist/extensions/index.js +18 -0
  538. package/dist/extensions/index.js.map +1 -0
  539. package/dist/extensions/llama/client.d.ts +67 -0
  540. package/dist/extensions/llama/client.d.ts.map +1 -0
  541. package/dist/extensions/llama/client.js +309 -0
  542. package/dist/extensions/llama/client.js.map +1 -0
  543. package/dist/extensions/llama/huggingface.d.ts +23 -0
  544. package/dist/extensions/llama/huggingface.d.ts.map +1 -0
  545. package/dist/extensions/llama/huggingface.js +141 -0
  546. package/dist/extensions/llama/huggingface.js.map +1 -0
  547. package/dist/extensions/llama/index.d.ts +3 -0
  548. package/dist/extensions/llama/index.d.ts.map +1 -0
  549. package/dist/extensions/llama/index.js +219 -0
  550. package/dist/extensions/llama/index.js.map +1 -0
  551. package/dist/extensions/llama/provider.d.ts +12 -0
  552. package/dist/extensions/llama/provider.d.ts.map +1 -0
  553. package/dist/extensions/llama/provider.js +146 -0
  554. package/dist/extensions/llama/provider.js.map +1 -0
  555. package/dist/extensions/llama/ui.d.ts +42 -0
  556. package/dist/extensions/llama/ui.d.ts.map +1 -0
  557. package/dist/extensions/llama/ui.js +416 -0
  558. package/dist/extensions/llama/ui.js.map +1 -0
  559. package/dist/index.d.ts +36 -0
  560. package/dist/index.d.ts.map +1 -0
  561. package/dist/index.js +48 -0
  562. package/dist/index.js.map +1 -0
  563. package/dist/main.d.ts +17 -0
  564. package/dist/main.d.ts.map +1 -0
  565. package/dist/main.js +820 -0
  566. package/dist/main.js.map +1 -0
  567. package/dist/migrations.d.ts +33 -0
  568. package/dist/migrations.d.ts.map +1 -0
  569. package/dist/migrations.js +288 -0
  570. package/dist/migrations.js.map +1 -0
  571. package/dist/modes/index.d.ts +10 -0
  572. package/dist/modes/index.d.ts.map +1 -0
  573. package/dist/modes/index.js +8 -0
  574. package/dist/modes/index.js.map +1 -0
  575. package/dist/modes/interactive/assets/clankolas.png +0 -0
  576. package/dist/modes/interactive/chat-viewport.d.ts +20 -0
  577. package/dist/modes/interactive/chat-viewport.d.ts.map +1 -0
  578. package/dist/modes/interactive/chat-viewport.js +28 -0
  579. package/dist/modes/interactive/chat-viewport.js.map +1 -0
  580. package/dist/modes/interactive/components/armin.d.ts +34 -0
  581. package/dist/modes/interactive/components/armin.d.ts.map +1 -0
  582. package/dist/modes/interactive/components/armin.js +333 -0
  583. package/dist/modes/interactive/components/armin.js.map +1 -0
  584. package/dist/modes/interactive/components/assistant-message.d.ts +26 -0
  585. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -0
  586. package/dist/modes/interactive/components/assistant-message.js +171 -0
  587. package/dist/modes/interactive/components/assistant-message.js.map +1 -0
  588. package/dist/modes/interactive/components/bash-execution.d.ts +34 -0
  589. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -0
  590. package/dist/modes/interactive/components/bash-execution.js +175 -0
  591. package/dist/modes/interactive/components/bash-execution.js.map +1 -0
  592. package/dist/modes/interactive/components/bordered-loader.d.ts +16 -0
  593. package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -0
  594. package/dist/modes/interactive/components/bordered-loader.js +54 -0
  595. package/dist/modes/interactive/components/bordered-loader.js.map +1 -0
  596. package/dist/modes/interactive/components/branch-summary-message.d.ts +16 -0
  597. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -0
  598. package/dist/modes/interactive/components/branch-summary-message.js +44 -0
  599. package/dist/modes/interactive/components/branch-summary-message.js.map +1 -0
  600. package/dist/modes/interactive/components/compaction-summary-message.d.ts +16 -0
  601. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -0
  602. package/dist/modes/interactive/components/compaction-summary-message.js +45 -0
  603. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -0
  604. package/dist/modes/interactive/components/config-selector.d.ts +102 -0
  605. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -0
  606. package/dist/modes/interactive/components/config-selector.js +770 -0
  607. package/dist/modes/interactive/components/config-selector.js.map +1 -0
  608. package/dist/modes/interactive/components/countdown-timer.d.ts +14 -0
  609. package/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -0
  610. package/dist/modes/interactive/components/countdown-timer.js +33 -0
  611. package/dist/modes/interactive/components/countdown-timer.js.map +1 -0
  612. package/dist/modes/interactive/components/custom-editor.d.ts +30 -0
  613. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -0
  614. package/dist/modes/interactive/components/custom-editor.js +115 -0
  615. package/dist/modes/interactive/components/custom-editor.js.map +1 -0
  616. package/dist/modes/interactive/components/custom-entry.d.ts +19 -0
  617. package/dist/modes/interactive/components/custom-entry.d.ts.map +1 -0
  618. package/dist/modes/interactive/components/custom-entry.js +52 -0
  619. package/dist/modes/interactive/components/custom-entry.js.map +1 -0
  620. package/dist/modes/interactive/components/custom-message.d.ts +22 -0
  621. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -0
  622. package/dist/modes/interactive/components/custom-message.js +87 -0
  623. package/dist/modes/interactive/components/custom-message.js.map +1 -0
  624. package/dist/modes/interactive/components/daxnuts.d.ts +23 -0
  625. package/dist/modes/interactive/components/daxnuts.d.ts.map +1 -0
  626. package/dist/modes/interactive/components/daxnuts.js +140 -0
  627. package/dist/modes/interactive/components/daxnuts.js.map +1 -0
  628. package/dist/modes/interactive/components/diff.d.ts +12 -0
  629. package/dist/modes/interactive/components/diff.d.ts.map +1 -0
  630. package/dist/modes/interactive/components/diff.js +133 -0
  631. package/dist/modes/interactive/components/diff.js.map +1 -0
  632. package/dist/modes/interactive/components/dynamic-border.d.ts +15 -0
  633. package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -0
  634. package/dist/modes/interactive/components/dynamic-border.js +21 -0
  635. package/dist/modes/interactive/components/dynamic-border.js.map +1 -0
  636. package/dist/modes/interactive/components/earendil-announcement.d.ts +5 -0
  637. package/dist/modes/interactive/components/earendil-announcement.d.ts.map +1 -0
  638. package/dist/modes/interactive/components/earendil-announcement.js +40 -0
  639. package/dist/modes/interactive/components/earendil-announcement.js.map +1 -0
  640. package/dist/modes/interactive/components/extension-editor.d.ts +21 -0
  641. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -0
  642. package/dist/modes/interactive/components/extension-editor.js +98 -0
  643. package/dist/modes/interactive/components/extension-editor.js.map +1 -0
  644. package/dist/modes/interactive/components/extension-input.d.ts +23 -0
  645. package/dist/modes/interactive/components/extension-input.d.ts.map +1 -0
  646. package/dist/modes/interactive/components/extension-input.js +61 -0
  647. package/dist/modes/interactive/components/extension-input.js.map +1 -0
  648. package/dist/modes/interactive/components/extension-selector.d.ts +26 -0
  649. package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -0
  650. package/dist/modes/interactive/components/extension-selector.js +83 -0
  651. package/dist/modes/interactive/components/extension-selector.js.map +1 -0
  652. package/dist/modes/interactive/components/first-time-setup.d.ts +25 -0
  653. package/dist/modes/interactive/components/first-time-setup.d.ts.map +1 -0
  654. package/dist/modes/interactive/components/first-time-setup.js +103 -0
  655. package/dist/modes/interactive/components/first-time-setup.js.map +1 -0
  656. package/dist/modes/interactive/components/footer.d.ts +32 -0
  657. package/dist/modes/interactive/components/footer.d.ts.map +1 -0
  658. package/dist/modes/interactive/components/footer.js +230 -0
  659. package/dist/modes/interactive/components/footer.js.map +1 -0
  660. package/dist/modes/interactive/components/index.d.ts +34 -0
  661. package/dist/modes/interactive/components/index.d.ts.map +1 -0
  662. package/dist/modes/interactive/components/index.js +35 -0
  663. package/dist/modes/interactive/components/index.js.map +1 -0
  664. package/dist/modes/interactive/components/keybinding-hints.d.ts +13 -0
  665. package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -0
  666. package/dist/modes/interactive/components/keybinding-hints.js +36 -0
  667. package/dist/modes/interactive/components/keybinding-hints.js.map +1 -0
  668. package/dist/modes/interactive/components/login-dialog.d.ts +52 -0
  669. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -0
  670. package/dist/modes/interactive/components/login-dialog.js +188 -0
  671. package/dist/modes/interactive/components/login-dialog.js.map +1 -0
  672. package/dist/modes/interactive/components/markdown-transform.d.ts +3 -0
  673. package/dist/modes/interactive/components/markdown-transform.d.ts.map +1 -0
  674. package/dist/modes/interactive/components/markdown-transform.js +19 -0
  675. package/dist/modes/interactive/components/markdown-transform.js.map +1 -0
  676. package/dist/modes/interactive/components/mermaid.d.ts +11 -0
  677. package/dist/modes/interactive/components/mermaid.d.ts.map +1 -0
  678. package/dist/modes/interactive/components/mermaid.js +75 -0
  679. package/dist/modes/interactive/components/mermaid.js.map +1 -0
  680. package/dist/modes/interactive/components/model-selector.d.ts +60 -0
  681. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -0
  682. package/dist/modes/interactive/components/model-selector.js +361 -0
  683. package/dist/modes/interactive/components/model-selector.js.map +1 -0
  684. package/dist/modes/interactive/components/oauth-selector.d.ts +33 -0
  685. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -0
  686. package/dist/modes/interactive/components/oauth-selector.js +163 -0
  687. package/dist/modes/interactive/components/oauth-selector.js.map +1 -0
  688. package/dist/modes/interactive/components/scoped-models-selector.d.ts +46 -0
  689. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -0
  690. package/dist/modes/interactive/components/scoped-models-selector.js +326 -0
  691. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -0
  692. package/dist/modes/interactive/components/session-selector-search.d.ts +23 -0
  693. package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -0
  694. package/dist/modes/interactive/components/session-selector-search.js +155 -0
  695. package/dist/modes/interactive/components/session-selector-search.js.map +1 -0
  696. package/dist/modes/interactive/components/session-selector.d.ts +98 -0
  697. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -0
  698. package/dist/modes/interactive/components/session-selector.js +891 -0
  699. package/dist/modes/interactive/components/session-selector.js.map +1 -0
  700. package/dist/modes/interactive/components/settings-selector.d.ts +98 -0
  701. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -0
  702. package/dist/modes/interactive/components/settings-selector.js +745 -0
  703. package/dist/modes/interactive/components/settings-selector.js.map +1 -0
  704. package/dist/modes/interactive/components/settings-submenu.d.ts +72 -0
  705. package/dist/modes/interactive/components/settings-submenu.d.ts.map +1 -0
  706. package/dist/modes/interactive/components/settings-submenu.js +165 -0
  707. package/dist/modes/interactive/components/settings-submenu.js.map +1 -0
  708. package/dist/modes/interactive/components/show-images-selector.d.ts +10 -0
  709. package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -0
  710. package/dist/modes/interactive/components/show-images-selector.js +39 -0
  711. package/dist/modes/interactive/components/show-images-selector.js.map +1 -0
  712. package/dist/modes/interactive/components/skill-invocation-message.d.ts +17 -0
  713. package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -0
  714. package/dist/modes/interactive/components/skill-invocation-message.js +47 -0
  715. package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -0
  716. package/dist/modes/interactive/components/status-indicator.d.ts +30 -0
  717. package/dist/modes/interactive/components/status-indicator.d.ts.map +1 -0
  718. package/dist/modes/interactive/components/status-indicator.js +67 -0
  719. package/dist/modes/interactive/components/status-indicator.js.map +1 -0
  720. package/dist/modes/interactive/components/theme-selector.d.ts +11 -0
  721. package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -0
  722. package/dist/modes/interactive/components/theme-selector.js +50 -0
  723. package/dist/modes/interactive/components/theme-selector.js.map +1 -0
  724. package/dist/modes/interactive/components/thinking-selector.d.ts +23 -0
  725. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -0
  726. package/dist/modes/interactive/components/thinking-selector.js +109 -0
  727. package/dist/modes/interactive/components/thinking-selector.js.map +1 -0
  728. package/dist/modes/interactive/components/tool-execution.d.ts +80 -0
  729. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -0
  730. package/dist/modes/interactive/components/tool-execution.js +328 -0
  731. package/dist/modes/interactive/components/tool-execution.js.map +1 -0
  732. package/dist/modes/interactive/components/tree-selector.d.ts +94 -0
  733. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -0
  734. package/dist/modes/interactive/components/tree-selector.js +1245 -0
  735. package/dist/modes/interactive/components/tree-selector.js.map +1 -0
  736. package/dist/modes/interactive/components/trust-selector.d.ts +23 -0
  737. package/dist/modes/interactive/components/trust-selector.d.ts.map +1 -0
  738. package/dist/modes/interactive/components/trust-selector.js +91 -0
  739. package/dist/modes/interactive/components/trust-selector.js.map +1 -0
  740. package/dist/modes/interactive/components/user-message-selector.d.ts +30 -0
  741. package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -0
  742. package/dist/modes/interactive/components/user-message-selector.js +114 -0
  743. package/dist/modes/interactive/components/user-message-selector.js.map +1 -0
  744. package/dist/modes/interactive/components/user-message.d.ts +16 -0
  745. package/dist/modes/interactive/components/user-message.d.ts.map +1 -0
  746. package/dist/modes/interactive/components/user-message.js +49 -0
  747. package/dist/modes/interactive/components/user-message.js.map +1 -0
  748. package/dist/modes/interactive/components/visual-truncate.d.ts +24 -0
  749. package/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -0
  750. package/dist/modes/interactive/components/visual-truncate.js +33 -0
  751. package/dist/modes/interactive/components/visual-truncate.js.map +1 -0
  752. package/dist/modes/interactive/external-editor.d.ts +12 -0
  753. package/dist/modes/interactive/external-editor.d.ts.map +1 -0
  754. package/dist/modes/interactive/external-editor.js +38 -0
  755. package/dist/modes/interactive/external-editor.js.map +1 -0
  756. package/dist/modes/interactive/interactive-mode.d.ts +471 -0
  757. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -0
  758. package/dist/modes/interactive/interactive-mode.js +5735 -0
  759. package/dist/modes/interactive/interactive-mode.js.map +1 -0
  760. package/dist/modes/interactive/model-catalog-refresh.d.ts +7 -0
  761. package/dist/modes/interactive/model-catalog-refresh.d.ts.map +1 -0
  762. package/dist/modes/interactive/model-catalog-refresh.js +34 -0
  763. package/dist/modes/interactive/model-catalog-refresh.js.map +1 -0
  764. package/dist/modes/interactive/model-search.d.ts +12 -0
  765. package/dist/modes/interactive/model-search.d.ts.map +1 -0
  766. package/dist/modes/interactive/model-search.js +15 -0
  767. package/dist/modes/interactive/model-search.js.map +1 -0
  768. package/dist/modes/interactive/session-share.d.ts +16 -0
  769. package/dist/modes/interactive/session-share.d.ts.map +1 -0
  770. package/dist/modes/interactive/session-share.js +184 -0
  771. package/dist/modes/interactive/session-share.js.map +1 -0
  772. package/dist/modes/interactive/theme/dark.json +91 -0
  773. package/dist/modes/interactive/theme/light.json +90 -0
  774. package/dist/modes/interactive/theme/theme-controller.d.ts +41 -0
  775. package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -0
  776. package/dist/modes/interactive/theme/theme-controller.js +130 -0
  777. package/dist/modes/interactive/theme/theme-controller.js.map +1 -0
  778. package/dist/modes/interactive/theme/theme-json.d.ts +84 -0
  779. package/dist/modes/interactive/theme/theme-json.d.ts.map +1 -0
  780. package/dist/modes/interactive/theme/theme-json.js +130 -0
  781. package/dist/modes/interactive/theme/theme-json.js.map +1 -0
  782. package/dist/modes/interactive/theme/theme-schema.json +356 -0
  783. package/dist/modes/interactive/theme/theme.d.ts +131 -0
  784. package/dist/modes/interactive/theme/theme.d.ts.map +1 -0
  785. package/dist/modes/interactive/theme/theme.js +991 -0
  786. package/dist/modes/interactive/theme/theme.js.map +1 -0
  787. package/dist/modes/interactive/tui-renderer.d.ts +21 -0
  788. package/dist/modes/interactive/tui-renderer.d.ts.map +1 -0
  789. package/dist/modes/interactive/tui-renderer.js +66 -0
  790. package/dist/modes/interactive/tui-renderer.js.map +1 -0
  791. package/dist/modes/json-event.d.ts +34 -0
  792. package/dist/modes/json-event.d.ts.map +1 -0
  793. package/dist/modes/json-event.js +29 -0
  794. package/dist/modes/json-event.js.map +1 -0
  795. package/dist/modes/print-mode.d.ts +28 -0
  796. package/dist/modes/print-mode.d.ts.map +1 -0
  797. package/dist/modes/print-mode.js +142 -0
  798. package/dist/modes/print-mode.js.map +1 -0
  799. package/dist/modes/rpc/jsonl.d.ts +17 -0
  800. package/dist/modes/rpc/jsonl.d.ts.map +1 -0
  801. package/dist/modes/rpc/jsonl.js +49 -0
  802. package/dist/modes/rpc/jsonl.js.map +1 -0
  803. package/dist/modes/rpc/rpc-client.d.ts +254 -0
  804. package/dist/modes/rpc/rpc-client.d.ts.map +1 -0
  805. package/dist/modes/rpc/rpc-client.js +495 -0
  806. package/dist/modes/rpc/rpc-client.js.map +1 -0
  807. package/dist/modes/rpc/rpc-mode.d.ts +20 -0
  808. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -0
  809. package/dist/modes/rpc/rpc-mode.js +657 -0
  810. package/dist/modes/rpc/rpc-mode.js.map +1 -0
  811. package/dist/modes/rpc/rpc-types.d.ts +469 -0
  812. package/dist/modes/rpc/rpc-types.d.ts.map +1 -0
  813. package/dist/modes/rpc/rpc-types.js +8 -0
  814. package/dist/modes/rpc/rpc-types.js.map +1 -0
  815. package/dist/package-manager-cli.d.ts +9 -0
  816. package/dist/package-manager-cli.d.ts.map +1 -0
  817. package/dist/package-manager-cli.js +961 -0
  818. package/dist/package-manager-cli.js.map +1 -0
  819. package/dist/rpc-entry.d.ts +3 -0
  820. package/dist/rpc-entry.d.ts.map +1 -0
  821. package/dist/rpc-entry.js +12 -0
  822. package/dist/rpc-entry.js.map +1 -0
  823. package/dist/utils/abort.d.ts +5 -0
  824. package/dist/utils/abort.d.ts.map +1 -0
  825. package/dist/utils/abort.js +48 -0
  826. package/dist/utils/abort.js.map +1 -0
  827. package/dist/utils/ansi.d.ts +2 -0
  828. package/dist/utils/ansi.d.ts.map +1 -0
  829. package/dist/utils/ansi.js +52 -0
  830. package/dist/utils/ansi.js.map +1 -0
  831. package/dist/utils/changelog.d.ts +22 -0
  832. package/dist/utils/changelog.d.ts.map +1 -0
  833. package/dist/utils/changelog.js +165 -0
  834. package/dist/utils/changelog.js.map +1 -0
  835. package/dist/utils/child-process.d.ts +18 -0
  836. package/dist/utils/child-process.d.ts.map +1 -0
  837. package/dist/utils/child-process.js +106 -0
  838. package/dist/utils/child-process.js.map +1 -0
  839. package/dist/utils/clipboard-command.d.ts +7 -0
  840. package/dist/utils/clipboard-command.d.ts.map +1 -0
  841. package/dist/utils/clipboard-command.js +45 -0
  842. package/dist/utils/clipboard-command.js.map +1 -0
  843. package/dist/utils/clipboard-image.d.ts +11 -0
  844. package/dist/utils/clipboard-image.d.ts.map +1 -0
  845. package/dist/utils/clipboard-image.js +228 -0
  846. package/dist/utils/clipboard-image.js.map +1 -0
  847. package/dist/utils/clipboard.d.ts +4 -0
  848. package/dist/utils/clipboard.d.ts.map +1 -0
  849. package/dist/utils/clipboard.js +84 -0
  850. package/dist/utils/clipboard.js.map +1 -0
  851. package/dist/utils/deprecation.d.ts +4 -0
  852. package/dist/utils/deprecation.d.ts.map +1 -0
  853. package/dist/utils/deprecation.js +13 -0
  854. package/dist/utils/deprecation.js.map +1 -0
  855. package/dist/utils/exif-orientation.d.ts +5 -0
  856. package/dist/utils/exif-orientation.d.ts.map +1 -0
  857. package/dist/utils/exif-orientation.js +157 -0
  858. package/dist/utils/exif-orientation.js.map +1 -0
  859. package/dist/utils/frontmatter.d.ts +8 -0
  860. package/dist/utils/frontmatter.d.ts.map +1 -0
  861. package/dist/utils/frontmatter.js +27 -0
  862. package/dist/utils/frontmatter.js.map +1 -0
  863. package/dist/utils/fs-watch.d.ts +5 -0
  864. package/dist/utils/fs-watch.d.ts.map +1 -0
  865. package/dist/utils/fs-watch.js +25 -0
  866. package/dist/utils/fs-watch.js.map +1 -0
  867. package/dist/utils/git.d.ts +26 -0
  868. package/dist/utils/git.d.ts.map +1 -0
  869. package/dist/utils/git.js +195 -0
  870. package/dist/utils/git.js.map +1 -0
  871. package/dist/utils/html.d.ts +7 -0
  872. package/dist/utils/html.d.ts.map +1 -0
  873. package/dist/utils/html.js +40 -0
  874. package/dist/utils/html.js.map +1 -0
  875. package/dist/utils/image-convert.d.ts +10 -0
  876. package/dist/utils/image-convert.d.ts.map +1 -0
  877. package/dist/utils/image-convert.js +45 -0
  878. package/dist/utils/image-convert.js.map +1 -0
  879. package/dist/utils/image-process.d.ts +18 -0
  880. package/dist/utils/image-process.d.ts.map +1 -0
  881. package/dist/utils/image-process.js +83 -0
  882. package/dist/utils/image-process.js.map +1 -0
  883. package/dist/utils/image-resize-core.d.ts +30 -0
  884. package/dist/utils/image-resize-core.d.ts.map +1 -0
  885. package/dist/utils/image-resize-core.js +124 -0
  886. package/dist/utils/image-resize-core.js.map +1 -0
  887. package/dist/utils/image-resize-worker.d.ts +2 -0
  888. package/dist/utils/image-resize-worker.d.ts.map +1 -0
  889. package/dist/utils/image-resize-worker.js +31 -0
  890. package/dist/utils/image-resize-worker.js.map +1 -0
  891. package/dist/utils/image-resize.d.ts +16 -0
  892. package/dist/utils/image-resize.d.ts.map +1 -0
  893. package/dist/utils/image-resize.js +97 -0
  894. package/dist/utils/image-resize.js.map +1 -0
  895. package/dist/utils/ion-user-agent.d.ts +2 -0
  896. package/dist/utils/ion-user-agent.d.ts.map +1 -0
  897. package/dist/utils/ion-user-agent.js +5 -0
  898. package/dist/utils/ion-user-agent.js.map +1 -0
  899. package/dist/utils/json.d.ts +3 -0
  900. package/dist/utils/json.d.ts.map +1 -0
  901. package/dist/utils/json.js +7 -0
  902. package/dist/utils/json.js.map +1 -0
  903. package/dist/utils/management-http.d.ts +25 -0
  904. package/dist/utils/management-http.d.ts.map +1 -0
  905. package/dist/utils/management-http.js +54 -0
  906. package/dist/utils/management-http.js.map +1 -0
  907. package/dist/utils/mime.d.ts +3 -0
  908. package/dist/utils/mime.d.ts.map +1 -0
  909. package/dist/utils/mime.js +110 -0
  910. package/dist/utils/mime.js.map +1 -0
  911. package/dist/utils/open-browser.d.ts +9 -0
  912. package/dist/utils/open-browser.d.ts.map +1 -0
  913. package/dist/utils/open-browser.js +22 -0
  914. package/dist/utils/open-browser.js.map +1 -0
  915. package/dist/utils/paths.d.ts +34 -0
  916. package/dist/utils/paths.d.ts.map +1 -0
  917. package/dist/utils/paths.js +114 -0
  918. package/dist/utils/paths.js.map +1 -0
  919. package/dist/utils/photon.d.ts +21 -0
  920. package/dist/utils/photon.d.ts.map +1 -0
  921. package/dist/utils/photon.js +121 -0
  922. package/dist/utils/photon.js.map +1 -0
  923. package/dist/utils/shell.d.ts +34 -0
  924. package/dist/utils/shell.d.ts.map +1 -0
  925. package/dist/utils/shell.js +216 -0
  926. package/dist/utils/shell.js.map +1 -0
  927. package/dist/utils/sleep.d.ts +5 -0
  928. package/dist/utils/sleep.d.ts.map +1 -0
  929. package/dist/utils/sleep.js +17 -0
  930. package/dist/utils/sleep.js.map +1 -0
  931. package/dist/utils/syntax-highlight.d.ts +13 -0
  932. package/dist/utils/syntax-highlight.d.ts.map +1 -0
  933. package/dist/utils/syntax-highlight.js +177 -0
  934. package/dist/utils/syntax-highlight.js.map +1 -0
  935. package/dist/utils/text.d.ts +8 -0
  936. package/dist/utils/text.d.ts.map +1 -0
  937. package/dist/utils/text.js +9 -0
  938. package/dist/utils/text.js.map +1 -0
  939. package/dist/utils/tool-result-images.d.ts +19 -0
  940. package/dist/utils/tool-result-images.d.ts.map +1 -0
  941. package/dist/utils/tool-result-images.js +45 -0
  942. package/dist/utils/tool-result-images.js.map +1 -0
  943. package/dist/utils/tools-manager.d.ts +19 -0
  944. package/dist/utils/tools-manager.d.ts.map +1 -0
  945. package/dist/utils/tools-manager.js +382 -0
  946. package/dist/utils/tools-manager.js.map +1 -0
  947. package/dist/utils/version-check.d.ts +19 -0
  948. package/dist/utils/version-check.d.ts.map +1 -0
  949. package/dist/utils/version-check.js +79 -0
  950. package/dist/utils/version-check.js.map +1 -0
  951. package/dist/utils/windows-self-update.d.ts +3 -0
  952. package/dist/utils/windows-self-update.d.ts.map +1 -0
  953. package/dist/utils/windows-self-update.js +77 -0
  954. package/dist/utils/windows-self-update.js.map +1 -0
  955. package/docs/browser-extension.md +108 -0
  956. package/docs/compaction.md +444 -0
  957. package/docs/containerization.md +156 -0
  958. package/docs/custom-provider.md +777 -0
  959. package/docs/development.md +90 -0
  960. package/docs/docs.json +164 -0
  961. package/docs/environment-variables.md +101 -0
  962. package/docs/extensions.md +3033 -0
  963. package/docs/images/doom-extension.png +0 -0
  964. package/docs/images/exy.png +0 -0
  965. package/docs/images/interactive-mode.png +0 -0
  966. package/docs/images/tree-view.png +0 -0
  967. package/docs/index.md +85 -0
  968. package/docs/json.md +98 -0
  969. package/docs/keybindings.md +239 -0
  970. package/docs/llama-cpp.md +101 -0
  971. package/docs/models.md +574 -0
  972. package/docs/packages.md +228 -0
  973. package/docs/prompt-templates.md +96 -0
  974. package/docs/providers.md +321 -0
  975. package/docs/quickstart.md +168 -0
  976. package/docs/rpc.md +1618 -0
  977. package/docs/sdk.md +1226 -0
  978. package/docs/security.md +59 -0
  979. package/docs/session-format.md +450 -0
  980. package/docs/sessions.md +145 -0
  981. package/docs/settings.md +408 -0
  982. package/docs/shell-aliases.md +13 -0
  983. package/docs/skills.md +241 -0
  984. package/docs/terminal-setup.md +192 -0
  985. package/docs/termux.md +126 -0
  986. package/docs/themes.md +322 -0
  987. package/docs/tmux.md +63 -0
  988. package/docs/tui.md +961 -0
  989. package/docs/usage.md +327 -0
  990. package/docs/webfetch.md +119 -0
  991. package/docs/windows.md +39 -0
  992. package/examples/README.md +28 -0
  993. package/examples/extensions/README.md +213 -0
  994. package/examples/extensions/auto-commit-on-exit.ts +49 -0
  995. package/examples/extensions/bash-spawn-hook.ts +30 -0
  996. package/examples/extensions/bookmark.ts +50 -0
  997. package/examples/extensions/border-status-editor.ts +150 -0
  998. package/examples/extensions/built-in-tool-renderer.ts +249 -0
  999. package/examples/extensions/claude-rules.ts +86 -0
  1000. package/examples/extensions/commands.ts +72 -0
  1001. package/examples/extensions/confirm-destructive.ts +59 -0
  1002. package/examples/extensions/custom-compaction.ts +117 -0
  1003. package/examples/extensions/custom-footer.ts +64 -0
  1004. package/examples/extensions/custom-header.ts +73 -0
  1005. package/examples/extensions/custom-provider-anthropic/index.ts +611 -0
  1006. package/examples/extensions/custom-provider-anthropic/package-lock.json +24 -0
  1007. package/examples/extensions/custom-provider-anthropic/package.json +19 -0
  1008. package/examples/extensions/custom-provider-gitlab-duo/index.ts +405 -0
  1009. package/examples/extensions/custom-provider-gitlab-duo/package.json +16 -0
  1010. package/examples/extensions/custom-provider-gitlab-duo/test.ts +82 -0
  1011. package/examples/extensions/dirty-repo-guard.ts +56 -0
  1012. package/examples/extensions/doom-overlay/README.md +46 -0
  1013. package/examples/extensions/doom-overlay/doom/build/doom.js +21 -0
  1014. package/examples/extensions/doom-overlay/doom/build/doom.wasm +0 -0
  1015. package/examples/extensions/doom-overlay/doom/build.sh +152 -0
  1016. package/examples/extensions/doom-overlay/doom/doomgeneric_pi.c +72 -0
  1017. package/examples/extensions/doom-overlay/doom-component.ts +132 -0
  1018. package/examples/extensions/doom-overlay/doom-engine.ts +173 -0
  1019. package/examples/extensions/doom-overlay/doom-keys.ts +104 -0
  1020. package/examples/extensions/doom-overlay/index.ts +74 -0
  1021. package/examples/extensions/doom-overlay/wad-finder.ts +55 -0
  1022. package/examples/extensions/dynamic-resources/SKILL.md +8 -0
  1023. package/examples/extensions/dynamic-resources/dynamic.json +81 -0
  1024. package/examples/extensions/dynamic-resources/dynamic.md +5 -0
  1025. package/examples/extensions/dynamic-resources/index.ts +15 -0
  1026. package/examples/extensions/dynamic-tools.ts +74 -0
  1027. package/examples/extensions/entry-renderer.ts +41 -0
  1028. package/examples/extensions/event-bus.ts +43 -0
  1029. package/examples/extensions/file-trigger.ts +41 -0
  1030. package/examples/extensions/git-checkpoint.ts +53 -0
  1031. package/examples/extensions/git-merge-and-resolve.ts +115 -0
  1032. package/examples/extensions/github-issue-autocomplete.ts +185 -0
  1033. package/examples/extensions/gondolin/index.ts +531 -0
  1034. package/examples/extensions/gondolin/package-lock.json +185 -0
  1035. package/examples/extensions/gondolin/package.json +19 -0
  1036. package/examples/extensions/handoff.ts +190 -0
  1037. package/examples/extensions/hello.ts +26 -0
  1038. package/examples/extensions/hidden-thinking-label.ts +53 -0
  1039. package/examples/extensions/inline-bash.ts +94 -0
  1040. package/examples/extensions/input-transform-streaming.ts +39 -0
  1041. package/examples/extensions/input-transform.ts +43 -0
  1042. package/examples/extensions/interactive-shell.ts +196 -0
  1043. package/examples/extensions/kimi-deferred-tools.ts +61 -0
  1044. package/examples/extensions/mac-system-theme.ts +47 -0
  1045. package/examples/extensions/message-renderer.ts +59 -0
  1046. package/examples/extensions/minimal-mode.ts +426 -0
  1047. package/examples/extensions/modal-editor.ts +85 -0
  1048. package/examples/extensions/model-status.ts +31 -0
  1049. package/examples/extensions/notify.ts +57 -0
  1050. package/examples/extensions/overlay-qa-tests.ts +1450 -0
  1051. package/examples/extensions/overlay-test.ts +153 -0
  1052. package/examples/extensions/permission-gate.ts +34 -0
  1053. package/examples/extensions/pirate.ts +47 -0
  1054. package/examples/extensions/plan-mode/README.md +66 -0
  1055. package/examples/extensions/plan-mode/index.ts +390 -0
  1056. package/examples/extensions/plan-mode/utils.ts +168 -0
  1057. package/examples/extensions/preset.ts +436 -0
  1058. package/examples/extensions/project-trust.ts +64 -0
  1059. package/examples/extensions/prompt-customizer.ts +97 -0
  1060. package/examples/extensions/protected-paths.ts +30 -0
  1061. package/examples/extensions/provider-payload.ts +18 -0
  1062. package/examples/extensions/qna.ts +118 -0
  1063. package/examples/extensions/question.ts +278 -0
  1064. package/examples/extensions/questionnaire.ts +440 -0
  1065. package/examples/extensions/rainbow-editor.ts +88 -0
  1066. package/examples/extensions/reload-runtime.ts +37 -0
  1067. package/examples/extensions/rpc-demo.ts +118 -0
  1068. package/examples/extensions/sandbox/index.ts +321 -0
  1069. package/examples/extensions/sandbox/package-lock.json +92 -0
  1070. package/examples/extensions/sandbox/package.json +19 -0
  1071. package/examples/extensions/send-user-message.ts +97 -0
  1072. package/examples/extensions/session-name.ts +27 -0
  1073. package/examples/extensions/shutdown-command.ts +63 -0
  1074. package/examples/extensions/snake.ts +343 -0
  1075. package/examples/extensions/space-invaders.ts +560 -0
  1076. package/examples/extensions/ssh.ts +220 -0
  1077. package/examples/extensions/status-line.ts +32 -0
  1078. package/examples/extensions/structured-output.ts +65 -0
  1079. package/examples/extensions/subagent/README.md +177 -0
  1080. package/examples/extensions/subagent/agents/planner.md +37 -0
  1081. package/examples/extensions/subagent/agents/reviewer.md +35 -0
  1082. package/examples/extensions/subagent/agents/scout.md +50 -0
  1083. package/examples/extensions/subagent/agents/worker.md +24 -0
  1084. package/examples/extensions/subagent/agents.ts +157 -0
  1085. package/examples/extensions/subagent/index.ts +1038 -0
  1086. package/examples/extensions/subagent/prompts/implement-and-review.md +10 -0
  1087. package/examples/extensions/subagent/prompts/implement.md +10 -0
  1088. package/examples/extensions/subagent/prompts/scout-and-plan.md +9 -0
  1089. package/examples/extensions/summarize.ts +199 -0
  1090. package/examples/extensions/system-prompt-header.ts +17 -0
  1091. package/examples/extensions/tic-tac-toe.ts +1008 -0
  1092. package/examples/extensions/timed-confirm.ts +70 -0
  1093. package/examples/extensions/titlebar-spinner.ts +58 -0
  1094. package/examples/extensions/todo.ts +297 -0
  1095. package/examples/extensions/tool-override.ts +144 -0
  1096. package/examples/extensions/tools.ts +146 -0
  1097. package/examples/extensions/trigger-compact.ts +50 -0
  1098. package/examples/extensions/truncated-tool.ts +195 -0
  1099. package/examples/extensions/widget-placement.ts +9 -0
  1100. package/examples/extensions/with-deps/index.ts +32 -0
  1101. package/examples/extensions/with-deps/package-lock.json +31 -0
  1102. package/examples/extensions/with-deps/package.json +22 -0
  1103. package/examples/extensions/working-indicator.ts +123 -0
  1104. package/examples/extensions/working-message-test.ts +25 -0
  1105. package/examples/plugins/ion-example-plugin/README.md +38 -0
  1106. package/examples/plugins/ion-example-plugin/package.json +10 -0
  1107. package/examples/plugins/ion-example-plugin/src/contract.ts +13 -0
  1108. package/examples/plugins/ion-example-plugin/src/session.ts +23 -0
  1109. package/examples/plugins/ion-example-plugin/src/tui.ts +31 -0
  1110. package/examples/rpc-extension-ui.ts +641 -0
  1111. package/examples/sdk/01-minimal.ts +26 -0
  1112. package/examples/sdk/02-custom-model.ts +49 -0
  1113. package/examples/sdk/03-custom-prompt.ts +70 -0
  1114. package/examples/sdk/04-skills.ts +55 -0
  1115. package/examples/sdk/05-tools.ts +48 -0
  1116. package/examples/sdk/06-extensions.ts +94 -0
  1117. package/examples/sdk/07-context-files.ts +42 -0
  1118. package/examples/sdk/08-prompt-templates.ts +51 -0
  1119. package/examples/sdk/09-api-keys-and-oauth.ts +34 -0
  1120. package/examples/sdk/10-settings.ts +53 -0
  1121. package/examples/sdk/11-sessions.ts +52 -0
  1122. package/examples/sdk/12-full-control.ts +74 -0
  1123. package/examples/sdk/13-session-runtime.ts +67 -0
  1124. package/examples/sdk/README.md +140 -0
  1125. package/npm-shrinkwrap.json +1912 -0
  1126. package/package.json +108 -0
@@ -0,0 +1,282 @@
1
+ /**
2
+ * Exa backend for `webfetch` search: the second, Firecrawl-independent search
3
+ * path. Two transports, no vendored SDK:
4
+ *
5
+ * - With `EXA_API_KEY` (or the `exaApiKey` setting): official REST
6
+ * `POST https://api.exa.ai/search` with an `x-api-key` header.
7
+ * - Without a key: the hosted MCP endpoint (`POST https://mcp.exa.ai/mcp`),
8
+ * a single JSON-RPC `tools/call` to `web_search_exa` that answers with a
9
+ * formatted text payload over SSE. No account required.
10
+ *
11
+ * Page fetching stays with Firecrawl/undici; Exa is search-only here so the
12
+ * keyless path never has to invent a document fetch.
13
+ */
14
+ import { request as undiciRequest } from "undici";
15
+ import { clampLimit, WEBFETCH_REQUEST_TIMEOUT_MS, WebfetchError } from "./guardrails.js";
16
+ export const EXA_BASE_URL = "https://api.exa.ai";
17
+ export const EXA_MCP_URL = "https://mcp.exa.ai/mcp";
18
+ export const EXA_API_KEY_ENV = "EXA_API_KEY";
19
+ /** Exa's public search cap; the tool clamps lower anyway. */
20
+ export const WEBFETCH_EXA_MAX_LIMIT = 100;
21
+ const EXA_HTTP_HEADROOM_MS = 5_000;
22
+ const EXA_SEARCH_TYPE = "auto";
23
+ /** Explicit settings value wins; `EXA_API_KEY` env is the fallback. Unset means the keyless hosted MCP tier. */
24
+ export function resolveExaApiKey(explicit, env = process.env) {
25
+ const trimmed = explicit?.trim() || env[EXA_API_KEY_ENV]?.trim();
26
+ return trimmed || undefined;
27
+ }
28
+ export class ExaError extends WebfetchError {
29
+ status;
30
+ /** True when the caller should try the next search backend. */
31
+ fallback;
32
+ constructor(message, options) {
33
+ super(message, options.code);
34
+ this.name = "ExaError";
35
+ this.status = options.status;
36
+ this.fallback = options.fallback;
37
+ }
38
+ }
39
+ /** True when a failed Exa call should fall through to the next search backend. */
40
+ export function isExaFallbackEligible(error) {
41
+ return error instanceof ExaError ? error.fallback : false;
42
+ }
43
+ async function defaultPost(url, body, init) {
44
+ const timeoutSignal = AbortSignal.timeout(init.timeoutMs + EXA_HTTP_HEADROOM_MS);
45
+ const signal = init.signal ? AbortSignal.any([init.signal, timeoutSignal]) : timeoutSignal;
46
+ let response;
47
+ try {
48
+ response = await undiciRequest(url, {
49
+ method: "POST",
50
+ headers: { "content-type": "application/json", ...init.headers },
51
+ body: JSON.stringify(body),
52
+ signal,
53
+ });
54
+ }
55
+ catch (error) {
56
+ if (timeoutSignal.aborted && !init.signal?.aborted) {
57
+ throw new ExaError(`Exa request to ${new URL(url).pathname} timed out`, { code: "timeout", fallback: true });
58
+ }
59
+ if (init.signal?.aborted) {
60
+ throw new Error("Operation aborted");
61
+ }
62
+ const reason = error instanceof Error ? error.message : String(error);
63
+ throw new ExaError(`Exa request to ${new URL(url).pathname} failed: ${reason}`, {
64
+ code: "transport",
65
+ fallback: true,
66
+ });
67
+ }
68
+ try {
69
+ return { status: response.statusCode, text: await response.body.text() };
70
+ }
71
+ catch (error) {
72
+ const reason = error instanceof Error ? error.message : String(error);
73
+ throw new ExaError(`Exa response could not be read: ${reason}`, { code: "transport", fallback: true });
74
+ }
75
+ }
76
+ function isRecord(value) {
77
+ return typeof value === "object" && value !== null && !Array.isArray(value);
78
+ }
79
+ function asString(value) {
80
+ return typeof value === "string" && value.length > 0 ? value : undefined;
81
+ }
82
+ function asNumber(value) {
83
+ return typeof value === "number" && Number.isFinite(value) ? value : undefined;
84
+ }
85
+ /** `N/A` is how the hosted MCP tool renders missing metadata. */
86
+ function metaOrUndefined(value) {
87
+ if (!value)
88
+ return undefined;
89
+ const trimmed = value.trim();
90
+ return trimmed === "" || trimmed.toUpperCase() === "N/A" ? undefined : trimmed;
91
+ }
92
+ /**
93
+ * Parse the keyless hosted-MCP payload. Results are blocks of
94
+ * `Title:/URL:/Published:/Author:/Highlights:` lines; a result without a URL is
95
+ * dropped rather than surfaced as a broken ref.
96
+ */
97
+ export function parseExaMcpResults(text) {
98
+ const results = [];
99
+ for (const block of text.split(/\n(?=Title:\s)/)) {
100
+ const title = /^Title:\s*(.+)$/m.exec(block)?.[1]?.trim();
101
+ const url = /^URL:\s*(.+)$/m.exec(block)?.[1]?.trim();
102
+ if (!url || !/^https?:\/\//i.test(url))
103
+ continue;
104
+ const publishedDate = metaOrUndefined(/^Published:\s*(.+)$/m.exec(block)?.[1]);
105
+ const highlights = /^Highlights:\s*\n?([\s\S]*)$/m.exec(block)?.[1]?.trim() ?? "";
106
+ results.push({ title: title || url, url, snippet: highlights, publishedDate });
107
+ }
108
+ return results;
109
+ }
110
+ /** Extract the first JSON-RPC text content from a plain or SSE-framed body. */
111
+ export function extractMcpText(body) {
112
+ const candidates = [];
113
+ const trimmed = body.trim();
114
+ if (trimmed.startsWith("{")) {
115
+ candidates.push(trimmed);
116
+ }
117
+ for (const line of body.split("\n")) {
118
+ if (line.startsWith("data: ")) {
119
+ candidates.push(line.slice(6).trim());
120
+ }
121
+ }
122
+ for (const candidate of candidates) {
123
+ if (!candidate.startsWith("{"))
124
+ continue;
125
+ let json;
126
+ try {
127
+ json = JSON.parse(candidate);
128
+ }
129
+ catch {
130
+ continue;
131
+ }
132
+ if (!isRecord(json) || !isRecord(json.result) || !Array.isArray(json.result.content))
133
+ continue;
134
+ for (const item of json.result.content) {
135
+ if (isRecord(item) && item.type === "text" && typeof item.text === "string" && item.text.trim()) {
136
+ return item.text;
137
+ }
138
+ }
139
+ }
140
+ return undefined;
141
+ }
142
+ function normalizeRestResults(json) {
143
+ if (!isRecord(json) || !Array.isArray(json.results))
144
+ return [];
145
+ const results = [];
146
+ for (const entry of json.results) {
147
+ if (!isRecord(entry))
148
+ continue;
149
+ const url = asString(entry.url);
150
+ if (!url)
151
+ continue;
152
+ const highlights = Array.isArray(entry.highlights)
153
+ ? entry.highlights.filter((item) => typeof item === "string")
154
+ : [];
155
+ const text = asString(entry.text);
156
+ results.push({
157
+ title: asString(entry.title) || url,
158
+ url,
159
+ snippet: highlights.join("\n") || (text?.slice(0, 300) ?? ""),
160
+ publishedDate: asString(entry.publishedDate),
161
+ });
162
+ }
163
+ return results;
164
+ }
165
+ function readRestMeta(json) {
166
+ if (!isRecord(json))
167
+ return {};
168
+ const meta = {};
169
+ const requestId = asString(json.requestId);
170
+ if (requestId)
171
+ meta.requestId = requestId;
172
+ const cost = isRecord(json.costDollars) ? asNumber(json.costDollars.total) : undefined;
173
+ if (cost !== undefined)
174
+ meta.costDollars = cost;
175
+ return meta;
176
+ }
177
+ function exaErrorMessage(text) {
178
+ try {
179
+ const json = JSON.parse(text);
180
+ if (isRecord(json) && isRecord(json.error) && typeof json.error.message === "string") {
181
+ return json.error.message;
182
+ }
183
+ if (isRecord(json) && typeof json.error === "string")
184
+ return json.error;
185
+ }
186
+ catch {
187
+ return undefined;
188
+ }
189
+ return undefined;
190
+ }
191
+ function throwForStatus(status, text) {
192
+ const detail = exaErrorMessage(text);
193
+ const message = `Exa request failed with status ${status}${detail ? `: ${detail}` : ""}`;
194
+ // Auth, quota, and server failures are worth another backend; a 4xx request
195
+ // shape error is not, and would fail the same way everywhere.
196
+ if (status === 401 || status === 402 || status === 403 || status === 429 || status >= 500) {
197
+ throw new ExaError(message, { code: "transport", status, fallback: true });
198
+ }
199
+ throw new ExaError(message, { code: "transport", status, fallback: false });
200
+ }
201
+ export function createExaBackend(options = {}) {
202
+ const timeoutMs = options.timeoutMs ?? WEBFETCH_REQUEST_TIMEOUT_MS;
203
+ const post = options.post ?? defaultPost;
204
+ const backend = {
205
+ id: "exa",
206
+ lastMeta: undefined,
207
+ async search(intent, searchOptions) {
208
+ if (!intent.query) {
209
+ throw new Error("Search query must not be empty");
210
+ }
211
+ // Exa has no image vertical, so image-only intents are answered by
212
+ // Firecrawl when it is available. With no Exa-capable modality left,
213
+ // return nothing instead of inventing web results for an image request.
214
+ const webCount = intent.results.web ?? 0;
215
+ const newsCount = intent.results.news ?? 0;
216
+ if (webCount + newsCount === 0)
217
+ return [];
218
+ const limit = clampLimit(webCount + newsCount, {
219
+ fallback: 10,
220
+ min: 1,
221
+ max: WEBFETCH_EXA_MAX_LIMIT,
222
+ });
223
+ if (options.apiKey) {
224
+ const response = await post(`${EXA_BASE_URL}/search`, {
225
+ query: intent.query,
226
+ numResults: limit,
227
+ type: EXA_SEARCH_TYPE,
228
+ ...(intent.filters.recencyMs !== undefined
229
+ ? { startPublishedDate: new Date(Date.now() - intent.filters.recencyMs).toISOString() }
230
+ : {}),
231
+ ...(intent.filters.domains ? { includeDomains: intent.filters.domains } : {}),
232
+ contents: { highlights: true },
233
+ }, { headers: { "x-api-key": options.apiKey }, timeoutMs, signal: searchOptions.signal });
234
+ if (response.status !== 200) {
235
+ throwForStatus(response.status, response.text);
236
+ }
237
+ let json;
238
+ try {
239
+ json = JSON.parse(response.text);
240
+ }
241
+ catch {
242
+ throw new ExaError("Exa returned invalid JSON", { code: "transport", fallback: true });
243
+ }
244
+ backend.lastMeta = readRestMeta(json);
245
+ return normalizeRestResults(json);
246
+ }
247
+ // The keyless MCP tier exposes no recency or domain controls, so a filtered
248
+ // request cannot be honored here; say so instead of silently dropping the
249
+ // filter. The keyed REST tier above supports both.
250
+ if (intent.filters.recencyMs !== undefined || intent.filters.domains) {
251
+ throw new ExaError("Exa's keyless search tier cannot apply recency or domain filters; set EXA_API_KEY to use them", { code: "unavailable", fallback: false });
252
+ }
253
+ const response = await post(EXA_MCP_URL, {
254
+ jsonrpc: "2.0",
255
+ id: 1,
256
+ method: "tools/call",
257
+ params: {
258
+ name: "web_search_exa",
259
+ arguments: { query: intent.query, type: EXA_SEARCH_TYPE, numResults: limit },
260
+ },
261
+ }, { headers: { accept: "application/json, text/event-stream" }, timeoutMs, signal: searchOptions.signal });
262
+ if (response.status !== 200) {
263
+ throwForStatus(response.status, response.text);
264
+ }
265
+ const text = extractMcpText(response.text);
266
+ if (!text) {
267
+ throw new ExaError("Exa returned no readable result payload", { code: "empty", fallback: true });
268
+ }
269
+ backend.lastMeta = undefined;
270
+ return parseExaMcpResults(text);
271
+ },
272
+ async fetch(_url) {
273
+ // Page fetching is Firecrawl/undici territory; the Exa backend is search-only.
274
+ throw new ExaError("The Exa backend does not fetch pages; use webextract", {
275
+ code: "unavailable",
276
+ fallback: false,
277
+ });
278
+ },
279
+ };
280
+ return backend;
281
+ }
282
+ //# sourceMappingURL=backend-exa.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backend-exa.js","sourceRoot":"","sources":["../../../src/core/webfetch/backend-exa.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,QAAQ,CAAC;AAElD,OAAO,EAAE,UAAU,EAAE,2BAA2B,EAAE,aAAa,EAA0B,MAAM,iBAAiB,CAAC;AAGjH,MAAM,CAAC,MAAM,YAAY,GAAG,oBAAoB,CAAC;AACjD,MAAM,CAAC,MAAM,WAAW,GAAG,wBAAwB,CAAC;AACpD,MAAM,CAAC,MAAM,eAAe,GAAG,aAAa,CAAC;AAC7C,6DAA6D;AAC7D,MAAM,CAAC,MAAM,sBAAsB,GAAG,GAAG,CAAC;AAC1C,MAAM,oBAAoB,GAAG,KAAK,CAAC;AACnC,MAAM,eAAe,GAAG,MAAM,CAAC;AAE/B,gHAAgH;AAChH,MAAM,UAAU,gBAAgB,CAAC,QAAiB,EAAE,GAAG,GAAsB,OAAO,CAAC,GAAG,EAAsB;IAC7G,MAAM,OAAO,GAAG,QAAQ,EAAE,IAAI,EAAE,IAAI,GAAG,CAAC,eAAe,CAAC,EAAE,IAAI,EAAE,CAAC;IACjE,OAAO,OAAO,IAAI,SAAS,CAAC;AAAA,CAC5B;AAED,MAAM,OAAO,QAAS,SAAQ,aAAa;IACjC,MAAM,CAAU;IACzB,+DAA+D;IACtD,QAAQ,CAAU;IAC3B,YAAY,OAAe,EAAE,OAAwE,EAAE;QACtG,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACvB,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC7B,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAAA,CACjC;CACD;AAED,kFAAkF;AAClF,MAAM,UAAU,qBAAqB,CAAC,KAAc,EAAW;IAC9D,OAAO,KAAK,YAAY,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC;AAAA,CAC1D;AAcD,KAAK,UAAU,WAAW,CACzB,GAAW,EACX,IAA6B,EAC7B,IAAkF,EACtC;IAC5C,MAAM,aAAa,GAAG,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,GAAG,oBAAoB,CAAC,CAAC;IACjF,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC;IAC3F,IAAI,QAAmD,CAAC;IACxD,IAAI,CAAC;QACJ,QAAQ,GAAG,MAAM,aAAa,CAAC,GAAG,EAAE;YACnC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE;YAChE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;YAC1B,MAAM;SACN,CAAC,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,IAAI,aAAa,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;YACpD,MAAM,IAAI,QAAQ,CAAC,kBAAkB,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,YAAY,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9G,CAAC;QACD,IAAI,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;QACtC,CAAC;QACD,MAAM,MAAM,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACtE,MAAM,IAAI,QAAQ,CAAC,kBAAkB,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,YAAY,MAAM,EAAE,EAAE;YAC/E,IAAI,EAAE,WAAW;YACjB,QAAQ,EAAE,IAAI;SACd,CAAC,CAAC;IACJ,CAAC;IACD,IAAI,CAAC;QACJ,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,UAAU,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;IAC1E,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,MAAM,MAAM,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACtE,MAAM,IAAI,QAAQ,CAAC,mCAAmC,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IACxG,CAAC;AAAA,CACD;AAED,SAAS,QAAQ,CAAC,KAAc,EAAoC;IACnE,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAAA,CAC5E;AAED,SAAS,QAAQ,CAAC,KAAc,EAAsB;IACrD,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AAAA,CACzE;AAED,SAAS,QAAQ,CAAC,KAAc,EAAsB;IACrD,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AAAA,CAC/E;AAED,iEAAiE;AACjE,SAAS,eAAe,CAAC,KAAyB,EAAsB;IACvE,IAAI,CAAC,KAAK;QAAE,OAAO,SAAS,CAAC;IAC7B,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,OAAO,OAAO,KAAK,EAAE,IAAI,OAAO,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;AAAA,CAC/E;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAY,EAAqB;IACnE,MAAM,OAAO,GAAsB,EAAE,CAAC;IACtC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,EAAE,CAAC;QAClD,MAAM,KAAK,GAAG,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;QAC1D,MAAM,GAAG,GAAG,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;QACtD,IAAI,CAAC,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC;YAAE,SAAS;QACjD,MAAM,aAAa,GAAG,eAAe,CAAC,sBAAsB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/E,MAAM,UAAU,GAAG,+BAA+B,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QAClF,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,IAAI,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,CAAC,CAAC;IAChF,CAAC;IACD,OAAO,OAAO,CAAC;AAAA,CACf;AAED,+EAA+E;AAC/E,MAAM,UAAU,cAAc,CAAC,IAAY,EAAsB;IAChE,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC7B,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC1B,CAAC;IACD,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACrC,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC/B,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QACvC,CAAC;IACF,CAAC;IACD,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACpC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QACzC,IAAI,IAAa,CAAC;QAClB,IAAI,CAAC;YACJ,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAY,CAAC;QACzC,CAAC;QAAC,MAAM,CAAC;YACR,SAAS;QACV,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;YAAE,SAAS;QAC/F,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACxC,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;gBACjG,OAAO,IAAI,CAAC,IAAI,CAAC;YAClB,CAAC;QACF,CAAC;IACF,CAAC;IACD,OAAO,SAAS,CAAC;AAAA,CACjB;AAED,SAAS,oBAAoB,CAAC,IAAa,EAAqB;IAC/D,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,EAAE,CAAC;IAC/D,MAAM,OAAO,GAAsB,EAAE,CAAC;IACtC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QAClC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,SAAS;QAC/B,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAChC,IAAI,CAAC,GAAG;YAAE,SAAS;QACnB,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC;YACjD,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,IAAI,EAAkB,EAAE,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC;YAC7E,CAAC,CAAC,EAAE,CAAC;QACN,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAClC,OAAO,CAAC,IAAI,CAAC;YACZ,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,GAAG;YACnC,GAAG;YACH,OAAO,EAAE,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC;YAC7D,aAAa,EAAE,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC;SAC5C,CAAC,CAAC;IACJ,CAAC;IACD,OAAO,OAAO,CAAC;AAAA,CACf;AAED,SAAS,YAAY,CAAC,IAAa,EAAgD;IAClF,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IAC/B,MAAM,IAAI,GAAiD,EAAE,CAAC;IAC9D,MAAM,SAAS,GAAG,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC3C,IAAI,SAAS;QAAE,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC1C,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACvF,IAAI,IAAI,KAAK,SAAS;QAAE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;IAChD,OAAO,IAAI,CAAC;AAAA,CACZ;AAED,SAAS,eAAe,CAAC,IAAY,EAAsB;IAC1D,IAAI,CAAC;QACJ,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAY,CAAC;QACzC,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;YACtF,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;QAC3B,CAAC;QACD,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC,KAAK,CAAC;IACzE,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,SAAS,CAAC;IAClB,CAAC;IACD,OAAO,SAAS,CAAC;AAAA,CACjB;AAED,SAAS,cAAc,CAAC,MAAc,EAAE,IAAY,EAAS;IAC5D,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IACrC,MAAM,OAAO,GAAG,kCAAkC,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IACzF,4EAA4E;IAC5E,8DAA8D;IAC9D,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,IAAI,GAAG,EAAE,CAAC;QAC3F,MAAM,IAAI,QAAQ,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5E,CAAC;IACD,MAAM,IAAI,QAAQ,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;AAAA,CAC5E;AAQD,MAAM,UAAU,gBAAgB,CAAC,OAAO,GAAsB,EAAE,EAAc;IAC7E,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,2BAA2B,CAAC;IACnE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,WAAW,CAAC;IAEzC,MAAM,OAAO,GAAe;QAC3B,EAAE,EAAE,KAAK;QACT,QAAQ,EAAE,SAAS;QACnB,KAAK,CAAC,MAAM,CACX,MAA4B,EAC5B,aAAsD,EACzB;YAC7B,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;gBACnB,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;YACnD,CAAC;YACD,mEAAmE;YACnE,qEAAqE;YACrE,wEAAwE;YACxE,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;YACzC,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC;YAC3C,IAAI,QAAQ,GAAG,SAAS,KAAK,CAAC;gBAAE,OAAO,EAAE,CAAC;YAC1C,MAAM,KAAK,GAAG,UAAU,CAAC,QAAQ,GAAG,SAAS,EAAE;gBAC9C,QAAQ,EAAE,EAAE;gBACZ,GAAG,EAAE,CAAC;gBACN,GAAG,EAAE,sBAAsB;aAC3B,CAAC,CAAC;YACH,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;gBACpB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAC1B,GAAG,YAAY,SAAS,EACxB;oBACC,KAAK,EAAE,MAAM,CAAC,KAAK;oBACnB,UAAU,EAAE,KAAK;oBACjB,IAAI,EAAE,eAAe;oBACrB,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,KAAK,SAAS;wBACzC,CAAC,CAAC,EAAE,kBAAkB,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,EAAE;wBACvF,CAAC,CAAC,EAAE,CAAC;oBACN,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBAC7E,QAAQ,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE;iBAC9B,EACD,EAAE,OAAO,EAAE,EAAE,WAAW,EAAE,OAAO,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,CAAC,MAAM,EAAE,CACrF,CAAC;gBACF,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;oBAC7B,cAAc,CAAC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;gBAChD,CAAC;gBACD,IAAI,IAAa,CAAC;gBAClB,IAAI,CAAC;oBACJ,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAY,CAAC;gBAC7C,CAAC;gBAAC,MAAM,CAAC;oBACR,MAAM,IAAI,QAAQ,CAAC,2BAA2B,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;gBACxF,CAAC;gBACD,OAAO,CAAC,QAAQ,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;gBACtC,OAAO,oBAAoB,CAAC,IAAI,CAAC,CAAC;YACnC,CAAC;YAED,4EAA4E;YAC5E,0EAA0E;YAC1E,mDAAmD;YACnD,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,KAAK,SAAS,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;gBACtE,MAAM,IAAI,QAAQ,CACjB,+FAA+F,EAC/F,EAAE,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,CACxC,CAAC;YACH,CAAC;YACD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAC1B,WAAW,EACX;gBACC,OAAO,EAAE,KAAK;gBACd,EAAE,EAAE,CAAC;gBACL,MAAM,EAAE,YAAY;gBACpB,MAAM,EAAE;oBACP,IAAI,EAAE,gBAAgB;oBACtB,SAAS,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,eAAe,EAAE,UAAU,EAAE,KAAK,EAAE;iBAC5E;aACD,EACD,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,qCAAqC,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,CAAC,MAAM,EAAE,CACvG,CAAC;YACF,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBAC7B,cAAc,CAAC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;YAChD,CAAC;YACD,MAAM,IAAI,GAAG,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC3C,IAAI,CAAC,IAAI,EAAE,CAAC;gBACX,MAAM,IAAI,QAAQ,CAAC,yCAAyC,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;YAClG,CAAC;YACD,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC;YAC7B,OAAO,kBAAkB,CAAC,IAAI,CAAC,CAAC;QAAA,CAChC;QACD,KAAK,CAAC,KAAK,CAAC,IAAY,EAAwB;YAC/C,+EAA+E;YAC/E,MAAM,IAAI,QAAQ,CAAC,sDAAsD,EAAE;gBAC1E,IAAI,EAAE,aAAa;gBACnB,QAAQ,EAAE,KAAK;aACf,CAAC,CAAC;QAAA,CACH;KACD,CAAC;IACF,OAAO,OAAO,CAAC;AAAA,CACf","sourcesContent":["/**\n * Exa backend for `webfetch` search: the second, Firecrawl-independent search\n * path. Two transports, no vendored SDK:\n *\n * - With `EXA_API_KEY` (or the `exaApiKey` setting): official REST\n * `POST https://api.exa.ai/search` with an `x-api-key` header.\n * - Without a key: the hosted MCP endpoint (`POST https://mcp.exa.ai/mcp`),\n * a single JSON-RPC `tools/call` to `web_search_exa` that answers with a\n * formatted text payload over SSE. No account required.\n *\n * Page fetching stays with Firecrawl/undici; Exa is search-only here so the\n * keyless path never has to invent a document fetch.\n */\n\nimport { request as undiciRequest } from \"undici\";\nimport type { WebDocument, WebSearchBackend, WebSearchResult } from \"./backend.ts\";\nimport { clampLimit, WEBFETCH_REQUEST_TIMEOUT_MS, WebfetchError, type WebfetchErrorCode } from \"./guardrails.ts\";\nimport type { ResolvedSearchIntent } from \"./search-intent.ts\";\n\nexport const EXA_BASE_URL = \"https://api.exa.ai\";\nexport const EXA_MCP_URL = \"https://mcp.exa.ai/mcp\";\nexport const EXA_API_KEY_ENV = \"EXA_API_KEY\";\n/** Exa's public search cap; the tool clamps lower anyway. */\nexport const WEBFETCH_EXA_MAX_LIMIT = 100;\nconst EXA_HTTP_HEADROOM_MS = 5_000;\nconst EXA_SEARCH_TYPE = \"auto\";\n\n/** Explicit settings value wins; `EXA_API_KEY` env is the fallback. Unset means the keyless hosted MCP tier. */\nexport function resolveExaApiKey(explicit?: string, env: NodeJS.ProcessEnv = process.env): string | undefined {\n\tconst trimmed = explicit?.trim() || env[EXA_API_KEY_ENV]?.trim();\n\treturn trimmed || undefined;\n}\n\nexport class ExaError extends WebfetchError {\n\treadonly status?: number;\n\t/** True when the caller should try the next search backend. */\n\treadonly fallback: boolean;\n\tconstructor(message: string, options: { code: WebfetchErrorCode; status?: number; fallback: boolean }) {\n\t\tsuper(message, options.code);\n\t\tthis.name = \"ExaError\";\n\t\tthis.status = options.status;\n\t\tthis.fallback = options.fallback;\n\t}\n}\n\n/** True when a failed Exa call should fall through to the next search backend. */\nexport function isExaFallbackEligible(error: unknown): boolean {\n\treturn error instanceof ExaError ? error.fallback : false;\n}\n\nexport interface ExaBackend extends WebSearchBackend {\n\treadonly id: \"exa\";\n\t/** `requestId`/`costDollars` from the most recent keyed search, for observability. */\n\tlastMeta: { requestId?: string; costDollars?: number } | undefined;\n}\n\nexport type ExaPostFn = (\n\turl: string,\n\tbody: Record<string, unknown>,\n\tinit: { headers: Record<string, string>; timeoutMs: number; signal?: AbortSignal },\n) => Promise<{ status: number; text: string }>;\n\nasync function defaultPost(\n\turl: string,\n\tbody: Record<string, unknown>,\n\tinit: { headers: Record<string, string>; timeoutMs: number; signal?: AbortSignal },\n): Promise<{ status: number; text: string }> {\n\tconst timeoutSignal = AbortSignal.timeout(init.timeoutMs + EXA_HTTP_HEADROOM_MS);\n\tconst signal = init.signal ? AbortSignal.any([init.signal, timeoutSignal]) : timeoutSignal;\n\tlet response: Awaited<ReturnType<typeof undiciRequest>>;\n\ttry {\n\t\tresponse = await undiciRequest(url, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: { \"content-type\": \"application/json\", ...init.headers },\n\t\t\tbody: JSON.stringify(body),\n\t\t\tsignal,\n\t\t});\n\t} catch (error) {\n\t\tif (timeoutSignal.aborted && !init.signal?.aborted) {\n\t\t\tthrow new ExaError(`Exa request to ${new URL(url).pathname} timed out`, { code: \"timeout\", fallback: true });\n\t\t}\n\t\tif (init.signal?.aborted) {\n\t\t\tthrow new Error(\"Operation aborted\");\n\t\t}\n\t\tconst reason = error instanceof Error ? error.message : String(error);\n\t\tthrow new ExaError(`Exa request to ${new URL(url).pathname} failed: ${reason}`, {\n\t\t\tcode: \"transport\",\n\t\t\tfallback: true,\n\t\t});\n\t}\n\ttry {\n\t\treturn { status: response.statusCode, text: await response.body.text() };\n\t} catch (error) {\n\t\tconst reason = error instanceof Error ? error.message : String(error);\n\t\tthrow new ExaError(`Exa response could not be read: ${reason}`, { code: \"transport\", fallback: true });\n\t}\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction asString(value: unknown): string | undefined {\n\treturn typeof value === \"string\" && value.length > 0 ? value : undefined;\n}\n\nfunction asNumber(value: unknown): number | undefined {\n\treturn typeof value === \"number\" && Number.isFinite(value) ? value : undefined;\n}\n\n/** `N/A` is how the hosted MCP tool renders missing metadata. */\nfunction metaOrUndefined(value: string | undefined): string | undefined {\n\tif (!value) return undefined;\n\tconst trimmed = value.trim();\n\treturn trimmed === \"\" || trimmed.toUpperCase() === \"N/A\" ? undefined : trimmed;\n}\n\n/**\n * Parse the keyless hosted-MCP payload. Results are blocks of\n * `Title:/URL:/Published:/Author:/Highlights:` lines; a result without a URL is\n * dropped rather than surfaced as a broken ref.\n */\nexport function parseExaMcpResults(text: string): WebSearchResult[] {\n\tconst results: WebSearchResult[] = [];\n\tfor (const block of text.split(/\\n(?=Title:\\s)/)) {\n\t\tconst title = /^Title:\\s*(.+)$/m.exec(block)?.[1]?.trim();\n\t\tconst url = /^URL:\\s*(.+)$/m.exec(block)?.[1]?.trim();\n\t\tif (!url || !/^https?:\\/\\//i.test(url)) continue;\n\t\tconst publishedDate = metaOrUndefined(/^Published:\\s*(.+)$/m.exec(block)?.[1]);\n\t\tconst highlights = /^Highlights:\\s*\\n?([\\s\\S]*)$/m.exec(block)?.[1]?.trim() ?? \"\";\n\t\tresults.push({ title: title || url, url, snippet: highlights, publishedDate });\n\t}\n\treturn results;\n}\n\n/** Extract the first JSON-RPC text content from a plain or SSE-framed body. */\nexport function extractMcpText(body: string): string | undefined {\n\tconst candidates: string[] = [];\n\tconst trimmed = body.trim();\n\tif (trimmed.startsWith(\"{\")) {\n\t\tcandidates.push(trimmed);\n\t}\n\tfor (const line of body.split(\"\\n\")) {\n\t\tif (line.startsWith(\"data: \")) {\n\t\t\tcandidates.push(line.slice(6).trim());\n\t\t}\n\t}\n\tfor (const candidate of candidates) {\n\t\tif (!candidate.startsWith(\"{\")) continue;\n\t\tlet json: unknown;\n\t\ttry {\n\t\t\tjson = JSON.parse(candidate) as unknown;\n\t\t} catch {\n\t\t\tcontinue;\n\t\t}\n\t\tif (!isRecord(json) || !isRecord(json.result) || !Array.isArray(json.result.content)) continue;\n\t\tfor (const item of json.result.content) {\n\t\t\tif (isRecord(item) && item.type === \"text\" && typeof item.text === \"string\" && item.text.trim()) {\n\t\t\t\treturn item.text;\n\t\t\t}\n\t\t}\n\t}\n\treturn undefined;\n}\n\nfunction normalizeRestResults(json: unknown): WebSearchResult[] {\n\tif (!isRecord(json) || !Array.isArray(json.results)) return [];\n\tconst results: WebSearchResult[] = [];\n\tfor (const entry of json.results) {\n\t\tif (!isRecord(entry)) continue;\n\t\tconst url = asString(entry.url);\n\t\tif (!url) continue;\n\t\tconst highlights = Array.isArray(entry.highlights)\n\t\t\t? entry.highlights.filter((item): item is string => typeof item === \"string\")\n\t\t\t: [];\n\t\tconst text = asString(entry.text);\n\t\tresults.push({\n\t\t\ttitle: asString(entry.title) || url,\n\t\t\turl,\n\t\t\tsnippet: highlights.join(\"\\n\") || (text?.slice(0, 300) ?? \"\"),\n\t\t\tpublishedDate: asString(entry.publishedDate),\n\t\t});\n\t}\n\treturn results;\n}\n\nfunction readRestMeta(json: unknown): { requestId?: string; costDollars?: number } {\n\tif (!isRecord(json)) return {};\n\tconst meta: { requestId?: string; costDollars?: number } = {};\n\tconst requestId = asString(json.requestId);\n\tif (requestId) meta.requestId = requestId;\n\tconst cost = isRecord(json.costDollars) ? asNumber(json.costDollars.total) : undefined;\n\tif (cost !== undefined) meta.costDollars = cost;\n\treturn meta;\n}\n\nfunction exaErrorMessage(text: string): string | undefined {\n\ttry {\n\t\tconst json = JSON.parse(text) as unknown;\n\t\tif (isRecord(json) && isRecord(json.error) && typeof json.error.message === \"string\") {\n\t\t\treturn json.error.message;\n\t\t}\n\t\tif (isRecord(json) && typeof json.error === \"string\") return json.error;\n\t} catch {\n\t\treturn undefined;\n\t}\n\treturn undefined;\n}\n\nfunction throwForStatus(status: number, text: string): never {\n\tconst detail = exaErrorMessage(text);\n\tconst message = `Exa request failed with status ${status}${detail ? `: ${detail}` : \"\"}`;\n\t// Auth, quota, and server failures are worth another backend; a 4xx request\n\t// shape error is not, and would fail the same way everywhere.\n\tif (status === 401 || status === 402 || status === 403 || status === 429 || status >= 500) {\n\t\tthrow new ExaError(message, { code: \"transport\", status, fallback: true });\n\t}\n\tthrow new ExaError(message, { code: \"transport\", status, fallback: false });\n}\n\nexport interface ExaBackendOptions {\n\tapiKey?: string;\n\ttimeoutMs?: number;\n\tpost?: ExaPostFn;\n}\n\nexport function createExaBackend(options: ExaBackendOptions = {}): ExaBackend {\n\tconst timeoutMs = options.timeoutMs ?? WEBFETCH_REQUEST_TIMEOUT_MS;\n\tconst post = options.post ?? defaultPost;\n\n\tconst backend: ExaBackend = {\n\t\tid: \"exa\",\n\t\tlastMeta: undefined,\n\t\tasync search(\n\t\t\tintent: ResolvedSearchIntent,\n\t\t\tsearchOptions: { limit: number; signal?: AbortSignal },\n\t\t): Promise<WebSearchResult[]> {\n\t\t\tif (!intent.query) {\n\t\t\t\tthrow new Error(\"Search query must not be empty\");\n\t\t\t}\n\t\t\t// Exa has no image vertical, so image-only intents are answered by\n\t\t\t// Firecrawl when it is available. With no Exa-capable modality left,\n\t\t\t// return nothing instead of inventing web results for an image request.\n\t\t\tconst webCount = intent.results.web ?? 0;\n\t\t\tconst newsCount = intent.results.news ?? 0;\n\t\t\tif (webCount + newsCount === 0) return [];\n\t\t\tconst limit = clampLimit(webCount + newsCount, {\n\t\t\t\tfallback: 10,\n\t\t\t\tmin: 1,\n\t\t\t\tmax: WEBFETCH_EXA_MAX_LIMIT,\n\t\t\t});\n\t\t\tif (options.apiKey) {\n\t\t\t\tconst response = await post(\n\t\t\t\t\t`${EXA_BASE_URL}/search`,\n\t\t\t\t\t{\n\t\t\t\t\t\tquery: intent.query,\n\t\t\t\t\t\tnumResults: limit,\n\t\t\t\t\t\ttype: EXA_SEARCH_TYPE,\n\t\t\t\t\t\t...(intent.filters.recencyMs !== undefined\n\t\t\t\t\t\t\t? { startPublishedDate: new Date(Date.now() - intent.filters.recencyMs).toISOString() }\n\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t...(intent.filters.domains ? { includeDomains: intent.filters.domains } : {}),\n\t\t\t\t\t\tcontents: { highlights: true },\n\t\t\t\t\t},\n\t\t\t\t\t{ headers: { \"x-api-key\": options.apiKey }, timeoutMs, signal: searchOptions.signal },\n\t\t\t\t);\n\t\t\t\tif (response.status !== 200) {\n\t\t\t\t\tthrowForStatus(response.status, response.text);\n\t\t\t\t}\n\t\t\t\tlet json: unknown;\n\t\t\t\ttry {\n\t\t\t\t\tjson = JSON.parse(response.text) as unknown;\n\t\t\t\t} catch {\n\t\t\t\t\tthrow new ExaError(\"Exa returned invalid JSON\", { code: \"transport\", fallback: true });\n\t\t\t\t}\n\t\t\t\tbackend.lastMeta = readRestMeta(json);\n\t\t\t\treturn normalizeRestResults(json);\n\t\t\t}\n\n\t\t\t// The keyless MCP tier exposes no recency or domain controls, so a filtered\n\t\t\t// request cannot be honored here; say so instead of silently dropping the\n\t\t\t// filter. The keyed REST tier above supports both.\n\t\t\tif (intent.filters.recencyMs !== undefined || intent.filters.domains) {\n\t\t\t\tthrow new ExaError(\n\t\t\t\t\t\"Exa's keyless search tier cannot apply recency or domain filters; set EXA_API_KEY to use them\",\n\t\t\t\t\t{ code: \"unavailable\", fallback: false },\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst response = await post(\n\t\t\t\tEXA_MCP_URL,\n\t\t\t\t{\n\t\t\t\t\tjsonrpc: \"2.0\",\n\t\t\t\t\tid: 1,\n\t\t\t\t\tmethod: \"tools/call\",\n\t\t\t\t\tparams: {\n\t\t\t\t\t\tname: \"web_search_exa\",\n\t\t\t\t\t\targuments: { query: intent.query, type: EXA_SEARCH_TYPE, numResults: limit },\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{ headers: { accept: \"application/json, text/event-stream\" }, timeoutMs, signal: searchOptions.signal },\n\t\t\t);\n\t\t\tif (response.status !== 200) {\n\t\t\t\tthrowForStatus(response.status, response.text);\n\t\t\t}\n\t\t\tconst text = extractMcpText(response.text);\n\t\t\tif (!text) {\n\t\t\t\tthrow new ExaError(\"Exa returned no readable result payload\", { code: \"empty\", fallback: true });\n\t\t\t}\n\t\t\tbackend.lastMeta = undefined;\n\t\t\treturn parseExaMcpResults(text);\n\t\t},\n\t\tasync fetch(_url: string): Promise<WebDocument> {\n\t\t\t// Page fetching is Firecrawl/undici territory; the Exa backend is search-only.\n\t\t\tthrow new ExaError(\"The Exa backend does not fetch pages; use webextract\", {\n\t\t\t\tcode: \"unavailable\",\n\t\t\t\tfallback: false,\n\t\t\t});\n\t\t},\n\t};\n\treturn backend;\n}\n"]}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Firecrawl backend for webfetch: thin `undici` POSTs to the hosted Firecrawl
3
+ * API. The SDK is never vendored (extra `axios` dep) and the server is never
4
+ * vendored (AGPL-3.0).
5
+ *
6
+ * Auth is an optional `Bearer` key, omitted entirely on the keyless tier.
7
+ * Resolve it with `resolveFirecrawlApiKey` (explicit settings value first,
8
+ * `FIRECRAWL_API_KEY` env second).
9
+ */
10
+ import type { WebSearchBackend } from "./backend.ts";
11
+ import { WebfetchError, type WebfetchErrorCode } from "./guardrails.ts";
12
+ export declare const FIRECRAWL_BASE_URL = "https://api.firecrawl.dev";
13
+ export declare const FIRECRAWL_API_KEY_ENV = "FIRECRAWL_API_KEY";
14
+ /** Explicit settings value wins; `FIRECRAWL_API_KEY` env is the fallback. Keyless (undefined) works with lower limits. */
15
+ export declare function resolveFirecrawlApiKey(explicit?: string, env?: NodeJS.ProcessEnv): string | undefined;
16
+ export declare class FirecrawlError extends WebfetchError {
17
+ readonly status?: number;
18
+ /** True when the caller should try the `undici` direct-fetch fallback (transport/auth failure, never content failure). */
19
+ readonly fallback: boolean;
20
+ constructor(message: string, options: {
21
+ code: WebfetchErrorCode;
22
+ status?: number;
23
+ fallback: boolean;
24
+ });
25
+ }
26
+ /**
27
+ * The keyless Firecrawl tier refused this network (403 "your IP address looks
28
+ * suspicious", 401 without a key, or 429 on the shared anonymous pool). This is
29
+ * provider-side and often IP-dependent, so the message names the exact fix
30
+ * instead of leaking the raw status. Direct page fetch still works through the
31
+ * `undici` fallback; only search is unavailable.
32
+ */
33
+ export declare function keylessUnavailableMessage(status: number, path: string): string;
34
+ /** True when a failed Firecrawl call should fall back to direct `undici` fetch instead of surfacing the error. */
35
+ export declare function isFallbackEligible(error: unknown): boolean;
36
+ export interface FirecrawlResponseMeta {
37
+ warning?: string;
38
+ creditsUsed?: number;
39
+ }
40
+ export interface FirecrawlBackend extends WebSearchBackend {
41
+ readonly id: "firecrawl";
42
+ /** `warning`/`creditsUsed` from the most recent search or scrape, for cost observability in tool details. */
43
+ lastMeta: FirecrawlResponseMeta | undefined;
44
+ }
45
+ export type FirecrawlPostFn = (path: string, body: Record<string, unknown>, init: {
46
+ headers: Record<string, string>;
47
+ timeoutMs: number;
48
+ signal?: AbortSignal;
49
+ }) => Promise<{
50
+ status: number;
51
+ json: unknown;
52
+ }>;
53
+ export interface FirecrawlBackendOptions {
54
+ apiKey?: string;
55
+ timeoutMs?: number;
56
+ post?: FirecrawlPostFn;
57
+ }
58
+ export declare function createFirecrawlBackend(options?: FirecrawlBackendOptions): FirecrawlBackend;
59
+ //# sourceMappingURL=backend-firecrawl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backend-firecrawl.d.ts","sourceRoot":"","sources":["../../../src/core/webfetch/backend-firecrawl.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAe,gBAAgB,EAAmB,MAAM,cAAc,CAAC;AACnF,OAAO,EAIN,aAAa,EACb,KAAK,iBAAiB,EACtB,MAAM,iBAAiB,CAAC;AAGzB,eAAO,MAAM,kBAAkB,8BAA8B,CAAC;AAC9D,eAAO,MAAM,qBAAqB,sBAAsB,CAAC;AAIzD,0HAA0H;AAC1H,wBAAgB,sBAAsB,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,GAAG,SAAS,CAGlH;AAED,qBAAa,cAAe,SAAQ,aAAa;IAChD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,0HAA0H;IAC1H,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,YAAY,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE;QAAE,IAAI,EAAE,iBAAiB,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,EAKpG;CACD;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAa9E;AAED,kHAAkH;AAClH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAM1D;AAED,MAAM,WAAW,qBAAqB;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,gBAAiB,SAAQ,gBAAgB;IACzD,QAAQ,CAAC,EAAE,EAAE,WAAW,CAAC;IACzB,6GAA6G;IAC7G,QAAQ,EAAE,qBAAqB,GAAG,SAAS,CAAC;CAC5C;AAED,MAAM,MAAM,eAAe,GAAG,CAC7B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,IAAI,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAAE,KAC9E,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC;AA2ChD,MAAM,WAAW,uBAAuB;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,eAAe,CAAC;CACvB;AAoGD,wBAAgB,sBAAsB,CAAC,OAAO,GAAE,uBAA4B,GAAG,gBAAgB,CAqJ9F","sourcesContent":["/**\n * Firecrawl backend for webfetch: thin `undici` POSTs to the hosted Firecrawl\n * API. The SDK is never vendored (extra `axios` dep) and the server is never\n * vendored (AGPL-3.0).\n *\n * Auth is an optional `Bearer` key, omitted entirely on the keyless tier.\n * Resolve it with `resolveFirecrawlApiKey` (explicit settings value first,\n * `FIRECRAWL_API_KEY` env second).\n */\n\nimport { request as undiciRequest } from \"undici\";\nimport type { WebDocument, WebSearchBackend, WebSearchResult } from \"./backend.ts\";\nimport {\n\tclampLimit,\n\tWEBFETCH_FIRECRAWL_MAX_LIMIT,\n\tWEBFETCH_REQUEST_TIMEOUT_MS,\n\tWebfetchError,\n\ttype WebfetchErrorCode,\n} from \"./guardrails.ts\";\nimport type { ResolvedSearchIntent } from \"./search-intent.ts\";\n\nexport const FIRECRAWL_BASE_URL = \"https://api.firecrawl.dev\";\nexport const FIRECRAWL_API_KEY_ENV = \"FIRECRAWL_API_KEY\";\nconst FIRECRAWL_502_MAX_ATTEMPTS = 3;\nconst FIRECRAWL_HTTP_HEADROOM_MS = 5_000;\n\n/** Explicit settings value wins; `FIRECRAWL_API_KEY` env is the fallback. Keyless (undefined) works with lower limits. */\nexport function resolveFirecrawlApiKey(explicit?: string, env: NodeJS.ProcessEnv = process.env): string | undefined {\n\tconst trimmed = explicit?.trim() || env[FIRECRAWL_API_KEY_ENV]?.trim();\n\treturn trimmed || undefined;\n}\n\nexport class FirecrawlError extends WebfetchError {\n\treadonly status?: number;\n\t/** True when the caller should try the `undici` direct-fetch fallback (transport/auth failure, never content failure). */\n\treadonly fallback: boolean;\n\tconstructor(message: string, options: { code: WebfetchErrorCode; status?: number; fallback: boolean }) {\n\t\tsuper(message, options.code);\n\t\tthis.name = \"FirecrawlError\";\n\t\tthis.status = options.status;\n\t\tthis.fallback = options.fallback;\n\t}\n}\n\n/**\n * The keyless Firecrawl tier refused this network (403 \"your IP address looks\n * suspicious\", 401 without a key, or 429 on the shared anonymous pool). This is\n * provider-side and often IP-dependent, so the message names the exact fix\n * instead of leaking the raw status. Direct page fetch still works through the\n * `undici` fallback; only search is unavailable.\n */\nexport function keylessUnavailableMessage(status: number, path: string): string {\n\tconst reason =\n\t\tstatus === 429\n\t\t\t? \"the keyless rate limit was exhausted\"\n\t\t\t: status === 401\n\t\t\t\t? \"no API key was sent\"\n\t\t\t\t: \"this network is not allowed on the anonymous tier\";\n\treturn [\n\t\t`Firecrawl ${path} is unavailable: ${reason} (status ${status}).`,\n\t\t\"Set a Firecrawl API key to fix this: add the `firecrawlApiKey` setting or the\",\n\t\t\"`FIRECRAWL_API_KEY` environment variable, then retry.\",\n\t\t\"`webextract` still works without a key: it fetches pages directly.\",\n\t].join(\" \");\n}\n\n/** True when a failed Firecrawl call should fall back to direct `undici` fetch instead of surfacing the error. */\nexport function isFallbackEligible(error: unknown): boolean {\n\tif (error instanceof FirecrawlError) return error.fallback;\n\tif (error instanceof WebfetchError) {\n\t\treturn error.code === \"timeout\" || error.code === \"transport\" || error.code === \"empty\";\n\t}\n\treturn false;\n}\n\nexport interface FirecrawlResponseMeta {\n\twarning?: string;\n\tcreditsUsed?: number;\n}\n\nexport interface FirecrawlBackend extends WebSearchBackend {\n\treadonly id: \"firecrawl\";\n\t/** `warning`/`creditsUsed` from the most recent search or scrape, for cost observability in tool details. */\n\tlastMeta: FirecrawlResponseMeta | undefined;\n}\n\nexport type FirecrawlPostFn = (\n\tpath: string,\n\tbody: Record<string, unknown>,\n\tinit: { headers: Record<string, string>; timeoutMs: number; signal?: AbortSignal },\n) => Promise<{ status: number; json: unknown }>;\n\nasync function defaultPost(\n\tpath: string,\n\tbody: Record<string, unknown>,\n\tinit: { headers: Record<string, string>; timeoutMs: number; signal?: AbortSignal },\n): Promise<{ status: number; json: unknown }> {\n\tconst timeoutSignal = AbortSignal.timeout(init.timeoutMs + FIRECRAWL_HTTP_HEADROOM_MS);\n\tconst signal = init.signal ? AbortSignal.any([init.signal, timeoutSignal]) : timeoutSignal;\n\tlet response: Awaited<ReturnType<typeof undiciRequest>>;\n\ttry {\n\t\tresponse = await undiciRequest(`${FIRECRAWL_BASE_URL}${path}`, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: { \"content-type\": \"application/json\", ...init.headers },\n\t\t\tbody: JSON.stringify(body),\n\t\t\tsignal,\n\t\t});\n\t} catch (error) {\n\t\tif (timeoutSignal.aborted && !init.signal?.aborted) {\n\t\t\tthrow new WebfetchError(`Firecrawl request to ${path} timed out`, \"timeout\");\n\t\t}\n\t\tif (init.signal?.aborted) {\n\t\t\tthrow new Error(\"Operation aborted\");\n\t\t}\n\t\tconst reason = error instanceof Error ? error.message : String(error);\n\t\tthrow new WebfetchError(`Firecrawl request to ${path} failed: ${reason}`, \"transport\");\n\t}\n\tlet text: string;\n\ttry {\n\t\ttext = await response.body.text();\n\t} catch (error) {\n\t\tconst reason = error instanceof Error ? error.message : String(error);\n\t\tthrow new WebfetchError(`Firecrawl request to ${path} failed: ${reason}`, \"transport\");\n\t}\n\tlet json: unknown;\n\ttry {\n\t\tjson = text ? (JSON.parse(text) as unknown) : undefined;\n\t} catch {\n\t\tthrow new WebfetchError(`Firecrawl request to ${path} returned invalid JSON`, \"transport\");\n\t}\n\treturn { status: response.statusCode, json };\n}\n\nexport interface FirecrawlBackendOptions {\n\tapiKey?: string;\n\ttimeoutMs?: number;\n\tpost?: FirecrawlPostFn;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction asString(value: unknown): string | undefined {\n\treturn typeof value === \"string\" ? value : undefined;\n}\n\nfunction asNumber(value: unknown): number | undefined {\n\treturn typeof value === \"number\" && Number.isFinite(value) ? value : undefined;\n}\n\nfunction firecrawlErrorMessage(json: unknown): string | undefined {\n\tif (!isRecord(json)) return undefined;\n\tconst direct = asString(json.error);\n\tif (direct) return direct;\n\tif (isRecord(json.data)) {\n\t\tconst nested = asString(json.data.error);\n\t\tif (nested) return nested;\n\t}\n\treturn undefined;\n}\n\nfunction readMeta(json: unknown): FirecrawlResponseMeta | undefined {\n\tif (!isRecord(json)) return undefined;\n\tconst data = isRecord(json.data) ? json.data : undefined;\n\tconst warning = asString(json.warning) ?? (data ? asString(data.warning) : undefined);\n\tconst creditsUsed = asNumber(json.creditsUsed) ?? (data ? asNumber(data.creditsUsed) : undefined);\n\tif (warning === undefined && creditsUsed === undefined) return undefined;\n\treturn { warning, creditsUsed };\n}\n\nfunction normalizeSearchEntry(entry: unknown, source: \"web\" | \"images\" | \"news\"): WebSearchResult | undefined {\n\tif (!isRecord(entry)) return undefined;\n\tconst url = asString(entry.url);\n\tif (!url) return undefined;\n\tconst markdown = asString(entry.markdown);\n\tconst description = asString(entry.description);\n\tconst snippet =\n\t\tsource === \"news\" ? (asString(entry.snippet) ?? description ?? \"\") : description || markdown?.slice(0, 300) || \"\";\n\treturn {\n\t\ttitle: asString(entry.title) || url,\n\t\turl,\n\t\tsnippet,\n\t\tpublishedDate: asString(entry.publishedDate) ?? asString(entry.date),\n\t\tscore: asNumber(entry.score),\n\t\tsource,\n\t\t...(source === \"images\"\n\t\t\t? {\n\t\t\t\t\timageUrl: asString(entry.imageUrl) ?? asString(entry.image),\n\t\t\t\t\timageWidth: asNumber(entry.imageWidth),\n\t\t\t\t\timageHeight: asNumber(entry.imageHeight),\n\t\t\t\t}\n\t\t\t: {}),\n\t};\n}\n\n/**\n * Flatten Firecrawl's per-source buckets into one ordered list, each bucket\n * trimmed to its requested budget. Web hits keep their inline markdown as the\n * snippet; image hits point at the image and its source page.\n */\nfunction normalizeSearchResponse(json: unknown, budgets: Record<string, number>): WebSearchResult[] {\n\tif (!isRecord(json)) return [];\n\tconst data = json.data;\n\tconst results: WebSearchResult[] = [];\n\tfor (const source of [\"web\", \"images\", \"news\"] as const) {\n\t\tconst budget = budgets[source];\n\t\tif (budget === undefined) continue;\n\t\tconst bucket = isRecord(data) ? data[source] : undefined;\n\t\tconst entries = Array.isArray(bucket) ? bucket : source === \"web\" && Array.isArray(data) ? data : undefined;\n\t\tif (!entries) continue;\n\t\tlet taken = 0;\n\t\tfor (const entry of entries) {\n\t\t\tif (taken >= budget) break;\n\t\t\tconst normalized = normalizeSearchEntry(entry, source);\n\t\t\tif (!normalized) continue;\n\t\t\tresults.push(normalized);\n\t\t\ttaken++;\n\t\t}\n\t}\n\treturn results;\n}\n\nfunction normalizeScrapeResponse(url: string, json: unknown): WebDocument {\n\tconst data = isRecord(json) ? (isRecord(json.data) ? json.data : undefined) : undefined;\n\tconst markdown = (data ? asString(data.markdown) : undefined) ?? \"\";\n\tconst metadata = data && isRecord(data.metadata) ? data.metadata : undefined;\n\tconst title = (metadata ? asString(metadata.title) : undefined) ?? (data ? asString(data.title) : undefined) ?? url;\n\tif (!markdown.trim()) {\n\t\tthrow new FirecrawlError(`Firecrawl scrape of ${url} returned no usable text`, {\n\t\t\tcode: \"empty\",\n\t\t\tfallback: true,\n\t\t});\n\t}\n\treturn { url, title, markdown, fetchedAt: new Date().toISOString() };\n}\n\nexport function createFirecrawlBackend(options: FirecrawlBackendOptions = {}): FirecrawlBackend {\n\tconst timeoutMs = options.timeoutMs ?? WEBFETCH_REQUEST_TIMEOUT_MS;\n\tconst post = options.post ?? defaultPost;\n\tconst headers: Record<string, string> = {};\n\tif (options.apiKey) {\n\t\theaders.authorization = `Bearer ${options.apiKey}`;\n\t}\n\n\tasync function callApi(\n\t\tpath: string,\n\t\tbody: Record<string, unknown>,\n\t\tsignal?: AbortSignal,\n\t): Promise<{ status: number; json: unknown }> {\n\t\tlet lastError: unknown;\n\t\tfor (let attempt = 1; attempt <= FIRECRAWL_502_MAX_ATTEMPTS; attempt++) {\n\t\t\tif (signal?.aborted) {\n\t\t\t\tthrow new Error(\"Operation aborted\");\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst response = await post(path, body, { headers, timeoutMs, signal });\n\t\t\t\tif (response.status === 502 && attempt < FIRECRAWL_502_MAX_ATTEMPTS) {\n\t\t\t\t\tlastError = new FirecrawlError(`Firecrawl request to ${path} failed with status 502`, {\n\t\t\t\t\t\tcode: \"transport\",\n\t\t\t\t\t\tstatus: 502,\n\t\t\t\t\t\tfallback: true,\n\t\t\t\t\t});\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\treturn response;\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof FirecrawlError && error.status === 502 && attempt < FIRECRAWL_502_MAX_ATTEMPTS) {\n\t\t\t\t\tlastError = error;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\t\tthrow lastError;\n\t}\n\n\tfunction throwForStatus(path: string, status: number, json: unknown): never {\n\t\tconst detail = firecrawlErrorMessage(json);\n\t\t// Keyless 401/403/429 is provider-side (anonymous pool or blocked network),\n\t\t// not a transport blip: name the fix instead of the raw status.\n\t\tif (!options.apiKey && (status === 401 || status === 403 || status === 429)) {\n\t\t\tthrow new FirecrawlError(keylessUnavailableMessage(status, path), {\n\t\t\t\tcode: \"unavailable\",\n\t\t\t\tstatus,\n\t\t\t\tfallback: true,\n\t\t\t});\n\t\t}\n\t\tconst message = `Firecrawl request to ${path} failed with status ${status}${detail ? `: ${detail}` : \"\"}`;\n\t\tif (status === 401 || status === 403) {\n\t\t\tthrow new FirecrawlError(message, { code: \"transport\", status, fallback: true });\n\t\t}\n\t\tif (status === 402 || status === 429 || status >= 500) {\n\t\t\tthrow new FirecrawlError(message, { code: \"transport\", status, fallback: true });\n\t\t}\n\t\tthrow new FirecrawlError(message, { code: \"transport\", status, fallback: false });\n\t}\n\n\tconst backend: FirecrawlBackend = {\n\t\tid: \"firecrawl\",\n\t\tlastMeta: undefined,\n\t\tasync search(\n\t\t\tintent: ResolvedSearchIntent,\n\t\t\tsearchOptions: { limit: number; signal?: AbortSignal },\n\t\t): Promise<WebSearchResult[]> {\n\t\t\tif (!intent.query) {\n\t\t\t\tthrow new Error(\"Search query must not be empty\");\n\t\t\t}\n\t\t\t// Per-modality limits: sum the requested counts, then slice each bucket\n\t\t\t// back to its own budget so one modality cannot starve another.\n\t\t\tconst sources: Array<\"web\" | \"images\" | \"news\"> = [];\n\t\t\tif (intent.results.web !== undefined) sources.push(\"web\");\n\t\t\tif (intent.results.images !== undefined) sources.push(\"images\");\n\t\t\tif (intent.results.news !== undefined) sources.push(\"news\");\n\t\t\tconst budgets: Record<string, number> = {};\n\t\t\tlet total = 0;\n\t\t\tfor (const source of sources) {\n\t\t\t\tconst count = clampLimit(intent.results[source] ?? 0, {\n\t\t\t\t\tfallback: 1,\n\t\t\t\t\tmin: 1,\n\t\t\t\t\tmax: WEBFETCH_FIRECRAWL_MAX_LIMIT,\n\t\t\t\t});\n\t\t\t\tbudgets[source] = count;\n\t\t\t\ttotal += count;\n\t\t\t}\n\t\t\ttotal = clampLimit(total, { fallback: 10, min: 1, max: WEBFETCH_FIRECRAWL_MAX_LIMIT });\n\n\t\t\tconst body: Record<string, unknown> = {\n\t\t\t\tquery: intent.query,\n\t\t\t\tlimit: total,\n\t\t\t\tsources,\n\t\t\t\thighlights: true,\n\t\t\t\ttimeout: timeoutMs,\n\t\t\t};\n\t\t\tif (intent.filters.domains) {\n\t\t\t\t// Firecrawl treats includeDomains/excludeDomains as mutually exclusive;\n\t\t\t\t// a request for both is narrowed to the include list.\n\t\t\t\tbody.includeDomains = intent.filters.domains;\n\t\t\t}\n\t\t\tif (intent.filters.recencyMs !== undefined) {\n\t\t\t\tbody.tbs = `qdr:d${Math.max(1, Math.round(intent.filters.recencyMs / (24 * 60 * 60 * 1000)))}`;\n\t\t\t}\n\t\t\tif (intent.filters.language) {\n\t\t\t\tbody.country = intent.filters.language;\n\t\t\t}\n\t\t\t// Page text is only useful for web hits; image and news hits carry their\n\t\t\t// own metadata and are cheaper without a scrape.\n\t\t\tif (intent.results.web !== undefined) {\n\t\t\t\tbody.scrapeOptions = { formats: [\"markdown\"], onlyMainContent: true };\n\t\t\t}\n\n\t\t\tconst response = await callApi(\"/v2/search\", body, searchOptions.signal);\n\t\t\tif (response.status !== 200) {\n\t\t\t\tthrowForStatus(\"/v2/search\", response.status, response.json);\n\t\t\t}\n\t\t\tif (isRecord(response.json) && response.json.success === false) {\n\t\t\t\tthrow new FirecrawlError(firecrawlErrorMessage(response.json) ?? \"Firecrawl search failed\", {\n\t\t\t\t\tcode: \"transport\",\n\t\t\t\t\tstatus: response.status,\n\t\t\t\t\tfallback: false,\n\t\t\t\t});\n\t\t\t}\n\t\t\tbackend.lastMeta = readMeta(response.json);\n\t\t\treturn normalizeSearchResponse(response.json, budgets);\n\t\t},\n\t\tasync fetch(url: string, fetchOptions: { signal?: AbortSignal }): Promise<WebDocument> {\n\t\t\tconst response = await callApi(\n\t\t\t\t\"/v2/scrape\",\n\t\t\t\t{ url, formats: [\"markdown\"], onlyMainContent: true, timeout: timeoutMs },\n\t\t\t\tfetchOptions.signal,\n\t\t\t);\n\t\t\tif (response.status !== 200) {\n\t\t\t\tthrowForStatus(\"/v2/scrape\", response.status, response.json);\n\t\t\t}\n\t\t\tif (isRecord(response.json) && response.json.success === false) {\n\t\t\t\tthrow new FirecrawlError(firecrawlErrorMessage(response.json) ?? `Firecrawl scrape of ${url} failed`, {\n\t\t\t\t\tcode: \"transport\",\n\t\t\t\t\tstatus: response.status,\n\t\t\t\t\tfallback: false,\n\t\t\t\t});\n\t\t\t}\n\t\t\tbackend.lastMeta = readMeta(response.json);\n\t\t\treturn normalizeScrapeResponse(url, response.json);\n\t\t},\n\t};\n\treturn backend;\n}\n"]}