@johpaz/hive-agents 0.0.35 → 0.0.36

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 (440) hide show
  1. package/README.md +64 -39
  2. package/dist/hive.js +3127 -3104
  3. package/dist/ui/assets/{AgentCreateForm-B4eK7efF.js → AgentCreateForm-tJZv9FZC.js} +1 -1
  4. package/dist/ui/assets/{AgentDetailPage-BD2uoJWk.js → AgentDetailPage-Du-mRcAX.js} +1 -1
  5. package/dist/ui/assets/AgentNewPage-DIFYd_Ys.js +1 -0
  6. package/dist/ui/assets/{AgentsPage-4JUZXvkA.js → AgentsPage-YvSgWRiw.js} +6 -6
  7. package/dist/ui/assets/CanvasPage-DtMwGvxf.js +33 -0
  8. package/dist/ui/assets/{ChannelsPage-BUn7-nhV.js → ChannelsPage-BdBXWHjj.js} +1 -1
  9. package/dist/ui/assets/DashboardPage-ghl1ZguH.js +6 -0
  10. package/dist/ui/assets/{LoginPage-C8j_urUD.js → LoginPage-CAmSI9Vy.js} +1 -1
  11. package/dist/ui/assets/LogsPage-DAPBHkwK.js +1 -0
  12. package/dist/ui/assets/MeetingPage-WjjGOqqU.js +1 -0
  13. package/dist/ui/assets/{NotFound-Drh-sJPN.js → NotFound-BMeQSGcG.js} +1 -1
  14. package/dist/ui/assets/ProvidersPage-Ct6HsAi1.js +1 -0
  15. package/dist/ui/assets/{RecoverPage-DNb1Pr8h.js → RecoverPage-DpW3l-yv.js} +1 -1
  16. package/dist/ui/assets/SettingsPage-DBJ7_E6C.js +9 -0
  17. package/dist/ui/assets/SetupPage-DKmLVUaj.js +1 -0
  18. package/dist/ui/assets/{WebChatPage-R-YOwA4F.js → WebChatPage-CVRcKept.js} +2 -2
  19. package/dist/ui/assets/accordion-C5d5Rm5z.js +1 -0
  20. package/dist/ui/assets/{alert-U8FsgWi7.js → alert-C-NE-P3s.js} +1 -1
  21. package/dist/ui/assets/{alert-dialog-CRdMkkmk.js → alert-dialog-C5mzbHdP.js} +1 -1
  22. package/dist/ui/assets/{badge-Cli1jnH5.js → badge-ChpACfWO.js} +1 -1
  23. package/dist/ui/assets/chevron-up-BYhk0K2J.js +1 -0
  24. package/dist/ui/assets/{dialog-DQ3s-LuO.js → dialog-QnZ0ad8O.js} +1 -1
  25. package/dist/ui/assets/dropdown-menu-BK-CO3Od.js +1 -0
  26. package/dist/ui/assets/{es-DcMjrpbA.js → es-NQNoaWDx.js} +1 -1
  27. package/dist/ui/assets/index-B2fCYtTS.css +2 -0
  28. package/dist/ui/assets/index-DMCjjdqf.js +116 -0
  29. package/dist/ui/assets/{label-0BvGVXvZ.js → label-D2H1IR_J.js} +1 -1
  30. package/dist/ui/assets/progress-BherYzY6.js +1 -0
  31. package/dist/ui/assets/scroll-area-DkeyX32e.js +1 -0
  32. package/dist/ui/assets/{slider-D47dOrRa.js → slider-CsiUDxc3.js} +1 -1
  33. package/dist/ui/assets/switch-BDwN8RYV.js +1 -0
  34. package/dist/ui/assets/{table-DhowbNxQ.js → table-CSc8ubon.js} +1 -1
  35. package/dist/ui/assets/terminal-DN38Q456.js +1 -0
  36. package/dist/ui/assets/useProviders-C6_QHsEi.js +1 -0
  37. package/dist/ui/assets/{vendor-radix-JY4ncZrD.js → vendor-radix-cw1bQaVC.js} +4 -4
  38. package/dist/ui/assets/{vendor-react-CscwQerf.js → vendor-react-D4s9E-zj.js} +1 -1
  39. package/dist/ui/dist/assets/AgentCreateForm-tJZv9FZC.js +1 -0
  40. package/dist/ui/dist/assets/AgentDetailPage-Du-mRcAX.js +1 -0
  41. package/dist/ui/dist/assets/AgentNewPage-DIFYd_Ys.js +1 -0
  42. package/dist/ui/dist/assets/AgentsPage-YvSgWRiw.js +10 -0
  43. package/dist/ui/dist/assets/CanvasPage-DtMwGvxf.js +33 -0
  44. package/dist/ui/dist/assets/ChannelsPage-BdBXWHjj.js +8 -0
  45. package/dist/ui/dist/assets/DashboardPage-ghl1ZguH.js +6 -0
  46. package/dist/ui/dist/assets/LoginPage-CAmSI9Vy.js +1 -0
  47. package/dist/ui/dist/assets/LogsPage-DAPBHkwK.js +1 -0
  48. package/dist/ui/dist/assets/MeetingPage-WjjGOqqU.js +1 -0
  49. package/dist/ui/dist/assets/NotFound-BMeQSGcG.js +1 -0
  50. package/dist/ui/dist/assets/ProvidersPage-Ct6HsAi1.js +1 -0
  51. package/dist/ui/dist/assets/RecoverPage-DpW3l-yv.js +1 -0
  52. package/dist/ui/dist/assets/SettingsPage-DBJ7_E6C.js +9 -0
  53. package/dist/ui/dist/assets/SetupPage-DKmLVUaj.js +1 -0
  54. package/dist/ui/dist/assets/WebChatPage-CVRcKept.js +16 -0
  55. package/dist/ui/dist/assets/accordion-C5d5Rm5z.js +1 -0
  56. package/dist/ui/dist/assets/activity-c3pNngT_.js +1 -0
  57. package/dist/ui/dist/assets/alert-C-NE-P3s.js +1 -0
  58. package/dist/ui/dist/assets/alert-dialog-C5mzbHdP.js +1 -0
  59. package/dist/ui/dist/assets/arrow-left-CBcbX5EZ.js +1 -0
  60. package/dist/ui/dist/assets/badge-ChpACfWO.js +1 -0
  61. package/dist/ui/dist/assets/calendar-B-KZ9RQO.js +1 -0
  62. package/dist/ui/dist/assets/card-CNf6BS2e.js +1 -0
  63. package/dist/ui/dist/assets/chevron-left-D4U-5A27.js +1 -0
  64. package/dist/ui/dist/assets/chevron-right-CR4Skrf3.js +1 -0
  65. package/dist/ui/dist/assets/chevron-up-BYhk0K2J.js +1 -0
  66. package/dist/ui/dist/assets/circle-alert-CyHDwUj8.js +1 -0
  67. package/dist/ui/dist/assets/circle-check-Bb54Ebmu.js +1 -0
  68. package/dist/ui/dist/assets/cpu-Cdgc_B1K.js +1 -0
  69. package/dist/ui/dist/assets/dialog-QnZ0ad8O.js +1 -0
  70. package/dist/ui/dist/assets/download-C3ifGMjJ.js +1 -0
  71. package/dist/ui/dist/assets/dropdown-menu-BK-CO3Od.js +1 -0
  72. package/dist/ui/dist/assets/es-NQNoaWDx.js +1 -0
  73. package/dist/ui/dist/assets/external-link-BvxYeTP1.js +1 -0
  74. package/dist/ui/dist/assets/eye-DqNTU_GD.js +1 -0
  75. package/dist/ui/dist/assets/file-text-BT_9S9SM.js +1 -0
  76. package/dist/ui/dist/assets/folder-open-BhH8y9ac.js +1 -0
  77. package/dist/ui/dist/assets/format-GVHeOyWI.js +1 -0
  78. package/dist/ui/dist/assets/gateway-url-COCbW0IR.js +1 -0
  79. package/dist/ui/dist/assets/gauge-D_TMa4i9.js +1 -0
  80. package/dist/ui/dist/assets/globe-DeCQTCDJ.js +1 -0
  81. package/dist/ui/dist/assets/hexagon-DsGOUl-H.js +1 -0
  82. package/dist/ui/dist/assets/history-BSG-Ypqf.js +1 -0
  83. package/dist/ui/dist/assets/index-B2fCYtTS.css +2 -0
  84. package/dist/ui/dist/assets/index-DMCjjdqf.js +116 -0
  85. package/dist/ui/dist/assets/info-NwLoa2Mj.js +1 -0
  86. package/dist/ui/dist/assets/key-3EP0dhkT.js +1 -0
  87. package/dist/ui/dist/assets/label-D2H1IR_J.js +1 -0
  88. package/dist/ui/dist/assets/loader-circle-CZNax6kS.js +1 -0
  89. package/dist/ui/dist/assets/lock-Ei1_J-Nq.js +1 -0
  90. package/dist/ui/dist/assets/pause-BUqah9Bi.js +1 -0
  91. package/dist/ui/dist/assets/play-NcZ4swwL.js +1 -0
  92. package/dist/ui/dist/assets/plus-CX1xyhp5.js +1 -0
  93. package/dist/ui/dist/assets/progress-BherYzY6.js +1 -0
  94. package/dist/ui/dist/assets/refresh-cw-DaYdjQFk.js +1 -0
  95. package/dist/ui/dist/assets/rolldown-runtime-S-ySWqyJ.js +1 -0
  96. package/dist/ui/dist/assets/save-CUdYyHNy.js +1 -0
  97. package/dist/ui/dist/assets/scroll-area-DkeyX32e.js +1 -0
  98. package/dist/ui/dist/assets/send-B0H5SEIE.js +1 -0
  99. package/dist/ui/dist/assets/settings-Ds4SqD8s.js +1 -0
  100. package/dist/ui/dist/assets/slider-CsiUDxc3.js +14 -0
  101. package/dist/ui/dist/assets/sparkles-yUEb-7oH.js +1 -0
  102. package/dist/ui/dist/assets/square-BD81nFtN.js +1 -0
  103. package/dist/ui/dist/assets/switch-BDwN8RYV.js +1 -0
  104. package/dist/ui/dist/assets/table-CSc8ubon.js +1 -0
  105. package/dist/ui/dist/assets/terminal-DN38Q456.js +1 -0
  106. package/dist/ui/dist/assets/textarea-CXgXWKrT.js +1 -0
  107. package/dist/ui/dist/assets/trash-2-CNjMkoq6.js +1 -0
  108. package/dist/ui/dist/assets/triangle-alert-C9Y8Ub4X.js +1 -0
  109. package/dist/ui/dist/assets/useProviders-C6_QHsEi.js +1 -0
  110. package/dist/ui/dist/assets/utils-3pnRFmFe.js +1 -0
  111. package/dist/ui/dist/assets/vendor-charts-Bu2lyBKP.js +65 -0
  112. package/dist/ui/dist/assets/vendor-query-DsWPbQdG.js +1 -0
  113. package/dist/ui/dist/assets/vendor-radix-cw1bQaVC.js +63 -0
  114. package/dist/ui/dist/assets/vendor-react-D4s9E-zj.js +1 -0
  115. package/dist/ui/dist/assets/vendor-router-C9pIYwbJ.js +3 -0
  116. package/dist/ui/dist/assets/volume-2-CeSXNDv4.js +1 -0
  117. package/dist/ui/dist/assets/zap-hlXjpSeA.js +1 -0
  118. package/dist/ui/dist/favicon.ico +0 -0
  119. package/dist/ui/dist/index.html +40 -0
  120. package/dist/ui/dist/placeholder.svg +1 -0
  121. package/dist/ui/index.html +6 -6
  122. package/package.json +137 -13
  123. package/packages/cli/src/adapters/binary.ts +461 -0
  124. package/packages/cli/src/adapters/bun-global.ts +378 -0
  125. package/packages/cli/src/adapters/config.ts +314 -0
  126. package/packages/cli/src/adapters/docker.ts +308 -0
  127. package/packages/cli/src/adapters/factory.ts +168 -0
  128. package/packages/cli/src/adapters/index.ts +80 -0
  129. package/packages/cli/src/adapters/types.ts +218 -0
  130. package/packages/cli/src/commands/agent-run.ts +168 -0
  131. package/packages/cli/src/commands/agents.ts +398 -0
  132. package/packages/cli/src/commands/chat.ts +142 -0
  133. package/packages/cli/src/commands/config.ts +49 -0
  134. package/packages/cli/src/commands/cron.ts +487 -0
  135. package/packages/cli/src/commands/dev.ts +58 -0
  136. package/packages/cli/src/commands/doctor.ts +320 -0
  137. package/packages/cli/src/commands/gateway.ts +719 -0
  138. package/packages/cli/src/commands/logs.ts +57 -0
  139. package/packages/cli/src/commands/mcp.ts +175 -0
  140. package/packages/cli/src/commands/message.ts +77 -0
  141. package/packages/cli/src/commands/migrate.ts +90 -0
  142. package/packages/cli/src/commands/onboard.ts +1656 -0
  143. package/packages/cli/src/commands/security.ts +144 -0
  144. package/packages/cli/src/commands/service.ts +50 -0
  145. package/packages/cli/src/commands/sessions.ts +116 -0
  146. package/packages/cli/src/commands/skills.ts +215 -0
  147. package/packages/cli/src/commands/update.ts +203 -0
  148. package/packages/cli/src/index.ts +210 -0
  149. package/packages/cli/src/ui-bundle.generated.ts +3 -0
  150. package/packages/cli/src/utils/token.ts +6 -0
  151. package/packages/core/src/agent/agent-loop.ts +691 -0
  152. package/packages/core/src/agent/compaction.ts +240 -0
  153. package/packages/core/src/agent/context-compiler.ts +467 -0
  154. package/packages/core/src/agent/context-guard.ts +91 -0
  155. package/packages/core/src/agent/conversation-store.ts +244 -0
  156. package/packages/core/src/agent/curator.ts +158 -0
  157. package/packages/core/src/agent/hooks.ts +166 -0
  158. package/packages/core/src/agent/llm-client.ts +167 -0
  159. package/packages/core/src/agent/llm-providers/anthropic.ts +212 -0
  160. package/packages/core/src/agent/llm-providers/deepseek.ts +8 -0
  161. package/packages/core/src/agent/llm-providers/gemini.ts +215 -0
  162. package/packages/core/src/agent/llm-providers/groq.ts +5 -0
  163. package/packages/core/src/agent/llm-providers/interface.ts +195 -0
  164. package/packages/core/src/agent/llm-providers/kimi.ts +8 -0
  165. package/packages/core/src/agent/llm-providers/local-llama.ts +37 -0
  166. package/packages/core/src/agent/llm-providers/mistral.ts +5 -0
  167. package/packages/core/src/agent/llm-providers/nvidia.ts +5 -0
  168. package/packages/core/src/agent/llm-providers/ollama.ts +175 -0
  169. package/packages/core/src/agent/llm-providers/openai-compat-base.ts +379 -0
  170. package/packages/core/src/agent/llm-providers/openai.ts +5 -0
  171. package/packages/core/src/agent/llm-providers/openrouter.ts +5 -0
  172. package/packages/core/src/agent/llm-providers/qwen.ts +5 -0
  173. package/packages/core/src/agent/native-tools.ts +31 -0
  174. package/packages/core/src/agent/playbook-selector.ts +147 -0
  175. package/packages/core/src/agent/prompt-builder.ts +169 -0
  176. package/packages/core/src/agent/providers/index.ts +204 -0
  177. package/packages/core/src/agent/providers.ts +1 -0
  178. package/packages/core/src/agent/reflector.ts +200 -0
  179. package/packages/core/src/agent/service.ts +267 -0
  180. package/packages/core/src/agent/skill-selector.ts +479 -0
  181. package/packages/core/src/agent/stuck-loop.ts +133 -0
  182. package/packages/core/src/agent/tool-selector.ts +569 -0
  183. package/packages/core/src/agent/tracer.ts +100 -0
  184. package/packages/core/src/auth/auth.ts +108 -0
  185. package/packages/core/src/auth/index.ts +1 -0
  186. package/packages/core/src/canvas/a2ui-tools.ts +255 -0
  187. package/packages/core/src/canvas/canvas-manager.ts +390 -0
  188. package/packages/core/src/canvas/canvas-tools.ts +448 -0
  189. package/packages/core/src/canvas/emitter.ts +149 -0
  190. package/packages/core/src/canvas/index.ts +3 -0
  191. package/packages/core/src/channels/base.ts +154 -0
  192. package/packages/core/src/channels/discord.ts +273 -0
  193. package/packages/core/src/channels/index.ts +7 -0
  194. package/packages/core/src/channels/manager.ts +450 -0
  195. package/packages/core/src/channels/slack.ts +323 -0
  196. package/packages/core/src/channels/telegram.ts +612 -0
  197. package/packages/core/src/channels/webchat.ts +139 -0
  198. package/packages/core/src/channels/whatsapp.ts +548 -0
  199. package/packages/core/src/config/index.ts +12 -0
  200. package/packages/core/src/config/loader.ts +569 -0
  201. package/packages/core/src/events/agent-bus.ts +460 -0
  202. package/packages/core/src/events/event-bus.ts +169 -0
  203. package/packages/core/src/gateway/channel-notify.ts +64 -0
  204. package/packages/core/src/gateway/helpers/cors.ts +32 -0
  205. package/packages/core/src/gateway/helpers/index.ts +4 -0
  206. package/packages/core/src/gateway/helpers/narration.ts +57 -0
  207. package/packages/core/src/gateway/helpers/path.ts +13 -0
  208. package/packages/core/src/gateway/helpers/redact.ts +61 -0
  209. package/packages/core/src/gateway/index.ts +5 -0
  210. package/packages/core/src/gateway/initializer.ts +363 -0
  211. package/packages/core/src/gateway/lane-queue.ts +169 -0
  212. package/packages/core/src/gateway/llm-local/client.ts +94 -0
  213. package/packages/core/src/gateway/llm-local/detector.ts +321 -0
  214. package/packages/core/src/gateway/llm-local/downloader.ts +216 -0
  215. package/packages/core/src/gateway/llm-local/index.ts +34 -0
  216. package/packages/core/src/gateway/llm-local/manager.ts +186 -0
  217. package/packages/core/src/gateway/llm-local/models.ts +149 -0
  218. package/packages/core/src/gateway/llm-local/server.ts +179 -0
  219. package/packages/core/src/gateway/resolver.ts +108 -0
  220. package/packages/core/src/gateway/router.ts +124 -0
  221. package/packages/core/src/gateway/routes/agents.ts +210 -0
  222. package/packages/core/src/gateway/routes/auth.ts +244 -0
  223. package/packages/core/src/gateway/routes/channels.ts +484 -0
  224. package/packages/core/src/gateway/routes/chat.ts +241 -0
  225. package/packages/core/src/gateway/routes/config.ts +12 -0
  226. package/packages/core/src/gateway/routes/cron-api.ts +544 -0
  227. package/packages/core/src/gateway/routes/ethics.ts +46 -0
  228. package/packages/core/src/gateway/routes/llm-local.ts +271 -0
  229. package/packages/core/src/gateway/routes/mcp.ts +319 -0
  230. package/packages/core/src/gateway/routes/meeting.ts +232 -0
  231. package/packages/core/src/gateway/routes/models.ts +163 -0
  232. package/packages/core/src/gateway/routes/multimodal.ts +93 -0
  233. package/packages/core/src/gateway/routes/providers.ts +220 -0
  234. package/packages/core/src/gateway/routes/setup.ts +441 -0
  235. package/packages/core/src/gateway/routes/skills.ts +115 -0
  236. package/packages/core/src/gateway/routes/system.ts +469 -0
  237. package/packages/core/src/gateway/routes/tasks.ts +44 -0
  238. package/packages/core/src/gateway/routes/tools.ts +59 -0
  239. package/packages/core/src/gateway/routes/tts-local.ts +388 -0
  240. package/packages/core/src/gateway/routes/users.ts +122 -0
  241. package/packages/core/src/gateway/routes/voice.ts +189 -0
  242. package/packages/core/src/gateway/routes/workspace.ts +281 -0
  243. package/packages/core/src/gateway/server.ts +2744 -0
  244. package/packages/core/src/gateway/session.ts +95 -0
  245. package/packages/core/src/gateway/slash-commands.ts +207 -0
  246. package/packages/core/src/gateway/tts/README.md +94 -0
  247. package/packages/core/src/gateway/tts/package.json +25 -0
  248. package/packages/core/src/gateway/tts/src/client.ts +59 -0
  249. package/packages/core/src/gateway/tts/src/detect.ts +42 -0
  250. package/packages/core/src/gateway/tts/src/index.ts +15 -0
  251. package/packages/core/src/gateway/tts/src/install.ts +129 -0
  252. package/packages/core/src/gateway/tts/src/models.ts +50 -0
  253. package/packages/core/src/gateway/tts/src/server.ts +252 -0
  254. package/packages/core/src/gateway/tts/voices/.gitkeep +0 -0
  255. package/packages/core/src/heartbeat/index.ts +157 -0
  256. package/packages/core/src/index.ts +56 -0
  257. package/packages/core/src/mcp/hot-reload.ts +148 -0
  258. package/packages/core/src/mcp/singleton.ts +21 -0
  259. package/packages/core/src/mcp/tool-sync.ts +176 -0
  260. package/packages/core/src/multimodal/index.ts +2 -0
  261. package/packages/core/src/multimodal/types.ts +28 -0
  262. package/packages/core/src/multimodal/vision-service.ts +283 -0
  263. package/packages/core/src/plugins/api.ts +128 -0
  264. package/packages/core/src/plugins/index.ts +2 -0
  265. package/packages/core/src/plugins/loader.ts +365 -0
  266. package/packages/core/src/resilience/circuit-breaker.ts +225 -0
  267. package/packages/core/src/scheduler/CronScheduler.ts +699 -0
  268. package/packages/core/src/scheduler/dag/AgentExecutor.ts +53 -0
  269. package/packages/core/src/scheduler/dag/DAGScheduler.ts +250 -0
  270. package/packages/core/src/scheduler/dag/EventBridge.ts +122 -0
  271. package/packages/core/src/scheduler/dag/TaskGraph.ts +192 -0
  272. package/packages/core/src/scheduler/dag/TaskNode.ts +97 -0
  273. package/packages/core/src/scheduler/dag/TaskResult.ts +22 -0
  274. package/packages/core/src/scheduler/dag/errors.ts +37 -0
  275. package/packages/core/src/scheduler/dag/index.ts +26 -0
  276. package/packages/core/src/scheduler/dag/presets/ResearchPreset.ts +97 -0
  277. package/packages/core/src/scheduler/dag/strategies/ParallelStrategy.ts +21 -0
  278. package/packages/core/src/scheduler/dag/strategies/PriorityStrategy.ts +46 -0
  279. package/packages/core/src/scheduler/index.ts +22 -0
  280. package/packages/core/src/scheduler/integration.ts +237 -0
  281. package/packages/core/src/scheduler/types.ts +164 -0
  282. package/packages/core/src/security/google-chat.ts +269 -0
  283. package/packages/core/src/security/index.ts +192 -0
  284. package/packages/core/src/security/pairing.ts +250 -0
  285. package/packages/core/src/security/rate-limit.ts +270 -0
  286. package/packages/core/src/security/signal.ts +321 -0
  287. package/packages/core/src/state/store.ts +312 -0
  288. package/packages/core/src/storage/crypto.ts +197 -0
  289. package/packages/core/src/storage/migrate.ts +147 -0
  290. package/packages/core/src/storage/onboarding.ts +1506 -0
  291. package/packages/core/src/storage/schema.ts +666 -0
  292. package/packages/core/src/storage/seed.ts +628 -0
  293. package/packages/core/src/storage/sqlite.ts +407 -0
  294. package/packages/core/src/storage/usage.ts +374 -0
  295. package/packages/core/src/tool-runtime/index.ts +476 -0
  296. package/packages/core/src/tool-runtime/tool-worker.ts +125 -0
  297. package/packages/core/src/tools/agents/get-available-models.ts +118 -0
  298. package/packages/core/src/tools/agents/index.ts +610 -0
  299. package/packages/core/src/tools/canvas/index.ts +420 -0
  300. package/packages/core/src/tools/cli/index.ts +142 -0
  301. package/packages/core/src/tools/core/index.ts +478 -0
  302. package/packages/core/src/tools/cron/index.ts +635 -0
  303. package/packages/core/src/tools/filesystem/fs-delete.ts +78 -0
  304. package/packages/core/src/tools/filesystem/fs-edit.ts +106 -0
  305. package/packages/core/src/tools/filesystem/fs-exists.ts +63 -0
  306. package/packages/core/src/tools/filesystem/fs-glob.ts +108 -0
  307. package/packages/core/src/tools/filesystem/fs-list.ts +129 -0
  308. package/packages/core/src/tools/filesystem/fs-read.ts +72 -0
  309. package/packages/core/src/tools/filesystem/fs-write.ts +67 -0
  310. package/packages/core/src/tools/filesystem/index.ts +34 -0
  311. package/packages/core/src/tools/filesystem/workspace-guard.ts +62 -0
  312. package/packages/core/src/tools/index.ts +197 -0
  313. package/packages/core/src/tools/meeting/index.ts +363 -0
  314. package/packages/core/src/tools/office/index.ts +47 -0
  315. package/packages/core/src/tools/office/office-escribir-docx.ts +192 -0
  316. package/packages/core/src/tools/office/office-escribir-pdf.ts +172 -0
  317. package/packages/core/src/tools/office/office-escribir-pptx.ts +174 -0
  318. package/packages/core/src/tools/office/office-escribir-xlsx.ts +116 -0
  319. package/packages/core/src/tools/office/office-leer-docx.ts +93 -0
  320. package/packages/core/src/tools/office/office-leer-pdf.ts +114 -0
  321. package/packages/core/src/tools/office/office-leer-pptx.ts +136 -0
  322. package/packages/core/src/tools/office/office-leer-xlsx.ts +124 -0
  323. package/packages/core/src/tools/types.ts +39 -0
  324. package/packages/core/src/tools/voice/index.ts +104 -0
  325. package/packages/core/src/tools/web/browser-click.ts +78 -0
  326. package/packages/core/src/tools/web/browser-extract.ts +139 -0
  327. package/packages/core/src/tools/web/browser-navigate.ts +106 -0
  328. package/packages/core/src/tools/web/browser-screenshot.ts +87 -0
  329. package/packages/core/src/tools/web/browser-script.ts +88 -0
  330. package/packages/core/src/tools/web/browser-service.ts +554 -0
  331. package/packages/core/src/tools/web/browser-type.ts +101 -0
  332. package/packages/core/src/tools/web/browser-wait.ts +136 -0
  333. package/packages/core/src/tools/web/index.ts +41 -0
  334. package/packages/core/src/tools/web/web-fetch.ts +78 -0
  335. package/packages/core/src/tools/web/web-search.ts +123 -0
  336. package/packages/core/src/utils/benchmark.ts +80 -0
  337. package/packages/core/src/utils/crypto.ts +73 -0
  338. package/packages/core/src/utils/date.ts +42 -0
  339. package/packages/core/src/utils/index.ts +5 -0
  340. package/packages/core/src/utils/logger.ts +389 -0
  341. package/packages/core/src/utils/retry.ts +70 -0
  342. package/packages/core/src/utils/toon.ts +253 -0
  343. package/packages/core/src/voice/index.ts +643 -0
  344. package/packages/mcp/src/config.ts +13 -0
  345. package/packages/mcp/src/index.ts +1 -0
  346. package/packages/mcp/src/logger.ts +47 -0
  347. package/packages/mcp/src/manager.ts +439 -0
  348. package/packages/mcp/src/transports/index.ts +67 -0
  349. package/packages/mcp/src/transports/sse.ts +238 -0
  350. package/packages/mcp/src/transports/websocket.ts +159 -0
  351. package/packages/skills/src/bundled/agents/agent_spawner/SKILL.md +167 -0
  352. package/packages/skills/src/bundled/agents/code_delegator/SKILL.md +156 -0
  353. package/packages/skills/src/bundled/agents/memory_manager/SKILL.md +143 -0
  354. package/packages/skills/src/bundled/agents/research_and_remember/SKILL.md +139 -0
  355. package/packages/skills/src/bundled/agents/task_orchestrator/SKILL.md +198 -0
  356. package/packages/skills/src/bundled/canvas/a2ui_dashboard/SKILL.md +176 -0
  357. package/packages/skills/src/bundled/canvas/a2ui_form/SKILL.md +202 -0
  358. package/packages/skills/src/bundled/canvas/a2ui_interactive/SKILL.md +206 -0
  359. package/packages/skills/src/bundled/canvas/canvas_dashboard/SKILL.md +146 -0
  360. package/packages/skills/src/bundled/canvas/canvas_interact/SKILL.md +148 -0
  361. package/packages/skills/src/bundled/canvas/canvas_report/SKILL.md +146 -0
  362. package/packages/skills/src/bundled/cli/cli_pipeline/SKILL.md +136 -0
  363. package/packages/skills/src/bundled/cli/cli_safe_exec/SKILL.md +125 -0
  364. package/packages/skills/src/bundled/cron_manager/SKILL.md +188 -0
  365. package/packages/skills/src/bundled/cron_reminder/SKILL.md +112 -0
  366. package/packages/skills/src/bundled/filesystem/file_manager/SKILL.md +118 -0
  367. package/packages/skills/src/bundled/filesystem/file_read_and_summarize/SKILL.md +108 -0
  368. package/packages/skills/src/bundled/filesystem/file_writer/SKILL.md +135 -0
  369. package/packages/skills/src/bundled/meeting/meeting_transcription/SKILL.md +213 -0
  370. package/packages/skills/src/bundled/office/office_document_manager/SKILL.md +262 -0
  371. package/packages/skills/src/bundled/search_knowledge/busqueda_fts5/SKILL.md +74 -0
  372. package/packages/skills/src/bundled/voice/voice_assistant/SKILL.md +174 -0
  373. package/packages/skills/src/bundled/voice/voice_input/SKILL.md +146 -0
  374. package/packages/skills/src/bundled/voice/voice_output/SKILL.md +151 -0
  375. package/packages/skills/src/bundled/web/browser_automate/SKILL.md +120 -0
  376. package/packages/skills/src/bundled/web/browser_scrape/SKILL.md +109 -0
  377. package/packages/skills/src/bundled/web/web_monitor/SKILL.md +127 -0
  378. package/packages/skills/src/bundled/web/web_research/SKILL.md +119 -0
  379. package/packages/skills/src/bundled-data.generated.ts +1964 -0
  380. package/packages/skills/src/index.ts +1 -0
  381. package/packages/skills/src/loader.ts +388 -0
  382. package/dist/ui/assets/AgentNewPage-GB-tVN50.js +0 -1
  383. package/dist/ui/assets/BridgePage-DDcDILKu.js +0 -1
  384. package/dist/ui/assets/CanvasPage-oOk2sGOD.js +0 -33
  385. package/dist/ui/assets/DashboardPage-DV_2qWYJ.js +0 -6
  386. package/dist/ui/assets/LogsPage-DayYjh01.js +0 -1
  387. package/dist/ui/assets/MeetingPage-C01uPuqj.js +0 -1
  388. package/dist/ui/assets/ProjectsPage-B8_am_Ib.js +0 -1
  389. package/dist/ui/assets/ProvidersPage-DBzi66e4.js +0 -1
  390. package/dist/ui/assets/SettingsPage-CFA_Tknl.js +0 -9
  391. package/dist/ui/assets/SetupPage-BrUWbhvT.js +0 -1
  392. package/dist/ui/assets/accordion-DdAEfIXR.js +0 -1
  393. package/dist/ui/assets/chevron-down-DIosfU_U.js +0 -1
  394. package/dist/ui/assets/chevron-up-CI-W21Fy.js +0 -1
  395. package/dist/ui/assets/circle-S0-ouLz-.js +0 -1
  396. package/dist/ui/assets/circle-minus-CE0iJrl8.js +0 -1
  397. package/dist/ui/assets/circle-x-jUJ5zZvQ.js +0 -1
  398. package/dist/ui/assets/dropdown-menu-C2CXM1VE.js +0 -1
  399. package/dist/ui/assets/index-BN0875JH.css +0 -2
  400. package/dist/ui/assets/index-CH6sBa3Q.js +0 -116
  401. package/dist/ui/assets/pencil-5VdSj-h5.js +0 -1
  402. package/dist/ui/assets/progress-JN30I5fF.js +0 -1
  403. package/dist/ui/assets/scroll-area-BQQPitM8.js +0 -1
  404. package/dist/ui/assets/search-ChPgnVKj.js +0 -1
  405. package/dist/ui/assets/switch-C7W2-KEx.js +0 -1
  406. package/dist/ui/assets/terminal-C-R5Fckz.js +0 -1
  407. package/dist/ui/assets/useProviders-TBnWn-Hq.js +0 -1
  408. /package/dist/ui/assets/{card-DFKnZ6ky.js → card-CNf6BS2e.js} +0 -0
  409. /package/dist/ui/assets/{circle-alert-KuAm2FWh.js → circle-alert-CyHDwUj8.js} +0 -0
  410. /package/dist/ui/assets/{circle-check-6Ard1-2z.js → circle-check-Bb54Ebmu.js} +0 -0
  411. /package/dist/ui/assets/{cpu-KDy6-FAI.js → cpu-Cdgc_B1K.js} +0 -0
  412. /package/dist/ui/assets/{download-Cjbk4Rek.js → download-C3ifGMjJ.js} +0 -0
  413. /package/dist/ui/assets/{external-link-HtrFM63g.js → external-link-BvxYeTP1.js} +0 -0
  414. /package/dist/ui/assets/{eye-D1dB40_o.js → eye-DqNTU_GD.js} +0 -0
  415. /package/dist/ui/assets/{file-text-CE58EfH0.js → file-text-BT_9S9SM.js} +0 -0
  416. /package/dist/ui/assets/{folder-open-DIPKeiI_.js → folder-open-BhH8y9ac.js} +0 -0
  417. /package/dist/ui/assets/{format-BwdV8bB5.js → format-GVHeOyWI.js} +0 -0
  418. /package/dist/ui/assets/{gateway-url-D5uj6Nxg.js → gateway-url-COCbW0IR.js} +0 -0
  419. /package/dist/ui/assets/{gauge-DmQmJHEg.js → gauge-D_TMa4i9.js} +0 -0
  420. /package/dist/ui/assets/{globe-_hUGxQF4.js → globe-DeCQTCDJ.js} +0 -0
  421. /package/dist/ui/assets/{hexagon-BaNGQlQj.js → hexagon-DsGOUl-H.js} +0 -0
  422. /package/dist/ui/assets/{history-BfZVGlZa.js → history-BSG-Ypqf.js} +0 -0
  423. /package/dist/ui/assets/{info-CBZ5-AlC.js → info-NwLoa2Mj.js} +0 -0
  424. /package/dist/ui/assets/{key-Bv5DdTPh.js → key-3EP0dhkT.js} +0 -0
  425. /package/dist/ui/assets/{loader-circle-C4hhXLgp.js → loader-circle-CZNax6kS.js} +0 -0
  426. /package/dist/ui/assets/{lock-CkZYexqw.js → lock-Ei1_J-Nq.js} +0 -0
  427. /package/dist/ui/assets/{pause-Bpy1_s7y.js → pause-BUqah9Bi.js} +0 -0
  428. /package/dist/ui/assets/{play-Cj4osqJZ.js → play-NcZ4swwL.js} +0 -0
  429. /package/dist/ui/assets/{plus-BQhgZN3A.js → plus-CX1xyhp5.js} +0 -0
  430. /package/dist/ui/assets/{refresh-cw-BfREHVQM.js → refresh-cw-DaYdjQFk.js} +0 -0
  431. /package/dist/ui/assets/{save-FFTD4dMp.js → save-CUdYyHNy.js} +0 -0
  432. /package/dist/ui/assets/{settings-BdHKUL92.js → settings-Ds4SqD8s.js} +0 -0
  433. /package/dist/ui/assets/{sparkles-r4uJbJAl.js → sparkles-yUEb-7oH.js} +0 -0
  434. /package/dist/ui/assets/{square-G7Hyufqm.js → square-BD81nFtN.js} +0 -0
  435. /package/dist/ui/assets/{textarea-5kyuD04X.js → textarea-CXgXWKrT.js} +0 -0
  436. /package/dist/ui/assets/{trash-2-DXVBRWfh.js → trash-2-CNjMkoq6.js} +0 -0
  437. /package/dist/ui/assets/{triangle-alert-Bu5seg9O.js → triangle-alert-C9Y8Ub4X.js} +0 -0
  438. /package/dist/ui/assets/{vendor-router-CCECILJ0.js → vendor-router-C9pIYwbJ.js} +0 -0
  439. /package/dist/ui/assets/{volume-2-s9DuS696.js → volume-2-CeSXNDv4.js} +0 -0
  440. /package/dist/ui/assets/{zap-BPHZzXKV.js → zap-hlXjpSeA.js} +0 -0
@@ -0,0 +1,220 @@
1
+ import { getDb } from "../../storage/sqlite"
2
+ import {
3
+ maskApiKey,
4
+ loadProviderApiKey, storeProviderApiKey,
5
+ loadProviderHeaders, storeProviderHeaders,
6
+ } from "../../storage/crypto"
7
+
8
+ export async function handleGetProviders(req: Request, addCorsHeaders: (r: Response, req: Request) => Response): Promise<Response> {
9
+ const rawProviders = getDb().query(`
10
+ SELECT id, name, base_url, enabled, active, num_ctx FROM providers
11
+ `).all() as Record<string, unknown>[]
12
+
13
+ const modelsRows = getDb().query(`SELECT * FROM models`).all() as Record<string, unknown>[]
14
+
15
+ const modelsByProvider: Record<string, Record<string, unknown>[]> = {}
16
+ for (const m of modelsRows) {
17
+ const pid = (m.provider_id || m.providerId) as string
18
+ if (!modelsByProvider[pid]) modelsByProvider[pid] = []
19
+ modelsByProvider[pid].push({
20
+ ...m,
21
+ enabled: !!m.enabled,
22
+ active: !!m.active,
23
+ provider_id: pid
24
+ })
25
+ }
26
+
27
+ const providers = await Promise.all(rawProviders.map(async (p) => {
28
+ const apiKey = await loadProviderApiKey(p.id as string)
29
+ const headers = await loadProviderHeaders(p.id as string)
30
+ return {
31
+ id: p.id,
32
+ name: p.name,
33
+ base_url: p.base_url,
34
+ enabled: p.enabled,
35
+ active: p.active,
36
+ num_ctx: p.num_ctx ?? null,
37
+ has_api_key: apiKey ? 1 : 0,
38
+ has_headers: Object.keys(headers).length > 0 ? 1 : 0,
39
+ masked_api_key: apiKey ? maskApiKey(apiKey) : null,
40
+ models: modelsByProvider[p.id as string] || [],
41
+ }
42
+ }))
43
+
44
+ return addCorsHeaders(Response.json({ providers }), req)
45
+ }
46
+
47
+ export async function handleCreateProvider(req: Request, addCorsHeaders: (r: Response, req: Request) => Response): Promise<Response> {
48
+ const body = await req.json().catch(() => ({}))
49
+ getDb().query(`
50
+ INSERT OR REPLACE INTO providers(id, name, base_url, enabled, active)
51
+ VALUES(?, ?, ?, ?, 1)
52
+ `).run(body.id, body.name, body.base_url || null, body.enabled !== undefined ? body.enabled : 1)
53
+ return addCorsHeaders(Response.json({ ok: true }), req)
54
+ }
55
+
56
+ export async function handleToggleProvider(req: Request, addCorsHeaders: (r: Response, req: Request) => Response): Promise<Response> {
57
+ const url = new URL(req.url)
58
+ const providerId = url.pathname.split("/")[3]
59
+ const body = await req.json().catch(() => ({}))
60
+ const { active } = body
61
+
62
+ if (active === undefined) {
63
+ return addCorsHeaders(new Response("Missing active field", { status: 400 }), req)
64
+ }
65
+
66
+ const db = getDb()
67
+ db.query(`UPDATE providers SET active = ?, enabled = ? WHERE id = ?`).run(active ? 1 : 0, active ? 1 : 0, providerId)
68
+
69
+ // Cascade: activate/deactivate all models for this provider
70
+ db.query(`UPDATE models SET active = ?, enabled = ? WHERE provider_id = ?`).run(active ? 1 : 0, active ? 1 : 0, providerId)
71
+
72
+ return addCorsHeaders(Response.json({ success: true, active }), req)
73
+ }
74
+
75
+ export async function handleUpdateProvider(req: Request, addCorsHeaders: (r: Response, req: Request) => Response): Promise<Response> {
76
+ const url = new URL(req.url)
77
+ const providerIdMatch = url.pathname.match(/^\/api\/providers\/([^/]+)$/)
78
+
79
+ if (!providerIdMatch) {
80
+ return addCorsHeaders(new Response("Invalid path", { status: 400 }), req)
81
+ }
82
+
83
+ const id = providerIdMatch[1]
84
+ const body = await req.json().catch(() => ({}))
85
+ const updates: string[] = []
86
+ const params: any[] = []
87
+
88
+ if (body.name) {
89
+ updates.push("name = ?")
90
+ params.push(body.name)
91
+ }
92
+ const baseUrl = body.base_url !== undefined ? body.base_url : body.baseUrl
93
+ if (baseUrl !== undefined) {
94
+ updates.push("base_url = ?")
95
+ params.push(baseUrl || null)
96
+ }
97
+ if (body.enabled !== undefined) {
98
+ updates.push("enabled = ?")
99
+ params.push(body.enabled ? 1 : 0)
100
+ }
101
+ if (body.active !== undefined) {
102
+ updates.push("active = ?")
103
+ params.push(body.active ? 1 : 0)
104
+ }
105
+ if (body.config?.apiKey || body.apiKey) {
106
+ await storeProviderApiKey(id, body.config?.apiKey || body.apiKey)
107
+ }
108
+ if (body.headers) {
109
+ await storeProviderHeaders(id, body.headers)
110
+ }
111
+ const numCtx = body.num_ctx !== undefined ? body.num_ctx : body.numCtx
112
+ if (numCtx !== undefined) {
113
+ updates.push("num_ctx = ?")
114
+ params.push(numCtx ? Number(numCtx) : null)
115
+ }
116
+
117
+ if (updates.length > 0) {
118
+ params.push(id)
119
+ getDb().query(`UPDATE providers SET ${updates.join(", ")} WHERE id = ?`).run(...params)
120
+
121
+ // Cascade active/enabled changes to models
122
+ const activeIdx = updates.findIndex(u => u.startsWith("active"))
123
+ const enabledIdx = updates.findIndex(u => u.startsWith("enabled"))
124
+
125
+ if (activeIdx !== -1) {
126
+ const activeVal = params[activeIdx]
127
+ getDb().query(`UPDATE models SET active = ?, enabled = ? WHERE provider_id = ?`).run(activeVal as any, activeVal as any, id)
128
+ } else if (enabledIdx !== -1) {
129
+ const enabledVal = params[enabledIdx]
130
+ getDb().query(`UPDATE models SET enabled = ?, active = ? WHERE provider_id = ?`).run(enabledVal as any, enabledVal as any, id)
131
+ }
132
+ }
133
+
134
+ return addCorsHeaders(Response.json({ ok: true }), req)
135
+ }
136
+
137
+ export async function handleSyncProviderModels(
138
+ req: Request,
139
+ addCorsHeaders: (r: Response, req: Request) => Response,
140
+ providerId: string
141
+ ): Promise<Response> {
142
+ const db = getDb()
143
+ const providerRow = db.query<Record<string, unknown>, [string]>(
144
+ "SELECT * FROM providers WHERE id = ?"
145
+ ).get(providerId)
146
+
147
+ if (!providerRow) {
148
+ return addCorsHeaders(new Response("Provider not found", { status: 404 }), req)
149
+ }
150
+
151
+ const baseUrl = ((providerRow.base_url as string) || "http://localhost:11434").replace(/\/(v1|api)\/?$/, "")
152
+
153
+ try {
154
+ let modelNames: string[] = []
155
+
156
+ // Ollama uses /api/tags, OpenAI-compatible providers use /v1/models
157
+ if (providerId === "ollama") {
158
+ const res = await fetch(`${baseUrl}/api/tags`, { signal: AbortSignal.timeout(10000) })
159
+ if (!res.ok) {
160
+ return addCorsHeaders(Response.json({ error: `Ollama responded ${res.status}` }, { status: 502 }), req)
161
+ }
162
+ const data = await res.json() as { models: Array<{ name: string }> }
163
+ modelNames = (data.models || []).map(m => m.name)
164
+ } else {
165
+ // OpenAI-compatible: local-llama, groq, mistral, etc.
166
+ const res = await fetch(`${baseUrl}/v1/models`, { signal: AbortSignal.timeout(10000) })
167
+ if (!res.ok) {
168
+ return addCorsHeaders(Response.json({ error: `${providerId} responded ${res.status}` }, { status: 502 }), req)
169
+ }
170
+ const data = await res.json() as { data: Array<{ id: string }> }
171
+ modelNames = (data.data || []).map(m => m.id)
172
+ }
173
+
174
+ if (modelNames.length === 0) {
175
+ return addCorsHeaders(Response.json({ error: "No models found from provider" }, { status: 400 }), req)
176
+ }
177
+
178
+ const upsert = db.query(
179
+ `INSERT INTO models (id, provider_id, name, model_type, context_window, enabled, active)
180
+ VALUES (?, ?, ?, 'llm', 32768, 1, 1)
181
+ ON CONFLICT(id) DO UPDATE SET name = excluded.name, enabled = 1, active = 1`
182
+ )
183
+
184
+ for (const name of modelNames) {
185
+ upsert.run(name, providerId, name)
186
+ }
187
+
188
+ // Disable models that are no longer present
189
+ const existingModels = db.query<Record<string, unknown>, [string]>(
190
+ "SELECT id FROM models WHERE provider_id = ?"
191
+ ).all(providerId) as Record<string, unknown>[]
192
+
193
+ const disable = db.query("UPDATE models SET active = 0, enabled = 0 WHERE id = ?")
194
+ for (const row of existingModels) {
195
+ if (!modelNames.includes(row.id as string)) {
196
+ disable.run(row.id as string)
197
+ }
198
+ }
199
+
200
+ const models = db.query<Record<string, unknown>, [string]>(
201
+ "SELECT id, name, provider_id, enabled, active FROM models WHERE provider_id = ?"
202
+ ).all(providerId)
203
+
204
+ return addCorsHeaders(Response.json({
205
+ success: true,
206
+ synced: modelNames.length,
207
+ models
208
+ }), req)
209
+ } catch (err: unknown) {
210
+ const errorMsg = (err as Error).message
211
+ const hint = providerId === "ollama"
212
+ ? "Could not connect to Ollama"
213
+ : providerId === "local-llama"
214
+ ? "Could not connect to llama-server. Make sure it's running on :8080"
215
+ : `Could not connect to provider: ${errorMsg}`
216
+ return addCorsHeaders(Response.json({
217
+ error: `${hint}: ${errorMsg}`
218
+ }, { status: 502 }), req)
219
+ }
220
+ }
@@ -0,0 +1,441 @@
1
+ import { writeFileSync, mkdirSync } from "node:fs"
2
+ import * as path from "node:path"
3
+ import { getDb } from "../../storage/sqlite"
4
+ import { SEED_DATA } from "../../storage/seed"
5
+ import {
6
+ initOnboardingDb,
7
+ saveUserProfile,
8
+ saveAgentConfig,
9
+ saveProviderConfig,
10
+ activateChannel,
11
+ saveVoiceConfig,
12
+ activateEthics,
13
+ } from "../../storage/onboarding"
14
+ import { getHiveDir } from "../../config/loader"
15
+ import type { Config } from "../../config/loader"
16
+
17
+ export function isSetupMode(): boolean {
18
+ try {
19
+ const db = getDb()
20
+ const userCount = (db.query("SELECT COUNT(*) as count FROM users").get() as { count: number }).count
21
+ if (userCount === 0) return true
22
+ // Also require a coordinator agent — setup may have failed mid-way after creating the user
23
+ const agentCount = (db.query("SELECT COUNT(*) as count FROM agents WHERE role = 'coordinator'").get() as { count: number }).count
24
+ return agentCount === 0
25
+ } catch {
26
+ return true
27
+ }
28
+ }
29
+
30
+ export function handleSetupProviders(
31
+ addCorsHeaders: (response: Response, request: Request) => Response,
32
+ req: Request
33
+ ): Response {
34
+ // Build provider+model list directly from SEED_DATA so it's always in sync
35
+ // with what the CLI onboarding shows, regardless of DB state.
36
+ const llmModelsByProvider = new Map<string, { id: string; name: string }[]>()
37
+
38
+ for (const model of SEED_DATA.models) {
39
+ if (model.modelType !== "llm") continue
40
+ if (!llmModelsByProvider.has(model.providerId)) {
41
+ llmModelsByProvider.set(model.providerId, [])
42
+ }
43
+ llmModelsByProvider.get(model.providerId)!.push({ id: model.id, name: model.name })
44
+ }
45
+
46
+ const result = SEED_DATA.providers
47
+ .filter(p => llmModelsByProvider.has(p.id) || p.id === "ollama")
48
+ .map(p => ({
49
+ id: p.id,
50
+ name: p.name,
51
+ models: llmModelsByProvider.get(p.id) ?? [],
52
+ }))
53
+
54
+ return addCorsHeaders(Response.json(result), req)
55
+ }
56
+
57
+ export function handleSetupEthics(
58
+ addCorsHeaders: (response: Response, request: Request) => Response,
59
+ req: Request
60
+ ): Response {
61
+ try {
62
+ const db = getDb()
63
+ const ethics = db.query(`
64
+ SELECT id, name, description, content, is_default, active FROM ethics ORDER BY id
65
+ `).all() as Array<{
66
+ id: string; name: string; description: string | null;
67
+ content: string; is_default: number; active: number;
68
+ }>
69
+
70
+ return addCorsHeaders(Response.json(
71
+ ethics.map(e => ({
72
+ id: e.id,
73
+ name: e.name,
74
+ description: e.description,
75
+ content: e.content,
76
+ isDefault: e.is_default === 1,
77
+ active: e.active === 1,
78
+ }))
79
+ ), req)
80
+ } catch (error) {
81
+ return addCorsHeaders(
82
+ Response.json({ error: (error as Error).message }, { status: 500 }),
83
+ req
84
+ )
85
+ }
86
+ }
87
+
88
+ /** GET /api/setup/ollama-models — public
89
+ * Queries the local Ollama instance for installed models.
90
+ * Used during setup to auto-populate the model selector.
91
+ */
92
+ export async function handleSetupOllamaModels(
93
+ addCorsHeaders: (response: Response, request: Request) => Response,
94
+ req: Request
95
+ ): Promise<Response> {
96
+ const base = (process.env.OLLAMA_HOST || "http://localhost:11434").replace(/\/(v1|api)\/?$/, "")
97
+ try {
98
+ const res = await fetch(`${base}/api/tags`, { signal: AbortSignal.timeout(5000) })
99
+ if (!res.ok) {
100
+ return addCorsHeaders(Response.json({ models: [], error: `Ollama respondió ${res.status}` }), req)
101
+ }
102
+ const data = await res.json() as { models?: Array<{ name: string }> }
103
+ const detected = data.models ?? []
104
+
105
+ // Persist detected models into the DB so they can be FK-referenced by agents
106
+ try {
107
+ const db = getDb()
108
+ for (const m of detected) {
109
+ db.query(`
110
+ INSERT OR IGNORE INTO models (id, name, provider_id, model_type, enabled, active)
111
+ VALUES (?, ?, 'ollama', 'llm', 1, 0)
112
+ `).run(m.name, m.name)
113
+ }
114
+ } catch { /* DB may not be initialized yet during early setup — ignore */ }
115
+
116
+ const models = detected.map(m => ({ id: m.name, name: m.name }))
117
+ return addCorsHeaders(Response.json({ models }), req)
118
+ } catch {
119
+ return addCorsHeaders(Response.json({ models: [], error: "Ollama no disponible en localhost:11434" }), req)
120
+ }
121
+ }
122
+
123
+ export async function handleSetupStatus(): Promise<Response> {
124
+ const setupMode = isSetupMode()
125
+ return Response.json({
126
+ configured: !setupMode,
127
+ setupMode,
128
+ })
129
+ }
130
+
131
+ export async function handleVerifyProvider(req: Request): Promise<Response> {
132
+ const body = await req.json().catch(() => ({}))
133
+ const { provider, apiKey, model } = body
134
+
135
+ if (!provider || !apiKey) {
136
+ return Response.json({
137
+ success: false,
138
+ error: "Provider and API key are required",
139
+ }, { status: 400 })
140
+ }
141
+
142
+ try {
143
+ let testUrl: string | null = null
144
+ let testBody: unknown = null
145
+ let headers: Record<string, string> = {}
146
+
147
+ const testMessages = [{ role: "user" as const, content: "Say 'ok' if you can read this." }]
148
+
149
+ if (provider === "ollama") {
150
+ const ollamaUrl = process.env.OLLAMA_HOST || "http://localhost:11434"
151
+ try {
152
+ const response = await fetch(`${ollamaUrl}/api/tags`, {
153
+ signal: AbortSignal.timeout(5000),
154
+ })
155
+ return Response.json({
156
+ success: response.ok,
157
+ error: response.ok ? null : `Could not connect to Ollama at ${ollamaUrl}`,
158
+ })
159
+ } catch {
160
+ return Response.json({
161
+ success: false,
162
+ error: `Could not connect to Ollama at ${ollamaUrl}`,
163
+ })
164
+ }
165
+ }
166
+
167
+ if (provider === "anthropic") {
168
+ testUrl = "https://api.anthropic.com/v1/messages"
169
+ testBody = {
170
+ model: model || "claude-sonnet-4-6",
171
+ max_tokens: 10,
172
+ messages: testMessages,
173
+ }
174
+ headers = {
175
+ "Content-Type": "application/json",
176
+ "x-api-key": apiKey,
177
+ "anthropic-version": "2023-06-01",
178
+ "anthropic-dangerous-direct-browser-access": "true",
179
+ }
180
+ } else if (provider === "openai") {
181
+ testUrl = "https://api.openai.com/v1/chat/completions"
182
+ testBody = {
183
+ model: model || "gpt-4o-mini",
184
+ max_tokens: 10,
185
+ messages: testMessages,
186
+ }
187
+ headers = {
188
+ "Content-Type": "application/json",
189
+ "Authorization": `Bearer ${apiKey}`,
190
+ }
191
+ } else if (provider === "gemini") {
192
+ testUrl = `https://generativelanguage.googleapis.com/v1beta/models/${model || "gemini-2.5-flash"}:generateContent?key=${apiKey}`
193
+ testBody = {
194
+ contents: [{ parts: [{ text: "Say ok" }] }],
195
+ }
196
+ headers = { "Content-Type": "application/json" }
197
+ } else if (provider === "groq") {
198
+ testUrl = "https://api.groq.com/openai/v1/chat/completions"
199
+ testBody = {
200
+ model: model || "llama-3.3-70b-versatile",
201
+ max_tokens: 10,
202
+ messages: testMessages,
203
+ }
204
+ headers = {
205
+ "Content-Type": "application/json",
206
+ "Authorization": `Bearer ${apiKey}`,
207
+ }
208
+ } else if (provider === "openrouter") {
209
+ testUrl = "https://openrouter.ai/api/v1/chat/completions"
210
+ testBody = {
211
+ model: model || "meta-llama/llama-3.3-70b-instruct",
212
+ max_tokens: 10,
213
+ messages: testMessages,
214
+ }
215
+ headers = {
216
+ "Content-Type": "application/json",
217
+ "Authorization": `Bearer ${apiKey}`,
218
+ }
219
+ } else if (provider === "mistral") {
220
+ testUrl = "https://api.mistral.ai/v1/chat/completions"
221
+ testBody = {
222
+ model: model || "mistral-small-latest",
223
+ max_tokens: 10,
224
+ messages: testMessages,
225
+ }
226
+ headers = {
227
+ "Content-Type": "application/json",
228
+ "Authorization": `Bearer ${apiKey}`,
229
+ }
230
+ } else if (provider === "deepseek") {
231
+ testUrl = "https://api.deepseek.com/v1/chat/completions"
232
+ testBody = {
233
+ model: model || "deepseek-chat",
234
+ max_tokens: 10,
235
+ messages: testMessages,
236
+ }
237
+ headers = {
238
+ "Content-Type": "application/json",
239
+ "Authorization": `Bearer ${apiKey}`,
240
+ }
241
+ } else if (provider === "kimi") {
242
+ testUrl = "https://api.moonshot.cn/v1/chat/completions"
243
+ testBody = {
244
+ model: model || "moonshot-v1-8k",
245
+ max_tokens: 10,
246
+ messages: testMessages,
247
+ }
248
+ headers = {
249
+ "Content-Type": "application/json",
250
+ "Authorization": `Bearer ${apiKey}`,
251
+ }
252
+ } else if (provider === "local-llama") {
253
+ const llamaUrl = (process.env.LOCAL_LLM_HOST || "http://localhost:8080").replace(/\/+$/, "")
254
+ try {
255
+ const response = await fetch(`${llamaUrl}/health`, {
256
+ signal: AbortSignal.timeout(5000),
257
+ })
258
+ const data = await response.json().catch(() => ({}))
259
+ return Response.json({
260
+ success: response.ok && data.status === "ok",
261
+ error: response.ok && data.status === "ok" ? null : `llama-server is running but not healthy (status: ${data.status || "unknown"})`,
262
+ })
263
+ } catch {
264
+ return Response.json({
265
+ success: false,
266
+ error: `Could not connect to llama-server at ${llamaUrl}. Make sure it's running with --port 8080`,
267
+ })
268
+ }
269
+ }
270
+
271
+ if (!testUrl) {
272
+ return Response.json({
273
+ success: false,
274
+ error: "Unsupported provider",
275
+ }, { status: 400 })
276
+ }
277
+
278
+ const response = await fetch(testUrl, {
279
+ method: "POST",
280
+ headers,
281
+ body: JSON.stringify(testBody),
282
+ signal: AbortSignal.timeout(10000),
283
+ })
284
+
285
+ return Response.json({
286
+ success: response.ok,
287
+ error: response.ok ? null : `API error: ${response.status}`,
288
+ })
289
+ } catch (error) {
290
+ return Response.json({
291
+ success: false,
292
+ error: `Connection error: ${(error as Error).message}`,
293
+ })
294
+ }
295
+ }
296
+
297
+ export async function handleCompleteSetup(
298
+ req: Request,
299
+ config: Config,
300
+ addCorsHeaders: (response: Response, request: Request) => Response
301
+ ): Promise<Response> {
302
+ if (!isSetupMode()) {
303
+ return addCorsHeaders(Response.json({
304
+ success: false,
305
+ error: "Setup already completed. Use config endpoints to modify settings.",
306
+ }, { status: 400 }), req)
307
+ }
308
+
309
+ const body = await req.json().catch(() => ({}))
310
+
311
+ // Re-check after the async boundary — a concurrent request may have
312
+ // completed setup while we were awaiting the request body.
313
+ if (!isSetupMode()) {
314
+ return addCorsHeaders(Response.json({
315
+ success: false,
316
+ error: "Setup already completed. Use config endpoints to modify settings.",
317
+ }, { status: 400 }), req)
318
+ }
319
+
320
+ try {
321
+ // Clean up any partial setup state (user created but setup didn't finish)
322
+ try {
323
+ const db = getDb()
324
+ const userCount = (db.query("SELECT COUNT(*) as count FROM users").get() as { count: number }).count
325
+ const agentCount = (db.query("SELECT COUNT(*) as count FROM agents WHERE role = 'coordinator'").get() as { count: number }).count
326
+ if (userCount > 0 && agentCount === 0) {
327
+ db.exec("DELETE FROM users") // ON DELETE CASCADE cleans up agents, channels, etc.
328
+ }
329
+ } catch { /* ignore cleanup errors */ }
330
+
331
+ initOnboardingDb()
332
+
333
+ // For Ollama: insert the selected model now that providers are seeded
334
+ // (the earlier insert in handleSetupOllamaModels may have failed due to missing FK)
335
+ if (body.provider === "ollama" && body.model) {
336
+ try {
337
+ getDb().query(`
338
+ INSERT OR IGNORE INTO models (id, name, provider_id, model_type, enabled, active)
339
+ VALUES (?, ?, 'ollama', 'llm', 1, 1)
340
+ `).run(body.model, body.model)
341
+ } catch { /* ignore */ }
342
+ }
343
+
344
+ // Let DB auto-generate userId via randomblob(16) — same as CLI onboarding
345
+ const userId = saveUserProfile({
346
+ userName: body.userName || "User",
347
+ userLanguage: body.userLanguage || "es",
348
+ userTimezone: body.userTimezone || "UTC",
349
+ userOccupation: body.userOccupation || "",
350
+ userNotes: body.userNotes || "",
351
+ })
352
+
353
+ // Let DB auto-generate agentId — same as CLI onboarding
354
+ const agentId = saveAgentConfig({
355
+ userId,
356
+ agentName: body.agentName || "Bee",
357
+ description: body.agentDescription || "",
358
+ tone: body.agentTone || "friendly",
359
+ providerId: body.provider || "",
360
+ modelId: body.model || "",
361
+ })
362
+
363
+ if (body.provider && (body.apiKey || body.provider === "ollama")) {
364
+ await saveProviderConfig({
365
+ userId,
366
+ provider: body.provider,
367
+ model: body.model,
368
+ apiKey: body.apiKey || undefined,
369
+ })
370
+ }
371
+
372
+ await activateChannel(userId, {
373
+ channelId: "webchat",
374
+ config: {},
375
+ })
376
+
377
+ if (body.channels) {
378
+ for (const [channelId, channelData] of Object.entries(body.channels as Record<string, unknown>)) {
379
+ if (channelId !== "webchat" && channelData && typeof channelData === "object" && (channelData as { enabled?: boolean }).enabled) {
380
+ await activateChannel(userId, {
381
+ channelId,
382
+ config: (channelData as { config?: Record<string, unknown> }).config || {},
383
+ })
384
+ }
385
+ }
386
+ }
387
+
388
+ if (body.voiceEnabled) {
389
+ await saveVoiceConfig({
390
+ userId,
391
+ channelId: "webchat",
392
+ voiceEnabled: true,
393
+ sttProvider: body.sttProvider || "groq-whisper",
394
+ ttsProvider: body.ttsProvider || "elevenlabs",
395
+ })
396
+ }
397
+
398
+ // Activar ethics — usar las seleccionadas por el usuario, o "default" si no viene nada
399
+ if (body.ethicsRules && typeof body.ethicsRules === "object") {
400
+ for (const [ethicsId, enabled] of Object.entries(body.ethicsRules as Record<string, boolean>)) {
401
+ if (enabled) activateEthics(userId, ethicsId)
402
+ }
403
+ } else {
404
+ activateEthics(userId, "default")
405
+ }
406
+
407
+ // Use the userId as the auth token — stable, DB-generated, known only to the user.
408
+ // Write ~/.hive/.env so the token survives restarts (loadEnv reads it at boot).
409
+ const authToken = userId
410
+ const hiveDir = getHiveDir()
411
+ const envContent = [
412
+ "# Hive configuration — auto-generated during setup",
413
+ `HIVE_HOST=${process.env.HIVE_HOST || "127.0.0.1"}`,
414
+ `HIVE_PORT=${process.env.HIVE_PORT || "18790"}`,
415
+ `HIVE_LOG_LEVEL=${process.env.HIVE_LOG_LEVEL || "info"}`,
416
+ `HIVE_AUTH_TOKEN=${authToken}`,
417
+ "",
418
+ ].join("\n")
419
+ mkdirSync(hiveDir, { recursive: true })
420
+ writeFileSync(`${hiveDir}/.env`, envContent, { mode: 0o600 })
421
+ writeFileSync(path.join(hiveDir, ".auth_token"), authToken, { mode: 0o600 })
422
+ process.env.HIVE_AUTH_TOKEN = authToken
423
+
424
+ // Restart the process so the gateway re-initializes in full mode.
425
+ // Docker (restart: unless-stopped) brings it back up automatically.
426
+ setTimeout(() => process.exit(0), 800)
427
+
428
+ return addCorsHeaders(Response.json({
429
+ success: true,
430
+ userId,
431
+ agentId,
432
+ authToken,
433
+ message: "Setup completed successfully",
434
+ }), req)
435
+ } catch (error) {
436
+ return addCorsHeaders(Response.json({
437
+ success: false,
438
+ error: (error as Error).message,
439
+ }, { status: 500 }), req)
440
+ }
441
+ }