@johpaz/hive-agents 0.0.35 → 0.0.37

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 (441) hide show
  1. package/README.md +64 -39
  2. package/dist/hive.js +3231 -3189
  3. package/dist/tool-worker.js +218406 -0
  4. package/dist/ui/assets/{AgentCreateForm-B4eK7efF.js → AgentCreateForm-tJZv9FZC.js} +1 -1
  5. package/dist/ui/assets/{AgentDetailPage-BD2uoJWk.js → AgentDetailPage-Du-mRcAX.js} +1 -1
  6. package/dist/ui/assets/AgentNewPage-DIFYd_Ys.js +1 -0
  7. package/dist/ui/assets/{AgentsPage-4JUZXvkA.js → AgentsPage-YvSgWRiw.js} +6 -6
  8. package/dist/ui/assets/CanvasPage-DtMwGvxf.js +33 -0
  9. package/dist/ui/assets/{ChannelsPage-BUn7-nhV.js → ChannelsPage-BdBXWHjj.js} +1 -1
  10. package/dist/ui/assets/DashboardPage-ghl1ZguH.js +6 -0
  11. package/dist/ui/assets/{LoginPage-C8j_urUD.js → LoginPage-CAmSI9Vy.js} +1 -1
  12. package/dist/ui/assets/LogsPage-DAPBHkwK.js +1 -0
  13. package/dist/ui/assets/MeetingPage-WjjGOqqU.js +1 -0
  14. package/dist/ui/assets/{NotFound-Drh-sJPN.js → NotFound-BMeQSGcG.js} +1 -1
  15. package/dist/ui/assets/ProvidersPage-Ct6HsAi1.js +1 -0
  16. package/dist/ui/assets/{RecoverPage-DNb1Pr8h.js → RecoverPage-DpW3l-yv.js} +1 -1
  17. package/dist/ui/assets/SettingsPage-DBJ7_E6C.js +9 -0
  18. package/dist/ui/assets/SetupPage-DKmLVUaj.js +1 -0
  19. package/dist/ui/assets/{WebChatPage-R-YOwA4F.js → WebChatPage-CVRcKept.js} +2 -2
  20. package/dist/ui/assets/accordion-C5d5Rm5z.js +1 -0
  21. package/dist/ui/assets/{alert-U8FsgWi7.js → alert-C-NE-P3s.js} +1 -1
  22. package/dist/ui/assets/{alert-dialog-CRdMkkmk.js → alert-dialog-C5mzbHdP.js} +1 -1
  23. package/dist/ui/assets/{badge-Cli1jnH5.js → badge-ChpACfWO.js} +1 -1
  24. package/dist/ui/assets/chevron-up-BYhk0K2J.js +1 -0
  25. package/dist/ui/assets/{dialog-DQ3s-LuO.js → dialog-QnZ0ad8O.js} +1 -1
  26. package/dist/ui/assets/dropdown-menu-BK-CO3Od.js +1 -0
  27. package/dist/ui/assets/{es-DcMjrpbA.js → es-NQNoaWDx.js} +1 -1
  28. package/dist/ui/assets/index-B2fCYtTS.css +2 -0
  29. package/dist/ui/assets/index-DMCjjdqf.js +116 -0
  30. package/dist/ui/assets/{label-0BvGVXvZ.js → label-D2H1IR_J.js} +1 -1
  31. package/dist/ui/assets/progress-BherYzY6.js +1 -0
  32. package/dist/ui/assets/scroll-area-DkeyX32e.js +1 -0
  33. package/dist/ui/assets/{slider-D47dOrRa.js → slider-CsiUDxc3.js} +1 -1
  34. package/dist/ui/assets/switch-BDwN8RYV.js +1 -0
  35. package/dist/ui/assets/{table-DhowbNxQ.js → table-CSc8ubon.js} +1 -1
  36. package/dist/ui/assets/terminal-DN38Q456.js +1 -0
  37. package/dist/ui/assets/useProviders-C6_QHsEi.js +1 -0
  38. package/dist/ui/assets/{vendor-radix-JY4ncZrD.js → vendor-radix-cw1bQaVC.js} +4 -4
  39. package/dist/ui/assets/{vendor-react-CscwQerf.js → vendor-react-D4s9E-zj.js} +1 -1
  40. package/dist/ui/dist/assets/AgentCreateForm-tJZv9FZC.js +1 -0
  41. package/dist/ui/dist/assets/AgentDetailPage-Du-mRcAX.js +1 -0
  42. package/dist/ui/dist/assets/AgentNewPage-DIFYd_Ys.js +1 -0
  43. package/dist/ui/dist/assets/AgentsPage-YvSgWRiw.js +10 -0
  44. package/dist/ui/dist/assets/CanvasPage-DtMwGvxf.js +33 -0
  45. package/dist/ui/dist/assets/ChannelsPage-BdBXWHjj.js +8 -0
  46. package/dist/ui/dist/assets/DashboardPage-ghl1ZguH.js +6 -0
  47. package/dist/ui/dist/assets/LoginPage-CAmSI9Vy.js +1 -0
  48. package/dist/ui/dist/assets/LogsPage-DAPBHkwK.js +1 -0
  49. package/dist/ui/dist/assets/MeetingPage-WjjGOqqU.js +1 -0
  50. package/dist/ui/dist/assets/NotFound-BMeQSGcG.js +1 -0
  51. package/dist/ui/dist/assets/ProvidersPage-Ct6HsAi1.js +1 -0
  52. package/dist/ui/dist/assets/RecoverPage-DpW3l-yv.js +1 -0
  53. package/dist/ui/dist/assets/SettingsPage-DBJ7_E6C.js +9 -0
  54. package/dist/ui/dist/assets/SetupPage-DKmLVUaj.js +1 -0
  55. package/dist/ui/dist/assets/WebChatPage-CVRcKept.js +16 -0
  56. package/dist/ui/dist/assets/accordion-C5d5Rm5z.js +1 -0
  57. package/dist/ui/dist/assets/activity-c3pNngT_.js +1 -0
  58. package/dist/ui/dist/assets/alert-C-NE-P3s.js +1 -0
  59. package/dist/ui/dist/assets/alert-dialog-C5mzbHdP.js +1 -0
  60. package/dist/ui/dist/assets/arrow-left-CBcbX5EZ.js +1 -0
  61. package/dist/ui/dist/assets/badge-ChpACfWO.js +1 -0
  62. package/dist/ui/dist/assets/calendar-B-KZ9RQO.js +1 -0
  63. package/dist/ui/dist/assets/card-CNf6BS2e.js +1 -0
  64. package/dist/ui/dist/assets/chevron-left-D4U-5A27.js +1 -0
  65. package/dist/ui/dist/assets/chevron-right-CR4Skrf3.js +1 -0
  66. package/dist/ui/dist/assets/chevron-up-BYhk0K2J.js +1 -0
  67. package/dist/ui/dist/assets/circle-alert-CyHDwUj8.js +1 -0
  68. package/dist/ui/dist/assets/circle-check-Bb54Ebmu.js +1 -0
  69. package/dist/ui/dist/assets/cpu-Cdgc_B1K.js +1 -0
  70. package/dist/ui/dist/assets/dialog-QnZ0ad8O.js +1 -0
  71. package/dist/ui/dist/assets/download-C3ifGMjJ.js +1 -0
  72. package/dist/ui/dist/assets/dropdown-menu-BK-CO3Od.js +1 -0
  73. package/dist/ui/dist/assets/es-NQNoaWDx.js +1 -0
  74. package/dist/ui/dist/assets/external-link-BvxYeTP1.js +1 -0
  75. package/dist/ui/dist/assets/eye-DqNTU_GD.js +1 -0
  76. package/dist/ui/dist/assets/file-text-BT_9S9SM.js +1 -0
  77. package/dist/ui/dist/assets/folder-open-BhH8y9ac.js +1 -0
  78. package/dist/ui/dist/assets/format-GVHeOyWI.js +1 -0
  79. package/dist/ui/dist/assets/gateway-url-COCbW0IR.js +1 -0
  80. package/dist/ui/dist/assets/gauge-D_TMa4i9.js +1 -0
  81. package/dist/ui/dist/assets/globe-DeCQTCDJ.js +1 -0
  82. package/dist/ui/dist/assets/hexagon-DsGOUl-H.js +1 -0
  83. package/dist/ui/dist/assets/history-BSG-Ypqf.js +1 -0
  84. package/dist/ui/dist/assets/index-B2fCYtTS.css +2 -0
  85. package/dist/ui/dist/assets/index-DMCjjdqf.js +116 -0
  86. package/dist/ui/dist/assets/info-NwLoa2Mj.js +1 -0
  87. package/dist/ui/dist/assets/key-3EP0dhkT.js +1 -0
  88. package/dist/ui/dist/assets/label-D2H1IR_J.js +1 -0
  89. package/dist/ui/dist/assets/loader-circle-CZNax6kS.js +1 -0
  90. package/dist/ui/dist/assets/lock-Ei1_J-Nq.js +1 -0
  91. package/dist/ui/dist/assets/pause-BUqah9Bi.js +1 -0
  92. package/dist/ui/dist/assets/play-NcZ4swwL.js +1 -0
  93. package/dist/ui/dist/assets/plus-CX1xyhp5.js +1 -0
  94. package/dist/ui/dist/assets/progress-BherYzY6.js +1 -0
  95. package/dist/ui/dist/assets/refresh-cw-DaYdjQFk.js +1 -0
  96. package/dist/ui/dist/assets/rolldown-runtime-S-ySWqyJ.js +1 -0
  97. package/dist/ui/dist/assets/save-CUdYyHNy.js +1 -0
  98. package/dist/ui/dist/assets/scroll-area-DkeyX32e.js +1 -0
  99. package/dist/ui/dist/assets/send-B0H5SEIE.js +1 -0
  100. package/dist/ui/dist/assets/settings-Ds4SqD8s.js +1 -0
  101. package/dist/ui/dist/assets/slider-CsiUDxc3.js +14 -0
  102. package/dist/ui/dist/assets/sparkles-yUEb-7oH.js +1 -0
  103. package/dist/ui/dist/assets/square-BD81nFtN.js +1 -0
  104. package/dist/ui/dist/assets/switch-BDwN8RYV.js +1 -0
  105. package/dist/ui/dist/assets/table-CSc8ubon.js +1 -0
  106. package/dist/ui/dist/assets/terminal-DN38Q456.js +1 -0
  107. package/dist/ui/dist/assets/textarea-CXgXWKrT.js +1 -0
  108. package/dist/ui/dist/assets/trash-2-CNjMkoq6.js +1 -0
  109. package/dist/ui/dist/assets/triangle-alert-C9Y8Ub4X.js +1 -0
  110. package/dist/ui/dist/assets/useProviders-C6_QHsEi.js +1 -0
  111. package/dist/ui/dist/assets/utils-3pnRFmFe.js +1 -0
  112. package/dist/ui/dist/assets/vendor-charts-Bu2lyBKP.js +65 -0
  113. package/dist/ui/dist/assets/vendor-query-DsWPbQdG.js +1 -0
  114. package/dist/ui/dist/assets/vendor-radix-cw1bQaVC.js +63 -0
  115. package/dist/ui/dist/assets/vendor-react-D4s9E-zj.js +1 -0
  116. package/dist/ui/dist/assets/vendor-router-C9pIYwbJ.js +3 -0
  117. package/dist/ui/dist/assets/volume-2-CeSXNDv4.js +1 -0
  118. package/dist/ui/dist/assets/zap-hlXjpSeA.js +1 -0
  119. package/dist/ui/dist/favicon.ico +0 -0
  120. package/dist/ui/dist/index.html +40 -0
  121. package/dist/ui/dist/placeholder.svg +1 -0
  122. package/dist/ui/index.html +6 -6
  123. package/package.json +138 -13
  124. package/packages/cli/src/adapters/binary.ts +461 -0
  125. package/packages/cli/src/adapters/bun-global.ts +378 -0
  126. package/packages/cli/src/adapters/config.ts +314 -0
  127. package/packages/cli/src/adapters/docker.ts +308 -0
  128. package/packages/cli/src/adapters/factory.ts +168 -0
  129. package/packages/cli/src/adapters/index.ts +80 -0
  130. package/packages/cli/src/adapters/types.ts +218 -0
  131. package/packages/cli/src/commands/agent-run.ts +168 -0
  132. package/packages/cli/src/commands/agents.ts +398 -0
  133. package/packages/cli/src/commands/chat.ts +142 -0
  134. package/packages/cli/src/commands/config.ts +49 -0
  135. package/packages/cli/src/commands/cron.ts +487 -0
  136. package/packages/cli/src/commands/dev.ts +58 -0
  137. package/packages/cli/src/commands/doctor.ts +320 -0
  138. package/packages/cli/src/commands/gateway.ts +719 -0
  139. package/packages/cli/src/commands/logs.ts +57 -0
  140. package/packages/cli/src/commands/mcp.ts +175 -0
  141. package/packages/cli/src/commands/message.ts +77 -0
  142. package/packages/cli/src/commands/migrate.ts +90 -0
  143. package/packages/cli/src/commands/onboard.ts +1656 -0
  144. package/packages/cli/src/commands/security.ts +144 -0
  145. package/packages/cli/src/commands/service.ts +50 -0
  146. package/packages/cli/src/commands/sessions.ts +116 -0
  147. package/packages/cli/src/commands/skills.ts +215 -0
  148. package/packages/cli/src/commands/update.ts +203 -0
  149. package/packages/cli/src/index.ts +210 -0
  150. package/packages/cli/src/ui-bundle.generated.ts +3 -0
  151. package/packages/cli/src/utils/token.ts +6 -0
  152. package/packages/core/src/agent/agent-loop.ts +691 -0
  153. package/packages/core/src/agent/compaction.ts +240 -0
  154. package/packages/core/src/agent/context-compiler.ts +467 -0
  155. package/packages/core/src/agent/context-guard.ts +91 -0
  156. package/packages/core/src/agent/conversation-store.ts +244 -0
  157. package/packages/core/src/agent/curator.ts +158 -0
  158. package/packages/core/src/agent/hooks.ts +166 -0
  159. package/packages/core/src/agent/llm-client.ts +167 -0
  160. package/packages/core/src/agent/llm-providers/anthropic.ts +212 -0
  161. package/packages/core/src/agent/llm-providers/deepseek.ts +8 -0
  162. package/packages/core/src/agent/llm-providers/gemini.ts +215 -0
  163. package/packages/core/src/agent/llm-providers/groq.ts +5 -0
  164. package/packages/core/src/agent/llm-providers/interface.ts +195 -0
  165. package/packages/core/src/agent/llm-providers/kimi.ts +8 -0
  166. package/packages/core/src/agent/llm-providers/local-llama.ts +37 -0
  167. package/packages/core/src/agent/llm-providers/mistral.ts +5 -0
  168. package/packages/core/src/agent/llm-providers/nvidia.ts +5 -0
  169. package/packages/core/src/agent/llm-providers/ollama.ts +175 -0
  170. package/packages/core/src/agent/llm-providers/openai-compat-base.ts +379 -0
  171. package/packages/core/src/agent/llm-providers/openai.ts +5 -0
  172. package/packages/core/src/agent/llm-providers/openrouter.ts +5 -0
  173. package/packages/core/src/agent/llm-providers/qwen.ts +5 -0
  174. package/packages/core/src/agent/native-tools.ts +31 -0
  175. package/packages/core/src/agent/playbook-selector.ts +147 -0
  176. package/packages/core/src/agent/prompt-builder.ts +169 -0
  177. package/packages/core/src/agent/providers/index.ts +204 -0
  178. package/packages/core/src/agent/providers.ts +1 -0
  179. package/packages/core/src/agent/reflector.ts +200 -0
  180. package/packages/core/src/agent/service.ts +267 -0
  181. package/packages/core/src/agent/skill-selector.ts +479 -0
  182. package/packages/core/src/agent/stuck-loop.ts +133 -0
  183. package/packages/core/src/agent/tool-selector.ts +569 -0
  184. package/packages/core/src/agent/tracer.ts +100 -0
  185. package/packages/core/src/auth/auth.ts +108 -0
  186. package/packages/core/src/auth/index.ts +1 -0
  187. package/packages/core/src/canvas/a2ui-tools.ts +255 -0
  188. package/packages/core/src/canvas/canvas-manager.ts +390 -0
  189. package/packages/core/src/canvas/canvas-tools.ts +448 -0
  190. package/packages/core/src/canvas/emitter.ts +149 -0
  191. package/packages/core/src/canvas/index.ts +3 -0
  192. package/packages/core/src/channels/base.ts +154 -0
  193. package/packages/core/src/channels/discord.ts +273 -0
  194. package/packages/core/src/channels/index.ts +7 -0
  195. package/packages/core/src/channels/manager.ts +450 -0
  196. package/packages/core/src/channels/slack.ts +323 -0
  197. package/packages/core/src/channels/telegram.ts +612 -0
  198. package/packages/core/src/channels/webchat.ts +139 -0
  199. package/packages/core/src/channels/whatsapp.ts +548 -0
  200. package/packages/core/src/config/index.ts +12 -0
  201. package/packages/core/src/config/loader.ts +569 -0
  202. package/packages/core/src/events/agent-bus.ts +460 -0
  203. package/packages/core/src/events/event-bus.ts +169 -0
  204. package/packages/core/src/gateway/channel-notify.ts +64 -0
  205. package/packages/core/src/gateway/helpers/cors.ts +32 -0
  206. package/packages/core/src/gateway/helpers/index.ts +4 -0
  207. package/packages/core/src/gateway/helpers/narration.ts +57 -0
  208. package/packages/core/src/gateway/helpers/path.ts +13 -0
  209. package/packages/core/src/gateway/helpers/redact.ts +61 -0
  210. package/packages/core/src/gateway/index.ts +5 -0
  211. package/packages/core/src/gateway/initializer.ts +363 -0
  212. package/packages/core/src/gateway/lane-queue.ts +169 -0
  213. package/packages/core/src/gateway/llm-local/client.ts +94 -0
  214. package/packages/core/src/gateway/llm-local/detector.ts +321 -0
  215. package/packages/core/src/gateway/llm-local/downloader.ts +216 -0
  216. package/packages/core/src/gateway/llm-local/index.ts +34 -0
  217. package/packages/core/src/gateway/llm-local/manager.ts +186 -0
  218. package/packages/core/src/gateway/llm-local/models.ts +149 -0
  219. package/packages/core/src/gateway/llm-local/server.ts +179 -0
  220. package/packages/core/src/gateway/resolver.ts +108 -0
  221. package/packages/core/src/gateway/router.ts +124 -0
  222. package/packages/core/src/gateway/routes/agents.ts +210 -0
  223. package/packages/core/src/gateway/routes/auth.ts +244 -0
  224. package/packages/core/src/gateway/routes/channels.ts +484 -0
  225. package/packages/core/src/gateway/routes/chat.ts +241 -0
  226. package/packages/core/src/gateway/routes/config.ts +12 -0
  227. package/packages/core/src/gateway/routes/cron-api.ts +544 -0
  228. package/packages/core/src/gateway/routes/ethics.ts +46 -0
  229. package/packages/core/src/gateway/routes/llm-local.ts +271 -0
  230. package/packages/core/src/gateway/routes/mcp.ts +319 -0
  231. package/packages/core/src/gateway/routes/meeting.ts +232 -0
  232. package/packages/core/src/gateway/routes/models.ts +163 -0
  233. package/packages/core/src/gateway/routes/multimodal.ts +93 -0
  234. package/packages/core/src/gateway/routes/providers.ts +220 -0
  235. package/packages/core/src/gateway/routes/setup.ts +441 -0
  236. package/packages/core/src/gateway/routes/skills.ts +115 -0
  237. package/packages/core/src/gateway/routes/system.ts +469 -0
  238. package/packages/core/src/gateway/routes/tasks.ts +44 -0
  239. package/packages/core/src/gateway/routes/tools.ts +59 -0
  240. package/packages/core/src/gateway/routes/tts-local.ts +388 -0
  241. package/packages/core/src/gateway/routes/users.ts +122 -0
  242. package/packages/core/src/gateway/routes/voice.ts +189 -0
  243. package/packages/core/src/gateway/routes/workspace.ts +281 -0
  244. package/packages/core/src/gateway/server.ts +2744 -0
  245. package/packages/core/src/gateway/session.ts +95 -0
  246. package/packages/core/src/gateway/slash-commands.ts +207 -0
  247. package/packages/core/src/gateway/tts/README.md +94 -0
  248. package/packages/core/src/gateway/tts/package.json +25 -0
  249. package/packages/core/src/gateway/tts/src/client.ts +59 -0
  250. package/packages/core/src/gateway/tts/src/detect.ts +42 -0
  251. package/packages/core/src/gateway/tts/src/index.ts +15 -0
  252. package/packages/core/src/gateway/tts/src/install.ts +129 -0
  253. package/packages/core/src/gateway/tts/src/models.ts +50 -0
  254. package/packages/core/src/gateway/tts/src/server.ts +252 -0
  255. package/packages/core/src/gateway/tts/voices/.gitkeep +0 -0
  256. package/packages/core/src/heartbeat/index.ts +157 -0
  257. package/packages/core/src/index.ts +56 -0
  258. package/packages/core/src/mcp/hot-reload.ts +148 -0
  259. package/packages/core/src/mcp/singleton.ts +21 -0
  260. package/packages/core/src/mcp/tool-sync.ts +176 -0
  261. package/packages/core/src/multimodal/index.ts +2 -0
  262. package/packages/core/src/multimodal/types.ts +28 -0
  263. package/packages/core/src/multimodal/vision-service.ts +283 -0
  264. package/packages/core/src/plugins/api.ts +128 -0
  265. package/packages/core/src/plugins/index.ts +2 -0
  266. package/packages/core/src/plugins/loader.ts +365 -0
  267. package/packages/core/src/resilience/circuit-breaker.ts +225 -0
  268. package/packages/core/src/scheduler/CronScheduler.ts +699 -0
  269. package/packages/core/src/scheduler/dag/AgentExecutor.ts +53 -0
  270. package/packages/core/src/scheduler/dag/DAGScheduler.ts +250 -0
  271. package/packages/core/src/scheduler/dag/EventBridge.ts +122 -0
  272. package/packages/core/src/scheduler/dag/TaskGraph.ts +192 -0
  273. package/packages/core/src/scheduler/dag/TaskNode.ts +97 -0
  274. package/packages/core/src/scheduler/dag/TaskResult.ts +22 -0
  275. package/packages/core/src/scheduler/dag/errors.ts +37 -0
  276. package/packages/core/src/scheduler/dag/index.ts +26 -0
  277. package/packages/core/src/scheduler/dag/presets/ResearchPreset.ts +97 -0
  278. package/packages/core/src/scheduler/dag/strategies/ParallelStrategy.ts +21 -0
  279. package/packages/core/src/scheduler/dag/strategies/PriorityStrategy.ts +46 -0
  280. package/packages/core/src/scheduler/index.ts +22 -0
  281. package/packages/core/src/scheduler/integration.ts +237 -0
  282. package/packages/core/src/scheduler/types.ts +164 -0
  283. package/packages/core/src/security/google-chat.ts +269 -0
  284. package/packages/core/src/security/index.ts +192 -0
  285. package/packages/core/src/security/pairing.ts +250 -0
  286. package/packages/core/src/security/rate-limit.ts +270 -0
  287. package/packages/core/src/security/signal.ts +321 -0
  288. package/packages/core/src/state/store.ts +312 -0
  289. package/packages/core/src/storage/crypto.ts +197 -0
  290. package/packages/core/src/storage/migrate.ts +147 -0
  291. package/packages/core/src/storage/onboarding.ts +1506 -0
  292. package/packages/core/src/storage/schema.ts +666 -0
  293. package/packages/core/src/storage/seed.ts +628 -0
  294. package/packages/core/src/storage/sqlite.ts +407 -0
  295. package/packages/core/src/storage/usage.ts +374 -0
  296. package/packages/core/src/tool-runtime/index.ts +502 -0
  297. package/packages/core/src/tool-runtime/tool-worker.ts +125 -0
  298. package/packages/core/src/tools/agents/get-available-models.ts +118 -0
  299. package/packages/core/src/tools/agents/index.ts +610 -0
  300. package/packages/core/src/tools/canvas/index.ts +420 -0
  301. package/packages/core/src/tools/cli/index.ts +142 -0
  302. package/packages/core/src/tools/core/index.ts +478 -0
  303. package/packages/core/src/tools/cron/index.ts +635 -0
  304. package/packages/core/src/tools/filesystem/fs-delete.ts +78 -0
  305. package/packages/core/src/tools/filesystem/fs-edit.ts +106 -0
  306. package/packages/core/src/tools/filesystem/fs-exists.ts +63 -0
  307. package/packages/core/src/tools/filesystem/fs-glob.ts +108 -0
  308. package/packages/core/src/tools/filesystem/fs-list.ts +129 -0
  309. package/packages/core/src/tools/filesystem/fs-read.ts +72 -0
  310. package/packages/core/src/tools/filesystem/fs-write.ts +67 -0
  311. package/packages/core/src/tools/filesystem/index.ts +34 -0
  312. package/packages/core/src/tools/filesystem/workspace-guard.ts +62 -0
  313. package/packages/core/src/tools/index.ts +197 -0
  314. package/packages/core/src/tools/meeting/index.ts +363 -0
  315. package/packages/core/src/tools/office/index.ts +47 -0
  316. package/packages/core/src/tools/office/office-escribir-docx.ts +192 -0
  317. package/packages/core/src/tools/office/office-escribir-pdf.ts +172 -0
  318. package/packages/core/src/tools/office/office-escribir-pptx.ts +174 -0
  319. package/packages/core/src/tools/office/office-escribir-xlsx.ts +116 -0
  320. package/packages/core/src/tools/office/office-leer-docx.ts +93 -0
  321. package/packages/core/src/tools/office/office-leer-pdf.ts +114 -0
  322. package/packages/core/src/tools/office/office-leer-pptx.ts +136 -0
  323. package/packages/core/src/tools/office/office-leer-xlsx.ts +124 -0
  324. package/packages/core/src/tools/types.ts +39 -0
  325. package/packages/core/src/tools/voice/index.ts +104 -0
  326. package/packages/core/src/tools/web/browser-click.ts +78 -0
  327. package/packages/core/src/tools/web/browser-extract.ts +139 -0
  328. package/packages/core/src/tools/web/browser-navigate.ts +106 -0
  329. package/packages/core/src/tools/web/browser-screenshot.ts +87 -0
  330. package/packages/core/src/tools/web/browser-script.ts +88 -0
  331. package/packages/core/src/tools/web/browser-service.ts +554 -0
  332. package/packages/core/src/tools/web/browser-type.ts +101 -0
  333. package/packages/core/src/tools/web/browser-wait.ts +136 -0
  334. package/packages/core/src/tools/web/index.ts +41 -0
  335. package/packages/core/src/tools/web/web-fetch.ts +78 -0
  336. package/packages/core/src/tools/web/web-search.ts +123 -0
  337. package/packages/core/src/utils/benchmark.ts +80 -0
  338. package/packages/core/src/utils/crypto.ts +73 -0
  339. package/packages/core/src/utils/date.ts +42 -0
  340. package/packages/core/src/utils/index.ts +5 -0
  341. package/packages/core/src/utils/logger.ts +389 -0
  342. package/packages/core/src/utils/retry.ts +70 -0
  343. package/packages/core/src/utils/toon.ts +253 -0
  344. package/packages/core/src/voice/index.ts +643 -0
  345. package/packages/mcp/src/config.ts +13 -0
  346. package/packages/mcp/src/index.ts +1 -0
  347. package/packages/mcp/src/logger.ts +47 -0
  348. package/packages/mcp/src/manager.ts +439 -0
  349. package/packages/mcp/src/transports/index.ts +67 -0
  350. package/packages/mcp/src/transports/sse.ts +238 -0
  351. package/packages/mcp/src/transports/websocket.ts +159 -0
  352. package/packages/skills/src/bundled/agents/agent_spawner/SKILL.md +167 -0
  353. package/packages/skills/src/bundled/agents/code_delegator/SKILL.md +156 -0
  354. package/packages/skills/src/bundled/agents/memory_manager/SKILL.md +143 -0
  355. package/packages/skills/src/bundled/agents/research_and_remember/SKILL.md +139 -0
  356. package/packages/skills/src/bundled/agents/task_orchestrator/SKILL.md +198 -0
  357. package/packages/skills/src/bundled/canvas/a2ui_dashboard/SKILL.md +176 -0
  358. package/packages/skills/src/bundled/canvas/a2ui_form/SKILL.md +202 -0
  359. package/packages/skills/src/bundled/canvas/a2ui_interactive/SKILL.md +206 -0
  360. package/packages/skills/src/bundled/canvas/canvas_dashboard/SKILL.md +146 -0
  361. package/packages/skills/src/bundled/canvas/canvas_interact/SKILL.md +148 -0
  362. package/packages/skills/src/bundled/canvas/canvas_report/SKILL.md +146 -0
  363. package/packages/skills/src/bundled/cli/cli_pipeline/SKILL.md +136 -0
  364. package/packages/skills/src/bundled/cli/cli_safe_exec/SKILL.md +125 -0
  365. package/packages/skills/src/bundled/cron_manager/SKILL.md +188 -0
  366. package/packages/skills/src/bundled/cron_reminder/SKILL.md +112 -0
  367. package/packages/skills/src/bundled/filesystem/file_manager/SKILL.md +118 -0
  368. package/packages/skills/src/bundled/filesystem/file_read_and_summarize/SKILL.md +108 -0
  369. package/packages/skills/src/bundled/filesystem/file_writer/SKILL.md +135 -0
  370. package/packages/skills/src/bundled/meeting/meeting_transcription/SKILL.md +213 -0
  371. package/packages/skills/src/bundled/office/office_document_manager/SKILL.md +262 -0
  372. package/packages/skills/src/bundled/search_knowledge/busqueda_fts5/SKILL.md +74 -0
  373. package/packages/skills/src/bundled/voice/voice_assistant/SKILL.md +174 -0
  374. package/packages/skills/src/bundled/voice/voice_input/SKILL.md +146 -0
  375. package/packages/skills/src/bundled/voice/voice_output/SKILL.md +151 -0
  376. package/packages/skills/src/bundled/web/browser_automate/SKILL.md +120 -0
  377. package/packages/skills/src/bundled/web/browser_scrape/SKILL.md +109 -0
  378. package/packages/skills/src/bundled/web/web_monitor/SKILL.md +127 -0
  379. package/packages/skills/src/bundled/web/web_research/SKILL.md +119 -0
  380. package/packages/skills/src/bundled-data.generated.ts +1964 -0
  381. package/packages/skills/src/index.ts +1 -0
  382. package/packages/skills/src/loader.ts +388 -0
  383. package/dist/ui/assets/AgentNewPage-GB-tVN50.js +0 -1
  384. package/dist/ui/assets/BridgePage-DDcDILKu.js +0 -1
  385. package/dist/ui/assets/CanvasPage-oOk2sGOD.js +0 -33
  386. package/dist/ui/assets/DashboardPage-DV_2qWYJ.js +0 -6
  387. package/dist/ui/assets/LogsPage-DayYjh01.js +0 -1
  388. package/dist/ui/assets/MeetingPage-C01uPuqj.js +0 -1
  389. package/dist/ui/assets/ProjectsPage-B8_am_Ib.js +0 -1
  390. package/dist/ui/assets/ProvidersPage-DBzi66e4.js +0 -1
  391. package/dist/ui/assets/SettingsPage-CFA_Tknl.js +0 -9
  392. package/dist/ui/assets/SetupPage-BrUWbhvT.js +0 -1
  393. package/dist/ui/assets/accordion-DdAEfIXR.js +0 -1
  394. package/dist/ui/assets/chevron-down-DIosfU_U.js +0 -1
  395. package/dist/ui/assets/chevron-up-CI-W21Fy.js +0 -1
  396. package/dist/ui/assets/circle-S0-ouLz-.js +0 -1
  397. package/dist/ui/assets/circle-minus-CE0iJrl8.js +0 -1
  398. package/dist/ui/assets/circle-x-jUJ5zZvQ.js +0 -1
  399. package/dist/ui/assets/dropdown-menu-C2CXM1VE.js +0 -1
  400. package/dist/ui/assets/index-BN0875JH.css +0 -2
  401. package/dist/ui/assets/index-CH6sBa3Q.js +0 -116
  402. package/dist/ui/assets/pencil-5VdSj-h5.js +0 -1
  403. package/dist/ui/assets/progress-JN30I5fF.js +0 -1
  404. package/dist/ui/assets/scroll-area-BQQPitM8.js +0 -1
  405. package/dist/ui/assets/search-ChPgnVKj.js +0 -1
  406. package/dist/ui/assets/switch-C7W2-KEx.js +0 -1
  407. package/dist/ui/assets/terminal-C-R5Fckz.js +0 -1
  408. package/dist/ui/assets/useProviders-TBnWn-Hq.js +0 -1
  409. /package/dist/ui/assets/{card-DFKnZ6ky.js → card-CNf6BS2e.js} +0 -0
  410. /package/dist/ui/assets/{circle-alert-KuAm2FWh.js → circle-alert-CyHDwUj8.js} +0 -0
  411. /package/dist/ui/assets/{circle-check-6Ard1-2z.js → circle-check-Bb54Ebmu.js} +0 -0
  412. /package/dist/ui/assets/{cpu-KDy6-FAI.js → cpu-Cdgc_B1K.js} +0 -0
  413. /package/dist/ui/assets/{download-Cjbk4Rek.js → download-C3ifGMjJ.js} +0 -0
  414. /package/dist/ui/assets/{external-link-HtrFM63g.js → external-link-BvxYeTP1.js} +0 -0
  415. /package/dist/ui/assets/{eye-D1dB40_o.js → eye-DqNTU_GD.js} +0 -0
  416. /package/dist/ui/assets/{file-text-CE58EfH0.js → file-text-BT_9S9SM.js} +0 -0
  417. /package/dist/ui/assets/{folder-open-DIPKeiI_.js → folder-open-BhH8y9ac.js} +0 -0
  418. /package/dist/ui/assets/{format-BwdV8bB5.js → format-GVHeOyWI.js} +0 -0
  419. /package/dist/ui/assets/{gateway-url-D5uj6Nxg.js → gateway-url-COCbW0IR.js} +0 -0
  420. /package/dist/ui/assets/{gauge-DmQmJHEg.js → gauge-D_TMa4i9.js} +0 -0
  421. /package/dist/ui/assets/{globe-_hUGxQF4.js → globe-DeCQTCDJ.js} +0 -0
  422. /package/dist/ui/assets/{hexagon-BaNGQlQj.js → hexagon-DsGOUl-H.js} +0 -0
  423. /package/dist/ui/assets/{history-BfZVGlZa.js → history-BSG-Ypqf.js} +0 -0
  424. /package/dist/ui/assets/{info-CBZ5-AlC.js → info-NwLoa2Mj.js} +0 -0
  425. /package/dist/ui/assets/{key-Bv5DdTPh.js → key-3EP0dhkT.js} +0 -0
  426. /package/dist/ui/assets/{loader-circle-C4hhXLgp.js → loader-circle-CZNax6kS.js} +0 -0
  427. /package/dist/ui/assets/{lock-CkZYexqw.js → lock-Ei1_J-Nq.js} +0 -0
  428. /package/dist/ui/assets/{pause-Bpy1_s7y.js → pause-BUqah9Bi.js} +0 -0
  429. /package/dist/ui/assets/{play-Cj4osqJZ.js → play-NcZ4swwL.js} +0 -0
  430. /package/dist/ui/assets/{plus-BQhgZN3A.js → plus-CX1xyhp5.js} +0 -0
  431. /package/dist/ui/assets/{refresh-cw-BfREHVQM.js → refresh-cw-DaYdjQFk.js} +0 -0
  432. /package/dist/ui/assets/{save-FFTD4dMp.js → save-CUdYyHNy.js} +0 -0
  433. /package/dist/ui/assets/{settings-BdHKUL92.js → settings-Ds4SqD8s.js} +0 -0
  434. /package/dist/ui/assets/{sparkles-r4uJbJAl.js → sparkles-yUEb-7oH.js} +0 -0
  435. /package/dist/ui/assets/{square-G7Hyufqm.js → square-BD81nFtN.js} +0 -0
  436. /package/dist/ui/assets/{textarea-5kyuD04X.js → textarea-CXgXWKrT.js} +0 -0
  437. /package/dist/ui/assets/{trash-2-DXVBRWfh.js → trash-2-CNjMkoq6.js} +0 -0
  438. /package/dist/ui/assets/{triangle-alert-Bu5seg9O.js → triangle-alert-C9Y8Ub4X.js} +0 -0
  439. /package/dist/ui/assets/{vendor-router-CCECILJ0.js → vendor-router-C9pIYwbJ.js} +0 -0
  440. /package/dist/ui/assets/{volume-2-s9DuS696.js → volume-2-CeSXNDv4.js} +0 -0
  441. /package/dist/ui/assets/{zap-BPHZzXKV.js → zap-hlXjpSeA.js} +0 -0
@@ -0,0 +1,232 @@
1
+ import { getDb } from "../../storage/sqlite";
2
+ import { voiceService, type AudioInput } from "../../voice/index";
3
+ import { logger } from "../../utils/logger";
4
+
5
+ const log = logger.child("meeting-routes");
6
+
7
+ type CorsHelper = (r: Response, req: Request) => Response;
8
+
9
+ // POST /api/meetings — Crear sesión
10
+ export async function handleCreateMeeting(
11
+ req: Request,
12
+ addCorsHeaders: CorsHelper
13
+ ): Promise<Response> {
14
+ try {
15
+ const body = await req.json().catch(() => ({})) as Record<string, unknown>;
16
+ const title = (body.title as string) || "Reunión sin título";
17
+ const sttModel = (body.stt_model as string) || "whisper-large-v3-turbo";
18
+
19
+ const db = getDb();
20
+ const result = db
21
+ .query(
22
+ `INSERT INTO meeting_sessions (title, stt_model)
23
+ VALUES (?, ?)
24
+ RETURNING id, title, status, stt_model, started_at`
25
+ )
26
+ .get(title, sttModel) as {
27
+ id: string;
28
+ title: string;
29
+ status: string;
30
+ stt_model: string;
31
+ started_at: number;
32
+ };
33
+
34
+ log.info(`Meeting session created: ${result.id}`);
35
+ return addCorsHeaders(Response.json({ ok: true, session: result }), req);
36
+ } catch (error) {
37
+ log.error(`handleCreateMeeting: ${(error as Error).message}`);
38
+ return addCorsHeaders(
39
+ Response.json({ ok: false, error: (error as Error).message }, { status: 500 }),
40
+ req
41
+ );
42
+ }
43
+ }
44
+
45
+ // GET /api/meetings — Listar sesiones
46
+ export async function handleListMeetings(
47
+ req: Request,
48
+ addCorsHeaders: CorsHelper
49
+ ): Promise<Response> {
50
+ try {
51
+ const db = getDb();
52
+ const sessions = db
53
+ .query(
54
+ `SELECT ms.*, COUNT(seg.id) as segment_count
55
+ FROM meeting_sessions ms
56
+ LEFT JOIN meeting_segments seg ON seg.session_id = ms.id
57
+ GROUP BY ms.id
58
+ ORDER BY ms.started_at DESC
59
+ LIMIT 50`
60
+ )
61
+ .all() as Record<string, unknown>[];
62
+
63
+ return addCorsHeaders(Response.json({ ok: true, sessions }), req);
64
+ } catch (error) {
65
+ log.error(`handleListMeetings: ${(error as Error).message}`);
66
+ return addCorsHeaders(
67
+ Response.json({ ok: false, error: (error as Error).message }, { status: 500 }),
68
+ req
69
+ );
70
+ }
71
+ }
72
+
73
+ // GET /api/meetings/:id — Detalle + segmentos
74
+ export async function handleGetMeeting(
75
+ req: Request,
76
+ addCorsHeaders: CorsHelper,
77
+ sessionId: string
78
+ ): Promise<Response> {
79
+ try {
80
+ const db = getDb();
81
+ const session = db
82
+ .query(`SELECT * FROM meeting_sessions WHERE id = ?`)
83
+ .get(sessionId) as Record<string, unknown> | undefined;
84
+
85
+ if (!session) {
86
+ return addCorsHeaders(
87
+ Response.json({ ok: false, error: "Sesión no encontrada" }, { status: 404 }),
88
+ req
89
+ );
90
+ }
91
+
92
+ const segments = db
93
+ .query(
94
+ `SELECT seq, speaker, text, created_at FROM meeting_segments
95
+ WHERE session_id = ? ORDER BY seq ASC`
96
+ )
97
+ .all(sessionId) as Record<string, unknown>[];
98
+
99
+ return addCorsHeaders(Response.json({ ok: true, session, segments }), req);
100
+ } catch (error) {
101
+ log.error(`handleGetMeeting: ${(error as Error).message}`);
102
+ return addCorsHeaders(
103
+ Response.json({ ok: false, error: (error as Error).message }, { status: 500 }),
104
+ req
105
+ );
106
+ }
107
+ }
108
+
109
+ // POST /api/meetings/:id/segments — Agregar segmento con audio base64
110
+ export async function handleAddMeetingSegment(
111
+ req: Request,
112
+ addCorsHeaders: CorsHelper,
113
+ sessionId: string
114
+ ): Promise<Response> {
115
+ try {
116
+ const body = await req.json().catch(() => ({})) as Record<string, unknown>;
117
+ const audioBase64 = body.audio_base64 as string;
118
+ const speaker = (body.speaker as string) || null;
119
+ const mimeType = (body.mime_type as string) || "audio/webm";
120
+
121
+ if (!audioBase64) {
122
+ return addCorsHeaders(
123
+ Response.json({ ok: false, error: "audio_base64 es requerido" }, { status: 400 }),
124
+ req
125
+ );
126
+ }
127
+
128
+ const db = getDb();
129
+ const session = db
130
+ .query(`SELECT id, stt_model, status FROM meeting_sessions WHERE id = ?`)
131
+ .get(sessionId) as { id: string; stt_model: string; status: string } | undefined;
132
+
133
+ if (!session) {
134
+ return addCorsHeaders(
135
+ Response.json({ ok: false, error: "Sesión no encontrada" }, { status: 404 }),
136
+ req
137
+ );
138
+ }
139
+ if (session.status !== "active") {
140
+ return addCorsHeaders(
141
+ Response.json(
142
+ { ok: false, error: `La sesión está ${session.status}` },
143
+ { status: 409 }
144
+ ),
145
+ req
146
+ );
147
+ }
148
+
149
+ const audioInput: AudioInput = { type: "base64", data: audioBase64, mimeType };
150
+ const transcription = await voiceService.transcribe(audioInput, session.stt_model);
151
+
152
+ const seqResult = db
153
+ .query(
154
+ `SELECT COALESCE(MAX(seq) + 1, 0) as next_seq FROM meeting_segments WHERE session_id = ?`
155
+ )
156
+ .get(sessionId) as { next_seq: number };
157
+
158
+ const seq = seqResult.next_seq;
159
+ db.query(
160
+ `INSERT INTO meeting_segments (session_id, seq, speaker, text) VALUES (?, ?, ?, ?)`
161
+ ).run(sessionId, seq, speaker, transcription);
162
+
163
+ return addCorsHeaders(
164
+ Response.json({ ok: true, seq, speaker, text: transcription }),
165
+ req
166
+ );
167
+ } catch (error) {
168
+ log.error(`handleAddMeetingSegment: ${(error as Error).message}`);
169
+ return addCorsHeaders(
170
+ Response.json({ ok: false, error: (error as Error).message }, { status: 500 }),
171
+ req
172
+ );
173
+ }
174
+ }
175
+
176
+ // POST /api/meetings/:id/stop — Detener sesión
177
+ export async function handleStopMeeting(
178
+ req: Request,
179
+ addCorsHeaders: CorsHelper,
180
+ sessionId: string
181
+ ): Promise<Response> {
182
+ try {
183
+ const db = getDb();
184
+ const session = db
185
+ .query(`SELECT id, title, status FROM meeting_sessions WHERE id = ?`)
186
+ .get(sessionId) as { id: string; title: string; status: string } | undefined;
187
+
188
+ if (!session) {
189
+ return addCorsHeaders(
190
+ Response.json({ ok: false, error: "Sesión no encontrada" }, { status: 404 }),
191
+ req
192
+ );
193
+ }
194
+
195
+ if (session.status !== "active") {
196
+ const count = (
197
+ db
198
+ .query(`SELECT COUNT(*) as c FROM meeting_segments WHERE session_id = ?`)
199
+ .get(sessionId) as { c: number }
200
+ ).c;
201
+ return addCorsHeaders(
202
+ Response.json({ ok: true, session_id: sessionId, segment_count: count }),
203
+ req
204
+ );
205
+ }
206
+
207
+ db.query(
208
+ `UPDATE meeting_sessions SET status = 'stopped', stopped_at = unixepoch() WHERE id = ?`
209
+ ).run(sessionId);
210
+
211
+ const countResult = db
212
+ .query(`SELECT COUNT(*) as count FROM meeting_segments WHERE session_id = ?`)
213
+ .get(sessionId) as { count: number };
214
+
215
+ log.info(`Meeting stopped: ${sessionId} — ${countResult.count} segments`);
216
+ return addCorsHeaders(
217
+ Response.json({
218
+ ok: true,
219
+ session_id: sessionId,
220
+ title: session.title,
221
+ segment_count: countResult.count,
222
+ }),
223
+ req
224
+ );
225
+ } catch (error) {
226
+ log.error(`handleStopMeeting: ${(error as Error).message}`);
227
+ return addCorsHeaders(
228
+ Response.json({ ok: false, error: (error as Error).message }, { status: 500 }),
229
+ req
230
+ );
231
+ }
232
+ }
@@ -0,0 +1,163 @@
1
+ import { getDb } from "../../storage/sqlite.ts"
2
+ import type { Config } from "../../config/loader.ts"
3
+
4
+ export async function handleGetModels(req: Request, addCorsHeaders: (r: Response, req: Request) => Response): Promise<Response> {
5
+ const url = new URL(req.url)
6
+ const providerId = url.searchParams.get("provider_id")
7
+
8
+ let models
9
+ if (providerId) {
10
+ models = getDb().query("SELECT * FROM models WHERE provider_id = ? ORDER BY name").all(providerId)
11
+ } else {
12
+ models = getDb().query("SELECT * FROM models ORDER BY name").all()
13
+ }
14
+
15
+ return addCorsHeaders(Response.json({ models }), req)
16
+ }
17
+
18
+ export async function handleCreateModel(req: Request, addCorsHeaders: (r: Response, req: Request) => Response): Promise<Response> {
19
+ const body = await req.json().catch(() => ({}))
20
+
21
+ const providerId = body.provider_id || body.providerId
22
+ const name = body.name
23
+ const modelType = body.model_type || body.modelType || "llm"
24
+ const contextWindow = body.context_window || body.contextWindow || 50000
25
+
26
+ if (!name || !providerId) {
27
+ return addCorsHeaders(Response.json({ ok: false, error: "name and provider_id are required" }, { status: 400 }), req)
28
+ }
29
+
30
+ const id = body.id || name
31
+
32
+ const existing = getDb().query("SELECT * FROM models WHERE id = ?").get(id) as any
33
+ if (existing) {
34
+ return addCorsHeaders(Response.json({ ok: false, error: "Model already exists", id, model: existing }, { status: 409 }), req)
35
+ }
36
+
37
+ getDb().query(`
38
+ INSERT INTO models(id, name, provider_id, model_type, context_window, enabled, active)
39
+ VALUES(?, ?, ?, ?, ?, 1, 1)
40
+ `).run(id, name, providerId, modelType, contextWindow)
41
+
42
+ const model = getDb().query("SELECT * FROM models WHERE id = ?").get(id)
43
+ return addCorsHeaders(Response.json({ ok: true, id, model }, { status: 201 }), req)
44
+ }
45
+
46
+ export async function handleToggleModel(req: Request, addCorsHeaders: (r: Response, req: Request) => Response): Promise<Response> {
47
+ const url = new URL(req.url)
48
+ // URL pattern: /api/models/:id/toggle — extract model id from path
49
+ const pathMatch = url.pathname.match(/^\/api\/models\/([^/]+)\/toggle$/)
50
+ const modelId = pathMatch ? decodeURIComponent(pathMatch[1]) : null
51
+ const body = await req.json().catch(() => ({}))
52
+ const { active } = body
53
+
54
+ if (!modelId || active === undefined) {
55
+ return addCorsHeaders(Response.json({ success: false, error: "model id and active required" }), req)
56
+ }
57
+
58
+ getDb().query(`UPDATE models SET active = ?, enabled = ? WHERE id = ?`).run(active ? 1 : 0, active ? 1 : 0, modelId)
59
+
60
+ return addCorsHeaders(Response.json({ success: true, active }), req)
61
+ }
62
+
63
+ export async function handleGetModelsConfig(
64
+ req: Request,
65
+ addCorsHeaders: (r: Response, req: Request) => Response,
66
+ config: Config
67
+ ): Promise<Response> {
68
+ return addCorsHeaders(Response.json({
69
+ config: config.models || {},
70
+ availableProviders: ["openai", "anthropic", "gemini", "kimi", "ollama", "openrouter", "deepseek"],
71
+ }), req);
72
+ }
73
+
74
+ export async function handleDeleteModel(req: Request, addCorsHeaders: (r: Response, req: Request) => Response): Promise<Response> {
75
+ const url = new URL(req.url)
76
+ const pathMatch = url.pathname.match(/^\/api\/models\/([^/]+)$/)
77
+ const modelId = pathMatch ? decodeURIComponent(pathMatch[1]) : null
78
+
79
+ if (!modelId) {
80
+ return addCorsHeaders(Response.json({ ok: false, error: "model id required" }, { status: 400 }), req)
81
+ }
82
+
83
+ const existing = getDb().query("SELECT * FROM models WHERE id = ?").get(modelId) as any
84
+ if (!existing) {
85
+ return addCorsHeaders(Response.json({ ok: false, error: "Model not found" }, { status: 404 }), req)
86
+ }
87
+
88
+ const agents = getDb().query("SELECT id, name FROM agents WHERE model_id = ?").all(modelId) as any[]
89
+ if (agents.length > 0) {
90
+ const names = agents.map(a => a.name).join(", ")
91
+ return addCorsHeaders(Response.json({ ok: false, error: `En uso por agentes: ${names}` }, { status: 409 }), req)
92
+ }
93
+
94
+ getDb().query("DELETE FROM models WHERE id = ?").run(modelId)
95
+ return addCorsHeaders(Response.json({ ok: true }), req)
96
+ }
97
+
98
+ export async function handleUpdateModel(req: Request, addCorsHeaders: (r: Response, req: Request) => Response): Promise<Response> {
99
+ const url = new URL(req.url)
100
+ const pathMatch = url.pathname.match(/^\/api\/models\/([^/]+)$/)
101
+ const oldId = pathMatch ? decodeURIComponent(pathMatch[1]) : null
102
+
103
+ if (!oldId) {
104
+ return addCorsHeaders(Response.json({ ok: false, error: "model id required" }, { status: 400 }), req)
105
+ }
106
+
107
+ const existing = getDb().query("SELECT * FROM models WHERE id = ?").get(oldId) as any
108
+ if (!existing) {
109
+ return addCorsHeaders(Response.json({ ok: false, error: "Model not found" }, { status: 404 }), req)
110
+ }
111
+
112
+ const body = await req.json().catch(() => ({}))
113
+ const newId: string | undefined = body.id
114
+ const newName: string | undefined = body.name
115
+
116
+ if (!newId || newId === oldId) {
117
+ // Only name change
118
+ const name = newName || existing.name
119
+ getDb().query("UPDATE models SET name = ? WHERE id = ?").run(name, oldId)
120
+ const model = getDb().query("SELECT * FROM models WHERE id = ?").get(oldId)
121
+ return addCorsHeaders(Response.json({ ok: true, model }), req)
122
+ }
123
+
124
+ // ID is changing — use a transaction to migrate agents references
125
+ const checkConflict = getDb().query("SELECT id FROM models WHERE id = ?").get(newId) as any
126
+ if (checkConflict) {
127
+ return addCorsHeaders(Response.json({ ok: false, error: "Ya existe un modelo con ese ID" }, { status: 409 }), req)
128
+ }
129
+
130
+ const name = newName || existing.name
131
+ getDb().transaction(() => {
132
+ getDb().query(`
133
+ INSERT INTO models(id, name, provider_id, model_type, context_window, capabilities, enabled, active)
134
+ SELECT ?, ?, provider_id, model_type, context_window, capabilities, enabled, active FROM models WHERE id = ?
135
+ `).run(newId, name, oldId)
136
+ getDb().query("UPDATE agents SET model_id = ? WHERE model_id = ?").run(newId, oldId)
137
+ getDb().query("DELETE FROM models WHERE id = ?").run(oldId)
138
+ })()
139
+
140
+ const model = getDb().query("SELECT * FROM models WHERE id = ?").get(newId)
141
+ return addCorsHeaders(Response.json({ ok: true, model }), req)
142
+ }
143
+
144
+ export async function handleUpdateModelsConfig(
145
+ req: Request,
146
+ addCorsHeaders: (r: Response, req: Request) => Response,
147
+ config: Config,
148
+ agent?: any
149
+ ): Promise<Response> {
150
+ const body = await req.json().catch(() => ({}));
151
+ const { defaultProvider, defaults, providers } = body;
152
+
153
+ config.models = config.models || {};
154
+ if (defaultProvider) config.models.defaultProvider = defaultProvider;
155
+ if (defaults) config.models.defaults = { ...(config.models.defaults || {}), ...defaults };
156
+ if (providers) config.models.providers = { ...(config.models.providers || {}), ...providers };
157
+
158
+ if (agent) {
159
+ await agent.updateConfig(config);
160
+ }
161
+
162
+ return addCorsHeaders(Response.json({ success: true }), req);
163
+ }
@@ -0,0 +1,93 @@
1
+ import { multimodalService } from "../../multimodal/index"
2
+ import { getDb } from "../../storage/sqlite"
3
+
4
+ export async function handleGetVisionProviders(req: Request, addCorsHeaders: (r: Response, req: Request) => Response): Promise<Response> {
5
+ const configured = multimodalService.getConfiguredVisionProviders()
6
+ const db = getDb()
7
+ const visionModels = db.query(`
8
+ SELECT m.id, m.name, m.provider_id, m.capabilities
9
+ FROM models m
10
+ JOIN providers p ON m.provider_id = p.id
11
+ WHERE m.enabled = 1 AND p.enabled = 1 AND p.api_key_encrypted IS NOT NULL AND p.api_key_encrypted != ''
12
+ `).all() as Array<{ id: string; name: string; provider_id: string; capabilities: string }>
13
+
14
+ const modelsWithVision = visionModels.filter(m => {
15
+ try {
16
+ const caps = JSON.parse(m.capabilities || "[]") as string[]
17
+ return caps.includes("vision")
18
+ } catch { return false }
19
+ })
20
+
21
+ return addCorsHeaders(Response.json({
22
+ configuredProviders: configured,
23
+ visionModels: modelsWithVision.map(m => ({
24
+ id: m.id,
25
+ name: m.name,
26
+ providerId: m.provider_id,
27
+ })),
28
+ }), req)
29
+ }
30
+
31
+ export async function handleGetChannelVision(req: Request, addCorsHeaders: (r: Response, req: Request) => Response, channelId: string): Promise<Response> {
32
+ const config = multimodalService.getChannelVisionConfig(channelId)
33
+ return addCorsHeaders(Response.json(config), req)
34
+ }
35
+
36
+ export async function handleUpdateChannelVision(req: Request, addCorsHeaders: (r: Response, req: Request) => Response, channelId: string): Promise<Response> {
37
+ const body = await req.json().catch(() => ({})) as {
38
+ visionEnabled?: boolean
39
+ ocrProvider?: string
40
+ visionProvider?: string
41
+ visionModelId?: string
42
+ }
43
+
44
+ const db = getDb()
45
+ const updates: string[] = []
46
+ const values: any[] = []
47
+
48
+ if (body.visionEnabled !== undefined) {
49
+ updates.push("vision_enabled = ?")
50
+ values.push(body.visionEnabled ? 1 : 0)
51
+ }
52
+ if (body.ocrProvider !== undefined) {
53
+ updates.push("ocr_provider = ?")
54
+ values.push(body.ocrProvider)
55
+ }
56
+ if (body.visionProvider !== undefined) {
57
+ updates.push("vision_provider = ?")
58
+ values.push(body.visionProvider)
59
+ }
60
+ if (body.visionModelId !== undefined) {
61
+ updates.push("vision_model_id = ?")
62
+ values.push(body.visionModelId)
63
+ }
64
+
65
+ if (updates.length === 0) {
66
+ return addCorsHeaders(Response.json({ success: false, error: "No fields to update" }, { status: 400 }), req)
67
+ }
68
+
69
+ values.push(channelId)
70
+ db.query(`UPDATE channels SET ${updates.join(", ")} WHERE id = ?`).run(...values)
71
+
72
+ const updated = multimodalService.getChannelVisionConfig(channelId)
73
+ return addCorsHeaders(Response.json({ success: true, config: updated }), req)
74
+ }
75
+
76
+ export async function handleOcrImage(req: Request, addCorsHeaders: (r: Response, req: Request) => Response): Promise<Response> {
77
+ const body = await req.json().catch(() => ({})) as {
78
+ image?: { url?: string; base64?: string; buffer?: string; mimeType?: string; caption?: string }
79
+ provider?: string
80
+ }
81
+
82
+ if (!body.image) {
83
+ return addCorsHeaders(Response.json({ success: false, error: "image required" }, { status: 400 }), req)
84
+ }
85
+
86
+ try {
87
+ const imageInput = multimodalService.normalizeImageFromChannel("api", body.image)
88
+ const text = await multimodalService.ocrImage(imageInput, body.provider)
89
+ return addCorsHeaders(Response.json({ success: true, text }), req)
90
+ } catch (error) {
91
+ return addCorsHeaders(Response.json({ success: false, error: (error as Error).message }, { status: 500 }), req)
92
+ }
93
+ }