@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,388 @@
|
|
|
1
|
+
import { existsSync, readdirSync, readFileSync } from "fs"
|
|
2
|
+
import { join } from "path"
|
|
3
|
+
import { homedir } from "os"
|
|
4
|
+
import { TTS_MODELS, getModelById } from "../tts/src/models.ts"
|
|
5
|
+
import { runInstall } from "../tts/src/install.ts"
|
|
6
|
+
import { startTTSServer } from "../tts/src/server.ts"
|
|
7
|
+
|
|
8
|
+
// Datos de TTS en HIVE_HOME/tts/ — funciona igual en dev, npm global y Docker
|
|
9
|
+
const TTS_ROOT =
|
|
10
|
+
process.env.HIVE_TTS_ROOT ??
|
|
11
|
+
join(process.env.HIVE_HOME ?? join(homedir(), ".hive"), "tts")
|
|
12
|
+
const BIN_PATH = join(TTS_ROOT, "bin", process.platform === "win32" ? "piper.exe" : "piper")
|
|
13
|
+
const VOICES_DIR = join(TTS_ROOT, "voices")
|
|
14
|
+
const TTS_PORT = Number(process.env.TTS_PORT ?? 5500)
|
|
15
|
+
|
|
16
|
+
let ttsServer: ReturnType<typeof Bun.serve> | null = null
|
|
17
|
+
let installing = false
|
|
18
|
+
let installLogs: string[] = []
|
|
19
|
+
let downloadingModelId: string | null = null
|
|
20
|
+
let downloadLogs: string[] = []
|
|
21
|
+
|
|
22
|
+
function isInstalled(): { piperExists: boolean; voiceExists: boolean; installed: boolean } {
|
|
23
|
+
const piperExists = existsSync(BIN_PATH)
|
|
24
|
+
const voiceExists = getInstalledVoices().length > 0
|
|
25
|
+
return { piperExists, voiceExists, installed: piperExists && voiceExists }
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function getInstalledVoices(): string[] {
|
|
29
|
+
if (!existsSync(VOICES_DIR)) return []
|
|
30
|
+
const files = readdirSync(VOICES_DIR)
|
|
31
|
+
return files
|
|
32
|
+
.filter((f) => f.endsWith(".onnx"))
|
|
33
|
+
.map((f) => f.replace(".onnx", ""))
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async function isRunning(): Promise<boolean> {
|
|
37
|
+
try {
|
|
38
|
+
const res = await fetch(`http://localhost:${TTS_PORT}/health`, {
|
|
39
|
+
signal: AbortSignal.timeout(600),
|
|
40
|
+
})
|
|
41
|
+
return res.ok
|
|
42
|
+
} catch {
|
|
43
|
+
return false
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export async function handleGetLocalTTSStatus(
|
|
48
|
+
req: Request,
|
|
49
|
+
addCors: (r: Response, req: Request) => Response
|
|
50
|
+
): Promise<Response> {
|
|
51
|
+
const { piperExists, voiceExists, installed } = isInstalled()
|
|
52
|
+
const running = await isRunning()
|
|
53
|
+
const voices = getInstalledVoices()
|
|
54
|
+
return addCors(
|
|
55
|
+
Response.json({
|
|
56
|
+
installed,
|
|
57
|
+
piperExists,
|
|
58
|
+
voiceExists,
|
|
59
|
+
running,
|
|
60
|
+
port: TTS_PORT,
|
|
61
|
+
installing,
|
|
62
|
+
voices
|
|
63
|
+
}),
|
|
64
|
+
req
|
|
65
|
+
)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export async function handleGetLocalTTSLogs(
|
|
69
|
+
req: Request,
|
|
70
|
+
addCors: (r: Response, req: Request) => Response
|
|
71
|
+
): Promise<Response> {
|
|
72
|
+
return addCors(
|
|
73
|
+
Response.json({ logs: installLogs.slice(-100), ttsRoot: TTS_ROOT, bunPath: process.execPath }),
|
|
74
|
+
req
|
|
75
|
+
)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export async function handleInstallLocalTTS(
|
|
79
|
+
req: Request,
|
|
80
|
+
addCors: (r: Response, req: Request) => Response
|
|
81
|
+
): Promise<Response> {
|
|
82
|
+
if (installing) {
|
|
83
|
+
return addCors(Response.json({ started: false, reason: "Ya hay una instalación en curso" }), req)
|
|
84
|
+
}
|
|
85
|
+
if (isInstalled().installed) {
|
|
86
|
+
return addCors(Response.json({ started: false, reason: "Piper ya está instalado" }), req)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
installing = true
|
|
90
|
+
installLogs = [`[${new Date().toISOString()}] Iniciando instalación de Piper...`]
|
|
91
|
+
installLogs.push(` TTS_ROOT: ${TTS_ROOT}`)
|
|
92
|
+
|
|
93
|
+
// Interceptar console.log de runInstall para capturar en installLogs
|
|
94
|
+
const origLog = console.log
|
|
95
|
+
const origWarn = console.warn
|
|
96
|
+
console.log = (...args) => { installLogs.push(args.join(" ")); origLog(...args) }
|
|
97
|
+
console.warn = (...args) => { installLogs.push(`[warn] ${args.join(" ")}`); origWarn(...args) }
|
|
98
|
+
|
|
99
|
+
runInstall(TTS_ROOT)
|
|
100
|
+
.then(() => {
|
|
101
|
+
installLogs.push(`[${new Date().toISOString()}] Instalación completada`)
|
|
102
|
+
})
|
|
103
|
+
.catch((err) => {
|
|
104
|
+
installLogs.push(`[error] ${err instanceof Error ? err.message : String(err)}`)
|
|
105
|
+
console.error(`[hive-tts install] Falló: ${err}`)
|
|
106
|
+
})
|
|
107
|
+
.finally(() => {
|
|
108
|
+
installing = false
|
|
109
|
+
console.log = origLog
|
|
110
|
+
console.warn = origWarn
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
return addCors(Response.json({ started: true }), req)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export async function handleStartLocalTTS(
|
|
117
|
+
req: Request,
|
|
118
|
+
addCors: (r: Response, req: Request) => Response
|
|
119
|
+
): Promise<Response> {
|
|
120
|
+
if (await isRunning()) {
|
|
121
|
+
return addCors(Response.json({ started: false, reason: "El servidor TTS ya está ejecutándose" }), req)
|
|
122
|
+
}
|
|
123
|
+
if (!isInstalled().installed) {
|
|
124
|
+
return addCors(
|
|
125
|
+
Response.json({ started: false, reason: "Piper no está instalado. Instálalo primero." }, { status: 400 }),
|
|
126
|
+
req
|
|
127
|
+
)
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
try {
|
|
131
|
+
ttsServer = startTTSServer({ port: TTS_PORT })
|
|
132
|
+
installLogs.push(`[tts-server] Servidor TTS iniciado en puerto ${TTS_PORT}`)
|
|
133
|
+
} catch (err) {
|
|
134
|
+
const msg = err instanceof Error ? err.message : String(err)
|
|
135
|
+
console.error(`[tts-server] Falló al iniciar: ${msg}`)
|
|
136
|
+
installLogs.push(`[error] Servidor TTS falló al iniciar: ${msg}`)
|
|
137
|
+
return addCors(Response.json({ started: false, reason: msg }), req)
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Esperar hasta 3s a que el server levante
|
|
141
|
+
for (let i = 0; i < 6; i++) {
|
|
142
|
+
await Bun.sleep(500)
|
|
143
|
+
if (await isRunning()) break
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const running = await isRunning()
|
|
147
|
+
return addCors(Response.json({ started: running }), req)
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export async function handleStopLocalTTS(
|
|
151
|
+
req: Request,
|
|
152
|
+
addCors: (r: Response, req: Request) => Response
|
|
153
|
+
): Promise<Response> {
|
|
154
|
+
if (ttsServer) {
|
|
155
|
+
ttsServer.stop(true)
|
|
156
|
+
ttsServer = null
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return addCors(Response.json({ stopped: true }), req)
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
async function ensureTTSRunning(): Promise<boolean> {
|
|
163
|
+
if (await isRunning()) return true
|
|
164
|
+
if (!isInstalled().installed) return false
|
|
165
|
+
|
|
166
|
+
try {
|
|
167
|
+
ttsServer = startTTSServer({ port: TTS_PORT })
|
|
168
|
+
} catch {
|
|
169
|
+
return false
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
for (let i = 0; i < 10; i++) {
|
|
173
|
+
await Bun.sleep(500)
|
|
174
|
+
if (await isRunning()) return true
|
|
175
|
+
}
|
|
176
|
+
return false
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export async function initializeLocalTTS() {
|
|
180
|
+
const { installed } = isInstalled()
|
|
181
|
+
if (installed) {
|
|
182
|
+
const running = await isRunning()
|
|
183
|
+
if (!running) {
|
|
184
|
+
try {
|
|
185
|
+
ttsServer = startTTSServer({ port: TTS_PORT })
|
|
186
|
+
console.log(`[tts-server] Servidor TTS auto-iniciado en puerto ${TTS_PORT}`)
|
|
187
|
+
} catch (err) {
|
|
188
|
+
console.error(`[tts-server] Falló el auto-inicio: ${err instanceof Error ? err.message : String(err)}`)
|
|
189
|
+
}
|
|
190
|
+
} else {
|
|
191
|
+
console.log(`[tts-server] Servidor TTS ya está ejecutándose en puerto ${TTS_PORT}`)
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Proxy de síntesis para el browser — evita exponer el puerto TTS directamente
|
|
197
|
+
export async function handleSpeakLocalTTS(
|
|
198
|
+
req: Request,
|
|
199
|
+
addCors: (r: Response, req: Request) => Response
|
|
200
|
+
): Promise<Response> {
|
|
201
|
+
let body: { text?: string; voice?: string }
|
|
202
|
+
try {
|
|
203
|
+
body = await req.json()
|
|
204
|
+
} catch {
|
|
205
|
+
return addCors(Response.json({ error: "Body JSON inválido" }, { status: 400 }), req)
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
const { text, voice } = body
|
|
209
|
+
if (!text || typeof text !== "string" || text.trim().length === 0) {
|
|
210
|
+
return addCors(Response.json({ error: "'text' requerido" }, { status: 400 }), req)
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
const running = await ensureTTSRunning()
|
|
214
|
+
if (!running) {
|
|
215
|
+
return addCors(
|
|
216
|
+
Response.json({ error: "Piper TTS no disponible" }, { status: 503 }),
|
|
217
|
+
req
|
|
218
|
+
)
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
try {
|
|
222
|
+
const res = await fetch(`http://localhost:${TTS_PORT}/tts`, {
|
|
223
|
+
method: "POST",
|
|
224
|
+
headers: { "Content-Type": "application/json" },
|
|
225
|
+
body: JSON.stringify({ text: text.trim(), voice }),
|
|
226
|
+
signal: AbortSignal.timeout(15_000),
|
|
227
|
+
})
|
|
228
|
+
if (!res.ok) {
|
|
229
|
+
const err = await res.json().catch(() => ({ error: "TTS error" }))
|
|
230
|
+
return addCors(Response.json(err, { status: 503 }), req)
|
|
231
|
+
}
|
|
232
|
+
const wav = await res.arrayBuffer()
|
|
233
|
+
return addCors(
|
|
234
|
+
new Response(wav, {
|
|
235
|
+
headers: {
|
|
236
|
+
"Content-Type": "audio/wav",
|
|
237
|
+
"Content-Length": String(wav.byteLength),
|
|
238
|
+
},
|
|
239
|
+
}),
|
|
240
|
+
req
|
|
241
|
+
)
|
|
242
|
+
} catch {
|
|
243
|
+
return addCors(
|
|
244
|
+
Response.json({ error: "Error al sintetizar con Piper" }, { status: 503 }),
|
|
245
|
+
req
|
|
246
|
+
)
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// ─── Gestión de modelos ──────────────────────────────────────────────────────
|
|
251
|
+
|
|
252
|
+
export async function handleGetAvailableModels(
|
|
253
|
+
req: Request,
|
|
254
|
+
addCors: (r: Response, req: Request) => Response
|
|
255
|
+
): Promise<Response> {
|
|
256
|
+
const installedVoices = getInstalledVoices()
|
|
257
|
+
const modelsWithStatus = TTS_MODELS.map((model) => ({
|
|
258
|
+
...model,
|
|
259
|
+
installed: installedVoices.includes(model.id),
|
|
260
|
+
}))
|
|
261
|
+
return addCors(Response.json({ models: modelsWithStatus }), req)
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
export async function handleGetInstalledVoices(
|
|
265
|
+
req: Request,
|
|
266
|
+
addCors: (r: Response, req: Request) => Response
|
|
267
|
+
): Promise<Response> {
|
|
268
|
+
const voices = getInstalledVoices().map((id) => {
|
|
269
|
+
const model = getModelById(id)
|
|
270
|
+
|
|
271
|
+
// Leer configuración de inferencia del modelo
|
|
272
|
+
let inferenceConfig = { length_scale: 1, noise_scale: 0.667, noise_w: 0.8 }
|
|
273
|
+
const configPath = join(VOICES_DIR, `${id}.onnx.json`)
|
|
274
|
+
if (existsSync(configPath)) {
|
|
275
|
+
try {
|
|
276
|
+
const config = JSON.parse(readFileSync(configPath, "utf-8"))
|
|
277
|
+
inferenceConfig = { ...inferenceConfig, ...config.inference }
|
|
278
|
+
} catch {
|
|
279
|
+
// Ignore
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
return {
|
|
284
|
+
id,
|
|
285
|
+
name: model?.name || id,
|
|
286
|
+
language: model?.language || "unknown",
|
|
287
|
+
inference: inferenceConfig,
|
|
288
|
+
}
|
|
289
|
+
})
|
|
290
|
+
return addCors(Response.json({ voices }), req)
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
export async function handleDownloadModel(
|
|
294
|
+
req: Request,
|
|
295
|
+
addCors: (r: Response, req: Request) => Response
|
|
296
|
+
): Promise<Response> {
|
|
297
|
+
let body: { modelId?: string }
|
|
298
|
+
try {
|
|
299
|
+
body = await req.json()
|
|
300
|
+
} catch {
|
|
301
|
+
return addCors(Response.json({ error: "Body JSON inválido" }, { status: 400 }), req)
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
const { modelId } = body
|
|
305
|
+
if (!modelId || typeof modelId !== "string") {
|
|
306
|
+
return addCors(Response.json({ error: "modelId requerido" }, { status: 400 }), req)
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
const model = getModelById(modelId)
|
|
310
|
+
if (!model) {
|
|
311
|
+
return addCors(Response.json({ error: `Modelo no encontrado: ${modelId}` }, { status: 404 }), req)
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
if (downloadingModelId) {
|
|
315
|
+
return addCors(
|
|
316
|
+
Response.json({
|
|
317
|
+
started: false,
|
|
318
|
+
reason: `Ya hay una descarga en curso: ${downloadingModelId}`
|
|
319
|
+
}, { status: 409 }),
|
|
320
|
+
req
|
|
321
|
+
)
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// Verificar si ya está instalado
|
|
325
|
+
const installedVoices = getInstalledVoices()
|
|
326
|
+
if (installedVoices.includes(modelId)) {
|
|
327
|
+
return addCors(
|
|
328
|
+
Response.json({ started: false, reason: "El modelo ya está instalado" }, { status: 409 }),
|
|
329
|
+
req
|
|
330
|
+
)
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
downloadingModelId = modelId
|
|
334
|
+
downloadLogs = [`[${new Date().toISOString()}] Iniciando descarga de ${model.name}...`]
|
|
335
|
+
|
|
336
|
+
// Ejecutar descarga en background
|
|
337
|
+
;(async () => {
|
|
338
|
+
try {
|
|
339
|
+
const modelDest = join(VOICES_DIR, `${modelId}.onnx`)
|
|
340
|
+
const configDest = join(VOICES_DIR, `${modelId}.onnx.json`)
|
|
341
|
+
|
|
342
|
+
downloadLogs.push(` Descargando modelo: ${model.size}`)
|
|
343
|
+
downloadLogs.push(` URL: ${model.modelUrl}`)
|
|
344
|
+
|
|
345
|
+
// Descargar modelo
|
|
346
|
+
const modelRes = await fetch(model.modelUrl)
|
|
347
|
+
if (!modelRes.ok) {
|
|
348
|
+
throw new Error(`HTTP ${modelRes.status} al descargar modelo`)
|
|
349
|
+
}
|
|
350
|
+
const modelBuf = await modelRes.arrayBuffer()
|
|
351
|
+
await Bun.write(modelDest, modelBuf)
|
|
352
|
+
downloadLogs.push(` ✓ Modelo descargado (${(modelBuf.byteLength / 1024 / 1024).toFixed(1)} MB)`)
|
|
353
|
+
|
|
354
|
+
// Descargar config
|
|
355
|
+
downloadLogs.push(` Descargando configuración...`)
|
|
356
|
+
const configRes = await fetch(model.configUrl)
|
|
357
|
+
if (!configRes.ok) {
|
|
358
|
+
throw new Error(`HTTP ${configRes.status} al descargar config`)
|
|
359
|
+
}
|
|
360
|
+
const configBuf = await configRes.arrayBuffer()
|
|
361
|
+
await Bun.write(configDest, configBuf)
|
|
362
|
+
downloadLogs.push(` ✓ Configuración descargada`)
|
|
363
|
+
|
|
364
|
+
downloadLogs.push(`[${new Date().toISOString()}] ${model.name} instalado exitosamente`)
|
|
365
|
+
} catch (err) {
|
|
366
|
+
downloadLogs.push(`[error] ${err instanceof Error ? err.message : String(err)}`)
|
|
367
|
+
console.error(`[hive-tts download] Error:`, err)
|
|
368
|
+
} finally {
|
|
369
|
+
downloadingModelId = null
|
|
370
|
+
}
|
|
371
|
+
})()
|
|
372
|
+
|
|
373
|
+
return addCors(Response.json({ started: true, modelId }), req)
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
export async function handleGetDownloadLogs(
|
|
377
|
+
req: Request,
|
|
378
|
+
addCors: (r: Response, req: Request) => Response
|
|
379
|
+
): Promise<Response> {
|
|
380
|
+
return addCors(
|
|
381
|
+
Response.json({
|
|
382
|
+
logs: downloadLogs,
|
|
383
|
+
downloading: downloadingModelId !== null,
|
|
384
|
+
currentModelId: downloadingModelId
|
|
385
|
+
}),
|
|
386
|
+
req
|
|
387
|
+
)
|
|
388
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { getDb } from "../../storage/sqlite"
|
|
2
|
+
|
|
3
|
+
export async function handleGetUsers(req: Request, addCorsHeaders: (r: Response, req: Request) => Response): Promise<Response> {
|
|
4
|
+
const users = getDb().query(`
|
|
5
|
+
SELECT u.*, COUNT(DISTINCT a.id) as agent_count
|
|
6
|
+
FROM users u
|
|
7
|
+
LEFT JOIN agents a ON u.id = a.user_id
|
|
8
|
+
GROUP BY u.id
|
|
9
|
+
ORDER BY u.created_at DESC
|
|
10
|
+
`).all() as Record<string, unknown>[]
|
|
11
|
+
|
|
12
|
+
return addCorsHeaders(Response.json({
|
|
13
|
+
users: users.map(u => ({
|
|
14
|
+
id: u.id,
|
|
15
|
+
name: u.name,
|
|
16
|
+
language: u.language,
|
|
17
|
+
timezone: u.timezone,
|
|
18
|
+
occupation: u.occupation,
|
|
19
|
+
notes: u.notes,
|
|
20
|
+
createdAt: new Date((u.created_at as number) * 1000).toISOString(),
|
|
21
|
+
agentCount: u.agent_count,
|
|
22
|
+
}))
|
|
23
|
+
}), req)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export async function handleCreateUser(req: Request, addCorsHeaders: (r: Response, req: Request) => Response): Promise<Response> {
|
|
27
|
+
const body = await req.json().catch(() => ({}))
|
|
28
|
+
|
|
29
|
+
const result = getDb().query(`
|
|
30
|
+
INSERT INTO users(name, language, timezone, occupation, notes)
|
|
31
|
+
VALUES(?, ?, ?, ?, ?)
|
|
32
|
+
RETURNING id
|
|
33
|
+
`).get(
|
|
34
|
+
body.name || "User",
|
|
35
|
+
body.language || "es",
|
|
36
|
+
body.timezone || "UTC",
|
|
37
|
+
body.occupation || "",
|
|
38
|
+
body.notes || ""
|
|
39
|
+
) as { id: string } | undefined
|
|
40
|
+
|
|
41
|
+
return addCorsHeaders(Response.json({
|
|
42
|
+
ok: true,
|
|
43
|
+
userId: result?.id
|
|
44
|
+
}), req)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export async function handleUpdateUserSettings(req: Request, addCorsHeaders: (r: Response, req: Request) => Response): Promise<Response> {
|
|
48
|
+
const url = new URL(req.url)
|
|
49
|
+
const userId = url.searchParams.get("userId") || "default"
|
|
50
|
+
const body = await req.json().catch(() => ({}))
|
|
51
|
+
|
|
52
|
+
const updates: string[] = []
|
|
53
|
+
const params: unknown[] = []
|
|
54
|
+
|
|
55
|
+
if (body.name !== undefined) {
|
|
56
|
+
updates.push("name = ?")
|
|
57
|
+
params.push(body.name)
|
|
58
|
+
}
|
|
59
|
+
if (body.language !== undefined) {
|
|
60
|
+
updates.push("language = ?")
|
|
61
|
+
params.push(body.language)
|
|
62
|
+
}
|
|
63
|
+
if (body.timezone !== undefined) {
|
|
64
|
+
updates.push("timezone = ?")
|
|
65
|
+
params.push(body.timezone)
|
|
66
|
+
}
|
|
67
|
+
if (body.occupation !== undefined) {
|
|
68
|
+
updates.push("occupation = ?")
|
|
69
|
+
params.push(body.occupation)
|
|
70
|
+
}
|
|
71
|
+
if (body.notes !== undefined) {
|
|
72
|
+
updates.push("notes = ?")
|
|
73
|
+
params.push(body.notes)
|
|
74
|
+
}
|
|
75
|
+
if (body.preferred_cron_channel !== undefined) {
|
|
76
|
+
updates.push("preferred_cron_channel = ?")
|
|
77
|
+
params.push(body.preferred_cron_channel)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (updates.length > 0) {
|
|
81
|
+
params.push(userId)
|
|
82
|
+
getDb().query(`UPDATE users SET ${updates.join(", ")} WHERE id = ?`).run(...params as any[])
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return addCorsHeaders(Response.json({ ok: true }), req)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export async function handleGetUserChannels(
|
|
89
|
+
req: Request,
|
|
90
|
+
addCorsHeaders: (r: Response, req: Request) => Response,
|
|
91
|
+
config?: any
|
|
92
|
+
): Promise<Response> {
|
|
93
|
+
return addCorsHeaders(Response.json({
|
|
94
|
+
user: config?.user || { id: "", name: "User", channels: {} },
|
|
95
|
+
}), req);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export async function handleLinkUserChannel(
|
|
99
|
+
req: Request,
|
|
100
|
+
addCorsHeaders: (r: Response, req: Request) => Response,
|
|
101
|
+
config?: any,
|
|
102
|
+
logger?: any
|
|
103
|
+
): Promise<Response> {
|
|
104
|
+
const body = await req.json().catch(() => ({}));
|
|
105
|
+
const { channel, channelUserId } = body;
|
|
106
|
+
|
|
107
|
+
if (!channel || !channelUserId) {
|
|
108
|
+
return addCorsHeaders(Response.json({ success: false, error: "Missing channel or channelUserId" }, { status: 400 }), req);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (config) {
|
|
112
|
+
config.user = config.user || { id: "", name: "User" };
|
|
113
|
+
config.user.channels = config.user.channels || {};
|
|
114
|
+
config.user.channels[channel] = channelUserId;
|
|
115
|
+
|
|
116
|
+
if (logger) {
|
|
117
|
+
logger.info(`Linked channel ${channel} to user ID ${channelUserId}`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return addCorsHeaders(Response.json({ success: true, channels: config?.user?.channels }), req);
|
|
122
|
+
}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { getDb } from "../../storage/sqlite"
|
|
2
|
+
import { voiceService } from "../../voice"
|
|
3
|
+
import { storeProviderApiKey, loadProviderApiKey } from "../../storage/crypto"
|
|
4
|
+
|
|
5
|
+
export async function handleGetVoiceProviders(req: Request, addCorsHeaders: (r: Response, req: Request) => Response): Promise<Response> {
|
|
6
|
+
return addCorsHeaders(Response.json({
|
|
7
|
+
providers: ["elevenlabs", "openai", "gemini", "qwen", "groq", "piper", "local-llama"]
|
|
8
|
+
}), req)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export async function handleGetConfiguredVoiceProviders(req: Request, addCorsHeaders: (r: Response, req: Request) => Response): Promise<Response> {
|
|
12
|
+
const voiceProviderIds = ["groq", "elevenlabs", "openai", "gemini", "qwen"]
|
|
13
|
+
const results = await Promise.all(voiceProviderIds.map(async id => ({
|
|
14
|
+
id,
|
|
15
|
+
configured: !!(await loadProviderApiKey(id))
|
|
16
|
+
})))
|
|
17
|
+
|
|
18
|
+
const providers: Record<string, boolean> = {}
|
|
19
|
+
for (const r of results) providers[r.id] = r.configured
|
|
20
|
+
providers.piper = true
|
|
21
|
+
providers["local-llama"] = true
|
|
22
|
+
|
|
23
|
+
return addCorsHeaders(Response.json(providers), req)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export async function handleSaveVoiceProviderKey(
|
|
27
|
+
req: Request,
|
|
28
|
+
addCorsHeaders: (r: Response, req: Request) => Response
|
|
29
|
+
): Promise<Response> {
|
|
30
|
+
const url = new URL(req.url)
|
|
31
|
+
const providerIdMatch = url.pathname.match(/^\/api\/voice\/providers\/([^/]+)\/key$/)
|
|
32
|
+
|
|
33
|
+
if (!providerIdMatch) {
|
|
34
|
+
return addCorsHeaders(Response.json({ success: false, error: "Invalid path" }, { status: 400 }), req)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const providerId = providerIdMatch[1]
|
|
38
|
+
const body = await req.json().catch(() => ({}))
|
|
39
|
+
const { apiKey } = body
|
|
40
|
+
|
|
41
|
+
if (!apiKey) {
|
|
42
|
+
return addCorsHeaders(Response.json({ success: false, error: "apiKey required" }, { status: 400 }), req)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
try {
|
|
46
|
+
const db = getDb()
|
|
47
|
+
|
|
48
|
+
// Get base URL for the provider
|
|
49
|
+
let baseUrl = ""
|
|
50
|
+
switch (providerId) {
|
|
51
|
+
case "groq": baseUrl = "https://api.groq.com/openai/v1"; break
|
|
52
|
+
case "elevenlabs": baseUrl = "https://api.elevenlabs.io/v1"; break
|
|
53
|
+
case "openai": baseUrl = "https://api.openai.com/v1"; break
|
|
54
|
+
case "gemini": baseUrl = "https://generativelanguage.googleapis.com/v1beta"; break
|
|
55
|
+
case "qwen": baseUrl = "https://dashscope.aliyuncs.com/compatible-mode/v1"; break
|
|
56
|
+
default:
|
|
57
|
+
return addCorsHeaders(Response.json({ success: false, error: "Unknown provider" }, { status: 400 }), req)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
db.query(`
|
|
61
|
+
INSERT OR REPLACE INTO providers (id, name, base_url, enabled, active)
|
|
62
|
+
VALUES (?, ?, ?, 1, 1)
|
|
63
|
+
`).run(providerId, providerId, baseUrl)
|
|
64
|
+
|
|
65
|
+
await storeProviderApiKey(providerId, apiKey)
|
|
66
|
+
|
|
67
|
+
return addCorsHeaders(Response.json({ success: true, provider: providerId }), req)
|
|
68
|
+
} catch (error) {
|
|
69
|
+
return addCorsHeaders(Response.json(
|
|
70
|
+
{ success: false, error: (error as Error).message },
|
|
71
|
+
{ status: 500 }
|
|
72
|
+
), req)
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export async function handleGetVoiceProviderVoices(
|
|
77
|
+
req: Request,
|
|
78
|
+
addCorsHeaders: (r: Response, req: Request) => Response,
|
|
79
|
+
providerId: string
|
|
80
|
+
): Promise<Response> {
|
|
81
|
+
try {
|
|
82
|
+
let voices: Array<{ id: string; name: string }>
|
|
83
|
+
|
|
84
|
+
switch (providerId) {
|
|
85
|
+
case "elevenlabs":
|
|
86
|
+
voices = await voiceService.getElevenLabsVoices()
|
|
87
|
+
break
|
|
88
|
+
case "openai":
|
|
89
|
+
voices = voiceService.getOpenAIVoices()
|
|
90
|
+
break
|
|
91
|
+
case "gemini":
|
|
92
|
+
voices = voiceService.getGeminiVoices()
|
|
93
|
+
break
|
|
94
|
+
case "qwen":
|
|
95
|
+
voices = voiceService.getQwenVoices()
|
|
96
|
+
break
|
|
97
|
+
case "piper": {
|
|
98
|
+
// Consultar voces disponibles en el servidor TTS local
|
|
99
|
+
const TTS_PORT = Number(process.env.TTS_PORT ?? 5500)
|
|
100
|
+
try {
|
|
101
|
+
const res = await fetch(`http://localhost:${TTS_PORT}/voices`, {
|
|
102
|
+
signal: AbortSignal.timeout(1000),
|
|
103
|
+
})
|
|
104
|
+
if (res.ok) {
|
|
105
|
+
const data = await res.json()
|
|
106
|
+
voices = (data.voices || []).map((v: string) => ({
|
|
107
|
+
id: v,
|
|
108
|
+
name: v.replace(/_/g, " ").replace(/-/g, " ").replace(/\b\w/g, c => c.toUpperCase()),
|
|
109
|
+
}))
|
|
110
|
+
} else {
|
|
111
|
+
voices = [{ id: "es_MX-claude-14947-epoch-high", name: "Piper Local (Claude Spanish)" }]
|
|
112
|
+
}
|
|
113
|
+
} catch {
|
|
114
|
+
// Servidor TTS no disponible - usar fallback para permitir selección
|
|
115
|
+
voices = [{ id: "es_MX-claude-14947-epoch-high", name: "Piper Local (Claude Spanish)" }]
|
|
116
|
+
}
|
|
117
|
+
break
|
|
118
|
+
}
|
|
119
|
+
default:
|
|
120
|
+
return addCorsHeaders(Response.json({ voices: [] }), req)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return addCorsHeaders(Response.json({ voices }), req)
|
|
124
|
+
} catch (error) {
|
|
125
|
+
return addCorsHeaders(Response.json(
|
|
126
|
+
{ voices: [], error: (error as Error).message },
|
|
127
|
+
{ status: 200 }
|
|
128
|
+
), req)
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export async function handleTestVoice(req: Request, addCorsHeaders: (r: Response, req: Request) => Response): Promise<Response> {
|
|
133
|
+
const body = await req.json().catch(() => ({}))
|
|
134
|
+
const { text, provider, voiceId } = body
|
|
135
|
+
|
|
136
|
+
if (!text || !provider) {
|
|
137
|
+
return addCorsHeaders(Response.json({ success: false, error: "text and provider required" }), req)
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return addCorsHeaders(Response.json({ success: true, message: "Voice test placeholder" }), req)
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export async function handleGetChannelVoice(
|
|
144
|
+
req: Request,
|
|
145
|
+
addCorsHeaders: (r: Response, req: Request) => Response,
|
|
146
|
+
channelId: string
|
|
147
|
+
): Promise<Response> {
|
|
148
|
+
const voiceConfig = voiceService.getChannelVoiceConfig(channelId)
|
|
149
|
+
return addCorsHeaders(Response.json(voiceConfig), req)
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export async function handleUpdateChannelVoice(
|
|
153
|
+
req: Request,
|
|
154
|
+
addCorsHeaders: (r: Response, req: Request) => Response,
|
|
155
|
+
channelId: string
|
|
156
|
+
): Promise<Response> {
|
|
157
|
+
const body = await req.json().catch(() => ({}))
|
|
158
|
+
const db = getDb()
|
|
159
|
+
const updates: string[] = []
|
|
160
|
+
const params: unknown[] = []
|
|
161
|
+
|
|
162
|
+
if (body.voiceEnabled !== undefined) {
|
|
163
|
+
updates.push("voice_enabled = ?")
|
|
164
|
+
params.push(body.voiceEnabled ? 1 : 0)
|
|
165
|
+
}
|
|
166
|
+
if (body.ttsEnabled !== undefined) {
|
|
167
|
+
updates.push("tts_enabled = ?")
|
|
168
|
+
params.push(body.ttsEnabled ? 1 : 0)
|
|
169
|
+
}
|
|
170
|
+
if (body.sttProvider !== undefined) {
|
|
171
|
+
updates.push("stt_provider = ?")
|
|
172
|
+
params.push(body.sttProvider)
|
|
173
|
+
}
|
|
174
|
+
if (body.ttsProvider !== undefined) {
|
|
175
|
+
updates.push("tts_provider = ?")
|
|
176
|
+
params.push(body.ttsProvider)
|
|
177
|
+
}
|
|
178
|
+
if (body.ttsVoiceId !== undefined) {
|
|
179
|
+
updates.push("tts_voice_id = ?")
|
|
180
|
+
params.push(body.ttsVoiceId)
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if (updates.length > 0) {
|
|
184
|
+
params.push(channelId)
|
|
185
|
+
db.query(`UPDATE channels SET ${updates.join(", ")} WHERE id = ?`).run(...params as any[])
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
return addCorsHeaders(Response.json({ success: true }), req)
|
|
189
|
+
}
|