@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.
- package/README.md +31 -71
- package/dist/hive.js +4318 -2898
- package/dist/tool-worker.js +2691 -1969
- package/dist/ui/assets/AgentCreateForm-b7xHyfNc.js +1 -0
- package/dist/ui/assets/AgentDetailPage-VHy3M7mI.js +1 -0
- package/dist/ui/assets/AgentNewPage-BnWImQMx.js +1 -0
- package/dist/ui/{dist/assets/AgentsPage-DGNLDXjR.js → assets/AgentsPage-WFy5abqx.js} +5 -5
- package/dist/ui/assets/ApiClientPage-BV7zLIL7.js +3 -0
- package/dist/ui/assets/{CanvasPage-CnMO1FN8.js → CanvasPage-B9zuIrTm.js} +7 -7
- package/dist/ui/assets/ChannelsPage-DiN3NvIM.js +8 -0
- package/dist/ui/{dist/assets/DashboardPage-VyXXp3U1.js → assets/DashboardPage-CHjARjVK.js} +2 -2
- package/dist/ui/assets/{LoginPage-DPj2s2Qq.js → LoginPage-Dwd_XxoU.js} +1 -1
- package/dist/ui/assets/LogsPage-DW8Nnqe6.js +1 -0
- package/dist/ui/assets/MeetingPage-D3bkiKYt.js +1 -0
- package/dist/ui/assets/{NotFound-BMeQSGcG.js → NotFound-BIUDlIXU.js} +1 -1
- package/dist/ui/assets/ProvidersPage-UqsDAxPQ.js +1 -0
- package/dist/ui/{dist/assets/RecoverPage-B-hDZUM2.js → assets/RecoverPage-8hTjr_JU.js} +1 -1
- package/dist/ui/assets/SettingsPage-DNa0jOkA.js +9 -0
- package/dist/ui/assets/SetupPage-Bdm2irQG.js +1 -0
- package/dist/ui/assets/WebChatPage-DElJg6P2.js +16 -0
- package/dist/ui/assets/accordion-CnLzKNHK.js +1 -0
- package/dist/ui/{dist/assets/alert-Bq6awLlW.js → assets/alert-DylmSCDJ.js} +1 -1
- package/dist/ui/{dist/assets/alert-dialog-DQvltYmf.js → assets/alert-dialog-DNNWN_SI.js} +1 -1
- package/dist/ui/assets/{badge-DXUDdTed.js → badge-ChENFgkC.js} +1 -1
- package/dist/ui/assets/bell-8BqRYmzf.js +1 -0
- package/dist/ui/assets/chevron-down-DIosfU_U.js +1 -0
- package/dist/ui/assets/chevron-up-CI-W21Fy.js +1 -0
- package/dist/ui/assets/circle-x-DjLkFDO8.js +1 -0
- package/dist/ui/assets/copy-Bu5d7C-0.js +1 -0
- package/dist/ui/{dist/assets/dialog-bI9jImCS.js → assets/dialog-BJ-npIv8.js} +1 -1
- package/dist/ui/{dist/assets/dropdown-menu-BK-CO3Od.js → assets/dropdown-menu-DDiaHg5y.js} +1 -1
- package/dist/ui/assets/{es-Cg8zdT52.js → es-ecSKCyB6.js} +1 -1
- package/dist/ui/assets/index-CawKP29y.js +116 -0
- package/dist/ui/assets/index-DIcsEkyd.css +2 -0
- package/dist/ui/{dist/assets/label-CrH0Jj3v.js → assets/label-Bi6udtSd.js} +1 -1
- package/dist/ui/assets/progress-D5c-Eilm.js +1 -0
- package/dist/ui/assets/scroll-area-CihOx0cb.js +1 -0
- package/dist/ui/assets/search-DzDptO9s.js +1 -0
- package/dist/ui/assets/select-BQCOjM2j.js +1 -0
- package/dist/ui/assets/send-BPk9XbIq.js +1 -0
- package/dist/ui/assets/shield-CxhcUT39.js +1 -0
- package/dist/ui/assets/{slider-CsiUDxc3.js → slider-bcUiUfx0.js} +1 -1
- package/dist/ui/assets/switch-BR30E4ej.js +1 -0
- package/dist/ui/assets/table-B3aGEaVp.js +1 -0
- package/dist/ui/assets/tabs-LQidMKRS.js +1 -0
- package/dist/ui/assets/textarea-B6Z1Zc6W.js +1 -0
- package/dist/ui/assets/useProviders-Dlizq_8q.js +1 -0
- package/dist/ui/{dist/assets/vendor-radix-cw1bQaVC.js → assets/vendor-radix-D6rA7xKY.js} +4 -4
- package/dist/ui/assets/{vendor-react-D4s9E-zj.js → vendor-react-BU5iQU4f.js} +1 -1
- package/dist/ui/dist/assets/AgentCreateForm-b7xHyfNc.js +1 -0
- package/dist/ui/dist/assets/AgentDetailPage-VHy3M7mI.js +1 -0
- package/dist/ui/dist/assets/AgentNewPage-BnWImQMx.js +1 -0
- package/dist/ui/{assets/AgentsPage-DGNLDXjR.js → dist/assets/AgentsPage-WFy5abqx.js} +5 -5
- package/dist/ui/dist/assets/ApiClientPage-BV7zLIL7.js +3 -0
- package/dist/ui/dist/assets/{CanvasPage-CnMO1FN8.js → CanvasPage-B9zuIrTm.js} +7 -7
- package/dist/ui/dist/assets/ChannelsPage-DiN3NvIM.js +8 -0
- package/dist/ui/{assets/DashboardPage-VyXXp3U1.js → dist/assets/DashboardPage-CHjARjVK.js} +2 -2
- package/dist/ui/dist/assets/{LoginPage-DPj2s2Qq.js → LoginPage-Dwd_XxoU.js} +1 -1
- package/dist/ui/dist/assets/LogsPage-DW8Nnqe6.js +1 -0
- package/dist/ui/dist/assets/MeetingPage-D3bkiKYt.js +1 -0
- package/dist/ui/dist/assets/{NotFound-BMeQSGcG.js → NotFound-BIUDlIXU.js} +1 -1
- package/dist/ui/dist/assets/ProvidersPage-UqsDAxPQ.js +1 -0
- package/dist/ui/{assets/RecoverPage-B-hDZUM2.js → dist/assets/RecoverPage-8hTjr_JU.js} +1 -1
- package/dist/ui/dist/assets/SettingsPage-DNa0jOkA.js +9 -0
- package/dist/ui/dist/assets/SetupPage-Bdm2irQG.js +1 -0
- package/dist/ui/dist/assets/WebChatPage-DElJg6P2.js +16 -0
- package/dist/ui/dist/assets/accordion-CnLzKNHK.js +1 -0
- package/dist/ui/{assets/alert-Bq6awLlW.js → dist/assets/alert-DylmSCDJ.js} +1 -1
- package/dist/ui/{assets/alert-dialog-DQvltYmf.js → dist/assets/alert-dialog-DNNWN_SI.js} +1 -1
- package/dist/ui/dist/assets/{badge-DXUDdTed.js → badge-ChENFgkC.js} +1 -1
- package/dist/ui/dist/assets/bell-8BqRYmzf.js +1 -0
- package/dist/ui/dist/assets/chevron-down-DIosfU_U.js +1 -0
- package/dist/ui/dist/assets/chevron-up-CI-W21Fy.js +1 -0
- package/dist/ui/dist/assets/circle-x-DjLkFDO8.js +1 -0
- package/dist/ui/dist/assets/copy-Bu5d7C-0.js +1 -0
- package/dist/ui/{assets/dialog-bI9jImCS.js → dist/assets/dialog-BJ-npIv8.js} +1 -1
- package/dist/ui/{assets/dropdown-menu-BK-CO3Od.js → dist/assets/dropdown-menu-DDiaHg5y.js} +1 -1
- package/dist/ui/dist/assets/{es-Cg8zdT52.js → es-ecSKCyB6.js} +1 -1
- package/dist/ui/dist/assets/index-CawKP29y.js +116 -0
- package/dist/ui/dist/assets/index-DIcsEkyd.css +2 -0
- package/dist/ui/{assets/label-CrH0Jj3v.js → dist/assets/label-Bi6udtSd.js} +1 -1
- package/dist/ui/dist/assets/progress-D5c-Eilm.js +1 -0
- package/dist/ui/dist/assets/scroll-area-CihOx0cb.js +1 -0
- package/dist/ui/dist/assets/search-DzDptO9s.js +1 -0
- package/dist/ui/dist/assets/select-BQCOjM2j.js +1 -0
- package/dist/ui/dist/assets/send-BPk9XbIq.js +1 -0
- package/dist/ui/dist/assets/shield-CxhcUT39.js +1 -0
- package/dist/ui/dist/assets/{slider-CsiUDxc3.js → slider-bcUiUfx0.js} +1 -1
- package/dist/ui/dist/assets/switch-BR30E4ej.js +1 -0
- package/dist/ui/dist/assets/table-B3aGEaVp.js +1 -0
- package/dist/ui/dist/assets/tabs-LQidMKRS.js +1 -0
- package/dist/ui/dist/assets/textarea-B6Z1Zc6W.js +1 -0
- package/dist/ui/dist/assets/useProviders-Dlizq_8q.js +1 -0
- package/dist/ui/{assets/vendor-radix-cw1bQaVC.js → dist/assets/vendor-radix-D6rA7xKY.js} +4 -4
- package/dist/ui/dist/assets/{vendor-react-D4s9E-zj.js → vendor-react-BU5iQU4f.js} +1 -1
- package/dist/ui/dist/index.html +6 -6
- package/dist/ui/index.html +6 -6
- package/package.json +1 -1
- package/packages/cli/src/adapters/binary.ts +8 -4
- package/packages/cli/src/adapters/bun-global.ts +5 -1
- package/packages/cli/src/adapters/config.ts +4 -3
- package/packages/cli/src/adapters/docker.ts +2 -1
- package/packages/cli/src/commands/gateway.ts +123 -9
- package/packages/cli/src/commands/logs.ts +2 -1
- package/packages/cli/src/commands/onboard.ts +27 -1
- package/packages/cli/src/commands/sessions.ts +2 -1
- package/packages/cli/src/commands/skills.ts +2 -1
- package/packages/core/src/agent/agent-loop.ts +104 -2
- package/packages/core/src/agent/context-compiler.ts +6 -0
- package/packages/core/src/agent/llm-client.ts +6 -0
- package/packages/core/src/agent/llm-providers/anthropic.ts +23 -8
- package/packages/core/src/agent/llm-providers/hiveagents.ts +248 -0
- package/packages/core/src/agent/llm-providers/interface.ts +7 -1
- package/packages/core/src/agent/llm-providers/minimax.ts +13 -0
- package/packages/core/src/agent/llm-providers/openai-compat-base.ts +49 -25
- package/packages/core/src/agent/llm-providers/opencode-go.ts +9 -0
- package/packages/core/src/agent/providers/index.ts +3 -2
- package/packages/core/src/agent/stuck-loop.ts +90 -14
- package/packages/core/src/channels/base.ts +7 -1
- package/packages/core/src/channels/whatsapp.ts +13 -1
- package/packages/core/src/config/loader.ts +8 -8
- package/packages/core/src/gateway/helpers/path.ts +2 -1
- package/packages/core/src/gateway/initializer.ts +4 -4
- package/packages/core/src/gateway/llm-local/downloader.ts +130 -11
- package/packages/core/src/gateway/llm-local/index.ts +2 -0
- package/packages/core/src/gateway/llm-local/models.ts +4 -3
- package/packages/core/src/gateway/router.ts +7 -5
- package/packages/core/src/gateway/routes/http-client.ts +16 -0
- package/packages/core/src/gateway/routes/llm-local.ts +51 -5
- package/packages/core/src/gateway/routes/providers.ts +99 -2
- package/packages/core/src/gateway/server.ts +131 -57
- package/packages/core/src/gateway/slash-commands.ts +7 -1
- package/packages/core/src/gateway/tts/src/install.ts +17 -9
- package/packages/core/src/storage/crypto.ts +152 -20
- package/packages/core/src/storage/migrate.ts +51 -18
- package/packages/core/src/storage/onboarding.ts +28 -0
- package/packages/core/src/storage/seed.ts +52 -2
- package/packages/core/src/tool-runtime/index.ts +22 -1
- package/packages/core/src/tools/api/api-request.ts +174 -0
- package/packages/core/src/tools/api/index.ts +16 -0
- package/packages/core/src/tools/index.ts +12 -0
- package/packages/core/src/tools/web/browser-click.ts +2 -2
- package/packages/core/src/tools/web/browser-extract.ts +22 -6
- package/packages/core/src/tools/web/browser-navigate.ts +34 -18
- package/packages/core/src/tools/web/browser-screenshot.ts +40 -8
- package/packages/core/src/tools/web/browser-script.ts +2 -2
- package/packages/core/src/tools/web/browser-service.ts +295 -341
- package/packages/core/src/tools/web/browser-type.ts +5 -10
- package/packages/core/src/tools/web/browser-wait.ts +2 -2
- package/packages/core/src/tools/web/index.ts +1 -1
- package/packages/core/src/utils/logger.ts +2 -1
- package/packages/mcp/src/manager.ts +2 -1
- package/packages/skills/src/bundled/api/api_client/SKILL.md +132 -0
- package/packages/skills/src/bundled-data.generated.ts +1191 -1134
- package/packages/skills/src/loader.ts +2 -1
- package/dist/ui/assets/AgentCreateForm-0oFbN3gj.js +0 -1
- package/dist/ui/assets/AgentDetailPage-BJ4L2fNJ.js +0 -1
- package/dist/ui/assets/AgentNewPage-B3n0LUck.js +0 -1
- package/dist/ui/assets/ChannelsPage-fbF8K4MR.js +0 -8
- package/dist/ui/assets/LogsPage-B2lY9maY.js +0 -1
- package/dist/ui/assets/MeetingPage-2ky_hKiG.js +0 -1
- package/dist/ui/assets/ProvidersPage-CEyUM2tD.js +0 -1
- package/dist/ui/assets/SettingsPage-eO0i3g8p.js +0 -9
- package/dist/ui/assets/SetupPage-ByYqTELb.js +0 -1
- package/dist/ui/assets/WebChatPage-BuGT2AL0.js +0 -16
- package/dist/ui/assets/accordion-C5d5Rm5z.js +0 -1
- package/dist/ui/assets/chevron-up-BYhk0K2J.js +0 -1
- package/dist/ui/assets/globe-DeCQTCDJ.js +0 -1
- package/dist/ui/assets/index-B2fCYtTS.css +0 -2
- package/dist/ui/assets/index-CQ7fn00w.js +0 -116
- package/dist/ui/assets/progress-BherYzY6.js +0 -1
- package/dist/ui/assets/scroll-area-DkeyX32e.js +0 -1
- package/dist/ui/assets/send-B0H5SEIE.js +0 -1
- package/dist/ui/assets/switch-BDwN8RYV.js +0 -1
- package/dist/ui/assets/table-CSc8ubon.js +0 -1
- package/dist/ui/assets/textarea-CXgXWKrT.js +0 -1
- package/dist/ui/assets/useProviders-CnlC_qCS.js +0 -1
- package/dist/ui/dist/assets/AgentCreateForm-0oFbN3gj.js +0 -1
- package/dist/ui/dist/assets/AgentDetailPage-BJ4L2fNJ.js +0 -1
- package/dist/ui/dist/assets/AgentNewPage-B3n0LUck.js +0 -1
- package/dist/ui/dist/assets/ChannelsPage-fbF8K4MR.js +0 -8
- package/dist/ui/dist/assets/LogsPage-B2lY9maY.js +0 -1
- package/dist/ui/dist/assets/MeetingPage-2ky_hKiG.js +0 -1
- package/dist/ui/dist/assets/ProvidersPage-CEyUM2tD.js +0 -1
- package/dist/ui/dist/assets/SettingsPage-eO0i3g8p.js +0 -9
- package/dist/ui/dist/assets/SetupPage-ByYqTELb.js +0 -1
- package/dist/ui/dist/assets/WebChatPage-BuGT2AL0.js +0 -16
- package/dist/ui/dist/assets/accordion-C5d5Rm5z.js +0 -1
- package/dist/ui/dist/assets/chevron-up-BYhk0K2J.js +0 -1
- package/dist/ui/dist/assets/globe-DeCQTCDJ.js +0 -1
- package/dist/ui/dist/assets/index-B2fCYtTS.css +0 -2
- package/dist/ui/dist/assets/index-CQ7fn00w.js +0 -116
- package/dist/ui/dist/assets/progress-BherYzY6.js +0 -1
- package/dist/ui/dist/assets/scroll-area-DkeyX32e.js +0 -1
- package/dist/ui/dist/assets/send-B0H5SEIE.js +0 -1
- package/dist/ui/dist/assets/switch-BDwN8RYV.js +0 -1
- package/dist/ui/dist/assets/table-CSc8ubon.js +0 -1
- package/dist/ui/dist/assets/textarea-CXgXWKrT.js +0 -1
- package/dist/ui/dist/assets/useProviders-CnlC_qCS.js +0 -1
- /package/dist/ui/assets/{card-CNf6BS2e.js → card-DFKnZ6ky.js} +0 -0
- /package/dist/ui/assets/{circle-alert-CyHDwUj8.js → circle-alert-KuAm2FWh.js} +0 -0
- /package/dist/ui/assets/{circle-check-Bb54Ebmu.js → circle-check-6Ard1-2z.js} +0 -0
- /package/dist/ui/assets/{cpu-Cdgc_B1K.js → cpu-KDy6-FAI.js} +0 -0
- /package/dist/ui/assets/{download-C3ifGMjJ.js → download-Cjbk4Rek.js} +0 -0
- /package/dist/ui/assets/{external-link-BvxYeTP1.js → external-link-6sTlRDUR.js} +0 -0
- /package/dist/ui/assets/{eye-DqNTU_GD.js → eye-Df8o0tkC.js} +0 -0
- /package/dist/ui/assets/{file-text-BT_9S9SM.js → file-text-lnxnjBp0.js} +0 -0
- /package/dist/ui/assets/{folder-open-BhH8y9ac.js → folder-open-DJBLDFjv.js} +0 -0
- /package/dist/ui/assets/{format-GVHeOyWI.js → format-BwdV8bB5.js} +0 -0
- /package/dist/ui/assets/{gateway-url-COCbW0IR.js → gateway-url-DwzPmoc8.js} +0 -0
- /package/dist/ui/assets/{gauge-D_TMa4i9.js → gauge-B8Tj43rC.js} +0 -0
- /package/dist/ui/assets/{hexagon-DsGOUl-H.js → hexagon-6L79pgVK.js} +0 -0
- /package/dist/ui/assets/{history-BSG-Ypqf.js → history-CAF_R34_.js} +0 -0
- /package/dist/ui/assets/{info-NwLoa2Mj.js → info-WjromB4Y.js} +0 -0
- /package/dist/ui/assets/{key-3EP0dhkT.js → key-DyKOoQh5.js} +0 -0
- /package/dist/ui/assets/{loader-circle-CZNax6kS.js → loader-circle-BmBOgYze.js} +0 -0
- /package/dist/ui/assets/{lock-Ei1_J-Nq.js → lock-BS6OLXPv.js} +0 -0
- /package/dist/ui/assets/{pause-BUqah9Bi.js → pause-VqeUmp2Z.js} +0 -0
- /package/dist/ui/assets/{play-NcZ4swwL.js → play-zJpWuhrr.js} +0 -0
- /package/dist/ui/assets/{plus-CX1xyhp5.js → plus-BZQX26Dr.js} +0 -0
- /package/dist/ui/assets/{refresh-cw-DaYdjQFk.js → refresh-cw-CCzDCAuz.js} +0 -0
- /package/dist/ui/assets/{save-CUdYyHNy.js → save-hUmZhceG.js} +0 -0
- /package/dist/ui/assets/{settings-Ds4SqD8s.js → settings-BGfrZ_zM.js} +0 -0
- /package/dist/ui/assets/{sparkles-yUEb-7oH.js → sparkles-BhwlS1pc.js} +0 -0
- /package/dist/ui/assets/{square-BD81nFtN.js → square-DMNWw4Hi.js} +0 -0
- /package/dist/ui/assets/{terminal-DN38Q456.js → terminal--7G943As.js} +0 -0
- /package/dist/ui/assets/{trash-2-CNjMkoq6.js → trash-2-xD2o4SgX.js} +0 -0
- /package/dist/ui/assets/{triangle-alert-C9Y8Ub4X.js → triangle-alert-pVIJGjga.js} +0 -0
- /package/dist/ui/assets/{vendor-router-C9pIYwbJ.js → vendor-router-gqiZ7xhx.js} +0 -0
- /package/dist/ui/assets/{volume-2-CeSXNDv4.js → volume-2-BekVQl6P.js} +0 -0
- /package/dist/ui/assets/{zap-hlXjpSeA.js → zap-B4RaNNO5.js} +0 -0
- /package/dist/ui/dist/assets/{card-CNf6BS2e.js → card-DFKnZ6ky.js} +0 -0
- /package/dist/ui/dist/assets/{circle-alert-CyHDwUj8.js → circle-alert-KuAm2FWh.js} +0 -0
- /package/dist/ui/dist/assets/{circle-check-Bb54Ebmu.js → circle-check-6Ard1-2z.js} +0 -0
- /package/dist/ui/dist/assets/{cpu-Cdgc_B1K.js → cpu-KDy6-FAI.js} +0 -0
- /package/dist/ui/dist/assets/{download-C3ifGMjJ.js → download-Cjbk4Rek.js} +0 -0
- /package/dist/ui/dist/assets/{external-link-BvxYeTP1.js → external-link-6sTlRDUR.js} +0 -0
- /package/dist/ui/dist/assets/{eye-DqNTU_GD.js → eye-Df8o0tkC.js} +0 -0
- /package/dist/ui/dist/assets/{file-text-BT_9S9SM.js → file-text-lnxnjBp0.js} +0 -0
- /package/dist/ui/dist/assets/{folder-open-BhH8y9ac.js → folder-open-DJBLDFjv.js} +0 -0
- /package/dist/ui/dist/assets/{format-GVHeOyWI.js → format-BwdV8bB5.js} +0 -0
- /package/dist/ui/dist/assets/{gateway-url-COCbW0IR.js → gateway-url-DwzPmoc8.js} +0 -0
- /package/dist/ui/dist/assets/{gauge-D_TMa4i9.js → gauge-B8Tj43rC.js} +0 -0
- /package/dist/ui/dist/assets/{hexagon-DsGOUl-H.js → hexagon-6L79pgVK.js} +0 -0
- /package/dist/ui/dist/assets/{history-BSG-Ypqf.js → history-CAF_R34_.js} +0 -0
- /package/dist/ui/dist/assets/{info-NwLoa2Mj.js → info-WjromB4Y.js} +0 -0
- /package/dist/ui/dist/assets/{key-3EP0dhkT.js → key-DyKOoQh5.js} +0 -0
- /package/dist/ui/dist/assets/{loader-circle-CZNax6kS.js → loader-circle-BmBOgYze.js} +0 -0
- /package/dist/ui/dist/assets/{lock-Ei1_J-Nq.js → lock-BS6OLXPv.js} +0 -0
- /package/dist/ui/dist/assets/{pause-BUqah9Bi.js → pause-VqeUmp2Z.js} +0 -0
- /package/dist/ui/dist/assets/{play-NcZ4swwL.js → play-zJpWuhrr.js} +0 -0
- /package/dist/ui/dist/assets/{plus-CX1xyhp5.js → plus-BZQX26Dr.js} +0 -0
- /package/dist/ui/dist/assets/{refresh-cw-DaYdjQFk.js → refresh-cw-CCzDCAuz.js} +0 -0
- /package/dist/ui/dist/assets/{save-CUdYyHNy.js → save-hUmZhceG.js} +0 -0
- /package/dist/ui/dist/assets/{settings-Ds4SqD8s.js → settings-BGfrZ_zM.js} +0 -0
- /package/dist/ui/dist/assets/{sparkles-yUEb-7oH.js → sparkles-BhwlS1pc.js} +0 -0
- /package/dist/ui/dist/assets/{square-BD81nFtN.js → square-DMNWw4Hi.js} +0 -0
- /package/dist/ui/dist/assets/{terminal-DN38Q456.js → terminal--7G943As.js} +0 -0
- /package/dist/ui/dist/assets/{trash-2-CNjMkoq6.js → trash-2-xD2o4SgX.js} +0 -0
- /package/dist/ui/dist/assets/{triangle-alert-C9Y8Ub4X.js → triangle-alert-pVIJGjga.js} +0 -0
- /package/dist/ui/dist/assets/{vendor-router-C9pIYwbJ.js → vendor-router-gqiZ7xhx.js} +0 -0
- /package/dist/ui/dist/assets/{volume-2-CeSXNDv4.js → volume-2-BekVQl6P.js} +0 -0
- /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)
|
|
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 ??
|
|
22
|
+
return val ?? _mem.get(name) ?? _readDbSecret(name)
|
|
20
23
|
} catch {
|
|
21
24
|
_keychainOk = false
|
|
22
|
-
return _mem.get(name) ??
|
|
25
|
+
return _mem.get(name) ?? _readDbSecret(name)
|
|
23
26
|
}
|
|
24
27
|
}
|
|
25
28
|
|
|
26
|
-
async function _set(name: string, value: string): Promise<
|
|
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
|
-
|
|
68
|
-
|
|
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<
|
|
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<
|
|
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<
|
|
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<
|
|
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<
|
|
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, "
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
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
|
|