@johpaz/hive-agents 0.0.35 → 0.0.37
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 +64 -39
- package/dist/hive.js +3231 -3189
- package/dist/tool-worker.js +218406 -0
- package/dist/ui/assets/{AgentCreateForm-B4eK7efF.js → AgentCreateForm-tJZv9FZC.js} +1 -1
- package/dist/ui/assets/{AgentDetailPage-BD2uoJWk.js → AgentDetailPage-Du-mRcAX.js} +1 -1
- package/dist/ui/assets/AgentNewPage-DIFYd_Ys.js +1 -0
- package/dist/ui/assets/{AgentsPage-4JUZXvkA.js → AgentsPage-YvSgWRiw.js} +6 -6
- package/dist/ui/assets/CanvasPage-DtMwGvxf.js +33 -0
- package/dist/ui/assets/{ChannelsPage-BUn7-nhV.js → ChannelsPage-BdBXWHjj.js} +1 -1
- package/dist/ui/assets/DashboardPage-ghl1ZguH.js +6 -0
- package/dist/ui/assets/{LoginPage-C8j_urUD.js → LoginPage-CAmSI9Vy.js} +1 -1
- package/dist/ui/assets/LogsPage-DAPBHkwK.js +1 -0
- package/dist/ui/assets/MeetingPage-WjjGOqqU.js +1 -0
- package/dist/ui/assets/{NotFound-Drh-sJPN.js → NotFound-BMeQSGcG.js} +1 -1
- package/dist/ui/assets/ProvidersPage-Ct6HsAi1.js +1 -0
- package/dist/ui/assets/{RecoverPage-DNb1Pr8h.js → RecoverPage-DpW3l-yv.js} +1 -1
- package/dist/ui/assets/SettingsPage-DBJ7_E6C.js +9 -0
- package/dist/ui/assets/SetupPage-DKmLVUaj.js +1 -0
- package/dist/ui/assets/{WebChatPage-R-YOwA4F.js → WebChatPage-CVRcKept.js} +2 -2
- package/dist/ui/assets/accordion-C5d5Rm5z.js +1 -0
- package/dist/ui/assets/{alert-U8FsgWi7.js → alert-C-NE-P3s.js} +1 -1
- package/dist/ui/assets/{alert-dialog-CRdMkkmk.js → alert-dialog-C5mzbHdP.js} +1 -1
- package/dist/ui/assets/{badge-Cli1jnH5.js → badge-ChpACfWO.js} +1 -1
- package/dist/ui/assets/chevron-up-BYhk0K2J.js +1 -0
- package/dist/ui/assets/{dialog-DQ3s-LuO.js → dialog-QnZ0ad8O.js} +1 -1
- package/dist/ui/assets/dropdown-menu-BK-CO3Od.js +1 -0
- package/dist/ui/assets/{es-DcMjrpbA.js → es-NQNoaWDx.js} +1 -1
- package/dist/ui/assets/index-B2fCYtTS.css +2 -0
- package/dist/ui/assets/index-DMCjjdqf.js +116 -0
- package/dist/ui/assets/{label-0BvGVXvZ.js → label-D2H1IR_J.js} +1 -1
- package/dist/ui/assets/progress-BherYzY6.js +1 -0
- package/dist/ui/assets/scroll-area-DkeyX32e.js +1 -0
- package/dist/ui/assets/{slider-D47dOrRa.js → slider-CsiUDxc3.js} +1 -1
- package/dist/ui/assets/switch-BDwN8RYV.js +1 -0
- package/dist/ui/assets/{table-DhowbNxQ.js → table-CSc8ubon.js} +1 -1
- package/dist/ui/assets/terminal-DN38Q456.js +1 -0
- package/dist/ui/assets/useProviders-C6_QHsEi.js +1 -0
- package/dist/ui/assets/{vendor-radix-JY4ncZrD.js → vendor-radix-cw1bQaVC.js} +4 -4
- package/dist/ui/assets/{vendor-react-CscwQerf.js → vendor-react-D4s9E-zj.js} +1 -1
- package/dist/ui/dist/assets/AgentCreateForm-tJZv9FZC.js +1 -0
- package/dist/ui/dist/assets/AgentDetailPage-Du-mRcAX.js +1 -0
- package/dist/ui/dist/assets/AgentNewPage-DIFYd_Ys.js +1 -0
- package/dist/ui/dist/assets/AgentsPage-YvSgWRiw.js +10 -0
- package/dist/ui/dist/assets/CanvasPage-DtMwGvxf.js +33 -0
- package/dist/ui/dist/assets/ChannelsPage-BdBXWHjj.js +8 -0
- package/dist/ui/dist/assets/DashboardPage-ghl1ZguH.js +6 -0
- package/dist/ui/dist/assets/LoginPage-CAmSI9Vy.js +1 -0
- package/dist/ui/dist/assets/LogsPage-DAPBHkwK.js +1 -0
- package/dist/ui/dist/assets/MeetingPage-WjjGOqqU.js +1 -0
- package/dist/ui/dist/assets/NotFound-BMeQSGcG.js +1 -0
- package/dist/ui/dist/assets/ProvidersPage-Ct6HsAi1.js +1 -0
- package/dist/ui/dist/assets/RecoverPage-DpW3l-yv.js +1 -0
- package/dist/ui/dist/assets/SettingsPage-DBJ7_E6C.js +9 -0
- package/dist/ui/dist/assets/SetupPage-DKmLVUaj.js +1 -0
- package/dist/ui/dist/assets/WebChatPage-CVRcKept.js +16 -0
- package/dist/ui/dist/assets/accordion-C5d5Rm5z.js +1 -0
- package/dist/ui/dist/assets/activity-c3pNngT_.js +1 -0
- package/dist/ui/dist/assets/alert-C-NE-P3s.js +1 -0
- package/dist/ui/dist/assets/alert-dialog-C5mzbHdP.js +1 -0
- package/dist/ui/dist/assets/arrow-left-CBcbX5EZ.js +1 -0
- package/dist/ui/dist/assets/badge-ChpACfWO.js +1 -0
- package/dist/ui/dist/assets/calendar-B-KZ9RQO.js +1 -0
- package/dist/ui/dist/assets/card-CNf6BS2e.js +1 -0
- package/dist/ui/dist/assets/chevron-left-D4U-5A27.js +1 -0
- package/dist/ui/dist/assets/chevron-right-CR4Skrf3.js +1 -0
- package/dist/ui/dist/assets/chevron-up-BYhk0K2J.js +1 -0
- package/dist/ui/dist/assets/circle-alert-CyHDwUj8.js +1 -0
- package/dist/ui/dist/assets/circle-check-Bb54Ebmu.js +1 -0
- package/dist/ui/dist/assets/cpu-Cdgc_B1K.js +1 -0
- package/dist/ui/dist/assets/dialog-QnZ0ad8O.js +1 -0
- package/dist/ui/dist/assets/download-C3ifGMjJ.js +1 -0
- package/dist/ui/dist/assets/dropdown-menu-BK-CO3Od.js +1 -0
- package/dist/ui/dist/assets/es-NQNoaWDx.js +1 -0
- package/dist/ui/dist/assets/external-link-BvxYeTP1.js +1 -0
- package/dist/ui/dist/assets/eye-DqNTU_GD.js +1 -0
- package/dist/ui/dist/assets/file-text-BT_9S9SM.js +1 -0
- package/dist/ui/dist/assets/folder-open-BhH8y9ac.js +1 -0
- package/dist/ui/dist/assets/format-GVHeOyWI.js +1 -0
- package/dist/ui/dist/assets/gateway-url-COCbW0IR.js +1 -0
- package/dist/ui/dist/assets/gauge-D_TMa4i9.js +1 -0
- package/dist/ui/dist/assets/globe-DeCQTCDJ.js +1 -0
- package/dist/ui/dist/assets/hexagon-DsGOUl-H.js +1 -0
- package/dist/ui/dist/assets/history-BSG-Ypqf.js +1 -0
- package/dist/ui/dist/assets/index-B2fCYtTS.css +2 -0
- package/dist/ui/dist/assets/index-DMCjjdqf.js +116 -0
- package/dist/ui/dist/assets/info-NwLoa2Mj.js +1 -0
- package/dist/ui/dist/assets/key-3EP0dhkT.js +1 -0
- package/dist/ui/dist/assets/label-D2H1IR_J.js +1 -0
- package/dist/ui/dist/assets/loader-circle-CZNax6kS.js +1 -0
- package/dist/ui/dist/assets/lock-Ei1_J-Nq.js +1 -0
- package/dist/ui/dist/assets/pause-BUqah9Bi.js +1 -0
- package/dist/ui/dist/assets/play-NcZ4swwL.js +1 -0
- package/dist/ui/dist/assets/plus-CX1xyhp5.js +1 -0
- package/dist/ui/dist/assets/progress-BherYzY6.js +1 -0
- package/dist/ui/dist/assets/refresh-cw-DaYdjQFk.js +1 -0
- package/dist/ui/dist/assets/rolldown-runtime-S-ySWqyJ.js +1 -0
- package/dist/ui/dist/assets/save-CUdYyHNy.js +1 -0
- package/dist/ui/dist/assets/scroll-area-DkeyX32e.js +1 -0
- package/dist/ui/dist/assets/send-B0H5SEIE.js +1 -0
- package/dist/ui/dist/assets/settings-Ds4SqD8s.js +1 -0
- package/dist/ui/dist/assets/slider-CsiUDxc3.js +14 -0
- package/dist/ui/dist/assets/sparkles-yUEb-7oH.js +1 -0
- package/dist/ui/dist/assets/square-BD81nFtN.js +1 -0
- package/dist/ui/dist/assets/switch-BDwN8RYV.js +1 -0
- package/dist/ui/dist/assets/table-CSc8ubon.js +1 -0
- package/dist/ui/dist/assets/terminal-DN38Q456.js +1 -0
- package/dist/ui/dist/assets/textarea-CXgXWKrT.js +1 -0
- package/dist/ui/dist/assets/trash-2-CNjMkoq6.js +1 -0
- package/dist/ui/dist/assets/triangle-alert-C9Y8Ub4X.js +1 -0
- package/dist/ui/dist/assets/useProviders-C6_QHsEi.js +1 -0
- package/dist/ui/dist/assets/utils-3pnRFmFe.js +1 -0
- package/dist/ui/dist/assets/vendor-charts-Bu2lyBKP.js +65 -0
- package/dist/ui/dist/assets/vendor-query-DsWPbQdG.js +1 -0
- package/dist/ui/dist/assets/vendor-radix-cw1bQaVC.js +63 -0
- package/dist/ui/dist/assets/vendor-react-D4s9E-zj.js +1 -0
- package/dist/ui/dist/assets/vendor-router-C9pIYwbJ.js +3 -0
- package/dist/ui/dist/assets/volume-2-CeSXNDv4.js +1 -0
- package/dist/ui/dist/assets/zap-hlXjpSeA.js +1 -0
- package/dist/ui/dist/favicon.ico +0 -0
- package/dist/ui/dist/index.html +40 -0
- package/dist/ui/dist/placeholder.svg +1 -0
- package/dist/ui/index.html +6 -6
- package/package.json +138 -13
- package/packages/cli/src/adapters/binary.ts +461 -0
- package/packages/cli/src/adapters/bun-global.ts +378 -0
- package/packages/cli/src/adapters/config.ts +314 -0
- package/packages/cli/src/adapters/docker.ts +308 -0
- package/packages/cli/src/adapters/factory.ts +168 -0
- package/packages/cli/src/adapters/index.ts +80 -0
- package/packages/cli/src/adapters/types.ts +218 -0
- package/packages/cli/src/commands/agent-run.ts +168 -0
- package/packages/cli/src/commands/agents.ts +398 -0
- package/packages/cli/src/commands/chat.ts +142 -0
- package/packages/cli/src/commands/config.ts +49 -0
- package/packages/cli/src/commands/cron.ts +487 -0
- package/packages/cli/src/commands/dev.ts +58 -0
- package/packages/cli/src/commands/doctor.ts +320 -0
- package/packages/cli/src/commands/gateway.ts +719 -0
- package/packages/cli/src/commands/logs.ts +57 -0
- package/packages/cli/src/commands/mcp.ts +175 -0
- package/packages/cli/src/commands/message.ts +77 -0
- package/packages/cli/src/commands/migrate.ts +90 -0
- package/packages/cli/src/commands/onboard.ts +1656 -0
- package/packages/cli/src/commands/security.ts +144 -0
- package/packages/cli/src/commands/service.ts +50 -0
- package/packages/cli/src/commands/sessions.ts +116 -0
- package/packages/cli/src/commands/skills.ts +215 -0
- package/packages/cli/src/commands/update.ts +203 -0
- package/packages/cli/src/index.ts +210 -0
- package/packages/cli/src/ui-bundle.generated.ts +3 -0
- package/packages/cli/src/utils/token.ts +6 -0
- package/packages/core/src/agent/agent-loop.ts +691 -0
- package/packages/core/src/agent/compaction.ts +240 -0
- package/packages/core/src/agent/context-compiler.ts +467 -0
- package/packages/core/src/agent/context-guard.ts +91 -0
- package/packages/core/src/agent/conversation-store.ts +244 -0
- package/packages/core/src/agent/curator.ts +158 -0
- package/packages/core/src/agent/hooks.ts +166 -0
- package/packages/core/src/agent/llm-client.ts +167 -0
- package/packages/core/src/agent/llm-providers/anthropic.ts +212 -0
- package/packages/core/src/agent/llm-providers/deepseek.ts +8 -0
- package/packages/core/src/agent/llm-providers/gemini.ts +215 -0
- package/packages/core/src/agent/llm-providers/groq.ts +5 -0
- package/packages/core/src/agent/llm-providers/interface.ts +195 -0
- package/packages/core/src/agent/llm-providers/kimi.ts +8 -0
- package/packages/core/src/agent/llm-providers/local-llama.ts +37 -0
- package/packages/core/src/agent/llm-providers/mistral.ts +5 -0
- package/packages/core/src/agent/llm-providers/nvidia.ts +5 -0
- package/packages/core/src/agent/llm-providers/ollama.ts +175 -0
- package/packages/core/src/agent/llm-providers/openai-compat-base.ts +379 -0
- package/packages/core/src/agent/llm-providers/openai.ts +5 -0
- package/packages/core/src/agent/llm-providers/openrouter.ts +5 -0
- package/packages/core/src/agent/llm-providers/qwen.ts +5 -0
- package/packages/core/src/agent/native-tools.ts +31 -0
- package/packages/core/src/agent/playbook-selector.ts +147 -0
- package/packages/core/src/agent/prompt-builder.ts +169 -0
- package/packages/core/src/agent/providers/index.ts +204 -0
- package/packages/core/src/agent/providers.ts +1 -0
- package/packages/core/src/agent/reflector.ts +200 -0
- package/packages/core/src/agent/service.ts +267 -0
- package/packages/core/src/agent/skill-selector.ts +479 -0
- package/packages/core/src/agent/stuck-loop.ts +133 -0
- package/packages/core/src/agent/tool-selector.ts +569 -0
- package/packages/core/src/agent/tracer.ts +100 -0
- package/packages/core/src/auth/auth.ts +108 -0
- package/packages/core/src/auth/index.ts +1 -0
- package/packages/core/src/canvas/a2ui-tools.ts +255 -0
- package/packages/core/src/canvas/canvas-manager.ts +390 -0
- package/packages/core/src/canvas/canvas-tools.ts +448 -0
- package/packages/core/src/canvas/emitter.ts +149 -0
- package/packages/core/src/canvas/index.ts +3 -0
- package/packages/core/src/channels/base.ts +154 -0
- package/packages/core/src/channels/discord.ts +273 -0
- package/packages/core/src/channels/index.ts +7 -0
- package/packages/core/src/channels/manager.ts +450 -0
- package/packages/core/src/channels/slack.ts +323 -0
- package/packages/core/src/channels/telegram.ts +612 -0
- package/packages/core/src/channels/webchat.ts +139 -0
- package/packages/core/src/channels/whatsapp.ts +548 -0
- package/packages/core/src/config/index.ts +12 -0
- package/packages/core/src/config/loader.ts +569 -0
- package/packages/core/src/events/agent-bus.ts +460 -0
- package/packages/core/src/events/event-bus.ts +169 -0
- package/packages/core/src/gateway/channel-notify.ts +64 -0
- package/packages/core/src/gateway/helpers/cors.ts +32 -0
- package/packages/core/src/gateway/helpers/index.ts +4 -0
- package/packages/core/src/gateway/helpers/narration.ts +57 -0
- package/packages/core/src/gateway/helpers/path.ts +13 -0
- package/packages/core/src/gateway/helpers/redact.ts +61 -0
- package/packages/core/src/gateway/index.ts +5 -0
- package/packages/core/src/gateway/initializer.ts +363 -0
- package/packages/core/src/gateway/lane-queue.ts +169 -0
- package/packages/core/src/gateway/llm-local/client.ts +94 -0
- package/packages/core/src/gateway/llm-local/detector.ts +321 -0
- package/packages/core/src/gateway/llm-local/downloader.ts +216 -0
- package/packages/core/src/gateway/llm-local/index.ts +34 -0
- package/packages/core/src/gateway/llm-local/manager.ts +186 -0
- package/packages/core/src/gateway/llm-local/models.ts +149 -0
- package/packages/core/src/gateway/llm-local/server.ts +179 -0
- package/packages/core/src/gateway/resolver.ts +108 -0
- package/packages/core/src/gateway/router.ts +124 -0
- package/packages/core/src/gateway/routes/agents.ts +210 -0
- package/packages/core/src/gateway/routes/auth.ts +244 -0
- package/packages/core/src/gateway/routes/channels.ts +484 -0
- package/packages/core/src/gateway/routes/chat.ts +241 -0
- package/packages/core/src/gateway/routes/config.ts +12 -0
- package/packages/core/src/gateway/routes/cron-api.ts +544 -0
- package/packages/core/src/gateway/routes/ethics.ts +46 -0
- package/packages/core/src/gateway/routes/llm-local.ts +271 -0
- package/packages/core/src/gateway/routes/mcp.ts +319 -0
- package/packages/core/src/gateway/routes/meeting.ts +232 -0
- package/packages/core/src/gateway/routes/models.ts +163 -0
- package/packages/core/src/gateway/routes/multimodal.ts +93 -0
- package/packages/core/src/gateway/routes/providers.ts +220 -0
- package/packages/core/src/gateway/routes/setup.ts +441 -0
- package/packages/core/src/gateway/routes/skills.ts +115 -0
- package/packages/core/src/gateway/routes/system.ts +469 -0
- package/packages/core/src/gateway/routes/tasks.ts +44 -0
- package/packages/core/src/gateway/routes/tools.ts +59 -0
- package/packages/core/src/gateway/routes/tts-local.ts +388 -0
- package/packages/core/src/gateway/routes/users.ts +122 -0
- package/packages/core/src/gateway/routes/voice.ts +189 -0
- package/packages/core/src/gateway/routes/workspace.ts +281 -0
- package/packages/core/src/gateway/server.ts +2744 -0
- package/packages/core/src/gateway/session.ts +95 -0
- package/packages/core/src/gateway/slash-commands.ts +207 -0
- package/packages/core/src/gateway/tts/README.md +94 -0
- package/packages/core/src/gateway/tts/package.json +25 -0
- package/packages/core/src/gateway/tts/src/client.ts +59 -0
- package/packages/core/src/gateway/tts/src/detect.ts +42 -0
- package/packages/core/src/gateway/tts/src/index.ts +15 -0
- package/packages/core/src/gateway/tts/src/install.ts +129 -0
- package/packages/core/src/gateway/tts/src/models.ts +50 -0
- package/packages/core/src/gateway/tts/src/server.ts +252 -0
- package/packages/core/src/gateway/tts/voices/.gitkeep +0 -0
- package/packages/core/src/heartbeat/index.ts +157 -0
- package/packages/core/src/index.ts +56 -0
- package/packages/core/src/mcp/hot-reload.ts +148 -0
- package/packages/core/src/mcp/singleton.ts +21 -0
- package/packages/core/src/mcp/tool-sync.ts +176 -0
- package/packages/core/src/multimodal/index.ts +2 -0
- package/packages/core/src/multimodal/types.ts +28 -0
- package/packages/core/src/multimodal/vision-service.ts +283 -0
- package/packages/core/src/plugins/api.ts +128 -0
- package/packages/core/src/plugins/index.ts +2 -0
- package/packages/core/src/plugins/loader.ts +365 -0
- package/packages/core/src/resilience/circuit-breaker.ts +225 -0
- package/packages/core/src/scheduler/CronScheduler.ts +699 -0
- package/packages/core/src/scheduler/dag/AgentExecutor.ts +53 -0
- package/packages/core/src/scheduler/dag/DAGScheduler.ts +250 -0
- package/packages/core/src/scheduler/dag/EventBridge.ts +122 -0
- package/packages/core/src/scheduler/dag/TaskGraph.ts +192 -0
- package/packages/core/src/scheduler/dag/TaskNode.ts +97 -0
- package/packages/core/src/scheduler/dag/TaskResult.ts +22 -0
- package/packages/core/src/scheduler/dag/errors.ts +37 -0
- package/packages/core/src/scheduler/dag/index.ts +26 -0
- package/packages/core/src/scheduler/dag/presets/ResearchPreset.ts +97 -0
- package/packages/core/src/scheduler/dag/strategies/ParallelStrategy.ts +21 -0
- package/packages/core/src/scheduler/dag/strategies/PriorityStrategy.ts +46 -0
- package/packages/core/src/scheduler/index.ts +22 -0
- package/packages/core/src/scheduler/integration.ts +237 -0
- package/packages/core/src/scheduler/types.ts +164 -0
- package/packages/core/src/security/google-chat.ts +269 -0
- package/packages/core/src/security/index.ts +192 -0
- package/packages/core/src/security/pairing.ts +250 -0
- package/packages/core/src/security/rate-limit.ts +270 -0
- package/packages/core/src/security/signal.ts +321 -0
- package/packages/core/src/state/store.ts +312 -0
- package/packages/core/src/storage/crypto.ts +197 -0
- package/packages/core/src/storage/migrate.ts +147 -0
- package/packages/core/src/storage/onboarding.ts +1506 -0
- package/packages/core/src/storage/schema.ts +666 -0
- package/packages/core/src/storage/seed.ts +628 -0
- package/packages/core/src/storage/sqlite.ts +407 -0
- package/packages/core/src/storage/usage.ts +374 -0
- package/packages/core/src/tool-runtime/index.ts +502 -0
- package/packages/core/src/tool-runtime/tool-worker.ts +125 -0
- package/packages/core/src/tools/agents/get-available-models.ts +118 -0
- package/packages/core/src/tools/agents/index.ts +610 -0
- package/packages/core/src/tools/canvas/index.ts +420 -0
- package/packages/core/src/tools/cli/index.ts +142 -0
- package/packages/core/src/tools/core/index.ts +478 -0
- package/packages/core/src/tools/cron/index.ts +635 -0
- package/packages/core/src/tools/filesystem/fs-delete.ts +78 -0
- package/packages/core/src/tools/filesystem/fs-edit.ts +106 -0
- package/packages/core/src/tools/filesystem/fs-exists.ts +63 -0
- package/packages/core/src/tools/filesystem/fs-glob.ts +108 -0
- package/packages/core/src/tools/filesystem/fs-list.ts +129 -0
- package/packages/core/src/tools/filesystem/fs-read.ts +72 -0
- package/packages/core/src/tools/filesystem/fs-write.ts +67 -0
- package/packages/core/src/tools/filesystem/index.ts +34 -0
- package/packages/core/src/tools/filesystem/workspace-guard.ts +62 -0
- package/packages/core/src/tools/index.ts +197 -0
- package/packages/core/src/tools/meeting/index.ts +363 -0
- package/packages/core/src/tools/office/index.ts +47 -0
- package/packages/core/src/tools/office/office-escribir-docx.ts +192 -0
- package/packages/core/src/tools/office/office-escribir-pdf.ts +172 -0
- package/packages/core/src/tools/office/office-escribir-pptx.ts +174 -0
- package/packages/core/src/tools/office/office-escribir-xlsx.ts +116 -0
- package/packages/core/src/tools/office/office-leer-docx.ts +93 -0
- package/packages/core/src/tools/office/office-leer-pdf.ts +114 -0
- package/packages/core/src/tools/office/office-leer-pptx.ts +136 -0
- package/packages/core/src/tools/office/office-leer-xlsx.ts +124 -0
- package/packages/core/src/tools/types.ts +39 -0
- package/packages/core/src/tools/voice/index.ts +104 -0
- package/packages/core/src/tools/web/browser-click.ts +78 -0
- package/packages/core/src/tools/web/browser-extract.ts +139 -0
- package/packages/core/src/tools/web/browser-navigate.ts +106 -0
- package/packages/core/src/tools/web/browser-screenshot.ts +87 -0
- package/packages/core/src/tools/web/browser-script.ts +88 -0
- package/packages/core/src/tools/web/browser-service.ts +554 -0
- package/packages/core/src/tools/web/browser-type.ts +101 -0
- package/packages/core/src/tools/web/browser-wait.ts +136 -0
- package/packages/core/src/tools/web/index.ts +41 -0
- package/packages/core/src/tools/web/web-fetch.ts +78 -0
- package/packages/core/src/tools/web/web-search.ts +123 -0
- package/packages/core/src/utils/benchmark.ts +80 -0
- package/packages/core/src/utils/crypto.ts +73 -0
- package/packages/core/src/utils/date.ts +42 -0
- package/packages/core/src/utils/index.ts +5 -0
- package/packages/core/src/utils/logger.ts +389 -0
- package/packages/core/src/utils/retry.ts +70 -0
- package/packages/core/src/utils/toon.ts +253 -0
- package/packages/core/src/voice/index.ts +643 -0
- package/packages/mcp/src/config.ts +13 -0
- package/packages/mcp/src/index.ts +1 -0
- package/packages/mcp/src/logger.ts +47 -0
- package/packages/mcp/src/manager.ts +439 -0
- package/packages/mcp/src/transports/index.ts +67 -0
- package/packages/mcp/src/transports/sse.ts +238 -0
- package/packages/mcp/src/transports/websocket.ts +159 -0
- package/packages/skills/src/bundled/agents/agent_spawner/SKILL.md +167 -0
- package/packages/skills/src/bundled/agents/code_delegator/SKILL.md +156 -0
- package/packages/skills/src/bundled/agents/memory_manager/SKILL.md +143 -0
- package/packages/skills/src/bundled/agents/research_and_remember/SKILL.md +139 -0
- package/packages/skills/src/bundled/agents/task_orchestrator/SKILL.md +198 -0
- package/packages/skills/src/bundled/canvas/a2ui_dashboard/SKILL.md +176 -0
- package/packages/skills/src/bundled/canvas/a2ui_form/SKILL.md +202 -0
- package/packages/skills/src/bundled/canvas/a2ui_interactive/SKILL.md +206 -0
- package/packages/skills/src/bundled/canvas/canvas_dashboard/SKILL.md +146 -0
- package/packages/skills/src/bundled/canvas/canvas_interact/SKILL.md +148 -0
- package/packages/skills/src/bundled/canvas/canvas_report/SKILL.md +146 -0
- package/packages/skills/src/bundled/cli/cli_pipeline/SKILL.md +136 -0
- package/packages/skills/src/bundled/cli/cli_safe_exec/SKILL.md +125 -0
- package/packages/skills/src/bundled/cron_manager/SKILL.md +188 -0
- package/packages/skills/src/bundled/cron_reminder/SKILL.md +112 -0
- package/packages/skills/src/bundled/filesystem/file_manager/SKILL.md +118 -0
- package/packages/skills/src/bundled/filesystem/file_read_and_summarize/SKILL.md +108 -0
- package/packages/skills/src/bundled/filesystem/file_writer/SKILL.md +135 -0
- package/packages/skills/src/bundled/meeting/meeting_transcription/SKILL.md +213 -0
- package/packages/skills/src/bundled/office/office_document_manager/SKILL.md +262 -0
- package/packages/skills/src/bundled/search_knowledge/busqueda_fts5/SKILL.md +74 -0
- package/packages/skills/src/bundled/voice/voice_assistant/SKILL.md +174 -0
- package/packages/skills/src/bundled/voice/voice_input/SKILL.md +146 -0
- package/packages/skills/src/bundled/voice/voice_output/SKILL.md +151 -0
- package/packages/skills/src/bundled/web/browser_automate/SKILL.md +120 -0
- package/packages/skills/src/bundled/web/browser_scrape/SKILL.md +109 -0
- package/packages/skills/src/bundled/web/web_monitor/SKILL.md +127 -0
- package/packages/skills/src/bundled/web/web_research/SKILL.md +119 -0
- package/packages/skills/src/bundled-data.generated.ts +1964 -0
- package/packages/skills/src/index.ts +1 -0
- package/packages/skills/src/loader.ts +388 -0
- package/dist/ui/assets/AgentNewPage-GB-tVN50.js +0 -1
- package/dist/ui/assets/BridgePage-DDcDILKu.js +0 -1
- package/dist/ui/assets/CanvasPage-oOk2sGOD.js +0 -33
- package/dist/ui/assets/DashboardPage-DV_2qWYJ.js +0 -6
- package/dist/ui/assets/LogsPage-DayYjh01.js +0 -1
- package/dist/ui/assets/MeetingPage-C01uPuqj.js +0 -1
- package/dist/ui/assets/ProjectsPage-B8_am_Ib.js +0 -1
- package/dist/ui/assets/ProvidersPage-DBzi66e4.js +0 -1
- package/dist/ui/assets/SettingsPage-CFA_Tknl.js +0 -9
- package/dist/ui/assets/SetupPage-BrUWbhvT.js +0 -1
- package/dist/ui/assets/accordion-DdAEfIXR.js +0 -1
- package/dist/ui/assets/chevron-down-DIosfU_U.js +0 -1
- package/dist/ui/assets/chevron-up-CI-W21Fy.js +0 -1
- package/dist/ui/assets/circle-S0-ouLz-.js +0 -1
- package/dist/ui/assets/circle-minus-CE0iJrl8.js +0 -1
- package/dist/ui/assets/circle-x-jUJ5zZvQ.js +0 -1
- package/dist/ui/assets/dropdown-menu-C2CXM1VE.js +0 -1
- package/dist/ui/assets/index-BN0875JH.css +0 -2
- package/dist/ui/assets/index-CH6sBa3Q.js +0 -116
- package/dist/ui/assets/pencil-5VdSj-h5.js +0 -1
- package/dist/ui/assets/progress-JN30I5fF.js +0 -1
- package/dist/ui/assets/scroll-area-BQQPitM8.js +0 -1
- package/dist/ui/assets/search-ChPgnVKj.js +0 -1
- package/dist/ui/assets/switch-C7W2-KEx.js +0 -1
- package/dist/ui/assets/terminal-C-R5Fckz.js +0 -1
- package/dist/ui/assets/useProviders-TBnWn-Hq.js +0 -1
- /package/dist/ui/assets/{card-DFKnZ6ky.js → card-CNf6BS2e.js} +0 -0
- /package/dist/ui/assets/{circle-alert-KuAm2FWh.js → circle-alert-CyHDwUj8.js} +0 -0
- /package/dist/ui/assets/{circle-check-6Ard1-2z.js → circle-check-Bb54Ebmu.js} +0 -0
- /package/dist/ui/assets/{cpu-KDy6-FAI.js → cpu-Cdgc_B1K.js} +0 -0
- /package/dist/ui/assets/{download-Cjbk4Rek.js → download-C3ifGMjJ.js} +0 -0
- /package/dist/ui/assets/{external-link-HtrFM63g.js → external-link-BvxYeTP1.js} +0 -0
- /package/dist/ui/assets/{eye-D1dB40_o.js → eye-DqNTU_GD.js} +0 -0
- /package/dist/ui/assets/{file-text-CE58EfH0.js → file-text-BT_9S9SM.js} +0 -0
- /package/dist/ui/assets/{folder-open-DIPKeiI_.js → folder-open-BhH8y9ac.js} +0 -0
- /package/dist/ui/assets/{format-BwdV8bB5.js → format-GVHeOyWI.js} +0 -0
- /package/dist/ui/assets/{gateway-url-D5uj6Nxg.js → gateway-url-COCbW0IR.js} +0 -0
- /package/dist/ui/assets/{gauge-DmQmJHEg.js → gauge-D_TMa4i9.js} +0 -0
- /package/dist/ui/assets/{globe-_hUGxQF4.js → globe-DeCQTCDJ.js} +0 -0
- /package/dist/ui/assets/{hexagon-BaNGQlQj.js → hexagon-DsGOUl-H.js} +0 -0
- /package/dist/ui/assets/{history-BfZVGlZa.js → history-BSG-Ypqf.js} +0 -0
- /package/dist/ui/assets/{info-CBZ5-AlC.js → info-NwLoa2Mj.js} +0 -0
- /package/dist/ui/assets/{key-Bv5DdTPh.js → key-3EP0dhkT.js} +0 -0
- /package/dist/ui/assets/{loader-circle-C4hhXLgp.js → loader-circle-CZNax6kS.js} +0 -0
- /package/dist/ui/assets/{lock-CkZYexqw.js → lock-Ei1_J-Nq.js} +0 -0
- /package/dist/ui/assets/{pause-Bpy1_s7y.js → pause-BUqah9Bi.js} +0 -0
- /package/dist/ui/assets/{play-Cj4osqJZ.js → play-NcZ4swwL.js} +0 -0
- /package/dist/ui/assets/{plus-BQhgZN3A.js → plus-CX1xyhp5.js} +0 -0
- /package/dist/ui/assets/{refresh-cw-BfREHVQM.js → refresh-cw-DaYdjQFk.js} +0 -0
- /package/dist/ui/assets/{save-FFTD4dMp.js → save-CUdYyHNy.js} +0 -0
- /package/dist/ui/assets/{settings-BdHKUL92.js → settings-Ds4SqD8s.js} +0 -0
- /package/dist/ui/assets/{sparkles-r4uJbJAl.js → sparkles-yUEb-7oH.js} +0 -0
- /package/dist/ui/assets/{square-G7Hyufqm.js → square-BD81nFtN.js} +0 -0
- /package/dist/ui/assets/{textarea-5kyuD04X.js → textarea-CXgXWKrT.js} +0 -0
- /package/dist/ui/assets/{trash-2-DXVBRWfh.js → trash-2-CNjMkoq6.js} +0 -0
- /package/dist/ui/assets/{triangle-alert-Bu5seg9O.js → triangle-alert-C9Y8Ub4X.js} +0 -0
- /package/dist/ui/assets/{vendor-router-CCECILJ0.js → vendor-router-C9pIYwbJ.js} +0 -0
- /package/dist/ui/assets/{volume-2-s9DuS696.js → volume-2-CeSXNDv4.js} +0 -0
- /package/dist/ui/assets/{zap-BPHZzXKV.js → zap-hlXjpSeA.js} +0 -0
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
import { logger } from "../../utils/logger"
|
|
2
|
+
import {
|
|
3
|
+
sanitizeMessages, requiresTemperature1, OPENAI_COMPAT_BASE_URLS,
|
|
4
|
+
getProviderProfile, modelSupportsTools, normalizeToolName, normalizeToolSchema,
|
|
5
|
+
} from "./interface"
|
|
6
|
+
import type { LLMCallOptions, LLMProvider, LLMResponse, LLMToolCall } from "./interface"
|
|
7
|
+
import type { ContentPart, LLMMessage } from "../llm-client"
|
|
8
|
+
|
|
9
|
+
const log = logger.child("llm-client")
|
|
10
|
+
|
|
11
|
+
export abstract class OpenAICompatBase implements LLMProvider {
|
|
12
|
+
constructor(protected readonly providerName: string) {}
|
|
13
|
+
|
|
14
|
+
/** Override to true when the provider requires reasoning_content to be round-tripped. */
|
|
15
|
+
protected needsReasoningRoundtrip(): boolean { return false }
|
|
16
|
+
|
|
17
|
+
/** Override to true for providers running on localhost. */
|
|
18
|
+
protected isLocalProvider(): boolean { return false }
|
|
19
|
+
|
|
20
|
+
/** Hook called before each request. Override for e.g. auto-starting a local server. */
|
|
21
|
+
protected async beforeCall(_options: LLMCallOptions): Promise<void> {}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Hook called after tools are prepared when sendTools is true.
|
|
25
|
+
* Override to inject tool descriptions into the system prompt
|
|
26
|
+
* (for local models whose chat templates don't support native tool calling).
|
|
27
|
+
*/
|
|
28
|
+
protected injectToolsIntoPrompt(_body: any, _preparedTools: any[]): void {}
|
|
29
|
+
|
|
30
|
+
private _convertContentPart(part: ContentPart): any {
|
|
31
|
+
switch (part.type) {
|
|
32
|
+
case "text":
|
|
33
|
+
return { type: "text", text: part.text }
|
|
34
|
+
case "image_url":
|
|
35
|
+
return { type: "image_url", image_url: { url: part.image_url.url } }
|
|
36
|
+
case "image_base64":
|
|
37
|
+
return { type: "image_url", image_url: { url: `data:${part.mimeType};base64,${part.base64}` } }
|
|
38
|
+
case "document":
|
|
39
|
+
log.warn(`[llm-client] ${this.providerName}: document content parts are not supported — content will be omitted`)
|
|
40
|
+
return { type: "text", text: `[Document: ${(part as any).fileName || "file"}] (content not supported for this provider)` }
|
|
41
|
+
default:
|
|
42
|
+
return { type: "text", text: JSON.stringify(part) }
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
private _convertMessage(msg: LLMMessage): any {
|
|
47
|
+
if (Array.isArray(msg.content)) {
|
|
48
|
+
return { ...msg, content: msg.content.map(p => this._convertContentPart(p)) }
|
|
49
|
+
}
|
|
50
|
+
return msg
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async call(options: LLMCallOptions): Promise<LLMResponse> {
|
|
54
|
+
const { default: OpenAI } = await import("openai")
|
|
55
|
+
|
|
56
|
+
const baseURL = options.baseUrl?.trim() || OPENAI_COMPAT_BASE_URLS[this.providerName] || undefined
|
|
57
|
+
const isLocal = this.isLocalProvider()
|
|
58
|
+
|
|
59
|
+
await this.beforeCall(options)
|
|
60
|
+
|
|
61
|
+
const apiKey = options.apiKey || (isLocal ? "ollama" : undefined)
|
|
62
|
+
if (!apiKey) {
|
|
63
|
+
throw new Error(`API key missing for provider: ${this.providerName}. Configure it in Settings → Providers.`)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const client = new OpenAI({ apiKey, baseURL })
|
|
67
|
+
|
|
68
|
+
const sanitized = sanitizeMessages(options.messages)
|
|
69
|
+
const rawMessages = this.needsReasoningRoundtrip()
|
|
70
|
+
? sanitized
|
|
71
|
+
: sanitized.map(({ reasoning_content: _rc, ...rest }) => rest as typeof sanitized[number])
|
|
72
|
+
const messagesForProvider = rawMessages.map(m => this._convertMessage(m))
|
|
73
|
+
|
|
74
|
+
const providerPrefix = new RegExp(`^${this.providerName}\\/`, "i")
|
|
75
|
+
const body: any = {
|
|
76
|
+
model: options.model.replace(providerPrefix, ""),
|
|
77
|
+
messages: messagesForProvider,
|
|
78
|
+
temperature: requiresTemperature1(this.providerName, options.model) ? 1 : (options.temperature ?? 0.7),
|
|
79
|
+
}
|
|
80
|
+
if (options.maxTokens) {
|
|
81
|
+
body.max_tokens = options.maxTokens
|
|
82
|
+
} else if (options.contextWindow) {
|
|
83
|
+
// Reserve 15% of context window for output tokens, cap at 8192
|
|
84
|
+
body.max_tokens = Math.min(8192, Math.floor(options.contextWindow * 0.15))
|
|
85
|
+
}
|
|
86
|
+
if (options.numCtx && isLocal) body.num_ctx = options.numCtx
|
|
87
|
+
|
|
88
|
+
const profile = getProviderProfile(this.providerName)
|
|
89
|
+
const sendTools = modelSupportsTools(this.providerName, options.model) && !!(options.tools?.length)
|
|
90
|
+
|
|
91
|
+
const toolNameMap = new Map<string, string>()
|
|
92
|
+
|
|
93
|
+
if (sendTools) {
|
|
94
|
+
const preparedTools = options.tools!.map((t) => {
|
|
95
|
+
const originalName = t.function.name
|
|
96
|
+
const wireName = profile.normalizeToolNames
|
|
97
|
+
? normalizeToolName(originalName, profile.toolNameReplacement)
|
|
98
|
+
: originalName
|
|
99
|
+
if (wireName !== originalName) toolNameMap.set(wireName, originalName)
|
|
100
|
+
return {
|
|
101
|
+
...t,
|
|
102
|
+
function: {
|
|
103
|
+
...t.function,
|
|
104
|
+
name: wireName,
|
|
105
|
+
parameters: normalizeToolSchema(t.function.parameters as Record<string, unknown>, profile),
|
|
106
|
+
},
|
|
107
|
+
}
|
|
108
|
+
})
|
|
109
|
+
body.tools = preparedTools
|
|
110
|
+
body.tool_choice = profile.toolChoiceAuto
|
|
111
|
+
if (profile.disableParallelToolCalls) body.parallel_tool_calls = false
|
|
112
|
+
|
|
113
|
+
this.injectToolsIntoPrompt(body, preparedTools)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
log.info(`[llm-client] ${this.providerName}/${body.model} — ${options.messages.length} msgs, ${options.tools?.length ?? 0} tools${sendTools ? "" : " (tools suppressed)"}`)
|
|
117
|
+
|
|
118
|
+
if (options.onToken) {
|
|
119
|
+
return this._streamCall(client, body, options, toolNameMap, sendTools, profile)
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
let response
|
|
123
|
+
try {
|
|
124
|
+
response = await client.chat.completions.create(body)
|
|
125
|
+
} catch (err: any) {
|
|
126
|
+
const status = err?.status ?? err?.response?.status
|
|
127
|
+
const errMsg = (err?.error?.message ?? err?.message ?? "").toLowerCase()
|
|
128
|
+
|
|
129
|
+
// Retry 1: tools rejected by provider — remove tools and retry
|
|
130
|
+
if (sendTools && profile.retryWithoutToolsOnCodes.includes(status)) {
|
|
131
|
+
log.warn(`[llm-client] ${this.providerName}: tools rejected (HTTP ${status}) — retrying without tools`)
|
|
132
|
+
const bodyNoTools = { ...body }
|
|
133
|
+
delete bodyNoTools.tools
|
|
134
|
+
delete bodyNoTools.tool_choice
|
|
135
|
+
delete bodyNoTools.parallel_tool_calls
|
|
136
|
+
response = await client.chat.completions.create(bodyNoTools)
|
|
137
|
+
}
|
|
138
|
+
// Retry 2: context overflow — compact messages and retry
|
|
139
|
+
else if (status === 400 && (errMsg.includes("context length") || errMsg.includes("input_tokens") || errMsg.includes("maximum input length"))) {
|
|
140
|
+
log.warn(`[llm-client] ${this.providerName}: context overflow — compacting messages and retrying`)
|
|
141
|
+
const compacted = [...body.messages]
|
|
142
|
+
const kept: any[] = []
|
|
143
|
+
let systemMsg: any = null
|
|
144
|
+
for (const m of compacted) {
|
|
145
|
+
if (m.role === "system") { systemMsg = m; continue }
|
|
146
|
+
kept.push(m)
|
|
147
|
+
}
|
|
148
|
+
// Keep only 33% of messages to free enough context budget
|
|
149
|
+
const keepRatio = Math.max(1, Math.floor(kept.length / 3))
|
|
150
|
+
const trimmed = kept.slice(-keepRatio)
|
|
151
|
+
body.messages = systemMsg ? [systemMsg, ...trimmed] : trimmed
|
|
152
|
+
// Reduce output budget to leave more room for input
|
|
153
|
+
if (body.max_tokens) body.max_tokens = Math.min(body.max_tokens, 4096)
|
|
154
|
+
|
|
155
|
+
log.info(`[llm-client] ${this.providerName}: compacted ${compacted.length} msgs → ${body.messages.length} msgs, max_tokens=${body.max_tokens}`)
|
|
156
|
+
response = await client.chat.completions.create(body)
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
throw err
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const choice = response.choices[0]
|
|
164
|
+
const msg = choice.message
|
|
165
|
+
|
|
166
|
+
let final_tool_calls: LLMToolCall[] | undefined = (msg.tool_calls as any[])?.map((tc: any) => ({
|
|
167
|
+
id: tc.id,
|
|
168
|
+
type: "function" as const,
|
|
169
|
+
function: {
|
|
170
|
+
name: toolNameMap.get(tc.function.name) ?? tc.function.name,
|
|
171
|
+
arguments: tc.function.arguments,
|
|
172
|
+
},
|
|
173
|
+
}))
|
|
174
|
+
|
|
175
|
+
let final_content = msg.content ?? ""
|
|
176
|
+
|
|
177
|
+
if (sendTools && (!final_tool_calls || final_tool_calls.length === 0) && final_content) {
|
|
178
|
+
const extracted = extractToolCallsFromText(final_content, toolNameMap)
|
|
179
|
+
if (extracted.tool_calls.length > 0) {
|
|
180
|
+
final_tool_calls = extracted.tool_calls
|
|
181
|
+
final_content = extracted.content
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return {
|
|
186
|
+
content: final_content,
|
|
187
|
+
tool_calls: final_tool_calls,
|
|
188
|
+
reasoning_content: (msg as any).reasoning_content ?? undefined,
|
|
189
|
+
stop_reason:
|
|
190
|
+
choice.finish_reason === "tool_calls" ? "tool_calls"
|
|
191
|
+
: choice.finish_reason === "length" ? "max_tokens"
|
|
192
|
+
: "stop",
|
|
193
|
+
usage: response.usage ? {
|
|
194
|
+
input_tokens: response.usage.prompt_tokens,
|
|
195
|
+
output_tokens: response.usage.completion_tokens,
|
|
196
|
+
} : undefined,
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
private async _streamCall(
|
|
201
|
+
client: any,
|
|
202
|
+
body: any,
|
|
203
|
+
options: LLMCallOptions,
|
|
204
|
+
toolNameMap: Map<string, string>,
|
|
205
|
+
sendTools: boolean,
|
|
206
|
+
profile: ReturnType<typeof getProviderProfile>,
|
|
207
|
+
): Promise<LLMResponse> {
|
|
208
|
+
let stream
|
|
209
|
+
try {
|
|
210
|
+
stream = await client.chat.completions.create({ ...body, stream: true })
|
|
211
|
+
} catch (err: any) {
|
|
212
|
+
const status = err?.status ?? err?.response?.status
|
|
213
|
+
const errMsg = (err?.error?.message ?? err?.message ?? "").toLowerCase()
|
|
214
|
+
|
|
215
|
+
if (sendTools && profile.retryWithoutToolsOnCodes.includes(status)) {
|
|
216
|
+
log.warn(`[llm-client] ${this.providerName}: tools rejected (HTTP ${status}) — retrying stream without tools`)
|
|
217
|
+
const bodyNoTools = { ...body }
|
|
218
|
+
delete bodyNoTools.tools
|
|
219
|
+
delete bodyNoTools.tool_choice
|
|
220
|
+
delete bodyNoTools.parallel_tool_calls
|
|
221
|
+
stream = await client.chat.completions.create({ ...bodyNoTools, stream: true })
|
|
222
|
+
} else if (status === 400 && (errMsg.includes("context length") || errMsg.includes("input_tokens") || errMsg.includes("maximum input length"))) {
|
|
223
|
+
log.warn(`[llm-client] ${this.providerName}: context overflow — compacting messages and retrying stream`)
|
|
224
|
+
const compacted = [...body.messages]
|
|
225
|
+
const kept: any[] = []
|
|
226
|
+
let systemMsg: any = null
|
|
227
|
+
for (const m of compacted) {
|
|
228
|
+
if (m.role === "system") { systemMsg = m; continue }
|
|
229
|
+
kept.push(m)
|
|
230
|
+
}
|
|
231
|
+
const keepRatio = Math.max(1, Math.floor(kept.length / 3))
|
|
232
|
+
const trimmed = kept.slice(-keepRatio)
|
|
233
|
+
body.messages = systemMsg ? [systemMsg, ...trimmed] : trimmed
|
|
234
|
+
if (body.max_tokens) body.max_tokens = Math.min(body.max_tokens, 4096)
|
|
235
|
+
log.info(`[llm-client] ${this.providerName}: compacted ${compacted.length} msgs → ${body.messages.length} msgs, max_tokens=${body.max_tokens}`)
|
|
236
|
+
stream = await client.chat.completions.create({ ...body, stream: true })
|
|
237
|
+
} else {
|
|
238
|
+
throw err
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
let content = ""
|
|
243
|
+
let reasoning_content = ""
|
|
244
|
+
let finish_reason = "stop"
|
|
245
|
+
const toolCallMap: Map<number, { id: string; name: string; arguments: string }> = new Map()
|
|
246
|
+
let input_tokens = 0
|
|
247
|
+
let output_tokens = 0
|
|
248
|
+
|
|
249
|
+
for await (const chunk of stream) {
|
|
250
|
+
const choice = chunk.choices?.[0]
|
|
251
|
+
if (!choice) continue
|
|
252
|
+
|
|
253
|
+
const delta = choice.delta as any
|
|
254
|
+
if (delta.content) {
|
|
255
|
+
content += delta.content
|
|
256
|
+
options.onToken!(delta.content)
|
|
257
|
+
}
|
|
258
|
+
if (delta.reasoning_content) {
|
|
259
|
+
reasoning_content += delta.reasoning_content
|
|
260
|
+
}
|
|
261
|
+
if (delta.tool_calls) {
|
|
262
|
+
for (const tc of delta.tool_calls) {
|
|
263
|
+
const idx: number = tc.index
|
|
264
|
+
if (!toolCallMap.has(idx)) {
|
|
265
|
+
toolCallMap.set(idx, { id: tc.id ?? "", name: tc.function?.name ?? "", arguments: "" })
|
|
266
|
+
}
|
|
267
|
+
const entry = toolCallMap.get(idx)!
|
|
268
|
+
if (tc.id) entry.id = tc.id
|
|
269
|
+
if (tc.function?.name) entry.name = tc.function.name
|
|
270
|
+
if (tc.function?.arguments) entry.arguments += tc.function.arguments
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
if (choice.finish_reason) finish_reason = choice.finish_reason
|
|
274
|
+
|
|
275
|
+
if (chunk.usage) {
|
|
276
|
+
input_tokens = chunk.usage.prompt_tokens ?? 0
|
|
277
|
+
output_tokens = chunk.usage.completion_tokens ?? 0
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
const tool_calls: LLMToolCall[] = [...toolCallMap.values()].map((tc) => ({
|
|
282
|
+
id: tc.id,
|
|
283
|
+
type: "function" as const,
|
|
284
|
+
function: {
|
|
285
|
+
name: toolNameMap.get(tc.name) ?? tc.name,
|
|
286
|
+
arguments: tc.arguments || "{}",
|
|
287
|
+
},
|
|
288
|
+
}))
|
|
289
|
+
|
|
290
|
+
let final_tool_calls: LLMToolCall[] | undefined = tool_calls.length ? tool_calls : undefined
|
|
291
|
+
let final_content = content
|
|
292
|
+
|
|
293
|
+
if (sendTools && !final_tool_calls && final_content) {
|
|
294
|
+
const extracted = extractToolCallsFromText(final_content, toolNameMap)
|
|
295
|
+
if (extracted.tool_calls.length > 0) {
|
|
296
|
+
final_tool_calls = extracted.tool_calls
|
|
297
|
+
final_content = extracted.content
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
return {
|
|
302
|
+
content: final_content,
|
|
303
|
+
tool_calls: final_tool_calls,
|
|
304
|
+
reasoning_content: reasoning_content || undefined,
|
|
305
|
+
stop_reason:
|
|
306
|
+
finish_reason === "tool_calls" ? "tool_calls"
|
|
307
|
+
: finish_reason === "length" ? "max_tokens"
|
|
308
|
+
: "stop",
|
|
309
|
+
usage: input_tokens > 0 || output_tokens > 0
|
|
310
|
+
? { input_tokens, output_tokens }
|
|
311
|
+
: undefined,
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Extracts tool_calls from text when the model fails to emit native tool_calls.
|
|
318
|
+
* Supports common formats used by Gemma, Qwen, and other local models.
|
|
319
|
+
*/
|
|
320
|
+
export function extractToolCallsFromText(
|
|
321
|
+
content: string,
|
|
322
|
+
toolNameMap: Map<string, string>,
|
|
323
|
+
knownToolNames?: Set<string>,
|
|
324
|
+
): { content: string; tool_calls: LLMToolCall[] } {
|
|
325
|
+
const tool_calls: LLMToolCall[] = []
|
|
326
|
+
let extractedContent = content
|
|
327
|
+
|
|
328
|
+
const regexes = [
|
|
329
|
+
/<tool_call>\s*({[\s\S]*?})\s*<\/tool_call>/g,
|
|
330
|
+
/<function_call>\s*({[\s\S]*?})\s*<\/function_call>/g,
|
|
331
|
+
/```(?:tool_call|json)\s*({[\s\S]*?})\s*```/g,
|
|
332
|
+
]
|
|
333
|
+
|
|
334
|
+
for (const regex of regexes) {
|
|
335
|
+
let match
|
|
336
|
+
while ((match = regex.exec(content)) !== null) {
|
|
337
|
+
try {
|
|
338
|
+
const json = JSON.parse(match[1])
|
|
339
|
+
if (json.name) {
|
|
340
|
+
tool_calls.push({
|
|
341
|
+
id: crypto.randomUUID(),
|
|
342
|
+
type: "function",
|
|
343
|
+
function: {
|
|
344
|
+
name: toolNameMap.get(json.name) ?? json.name,
|
|
345
|
+
arguments: typeof json.arguments === "object" ? JSON.stringify(json.arguments) : (json.arguments || "{}"),
|
|
346
|
+
},
|
|
347
|
+
})
|
|
348
|
+
extractedContent = extractedContent.replace(match[0], "").trim()
|
|
349
|
+
}
|
|
350
|
+
} catch {
|
|
351
|
+
// ignore parse errors
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// Fallback: entire output is a bare JSON tool call — only if name matches a known tool
|
|
357
|
+
if (tool_calls.length === 0 && knownToolNames && knownToolNames.size > 0) {
|
|
358
|
+
try {
|
|
359
|
+
const json = JSON.parse(content.trim())
|
|
360
|
+
const resolvedName = toolNameMap.get(json.name) ?? json.name
|
|
361
|
+
if (json.name && knownToolNames.has(resolvedName) && (json.arguments || json.parameters)) {
|
|
362
|
+
const args = json.arguments || json.parameters
|
|
363
|
+
tool_calls.push({
|
|
364
|
+
id: crypto.randomUUID(),
|
|
365
|
+
type: "function",
|
|
366
|
+
function: {
|
|
367
|
+
name: resolvedName,
|
|
368
|
+
arguments: typeof args === "object" ? JSON.stringify(args) : (args || "{}"),
|
|
369
|
+
},
|
|
370
|
+
})
|
|
371
|
+
extractedContent = ""
|
|
372
|
+
}
|
|
373
|
+
} catch {
|
|
374
|
+
// not valid JSON
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
return { content: extractedContent, tool_calls }
|
|
379
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Native Tools Type Definitions
|
|
3
|
+
*
|
|
4
|
+
* Tool interface for native Hive tools (no LangChain)
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export interface Tool {
|
|
8
|
+
name: string
|
|
9
|
+
description: string
|
|
10
|
+
parameters: {
|
|
11
|
+
type: "object"
|
|
12
|
+
properties: Record<string, ToolParameter>
|
|
13
|
+
required?: string[]
|
|
14
|
+
}
|
|
15
|
+
execute: (params: Record<string, unknown>, config?: any) => Promise<string | object>
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface ToolParameter {
|
|
19
|
+
type: string
|
|
20
|
+
description?: string
|
|
21
|
+
enum?: string[]
|
|
22
|
+
items?: ToolParameter
|
|
23
|
+
properties?: Record<string, ToolParameter>
|
|
24
|
+
required?: string[]
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface ToolResult {
|
|
28
|
+
success: boolean
|
|
29
|
+
result?: any
|
|
30
|
+
error?: string
|
|
31
|
+
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FTS5-based Playbook Rules Selector (ACE Curator)
|
|
3
|
+
*
|
|
4
|
+
* This module allows the Context Compiler to inject relevant evolved rules
|
|
5
|
+
* into the agent prompt based on semantic relevance to the current message.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { getDb } from "../storage/sqlite"
|
|
9
|
+
import { logger } from "../utils/logger"
|
|
10
|
+
|
|
11
|
+
const log = logger.child("playbook-selector")
|
|
12
|
+
|
|
13
|
+
// ─── Types ───────────────────────────────────────────────────────────────────────
|
|
14
|
+
|
|
15
|
+
export interface PlaybookRule {
|
|
16
|
+
id: number
|
|
17
|
+
rule: string
|
|
18
|
+
category: string
|
|
19
|
+
applicable_to?: string
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// ─── Configuration ─────────────────────────────────────────────────────────────
|
|
23
|
+
|
|
24
|
+
/** Maximum rules to inject per context window */
|
|
25
|
+
const MAX_RULES_PER_TURN = 5
|
|
26
|
+
|
|
27
|
+
/** Minimum bm25 score threshold for rules */
|
|
28
|
+
const MIN_RELEVANCE_THRESHOLD = -10 // Relaxed for better matching
|
|
29
|
+
|
|
30
|
+
// ─── Selection Logic ───────────────────────────────────────────────────────────
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Select relevant rules from the Playbook based on semantic matching
|
|
34
|
+
*/
|
|
35
|
+
export function selectPlaybookRules(message: string): PlaybookRule[] {
|
|
36
|
+
const db = getDb()
|
|
37
|
+
const startTime = performance.now()
|
|
38
|
+
|
|
39
|
+
// Clean query — use prefix matching for consistency with skill-selector and tool-selector
|
|
40
|
+
const keywords = message
|
|
41
|
+
.toLowerCase()
|
|
42
|
+
// Keep only letters, numbers, spaces (strips ALL FTS5 special syntax)
|
|
43
|
+
.replace(/[^\p{L}\p{N}\s]/gu, " ")
|
|
44
|
+
.split(/\s+/)
|
|
45
|
+
.filter(w => w.length > 3)
|
|
46
|
+
.slice(0, 5)
|
|
47
|
+
|
|
48
|
+
if (keywords.length === 0) return []
|
|
49
|
+
|
|
50
|
+
// Use prefix matching for better recall (e.g., "program*" matches "programar", "programación")
|
|
51
|
+
const ftsQuery = keywords.map(w => `${w}*`).join(" OR ")
|
|
52
|
+
|
|
53
|
+
try {
|
|
54
|
+
// Query FTS table
|
|
55
|
+
const ftsResults = db.query(`
|
|
56
|
+
SELECT rowid, bm25(playbook_fts) as score
|
|
57
|
+
FROM playbook_fts
|
|
58
|
+
WHERE playbook_fts MATCH ?
|
|
59
|
+
ORDER BY score ASC
|
|
60
|
+
LIMIT ?
|
|
61
|
+
`).all(ftsQuery, MAX_RULES_PER_TURN) as Array<{ rowid: number; score: number }>
|
|
62
|
+
|
|
63
|
+
const relevantIds = ftsResults
|
|
64
|
+
.filter(r => r.score >= MIN_RELEVANCE_THRESHOLD)
|
|
65
|
+
.map(r => r.rowid)
|
|
66
|
+
|
|
67
|
+
if (relevantIds.length === 0) return []
|
|
68
|
+
|
|
69
|
+
// Fetch full rules
|
|
70
|
+
const rules = db.query(`
|
|
71
|
+
SELECT id, rule, category, applicable_to
|
|
72
|
+
FROM playbook
|
|
73
|
+
WHERE id IN (${relevantIds.map(() => '?').join(',')})
|
|
74
|
+
AND active = 1
|
|
75
|
+
`).all(...relevantIds) as PlaybookRule[]
|
|
76
|
+
|
|
77
|
+
const timing = performance.now() - startTime
|
|
78
|
+
log.info(`[playbook-selector] Selected ${rules.length} rules in ${timing.toFixed(2)}ms`)
|
|
79
|
+
if (rules.length > 0) {
|
|
80
|
+
log.debug(`[playbook-selector] Rules: ${rules.map(r => `[${r.id}] ${r.rule.substring(0, 60)}`).join(', ')}`)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return rules
|
|
84
|
+
} catch (err) {
|
|
85
|
+
log.error(`[playbook-selector] Failed to select rules:`, err)
|
|
86
|
+
return []
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// ─── Sync Logic ───────────────────────────────────────────────────────────────
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Sync active playbook rules to FTS5 virtual table
|
|
94
|
+
*/
|
|
95
|
+
export async function syncPlaybookToFTS(): Promise<void> {
|
|
96
|
+
const db = getDb()
|
|
97
|
+
|
|
98
|
+
try {
|
|
99
|
+
// Step 1: Get active rules
|
|
100
|
+
const rules = db.query(`
|
|
101
|
+
SELECT id, rule, category, applicable_to
|
|
102
|
+
FROM playbook
|
|
103
|
+
WHERE active = 1
|
|
104
|
+
`).all() as Array<{
|
|
105
|
+
id: number
|
|
106
|
+
rule: string
|
|
107
|
+
category: string
|
|
108
|
+
applicable_to: string
|
|
109
|
+
}>
|
|
110
|
+
|
|
111
|
+
if (rules.length === 0) {
|
|
112
|
+
log.debug(`[playbook-selector] No rules in playbook to sync`)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Step 2: Atomic transaction for FTS5 sync
|
|
116
|
+
const syncTransaction = db.transaction(() => {
|
|
117
|
+
// Verify table exists
|
|
118
|
+
const tableCheck = db.query("SELECT name FROM sqlite_master WHERE type='table' AND name='playbook_fts'").get()
|
|
119
|
+
if (!tableCheck) {
|
|
120
|
+
throw new Error("playbook_fts table does not exist!")
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// A: Clear existing data
|
|
124
|
+
db.run("DELETE FROM playbook_fts")
|
|
125
|
+
|
|
126
|
+
// B: Prepare insertion
|
|
127
|
+
const insert = db.prepare(`
|
|
128
|
+
INSERT INTO playbook_fts(rowid, rule, category, applicable_to)
|
|
129
|
+
VALUES (?, ?, ?, ?)
|
|
130
|
+
`)
|
|
131
|
+
|
|
132
|
+
// C: Re-populate
|
|
133
|
+
for (const item of rules) {
|
|
134
|
+
insert.run(item.id, item.rule, item.category, item.applicable_to)
|
|
135
|
+
}
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
// Execute transaction
|
|
139
|
+
syncTransaction()
|
|
140
|
+
|
|
141
|
+
log.info(`[playbook-selector] Atomic sync complete: ${rules.length} rules indexed in FTS5`)
|
|
142
|
+
|
|
143
|
+
} catch (err) {
|
|
144
|
+
log.error(`[playbook-selector] Transactional sync failed:`, err)
|
|
145
|
+
throw err
|
|
146
|
+
}
|
|
147
|
+
}
|