@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
|
@@ -18,22 +18,116 @@ export const MODELS_DIR = join(LLM_ROOT, "models")
|
|
|
18
18
|
if (!existsSync(BIN_DIR)) mkdirSync(BIN_DIR, { recursive: true })
|
|
19
19
|
if (!existsSync(MODELS_DIR)) mkdirSync(MODELS_DIR, { recursive: true })
|
|
20
20
|
|
|
21
|
-
/** URLs de modelos en HuggingFace (Gemma 4 según
|
|
21
|
+
/** URLs de modelos en HuggingFace (Gemma 4 y Qwen 3.5 según Unsloth) */
|
|
22
22
|
export const HF_MODEL_URLS = {
|
|
23
|
+
// mmproj legacy (E4B)
|
|
23
24
|
mmproj: "https://huggingface.co/unsloth/gemma-4-E4B-it-GGUF/resolve/main/mmproj-BF16.gguf",
|
|
25
|
+
// mmproj Gemma 4
|
|
26
|
+
mmproj_gemma4_12b: "https://huggingface.co/unsloth/gemma-4-12b-it-GGUF/resolve/main/mmproj-BF16.gguf",
|
|
27
|
+
mmproj_gemma4_26b: "https://huggingface.co/unsloth/gemma-4-26B-A4B-it-GGUF/resolve/main/mmproj-BF16.gguf",
|
|
28
|
+
mmproj_gemma4_31b: "https://huggingface.co/unsloth/gemma-4-31B-it-GGUF/resolve/main/mmproj-BF16.gguf",
|
|
29
|
+
// mmproj Qwen 3.5
|
|
30
|
+
mmproj_qwen3_5_2b: "https://huggingface.co/unsloth/Qwen3.5-2B-GGUF/resolve/main/mmproj-F16.gguf",
|
|
31
|
+
mmproj_qwen3_5_4b: "https://huggingface.co/unsloth/Qwen3.5-4B-GGUF/resolve/main/mmproj-F16.gguf",
|
|
32
|
+
mmproj_qwen3_5_9b: "https://huggingface.co/unsloth/Qwen3.5-9B-GGUF/resolve/main/mmproj-F16.gguf",
|
|
33
|
+
mmproj_qwen3_5_27b: "https://huggingface.co/unsloth/Qwen3.5-27B-GGUF/resolve/main/mmproj-F16.gguf",
|
|
34
|
+
mmproj_qwen3_5_35b: "https://huggingface.co/unsloth/Qwen3.5-35B-A3B-GGUF/resolve/main/mmproj-F16.gguf",
|
|
35
|
+
// modelos Gemma 4
|
|
24
36
|
e2b_Q4_K_XL: "https://huggingface.co/unsloth/gemma-4-E2B-it-GGUF/resolve/main/gemma-4-E2B-it-UD-Q4_K_XL.gguf",
|
|
25
|
-
e4b_Q4_K_XL: "https://huggingface.co/unsloth/gemma-4-E4B-it-GGUF/resolve/main/gemma-4-E4B-it-UD-Q4_K_XL.gguf"
|
|
37
|
+
e4b_Q4_K_XL: "https://huggingface.co/unsloth/gemma-4-E4B-it-GGUF/resolve/main/gemma-4-E4B-it-UD-Q4_K_XL.gguf",
|
|
38
|
+
gemma4_12b_Q4_K_XL: "https://huggingface.co/unsloth/gemma-4-12b-it-GGUF/resolve/main/gemma-4-12b-it-UD-Q4_K_XL.gguf",
|
|
39
|
+
gemma4_26b_Q4_K_M: "https://huggingface.co/unsloth/gemma-4-26B-A4B-it-GGUF/resolve/main/gemma-4-26B-A4B-it-UD-Q4_K_M.gguf",
|
|
40
|
+
gemma4_31b_Q4_K_XL: "https://huggingface.co/unsloth/gemma-4-31B-it-GGUF/resolve/main/gemma-4-31B-it-UD-Q4_K_XL.gguf",
|
|
41
|
+
// modelos Qwen 3.5
|
|
42
|
+
qwen3_5_2b_Q4_K_XL: "https://huggingface.co/unsloth/Qwen3.5-2B-GGUF/resolve/main/Qwen3.5-2B-UD-Q4_K_XL.gguf",
|
|
43
|
+
qwen3_5_4b_Q4_K_XL: "https://huggingface.co/unsloth/Qwen3.5-4B-GGUF/resolve/main/Qwen3.5-4B-UD-Q4_K_XL.gguf",
|
|
44
|
+
qwen3_5_9b_Q4_K_XL: "https://huggingface.co/unsloth/Qwen3.5-9B-GGUF/resolve/main/Qwen3.5-9B-UD-Q4_K_XL.gguf",
|
|
45
|
+
qwen3_5_27b_Q4_K_XL: "https://huggingface.co/unsloth/Qwen3.5-27B-GGUF/resolve/main/Qwen3.5-27B-UD-Q4_K_XL.gguf",
|
|
46
|
+
qwen3_5_35b_Q4_K_XL: "https://huggingface.co/unsloth/Qwen3.5-35B-A3B-GGUF/resolve/main/Qwen3.5-35B-A3B-UD-Q4_K_XL.gguf",
|
|
26
47
|
}
|
|
27
48
|
|
|
28
|
-
export type ModelId =
|
|
49
|
+
export type ModelId =
|
|
50
|
+
| "mmproj"
|
|
51
|
+
| "mmproj_gemma4_12b"
|
|
52
|
+
| "mmproj_gemma4_26b"
|
|
53
|
+
| "mmproj_gemma4_31b"
|
|
54
|
+
| "mmproj_qwen3_5_2b"
|
|
55
|
+
| "mmproj_qwen3_5_4b"
|
|
56
|
+
| "mmproj_qwen3_5_9b"
|
|
57
|
+
| "mmproj_qwen3_5_27b"
|
|
58
|
+
| "mmproj_qwen3_5_35b"
|
|
59
|
+
| "e2b_Q4_K_XL"
|
|
60
|
+
| "e4b_Q4_K_XL"
|
|
61
|
+
| "gemma4_12b_Q4_K_XL"
|
|
62
|
+
| "gemma4_26b_Q4_K_M"
|
|
63
|
+
| "gemma4_31b_Q4_K_XL"
|
|
64
|
+
| "qwen3_5_2b_Q4_K_XL"
|
|
65
|
+
| "qwen3_5_4b_Q4_K_XL"
|
|
66
|
+
| "qwen3_5_9b_Q4_K_XL"
|
|
67
|
+
| "qwen3_5_27b_Q4_K_XL"
|
|
68
|
+
| "qwen3_5_35b_Q4_K_XL"
|
|
29
69
|
|
|
30
70
|
/** Modelos que requieren proyector de visión (mmproj) */
|
|
31
|
-
export const VISION_MODELS: ModelId[] = [
|
|
71
|
+
export const VISION_MODELS: ModelId[] = [
|
|
72
|
+
"e4b_Q4_K_XL",
|
|
73
|
+
"gemma4_12b_Q4_K_XL",
|
|
74
|
+
"gemma4_26b_Q4_K_M",
|
|
75
|
+
"gemma4_31b_Q4_K_XL",
|
|
76
|
+
"qwen3_5_2b_Q4_K_XL",
|
|
77
|
+
"qwen3_5_4b_Q4_K_XL",
|
|
78
|
+
"qwen3_5_9b_Q4_K_XL",
|
|
79
|
+
"qwen3_5_27b_Q4_K_XL",
|
|
80
|
+
"qwen3_5_35b_Q4_K_XL",
|
|
81
|
+
]
|
|
82
|
+
|
|
83
|
+
/** Mapeo de cada modelo a su mmproj correspondiente */
|
|
84
|
+
export const MODEL_MMPROJ_MAP: Record<ModelId, ModelId | undefined> = {
|
|
85
|
+
mmproj: undefined,
|
|
86
|
+
mmproj_gemma4_12b: undefined,
|
|
87
|
+
mmproj_gemma4_26b: undefined,
|
|
88
|
+
mmproj_gemma4_31b: undefined,
|
|
89
|
+
mmproj_qwen3_5_2b: undefined,
|
|
90
|
+
mmproj_qwen3_5_4b: undefined,
|
|
91
|
+
mmproj_qwen3_5_9b: undefined,
|
|
92
|
+
mmproj_qwen3_5_27b: undefined,
|
|
93
|
+
mmproj_qwen3_5_35b: undefined,
|
|
94
|
+
e2b_Q4_K_XL: undefined,
|
|
95
|
+
e4b_Q4_K_XL: "mmproj",
|
|
96
|
+
gemma4_12b_Q4_K_XL: "mmproj_gemma4_12b",
|
|
97
|
+
gemma4_26b_Q4_K_M: "mmproj_gemma4_26b",
|
|
98
|
+
gemma4_31b_Q4_K_XL: "mmproj_gemma4_31b",
|
|
99
|
+
qwen3_5_2b_Q4_K_XL: "mmproj_qwen3_5_2b",
|
|
100
|
+
qwen3_5_4b_Q4_K_XL: "mmproj_qwen3_5_4b",
|
|
101
|
+
qwen3_5_9b_Q4_K_XL: "mmproj_qwen3_5_9b",
|
|
102
|
+
qwen3_5_27b_Q4_K_XL: "mmproj_qwen3_5_27b",
|
|
103
|
+
qwen3_5_35b_Q4_K_XL: "mmproj_qwen3_5_35b",
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** Devuelve el ID del mmproj asociado a un modelo, o undefined si no requiere visión */
|
|
107
|
+
export function getModelMMProjId(modelId: ModelId): ModelId | undefined {
|
|
108
|
+
return MODEL_MMPROJ_MAP[modelId]
|
|
109
|
+
}
|
|
32
110
|
|
|
33
111
|
export const MODEL_FILES: Record<ModelId, string> = {
|
|
34
112
|
mmproj: "mmproj-BF16.gguf",
|
|
113
|
+
mmproj_gemma4_12b: "mmproj-gemma4-12b-BF16.gguf",
|
|
114
|
+
mmproj_gemma4_26b: "mmproj-gemma4-26b-BF16.gguf",
|
|
115
|
+
mmproj_gemma4_31b: "mmproj-gemma4-31b-BF16.gguf",
|
|
116
|
+
mmproj_qwen3_5_2b: "mmproj-qwen3.5-2b-F16.gguf",
|
|
117
|
+
mmproj_qwen3_5_4b: "mmproj-qwen3.5-4b-F16.gguf",
|
|
118
|
+
mmproj_qwen3_5_9b: "mmproj-qwen3.5-9b-F16.gguf",
|
|
119
|
+
mmproj_qwen3_5_27b: "mmproj-qwen3.5-27b-F16.gguf",
|
|
120
|
+
mmproj_qwen3_5_35b: "mmproj-qwen3.5-35b-F16.gguf",
|
|
35
121
|
e2b_Q4_K_XL: "gemma-4-E2B-it-UD-Q4_K_XL.gguf",
|
|
36
122
|
e4b_Q4_K_XL: "gemma-4-E4B-it-UD-Q4_K_XL.gguf",
|
|
123
|
+
gemma4_12b_Q4_K_XL: "gemma-4-12b-it-UD-Q4_K_XL.gguf",
|
|
124
|
+
gemma4_26b_Q4_K_M: "gemma-4-26B-A4B-it-UD-Q4_K_M.gguf",
|
|
125
|
+
gemma4_31b_Q4_K_XL: "gemma-4-31B-it-UD-Q4_K_XL.gguf",
|
|
126
|
+
qwen3_5_2b_Q4_K_XL: "Qwen3.5-2B-UD-Q4_K_XL.gguf",
|
|
127
|
+
qwen3_5_4b_Q4_K_XL: "Qwen3.5-4B-UD-Q4_K_XL.gguf",
|
|
128
|
+
qwen3_5_9b_Q4_K_XL: "Qwen3.5-9B-UD-Q4_K_XL.gguf",
|
|
129
|
+
qwen3_5_27b_Q4_K_XL: "Qwen3.5-27B-UD-Q4_K_XL.gguf",
|
|
130
|
+
qwen3_5_35b_Q4_K_XL: "Qwen3.5-35B-A3B-UD-Q4_K_XL.gguf",
|
|
37
131
|
}
|
|
38
132
|
|
|
39
133
|
export function getModelPath(modelId: ModelId): string {
|
|
@@ -65,13 +159,14 @@ export async function downloadFile(
|
|
|
65
159
|
const { done, value } = await reader.read()
|
|
66
160
|
if (done) break
|
|
67
161
|
|
|
68
|
-
writer.write(value)
|
|
162
|
+
await writer.write(value)
|
|
69
163
|
downloaded += value.byteLength
|
|
70
164
|
if (onProgress) onProgress(downloaded, total)
|
|
71
165
|
}
|
|
166
|
+
await writer.flush()
|
|
72
167
|
await writer.end()
|
|
73
168
|
} catch (err) {
|
|
74
|
-
await writer.end()
|
|
169
|
+
try { await writer.end() } catch { /* ignore */ }
|
|
75
170
|
throw err
|
|
76
171
|
}
|
|
77
172
|
}
|
|
@@ -191,9 +286,10 @@ export async function downloadModel(
|
|
|
191
286
|
await downloadFile(url, dest, onProgress)
|
|
192
287
|
console.log(`[hive-local] ✓ Modelo ${modelId} descargado`)
|
|
193
288
|
|
|
194
|
-
// Advertir si el modelo requiere visión y no tenemos mmproj (NO descargar automáticamente)
|
|
195
|
-
|
|
196
|
-
|
|
289
|
+
// Advertir si el modelo requiere visión y no tenemos su mmproj (NO descargar automáticamente)
|
|
290
|
+
const mmprojId = getModelMMProjId(modelId)
|
|
291
|
+
if (mmprojId && !isModelDownloaded(mmprojId)) {
|
|
292
|
+
console.warn(`[hive-local] ⚠️ El modelo ${modelId} requiere el proyector de visión (${mmprojId}). Descárgalo manualmente desde la UI.`)
|
|
197
293
|
}
|
|
198
294
|
|
|
199
295
|
return dest
|
|
@@ -206,11 +302,34 @@ export async function installMMProj(): Promise<string> {
|
|
|
206
302
|
|
|
207
303
|
/** Lista modelos disponibles localmente (solo modelos de texto/visión finales) */
|
|
208
304
|
export function listLocalModels(): { id: ModelId; name: string; size: string; downloaded: boolean }[] {
|
|
209
|
-
const models: ModelId[] = [
|
|
305
|
+
const models: ModelId[] = [
|
|
306
|
+
"e2b_Q4_K_XL",
|
|
307
|
+
"e4b_Q4_K_XL",
|
|
308
|
+
"gemma4_12b_Q4_K_XL",
|
|
309
|
+
"gemma4_26b_Q4_K_M",
|
|
310
|
+
"gemma4_31b_Q4_K_XL",
|
|
311
|
+
"qwen3_5_2b_Q4_K_XL",
|
|
312
|
+
"qwen3_5_4b_Q4_K_XL",
|
|
313
|
+
"qwen3_5_9b_Q4_K_XL",
|
|
314
|
+
"qwen3_5_27b_Q4_K_XL",
|
|
315
|
+
"qwen3_5_35b_Q4_K_XL",
|
|
316
|
+
]
|
|
317
|
+
const sizeMap: Record<string, string> = {
|
|
318
|
+
e2b_Q4_K_XL: "~3 GB",
|
|
319
|
+
e4b_Q4_K_XL: "~5 GB",
|
|
320
|
+
gemma4_12b_Q4_K_XL: "~7 GB",
|
|
321
|
+
gemma4_26b_Q4_K_M: "~10 GB",
|
|
322
|
+
gemma4_31b_Q4_K_XL: "~14 GB",
|
|
323
|
+
qwen3_5_2b_Q4_K_XL: "~1.2 GB",
|
|
324
|
+
qwen3_5_4b_Q4_K_XL: "~2.5 GB",
|
|
325
|
+
qwen3_5_9b_Q4_K_XL: "~5.4 GB",
|
|
326
|
+
qwen3_5_27b_Q4_K_XL: "~16 GB",
|
|
327
|
+
qwen3_5_35b_Q4_K_XL: "~21 GB",
|
|
328
|
+
}
|
|
210
329
|
return models.map((id) => ({
|
|
211
330
|
id,
|
|
212
331
|
name: MODEL_FILES[id],
|
|
213
|
-
size: id
|
|
332
|
+
size: sizeMap[id] || "~?",
|
|
214
333
|
downloaded: isModelDownloaded(id),
|
|
215
334
|
}))
|
|
216
335
|
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
import { existsSync } from "fs"
|
|
8
|
-
import { MODELS_DIR, getModelPath, type ModelId } from "./downloader"
|
|
8
|
+
import { MODELS_DIR, getModelPath, getModelMMProjId, type ModelId } from "./downloader"
|
|
9
9
|
|
|
10
10
|
export interface ModelConfig {
|
|
11
11
|
modelPath: string
|
|
@@ -43,8 +43,9 @@ export function getModelConfig(modelId: ModelId, port: number = 8081): ModelConf
|
|
|
43
43
|
throw new Error(`Modelo no descargado: ${modelId}. Ejecuta downloadModel("${modelId}") primero.`)
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
const
|
|
47
|
-
const
|
|
46
|
+
const mmprojId = getModelMMProjId(modelId)
|
|
47
|
+
const mmprojPath = mmprojId ? getModelPath(mmprojId) : undefined
|
|
48
|
+
const hasMMProj = mmprojPath ? existsSync(mmprojPath) : false
|
|
48
49
|
|
|
49
50
|
return {
|
|
50
51
|
modelPath,
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { Config, Binding } from "../config/loader.ts";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import * as path from "node:path";
|
|
2
4
|
|
|
3
5
|
export interface RoutingContext {
|
|
4
6
|
channel: string;
|
|
@@ -113,12 +115,12 @@ export class Router {
|
|
|
113
115
|
const agent = agents.find((a) => a.id === agentId);
|
|
114
116
|
|
|
115
117
|
if (agent?.workspace) {
|
|
116
|
-
return agent.workspace.replace(/^~/,
|
|
118
|
+
return agent.workspace.replace(/^~/, homedir());
|
|
117
119
|
}
|
|
118
120
|
|
|
119
|
-
const baseDir = this.config.agent?.baseDir?.replace(/^~/,
|
|
120
|
-
??
|
|
121
|
-
|
|
122
|
-
return
|
|
121
|
+
const baseDir = this.config.agent?.baseDir?.replace(/^~/, homedir())
|
|
122
|
+
?? path.join(homedir(), ".hive", "agents");
|
|
123
|
+
|
|
124
|
+
return path.join(baseDir, agentId, "workspace");
|
|
123
125
|
}
|
|
124
126
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { apiRequestTool } from "../../tools/api/api-request.ts";
|
|
2
|
+
|
|
3
|
+
export async function handleHttpRequest(req: Request, addCorsHeaders: (r: Response, req: Request) => Response): Promise<Response> {
|
|
4
|
+
try {
|
|
5
|
+
const body = await req.json().catch(() => ({}));
|
|
6
|
+
|
|
7
|
+
const result = await apiRequestTool.execute(body, { configurable: {} });
|
|
8
|
+
|
|
9
|
+
return addCorsHeaders(Response.json(result), req);
|
|
10
|
+
} catch (error) {
|
|
11
|
+
return addCorsHeaders(Response.json({
|
|
12
|
+
ok: false,
|
|
13
|
+
error: `Request failed: ${(error as Error).message}`,
|
|
14
|
+
}), req);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -19,6 +19,15 @@ let installing = false
|
|
|
19
19
|
let installLogs: string[] = []
|
|
20
20
|
let downloadingModelId: string | null = null
|
|
21
21
|
|
|
22
|
+
interface DownloadProgress {
|
|
23
|
+
modelId: string
|
|
24
|
+
downloaded: number
|
|
25
|
+
total: number
|
|
26
|
+
percent: number
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
let currentDownloadProgress: DownloadProgress | null = null
|
|
30
|
+
|
|
22
31
|
async function getInstalledStatus() {
|
|
23
32
|
const { LLAMA_CPP_DEFAULT_VER } = await import("../llm-local/detector")
|
|
24
33
|
const gpu = await detectGPU()
|
|
@@ -183,7 +192,12 @@ export async function handleDownloadLLMModel(
|
|
|
183
192
|
;(async () => {
|
|
184
193
|
try {
|
|
185
194
|
await downloadModel(modelId, (d, t) => {
|
|
186
|
-
|
|
195
|
+
currentDownloadProgress = {
|
|
196
|
+
modelId,
|
|
197
|
+
downloaded: d,
|
|
198
|
+
total: t,
|
|
199
|
+
percent: t > 0 ? Math.round((d / t) * 100) : 0,
|
|
200
|
+
}
|
|
187
201
|
})
|
|
188
202
|
installLogs.push(`✓ Modelo ${modelId} descargado exitosamente`)
|
|
189
203
|
} catch (err) {
|
|
@@ -191,6 +205,7 @@ export async function handleDownloadLLMModel(
|
|
|
191
205
|
installLogs.push(`[error] Error descargando ${modelId}: ${msg}`)
|
|
192
206
|
} finally {
|
|
193
207
|
downloadingModelId = null
|
|
208
|
+
currentDownloadProgress = null
|
|
194
209
|
}
|
|
195
210
|
})()
|
|
196
211
|
|
|
@@ -207,7 +222,15 @@ export async function handleStartLocalLLM(
|
|
|
207
222
|
} catch { /* ignore if no body */ }
|
|
208
223
|
|
|
209
224
|
const mode = body.mode || "TEXT"
|
|
210
|
-
|
|
225
|
+
// If no modelId specified, prefer the recommended model; fall back to the
|
|
226
|
+
// first downloaded model so the user doesn't get an error when they only
|
|
227
|
+
// downloaded a non-default model.
|
|
228
|
+
const recommended = getRecommendedModel(mode.toLowerCase() as any)
|
|
229
|
+
const allModels = listLocalModels()
|
|
230
|
+
const downloadedModels = allModels.filter(m => m.downloaded)
|
|
231
|
+
const resolvedModelId: string =
|
|
232
|
+
body.modelId ||
|
|
233
|
+
(downloadedModels.find(m => m.id === recommended) ? recommended : (downloadedModels[0]?.id ?? recommended))
|
|
211
234
|
|
|
212
235
|
const status = await getInstalledStatus()
|
|
213
236
|
if (!status.installed && !status.binaryExists) {
|
|
@@ -217,11 +240,18 @@ export async function handleStartLocalLLM(
|
|
|
217
240
|
)
|
|
218
241
|
}
|
|
219
242
|
|
|
243
|
+
if (downloadedModels.length === 0) {
|
|
244
|
+
return addCors(
|
|
245
|
+
Response.json({ started: false, reason: "No hay modelos descargados. Descarga un modelo primero desde la sección de modelos." }, { status: 400 }),
|
|
246
|
+
req
|
|
247
|
+
)
|
|
248
|
+
}
|
|
249
|
+
|
|
220
250
|
try {
|
|
221
|
-
installLogs.push(`[llm-server] Iniciando servidor en modo ${mode} con modelo ${
|
|
222
|
-
await llamaManager.start(mode,
|
|
251
|
+
installLogs.push(`[llm-server] Iniciando servidor en modo ${mode} con modelo ${resolvedModelId}...`)
|
|
252
|
+
await llamaManager.start(mode, resolvedModelId as any)
|
|
223
253
|
installLogs.push(`[llm-server] Servidor ${mode} iniciado correctamente.`)
|
|
224
|
-
return addCors(Response.json({ started: true, mode }), req)
|
|
254
|
+
return addCors(Response.json({ started: true, mode, modelId: resolvedModelId }), req)
|
|
225
255
|
} catch (err) {
|
|
226
256
|
const msg = err instanceof Error ? err.message : String(err)
|
|
227
257
|
installLogs.push(`[error] Servidor LLM falló al iniciar: ${msg}`)
|
|
@@ -251,6 +281,22 @@ export async function handleStopLocalLLM(
|
|
|
251
281
|
* Verifica el estado del LLM local al iniciar el gateway.
|
|
252
282
|
* NO auto-inicia el servidor ni descarga nada — el usuario debe hacerlo manualmente.
|
|
253
283
|
*/
|
|
284
|
+
export async function handleGetDownloadProgress(
|
|
285
|
+
req: Request,
|
|
286
|
+
addCors: (r: Response, req: Request) => Response
|
|
287
|
+
): Promise<Response> {
|
|
288
|
+
if (!currentDownloadProgress) {
|
|
289
|
+
return addCors(Response.json({ active: false }), req)
|
|
290
|
+
}
|
|
291
|
+
return addCors(
|
|
292
|
+
Response.json({
|
|
293
|
+
active: true,
|
|
294
|
+
...currentDownloadProgress,
|
|
295
|
+
}),
|
|
296
|
+
req
|
|
297
|
+
)
|
|
298
|
+
}
|
|
299
|
+
|
|
254
300
|
export async function initializeLocalLLM() {
|
|
255
301
|
try {
|
|
256
302
|
const status = await getInstalledStatus()
|
|
@@ -4,6 +4,11 @@ import {
|
|
|
4
4
|
loadProviderApiKey, storeProviderApiKey,
|
|
5
5
|
loadProviderHeaders, storeProviderHeaders,
|
|
6
6
|
} from "../../storage/crypto"
|
|
7
|
+
import { listLocalModels } from "../llm-local/downloader"
|
|
8
|
+
import { loadHiveAgentsModel, getHiveAgentsModelStatus } from "../../agent/llm-providers/hiveagents"
|
|
9
|
+
import { logger } from "../../utils/logger"
|
|
10
|
+
|
|
11
|
+
const log = logger.child("gateway")
|
|
7
12
|
|
|
8
13
|
export async function handleGetProviders(req: Request, addCorsHeaders: (r: Response, req: Request) => Response): Promise<Response> {
|
|
9
14
|
const rawProviders = getDb().query(`
|
|
@@ -24,20 +29,60 @@ export async function handleGetProviders(req: Request, addCorsHeaders: (r: Respo
|
|
|
24
29
|
})
|
|
25
30
|
}
|
|
26
31
|
|
|
32
|
+
// Inyectar modelos locales descargados dinámicamente para local-llama
|
|
33
|
+
try {
|
|
34
|
+
const localModels = listLocalModels()
|
|
35
|
+
const downloadedLocalModels = localModels.filter(m => m.downloaded)
|
|
36
|
+
if (downloadedLocalModels.length > 0) {
|
|
37
|
+
const existingLocalModels = modelsByProvider["local-llama"] || []
|
|
38
|
+
for (const localModel of downloadedLocalModels) {
|
|
39
|
+
const existingIdx = existingLocalModels.findIndex((m: any) => m.id === localModel.id)
|
|
40
|
+
if (existingIdx === -1) {
|
|
41
|
+
existingLocalModels.push({
|
|
42
|
+
id: localModel.id,
|
|
43
|
+
name: localModel.name,
|
|
44
|
+
provider_id: "local-llama",
|
|
45
|
+
model_type: "llm",
|
|
46
|
+
context_window: 16000,
|
|
47
|
+
capabilities: JSON.stringify(["chat", "local"]),
|
|
48
|
+
enabled: true,
|
|
49
|
+
active: true,
|
|
50
|
+
})
|
|
51
|
+
} else {
|
|
52
|
+
// Modelo del seed ya existe pero está descargado: forzar activo
|
|
53
|
+
existingLocalModels[existingIdx] = {
|
|
54
|
+
...existingLocalModels[existingIdx],
|
|
55
|
+
enabled: true,
|
|
56
|
+
active: true,
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
modelsByProvider["local-llama"] = existingLocalModels
|
|
61
|
+
}
|
|
62
|
+
} catch {
|
|
63
|
+
// Ignorar si no se pueden obtener modelos locales
|
|
64
|
+
}
|
|
65
|
+
|
|
27
66
|
const providers = await Promise.all(rawProviders.map(async (p) => {
|
|
28
67
|
const apiKey = await loadProviderApiKey(p.id as string)
|
|
29
68
|
const headers = await loadProviderHeaders(p.id as string)
|
|
69
|
+
const providerModels = modelsByProvider[p.id as string] || []
|
|
70
|
+
// Auto-activar local-llama si tiene modelos descargados dinámicamente
|
|
71
|
+
let active = p.active
|
|
72
|
+
if (p.id === "local-llama" && providerModels.some((m: any) => m.active || m.enabled)) {
|
|
73
|
+
active = true
|
|
74
|
+
}
|
|
30
75
|
return {
|
|
31
76
|
id: p.id,
|
|
32
77
|
name: p.name,
|
|
33
78
|
base_url: p.base_url,
|
|
34
79
|
enabled: p.enabled,
|
|
35
|
-
active
|
|
80
|
+
active,
|
|
36
81
|
num_ctx: p.num_ctx ?? null,
|
|
37
82
|
has_api_key: apiKey ? 1 : 0,
|
|
38
83
|
has_headers: Object.keys(headers).length > 0 ? 1 : 0,
|
|
39
84
|
masked_api_key: apiKey ? maskApiKey(apiKey) : null,
|
|
40
|
-
models:
|
|
85
|
+
models: providerModels,
|
|
41
86
|
}
|
|
42
87
|
}))
|
|
43
88
|
|
|
@@ -218,3 +263,55 @@ export async function handleSyncProviderModels(
|
|
|
218
263
|
}, { status: 502 }), req)
|
|
219
264
|
}
|
|
220
265
|
}
|
|
266
|
+
|
|
267
|
+
export async function handleLoadHiveAgentsModel(
|
|
268
|
+
req: Request,
|
|
269
|
+
addCorsHeaders: (r: Response, req: Request) => Response
|
|
270
|
+
): Promise<Response> {
|
|
271
|
+
const body = await req.json().catch(() => ({}))
|
|
272
|
+
const modelId = body.model_id || body.modelId
|
|
273
|
+
const ctx = typeof body.ctx === "number" && body.ctx > 0 ? body.ctx : 50000
|
|
274
|
+
if (!modelId) {
|
|
275
|
+
return addCorsHeaders(Response.json({ error: "model_id is required" }, { status: 400 }), req)
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
const providerRow = getDb().query("SELECT * FROM providers WHERE id = ?").get("hiveagents") as Record<string, unknown> | undefined
|
|
279
|
+
if (!providerRow) {
|
|
280
|
+
return addCorsHeaders(Response.json({ error: "Provider not found" }, { status: 404 }), req)
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
const apiKey = await loadProviderApiKey("hiveagents")
|
|
284
|
+
if (!apiKey) {
|
|
285
|
+
return addCorsHeaders(Response.json({ error: "API key not configured for hiveagents" }, { status: 400 }), req)
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
const baseUrl = providerRow.base_url as string | undefined
|
|
289
|
+
log.info(`[gateway] Loading hiveagents model ${modelId} with ctx=${ctx} via ${baseUrl || "https://llm.hiveagents.io"}`)
|
|
290
|
+
|
|
291
|
+
const result = await loadHiveAgentsModel(modelId as string, apiKey, baseUrl, ctx)
|
|
292
|
+
if (!result.success) {
|
|
293
|
+
log.error(`[gateway] Failed to load hiveagents model ${modelId}: ${result.error}`)
|
|
294
|
+
return addCorsHeaders(Response.json({ error: result.error }, { status: 502 }), req)
|
|
295
|
+
}
|
|
296
|
+
const isLoading = (result as any).loading === true
|
|
297
|
+
log.info(`[gateway] hiveagents load request accepted for ${modelId} with ctx=${ctx}${isLoading ? " (timeout/backend still loading)" : ""}`)
|
|
298
|
+
return addCorsHeaders(Response.json({ success: true, loading: isLoading, model_id: modelId, ctx }), req)
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
export async function handleGetHiveAgentsModelStatus(
|
|
302
|
+
req: Request,
|
|
303
|
+
addCorsHeaders: (r: Response, req: Request) => Response
|
|
304
|
+
): Promise<Response> {
|
|
305
|
+
const providerRow = getDb().query("SELECT * FROM providers WHERE id = ?").get("hiveagents") as Record<string, unknown> | undefined
|
|
306
|
+
if (!providerRow) {
|
|
307
|
+
return addCorsHeaders(Response.json({ error: "Provider not found" }, { status: 404 }), req)
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
const apiKey = await loadProviderApiKey("hiveagents")
|
|
311
|
+
if (!apiKey) {
|
|
312
|
+
return addCorsHeaders(Response.json({ error: "API key not configured for hiveagents" }, { status: 400 }), req)
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
const status = await getHiveAgentsModelStatus(apiKey, providerRow.base_url as string | undefined)
|
|
316
|
+
return addCorsHeaders(Response.json({ success: true, ...status }), req)
|
|
317
|
+
}
|