@johpaz/hive-agents 0.0.38 → 0.0.40

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 (263) hide show
  1. package/README.md +31 -71
  2. package/dist/hive.js +4318 -2898
  3. package/dist/tool-worker.js +2691 -1969
  4. package/dist/ui/assets/AgentCreateForm-b7xHyfNc.js +1 -0
  5. package/dist/ui/assets/AgentDetailPage-VHy3M7mI.js +1 -0
  6. package/dist/ui/assets/AgentNewPage-BnWImQMx.js +1 -0
  7. package/dist/ui/{dist/assets/AgentsPage-DGNLDXjR.js → assets/AgentsPage-WFy5abqx.js} +5 -5
  8. package/dist/ui/assets/ApiClientPage-BV7zLIL7.js +3 -0
  9. package/dist/ui/assets/{CanvasPage-CnMO1FN8.js → CanvasPage-B9zuIrTm.js} +7 -7
  10. package/dist/ui/assets/ChannelsPage-DiN3NvIM.js +8 -0
  11. package/dist/ui/{dist/assets/DashboardPage-VyXXp3U1.js → assets/DashboardPage-CHjARjVK.js} +2 -2
  12. package/dist/ui/assets/{LoginPage-DPj2s2Qq.js → LoginPage-Dwd_XxoU.js} +1 -1
  13. package/dist/ui/assets/LogsPage-DW8Nnqe6.js +1 -0
  14. package/dist/ui/assets/MeetingPage-D3bkiKYt.js +1 -0
  15. package/dist/ui/assets/{NotFound-BMeQSGcG.js → NotFound-BIUDlIXU.js} +1 -1
  16. package/dist/ui/assets/ProvidersPage-UqsDAxPQ.js +1 -0
  17. package/dist/ui/{dist/assets/RecoverPage-B-hDZUM2.js → assets/RecoverPage-8hTjr_JU.js} +1 -1
  18. package/dist/ui/assets/SettingsPage-DNa0jOkA.js +9 -0
  19. package/dist/ui/assets/SetupPage-Bdm2irQG.js +1 -0
  20. package/dist/ui/assets/WebChatPage-DElJg6P2.js +16 -0
  21. package/dist/ui/assets/accordion-CnLzKNHK.js +1 -0
  22. package/dist/ui/{dist/assets/alert-Bq6awLlW.js → assets/alert-DylmSCDJ.js} +1 -1
  23. package/dist/ui/{dist/assets/alert-dialog-DQvltYmf.js → assets/alert-dialog-DNNWN_SI.js} +1 -1
  24. package/dist/ui/assets/{badge-DXUDdTed.js → badge-ChENFgkC.js} +1 -1
  25. package/dist/ui/assets/bell-8BqRYmzf.js +1 -0
  26. package/dist/ui/assets/chevron-down-DIosfU_U.js +1 -0
  27. package/dist/ui/assets/chevron-up-CI-W21Fy.js +1 -0
  28. package/dist/ui/assets/circle-x-DjLkFDO8.js +1 -0
  29. package/dist/ui/assets/copy-Bu5d7C-0.js +1 -0
  30. package/dist/ui/{dist/assets/dialog-bI9jImCS.js → assets/dialog-BJ-npIv8.js} +1 -1
  31. package/dist/ui/{dist/assets/dropdown-menu-BK-CO3Od.js → assets/dropdown-menu-DDiaHg5y.js} +1 -1
  32. package/dist/ui/assets/{es-Cg8zdT52.js → es-ecSKCyB6.js} +1 -1
  33. package/dist/ui/assets/index-CawKP29y.js +116 -0
  34. package/dist/ui/assets/index-DIcsEkyd.css +2 -0
  35. package/dist/ui/{dist/assets/label-CrH0Jj3v.js → assets/label-Bi6udtSd.js} +1 -1
  36. package/dist/ui/assets/progress-D5c-Eilm.js +1 -0
  37. package/dist/ui/assets/scroll-area-CihOx0cb.js +1 -0
  38. package/dist/ui/assets/search-DzDptO9s.js +1 -0
  39. package/dist/ui/assets/select-BQCOjM2j.js +1 -0
  40. package/dist/ui/assets/send-BPk9XbIq.js +1 -0
  41. package/dist/ui/assets/shield-CxhcUT39.js +1 -0
  42. package/dist/ui/assets/{slider-CsiUDxc3.js → slider-bcUiUfx0.js} +1 -1
  43. package/dist/ui/assets/switch-BR30E4ej.js +1 -0
  44. package/dist/ui/assets/table-B3aGEaVp.js +1 -0
  45. package/dist/ui/assets/tabs-LQidMKRS.js +1 -0
  46. package/dist/ui/assets/textarea-B6Z1Zc6W.js +1 -0
  47. package/dist/ui/assets/useProviders-Dlizq_8q.js +1 -0
  48. package/dist/ui/{dist/assets/vendor-radix-cw1bQaVC.js → assets/vendor-radix-D6rA7xKY.js} +4 -4
  49. package/dist/ui/assets/{vendor-react-D4s9E-zj.js → vendor-react-BU5iQU4f.js} +1 -1
  50. package/dist/ui/dist/assets/AgentCreateForm-b7xHyfNc.js +1 -0
  51. package/dist/ui/dist/assets/AgentDetailPage-VHy3M7mI.js +1 -0
  52. package/dist/ui/dist/assets/AgentNewPage-BnWImQMx.js +1 -0
  53. package/dist/ui/{assets/AgentsPage-DGNLDXjR.js → dist/assets/AgentsPage-WFy5abqx.js} +5 -5
  54. package/dist/ui/dist/assets/ApiClientPage-BV7zLIL7.js +3 -0
  55. package/dist/ui/dist/assets/{CanvasPage-CnMO1FN8.js → CanvasPage-B9zuIrTm.js} +7 -7
  56. package/dist/ui/dist/assets/ChannelsPage-DiN3NvIM.js +8 -0
  57. package/dist/ui/{assets/DashboardPage-VyXXp3U1.js → dist/assets/DashboardPage-CHjARjVK.js} +2 -2
  58. package/dist/ui/dist/assets/{LoginPage-DPj2s2Qq.js → LoginPage-Dwd_XxoU.js} +1 -1
  59. package/dist/ui/dist/assets/LogsPage-DW8Nnqe6.js +1 -0
  60. package/dist/ui/dist/assets/MeetingPage-D3bkiKYt.js +1 -0
  61. package/dist/ui/dist/assets/{NotFound-BMeQSGcG.js → NotFound-BIUDlIXU.js} +1 -1
  62. package/dist/ui/dist/assets/ProvidersPage-UqsDAxPQ.js +1 -0
  63. package/dist/ui/{assets/RecoverPage-B-hDZUM2.js → dist/assets/RecoverPage-8hTjr_JU.js} +1 -1
  64. package/dist/ui/dist/assets/SettingsPage-DNa0jOkA.js +9 -0
  65. package/dist/ui/dist/assets/SetupPage-Bdm2irQG.js +1 -0
  66. package/dist/ui/dist/assets/WebChatPage-DElJg6P2.js +16 -0
  67. package/dist/ui/dist/assets/accordion-CnLzKNHK.js +1 -0
  68. package/dist/ui/{assets/alert-Bq6awLlW.js → dist/assets/alert-DylmSCDJ.js} +1 -1
  69. package/dist/ui/{assets/alert-dialog-DQvltYmf.js → dist/assets/alert-dialog-DNNWN_SI.js} +1 -1
  70. package/dist/ui/dist/assets/{badge-DXUDdTed.js → badge-ChENFgkC.js} +1 -1
  71. package/dist/ui/dist/assets/bell-8BqRYmzf.js +1 -0
  72. package/dist/ui/dist/assets/chevron-down-DIosfU_U.js +1 -0
  73. package/dist/ui/dist/assets/chevron-up-CI-W21Fy.js +1 -0
  74. package/dist/ui/dist/assets/circle-x-DjLkFDO8.js +1 -0
  75. package/dist/ui/dist/assets/copy-Bu5d7C-0.js +1 -0
  76. package/dist/ui/{assets/dialog-bI9jImCS.js → dist/assets/dialog-BJ-npIv8.js} +1 -1
  77. package/dist/ui/{assets/dropdown-menu-BK-CO3Od.js → dist/assets/dropdown-menu-DDiaHg5y.js} +1 -1
  78. package/dist/ui/dist/assets/{es-Cg8zdT52.js → es-ecSKCyB6.js} +1 -1
  79. package/dist/ui/dist/assets/index-CawKP29y.js +116 -0
  80. package/dist/ui/dist/assets/index-DIcsEkyd.css +2 -0
  81. package/dist/ui/{assets/label-CrH0Jj3v.js → dist/assets/label-Bi6udtSd.js} +1 -1
  82. package/dist/ui/dist/assets/progress-D5c-Eilm.js +1 -0
  83. package/dist/ui/dist/assets/scroll-area-CihOx0cb.js +1 -0
  84. package/dist/ui/dist/assets/search-DzDptO9s.js +1 -0
  85. package/dist/ui/dist/assets/select-BQCOjM2j.js +1 -0
  86. package/dist/ui/dist/assets/send-BPk9XbIq.js +1 -0
  87. package/dist/ui/dist/assets/shield-CxhcUT39.js +1 -0
  88. package/dist/ui/dist/assets/{slider-CsiUDxc3.js → slider-bcUiUfx0.js} +1 -1
  89. package/dist/ui/dist/assets/switch-BR30E4ej.js +1 -0
  90. package/dist/ui/dist/assets/table-B3aGEaVp.js +1 -0
  91. package/dist/ui/dist/assets/tabs-LQidMKRS.js +1 -0
  92. package/dist/ui/dist/assets/textarea-B6Z1Zc6W.js +1 -0
  93. package/dist/ui/dist/assets/useProviders-Dlizq_8q.js +1 -0
  94. package/dist/ui/{assets/vendor-radix-cw1bQaVC.js → dist/assets/vendor-radix-D6rA7xKY.js} +4 -4
  95. package/dist/ui/dist/assets/{vendor-react-D4s9E-zj.js → vendor-react-BU5iQU4f.js} +1 -1
  96. package/dist/ui/dist/index.html +6 -6
  97. package/dist/ui/index.html +6 -6
  98. package/package.json +1 -1
  99. package/packages/cli/src/adapters/binary.ts +8 -4
  100. package/packages/cli/src/adapters/bun-global.ts +5 -1
  101. package/packages/cli/src/adapters/config.ts +4 -3
  102. package/packages/cli/src/adapters/docker.ts +2 -1
  103. package/packages/cli/src/commands/gateway.ts +123 -9
  104. package/packages/cli/src/commands/logs.ts +2 -1
  105. package/packages/cli/src/commands/onboard.ts +27 -1
  106. package/packages/cli/src/commands/sessions.ts +2 -1
  107. package/packages/cli/src/commands/skills.ts +2 -1
  108. package/packages/core/src/agent/agent-loop.ts +104 -2
  109. package/packages/core/src/agent/context-compiler.ts +6 -0
  110. package/packages/core/src/agent/llm-client.ts +6 -0
  111. package/packages/core/src/agent/llm-providers/anthropic.ts +23 -8
  112. package/packages/core/src/agent/llm-providers/hiveagents.ts +248 -0
  113. package/packages/core/src/agent/llm-providers/interface.ts +7 -1
  114. package/packages/core/src/agent/llm-providers/minimax.ts +13 -0
  115. package/packages/core/src/agent/llm-providers/openai-compat-base.ts +49 -25
  116. package/packages/core/src/agent/llm-providers/opencode-go.ts +9 -0
  117. package/packages/core/src/agent/providers/index.ts +3 -2
  118. package/packages/core/src/agent/stuck-loop.ts +90 -14
  119. package/packages/core/src/channels/base.ts +7 -1
  120. package/packages/core/src/channels/whatsapp.ts +13 -1
  121. package/packages/core/src/config/loader.ts +8 -8
  122. package/packages/core/src/gateway/helpers/path.ts +2 -1
  123. package/packages/core/src/gateway/initializer.ts +4 -4
  124. package/packages/core/src/gateway/llm-local/downloader.ts +130 -11
  125. package/packages/core/src/gateway/llm-local/index.ts +2 -0
  126. package/packages/core/src/gateway/llm-local/models.ts +4 -3
  127. package/packages/core/src/gateway/router.ts +7 -5
  128. package/packages/core/src/gateway/routes/http-client.ts +16 -0
  129. package/packages/core/src/gateway/routes/llm-local.ts +51 -5
  130. package/packages/core/src/gateway/routes/providers.ts +99 -2
  131. package/packages/core/src/gateway/server.ts +131 -57
  132. package/packages/core/src/gateway/slash-commands.ts +7 -1
  133. package/packages/core/src/gateway/tts/src/install.ts +17 -9
  134. package/packages/core/src/storage/crypto.ts +152 -20
  135. package/packages/core/src/storage/migrate.ts +51 -18
  136. package/packages/core/src/storage/onboarding.ts +28 -0
  137. package/packages/core/src/storage/seed.ts +52 -2
  138. package/packages/core/src/tool-runtime/index.ts +22 -1
  139. package/packages/core/src/tools/api/api-request.ts +174 -0
  140. package/packages/core/src/tools/api/index.ts +16 -0
  141. package/packages/core/src/tools/index.ts +12 -0
  142. package/packages/core/src/tools/web/browser-click.ts +2 -2
  143. package/packages/core/src/tools/web/browser-extract.ts +22 -6
  144. package/packages/core/src/tools/web/browser-navigate.ts +34 -18
  145. package/packages/core/src/tools/web/browser-screenshot.ts +40 -8
  146. package/packages/core/src/tools/web/browser-script.ts +2 -2
  147. package/packages/core/src/tools/web/browser-service.ts +295 -341
  148. package/packages/core/src/tools/web/browser-type.ts +5 -10
  149. package/packages/core/src/tools/web/browser-wait.ts +2 -2
  150. package/packages/core/src/tools/web/index.ts +1 -1
  151. package/packages/core/src/utils/logger.ts +2 -1
  152. package/packages/mcp/src/manager.ts +2 -1
  153. package/packages/skills/src/bundled/api/api_client/SKILL.md +132 -0
  154. package/packages/skills/src/bundled-data.generated.ts +1191 -1134
  155. package/packages/skills/src/loader.ts +2 -1
  156. package/dist/ui/assets/AgentCreateForm-0oFbN3gj.js +0 -1
  157. package/dist/ui/assets/AgentDetailPage-BJ4L2fNJ.js +0 -1
  158. package/dist/ui/assets/AgentNewPage-B3n0LUck.js +0 -1
  159. package/dist/ui/assets/ChannelsPage-fbF8K4MR.js +0 -8
  160. package/dist/ui/assets/LogsPage-B2lY9maY.js +0 -1
  161. package/dist/ui/assets/MeetingPage-2ky_hKiG.js +0 -1
  162. package/dist/ui/assets/ProvidersPage-CEyUM2tD.js +0 -1
  163. package/dist/ui/assets/SettingsPage-eO0i3g8p.js +0 -9
  164. package/dist/ui/assets/SetupPage-ByYqTELb.js +0 -1
  165. package/dist/ui/assets/WebChatPage-BuGT2AL0.js +0 -16
  166. package/dist/ui/assets/accordion-C5d5Rm5z.js +0 -1
  167. package/dist/ui/assets/chevron-up-BYhk0K2J.js +0 -1
  168. package/dist/ui/assets/globe-DeCQTCDJ.js +0 -1
  169. package/dist/ui/assets/index-B2fCYtTS.css +0 -2
  170. package/dist/ui/assets/index-CQ7fn00w.js +0 -116
  171. package/dist/ui/assets/progress-BherYzY6.js +0 -1
  172. package/dist/ui/assets/scroll-area-DkeyX32e.js +0 -1
  173. package/dist/ui/assets/send-B0H5SEIE.js +0 -1
  174. package/dist/ui/assets/switch-BDwN8RYV.js +0 -1
  175. package/dist/ui/assets/table-CSc8ubon.js +0 -1
  176. package/dist/ui/assets/textarea-CXgXWKrT.js +0 -1
  177. package/dist/ui/assets/useProviders-CnlC_qCS.js +0 -1
  178. package/dist/ui/dist/assets/AgentCreateForm-0oFbN3gj.js +0 -1
  179. package/dist/ui/dist/assets/AgentDetailPage-BJ4L2fNJ.js +0 -1
  180. package/dist/ui/dist/assets/AgentNewPage-B3n0LUck.js +0 -1
  181. package/dist/ui/dist/assets/ChannelsPage-fbF8K4MR.js +0 -8
  182. package/dist/ui/dist/assets/LogsPage-B2lY9maY.js +0 -1
  183. package/dist/ui/dist/assets/MeetingPage-2ky_hKiG.js +0 -1
  184. package/dist/ui/dist/assets/ProvidersPage-CEyUM2tD.js +0 -1
  185. package/dist/ui/dist/assets/SettingsPage-eO0i3g8p.js +0 -9
  186. package/dist/ui/dist/assets/SetupPage-ByYqTELb.js +0 -1
  187. package/dist/ui/dist/assets/WebChatPage-BuGT2AL0.js +0 -16
  188. package/dist/ui/dist/assets/accordion-C5d5Rm5z.js +0 -1
  189. package/dist/ui/dist/assets/chevron-up-BYhk0K2J.js +0 -1
  190. package/dist/ui/dist/assets/globe-DeCQTCDJ.js +0 -1
  191. package/dist/ui/dist/assets/index-B2fCYtTS.css +0 -2
  192. package/dist/ui/dist/assets/index-CQ7fn00w.js +0 -116
  193. package/dist/ui/dist/assets/progress-BherYzY6.js +0 -1
  194. package/dist/ui/dist/assets/scroll-area-DkeyX32e.js +0 -1
  195. package/dist/ui/dist/assets/send-B0H5SEIE.js +0 -1
  196. package/dist/ui/dist/assets/switch-BDwN8RYV.js +0 -1
  197. package/dist/ui/dist/assets/table-CSc8ubon.js +0 -1
  198. package/dist/ui/dist/assets/textarea-CXgXWKrT.js +0 -1
  199. package/dist/ui/dist/assets/useProviders-CnlC_qCS.js +0 -1
  200. /package/dist/ui/assets/{card-CNf6BS2e.js → card-DFKnZ6ky.js} +0 -0
  201. /package/dist/ui/assets/{circle-alert-CyHDwUj8.js → circle-alert-KuAm2FWh.js} +0 -0
  202. /package/dist/ui/assets/{circle-check-Bb54Ebmu.js → circle-check-6Ard1-2z.js} +0 -0
  203. /package/dist/ui/assets/{cpu-Cdgc_B1K.js → cpu-KDy6-FAI.js} +0 -0
  204. /package/dist/ui/assets/{download-C3ifGMjJ.js → download-Cjbk4Rek.js} +0 -0
  205. /package/dist/ui/assets/{external-link-BvxYeTP1.js → external-link-6sTlRDUR.js} +0 -0
  206. /package/dist/ui/assets/{eye-DqNTU_GD.js → eye-Df8o0tkC.js} +0 -0
  207. /package/dist/ui/assets/{file-text-BT_9S9SM.js → file-text-lnxnjBp0.js} +0 -0
  208. /package/dist/ui/assets/{folder-open-BhH8y9ac.js → folder-open-DJBLDFjv.js} +0 -0
  209. /package/dist/ui/assets/{format-GVHeOyWI.js → format-BwdV8bB5.js} +0 -0
  210. /package/dist/ui/assets/{gateway-url-COCbW0IR.js → gateway-url-DwzPmoc8.js} +0 -0
  211. /package/dist/ui/assets/{gauge-D_TMa4i9.js → gauge-B8Tj43rC.js} +0 -0
  212. /package/dist/ui/assets/{hexagon-DsGOUl-H.js → hexagon-6L79pgVK.js} +0 -0
  213. /package/dist/ui/assets/{history-BSG-Ypqf.js → history-CAF_R34_.js} +0 -0
  214. /package/dist/ui/assets/{info-NwLoa2Mj.js → info-WjromB4Y.js} +0 -0
  215. /package/dist/ui/assets/{key-3EP0dhkT.js → key-DyKOoQh5.js} +0 -0
  216. /package/dist/ui/assets/{loader-circle-CZNax6kS.js → loader-circle-BmBOgYze.js} +0 -0
  217. /package/dist/ui/assets/{lock-Ei1_J-Nq.js → lock-BS6OLXPv.js} +0 -0
  218. /package/dist/ui/assets/{pause-BUqah9Bi.js → pause-VqeUmp2Z.js} +0 -0
  219. /package/dist/ui/assets/{play-NcZ4swwL.js → play-zJpWuhrr.js} +0 -0
  220. /package/dist/ui/assets/{plus-CX1xyhp5.js → plus-BZQX26Dr.js} +0 -0
  221. /package/dist/ui/assets/{refresh-cw-DaYdjQFk.js → refresh-cw-CCzDCAuz.js} +0 -0
  222. /package/dist/ui/assets/{save-CUdYyHNy.js → save-hUmZhceG.js} +0 -0
  223. /package/dist/ui/assets/{settings-Ds4SqD8s.js → settings-BGfrZ_zM.js} +0 -0
  224. /package/dist/ui/assets/{sparkles-yUEb-7oH.js → sparkles-BhwlS1pc.js} +0 -0
  225. /package/dist/ui/assets/{square-BD81nFtN.js → square-DMNWw4Hi.js} +0 -0
  226. /package/dist/ui/assets/{terminal-DN38Q456.js → terminal--7G943As.js} +0 -0
  227. /package/dist/ui/assets/{trash-2-CNjMkoq6.js → trash-2-xD2o4SgX.js} +0 -0
  228. /package/dist/ui/assets/{triangle-alert-C9Y8Ub4X.js → triangle-alert-pVIJGjga.js} +0 -0
  229. /package/dist/ui/assets/{vendor-router-C9pIYwbJ.js → vendor-router-gqiZ7xhx.js} +0 -0
  230. /package/dist/ui/assets/{volume-2-CeSXNDv4.js → volume-2-BekVQl6P.js} +0 -0
  231. /package/dist/ui/assets/{zap-hlXjpSeA.js → zap-B4RaNNO5.js} +0 -0
  232. /package/dist/ui/dist/assets/{card-CNf6BS2e.js → card-DFKnZ6ky.js} +0 -0
  233. /package/dist/ui/dist/assets/{circle-alert-CyHDwUj8.js → circle-alert-KuAm2FWh.js} +0 -0
  234. /package/dist/ui/dist/assets/{circle-check-Bb54Ebmu.js → circle-check-6Ard1-2z.js} +0 -0
  235. /package/dist/ui/dist/assets/{cpu-Cdgc_B1K.js → cpu-KDy6-FAI.js} +0 -0
  236. /package/dist/ui/dist/assets/{download-C3ifGMjJ.js → download-Cjbk4Rek.js} +0 -0
  237. /package/dist/ui/dist/assets/{external-link-BvxYeTP1.js → external-link-6sTlRDUR.js} +0 -0
  238. /package/dist/ui/dist/assets/{eye-DqNTU_GD.js → eye-Df8o0tkC.js} +0 -0
  239. /package/dist/ui/dist/assets/{file-text-BT_9S9SM.js → file-text-lnxnjBp0.js} +0 -0
  240. /package/dist/ui/dist/assets/{folder-open-BhH8y9ac.js → folder-open-DJBLDFjv.js} +0 -0
  241. /package/dist/ui/dist/assets/{format-GVHeOyWI.js → format-BwdV8bB5.js} +0 -0
  242. /package/dist/ui/dist/assets/{gateway-url-COCbW0IR.js → gateway-url-DwzPmoc8.js} +0 -0
  243. /package/dist/ui/dist/assets/{gauge-D_TMa4i9.js → gauge-B8Tj43rC.js} +0 -0
  244. /package/dist/ui/dist/assets/{hexagon-DsGOUl-H.js → hexagon-6L79pgVK.js} +0 -0
  245. /package/dist/ui/dist/assets/{history-BSG-Ypqf.js → history-CAF_R34_.js} +0 -0
  246. /package/dist/ui/dist/assets/{info-NwLoa2Mj.js → info-WjromB4Y.js} +0 -0
  247. /package/dist/ui/dist/assets/{key-3EP0dhkT.js → key-DyKOoQh5.js} +0 -0
  248. /package/dist/ui/dist/assets/{loader-circle-CZNax6kS.js → loader-circle-BmBOgYze.js} +0 -0
  249. /package/dist/ui/dist/assets/{lock-Ei1_J-Nq.js → lock-BS6OLXPv.js} +0 -0
  250. /package/dist/ui/dist/assets/{pause-BUqah9Bi.js → pause-VqeUmp2Z.js} +0 -0
  251. /package/dist/ui/dist/assets/{play-NcZ4swwL.js → play-zJpWuhrr.js} +0 -0
  252. /package/dist/ui/dist/assets/{plus-CX1xyhp5.js → plus-BZQX26Dr.js} +0 -0
  253. /package/dist/ui/dist/assets/{refresh-cw-DaYdjQFk.js → refresh-cw-CCzDCAuz.js} +0 -0
  254. /package/dist/ui/dist/assets/{save-CUdYyHNy.js → save-hUmZhceG.js} +0 -0
  255. /package/dist/ui/dist/assets/{settings-Ds4SqD8s.js → settings-BGfrZ_zM.js} +0 -0
  256. /package/dist/ui/dist/assets/{sparkles-yUEb-7oH.js → sparkles-BhwlS1pc.js} +0 -0
  257. /package/dist/ui/dist/assets/{square-BD81nFtN.js → square-DMNWw4Hi.js} +0 -0
  258. /package/dist/ui/dist/assets/{terminal-DN38Q456.js → terminal--7G943As.js} +0 -0
  259. /package/dist/ui/dist/assets/{trash-2-CNjMkoq6.js → trash-2-xD2o4SgX.js} +0 -0
  260. /package/dist/ui/dist/assets/{triangle-alert-C9Y8Ub4X.js → triangle-alert-pVIJGjga.js} +0 -0
  261. /package/dist/ui/dist/assets/{vendor-router-C9pIYwbJ.js → vendor-router-gqiZ7xhx.js} +0 -0
  262. /package/dist/ui/dist/assets/{volume-2-CeSXNDv4.js → volume-2-BekVQl6P.js} +0 -0
  263. /package/dist/ui/dist/assets/{zap-hlXjpSeA.js → zap-B4RaNNO5.js} +0 -0
@@ -1,4 +1,5 @@
1
1
  import { logger } from "../utils/logger"
2
+ import { getDb } from "./sqlite"
2
3
 
3
4
  const log = logger.child("crypto")
4
5
  const SERVICE = "hive"
@@ -12,30 +13,71 @@ const _mem = new Map<string, string>()
12
13
  let _keychainOk: boolean | null = null // null = untested
13
14
 
14
15
  async function _get(name: string): Promise<string | null> {
15
- if (_keychainOk === false) return _mem.get(name) ?? null
16
+ if (_keychainOk === false) {
17
+ return _mem.get(name) ?? _readDbSecret(name)
18
+ }
16
19
  try {
17
20
  const val = await (Bun as any).secrets.get({ service: SERVICE, name })
18
21
  _keychainOk = true
19
- return val ?? null
22
+ return val ?? _mem.get(name) ?? _readDbSecret(name)
20
23
  } catch {
21
24
  _keychainOk = false
22
- return _mem.get(name) ?? null
25
+ return _mem.get(name) ?? _readDbSecret(name)
23
26
  }
24
27
  }
25
28
 
26
- async function _set(name: string, value: string): Promise<void> {
29
+ async function _set(name: string, value: string): Promise<boolean> {
27
30
  if (_keychainOk === false) {
28
- log.warn(`[secrets] OS keychain unavailable — in-memory fallback (secret lost on restart): ${name}`)
29
31
  _mem.set(name, value)
30
- return
32
+ return persistSecretToDb(name, value)
31
33
  }
32
34
  try {
33
35
  await (Bun as any).secrets.set({ service: SERVICE, name, value })
34
36
  _keychainOk = true
37
+ return true
35
38
  } catch {
36
39
  _keychainOk = false
37
- log.warn(`[secrets] OS keychain unavailable — in-memory fallback (secret lost on restart): ${name}`)
38
40
  _mem.set(name, value)
41
+ return persistSecretToDb(name, value)
42
+ }
43
+ }
44
+
45
+ /**
46
+ * Read a secret from its DB ciphertext column as a last-resort fallback
47
+ * when the keychain and in-memory map are both empty. Used to survive
48
+ * container restarts when the OS keychain is unavailable (Docker, headless).
49
+ */
50
+ function _readDbSecret(name: string): string | null {
51
+ const parts = name.split(":")
52
+ if (parts.length !== 3) return null
53
+ const [kind, id, field] = parts
54
+
55
+ let table: string
56
+ let column: string
57
+ switch (`${kind}:${field}`) {
58
+ case "provider:api_key": table = "providers"; column = "api_key"; break
59
+ case "provider:headers": table = "providers"; column = "headers"; break
60
+ case "channel:config": table = "channels"; column = "config"; break
61
+ case "mcp:headers": table = "mcp_servers"; column = "headers"; break
62
+ case "mcp:env": table = "mcp_servers"; column = "env"; break
63
+ case "agent:headers": table = "agents"; column = "headers"; break
64
+ default: return null
65
+ }
66
+
67
+ try {
68
+ const db = getDb()
69
+ const row = db.query(
70
+ `SELECT ${column}_encrypted AS enc, ${column}_iv AS iv FROM ${table} WHERE id = ?`
71
+ ).get(id) as { enc: string | null; iv: string | null } | undefined
72
+ if (!row?.enc || !row?.iv) return null
73
+ const plain = legacyDecryptAES(row.enc, row.iv)
74
+ if (plain) {
75
+ // Cache in memory for subsequent lookups in this process
76
+ _mem.set(name, plain)
77
+ }
78
+ return plain || null
79
+ } catch {
80
+ return null
39
81
  }
40
82
  }
41
83
 
@@ -64,16 +106,22 @@ export async function deleteSecret(name: string): Promise<void> {
64
106
 
65
107
  // ─── Provider secrets ────────────────────────────────────────────────────────
66
108
 
67
- export async function storeProviderApiKey(id: string, apiKey: string): Promise<void> {
68
- await _set(`provider:${id}:api_key`, apiKey)
109
+ /**
110
+ * Returns true if the secret was persisted to a durable store (OS keychain
111
+ * or DB-backed fallback). Returns false if it ended up in the per-process
112
+ * in-memory map only — useful so callers can avoid destructive actions
113
+ * (like nulling the DB ciphertext) that would lose data on restart.
114
+ */
115
+ export async function storeProviderApiKey(id: string, apiKey: string): Promise<boolean> {
116
+ return await _set(`provider:${id}:api_key`, apiKey)
69
117
  }
70
118
 
71
119
  export async function loadProviderApiKey(id: string): Promise<string> {
72
120
  return (await _get(`provider:${id}:api_key`)) ?? ""
73
121
  }
74
122
 
75
- export async function storeProviderHeaders(id: string, headers: Record<string, unknown>): Promise<void> {
76
- await _set(`provider:${id}:headers`, JSON.stringify(headers))
123
+ export async function storeProviderHeaders(id: string, headers: Record<string, unknown>): Promise<boolean> {
124
+ return await _set(`provider:${id}:headers`, JSON.stringify(headers))
77
125
  }
78
126
 
79
127
  export async function loadProviderHeaders(id: string): Promise<Record<string, unknown>> {
@@ -90,8 +138,8 @@ export async function deleteProviderSecrets(id: string): Promise<void> {
90
138
 
91
139
  // ─── Channel secrets ─────────────────────────────────────────────────────────
92
140
 
93
- export async function storeChannelConfig(id: string, config: Record<string, unknown>): Promise<void> {
94
- await _set(`channel:${id}:config`, JSON.stringify(config))
141
+ export async function storeChannelConfig(id: string, config: Record<string, unknown>): Promise<boolean> {
142
+ return await _set(`channel:${id}:config`, JSON.stringify(config))
95
143
  }
96
144
 
97
145
  export async function loadChannelConfig(id: string): Promise<Record<string, unknown>> {
@@ -105,8 +153,8 @@ export async function deleteChannelSecrets(id: string): Promise<void> {
105
153
 
106
154
  // ─── MCP secrets ──────────────────────────────────────────────────────────────
107
155
 
108
- export async function storeMcpHeaders(id: string, headers: Record<string, unknown>): Promise<void> {
109
- await _set(`mcp:${id}:headers`, JSON.stringify(headers))
156
+ export async function storeMcpHeaders(id: string, headers: Record<string, unknown>): Promise<boolean> {
157
+ return await _set(`mcp:${id}:headers`, JSON.stringify(headers))
110
158
  }
111
159
 
112
160
  export async function loadMcpHeaders(id: string): Promise<Record<string, unknown>> {
@@ -114,8 +162,8 @@ export async function loadMcpHeaders(id: string): Promise<Record<string, unknown
114
162
  return raw ? JSON.parse(raw) : {}
115
163
  }
116
164
 
117
- export async function storeMcpEnv(id: string, env: Record<string, string>): Promise<void> {
118
- await _set(`mcp:${id}:env`, JSON.stringify(env))
165
+ export async function storeMcpEnv(id: string, env: Record<string, string>): Promise<boolean> {
166
+ return await _set(`mcp:${id}:env`, JSON.stringify(env))
119
167
  }
120
168
 
121
169
  export async function loadMcpEnv(id: string): Promise<Record<string, string>> {
@@ -132,8 +180,8 @@ export async function deleteMcpSecrets(id: string): Promise<void> {
132
180
 
133
181
  // ─── Agent secrets ────────────────────────────────────────────────────────────
134
182
 
135
- export async function storeAgentHeaders(id: string, headers: Record<string, unknown>): Promise<void> {
136
- await _set(`agent:${id}:headers`, JSON.stringify(headers))
183
+ export async function storeAgentHeaders(id: string, headers: Record<string, unknown>): Promise<boolean> {
184
+ return await _set(`agent:${id}:headers`, JSON.stringify(headers))
137
185
  }
138
186
 
139
187
  export async function loadAgentHeaders(id: string): Promise<Record<string, unknown>> {
@@ -182,7 +230,7 @@ export function legacyDecryptAES(encrypted: string, iv: string): string {
182
230
  const hiveDir = process.env.HIVE_HOME || nodePath.join(nodeOs.homedir(), ".hive")
183
231
  const keyPath = nodePath.join(hiveDir, ".master.key")
184
232
  if (!nodeFs.existsSync(keyPath)) return ""
185
- key = Buffer.from(nodeFs.readFileSync(keyPath, "utf-8").trim(), "hex")
233
+ key = Buffer.from(nodeFs.readFileSync(keyPath, "utf8").trim(), "hex")
186
234
  }
187
235
 
188
236
  try {
@@ -195,3 +243,87 @@ export function legacyDecryptAES(encrypted: string, iv: string): string {
195
243
  return ""
196
244
  }
197
245
  }
246
+
247
+ function getMasterKey(): Buffer | null {
248
+ const nodeCrypto = require("node:crypto")
249
+ const nodeFs = require("node:fs")
250
+ const nodePath = require("node:path")
251
+ const nodeOs = require("node:os")
252
+
253
+ const masterKey = process.env.HIVE_MASTER_KEY
254
+ if (masterKey) {
255
+ return Buffer.from(masterKey.slice(0, 32).padEnd(32, "0"), "utf8")
256
+ }
257
+ const hiveDir = process.env.HIVE_HOME || nodePath.join(nodeOs.homedir(), ".hive")
258
+ const keyPath = nodePath.join(hiveDir, ".master.key")
259
+ if (!nodeFs.existsSync(keyPath)) return null
260
+ try {
261
+ return Buffer.from(nodeFs.readFileSync(keyPath, "utf8").trim(), "hex")
262
+ } catch {
263
+ return null
264
+ }
265
+ }
266
+
267
+ /**
268
+ * Encrypt a plaintext string using the same AES-256-GCM scheme as the legacy
269
+ * store. Format: `<encDataHex>:<authTagHex>`. Used as a DB-backed fallback
270
+ * when the OS keychain is unavailable (headless Linux, Docker, etc.).
271
+ */
272
+ export function legacyEncryptAES(plain: string, ivHex: string): string {
273
+ const nodeCrypto = require("node:crypto")
274
+ const key = getMasterKey()
275
+ if (!key) return ""
276
+ try {
277
+ const iv = Buffer.from(ivHex, "hex")
278
+ const cipher = nodeCrypto.createCipheriv("aes-256-gcm", key, iv)
279
+ const encData = cipher.update(plain, "utf8", "hex") + cipher.final("hex")
280
+ const authTag = cipher.getAuthTag().toString("hex")
281
+ return `${encData}:${authTag}`
282
+ } catch {
283
+ return ""
284
+ }
285
+ }
286
+
287
+ /**
288
+ * DB-backed persistence fallback for secrets. Maps the canonical secret
289
+ * name (e.g. `provider:openai:api_key`) to the matching ciphertext column
290
+ * and updates the row in-place. Returns true if the row was written.
291
+ */
292
+ function persistSecretToDb(name: string, value: string): boolean {
293
+ const nodeCrypto = require("node:crypto")
294
+ const parts = name.split(":")
295
+ if (parts.length !== 3) return false
296
+ const [kind, id, field] = parts
297
+
298
+ let table: string
299
+ let column: string
300
+ switch (`${kind}:${field}`) {
301
+ case "provider:api_key": table = "providers"; column = "api_key"; break
302
+ case "provider:headers": table = "providers"; column = "headers"; break
303
+ case "channel:config": table = "channels"; column = "config"; break
304
+ case "mcp:headers": table = "mcp_servers"; column = "headers"; break
305
+ case "mcp:env": table = "mcp_servers"; column = "env"; break
306
+ case "agent:headers": table = "agents"; column = "headers"; break
307
+ default: return false
308
+ }
309
+
310
+ const key = getMasterKey()
311
+ if (!key) {
312
+ log.warn(`[secrets] No master key in ${process.env.HIVE_HOME || "~/.hive"}/.master.key — cannot persist ${name} to DB fallback`)
313
+ return false
314
+ }
315
+
316
+ const iv = nodeCrypto.randomBytes(12).toString("hex")
317
+ const enc = legacyEncryptAES(value, iv)
318
+ if (!enc) return false
319
+
320
+ try {
321
+ const db = getDb()
322
+ db.query(`UPDATE ${table} SET ${column}_encrypted = ?, ${column}_iv = ? WHERE id = ?`)
323
+ .run(enc, iv, id)
324
+ return true
325
+ } catch (err) {
326
+ log.warn(`[secrets] DB fallback failed for ${name}: ${(err as Error).message}`)
327
+ return false
328
+ }
329
+ }
@@ -39,25 +39,38 @@ export async function migrateEncryptedSecretsToKeychain(): Promise<void> {
39
39
  for (const p of providers) {
40
40
  if (p.api_key_encrypted && p.api_key_iv) {
41
41
  const existing = await loadProviderApiKey(p.id)
42
+ let stored = !!existing
42
43
  if (!existing) {
43
44
  const plain = legacyDecryptAES(p.api_key_encrypted, p.api_key_iv)
44
45
  if (plain) {
45
- await storeProviderApiKey(p.id, plain)
46
- migrated++
46
+ stored = await storeProviderApiKey(p.id, plain)
47
+ if (stored) migrated++
47
48
  }
48
49
  }
49
- db.query(`UPDATE providers SET api_key_encrypted = NULL, api_key_iv = NULL WHERE id = ?`).run(p.id)
50
+ // Only null the DB ciphertext when the secret reached a durable store
51
+ // (OS keychain or DB-backed fallback). In-memory fallback would lose
52
+ // the secret on the next process restart.
53
+ if (stored) {
54
+ db.query(`UPDATE providers SET api_key_encrypted = NULL, api_key_iv = NULL WHERE id = ?`).run(p.id)
55
+ } else {
56
+ log.warn(`[migrate] keychain unavailable — keeping AES ciphertext for ${p.id} (will retry next start)`)
57
+ }
50
58
  }
51
59
 
52
60
  if (p.headers_encrypted && p.headers_iv) {
53
61
  const plain = legacyDecryptAES(p.headers_encrypted, p.headers_iv)
62
+ let stored = false
54
63
  if (plain) {
55
64
  try {
56
- await storeProviderHeaders(p.id, JSON.parse(plain))
57
- migrated++
65
+ stored = await storeProviderHeaders(p.id, JSON.parse(plain))
66
+ if (stored) migrated++
58
67
  } catch { /* ignore JSON parse errors */ }
59
68
  }
60
- db.query(`UPDATE providers SET headers_encrypted = NULL, headers_iv = NULL WHERE id = ?`).run(p.id)
69
+ if (stored) {
70
+ db.query(`UPDATE providers SET headers_encrypted = NULL, headers_iv = NULL WHERE id = ?`).run(p.id)
71
+ } else {
72
+ log.warn(`[migrate] keychain unavailable — keeping AES headers ciphertext for ${p.id}`)
73
+ }
61
74
  }
62
75
  }
63
76
 
@@ -74,13 +87,18 @@ export async function migrateEncryptedSecretsToKeychain(): Promise<void> {
74
87
 
75
88
  for (const c of channels) {
76
89
  const plain = legacyDecryptAES(c.config_encrypted, c.config_iv)
90
+ let stored = false
77
91
  if (plain) {
78
92
  try {
79
- await storeChannelConfig(c.id, JSON.parse(plain))
80
- migrated++
93
+ stored = await storeChannelConfig(c.id, JSON.parse(plain))
94
+ if (stored) migrated++
81
95
  } catch { /* ignore JSON parse errors */ }
82
96
  }
83
- db.query(`UPDATE channels SET config_encrypted = NULL, config_iv = NULL WHERE id = ?`).run(c.id)
97
+ if (stored) {
98
+ db.query(`UPDATE channels SET config_encrypted = NULL, config_iv = NULL WHERE id = ?`).run(c.id)
99
+ } else {
100
+ log.warn(`[migrate] keychain unavailable — keeping channel config for ${c.id}`)
101
+ }
84
102
  }
85
103
 
86
104
  // ── MCP servers ────────────────────────────────────────────────────────────
@@ -99,23 +117,33 @@ export async function migrateEncryptedSecretsToKeychain(): Promise<void> {
99
117
  for (const m of mcpServers) {
100
118
  if (m.headers_encrypted && m.headers_iv) {
101
119
  const plain = legacyDecryptAES(m.headers_encrypted, m.headers_iv)
120
+ let stored = false
102
121
  if (plain) {
103
122
  try {
104
- await storeMcpHeaders(m.id, JSON.parse(plain))
105
- migrated++
123
+ stored = await storeMcpHeaders(m.id, JSON.parse(plain))
124
+ if (stored) migrated++
106
125
  } catch { /* ignore */ }
107
126
  }
108
- db.query(`UPDATE mcp_servers SET headers_encrypted = NULL, headers_iv = NULL WHERE id = ?`).run(m.id)
127
+ if (stored) {
128
+ db.query(`UPDATE mcp_servers SET headers_encrypted = NULL, headers_iv = NULL WHERE id = ?`).run(m.id)
129
+ } else {
130
+ log.warn(`[migrate] keychain unavailable — keeping MCP headers for ${m.id}`)
131
+ }
109
132
  }
110
133
  if (m.env_encrypted && m.env_iv) {
111
134
  const plain = legacyDecryptAES(m.env_encrypted, m.env_iv)
135
+ let stored = false
112
136
  if (plain) {
113
137
  try {
114
- await storeMcpEnv(m.id, JSON.parse(plain))
115
- migrated++
138
+ stored = await storeMcpEnv(m.id, JSON.parse(plain))
139
+ if (stored) migrated++
116
140
  } catch { /* ignore */ }
117
141
  }
118
- db.query(`UPDATE mcp_servers SET env_encrypted = NULL, env_iv = NULL WHERE id = ?`).run(m.id)
142
+ if (stored) {
143
+ db.query(`UPDATE mcp_servers SET env_encrypted = NULL, env_iv = NULL WHERE id = ?`).run(m.id)
144
+ } else {
145
+ log.warn(`[migrate] keychain unavailable — keeping MCP env for ${m.id}`)
146
+ }
119
147
  }
120
148
  }
121
149
 
@@ -132,13 +160,18 @@ export async function migrateEncryptedSecretsToKeychain(): Promise<void> {
132
160
 
133
161
  for (const a of agents) {
134
162
  const plain = legacyDecryptAES(a.headers_encrypted, a.headers_iv)
163
+ let stored = false
135
164
  if (plain) {
136
165
  try {
137
- await storeAgentHeaders(a.id, JSON.parse(plain))
138
- migrated++
166
+ stored = await storeAgentHeaders(a.id, JSON.parse(plain))
167
+ if (stored) migrated++
139
168
  } catch { /* ignore */ }
140
169
  }
141
- db.query(`UPDATE agents SET headers_encrypted = NULL, headers_iv = NULL WHERE id = ?`).run(a.id)
170
+ if (stored) {
171
+ db.query(`UPDATE agents SET headers_encrypted = NULL, headers_iv = NULL WHERE id = ?`).run(a.id)
172
+ } else {
173
+ log.warn(`[migrate] keychain unavailable — keeping agent headers for ${a.id}`)
174
+ }
142
175
  }
143
176
 
144
177
  if (migrated > 0) {
@@ -1500,6 +1500,34 @@ export function runStartupMigrations(): void {
1500
1500
  markApplied("v0.0.32");
1501
1501
  log.info("✅ Migration v0.0.32: vision columns added to channels");
1502
1502
  }
1503
+
1504
+ // v0.0.33 — add HiveAgents LLM provider + 5 local GGUF models
1505
+ if (!applied("v0.0.33")) {
1506
+ const db = getDb();
1507
+ log.info("[migration v0.0.33] Adding HiveAgents LLM provider and models...");
1508
+
1509
+ db.query(`
1510
+ INSERT OR IGNORE INTO providers (id, name, base_url, category, enabled, active)
1511
+ VALUES ('hiveagents', 'HiveAgents LLM (Cloudflare)', 'https://llm.hiveagents.io/v1', 'llm', 1, 1)
1512
+ `).run();
1513
+
1514
+ const hiveModels = [
1515
+ { id: "Qwen3.6-35B-A3B-UD-Q6_K.gguf", name: "Qwen3.6 35B MoE (Recomendado)", ctx: 8192, caps: '["chat","streaming","reasoning"]' },
1516
+ { id: "gemma-4-26B-A4B-it-UD-Q6_K_XL.gguf", name: "Gemma 4 26B MoE", ctx: 8192, caps: '["chat","streaming"]' },
1517
+ { id: "gemma-4-12b-it-UD-Q4_K_XL.gguf", name: "Gemma 4 12B Dense", ctx: 8192, caps: '["chat","streaming"]' },
1518
+ { id: "Qwen3.6-27B-UD-Q6_K_XL.gguf", name: "Qwen3.6 27B + MTP", ctx: 8192, caps: '["chat","streaming","reasoning"]' },
1519
+ { id: "gemma-4-31B-it-UD-Q6_K_XL.gguf", name: "Gemma 4 31B Dense", ctx: 8192, caps: '["chat","streaming"]' },
1520
+ ];
1521
+ for (const m of hiveModels) {
1522
+ db.query(`
1523
+ INSERT OR IGNORE INTO models (id, provider_id, name, model_type, context_window, capabilities, enabled, active)
1524
+ VALUES (?, 'hiveagents', ?, 'llm', ?, ?, 1, 1)
1525
+ `).run(m.id, m.name, m.ctx, m.caps);
1526
+ }
1527
+
1528
+ markApplied("v0.0.33");
1529
+ log.info("✅ Migration v0.0.33: HiveAgents LLM provider + 5 models added");
1530
+ }
1503
1531
  } catch (e) {
1504
1532
  log.error("⚠️ runStartupMigrations failed:", { error: (e as Error).message });
1505
1533
  }
@@ -139,7 +139,10 @@ export const SEED_DATA: SeedData = {
139
139
  { id: "elevenlabs", name: "ElevenLabs", baseUrl: "https://api.elevenlabs.io/v1" },
140
140
  { id: "qwen", name: "Qwen (Alibaba)", baseUrl: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1", category: "llm" },
141
141
  { id: "nvidia", name: "NVIDIA NIM", baseUrl: "https://integrate.api.nvidia.com/v1" },
142
+ { id: "minimax", name: "MiniMax", baseUrl: "https://api.minimaxi.com/v1" },
143
+ { id: "opencode-go", name: "OpenCode Go", baseUrl: "https://opencode.ai/zen/go/v1" },
142
144
  { id: "piper", name: "Piper (Local TTS)" },
145
+ { id: "hiveagents", name: "HiveAgents LLM (Cloudflare)", baseUrl: "https://llm.hiveagents.io/v1", category: "llm" },
143
146
  ],
144
147
 
145
148
  models: [
@@ -249,6 +252,14 @@ export const SEED_DATA: SeedData = {
249
252
  { id: "e2b_Q4_K_XL", providerId: "local-llama", name: "Gemma 4 2B (Local)", modelType: "llm", contextWindow: 16000, capabilities: JSON.stringify(["chat", "text", "stt", "local"]) },
250
253
  { id: "e4b_Q4_K_XL", providerId: "local-llama", name: "Gemma 4 4B (Local)", modelType: "llm", contextWindow: 16000, capabilities: JSON.stringify(["chat", "text", "vision", "stt", "local"]) },
251
254
  { id: "e4b_vision", providerId: "local-llama", name: "Gemma 4 4B Vision (Local)", modelType: "llm", contextWindow: 16000, capabilities: JSON.stringify(["chat", "vision", "local"]) },
255
+ { id: "gemma4_12b_Q4_K_XL", providerId: "local-llama", name: "Gemma 4 12B (Local)", modelType: "llm", contextWindow: 16000, capabilities: JSON.stringify(["chat", "vision", "local"]) },
256
+ { id: "gemma4_26b_Q4_K_M", providerId: "local-llama", name: "Gemma 4 26B (Local)", modelType: "llm", contextWindow: 16000, capabilities: JSON.stringify(["chat", "vision", "local"]) },
257
+ { id: "gemma4_31b_Q4_K_XL", providerId: "local-llama", name: "Gemma 4 31B (Local)", modelType: "llm", contextWindow: 16000, capabilities: JSON.stringify(["chat", "vision", "local"]) },
258
+ { id: "qwen3_5_2b_Q4_K_XL", providerId: "local-llama", name: "Qwen 3.5 2B (Local)", modelType: "llm", contextWindow: 16000, capabilities: JSON.stringify(["chat", "local"]) },
259
+ { id: "qwen3_5_4b_Q4_K_XL", providerId: "local-llama", name: "Qwen 3.5 4B (Local)", modelType: "llm", contextWindow: 16000, capabilities: JSON.stringify(["chat", "local"]) },
260
+ { id: "qwen3_5_9b_Q4_K_XL", providerId: "local-llama", name: "Qwen 3.5 9B (Local)", modelType: "llm", contextWindow: 16000, capabilities: JSON.stringify(["chat", "local"]) },
261
+ { id: "qwen3_5_27b_Q4_K_XL", providerId: "local-llama", name: "Qwen 3.5 27B (Local)", modelType: "llm", contextWindow: 16000, capabilities: JSON.stringify(["chat", "local"]) },
262
+ { id: "qwen3_5_35b_Q4_K_XL", providerId: "local-llama", name: "Qwen 3.5 35B (Local)", modelType: "llm", contextWindow: 16000, capabilities: JSON.stringify(["chat", "local"]) },
252
263
  { id: "local_stt", providerId: "local-llama", name: "Local STT (Gemma)", modelType: "stt", contextWindow: 16000, capabilities: JSON.stringify(["transcription", "local"]) },
253
264
 
254
265
 
@@ -282,6 +293,42 @@ export const SEED_DATA: SeedData = {
282
293
  { id: "google/gemma-4-31b-it", providerId: "nvidia", name: "Gemma 4 31B (NVIDIA)", modelType: "llm", contextWindow: 262144, capabilities: JSON.stringify(["chat", "vision", "json_mode", "function_calling", "streaming"]) },
283
294
  { id: "google/gemma-3-27b-it", providerId: "nvidia", name: "Gemma 3 27B (NVIDIA)", modelType: "llm", contextWindow: 131072, capabilities: JSON.stringify(["chat", "vision", "json_mode", "function_calling", "streaming"]) },
284
295
  { id: "z-ai/glm-5.1", providerId: "nvidia", name: "GLM 5.1 (NVIDIA)", modelType: "llm", contextWindow: 131072, capabilities: JSON.stringify(["chat", "json_mode", "function_calling", "streaming"]) },
296
+
297
+ // ── MiniMax (fuente: platform.minimaxi.com) — OpenAI-compatible endpoint ──
298
+ { id: "MiniMax-M3", providerId: "minimax", name: "MiniMax M3", modelType: "llm", contextWindow: 1000000, capabilities: JSON.stringify(["chat", "code", "vision", "function_calling", "streaming", "reasoning"]) },
299
+ { id: "MiniMax-M2.7", providerId: "minimax", name: "MiniMax M2.7", modelType: "llm", contextWindow: 1000000, capabilities: JSON.stringify(["chat", "code", "function_calling", "streaming"]) },
300
+ { id: "MiniMax-M2.7-highspeed", providerId: "minimax", name: "MiniMax M2.7 Highspeed", modelType: "llm", contextWindow: 1000000, capabilities: JSON.stringify(["chat", "code", "function_calling", "streaming"]) },
301
+ { id: "MiniMax-M2.5", providerId: "minimax", name: "MiniMax M2.5", modelType: "llm", contextWindow: 1000000, capabilities: JSON.stringify(["chat", "code", "function_calling", "streaming"]) },
302
+ { id: "MiniMax-M2.5-highspeed", providerId: "minimax", name: "MiniMax M2.5 Highspeed", modelType: "llm", contextWindow: 1000000, capabilities: JSON.stringify(["chat", "code", "function_calling", "streaming"]) },
303
+
304
+ // ── OpenCode Go (fuente: opencode.ai) — OpenAI-compatible endpoint ──
305
+ { id: "opencode-go/minimax-m3", providerId: "opencode-go", name: "MiniMax M3", modelType: "llm", contextWindow: 1000000, capabilities: JSON.stringify(["chat", "code", "vision", "function_calling", "streaming", "reasoning"]) },
306
+ { id: "opencode-go/minimax-m2.7", providerId: "opencode-go", name: "MiniMax M2.7", modelType: "llm", contextWindow: 1000000, capabilities: JSON.stringify(["chat", "code", "function_calling", "streaming"]) },
307
+ { id: "opencode-go/minimax-m2.5", providerId: "opencode-go", name: "MiniMax M2.5", modelType: "llm", contextWindow: 1000000, capabilities: JSON.stringify(["chat", "code", "function_calling", "streaming"]) },
308
+ { id: "opencode-go/kimi-k2.6", providerId: "opencode-go", name: "Kimi K2.6", modelType: "llm", contextWindow: 262144, capabilities: JSON.stringify(["chat", "code", "function_calling", "streaming"]) },
309
+ { id: "opencode-go/kimi-k2.5", providerId: "opencode-go", name: "Kimi K2.5", modelType: "llm", contextWindow: 262144, capabilities: JSON.stringify(["chat", "code", "function_calling", "streaming"]) },
310
+ { id: "opencode-go/glm-5.1", providerId: "opencode-go", name: "GLM-5.1", modelType: "llm", contextWindow: 128000, capabilities: JSON.stringify(["chat", "code", "function_calling", "streaming"]) },
311
+ { id: "opencode-go/glm-5", providerId: "opencode-go", name: "GLM-5", modelType: "llm", contextWindow: 128000, capabilities: JSON.stringify(["chat", "code", "function_calling", "streaming"]) },
312
+ { id: "opencode-go/deepseek-v4-pro", providerId: "opencode-go", name: "DeepSeek V4 Pro", modelType: "llm", contextWindow: 128000, capabilities: JSON.stringify(["chat", "code", "function_calling", "streaming", "reasoning"]) },
313
+ { id: "opencode-go/deepseek-v4-flash", providerId: "opencode-go", name: "DeepSeek V4 Flash", modelType: "llm", contextWindow: 128000, capabilities: JSON.stringify(["chat", "code", "function_calling", "streaming"]) },
314
+ { id: "opencode-go/mimo-v2-pro", providerId: "opencode-go", name: "MiMo-V2 Pro", modelType: "llm", contextWindow: 128000, capabilities: JSON.stringify(["chat", "code", "function_calling", "streaming", "reasoning"]) },
315
+ { id: "opencode-go/mimo-v2-omni", providerId: "opencode-go", name: "MiMo-V2 Omni", modelType: "llm", contextWindow: 128000, capabilities: JSON.stringify(["chat", "code", "function_calling", "streaming"]) },
316
+ { id: "opencode-go/mimo-v2.5-pro", providerId: "opencode-go", name: "MiMo-V2.5 Pro", modelType: "llm", contextWindow: 128000, capabilities: JSON.stringify(["chat", "code", "function_calling", "streaming", "reasoning"]) },
317
+ { id: "opencode-go/mimo-v2.5", providerId: "opencode-go", name: "MiMo-V2.5", modelType: "llm", contextWindow: 128000, capabilities: JSON.stringify(["chat", "code", "function_calling", "streaming"]) },
318
+ { id: "opencode-go/hy3-preview", providerId: "opencode-go", name: "Hunyuan 3 Preview", modelType: "llm", contextWindow: 128000, capabilities: JSON.stringify(["chat", "code", "function_calling", "streaming"]) },
319
+
320
+ // ── HiveAgents (llama.cpp local, acceso vía Cloudflare) ──
321
+ // IDs actualizados según modelos disponibles en https://llm.hiveagents.io
322
+ // contextWindow = 50000 porque así se cargan en el backend.
323
+ { id: "Qwen3.6-35B-A3B-UD-Q6_K.gguf", providerId: "hiveagents", name: "Qwen3.6 35B MoE (Recomendado)", modelType: "llm", contextWindow: 50000, capabilities: JSON.stringify(["chat", "streaming", "reasoning"]) },
324
+ { id: "Qwen3.6-35B-A3B-UD-Q4_K_M.gguf", providerId: "hiveagents", name: "Qwen3.6 35B MoE (Q4_K_M)", modelType: "llm", contextWindow: 50000, capabilities: JSON.stringify(["chat", "streaming", "reasoning"]) },
325
+ { id: "Qwen3.6-27B-UD-Q4_K_XL.gguf", providerId: "hiveagents", name: "Qwen3.6 27B + MTP", modelType: "llm", contextWindow: 50000, capabilities: JSON.stringify(["chat", "streaming", "reasoning"]) },
326
+ { id: "Qwen3-Coder-Next-UD-Q4_K_M.gguf", providerId: "hiveagents", name: "Qwen3 Coder Next", modelType: "llm", contextWindow: 50000, capabilities: JSON.stringify(["chat", "streaming", "code"]) },
327
+ { id: "Qwopus3.6-27B-v2-MTP-Q6_K.gguf", providerId: "hiveagents", name: "Qwopus3.6 27B v2 (Q6_K)", modelType: "llm", contextWindow: 50000, capabilities: JSON.stringify(["chat", "streaming", "reasoning"]) },
328
+ { id: "Qwopus3.6-27B-v2-MTP-Q4_K_S.gguf", providerId: "hiveagents", name: "Qwopus3.6 27B v2 (Q4_K_S)", modelType: "llm", contextWindow: 50000, capabilities: JSON.stringify(["chat", "streaming", "reasoning"]) },
329
+ { id: "gemma-4-31B-it-UD-Q4_K_XL.gguf", providerId: "hiveagents", name: "Gemma 4 31B Dense", modelType: "llm", contextWindow: 50000, capabilities: JSON.stringify(["chat", "streaming"]) },
330
+ { id: "gemma-4-26B-A4B-it-UD-Q4_K_M.gguf", providerId: "hiveagents", name: "Gemma 4 26B MoE", modelType: "llm", contextWindow: 50000, capabilities: JSON.stringify(["chat", "streaming"]) },
331
+ { id: "gemma-4-12b-it-UD-Q4_K_XL.gguf", providerId: "hiveagents", name: "Gemma 4 12B Dense", modelType: "llm", contextWindow: 50000, capabilities: JSON.stringify(["chat", "streaming"]) },
285
332
  ],
286
333
 
287
334
 
@@ -503,10 +550,13 @@ export function seedAllData(): void {
503
550
 
504
551
  let modelCount = 0;
505
552
  for (const model of SEED_DATA.models) {
553
+ // Local LLM models are always active so they appear in the selector
554
+ // (downloaded status is checked separately at runtime)
555
+ const isLocal = model.providerId === "local-llama";
506
556
  db.query(`
507
557
  INSERT OR REPLACE INTO models (id, provider_id, name, model_type, context_window, capabilities, enabled, active)
508
- VALUES (?, ?, ?, ?, ?, ?, 1, 0)
509
- `).run(model.id, model.providerId, model.name, model.modelType, model.contextWindow || null, model.capabilities || null)
558
+ VALUES (?, ?, ?, ?, ?, ?, 1, ?)
559
+ `).run(model.id, model.providerId, model.name, model.modelType, model.contextWindow || null, model.capabilities || null, isLocal ? 1 : 0)
510
560
  modelCount++;
511
561
  }
512
562
  db.run("PRAGMA foreign_keys = ON;");
@@ -1,5 +1,6 @@
1
1
  import { existsSync } from "node:fs"
2
2
  import { fileURLToPath } from "node:url"
3
+ import { dirname, join } from "node:path"
3
4
  import { availableParallelism } from "node:os"
4
5
  import type { Config } from "../config/loader.ts"
5
6
  import { loadConfig } from "../config/loader.ts"
@@ -110,8 +111,28 @@ function resolveWorkerEntry(): string {
110
111
  }
111
112
  }
112
113
 
114
+ const fallbacks: string[] = []
115
+ const envPath = process.env.HIVE_TOOL_WORKER_PATH
116
+ if (envPath) fallbacks.push(envPath)
117
+
118
+ try {
119
+ const execDir = dirname(process.execPath)
120
+ fallbacks.push(join(execDir, "tool-worker.js"))
121
+ fallbacks.push(join(execDir, "packages", "core", "src", "tool-runtime", "tool-worker.js"))
122
+ } catch {
123
+ // process.execPath is not available — skip execDir-based fallbacks
124
+ }
125
+
126
+ fallbacks.push("/app/tool-worker.js")
127
+
128
+ for (const filePath of fallbacks) {
129
+ if (existsSync(filePath)) {
130
+ return filePath
131
+ }
132
+ }
133
+
113
134
  throw new Error(
114
- `Tool worker entry not found. Tried: ${candidates.map((candidate) => fileURLToPath(candidate)).join(", ")}`
135
+ `Tool worker entry not found. Tried: ${[...candidates.map((candidate) => fileURLToPath(candidate)), ...fallbacks].join(", ")}`
115
136
  )
116
137
  }
117
138