@johpaz/hive-agents 0.0.39 → 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 +29 -69
- package/dist/hive.js +2522 -1927
- package/dist/tool-worker.js +1791 -1334
- 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-C-GSRk-N.js → assets/AgentsPage-WFy5abqx.js} +1 -1
- package/dist/ui/assets/ApiClientPage-BV7zLIL7.js +3 -0
- package/dist/ui/assets/{CanvasPage-Cvs5ctza.js → CanvasPage-B9zuIrTm.js} +1 -1
- package/dist/ui/assets/{ChannelsPage-C5m_L7P9.js → ChannelsPage-DiN3NvIM.js} +1 -1
- package/dist/ui/assets/{DashboardPage-CztbRQdm.js → DashboardPage-CHjARjVK.js} +1 -1
- package/dist/ui/assets/{LoginPage-OMsrx5oj.js → LoginPage-Dwd_XxoU.js} +1 -1
- package/dist/ui/{dist/assets/LogsPage-CcYYwjgF.js → assets/LogsPage-DW8Nnqe6.js} +1 -1
- package/dist/ui/assets/MeetingPage-D3bkiKYt.js +1 -0
- package/dist/ui/assets/{NotFound-GbAJDgoD.js → NotFound-BIUDlIXU.js} +1 -1
- package/dist/ui/assets/ProvidersPage-UqsDAxPQ.js +1 -0
- package/dist/ui/{dist/assets/RecoverPage-CwB2ByCU.js → assets/RecoverPage-8hTjr_JU.js} +1 -1
- package/dist/ui/assets/SettingsPage-DNa0jOkA.js +9 -0
- package/dist/ui/assets/{SetupPage-DOVh1ldK.js → SetupPage-Bdm2irQG.js} +1 -1
- package/dist/ui/assets/WebChatPage-DElJg6P2.js +16 -0
- package/dist/ui/assets/accordion-CnLzKNHK.js +1 -0
- package/dist/ui/{dist/assets/alert-D_2Y3qjL.js → assets/alert-DylmSCDJ.js} +1 -1
- package/dist/ui/{dist/assets/alert-dialog-CpMxaNcu.js → assets/alert-dialog-DNNWN_SI.js} +1 -1
- package/dist/ui/assets/{badge-CxTPR6_t.js → badge-ChENFgkC.js} +1 -1
- 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/{dist/assets/dialog-DfS3idb3.js → assets/dialog-BJ-npIv8.js} +1 -1
- package/dist/ui/assets/{dropdown-menu-BdCbAW1z.js → dropdown-menu-DDiaHg5y.js} +1 -1
- package/dist/ui/assets/{es-Cz5h9_84.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-byJkqOYq.js → assets/label-Bi6udtSd.js} +1 -1
- package/dist/ui/assets/select-BQCOjM2j.js +1 -0
- package/dist/ui/assets/useProviders-Dlizq_8q.js +1 -0
- 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-C-GSRk-N.js → dist/assets/AgentsPage-WFy5abqx.js} +1 -1
- package/dist/ui/dist/assets/ApiClientPage-BV7zLIL7.js +3 -0
- package/dist/ui/dist/assets/{CanvasPage-Cvs5ctza.js → CanvasPage-B9zuIrTm.js} +1 -1
- package/dist/ui/dist/assets/{ChannelsPage-C5m_L7P9.js → ChannelsPage-DiN3NvIM.js} +1 -1
- package/dist/ui/dist/assets/{DashboardPage-CztbRQdm.js → DashboardPage-CHjARjVK.js} +1 -1
- package/dist/ui/dist/assets/{LoginPage-OMsrx5oj.js → LoginPage-Dwd_XxoU.js} +1 -1
- package/dist/ui/{assets/LogsPage-CcYYwjgF.js → dist/assets/LogsPage-DW8Nnqe6.js} +1 -1
- package/dist/ui/dist/assets/MeetingPage-D3bkiKYt.js +1 -0
- package/dist/ui/dist/assets/{NotFound-GbAJDgoD.js → NotFound-BIUDlIXU.js} +1 -1
- package/dist/ui/dist/assets/ProvidersPage-UqsDAxPQ.js +1 -0
- package/dist/ui/{assets/RecoverPage-CwB2ByCU.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-DOVh1ldK.js → SetupPage-Bdm2irQG.js} +1 -1
- 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-D_2Y3qjL.js → dist/assets/alert-DylmSCDJ.js} +1 -1
- package/dist/ui/{assets/alert-dialog-CpMxaNcu.js → dist/assets/alert-dialog-DNNWN_SI.js} +1 -1
- package/dist/ui/dist/assets/{badge-CxTPR6_t.js → badge-ChENFgkC.js} +1 -1
- 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/{assets/dialog-DfS3idb3.js → dist/assets/dialog-BJ-npIv8.js} +1 -1
- package/dist/ui/dist/assets/{dropdown-menu-BdCbAW1z.js → dropdown-menu-DDiaHg5y.js} +1 -1
- package/dist/ui/dist/assets/{es-Cz5h9_84.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-byJkqOYq.js → dist/assets/label-Bi6udtSd.js} +1 -1
- package/dist/ui/dist/assets/select-BQCOjM2j.js +1 -0
- package/dist/ui/dist/assets/useProviders-Dlizq_8q.js +1 -0
- package/dist/ui/dist/index.html +4 -4
- package/dist/ui/index.html +4 -4
- package/package.json +1 -1
- package/packages/cli/src/commands/gateway.ts +1 -1
- package/packages/cli/src/commands/onboard.ts +27 -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 +2 -0
- package/packages/core/src/agent/llm-providers/hiveagents.ts +248 -0
- package/packages/core/src/agent/llm-providers/interface.ts +2 -0
- package/packages/core/src/agent/llm-providers/openai-compat-base.ts +49 -25
- 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/config/loader.ts +1 -1
- package/packages/core/src/gateway/routes/providers.ts +56 -0
- package/packages/core/src/gateway/server.ts +120 -55
- package/packages/core/src/gateway/slash-commands.ts +7 -1
- package/packages/core/src/storage/onboarding.ts +28 -0
- package/packages/core/src/storage/seed.ts +14 -0
- package/packages/skills/src/bundled-data.generated.ts +1357 -1357
- package/dist/ui/assets/AgentCreateForm-BTCzFbca.js +0 -1
- package/dist/ui/assets/AgentDetailPage-o27TRSVw.js +0 -1
- package/dist/ui/assets/AgentNewPage-400cCpYt.js +0 -1
- package/dist/ui/assets/ApiClientPage-BOTpz6oP.js +0 -3
- package/dist/ui/assets/MeetingPage-CrKVAfe6.js +0 -1
- package/dist/ui/assets/ProvidersPage-uqPcZUSV.js +0 -1
- package/dist/ui/assets/SettingsPage-DKLlye0z.js +0 -9
- package/dist/ui/assets/WebChatPage-c-7S9jnT.js +0 -16
- package/dist/ui/assets/accordion-DAbcVQCn.js +0 -1
- package/dist/ui/assets/chevron-up-BYhk0K2J.js +0 -1
- package/dist/ui/assets/index-CmGm_r89.js +0 -116
- package/dist/ui/assets/index-T7HgphSn.css +0 -2
- package/dist/ui/assets/select-Cl16QYa_.js +0 -1
- package/dist/ui/assets/useProviders-eEri6BAc.js +0 -1
- package/dist/ui/dist/assets/AgentCreateForm-BTCzFbca.js +0 -1
- package/dist/ui/dist/assets/AgentDetailPage-o27TRSVw.js +0 -1
- package/dist/ui/dist/assets/AgentNewPage-400cCpYt.js +0 -1
- package/dist/ui/dist/assets/ApiClientPage-BOTpz6oP.js +0 -3
- package/dist/ui/dist/assets/MeetingPage-CrKVAfe6.js +0 -1
- package/dist/ui/dist/assets/ProvidersPage-uqPcZUSV.js +0 -1
- package/dist/ui/dist/assets/SettingsPage-DKLlye0z.js +0 -9
- package/dist/ui/dist/assets/WebChatPage-c-7S9jnT.js +0 -16
- package/dist/ui/dist/assets/accordion-DAbcVQCn.js +0 -1
- package/dist/ui/dist/assets/chevron-up-BYhk0K2J.js +0 -1
- package/dist/ui/dist/assets/index-CmGm_r89.js +0 -116
- package/dist/ui/dist/assets/index-T7HgphSn.css +0 -2
- package/dist/ui/dist/assets/select-Cl16QYa_.js +0 -1
- package/dist/ui/dist/assets/useProviders-eEri6BAc.js +0 -1
- /package/dist/ui/assets/{card-CXAm46at.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/{circle-x-Bv6WrUJo.js → circle-x-DjLkFDO8.js} +0 -0
- /package/dist/ui/assets/{copy-dU94ZGsi.js → copy-Bu5d7C-0.js} +0 -0
- /package/dist/ui/assets/{cpu-DSpPVLAz.js → cpu-KDy6-FAI.js} +0 -0
- /package/dist/ui/assets/{download-D9ZyUZZR.js → download-Cjbk4Rek.js} +0 -0
- /package/dist/ui/assets/{external-link-CHPbUorN.js → external-link-6sTlRDUR.js} +0 -0
- /package/dist/ui/assets/{eye-epHJZ_nQ.js → eye-Df8o0tkC.js} +0 -0
- /package/dist/ui/assets/{file-text-BEjEmgby.js → file-text-lnxnjBp0.js} +0 -0
- /package/dist/ui/assets/{folder-open-iQMHVEqS.js → folder-open-DJBLDFjv.js} +0 -0
- /package/dist/ui/assets/{format-oFACFaca.js → format-BwdV8bB5.js} +0 -0
- /package/dist/ui/assets/{gateway-url-iG-C6Agn.js → gateway-url-DwzPmoc8.js} +0 -0
- /package/dist/ui/assets/{gauge-D0_GMEcq.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/{progress-Dtz-Mzys.js → progress-D5c-Eilm.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/{scroll-area-BXtLsE9E.js → scroll-area-CihOx0cb.js} +0 -0
- /package/dist/ui/assets/{search-BGmPJ-6L.js → search-DzDptO9s.js} +0 -0
- /package/dist/ui/assets/{send-BuQcUO-R.js → send-BPk9XbIq.js} +0 -0
- /package/dist/ui/assets/{settings-CcMGI1iU.js → settings-BGfrZ_zM.js} +0 -0
- /package/dist/ui/assets/{shield-C-05qB-2.js → shield-CxhcUT39.js} +0 -0
- /package/dist/ui/assets/{slider-D2I0qven.js → slider-bcUiUfx0.js} +0 -0
- /package/dist/ui/assets/{sparkles-D6fx8JC5.js → sparkles-BhwlS1pc.js} +0 -0
- /package/dist/ui/assets/{square-BD81nFtN.js → square-DMNWw4Hi.js} +0 -0
- /package/dist/ui/assets/{switch-h2SfQX4B.js → switch-BR30E4ej.js} +0 -0
- /package/dist/ui/assets/{table-CVkIRJKK.js → table-B3aGEaVp.js} +0 -0
- /package/dist/ui/assets/{tabs-C619jxbO.js → tabs-LQidMKRS.js} +0 -0
- /package/dist/ui/assets/{terminal-DN38Q456.js → terminal--7G943As.js} +0 -0
- /package/dist/ui/assets/{textarea-wvA-FDjO.js → textarea-B6Z1Zc6W.js} +0 -0
- /package/dist/ui/assets/{trash-2-BHRa5ft9.js → trash-2-xD2o4SgX.js} +0 -0
- /package/dist/ui/assets/{triangle-alert-D4nwAVbc.js → triangle-alert-pVIJGjga.js} +0 -0
- /package/dist/ui/assets/{vendor-router-pCP7sjma.js → vendor-router-gqiZ7xhx.js} +0 -0
- /package/dist/ui/assets/{volume-2-B6tkRy2u.js → volume-2-BekVQl6P.js} +0 -0
- /package/dist/ui/assets/{zap-QO7iWMRg.js → zap-B4RaNNO5.js} +0 -0
- /package/dist/ui/dist/assets/{card-CXAm46at.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/{circle-x-Bv6WrUJo.js → circle-x-DjLkFDO8.js} +0 -0
- /package/dist/ui/dist/assets/{copy-dU94ZGsi.js → copy-Bu5d7C-0.js} +0 -0
- /package/dist/ui/dist/assets/{cpu-DSpPVLAz.js → cpu-KDy6-FAI.js} +0 -0
- /package/dist/ui/dist/assets/{download-D9ZyUZZR.js → download-Cjbk4Rek.js} +0 -0
- /package/dist/ui/dist/assets/{external-link-CHPbUorN.js → external-link-6sTlRDUR.js} +0 -0
- /package/dist/ui/dist/assets/{eye-epHJZ_nQ.js → eye-Df8o0tkC.js} +0 -0
- /package/dist/ui/dist/assets/{file-text-BEjEmgby.js → file-text-lnxnjBp0.js} +0 -0
- /package/dist/ui/dist/assets/{folder-open-iQMHVEqS.js → folder-open-DJBLDFjv.js} +0 -0
- /package/dist/ui/dist/assets/{format-oFACFaca.js → format-BwdV8bB5.js} +0 -0
- /package/dist/ui/dist/assets/{gateway-url-iG-C6Agn.js → gateway-url-DwzPmoc8.js} +0 -0
- /package/dist/ui/dist/assets/{gauge-D0_GMEcq.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/{progress-Dtz-Mzys.js → progress-D5c-Eilm.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/{scroll-area-BXtLsE9E.js → scroll-area-CihOx0cb.js} +0 -0
- /package/dist/ui/dist/assets/{search-BGmPJ-6L.js → search-DzDptO9s.js} +0 -0
- /package/dist/ui/dist/assets/{send-BuQcUO-R.js → send-BPk9XbIq.js} +0 -0
- /package/dist/ui/dist/assets/{settings-CcMGI1iU.js → settings-BGfrZ_zM.js} +0 -0
- /package/dist/ui/dist/assets/{shield-C-05qB-2.js → shield-CxhcUT39.js} +0 -0
- /package/dist/ui/dist/assets/{slider-D2I0qven.js → slider-bcUiUfx0.js} +0 -0
- /package/dist/ui/dist/assets/{sparkles-D6fx8JC5.js → sparkles-BhwlS1pc.js} +0 -0
- /package/dist/ui/dist/assets/{square-BD81nFtN.js → square-DMNWw4Hi.js} +0 -0
- /package/dist/ui/dist/assets/{switch-h2SfQX4B.js → switch-BR30E4ej.js} +0 -0
- /package/dist/ui/dist/assets/{table-CVkIRJKK.js → table-B3aGEaVp.js} +0 -0
- /package/dist/ui/dist/assets/{tabs-C619jxbO.js → tabs-LQidMKRS.js} +0 -0
- /package/dist/ui/dist/assets/{terminal-DN38Q456.js → terminal--7G943As.js} +0 -0
- /package/dist/ui/dist/assets/{textarea-wvA-FDjO.js → textarea-B6Z1Zc6W.js} +0 -0
- /package/dist/ui/dist/assets/{trash-2-BHRa5ft9.js → trash-2-xD2o4SgX.js} +0 -0
- /package/dist/ui/dist/assets/{triangle-alert-D4nwAVbc.js → triangle-alert-pVIJGjga.js} +0 -0
- /package/dist/ui/dist/assets/{vendor-router-pCP7sjma.js → vendor-router-gqiZ7xhx.js} +0 -0
- /package/dist/ui/dist/assets/{volume-2-B6tkRy2u.js → volume-2-BekVQl6P.js} +0 -0
- /package/dist/ui/dist/assets/{zap-QO7iWMRg.js → zap-B4RaNNO5.js} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as e}from"./rolldown-runtime-S-ySWqyJ.js";import{_ as t}from"./vendor-charts-Bu2lyBKP.js";import{$t as n,Gt as r,Ht as i,Jt as a,Kt as o,Qt as s,Ut as c,Vt as l,Wt as u,Xt as d,Yt as f,Zt as p,en as m,qt as h,tn as g}from"./vendor-radix-D6rA7xKY.js";import{o as _}from"./vendor-query-DsWPbQdG.js";import{r as v,t as y}from"./utils-3pnRFmFe.js";import{t as b}from"./chevron-down-DIosfU_U.js";import{t as x}from"./chevron-up-CI-W21Fy.js";var S=v(`Check`,[[`path`,{d:`M20 6 9 17l-5-5`,key:`1gmf2c`}]]),C=e(t(),1),w=_(),T=f,E=i,D=m,O=C.forwardRef(({className:e,children:t,...r},i)=>(0,w.jsxs)(n,{ref:i,className:y(`flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1 cursor-pointer`,e),...r,children:[t,(0,w.jsx)(c,{asChild:!0,children:(0,w.jsx)(b,{className:`h-4 w-4 opacity-50`})})]}));O.displayName=n.displayName;var k=C.forwardRef(({className:e,...t},n)=>(0,w.jsx)(p,{ref:n,className:y(`flex cursor-default items-center justify-center py-1`,e),...t,children:(0,w.jsx)(x,{className:`h-4 w-4`})}));k.displayName=p.displayName;var A=C.forwardRef(({className:e,...t},n)=>(0,w.jsx)(d,{ref:n,className:y(`flex cursor-default items-center justify-center py-1`,e),...t,children:(0,w.jsx)(b,{className:`h-4 w-4`})}));A.displayName=d.displayName;var j=C.forwardRef(({className:e,children:t,position:n=`popper`,align:r=`center`,...i},o)=>(0,w.jsx)(a,{children:(0,w.jsxs)(l,{ref:o,className:y(`relative z-[10001] max-h-[--radix-select-content-available-height] min-w-[8rem] origin-[--radix-select-content-transform-origin] overflow-x-hidden overflow-y-auto rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2`,n===`popper`&&`data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1`,e),position:n,align:r,...i,children:[(0,w.jsx)(k,{}),(0,w.jsx)(g,{className:y(`p-1`,n===`popper`&&`h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1`),children:t}),(0,w.jsx)(A,{})]})}));j.displayName=l.displayName;var M=C.forwardRef(({className:e,...t},n)=>(0,w.jsx)(h,{ref:n,className:y(`py-1.5 pl-8 pr-2 text-sm font-semibold`,e),...t}));M.displayName=h.displayName;var N=C.forwardRef(({className:e,children:t,...n},i)=>(0,w.jsxs)(u,{ref:i,className:y(`relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 focus:bg-accent focus:text-accent-foreground`,e),...n,children:[(0,w.jsx)(`span`,{className:`absolute left-2 flex h-3.5 w-3.5 items-center justify-center`,children:(0,w.jsx)(r,{children:(0,w.jsx)(S,{className:`h-4 w-4`})})}),(0,w.jsx)(o,{children:t})]}));N.displayName=u.displayName;var P=C.forwardRef(({className:e,...t},n)=>(0,w.jsx)(s,{ref:n,className:y(`-mx-1 my-1 h-px bg-muted`,e),...t}));P.displayName=s.displayName;export{M as a,S as c,N as i,j as n,O as o,E as r,D as s,T as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"./index-CawKP29y.js";
|
package/dist/ui/dist/index.html
CHANGED
|
@@ -21,16 +21,16 @@
|
|
|
21
21
|
<meta name="twitter:title" content="Hive">
|
|
22
22
|
<meta property="og:description" content="Hive Agents">
|
|
23
23
|
<meta name="twitter:description" content="Hive Agents">
|
|
24
|
-
<script type="module" crossorigin src="/assets/index-
|
|
24
|
+
<script type="module" crossorigin src="/assets/index-CawKP29y.js"></script>
|
|
25
25
|
<link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-S-ySWqyJ.js">
|
|
26
26
|
<link rel="modulepreload" crossorigin href="/assets/vendor-charts-Bu2lyBKP.js">
|
|
27
|
-
<link rel="modulepreload" crossorigin href="/assets/vendor-router-
|
|
27
|
+
<link rel="modulepreload" crossorigin href="/assets/vendor-router-gqiZ7xhx.js">
|
|
28
28
|
<link rel="modulepreload" crossorigin href="/assets/vendor-query-DsWPbQdG.js">
|
|
29
29
|
<link rel="modulepreload" crossorigin href="/assets/vendor-radix-D6rA7xKY.js">
|
|
30
30
|
<link rel="modulepreload" crossorigin href="/assets/utils-3pnRFmFe.js">
|
|
31
31
|
<link rel="modulepreload" crossorigin href="/assets/vendor-react-BU5iQU4f.js">
|
|
32
|
-
<link rel="modulepreload" crossorigin href="/assets/gateway-url-
|
|
33
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
32
|
+
<link rel="modulepreload" crossorigin href="/assets/gateway-url-DwzPmoc8.js">
|
|
33
|
+
<link rel="stylesheet" crossorigin href="/assets/index-DIcsEkyd.css">
|
|
34
34
|
</head>
|
|
35
35
|
|
|
36
36
|
<body>
|
package/dist/ui/index.html
CHANGED
|
@@ -21,16 +21,16 @@
|
|
|
21
21
|
<meta name="twitter:title" content="Hive">
|
|
22
22
|
<meta property="og:description" content="Hive Agents">
|
|
23
23
|
<meta name="twitter:description" content="Hive Agents">
|
|
24
|
-
<script type="module" crossorigin src="/assets/index-
|
|
24
|
+
<script type="module" crossorigin src="/assets/index-CawKP29y.js"></script>
|
|
25
25
|
<link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-S-ySWqyJ.js">
|
|
26
26
|
<link rel="modulepreload" crossorigin href="/assets/vendor-charts-Bu2lyBKP.js">
|
|
27
|
-
<link rel="modulepreload" crossorigin href="/assets/vendor-router-
|
|
27
|
+
<link rel="modulepreload" crossorigin href="/assets/vendor-router-gqiZ7xhx.js">
|
|
28
28
|
<link rel="modulepreload" crossorigin href="/assets/vendor-query-DsWPbQdG.js">
|
|
29
29
|
<link rel="modulepreload" crossorigin href="/assets/vendor-radix-D6rA7xKY.js">
|
|
30
30
|
<link rel="modulepreload" crossorigin href="/assets/utils-3pnRFmFe.js">
|
|
31
31
|
<link rel="modulepreload" crossorigin href="/assets/vendor-react-BU5iQU4f.js">
|
|
32
|
-
<link rel="modulepreload" crossorigin href="/assets/gateway-url-
|
|
33
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
32
|
+
<link rel="modulepreload" crossorigin href="/assets/gateway-url-DwzPmoc8.js">
|
|
33
|
+
<link rel="stylesheet" crossorigin href="/assets/index-DIcsEkyd.css">
|
|
34
34
|
</head>
|
|
35
35
|
|
|
36
36
|
<body>
|
package/package.json
CHANGED
|
@@ -365,7 +365,7 @@ export async function start(flags: string[]): Promise<void> {
|
|
|
365
365
|
║ ██║ ██║██║ ╚████╔╝ ███████╗ ║
|
|
366
366
|
║ ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚══════╝ ║
|
|
367
367
|
║ ║
|
|
368
|
-
║ Personal Swarm AI Gateway — v0.0.
|
|
368
|
+
║ Personal Swarm AI Gateway — v0.0.40 ║
|
|
369
369
|
╚════════════════════════════════════════════╝
|
|
370
370
|
|
|
371
371
|
📦 Installation: ${adapter.name}
|
|
@@ -50,7 +50,7 @@ function reloadEnvToProcess(hiveDir: string): void {
|
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
const VERSION = "0.0.
|
|
53
|
+
const VERSION = "0.0.40";
|
|
54
54
|
|
|
55
55
|
const DEFAULT_MODELS: Record<string, string> = {
|
|
56
56
|
anthropic: "claude-sonnet-4-6",
|
|
@@ -62,6 +62,7 @@ const DEFAULT_MODELS: Record<string, string> = {
|
|
|
62
62
|
openrouter: "meta-llama/llama-3.3-70b-instruct",
|
|
63
63
|
ollama: "llama3.3:8b",
|
|
64
64
|
nvidia: "meta/llama-3.3-70b-instruct",
|
|
65
|
+
hiveagents: "Qwen3.6-35B-A3B-UD-Q4_K_M.gguf",
|
|
65
66
|
};
|
|
66
67
|
|
|
67
68
|
const PROVIDER_BASE_URLS: Record<string, string> = {
|
|
@@ -74,6 +75,7 @@ const PROVIDER_BASE_URLS: Record<string, string> = {
|
|
|
74
75
|
openrouter: "https://openrouter.ai/api",
|
|
75
76
|
ollama: "http://localhost:11434",
|
|
76
77
|
nvidia: "https://integrate.api.nvidia.com/v1",
|
|
78
|
+
hiveagents: "https://llm.hiveagents.io/v1",
|
|
77
79
|
};
|
|
78
80
|
|
|
79
81
|
const API_KEY_PLACEHOLDERS: Record<string, string> = {
|
|
@@ -86,6 +88,7 @@ const API_KEY_PLACEHOLDERS: Record<string, string> = {
|
|
|
86
88
|
openrouter: "sk-or-...",
|
|
87
89
|
ollama: "",
|
|
88
90
|
nvidia: "nvapi-...",
|
|
91
|
+
hiveagents: "Bearer token...",
|
|
89
92
|
};
|
|
90
93
|
|
|
91
94
|
const API_KEY_LINKS: Record<string, string> = {
|
|
@@ -98,6 +101,7 @@ const API_KEY_LINKS: Record<string, string> = {
|
|
|
98
101
|
openrouter: "https://openrouter.ai/keys",
|
|
99
102
|
ollama: "",
|
|
100
103
|
nvidia: "https://build.nvidia.com/",
|
|
104
|
+
hiveagents: "",
|
|
101
105
|
};
|
|
102
106
|
|
|
103
107
|
const AVAILABLE_MODELS: Record<string, Array<{ value: string; label: string; hint?: string }>> = {
|
|
@@ -154,6 +158,17 @@ const AVAILABLE_MODELS: Record<string, Array<{ value: string; label: string; hin
|
|
|
154
158
|
{ value: "google/gemma-4-31b-it", label: "Gemma 4 31B", hint: "Multimodal — 256K contexto" },
|
|
155
159
|
{ value: "moonshotai/kimi-k2-thinking", label: "Kimi K2 Thinking", hint: "Razonamiento profundo — 256K" },
|
|
156
160
|
],
|
|
161
|
+
hiveagents: [
|
|
162
|
+
{ value: "Qwen3.6-35B-A3B-UD-Q4_K_M.gguf", label: "Qwen3.6 35B MoE Q4 (Recomendado)", hint: "MoE 22.7GB — 62.8 t/s, el más rápido" },
|
|
163
|
+
{ value: "Qwen3.6-35B-A3B-UD-Q6_K.gguf", label: "Qwen3.6 35B MoE Q6", hint: "MoE 30GB — 57.7 t/s" },
|
|
164
|
+
{ value: "Qwen3-Coder-Next-UD-Q4_K_M.gguf", label: "Qwen3 Coder Next MoE Q4", hint: "MoE 49.3GB — 50.9 t/s, ocupa toda la VRAM" },
|
|
165
|
+
{ value: "gemma-4-26B-A4B-UD-Q4_K_M.gguf", label: "Gemma 4 26B MoE Q4", hint: "MoE 16.9GB — 51.5 t/s" },
|
|
166
|
+
{ value: "gemma-4-26B-A4B-UD-Q6_K_XL.gguf", label: "Gemma 4 26B MoE Q6", hint: "MoE 23.3GB — 47.8 t/s" },
|
|
167
|
+
{ value: "gemma-4-12b-it-UD-Q4_K_XL.gguf", label: "Gemma 4 12B Dense Q4", hint: "Dense 7.4GB — 27.7 t/s" },
|
|
168
|
+
{ value: "Qwopus3.6-27B-v2-MTP-Q6_K.gguf", label: "Qwopus 27B Dense+MTP Q6", hint: "Dense+MTP 22.4GB — 17.9 t/s" },
|
|
169
|
+
{ value: "Qwen3.6-27B-UD-Q6_K_XL.gguf", label: "Qwen3.6 27B Dense+MTP Q6", hint: "Dense+MTP 26GB — 16 t/s" },
|
|
170
|
+
{ value: "gemma-4-31B-it-UD-Q6_K_XL.gguf", label: "Gemma 4 31B Dense Q6", hint: "Dense 27.5GB — 7.6 t/s, mayor calidad" },
|
|
171
|
+
],
|
|
157
172
|
};
|
|
158
173
|
|
|
159
174
|
const BUNDLED_SKILLS = [
|
|
@@ -390,6 +405,15 @@ async function testLLMConnection(provider: string, apiKey: string, model: string
|
|
|
390
405
|
return response.ok;
|
|
391
406
|
}
|
|
392
407
|
|
|
408
|
+
if (provider === "hiveagents") {
|
|
409
|
+
try {
|
|
410
|
+
const response = await fetch("https://llm.hiveagents.io/health");
|
|
411
|
+
return response.ok;
|
|
412
|
+
} catch {
|
|
413
|
+
return false;
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
|
|
393
417
|
return false;
|
|
394
418
|
} catch {
|
|
395
419
|
return false;
|
|
@@ -542,6 +566,7 @@ async function runUpdateWizard(existing: ExistingConfig): Promise<void> {
|
|
|
542
566
|
{ value: "nvidia", label: "NVIDIA NIM", hint: "Modelos gratuitos" },
|
|
543
567
|
{ value: "openrouter", label: "OpenRouter", hint: "Multi-modelo" },
|
|
544
568
|
{ value: "ollama", label: "Ollama (local)", hint: "Sin costo" },
|
|
569
|
+
{ value: "hiveagents", label: "HiveAgents LLM", hint: "Qwen3.6 / Gemma4 vía Cloudflare" },
|
|
545
570
|
],
|
|
546
571
|
}) as string;
|
|
547
572
|
|
|
@@ -1057,6 +1082,7 @@ async function runFullWizard(): Promise<void> {
|
|
|
1057
1082
|
{ value: "ollama", label: "Ollama (Local)", hint: "Gratis, corre localmente" },
|
|
1058
1083
|
{ value: "nvidia", label: "NVIDIA NIM", hint: "Modelos gratuitos en build.nvidia.com" },
|
|
1059
1084
|
{ value: "openrouter", label: "OpenRouter", hint: "Múltiples proveedores" },
|
|
1085
|
+
{ value: "hiveagents", label: "HiveAgents LLM", hint: "Local — Qwen3.6 / Gemma4 vía Cloudflare" },
|
|
1060
1086
|
],
|
|
1061
1087
|
initialValue: state.provider,
|
|
1062
1088
|
});
|
|
@@ -28,9 +28,12 @@ import { resolveUserId, resolveAgentId } from "../storage/onboarding"
|
|
|
28
28
|
import type { ContentPart } from "../multimodal/types"
|
|
29
29
|
import { loadConfig } from "../config/loader"
|
|
30
30
|
import { executeToolBatch } from "../tool-runtime"
|
|
31
|
+
import { createStuckLoopDetector, getInterventionMessage, type StuckLoopState } from "./stuck-loop"
|
|
31
32
|
|
|
32
33
|
const log = logger.child("agent-loop")
|
|
33
34
|
|
|
35
|
+
const DEFAULT_MAX_WALL_CLOCK_MS = 5 * 60 * 1000
|
|
36
|
+
|
|
34
37
|
// ─── Types ────────────────────────────────────────────────────────────────────
|
|
35
38
|
|
|
36
39
|
export interface AgentLoopOptions {
|
|
@@ -45,14 +48,19 @@ export interface AgentLoopOptions {
|
|
|
45
48
|
isolated?: boolean
|
|
46
49
|
taskContext?: string | ContentPart[]
|
|
47
50
|
onStep?: (step: StepEvent) => Promise<void>
|
|
51
|
+
onToken?: (token: string) => void
|
|
48
52
|
/** User ID for context propagation */
|
|
49
53
|
userId?: string
|
|
50
54
|
/** Abort signal to stop generation mid-execution */
|
|
51
55
|
signal?: AbortSignal
|
|
52
56
|
/** Clean text for FTS5 and tracing (extracted from userMessage if multimodal) */
|
|
53
57
|
rawUserMessage?: string
|
|
58
|
+
/** Extra tools to force into the LLM loadout (used by tests/evals). */
|
|
59
|
+
extraTools?: any[]
|
|
54
60
|
}
|
|
55
61
|
|
|
62
|
+
export type { StepEvent as AgentStepEvent }
|
|
63
|
+
|
|
56
64
|
export interface StepEvent {
|
|
57
65
|
type: "text" | "tool_call" | "tool_result"
|
|
58
66
|
message: string
|
|
@@ -63,7 +71,7 @@ export interface StepEvent {
|
|
|
63
71
|
// ─── Stream chunk types (compatible with providers/index.ts) ─────────────────
|
|
64
72
|
|
|
65
73
|
export interface StreamChunk {
|
|
66
|
-
agent?: { messages: any[] }
|
|
74
|
+
agent?: { messages: any[]; streamed?: boolean }
|
|
67
75
|
tools?: { messages: any[] }
|
|
68
76
|
usage?: { input_tokens: number; output_tokens: number }
|
|
69
77
|
}
|
|
@@ -82,6 +90,12 @@ export async function* runAgent(
|
|
|
82
90
|
|
|
83
91
|
const agentName = agent.name || opts.agentId
|
|
84
92
|
const maxIterations = agent.max_iterations || 10
|
|
93
|
+
const maxWallClockMs = agent.max_wall_clock_ms || DEFAULT_MAX_WALL_CLOCK_MS
|
|
94
|
+
const wallClockDeadline = Date.now() + maxWallClockMs
|
|
95
|
+
|
|
96
|
+
// Stuck-loop protection
|
|
97
|
+
const stuckDetector = createStuckLoopDetector(loadConfig())
|
|
98
|
+
let stuckState: StuckLoopState | undefined
|
|
85
99
|
|
|
86
100
|
// Resolve LLM provider config
|
|
87
101
|
const providerCfg = await resolveProviderConfig(
|
|
@@ -122,6 +136,19 @@ export async function* runAgent(
|
|
|
122
136
|
userId: opts.userId,
|
|
123
137
|
})
|
|
124
138
|
|
|
139
|
+
// Force extra tools into the loadout (tests/evals)
|
|
140
|
+
if (opts.extraTools?.length) {
|
|
141
|
+
const existingNames = new Set(ctx.tools.map((t: any) => t.function?.name))
|
|
142
|
+
for (const tool of opts.extraTools) {
|
|
143
|
+
const name = tool.function?.name || tool.name
|
|
144
|
+
if (name && !existingNames.has(name)) {
|
|
145
|
+
ctx.tools.push(tool)
|
|
146
|
+
existingNames.add(name)
|
|
147
|
+
log.info(`[agent-loop] Force-injected tool into loadout: ${name}`)
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
125
152
|
const systemPrompt = opts.systemPromptOverride || ctx.systemPrompt
|
|
126
153
|
|
|
127
154
|
// Build initial messages array for the model
|
|
@@ -143,6 +170,9 @@ export async function* runAgent(
|
|
|
143
170
|
let lastToolSignature = ""
|
|
144
171
|
let consecutiveRepeat = 0
|
|
145
172
|
let loopDetected = false
|
|
173
|
+
// Stall detection: iterations without a forward-progress tool call (write/click/navigate)
|
|
174
|
+
let idleIterations = 0
|
|
175
|
+
const PROGRESS_TOOLS = new Set(["browser_type", "browser_click", "browser_navigate"])
|
|
146
176
|
|
|
147
177
|
// ── The loop ────────────────────────────────────────────────────────────
|
|
148
178
|
while (iterations < maxIterations) {
|
|
@@ -152,12 +182,25 @@ export async function* runAgent(
|
|
|
152
182
|
break
|
|
153
183
|
}
|
|
154
184
|
|
|
185
|
+
if (Date.now() > wallClockDeadline) {
|
|
186
|
+
log.warn(`[agent-loop] Wall-clock timeout exceeded (${maxWallClockMs}ms). Breaking.`)
|
|
187
|
+
finalContent = "La tarea tomó demasiado tiempo. Te sugiero dividirla en pasos más pequeños o darme más detalles para continuar."
|
|
188
|
+
break
|
|
189
|
+
}
|
|
190
|
+
|
|
155
191
|
iterations++
|
|
156
192
|
|
|
193
|
+
let streamedThisCall = false
|
|
157
194
|
const response = await callLLM({
|
|
158
195
|
...providerCfg,
|
|
159
196
|
messages: clearOldToolResults(messages) as LLMMessage[],
|
|
160
197
|
tools: ctx.tools.length > 0 ? ctx.tools : undefined,
|
|
198
|
+
onToken: opts.onToken
|
|
199
|
+
? (token: string) => {
|
|
200
|
+
streamedThisCall = true
|
|
201
|
+
opts.onToken?.(token)
|
|
202
|
+
}
|
|
203
|
+
: undefined,
|
|
161
204
|
})
|
|
162
205
|
|
|
163
206
|
// Accumulate usage
|
|
@@ -169,7 +212,7 @@ export async function* runAgent(
|
|
|
169
212
|
// Emit agent chunk (compatible with providers/index.ts)
|
|
170
213
|
const agentMsg: any = { content: response.content }
|
|
171
214
|
if (response.tool_calls?.length) agentMsg.tool_calls = response.tool_calls
|
|
172
|
-
yield { agent: { messages: [agentMsg] } }
|
|
215
|
+
yield { agent: { messages: [agentMsg], streamed: streamedThisCall } }
|
|
173
216
|
|
|
174
217
|
// Notify onStep for narration text
|
|
175
218
|
if (opts.onStep && response.content) {
|
|
@@ -287,6 +330,10 @@ export async function* runAgent(
|
|
|
287
330
|
tool_call_id: tc.id,
|
|
288
331
|
})
|
|
289
332
|
|
|
333
|
+
// Record tool call for stuck-loop detection
|
|
334
|
+
const errorMessage = toolResultLLM.startsWith("[Tool Error]") ? toolResultLLM : undefined
|
|
335
|
+
stuckDetector.recordToolCall(opts.threadId, toolName, tc.function.arguments as Record<string, unknown>, errorMessage)
|
|
336
|
+
|
|
290
337
|
// Dynamic tool injection: when search_knowledge finds tools (native or MCP), add them to ctx.tools
|
|
291
338
|
if (toolName === "search_knowledge") {
|
|
292
339
|
// Use JS object directly (no parse needed)
|
|
@@ -463,6 +510,54 @@ export async function* runAgent(
|
|
|
463
510
|
|
|
464
511
|
if (loopDetected) break
|
|
465
512
|
|
|
513
|
+
// Check for stuck loop after each iteration
|
|
514
|
+
stuckState = stuckDetector.check(opts.threadId)
|
|
515
|
+
if (stuckState.detected) {
|
|
516
|
+
const intervention = getInterventionMessage(stuckState)
|
|
517
|
+
log.warn(`[agent-loop] ${intervention}`)
|
|
518
|
+
|
|
519
|
+
if (stuckState.count >= 4) {
|
|
520
|
+
// Critical: break and notify user instead of looping forever
|
|
521
|
+
finalContent = intervention
|
|
522
|
+
loopDetected = true
|
|
523
|
+
emitCanvas("canvas:node_update", {
|
|
524
|
+
nodeId: opts.agentId,
|
|
525
|
+
changes: { status: "stuck", currentTool: stuckState.toolName },
|
|
526
|
+
})
|
|
527
|
+
break
|
|
528
|
+
} else {
|
|
529
|
+
// Warning: inject intervention message so the model changes strategy
|
|
530
|
+
messages.push({
|
|
531
|
+
role: "user",
|
|
532
|
+
content: intervention,
|
|
533
|
+
})
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
// Stall detection: no forward-progress tool for several iterations
|
|
538
|
+
const hadProgress = toolResults.some(
|
|
539
|
+
(r) => PROGRESS_TOOLS.has(r.toolName) && !String(r.result).startsWith("[Tool Error]")
|
|
540
|
+
)
|
|
541
|
+
if (hadProgress) {
|
|
542
|
+
idleIterations = 0
|
|
543
|
+
} else if (toolResults.length > 0) {
|
|
544
|
+
idleIterations++
|
|
545
|
+
}
|
|
546
|
+
if (idleIterations >= 3 && idleIterations < 5) {
|
|
547
|
+
const stallMsg = "ADVERTENCIA: Llevas varios pasos sin modificar la página. Si ya completaste el formulario, responde al usuario. Si no, avanza con browser_type/browser_click en lugar de seguir inspeccionando."
|
|
548
|
+
log.warn(`[agent-loop] ${stallMsg}`)
|
|
549
|
+
messages.push({ role: "user", content: stallMsg })
|
|
550
|
+
} else if (idleIterations >= 5) {
|
|
551
|
+
const stallMsg = "No logré avanzar en el formulario después de varios intentos. Puede que la página no sea compatible o que falten instrucciones. Te sugiero revisar la URL o darme más detalles."
|
|
552
|
+
log.warn(`[agent-loop] Stall break: ${stallMsg}`)
|
|
553
|
+
finalContent = stallMsg
|
|
554
|
+
emitCanvas("canvas:node_update", {
|
|
555
|
+
nodeId: opts.agentId,
|
|
556
|
+
changes: { status: "stuck", currentTool: "NO_PROGRESS" },
|
|
557
|
+
})
|
|
558
|
+
break
|
|
559
|
+
}
|
|
560
|
+
|
|
466
561
|
emitCanvas("canvas:node_update", {
|
|
467
562
|
nodeId: opts.agentId,
|
|
468
563
|
changes: { status: "thinking", currentTool: null },
|
|
@@ -603,6 +698,10 @@ export class AgentLoop {
|
|
|
603
698
|
raw_user_message?: string
|
|
604
699
|
}
|
|
605
700
|
signal?: AbortSignal
|
|
701
|
+
onToken?: (token: string) => void
|
|
702
|
+
onStep?: (step: StepEvent) => Promise<void>
|
|
703
|
+
/** Extra tools to force into the LLM loadout (tests/evals). */
|
|
704
|
+
extraTools?: any[]
|
|
606
705
|
}
|
|
607
706
|
): AsyncIterable<StreamChunk> {
|
|
608
707
|
// Resolve from database with priority: explicit param → DB lookup → single user/agent
|
|
@@ -647,6 +746,9 @@ export class AgentLoop {
|
|
|
647
746
|
mcpManager: this.mcpManager,
|
|
648
747
|
userId,
|
|
649
748
|
signal: config.signal,
|
|
749
|
+
onToken: config.onToken,
|
|
750
|
+
onStep: config.onStep,
|
|
751
|
+
extraTools: config.extraTools,
|
|
650
752
|
})
|
|
651
753
|
}
|
|
652
754
|
|
|
@@ -183,6 +183,12 @@ export async function compileContext(opts: {
|
|
|
183
183
|
// Sanitized name valid for all LLM providers (no spaces, max 64 chars)
|
|
184
184
|
const fullName = mcpToolFullName(server.name, mcpTool.name)
|
|
185
185
|
|
|
186
|
+
// Skip tools whose sanitized name is empty or fails provider validation
|
|
187
|
+
if (!fullName || !/^[a-zA-Z0-9_-]{1,64}$/.test(fullName)) {
|
|
188
|
+
log.warn(`[context-compiler] Skipping MCP tool with unsupported name: "${mcpTool.name}" (server: ${server.name}, sanitized: "${fullName}")`)
|
|
189
|
+
continue
|
|
190
|
+
}
|
|
191
|
+
|
|
186
192
|
// Executor for agent-loop (has the real call)
|
|
187
193
|
mcpToolExecutors.push({
|
|
188
194
|
name: fullName,
|
|
@@ -26,6 +26,7 @@ import { NvidiaProvider } from "./llm-providers/nvidia"
|
|
|
26
26
|
import { QwenProvider } from "./llm-providers/qwen"
|
|
27
27
|
import { MiniMaxProvider } from "./llm-providers/minimax"
|
|
28
28
|
import { OpenCodeGoProvider } from "./llm-providers/opencode-go"
|
|
29
|
+
import { HiveAgentsProvider } from "./llm-providers/hiveagents"
|
|
29
30
|
import type { LLMProvider } from "./llm-providers/interface"
|
|
30
31
|
|
|
31
32
|
const log = logger.child("llm-client")
|
|
@@ -113,6 +114,7 @@ function getProvider(provider: string): LLMProvider {
|
|
|
113
114
|
case "qwen": return new QwenProvider()
|
|
114
115
|
case "minimax": return new MiniMaxProvider()
|
|
115
116
|
case "opencode-go": return new OpenCodeGoProvider()
|
|
117
|
+
case "hiveagents": return new HiveAgentsProvider()
|
|
116
118
|
default:
|
|
117
119
|
log.warn(`[llm-client] Unknown provider "${provider}" — falling back to OpenAI-compatible endpoint`)
|
|
118
120
|
return new OpenAIProvider()
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
import { logger } from "../../utils/logger"
|
|
2
|
+
import { OpenAICompatBase } from "./openai-compat-base"
|
|
3
|
+
import type { LLMCallOptions, LLMResponse } from "./interface"
|
|
4
|
+
|
|
5
|
+
const log = logger.child("llm-client")
|
|
6
|
+
|
|
7
|
+
const DEFAULT_BASE = "https://llm.hiveagents.io"
|
|
8
|
+
|
|
9
|
+
/** Contexto por defecto que se solicita al backend de HiveAgents al cargar un modelo. */
|
|
10
|
+
export const HIVEAGENTS_DEFAULT_LOAD_CTX = 50000
|
|
11
|
+
|
|
12
|
+
// Cloudflare blocks requests with the OpenAI SDK User-Agent and x-stainless-* fingerprint headers.
|
|
13
|
+
const BLOCKED_HEADERS = [
|
|
14
|
+
"user-agent",
|
|
15
|
+
"x-stainless-lang",
|
|
16
|
+
"x-stainless-package-version",
|
|
17
|
+
"x-stainless-runtime",
|
|
18
|
+
"x-stainless-runtime-version",
|
|
19
|
+
"x-stainless-arch",
|
|
20
|
+
"x-stainless-os",
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
export interface HiveAgentsLoadResult {
|
|
24
|
+
success: boolean
|
|
25
|
+
loading?: boolean
|
|
26
|
+
error?: string
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface HiveAgentsStatusResult {
|
|
30
|
+
loaded: boolean
|
|
31
|
+
model?: { name?: string; ctx?: number; n_ctx?: number }
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function getApiBase(baseUrl?: string): string {
|
|
35
|
+
return (baseUrl?.replace(/\/v1\/?$/, "") || DEFAULT_BASE)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function getAuthHeaders(apiKey: string): Record<string, string> {
|
|
39
|
+
return {
|
|
40
|
+
"Content-Type": "application/json",
|
|
41
|
+
Authorization: `Bearer ${apiKey}`,
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Solicita la carga de un modelo GGUF en el backend de HiveAgents.
|
|
47
|
+
* Siempre pide ctx=HIVEAGENTS_LOAD_CTX para maximizar la ventana de contexto disponible.
|
|
48
|
+
*/
|
|
49
|
+
/** Timeout para la petición de carga. Menor al límite de Cloudflare (100s) para evitar 524. */
|
|
50
|
+
const HIVEAGENTS_LOAD_FETCH_TIMEOUT_MS = 90000
|
|
51
|
+
|
|
52
|
+
export async function loadHiveAgentsModel(
|
|
53
|
+
modelId: string,
|
|
54
|
+
apiKey: string,
|
|
55
|
+
baseUrl?: string,
|
|
56
|
+
ctx = HIVEAGENTS_DEFAULT_LOAD_CTX
|
|
57
|
+
): Promise<HiveAgentsLoadResult> {
|
|
58
|
+
const apiBase = getApiBase(baseUrl)
|
|
59
|
+
const headers = getAuthHeaders(apiKey)
|
|
60
|
+
const loadBody = {
|
|
61
|
+
model: modelId,
|
|
62
|
+
config: { ctx },
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
try {
|
|
66
|
+
log.info(`[hiveagents] → POST ${apiBase}/api/load`)
|
|
67
|
+
log.info(`[hiveagents] → Body: ${JSON.stringify(loadBody)}`)
|
|
68
|
+
const res = await fetch(`${apiBase}/api/load`, {
|
|
69
|
+
method: "POST",
|
|
70
|
+
headers,
|
|
71
|
+
body: JSON.stringify(loadBody),
|
|
72
|
+
signal: AbortSignal.timeout(HIVEAGENTS_LOAD_FETCH_TIMEOUT_MS),
|
|
73
|
+
})
|
|
74
|
+
const responseText = await res.text().catch(() => "")
|
|
75
|
+
if (!res.ok) {
|
|
76
|
+
// 524 = Cloudflare timeout. El backend puede seguir cargando, así que lo tratamos como "en progreso".
|
|
77
|
+
// 530 = Cloudflare Tunnel error (origen no resoluble); también puede ser transitorio.
|
|
78
|
+
const isTransientCloudflareError = [502, 503, 504, 524, 530].includes(res.status)
|
|
79
|
+
if (isTransientCloudflareError) {
|
|
80
|
+
log.warn(`[hiveagents] ← Load request hit transient error (HTTP ${res.status}); backend may still be loading`)
|
|
81
|
+
return { success: true, loading: true }
|
|
82
|
+
}
|
|
83
|
+
log.error(`[hiveagents] ← Load failed: HTTP ${res.status} ${res.statusText} — ${responseText}`)
|
|
84
|
+
return { success: false, error: `Load failed: HTTP ${res.status} — ${responseText || res.statusText}` }
|
|
85
|
+
}
|
|
86
|
+
log.info(`[hiveagents] ← Load accepted: ${responseText}`)
|
|
87
|
+
return { success: true }
|
|
88
|
+
} catch (err) {
|
|
89
|
+
const msg = (err as Error).message || ""
|
|
90
|
+
// AbortError por timeout interno: el backend puede seguir cargando.
|
|
91
|
+
if (msg.includes("timed out") || msg.includes("abort") || msg.includes("AbortError")) {
|
|
92
|
+
log.warn(`[hiveagents] ← Load request timed out after ${HIVEAGENTS_LOAD_FETCH_TIMEOUT_MS}ms; backend may still be loading`)
|
|
93
|
+
return { success: true, loading: true }
|
|
94
|
+
}
|
|
95
|
+
return { success: false, error: msg }
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Consulta el estado actual del backend de HiveAgents.
|
|
101
|
+
*/
|
|
102
|
+
export async function getHiveAgentsModelStatus(
|
|
103
|
+
apiKey: string,
|
|
104
|
+
baseUrl?: string
|
|
105
|
+
): Promise<HiveAgentsStatusResult> {
|
|
106
|
+
const apiBase = getApiBase(baseUrl)
|
|
107
|
+
const headers = getAuthHeaders(apiKey)
|
|
108
|
+
|
|
109
|
+
try {
|
|
110
|
+
const res = await fetch(`${apiBase}/api/status`, { headers })
|
|
111
|
+
if (!res.ok) return { loaded: false }
|
|
112
|
+
const data = await res.json() as any
|
|
113
|
+
return {
|
|
114
|
+
loaded: !!data.loaded,
|
|
115
|
+
model: data.model,
|
|
116
|
+
}
|
|
117
|
+
} catch {
|
|
118
|
+
return { loaded: false }
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export class HiveAgentsProvider extends OpenAICompatBase {
|
|
123
|
+
private _currentModelId = ""
|
|
124
|
+
|
|
125
|
+
constructor() { super("hiveagents") }
|
|
126
|
+
|
|
127
|
+
private _isGemma4(modelId: string): boolean { return /^gemma-?4/i.test(modelId) }
|
|
128
|
+
private _isQwen3(modelId: string): boolean { return /^qwen3?/i.test(modelId) }
|
|
129
|
+
|
|
130
|
+
// Cloudflare WAF blocks requests carrying x-stainless-* headers from the OpenAI SDK.
|
|
131
|
+
// Strip them via a custom fetch wrapper so they never reach the WAF.
|
|
132
|
+
protected async resolveOpenAIClient(apiKey: string, baseURL: string | undefined): Promise<any> {
|
|
133
|
+
const { default: OpenAI } = await import("openai")
|
|
134
|
+
return new OpenAI({
|
|
135
|
+
apiKey,
|
|
136
|
+
baseURL,
|
|
137
|
+
fetch: async (url: RequestInfo | URL, init?: RequestInit) => {
|
|
138
|
+
const headers = new Headers(init?.headers as HeadersInit | undefined)
|
|
139
|
+
for (const h of BLOCKED_HEADERS) headers.delete(h)
|
|
140
|
+
|
|
141
|
+
// Debug: log exact request so we can replicate with curl
|
|
142
|
+
const headersObj: Record<string, string> = {}
|
|
143
|
+
headers.forEach((v, k) => { headersObj[k] = k.toLowerCase() === "authorization" ? `Bearer ••••${v.slice(-6)}` : v })
|
|
144
|
+
log.info(`[hiveagents] → POST ${url}`)
|
|
145
|
+
log.info(`[hiveagents] → Headers: ${JSON.stringify(headersObj)}`)
|
|
146
|
+
if (init?.body) {
|
|
147
|
+
try {
|
|
148
|
+
const parsed = JSON.parse(init.body as string)
|
|
149
|
+
const summary = { model: parsed.model, messages: parsed.messages?.length, tools: parsed.tools?.length, max_tokens: parsed.max_tokens, temperature: parsed.temperature, tool_choice: parsed.tool_choice, extra_body: parsed.extra_body }
|
|
150
|
+
log.info(`[hiveagents] → Body summary: ${JSON.stringify(summary)}`)
|
|
151
|
+
} catch { /* ignore */ }
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const res = await fetch(url, { ...init, headers })
|
|
155
|
+
log.info(`[hiveagents] ← Response: ${res.status} ${res.statusText}`)
|
|
156
|
+
return res
|
|
157
|
+
},
|
|
158
|
+
})
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
async call(options: LLMCallOptions): Promise<LLMResponse> {
|
|
162
|
+
const realModelId = options.model.replace(/^hiveagents\//i, "")
|
|
163
|
+
if (realModelId && realModelId !== "local") {
|
|
164
|
+
await this._ensureModelLoaded(realModelId, options)
|
|
165
|
+
}
|
|
166
|
+
this._currentModelId = realModelId
|
|
167
|
+
|
|
168
|
+
let callOptions = { ...options, model: "hiveagents/local" }
|
|
169
|
+
|
|
170
|
+
// Qwen3: inject /no_think when thinking is explicitly disabled
|
|
171
|
+
if (this._isQwen3(realModelId) && options.thinking?.enabled === false) {
|
|
172
|
+
const msgs = callOptions.messages.map(m => ({ ...m }))
|
|
173
|
+
const sysMsg = msgs.find(m => m.role === "system")
|
|
174
|
+
if (sysMsg && typeof sysMsg.content === "string") {
|
|
175
|
+
if (!sysMsg.content.startsWith("/no_think"))
|
|
176
|
+
sysMsg.content = "/no_think\n" + sysMsg.content
|
|
177
|
+
} else {
|
|
178
|
+
msgs.unshift({ role: "system", content: "/no_think" })
|
|
179
|
+
}
|
|
180
|
+
callOptions = { ...callOptions, messages: msgs }
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return super.call(callOptions)
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Gemma 4: inject chat_template_kwargs.enable_thinking via extra_body.
|
|
187
|
+
// Default is true (thinking ON) when options.thinking is not set.
|
|
188
|
+
protected modifyRequestBody(body: any, options: LLMCallOptions): any {
|
|
189
|
+
if (this._isGemma4(this._currentModelId)) {
|
|
190
|
+
const enableThinking = options.thinking?.enabled !== false
|
|
191
|
+
body.extra_body = {
|
|
192
|
+
...(body.extra_body ?? {}),
|
|
193
|
+
chat_template_kwargs: { enable_thinking: enableThinking },
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return body
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Fallback defensivo: si la UI no cargó el modelo previamente,
|
|
201
|
+
* lo intenta cargar justo antes de inferir.
|
|
202
|
+
*/
|
|
203
|
+
private async _ensureModelLoaded(modelId: string, options: LLMCallOptions): Promise<void> {
|
|
204
|
+
const status = await getHiveAgentsModelStatus(options.apiKey, options.baseUrl)
|
|
205
|
+
if (status.loaded && status.model?.name === modelId) {
|
|
206
|
+
log.info(`[hiveagents] Model ${modelId} already loaded`)
|
|
207
|
+
return
|
|
208
|
+
}
|
|
209
|
+
log.warn(`[hiveagents] Model ${modelId} not loaded. Triggering load with ctx=${HIVEAGENTS_DEFAULT_LOAD_CTX}`)
|
|
210
|
+
const result = await loadHiveAgentsModel(modelId, options.apiKey, options.baseUrl)
|
|
211
|
+
if (!result.success) {
|
|
212
|
+
log.warn(`[hiveagents] Auto-load failed for ${modelId}: ${result.error}`)
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
protected injectToolsIntoPrompt(body: any, preparedTools: any[]): void {
|
|
217
|
+
// When the backend already receives native OpenAI-style tools, do not confuse
|
|
218
|
+
// the model with an alternate <tool_call> text format. HiveAgents supports
|
|
219
|
+
// native tool_calls when the model/chat-template supports them.
|
|
220
|
+
if (body.tools && body.tools.length > 0) {
|
|
221
|
+
return
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// Fallback for models/backends that do not expose native tool calling:
|
|
225
|
+
// inject the tool descriptions as text and instruct the model to emit
|
|
226
|
+
// a single JSON block wrapped in <tool_call> tags.
|
|
227
|
+
const toolDescriptions = preparedTools.map(t => JSON.stringify(t.function)).join("\n")
|
|
228
|
+
const instruction = [
|
|
229
|
+
"You have access to the following tools.",
|
|
230
|
+
"When you need to use a tool, output EXACTLY one JSON block wrapped in <tool_call> tags and NOTHING ELSE in that turn:",
|
|
231
|
+
"",
|
|
232
|
+
"<tool_call>",
|
|
233
|
+
'{"name": "browser_navigate", "arguments": {"url": "https://example.com"}}',
|
|
234
|
+
"</tool_call>",
|
|
235
|
+
"",
|
|
236
|
+
"Use the exact tool name and argument names from the list below. Do not add extra text, markdown, or explanations inside the tool_call block.",
|
|
237
|
+
"",
|
|
238
|
+
"Tools:",
|
|
239
|
+
toolDescriptions,
|
|
240
|
+
].join("\n")
|
|
241
|
+
const sysMsg = body.messages.find((m: any) => m.role === "system")
|
|
242
|
+
if (sysMsg) {
|
|
243
|
+
sysMsg.content += "\n\n" + instruction
|
|
244
|
+
} else {
|
|
245
|
+
body.messages.unshift({ role: "system", content: instruction })
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
@@ -30,6 +30,7 @@ export const OPENAI_COMPAT_BASE_URLS: Record<string, string> = {
|
|
|
30
30
|
qwen: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
|
|
31
31
|
minimax: "https://api.minimaxi.com/v1",
|
|
32
32
|
"opencode-go": "https://opencode.ai/zen/go/v1",
|
|
33
|
+
hiveagents: "https://llm.hiveagents.io/v1",
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
// ─── Provider profiles ────────────────────────────────────────────────────────
|
|
@@ -70,6 +71,7 @@ export const PROVIDER_PROFILES: Record<string, ProviderProfile> = {
|
|
|
70
71
|
"local-llama": { ...DEFAULT_PROFILE },
|
|
71
72
|
minimax: { ...DEFAULT_PROFILE, normalizeToolNames: true, retryWithoutToolsOnCodes: [400, 422] },
|
|
72
73
|
"opencode-go": { ...DEFAULT_PROFILE, normalizeToolNames: true, retryWithoutToolsOnCodes: [400, 422] },
|
|
74
|
+
hiveagents: { ...DEFAULT_PROFILE, retryWithoutToolsOnCodes: [400, 422] },
|
|
73
75
|
}
|
|
74
76
|
|
|
75
77
|
export function getProviderProfile(provider: string): ProviderProfile {
|