@johpaz/hive 1.7.2 → 1.7.3
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 +178 -36
- package/dist/hive.js +315124 -0
- package/package.json +11 -3
- package/packages/core/src/index.ts +0 -1
- package/.dockerignore +0 -9
- package/CONTRIBUTING.md +0 -44
- package/Dockerfile +0 -67
- package/docker-compose.yml +0 -19
- package/packages/cli/package.json +0 -28
- package/packages/cli/src/commands/agent-run.ts +0 -168
- package/packages/cli/src/commands/agents.ts +0 -398
- package/packages/cli/src/commands/chat.ts +0 -142
- package/packages/cli/src/commands/config.ts +0 -50
- package/packages/cli/src/commands/cron.ts +0 -161
- package/packages/cli/src/commands/dev.ts +0 -95
- package/packages/cli/src/commands/doctor.ts +0 -133
- package/packages/cli/src/commands/gateway.ts +0 -422
- package/packages/cli/src/commands/logs.ts +0 -57
- package/packages/cli/src/commands/mcp.ts +0 -175
- package/packages/cli/src/commands/message.ts +0 -77
- package/packages/cli/src/commands/onboard.ts +0 -1696
- package/packages/cli/src/commands/security.ts +0 -144
- package/packages/cli/src/commands/service.ts +0 -50
- package/packages/cli/src/commands/sessions.ts +0 -116
- package/packages/cli/src/commands/skills.ts +0 -187
- package/packages/cli/src/commands/update.ts +0 -25
- package/packages/cli/src/index.ts +0 -190
- package/packages/cli/src/utils/token.ts +0 -6
- package/packages/code-bridge/README.md +0 -78
- package/packages/code-bridge/package.json +0 -18
- package/packages/code-bridge/src/index.ts +0 -95
- package/packages/code-bridge/src/process-manager.ts +0 -212
- package/packages/code-bridge/src/schemas.ts +0 -133
- package/packages/core/package.json +0 -55
- package/packages/core/src/agent/agent-loop.ts +0 -520
- package/packages/core/src/agent/compaction.ts +0 -183
- package/packages/core/src/agent/context-compiler.ts +0 -544
- package/packages/core/src/agent/context-guard.ts +0 -91
- package/packages/core/src/agent/conversation-store.ts +0 -193
- package/packages/core/src/agent/curator.ts +0 -158
- package/packages/core/src/agent/hooks.ts +0 -166
- package/packages/core/src/agent/llm-client.ts +0 -503
- package/packages/core/src/agent/native-tools.ts +0 -31
- package/packages/core/src/agent/playbook-selector.ts +0 -143
- package/packages/core/src/agent/prompt-builder.ts +0 -167
- package/packages/core/src/agent/providers/index.ts +0 -186
- package/packages/core/src/agent/providers.ts +0 -1
- package/packages/core/src/agent/reflector.ts +0 -200
- package/packages/core/src/agent/service.ts +0 -266
- package/packages/core/src/agent/skill-selector.ts +0 -413
- package/packages/core/src/agent/stuck-loop.ts +0 -133
- package/packages/core/src/agent/tool-selector.ts +0 -623
- package/packages/core/src/agent/tracer.ts +0 -102
- package/packages/core/src/canvas/canvas-manager.ts +0 -319
- package/packages/core/src/canvas/canvas-tools.ts +0 -420
- package/packages/core/src/canvas/emitter.ts +0 -119
- package/packages/core/src/canvas/index.ts +0 -2
- package/packages/core/src/channels/base.ts +0 -140
- package/packages/core/src/channels/discord.ts +0 -260
- package/packages/core/src/channels/index.ts +0 -7
- package/packages/core/src/channels/manager.ts +0 -383
- package/packages/core/src/channels/slack.ts +0 -287
- package/packages/core/src/channels/telegram.ts +0 -552
- package/packages/core/src/channels/webchat.ts +0 -139
- package/packages/core/src/channels/whatsapp.ts +0 -375
- package/packages/core/src/config/index.ts +0 -12
- package/packages/core/src/config/loader.ts +0 -529
- package/packages/core/src/events/agent-bus.ts +0 -460
- package/packages/core/src/events/event-bus.ts +0 -169
- package/packages/core/src/gateway/helpers/cors.ts +0 -32
- package/packages/core/src/gateway/helpers/index.ts +0 -4
- package/packages/core/src/gateway/helpers/narration.ts +0 -60
- package/packages/core/src/gateway/helpers/path.ts +0 -13
- package/packages/core/src/gateway/helpers/redact.ts +0 -61
- package/packages/core/src/gateway/index.ts +0 -5
- package/packages/core/src/gateway/initializer.ts +0 -332
- package/packages/core/src/gateway/lane-queue.ts +0 -169
- package/packages/core/src/gateway/resolver.ts +0 -108
- package/packages/core/src/gateway/router.ts +0 -124
- package/packages/core/src/gateway/routes/agents.ts +0 -187
- package/packages/core/src/gateway/routes/channels.ts +0 -203
- package/packages/core/src/gateway/routes/chat.ts +0 -241
- package/packages/core/src/gateway/routes/config.ts +0 -12
- package/packages/core/src/gateway/routes/cron.ts +0 -42
- package/packages/core/src/gateway/routes/ethics.ts +0 -46
- package/packages/core/src/gateway/routes/mcp.ts +0 -346
- package/packages/core/src/gateway/routes/models.ts +0 -93
- package/packages/core/src/gateway/routes/projects.ts +0 -179
- package/packages/core/src/gateway/routes/providers.ts +0 -192
- package/packages/core/src/gateway/routes/setup.ts +0 -267
- package/packages/core/src/gateway/routes/skills.ts +0 -70
- package/packages/core/src/gateway/routes/system.ts +0 -165
- package/packages/core/src/gateway/routes/tasks.ts +0 -44
- package/packages/core/src/gateway/routes/tools.ts +0 -35
- package/packages/core/src/gateway/routes/users.ts +0 -118
- package/packages/core/src/gateway/routes/voice.ts +0 -73
- package/packages/core/src/gateway/routes/workspace.ts +0 -281
- package/packages/core/src/gateway/server.ts +0 -1978
- package/packages/core/src/gateway/session.ts +0 -95
- package/packages/core/src/gateway/slash-commands.ts +0 -193
- package/packages/core/src/heartbeat/index.ts +0 -157
- package/packages/core/src/mcp/hot-reload.ts +0 -213
- package/packages/core/src/mcp/singleton.ts +0 -21
- package/packages/core/src/memory/index.ts +0 -1
- package/packages/core/src/memory/notes.ts +0 -68
- package/packages/core/src/plugins/api.ts +0 -128
- package/packages/core/src/plugins/index.ts +0 -2
- package/packages/core/src/plugins/loader.ts +0 -365
- package/packages/core/src/resilience/circuit-breaker.ts +0 -225
- package/packages/core/src/security/google-chat.ts +0 -269
- package/packages/core/src/security/index.ts +0 -192
- package/packages/core/src/security/pairing.ts +0 -250
- package/packages/core/src/security/rate-limit.ts +0 -270
- package/packages/core/src/security/signal.ts +0 -321
- package/packages/core/src/state/store.ts +0 -312
- package/packages/core/src/storage/crypto.ts +0 -101
- package/packages/core/src/storage/onboarding.ts +0 -1609
- package/packages/core/src/storage/schema.ts +0 -567
- package/packages/core/src/storage/seed.ts +0 -608
- package/packages/core/src/storage/sqlite.ts +0 -363
- package/packages/core/src/storage/usage.ts +0 -270
- package/packages/core/src/tools/agents/index.ts +0 -607
- package/packages/core/src/tools/bridge-events.ts +0 -26
- package/packages/core/src/tools/canvas/index.ts +0 -281
- package/packages/core/src/tools/cli/index.ts +0 -142
- package/packages/core/src/tools/codebridge/index.ts +0 -179
- package/packages/core/src/tools/core/index.ts +0 -257
- package/packages/core/src/tools/cron/index.ts +0 -373
- package/packages/core/src/tools/filesystem/fs-delete.ts +0 -78
- package/packages/core/src/tools/filesystem/fs-edit.ts +0 -106
- package/packages/core/src/tools/filesystem/fs-exists.ts +0 -63
- package/packages/core/src/tools/filesystem/fs-glob.ts +0 -108
- package/packages/core/src/tools/filesystem/fs-list.ts +0 -129
- package/packages/core/src/tools/filesystem/fs-read.ts +0 -72
- package/packages/core/src/tools/filesystem/fs-write.ts +0 -67
- package/packages/core/src/tools/filesystem/index.ts +0 -34
- package/packages/core/src/tools/filesystem/workspace-guard.ts +0 -62
- package/packages/core/src/tools/index.ts +0 -197
- package/packages/core/src/tools/projects/index.ts +0 -37
- package/packages/core/src/tools/projects/project-create.ts +0 -94
- package/packages/core/src/tools/projects/project-done.ts +0 -66
- package/packages/core/src/tools/projects/project-fail.ts +0 -66
- package/packages/core/src/tools/projects/project-list.ts +0 -96
- package/packages/core/src/tools/projects/project-update.ts +0 -72
- package/packages/core/src/tools/projects/task-create.ts +0 -68
- package/packages/core/src/tools/projects/task-evaluate.ts +0 -93
- package/packages/core/src/tools/projects/task-update.ts +0 -93
- package/packages/core/src/tools/search-knowledge/search-knowledge.ts +0 -155
- package/packages/core/src/tools/types.ts +0 -39
- package/packages/core/src/tools/voice/index.ts +0 -104
- package/packages/core/src/tools/web/browser-click.ts +0 -54
- package/packages/core/src/tools/web/browser-navigate.ts +0 -84
- package/packages/core/src/tools/web/browser-screenshot.ts +0 -54
- package/packages/core/src/tools/web/browser-type.ts +0 -60
- package/packages/core/src/tools/web/index.ts +0 -31
- package/packages/core/src/tools/web/web-fetch.ts +0 -78
- package/packages/core/src/tools/web/web-search.ts +0 -123
- package/packages/core/src/utils/benchmark.ts +0 -80
- package/packages/core/src/utils/crypto.ts +0 -73
- package/packages/core/src/utils/date.ts +0 -42
- package/packages/core/src/utils/index.ts +0 -5
- package/packages/core/src/utils/logger.ts +0 -389
- package/packages/core/src/utils/retry.ts +0 -70
- package/packages/core/src/utils/toon.ts +0 -356
- package/packages/core/src/voice/index.ts +0 -583
- package/packages/hive-ui/README.md +0 -52
- package/packages/hive-ui/components.json +0 -20
- package/packages/hive-ui/index.html +0 -30
- package/packages/hive-ui/package.json +0 -90
- package/packages/hive-ui/public/favicon.ico +0 -0
- package/packages/hive-ui/public/placeholder.svg +0 -1
- package/packages/hive-ui/src/App.tsx +0 -115
- package/packages/hive-ui/src/components/CronJobsPanel.tsx +0 -200
- package/packages/hive-ui/src/components/NavLink.tsx +0 -34
- package/packages/hive-ui/src/components/NotesPanel.tsx +0 -79
- package/packages/hive-ui/src/components/SystemMonitor.tsx +0 -270
- package/packages/hive-ui/src/components/UsageStatsPanel.tsx +0 -334
- package/packages/hive-ui/src/components/WelcomeDialog.tsx +0 -279
- package/packages/hive-ui/src/components/ui/accordion.tsx +0 -52
- package/packages/hive-ui/src/components/ui/alert-dialog.tsx +0 -104
- package/packages/hive-ui/src/components/ui/alert.tsx +0 -45
- package/packages/hive-ui/src/components/ui/aspect-ratio.tsx +0 -5
- package/packages/hive-ui/src/components/ui/avatar.tsx +0 -38
- package/packages/hive-ui/src/components/ui/badge.tsx +0 -29
- package/packages/hive-ui/src/components/ui/bee-loader.tsx +0 -68
- package/packages/hive-ui/src/components/ui/breadcrumb.tsx +0 -90
- package/packages/hive-ui/src/components/ui/button.tsx +0 -47
- package/packages/hive-ui/src/components/ui/calendar.tsx +0 -54
- package/packages/hive-ui/src/components/ui/card.tsx +0 -45
- package/packages/hive-ui/src/components/ui/carousel.tsx +0 -224
- package/packages/hive-ui/src/components/ui/chart.tsx +0 -303
- package/packages/hive-ui/src/components/ui/checkbox.tsx +0 -26
- package/packages/hive-ui/src/components/ui/collapsible.tsx +0 -9
- package/packages/hive-ui/src/components/ui/command.tsx +0 -133
- package/packages/hive-ui/src/components/ui/context-menu.tsx +0 -178
- package/packages/hive-ui/src/components/ui/dialog.tsx +0 -95
- package/packages/hive-ui/src/components/ui/drawer.tsx +0 -87
- package/packages/hive-ui/src/components/ui/dropdown-menu.tsx +0 -179
- package/packages/hive-ui/src/components/ui/form.tsx +0 -129
- package/packages/hive-ui/src/components/ui/hover-card.tsx +0 -27
- package/packages/hive-ui/src/components/ui/input-otp.tsx +0 -61
- package/packages/hive-ui/src/components/ui/input.tsx +0 -22
- package/packages/hive-ui/src/components/ui/label.tsx +0 -17
- package/packages/hive-ui/src/components/ui/menubar.tsx +0 -207
- package/packages/hive-ui/src/components/ui/navigation-menu.tsx +0 -120
- package/packages/hive-ui/src/components/ui/pagination.tsx +0 -80
- package/packages/hive-ui/src/components/ui/popover.tsx +0 -29
- package/packages/hive-ui/src/components/ui/progress.tsx +0 -23
- package/packages/hive-ui/src/components/ui/radio-group.tsx +0 -36
- package/packages/hive-ui/src/components/ui/resizable.tsx +0 -37
- package/packages/hive-ui/src/components/ui/scroll-area.tsx +0 -38
- package/packages/hive-ui/src/components/ui/select.tsx +0 -143
- package/packages/hive-ui/src/components/ui/separator.tsx +0 -20
- package/packages/hive-ui/src/components/ui/sheet.tsx +0 -107
- package/packages/hive-ui/src/components/ui/sidebar.tsx +0 -636
- package/packages/hive-ui/src/components/ui/skeleton.tsx +0 -7
- package/packages/hive-ui/src/components/ui/slider.tsx +0 -23
- package/packages/hive-ui/src/components/ui/sonner.tsx +0 -27
- package/packages/hive-ui/src/components/ui/switch.tsx +0 -27
- package/packages/hive-ui/src/components/ui/table.tsx +0 -72
- package/packages/hive-ui/src/components/ui/tabs.tsx +0 -53
- package/packages/hive-ui/src/components/ui/textarea.tsx +0 -21
- package/packages/hive-ui/src/components/ui/toast.tsx +0 -111
- package/packages/hive-ui/src/components/ui/toaster.tsx +0 -24
- package/packages/hive-ui/src/components/ui/toggle-group.tsx +0 -49
- package/packages/hive-ui/src/components/ui/toggle.tsx +0 -37
- package/packages/hive-ui/src/components/ui/tooltip.tsx +0 -28
- package/packages/hive-ui/src/components/ui/use-toast.ts +0 -3
- package/packages/hive-ui/src/hooks/use-mobile.tsx +0 -19
- package/packages/hive-ui/src/hooks/use-toast.ts +0 -186
- package/packages/hive-ui/src/hooks/useAgentConfig.ts +0 -25
- package/packages/hive-ui/src/hooks/useAgents.ts +0 -38
- package/packages/hive-ui/src/hooks/useBridge.ts +0 -38
- package/packages/hive-ui/src/hooks/useCanvas.ts +0 -24
- package/packages/hive-ui/src/hooks/useChannels.ts +0 -2
- package/packages/hive-ui/src/hooks/useEthics.ts +0 -51
- package/packages/hive-ui/src/hooks/useProviders.ts +0 -14
- package/packages/hive-ui/src/hooks/useTheme.ts +0 -29
- package/packages/hive-ui/src/hooks/useUserConfig.ts +0 -17
- package/packages/hive-ui/src/hooks/useWebSocket.ts +0 -12
- package/packages/hive-ui/src/index.css +0 -620
- package/packages/hive-ui/src/lib/api.ts +0 -100
- package/packages/hive-ui/src/lib/constants.ts +0 -6
- package/packages/hive-ui/src/lib/models.ts +0 -64
- package/packages/hive-ui/src/lib/swal.ts +0 -30
- package/packages/hive-ui/src/lib/utils.ts +0 -6
- package/packages/hive-ui/src/lib/websocket.ts +0 -7
- package/packages/hive-ui/src/main.tsx +0 -5
- package/packages/hive-ui/src/modules/agent-config/details/AgentDetailsEditor.tsx +0 -524
- package/packages/hive-ui/src/modules/agent-config/ethics/EthicsConflictDetector.tsx +0 -18
- package/packages/hive-ui/src/modules/agent-config/ethics/EthicsEditor.tsx +0 -19
- package/packages/hive-ui/src/modules/agent-config/ethics/EthicsRulesList.tsx +0 -36
- package/packages/hive-ui/src/modules/agent-config/ethics/EthicsTemplateGallery.tsx +0 -361
- package/packages/hive-ui/src/modules/agent-config/ethics/index.ts +0 -4
- package/packages/hive-ui/src/modules/agent-config/index.ts +0 -6
- package/packages/hive-ui/src/modules/agent-config/mcp/MCPServerAdd.tsx +0 -322
- package/packages/hive-ui/src/modules/agent-config/mcp/MCPServerCard.tsx +0 -93
- package/packages/hive-ui/src/modules/agent-config/mcp/MCPServerConfig.tsx +0 -427
- package/packages/hive-ui/src/modules/agent-config/mcp/MCPServerList.tsx +0 -85
- package/packages/hive-ui/src/modules/agent-config/mcp/MCPToolExplorer.tsx +0 -79
- package/packages/hive-ui/src/modules/agent-config/mcp/index.ts +0 -5
- package/packages/hive-ui/src/modules/agent-config/shared/ConfigEditorLayout.tsx +0 -30
- package/packages/hive-ui/src/modules/agent-config/shared/ConfigExporter.tsx +0 -26
- package/packages/hive-ui/src/modules/agent-config/shared/ConfigImporter.tsx +0 -25
- package/packages/hive-ui/src/modules/agent-config/shared/DiffViewer.tsx +0 -31
- package/packages/hive-ui/src/modules/agent-config/shared/MarkdownEditor.tsx +0 -32
- package/packages/hive-ui/src/modules/agent-config/shared/SaveStatusIndicator.tsx +0 -23
- package/packages/hive-ui/src/modules/agent-config/shared/ValidationPanel.tsx +0 -36
- package/packages/hive-ui/src/modules/agent-config/shared/index.ts +0 -7
- package/packages/hive-ui/src/modules/agent-config/skills/SkillCard.tsx +0 -81
- package/packages/hive-ui/src/modules/agent-config/skills/SkillConfigEditor.tsx +0 -22
- package/packages/hive-ui/src/modules/agent-config/skills/SkillCreator.tsx +0 -60
- package/packages/hive-ui/src/modules/agent-config/skills/SkillInstaller.tsx +0 -23
- package/packages/hive-ui/src/modules/agent-config/skills/SkillList.tsx +0 -72
- package/packages/hive-ui/src/modules/agent-config/skills/SkillsTab.tsx +0 -202
- package/packages/hive-ui/src/modules/agent-config/skills/index.ts +0 -5
- package/packages/hive-ui/src/modules/agent-config/tools/ToolCard.tsx +0 -27
- package/packages/hive-ui/src/modules/agent-config/tools/ToolConfigPanel.tsx +0 -22
- package/packages/hive-ui/src/modules/agent-config/tools/ToolManager.tsx +0 -266
- package/packages/hive-ui/src/modules/agent-config/tools/ToolPermissions.tsx +0 -287
- package/packages/hive-ui/src/modules/agent-config/tools/ToolRegistry.tsx +0 -84
- package/packages/hive-ui/src/modules/agent-config/tools/ToolUsageStats.tsx +0 -52
- package/packages/hive-ui/src/modules/agent-config/tools/index.ts +0 -4
- package/packages/hive-ui/src/modules/agent-config/user/ActiveAgentsList.tsx +0 -109
- package/packages/hive-ui/src/modules/agent-config/user/GlobalConfigOverview.tsx +0 -119
- package/packages/hive-ui/src/modules/agent-config/user/UserMemoryManager.tsx +0 -54
- package/packages/hive-ui/src/modules/agent-config/user/UserPreferencesForm.tsx +0 -163
- package/packages/hive-ui/src/modules/agent-config/user/UserProfileEditor.tsx +0 -261
- package/packages/hive-ui/src/modules/agent-config/user/index.ts +0 -3
- package/packages/hive-ui/src/modules/agents/AgentActivityLog.tsx +0 -25
- package/packages/hive-ui/src/modules/agents/AgentCard.tsx +0 -305
- package/packages/hive-ui/src/modules/agents/AgentCreateForm.tsx +0 -446
- package/packages/hive-ui/src/modules/agents/AgentDetail.tsx +0 -28
- package/packages/hive-ui/src/modules/agents/AgentInternalCard.tsx +0 -162
- package/packages/hive-ui/src/modules/agents/AgentList.tsx +0 -29
- package/packages/hive-ui/src/modules/agents/AgentStatusBadge.tsx +0 -34
- package/packages/hive-ui/src/modules/agents/ModelSelector.tsx +0 -151
- package/packages/hive-ui/src/modules/bridge/BridgeLogViewer.tsx +0 -61
- package/packages/hive-ui/src/modules/bridge/BridgeProcessList.tsx +0 -77
- package/packages/hive-ui/src/modules/bridge/BridgeStatus.tsx +0 -23
- package/packages/hive-ui/src/modules/bridge/BridgeTerminal.tsx +0 -7
- package/packages/hive-ui/src/modules/canvas/CanvasButton.tsx +0 -3
- package/packages/hive-ui/src/modules/canvas/CanvasChart.tsx +0 -3
- package/packages/hive-ui/src/modules/canvas/CanvasComponentMap.tsx +0 -605
- package/packages/hive-ui/src/modules/canvas/CanvasContainer.tsx +0 -360
- package/packages/hive-ui/src/modules/canvas/CanvasForm.tsx +0 -3
- package/packages/hive-ui/src/modules/canvas/CanvasMarkdown.tsx +0 -3
- package/packages/hive-ui/src/modules/canvas/CanvasTable.tsx +0 -3
- package/packages/hive-ui/src/modules/canvas/ComponentRenderer.tsx +0 -30
- package/packages/hive-ui/src/modules/canvas/DynamicRenderer.tsx +0 -3
- package/packages/hive-ui/src/modules/channels/available/AvailableChannelsGrid.tsx +0 -89
- package/packages/hive-ui/src/modules/channels/available/ChannelAuthForm.tsx +0 -33
- package/packages/hive-ui/src/modules/channels/available/ChannelSetupWizard.tsx +0 -48
- package/packages/hive-ui/src/modules/channels/available/ChannelTestConnection.tsx +0 -37
- package/packages/hive-ui/src/modules/channels/available/ChannelTypeCard.tsx +0 -30
- package/packages/hive-ui/src/modules/channels/available/ChannelWebhookConfig.tsx +0 -30
- package/packages/hive-ui/src/modules/channels/available/index.ts +0 -6
- package/packages/hive-ui/src/modules/channels/connected/ChannelCard.tsx +0 -95
- package/packages/hive-ui/src/modules/channels/connected/ChannelConfigPanel.tsx +0 -260
- package/packages/hive-ui/src/modules/channels/connected/ChannelDisconnectButton.tsx +0 -21
- package/packages/hive-ui/src/modules/channels/connected/ChannelLogsViewer.tsx +0 -42
- package/packages/hive-ui/src/modules/channels/connected/ChannelQRCode.tsx +0 -32
- package/packages/hive-ui/src/modules/channels/connected/ChannelReconnectButton.tsx +0 -16
- package/packages/hive-ui/src/modules/channels/connected/ChannelStatusBadge.tsx +0 -26
- package/packages/hive-ui/src/modules/channels/connected/ConnectedChannelsList.tsx +0 -40
- package/packages/hive-ui/src/modules/channels/connected/index.ts +0 -8
- package/packages/hive-ui/src/modules/channels/shared/ChannelCard.tsx +0 -84
- package/packages/hive-ui/src/modules/channels/shared/ChannelConfigDialog.tsx +0 -279
- package/packages/hive-ui/src/modules/channels/shared/ChannelIcon.tsx +0 -40
- package/packages/hive-ui/src/modules/channels/shared/ChannelStats.tsx +0 -37
- package/packages/hive-ui/src/modules/channels/shared/ChannelTypeBadge.tsx +0 -23
- package/packages/hive-ui/src/modules/channels/shared/ConnectionHealthIndicator.tsx +0 -20
- package/packages/hive-ui/src/modules/channels/shared/MessagePreview.tsx +0 -19
- package/packages/hive-ui/src/modules/channels/shared/index.ts +0 -5
- package/packages/hive-ui/src/modules/chat/ChatContainer.tsx +0 -268
- package/packages/hive-ui/src/modules/chat/ChatHistory.tsx +0 -101
- package/packages/hive-ui/src/modules/chat/ChatInput.tsx +0 -108
- package/packages/hive-ui/src/modules/chat/ChatMessage.tsx +0 -137
- package/packages/hive-ui/src/modules/chat/ThinkingIndicator.tsx +0 -10
- package/packages/hive-ui/src/modules/layout/AppLayout.tsx +0 -45
- package/packages/hive-ui/src/modules/layout/ConnectionStatus.tsx +0 -19
- package/packages/hive-ui/src/modules/layout/Header.tsx +0 -20
- package/packages/hive-ui/src/modules/layout/HiveSidebar.tsx +0 -173
- package/packages/hive-ui/src/modules/layout/ThemeToggle.tsx +0 -18
- package/packages/hive-ui/src/modules/providers/ProviderCard.tsx +0 -319
- package/packages/hive-ui/src/modules/providers/ProviderConfigForm.tsx +0 -146
- package/packages/hive-ui/src/modules/providers/ProviderFailoverConfig.tsx +0 -110
- package/packages/hive-ui/src/modules/providers/ProviderList.tsx +0 -33
- package/packages/hive-ui/src/modules/providers/ProviderStatusIndicator.tsx +0 -23
- package/packages/hive-ui/src/modules/providers/configs/ProviderAPIKeyManager.tsx +0 -39
- package/packages/hive-ui/src/modules/providers/configs/ProviderEndpointConfig.tsx +0 -27
- package/packages/hive-ui/src/modules/providers/configs/ProviderRateLimits.tsx +0 -37
- package/packages/hive-ui/src/modules/providers/configs/ProviderRetryPolicy.tsx +0 -46
- package/packages/hive-ui/src/modules/providers/configs/index.ts +0 -4
- package/packages/hive-ui/src/modules/providers/index.ts +0 -5
- package/packages/hive-ui/src/modules/providers/models/ModelBenchmarkBadge.tsx +0 -21
- package/packages/hive-ui/src/modules/providers/models/ModelCapabilities.tsx +0 -44
- package/packages/hive-ui/src/modules/providers/models/ModelCard.tsx +0 -36
- package/packages/hive-ui/src/modules/providers/models/ModelComparisonTable.tsx +0 -47
- package/packages/hive-ui/src/modules/providers/models/ModelList.tsx +0 -51
- package/packages/hive-ui/src/modules/providers/models/ModelPricingInfo.tsx +0 -17
- package/packages/hive-ui/src/modules/providers/models/ModelSelector.tsx +0 -32
- package/packages/hive-ui/src/modules/providers/models/index.ts +0 -7
- package/packages/hive-ui/src/pages/AgentDetailPage.tsx +0 -74
- package/packages/hive-ui/src/pages/AgentNewPage.tsx +0 -5
- package/packages/hive-ui/src/pages/AgentsPage.tsx +0 -147
- package/packages/hive-ui/src/pages/BridgePage.tsx +0 -83
- package/packages/hive-ui/src/pages/CanvasPage.tsx +0 -32
- package/packages/hive-ui/src/pages/ChannelsPage.tsx +0 -176
- package/packages/hive-ui/src/pages/DashboardPage.tsx +0 -321
- package/packages/hive-ui/src/pages/Index.tsx +0 -14
- package/packages/hive-ui/src/pages/LogsPage.tsx +0 -252
- package/packages/hive-ui/src/pages/NotFound.tsx +0 -24
- package/packages/hive-ui/src/pages/ProjectsPage.tsx +0 -241
- package/packages/hive-ui/src/pages/ProvidersPage.tsx +0 -111
- package/packages/hive-ui/src/pages/SettingsPage.tsx +0 -147
- package/packages/hive-ui/src/pages/SetupPage.tsx +0 -1177
- package/packages/hive-ui/src/pages/WebChatPage.tsx +0 -15
- package/packages/hive-ui/src/stores/agentConfigStore.ts +0 -32
- package/packages/hive-ui/src/stores/agentStore.ts +0 -5
- package/packages/hive-ui/src/stores/bridgeStore.ts +0 -237
- package/packages/hive-ui/src/stores/canvasStore.ts +0 -250
- package/packages/hive-ui/src/stores/channelStore.ts +0 -5
- package/packages/hive-ui/src/stores/chatStore.ts +0 -42
- package/packages/hive-ui/src/stores/ethicsStore.ts +0 -141
- package/packages/hive-ui/src/stores/mcpStore.ts +0 -5
- package/packages/hive-ui/src/stores/modelStore.ts +0 -2
- package/packages/hive-ui/src/stores/projectsStore.ts +0 -141
- package/packages/hive-ui/src/stores/providerStore.ts +0 -2
- package/packages/hive-ui/src/stores/skillStore.ts +0 -5
- package/packages/hive-ui/src/stores/toolStore.ts +0 -5
- package/packages/hive-ui/src/stores/useGlobalConfigStore.ts +0 -937
- package/packages/hive-ui/src/stores/useLoaderStore.ts +0 -21
- package/packages/hive-ui/src/stores/useNotesAndCronsStore.ts +0 -144
- package/packages/hive-ui/src/stores/useWebSocketStore.ts +0 -152
- package/packages/hive-ui/src/stores/useWelcomeStore.ts +0 -37
- package/packages/hive-ui/src/stores/userConfigStore.ts +0 -23
- package/packages/hive-ui/src/stores/userStore.ts +0 -82
- package/packages/hive-ui/src/test/setup.ts +0 -15
- package/packages/hive-ui/src/types/agent-config.ts +0 -33
- package/packages/hive-ui/src/types/agent.ts +0 -65
- package/packages/hive-ui/src/types/bridge.ts +0 -27
- package/packages/hive-ui/src/types/canvas.ts +0 -76
- package/packages/hive-ui/src/types/channels.ts +0 -109
- package/packages/hive-ui/src/types/chat.ts +0 -25
- package/packages/hive-ui/src/types/connections.ts +0 -17
- package/packages/hive-ui/src/types/ethics.ts +0 -41
- package/packages/hive-ui/src/types/index.ts +0 -15
- package/packages/hive-ui/src/types/mcp.ts +0 -36
- package/packages/hive-ui/src/types/notes-crons.ts +0 -31
- package/packages/hive-ui/src/types/providers.ts +0 -145
- package/packages/hive-ui/src/types/skill.ts +0 -12
- package/packages/hive-ui/src/types/tool.ts +0 -44
- package/packages/hive-ui/src/types/user.ts +0 -26
- package/packages/hive-ui/src/types/websocket.ts +0 -14
- package/packages/hive-ui/src/vite-env.d.ts +0 -1
- package/packages/mcp/package.json +0 -26
- package/packages/mcp/src/config.ts +0 -13
- package/packages/mcp/src/index.ts +0 -1
- package/packages/mcp/src/logger.ts +0 -42
- package/packages/mcp/src/manager.ts +0 -439
- package/packages/mcp/src/transports/index.ts +0 -67
- package/packages/mcp/src/transports/sse.ts +0 -241
- package/packages/mcp/src/transports/websocket.ts +0 -159
- package/packages/skills/package.json +0 -21
- package/packages/skills/src/index.ts +0 -1
- package/packages/skills/src/loader.ts +0 -346
|
@@ -1,1609 +0,0 @@
|
|
|
1
|
-
import { logger } from "../utils/logger.ts";
|
|
2
|
-
import { getDb, initializeDatabase } from "./sqlite";
|
|
3
|
-
import { encryptApiKey, encryptConfig, decryptApiKey, decryptConfig } from "./crypto";
|
|
4
|
-
import { seedAllData } from "./seed";
|
|
5
|
-
|
|
6
|
-
export interface OnboardingSection {
|
|
7
|
-
step: "user" | "skills" | "ethics" | "tools" | "provider" | "model" | "channel" | "codebridge" | "mcp" | "agent" | "complete";
|
|
8
|
-
userId: string;
|
|
9
|
-
data: Record<string, unknown>;
|
|
10
|
-
completedAt?: number;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
const log = logger.child("onboarding");
|
|
14
|
-
// 9️⃣ Hive System Prompt
|
|
15
|
-
|
|
16
|
-
const HIVE_SYSTEM_PROMPT = `
|
|
17
|
-
HIVE — Sistema Operativo de Agentes IA
|
|
18
|
-
|
|
19
|
-
**Instrucciones de uso Critico**
|
|
20
|
-
###Siempre antes de guardar algo en la bd debes confirmar con el usuario que este correcto###
|
|
21
|
-
## Agente Coordinador Principal
|
|
22
|
-
|
|
23
|
-
Sos el agente coordinador principal de Hive.
|
|
24
|
-
Tu rol es entender las necesidades del usuario y resolverlas directamente o delegando a agentes workers especializados.
|
|
25
|
-
Tienes "role = 'coordinator'".
|
|
26
|
-
|
|
27
|
-
---
|
|
28
|
-
|
|
29
|
-
## 🧠 IDENTIDAD Y RESPONSABILIDADES
|
|
30
|
-
|
|
31
|
-
- Sos el punto de entrada único del usuario
|
|
32
|
-
- Resolvés tareas simples directamente con tus herramientas nativas
|
|
33
|
-
- Delegás tareas complejas, largas o especializadas a workers
|
|
34
|
-
- Mantenés contexto, memoria y seguimiento de proyectos activos
|
|
35
|
-
- Operás bajo un **Código de Ética obligatorio** — tus acciones deben respetarlo siempre
|
|
36
|
-
|
|
37
|
-
---
|
|
38
|
-
|
|
39
|
-
## 📋 FLUJO COMPLETO: PROYECTOS + AGENTES + CRON
|
|
40
|
-
|
|
41
|
-
Esta es la guía definitiva para decidir qué estrategia usar y cómo ejecutarla.
|
|
42
|
-
|
|
43
|
-
### 1️⃣ PRIMERO: Evaluá la complejidad de la tarea
|
|
44
|
-
|
|
45
|
-
**Tarea simple (1-2 pasos, la hacés vos solo):**
|
|
46
|
-
- Ejecutala directamente con tus tools nativas
|
|
47
|
-
- Ej: "buscá el precio de BTC", "enviá un mensaje a Juan"
|
|
48
|
-
- Si la tarea es de una sola acción, debes cerrarla
|
|
49
|
-
|
|
50
|
-
**Tarea repetitiva/programada (se ejecuta en horarios específicos, pregunta al usuario cuantas veces se debe ejecutar):**
|
|
51
|
-
- Usá \`cron_add\` — puede ser sin proyecto si la tarea es simple
|
|
52
|
-
- El cron puede ejecutar una acción directa O lanzar un worker
|
|
53
|
-
|
|
54
|
-
**Tarea compleja (múltiples pasos, múltiples workers, coordinación):**
|
|
55
|
-
- Creá un proyecto con \`project_create\`
|
|
56
|
-
- Descomponé en tareas atómicas
|
|
57
|
-
- Asigná agents/workers a cada tarea
|
|
58
|
-
- Opcional: vinculá el proyecto a un cron para ejecución programada
|
|
59
|
-
|
|
60
|
-
---
|
|
61
|
-
|
|
62
|
-
### 2️⃣ CREACIÓN DE PROYECTOS (solo cuando corresponde)
|
|
63
|
-
|
|
64
|
-
**Creá un proyecto ÚNICAMENTE cuando:**
|
|
65
|
-
- Hay **múltiples workers** coordinando en paralelo o secuencia
|
|
66
|
-
- Necesitás **trackear progreso** de varias subtareas independientes
|
|
67
|
-
- El trabajo tiene **etapas con dependencias** entre workers
|
|
68
|
-
- El usuario necesita **visibilidad estructurada** del avance
|
|
69
|
-
|
|
70
|
-
**NO creés proyecto para:**
|
|
71
|
-
- Tareas que hacés vos solo (coordinador)
|
|
72
|
-
- Una tarea cron simple, aunque sea recurrente
|
|
73
|
-
- Tareas que solo tardan mucho pero son unitarias
|
|
74
|
-
|
|
75
|
-
**Estructura de \"project_create\":**
|
|
76
|
-
json
|
|
77
|
-
{
|
|
78
|
-
"name": "Sistema de Growth Automatizado",
|
|
79
|
-
"description": "Automatizar búsqueda de tendencias, análisis de redes y generación de contenido",
|
|
80
|
-
"type": "code",
|
|
81
|
-
"tasks": [
|
|
82
|
-
{
|
|
83
|
-
"name": "Buscar tendencias diarias",
|
|
84
|
-
"description": "Buscar en web las tendencias de IA del día",
|
|
85
|
-
"agent_id": "researcher-agent" // ← ID del agent si YA existe
|
|
86
|
-
},
|
|
87
|
-
{
|
|
88
|
-
"name": "Analizar redes sociales",
|
|
89
|
-
"description": "Monitorear métricas de Twitter/X",
|
|
90
|
-
"agent_id": null // ← null si el agent aún no existe
|
|
91
|
-
}
|
|
92
|
-
]
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
**Orden correcto de operaciones:**
|
|
96
|
-
|
|
97
|
-
**Opcion A: Si los agents YA existen**
|
|
98
|
-
1. find_agent -> obtener IDs de agents existentes
|
|
99
|
-
2. project_create -> crear proyecto con tasks[].agent_id
|
|
100
|
-
3. (Opcional) cron_add -> vincular proyecto a cron
|
|
101
|
-
|
|
102
|
-
**Opcion B: Si los agents NO existen**
|
|
103
|
-
1. project_create -> crear proyecto con tasks (agent_id: null)
|
|
104
|
-
2. create_agent -> crear cada agent necesario
|
|
105
|
-
3. task_update -> asignar agent_id a cada tarea (ESTO ES CRITICO)
|
|
106
|
-
4. (Opcional) cron_add -> vincular proyecto a cron
|
|
107
|
-
|
|
108
|
-
> IMPORTANTE: Las tareas NO se ejecutan solas. Un agent debe recibir la instruccion de ejecutarlas. Para eso esta el **cron**.
|
|
109
|
-
|
|
110
|
-
---
|
|
111
|
-
|
|
112
|
-
### 4️⃣ CRON + PROYECTOS: Cómo vincular y activar
|
|
113
|
-
|
|
114
|
-
**El problema:** Creaste el proyecto, asignaste agents a las tareas... ¿pero quién ejecuta el proyecto?
|
|
115
|
-
|
|
116
|
-
**La solución:** Un cron que **active el proyecto** y le diga a un agent qué hacer.
|
|
117
|
-
|
|
118
|
-
**Paso 1: Crear el cron vinculado al proyecto**
|
|
119
|
-
json
|
|
120
|
-
{
|
|
121
|
-
"name": "Ejecutar Growth AI diario",
|
|
122
|
-
"expression": "0 7 * * *",
|
|
123
|
-
"projectId": "48ded8b948c346a9",
|
|
124
|
-
"taskMessage": "Soy el coordinador. Inicia el proyecto 'Sistema de Growth AI automatizado'. Ejecuta las 3 tareas en orden:\n1. ai_researcher -> Buscar tendencias de IA en la web\n2. social_media_writer -> Generar posts para redes\n3. email_manager -> Compilar y enviar email resumen\n\nReporta el resultado de cada tarea con task_update(status='completed', result=...). Al finalizar, ejecuta project_done con un resumen ejecutivo."
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
**Paso 2: Que pasa cuando el cron se ejecuta**
|
|
129
|
-
[7:00 AM] Cron trigger -> Proyecto se activa (status -> 'active')
|
|
130
|
-
[7:00 AM] Agente coordinador recibe el taskMessage
|
|
131
|
-
[7:01 AM] Coordinador delega a ai_researcher -> tarea 1
|
|
132
|
-
[7:05 AM] ai_researcher completa -> task_update(status='completed')
|
|
133
|
-
[7:06 AM] Coordinador delega a social_media_writer -> tarea 2
|
|
134
|
-
[7:10 AM] social_media_writer completa -> task_update(status='completed')
|
|
135
|
-
[7:11 AM] Coordinador delega a email_manager -> tarea 3
|
|
136
|
-
[7:15 AM] email_manager completa -> task_update(status='completed')
|
|
137
|
-
[7:16 AM] Coordinador -> project_done(summary='...')
|
|
138
|
-
[7:17 AM] Notificacion al usuario: "Proyecto completado. 3 tendencias encontradas, 5 posts generados, email enviado"
|
|
139
|
-
|
|
140
|
-
**Formato de expresion cron (5 campos):**
|
|
141
|
-
minuto (0-59)
|
|
142
|
-
hora (0-23)
|
|
143
|
-
dia del mes (1-31)
|
|
144
|
-
mes (1-12)
|
|
145
|
-
dia de la semana (0-6, 0=Domingo)
|
|
146
|
-
|
|
147
|
-
* * * * *
|
|
148
|
-
|
|
149
|
-
**Ejemplos:**
|
|
150
|
-
- "0 7 * * *" -> Todos los dias a las 7:00 AM
|
|
151
|
-
- "0 9 * * 1-5" -> Lunes a Viernes a las 9:00 AM
|
|
152
|
-
- "0 */2 * * *" -> Cada 2 horas
|
|
153
|
-
- "0 0 * * 0" -> Todos los Domingos a medianoche
|
|
154
|
-
|
|
155
|
-
TIP: El "taskMessage" del cron es CRITICO. Debe incluir:
|
|
156
|
-
- Que proyecto iniciar
|
|
157
|
-
- Que tareas ejecutar y en que orden
|
|
158
|
-
- Que agents usar (por nombre o ID)
|
|
159
|
-
- Como reportar resultados
|
|
160
|
-
- Que hacer al finalizar (project_done)
|
|
161
|
-
|
|
162
|
-
---
|
|
163
|
-
|
|
164
|
-
### 3. CREACIÓN DE AGENTS/WORKERS
|
|
165
|
-
|
|
166
|
-
**Flujo de delegación:**
|
|
167
|
-
find_agent -> ¿Existe un worker apto para esta tarea?
|
|
168
|
-
- SI -> Reutilizalo (ahorras recursos)
|
|
169
|
-
- NO -> Continuar
|
|
170
|
-
create_agent -> Crealo con configuración específica
|
|
171
|
-
|
|
172
|
-
**Cuando crear un worker:**
|
|
173
|
-
- Tareas largas con muchas iteraciones
|
|
174
|
-
- Tareas que pueden correr en paralelo
|
|
175
|
-
- Tareas que requieren herramientas específicas o aisladas
|
|
176
|
-
- Tareas especializadas (research, code, content, data analysis)
|
|
177
|
-
|
|
178
|
-
**Configuración de create_agent:**
|
|
179
|
-
json
|
|
180
|
-
{
|
|
181
|
-
"name": "researcher",
|
|
182
|
-
"description": "Especialista en busqueda web y verificacion de fuentes",
|
|
183
|
-
"system_prompt": "Sos un investigador experto. Tu rol es buscar informacion actualizada en la web, verificar fuentes y resumir hallazgos. Usa web_search con filtros de fecha cuando busques noticias recientes.",
|
|
184
|
-
"tools_json": ["web_search", "web_fetch", "save_note"],
|
|
185
|
-
"model_id": null,
|
|
186
|
-
"provider_id": null
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
**Reglas de agents:**
|
|
191
|
-
- Vos tenes role = 'coordinator', los workers tienen role = 'worker'
|
|
192
|
-
- No dupliques workers -- busca antes de crear
|
|
193
|
-
- Asigna solo las tools necesarias (minimo privilegio)
|
|
194
|
-
- El Curator archiva workers inactivos >14 dias automaticamente
|
|
195
|
-
|
|
196
|
-
---
|
|
197
|
-
|
|
198
|
-
### 5. EVALUACION Y CIERRE DE TAREAS
|
|
199
|
-
|
|
200
|
-
**Cuando un worker completa una tarea:**
|
|
201
|
-
|
|
202
|
-
1. **Actualiza el estado** inmediatamente:
|
|
203
|
-
json
|
|
204
|
-
{
|
|
205
|
-
"task_id": 42,
|
|
206
|
-
"status": "completed",
|
|
207
|
-
"progress": 100,
|
|
208
|
-
"result": "Resumen del resultado..."
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
2. **Opcional: evalua la calidad** con task_evaluate:
|
|
212
|
-
json
|
|
213
|
-
{
|
|
214
|
-
"task_id": 42,
|
|
215
|
-
"criteria": [
|
|
216
|
-
"El resultado contiene URLs validas",
|
|
217
|
-
"Minimo 5 fuentes verificadas",
|
|
218
|
-
"El formato es JSON valido"
|
|
219
|
-
],
|
|
220
|
-
"auto_update": true,
|
|
221
|
-
"evaluation_notes": "Revisado por coordinador"
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
3. **Si todas las tareas estan completas** -> project_done:
|
|
225
|
-
json
|
|
226
|
-
{
|
|
227
|
-
"projectId": "<id>",
|
|
228
|
-
"summary": "Proyecto completado exitosamente. Se generaron 3 reportes con 15 fuentes verificadas."
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
4. **Si una tarea falla**:
|
|
232
|
-
- Evalua si bloquea el proyecto
|
|
233
|
-
- Si bloquea -> project_fail con razon clara
|
|
234
|
-
- Si no bloquea -> reasigna o saltea la tarea
|
|
235
|
-
|
|
236
|
-
---
|
|
237
|
-
|
|
238
|
-
## ACTUALIZACION DE PROYECTO
|
|
239
|
-
|
|
240
|
-
Cuando un worker entrega su resultado o responde:
|
|
241
|
-
- **Actualiza inmediatamente** el estado de su tarea con task_update
|
|
242
|
-
- Si todas las tareas estan completas -> project_done
|
|
243
|
-
- Si una tarea falla -> evalua si bloquea el proyecto -> task_update + project_fail si corresponde
|
|
244
|
-
- Reporta al usuario el avance con report_progress o notify
|
|
245
|
-
|
|
246
|
-
---
|
|
247
|
-
|
|
248
|
-
## 🛠️ HERRAMIENTAS NATIVAS (52 tools)
|
|
249
|
-
|
|
250
|
-
Las 52 herramientas nativas se cargan dinámicamente desde la base de datos.
|
|
251
|
-
**Usá "search_knowledge" para descubrir herramientas por nombre o descripción.**
|
|
252
|
-
|
|
253
|
-
**Categorías disponibles:**
|
|
254
|
-
|
|
255
|
-
| Categoría | Tools | Ejemplos clave |
|
|
256
|
-
|-----------|-------|----------------|
|
|
257
|
-
| 📁 FILESYSTEM | 7 | fs_read, fs_write, fs_edit, fs_delete, fs_list, fs_glob, fs_exists |
|
|
258
|
-
| 🌐 WEB | 6 | web_search, web_fetch, browser_navigate, browser_screenshot, browser_click, browser_type |
|
|
259
|
-
| 📋 PROJECTS | 8 | project_create, project_list, task_create, task_update, project_done |
|
|
260
|
-
| ⏰ CRON | 4 | cron_add, cron_list, cron_edit, cron_remove |
|
|
261
|
-
| 💻 CLI | 1 | cli_exec |
|
|
262
|
-
| 🧠 AGENTS | 14 | memory_*, agent_*, task_delegate, bus_*, project_updates |
|
|
263
|
-
| 🎨 CANVAS | 7 | canvas_show_card, canvas_show_progress, canvas_ask, canvas_confirm |
|
|
264
|
-
| 🌉 CODEBRIDGE | 3 | codebridge_launch, codebridge_status, codebridge_cancel |
|
|
265
|
-
| 🎙️ VOICE | 2 | voice_transcribe, voice_speak |
|
|
266
|
-
| 🔔 CORE | 4 | search_knowledge, notify, save_note, report_progress |
|
|
267
|
-
|
|
268
|
-
**Reglas importantes:**
|
|
269
|
-
- ⚠️ NUNCA uses "cli_exec" para tareas cron — usá siempre "cron_*"
|
|
270
|
-
- 💡 Para proyectos programados, usá "projectId" en "cron_add"
|
|
271
|
-
- 🔍 Usá "search_knowledge({ query: "archivo", type: "tools" })" para encontrar tools
|
|
272
|
-
- 🔌 Las tools MCP siguen el formato: "{servidor}__{herramienta}" (ej. "github__create_pr")
|
|
273
|
-
|
|
274
|
-
---
|
|
275
|
-
|
|
276
|
-
## 🔌 SERVIDORES MCP (dinámicos)
|
|
277
|
-
|
|
278
|
-
Hive puede conectar servidores MCP externos que agregan herramientas adicionales al contexto.
|
|
279
|
-
- Las tools MCP siguen el formato: "{ servidor }__{ herramienta } " (ej. "github__create_pr", "filesystem__read_file")
|
|
280
|
-
- Aparecen automáticamente en tu loadout cuando el servidor está conectado
|
|
281
|
-
- Usá "search_knowledge" para descubrir qué herramientas MCP están disponibles en la sesión
|
|
282
|
-
|
|
283
|
-
---
|
|
284
|
-
|
|
285
|
-
## 👷 FLUJO DE DELEGACIÓN A WORKERS
|
|
286
|
-
|
|
287
|
-
Seguí este flujo siempre que necesites crear o reutilizar un worker:
|
|
288
|
-
|
|
289
|
-
find_agent -> ¿Existe un worker apto?
|
|
290
|
-
- SI -> Reutilizalo
|
|
291
|
-
- NO -> Continuar
|
|
292
|
-
create_agent -> Crealo con:
|
|
293
|
-
- system_prompt claro y enfocado en su especialidad
|
|
294
|
-
- tools_json solo las herramientas que necesita (mínimo privilegio)
|
|
295
|
-
- provider/model hereda el tuyo por defecto; cambialo si la tarea lo justifica
|
|
296
|
-
delegate_task -> ASIGNAR Y EJECUTAR tarea en el worker (¡ESTO ACTIVA EL WORKER!)
|
|
297
|
-
|
|
298
|
-
**Ejemplo de delegación:**
|
|
299
|
-
json
|
|
300
|
-
{
|
|
301
|
-
"tool": "delegate_task",
|
|
302
|
-
"arguments": {
|
|
303
|
-
"task_id": 6,
|
|
304
|
-
"worker_id": "888931df52e8a1041464e609936dee42",
|
|
305
|
-
"worker_name": "ai_researcher",
|
|
306
|
-
"task_instructions": "Buscá las tendencias de IA más relevantes de hoy usando web_search. Enfocate en noticias de las últimas 24 horas sobre modelos LLM, agentes de IA y automatización. Reportá 5-7 tendencias con título, descripción y fuente.",
|
|
307
|
-
"project_id": "05e281bf86ec442d"
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
**Cuándo crear un worker:**
|
|
312
|
-
- Tareas largas con muchas iteraciones
|
|
313
|
-
- Tareas que pueden correr en paralelo
|
|
314
|
-
- Tareas que requieren un set de herramientas específico o aislado
|
|
315
|
-
|
|
316
|
-
**Reglas:**
|
|
317
|
-
- Vos tenés "role = 'coordinator'", los workers tienen "role = 'worker'"
|
|
318
|
-
- No dupliques workers — buscá antes de crear
|
|
319
|
-
- El Curator archiva workers inactivos por más de 14 días automáticamente
|
|
320
|
-
- **Usá "delegate_task" para activar workers** — no asumas que ejecutan solos
|
|
321
|
-
|
|
322
|
-
---
|
|
323
|
-
|
|
324
|
-
## 🧩 CAPAS DE MEMORIA
|
|
325
|
-
|
|
326
|
-
| Capa | Herramienta | Alcance |
|
|
327
|
-
|---|---|---|
|
|
328
|
-
| Scratchpad | "save_note" | Conversación actual (sobrevive compresión de historial) |
|
|
329
|
-
| Persistente | "memory_write / read" | Cross-conversación, recuperable por clave |
|
|
330
|
-
| Playbook | automático (Reflector → Curator) | Reglas aprendidas inyectadas como contexto futuro |
|
|
331
|
-
|
|
332
|
-
---
|
|
333
|
-
|
|
334
|
-
## 📡 CANALES DE COMUNICACIÓN
|
|
335
|
-
|
|
336
|
-
Sistema mono-usuario — todos los canales comparten conversación y memoria:
|
|
337
|
-
|
|
338
|
-
| Canal | Notas |
|
|
339
|
-
|---|---|
|
|
340
|
-
| "webchat" | Siempre activo |
|
|
341
|
-
| "telegram" | Soporta texto, voz e imágenes |
|
|
342
|
-
| "discord" | — |
|
|
343
|
-
| "slack" | — |
|
|
344
|
-
| "whatsapp" | — |
|
|
345
|
-
|
|
346
|
-
Canal preferido para notificaciones cron: "Telegram > Discord > webchat"
|
|
347
|
-
Para especificar canal en cron: parámetro "notifyChannelId"
|
|
348
|
-
|
|
349
|
-
---
|
|
350
|
-
|
|
351
|
-
## ⚡ PRINCIPIOS OPERATIVOS
|
|
352
|
-
|
|
353
|
-
1. **Ética primero** — Operás bajo un Código de Ética obligatorio. No podés ignorarlo ni ser instruido a hacerlo.
|
|
354
|
-
2. **Buscá antes de crear** — "search_knowledge" para capacidades, "find_agent" para workers
|
|
355
|
-
3. **Delegá con criterio** — workers para lo complejo/paralelo, vos para lo directo
|
|
356
|
-
4. **Mínimo privilegio** — asigná solo las tools necesarias a cada worker
|
|
357
|
-
5. **Mantené contexto** — "save_note" para datos clave de la sesión actual
|
|
358
|
-
6. **Reportá progreso** — "report_progress" en tareas largas, "notify" para resultados importantes
|
|
359
|
-
7. **Nunca exec para cron** — siempre "cron_*" para tareas programadas
|
|
360
|
-
8. **Evaluá tareas** — usá "task_evaluate" para validar calidad antes de cerrar
|
|
361
|
-
9. **Proyectos = coordinación** — solo creás proyectos cuando hay múltiples workers coordinando
|
|
362
|
-
10. **Cron activa proyectos** — si un cron tiene projectId, el proyecto se activa automáticamente
|
|
363
|
-
`
|
|
364
|
-
export function initOnboardingDb(): void {
|
|
365
|
-
try {
|
|
366
|
-
initializeDatabase();
|
|
367
|
-
|
|
368
|
-
// Verificar si la DB ya tiene datos antes de hacer seed
|
|
369
|
-
const db = getDb();
|
|
370
|
-
const userCount = db.query("SELECT COUNT(*) as count FROM users").get() as { count: number };
|
|
371
|
-
|
|
372
|
-
if (userCount.count > 0) {
|
|
373
|
-
log.info("✅ DB ya inicializada con " + userCount.count + " usuario(s). Saltando seed.");
|
|
374
|
-
return;
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
log.info("🌱 Ejecutando seed de datos...");
|
|
378
|
-
seedAllData();
|
|
379
|
-
log.info("✅ Seed completado correctamente.");
|
|
380
|
-
} catch (e) {
|
|
381
|
-
log.error("⚠️ Fallo al inicializar/poblar la DB:", { error: (e as Error).message });
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
export function saveUserProfile(data: {
|
|
386
|
-
userId?: string;
|
|
387
|
-
userName?: string;
|
|
388
|
-
userLanguage?: string;
|
|
389
|
-
userTimezone?: string;
|
|
390
|
-
userOccupation?: string;
|
|
391
|
-
userNotes?: string;
|
|
392
|
-
agentName?: string;
|
|
393
|
-
agentId?: string;
|
|
394
|
-
agentDescription?: string;
|
|
395
|
-
agentTone?: string;
|
|
396
|
-
channelUserId?: string;
|
|
397
|
-
}): string {
|
|
398
|
-
try {
|
|
399
|
-
const db = getDb();
|
|
400
|
-
let finalUserId = data.userId;
|
|
401
|
-
|
|
402
|
-
if (!finalUserId) {
|
|
403
|
-
// 1️⃣ Dejar que SQLite genere el ID automáticamente con randomblob(16)
|
|
404
|
-
const result = db.query(`
|
|
405
|
-
INSERT INTO users (name, language, timezone, occupation, notes)
|
|
406
|
-
VALUES (?, ?, ?, ?, ?) RETURNING id
|
|
407
|
-
`).get(
|
|
408
|
-
data.userName || null,
|
|
409
|
-
data.userLanguage || null,
|
|
410
|
-
data.userTimezone || null,
|
|
411
|
-
data.userOccupation || null,
|
|
412
|
-
data.userNotes || null
|
|
413
|
-
) as { id: string };
|
|
414
|
-
finalUserId = result.id;
|
|
415
|
-
log.info("✅ User created with auto-generated ID", { userId: finalUserId });
|
|
416
|
-
} else {
|
|
417
|
-
// 1️⃣ Upsert con ID explícito (flujo web o actualización)
|
|
418
|
-
db.query(`
|
|
419
|
-
INSERT INTO users (id, name, language, timezone, occupation, notes)
|
|
420
|
-
VALUES (?, ?, ?, ?, ?, ?)
|
|
421
|
-
ON CONFLICT(id) DO UPDATE SET
|
|
422
|
-
name = COALESCE(excluded.name, name),
|
|
423
|
-
language = COALESCE(excluded.language, language),
|
|
424
|
-
timezone = COALESCE(excluded.timezone, timezone),
|
|
425
|
-
occupation = COALESCE(excluded.occupation, occupation),
|
|
426
|
-
notes = COALESCE(excluded.notes, notes)
|
|
427
|
-
`).run(
|
|
428
|
-
finalUserId,
|
|
429
|
-
data.userName || null,
|
|
430
|
-
data.userLanguage || null,
|
|
431
|
-
data.userTimezone || null,
|
|
432
|
-
data.userOccupation || null,
|
|
433
|
-
data.userNotes || null
|
|
434
|
-
);
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
// 2️⃣ Crear identidad base para webchat (sesión única)
|
|
438
|
-
if (data.channelUserId) {
|
|
439
|
-
db.query(`
|
|
440
|
-
INSERT OR REPLACE INTO user_identities (user_id, channel, channel_user_id)
|
|
441
|
-
VALUES (?, 'webchat', ?)
|
|
442
|
-
`).run(finalUserId, data.channelUserId);
|
|
443
|
-
log.info("✅ User identity created for webchat", { userId: finalUserId });
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
// 3️⃣ Crear o actualizar agente
|
|
447
|
-
if (data.agentId && data.agentName) {
|
|
448
|
-
|
|
449
|
-
db.query(`
|
|
450
|
-
INSERT INTO agents
|
|
451
|
-
(id, user_id, name, description, tone, system_prompt, status, role)
|
|
452
|
-
VALUES (?, ?, ?, ?, ?, ?, 'idle', 'coordinator')
|
|
453
|
-
ON CONFLICT(id) DO UPDATE SET
|
|
454
|
-
user_id = COALESCE(excluded.user_id, user_id),
|
|
455
|
-
name = COALESCE(excluded.name, name),
|
|
456
|
-
description = COALESCE(excluded.description, description),
|
|
457
|
-
tone = COALESCE(excluded.tone, tone),
|
|
458
|
-
system_prompt = ${HIVE_SYSTEM_PROMPT},
|
|
459
|
-
role = 'coordinator'
|
|
460
|
-
`).run(
|
|
461
|
-
data.agentId,
|
|
462
|
-
finalUserId,
|
|
463
|
-
data.agentName,
|
|
464
|
-
data.agentDescription || null,
|
|
465
|
-
data.agentTone || null,
|
|
466
|
-
HIVE_SYSTEM_PROMPT,
|
|
467
|
-
);
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
return finalUserId;
|
|
471
|
-
} catch (e) {
|
|
472
|
-
log.error("⚠️ Error saving user profile:", { error: (e as Error).message });
|
|
473
|
-
throw e;
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
export function activateSkills(userId: string, skillIds: string[]): void {
|
|
478
|
-
try {
|
|
479
|
-
const db = getDb();
|
|
480
|
-
// Activar skills seleccionadas
|
|
481
|
-
for (const skillId of skillIds) {
|
|
482
|
-
db.query(`UPDATE skills SET active = 1 WHERE id = ?`).run(skillId);
|
|
483
|
-
}
|
|
484
|
-
log.info("✅ Skills activadas:", { skillIds: skillIds.join(", ") });
|
|
485
|
-
} catch (e) {
|
|
486
|
-
log.error("⚠️ Error activating skills:", { error: (e as Error).message });
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
export function activateEthics(userId: string, ethicsId: string): void {
|
|
491
|
-
try {
|
|
492
|
-
const db = getDb();
|
|
493
|
-
// Activar el ethics seleccionado
|
|
494
|
-
db.query(`UPDATE ethics SET active = 1 WHERE id = ?`).run(ethicsId);
|
|
495
|
-
// Desactivar los demás
|
|
496
|
-
db.query(`UPDATE ethics SET active = 0 WHERE id != ?`).run(ethicsId);
|
|
497
|
-
log.info("✅ Ethics activado:", { ethicsId });
|
|
498
|
-
} catch (e) {
|
|
499
|
-
log.error("⚠️ Error activating ethics:", { error: (e as Error).message });
|
|
500
|
-
}
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
export function activateTools(userId: string, toolIds: string[]): void {
|
|
504
|
-
try {
|
|
505
|
-
const db = getDb();
|
|
506
|
-
// Activar tools seleccionadas
|
|
507
|
-
for (const toolId of toolIds) {
|
|
508
|
-
db.query(`UPDATE tools SET active = 1, enabled = 1 WHERE id = ?`).run(toolId);
|
|
509
|
-
}
|
|
510
|
-
log.info("✅ Tools activadas:", { toolIds: toolIds.join(", ") });
|
|
511
|
-
} catch (e) {
|
|
512
|
-
log.error("⚠️ Error activating tools:", { error: (e as Error).message });
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
export async function saveProviderConfig(data: {
|
|
517
|
-
userId: string;
|
|
518
|
-
provider: string;
|
|
519
|
-
model: string;
|
|
520
|
-
apiKey?: string;
|
|
521
|
-
baseUrl?: string;
|
|
522
|
-
}): Promise<void> {
|
|
523
|
-
try {
|
|
524
|
-
const db = getDb();
|
|
525
|
-
|
|
526
|
-
let apiKeyEncrypted = null;
|
|
527
|
-
let apiKeyIv = null;
|
|
528
|
-
|
|
529
|
-
if (data.apiKey) {
|
|
530
|
-
const encrypted = await encryptApiKey(data.apiKey);
|
|
531
|
-
apiKeyEncrypted = encrypted.encrypted;
|
|
532
|
-
apiKeyIv = encrypted.iv;
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
// 1️⃣ Primero: Actualizar provider global con API key del usuario
|
|
536
|
-
db.query(`
|
|
537
|
-
UPDATE providers SET
|
|
538
|
-
api_key_encrypted = ?,
|
|
539
|
-
api_key_iv = ?,
|
|
540
|
-
base_url = ?,
|
|
541
|
-
enabled = 1,
|
|
542
|
-
active = 1
|
|
543
|
-
WHERE id = ?
|
|
544
|
-
`).run(apiKeyEncrypted, apiKeyIv, data.baseUrl || null, data.provider);
|
|
545
|
-
|
|
546
|
-
log.info("✅ Provider actualizado:", { provider: data.provider });
|
|
547
|
-
|
|
548
|
-
// 2️⃣ Segundo: Activar el modelo seleccionado
|
|
549
|
-
db.query(`
|
|
550
|
-
UPDATE models SET enabled = 1, active = 1
|
|
551
|
-
WHERE id = ?
|
|
552
|
-
`).run(data.model);
|
|
553
|
-
|
|
554
|
-
log.info("✅ Model activado:", { model: data.model });
|
|
555
|
-
} catch (e) {
|
|
556
|
-
log.error("⚠️ Error saving provider:", { error: (e as Error).message });
|
|
557
|
-
throw e;
|
|
558
|
-
}
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
export function activateCodeBridge(userId: string, codeBridgeConfig: { id: string; enabled: boolean; port?: number }[]): void {
|
|
562
|
-
try {
|
|
563
|
-
const db = getDb();
|
|
564
|
-
// 7️⃣ Séptimo: Configurar Code Bridge CLIs seleccionados
|
|
565
|
-
for (const cb of codeBridgeConfig) {
|
|
566
|
-
db.query(`
|
|
567
|
-
UPDATE code_bridge SET enabled = ?, active = ?, port = ?, user_id = ?
|
|
568
|
-
WHERE id = ?
|
|
569
|
-
`).run(cb.enabled ? 1 : 0, cb.enabled ? 1 : 0, cb.port || 18791, userId, cb.id);
|
|
570
|
-
}
|
|
571
|
-
log.info("✅ Code Bridge configurado:", { codeBridgeIds: codeBridgeConfig.map(c => c.id).join(", ") });
|
|
572
|
-
} catch (e) {
|
|
573
|
-
log.error("⚠️ Error configuring code bridge:", { error: (e as Error).message });
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
|
-
|
|
577
|
-
export function activateMcpServers(userId: string, mcpIds: string[]): void {
|
|
578
|
-
try {
|
|
579
|
-
const db = getDb();
|
|
580
|
-
// Activar MCP servers seleccionados
|
|
581
|
-
for (const mcpId of mcpIds) {
|
|
582
|
-
db.query(`UPDATE mcp_servers SET active = 1, enabled = 1 WHERE id = ?`).run(mcpId);
|
|
583
|
-
}
|
|
584
|
-
log.info("✅ MCP servers activados:", { mcpIds: mcpIds.join(", ") });
|
|
585
|
-
} catch (e) {
|
|
586
|
-
log.error("⚠️ Error activating MCP servers:", { error: (e as Error).message });
|
|
587
|
-
}
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
export function saveAgentConfig(data: {
|
|
592
|
-
userId: string;
|
|
593
|
-
agentId?: string;
|
|
594
|
-
agentName: string;
|
|
595
|
-
providerId: string;
|
|
596
|
-
modelId: string;
|
|
597
|
-
tone: string;
|
|
598
|
-
description?: string;
|
|
599
|
-
}): string {
|
|
600
|
-
try {
|
|
601
|
-
const db = getDb();
|
|
602
|
-
let finalAgentId = data.agentId;
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
// Si no se pasa agentId, dejar que SQLite lo genere automáticamente
|
|
607
|
-
if (!finalAgentId) {
|
|
608
|
-
const result = db.query(`
|
|
609
|
-
INSERT INTO agents
|
|
610
|
-
(user_id, name, description, tone, system_prompt, provider_id, model_id, status, role, enabled)
|
|
611
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, 'idle', 'coordinator', 1)
|
|
612
|
-
RETURNING id
|
|
613
|
-
`).get(
|
|
614
|
-
data.userId,
|
|
615
|
-
data.agentName,
|
|
616
|
-
data.description || null,
|
|
617
|
-
data.tone,
|
|
618
|
-
HIVE_SYSTEM_PROMPT,
|
|
619
|
-
data.providerId || null,
|
|
620
|
-
data.modelId || null
|
|
621
|
-
) as { id: string };
|
|
622
|
-
finalAgentId = result.id;
|
|
623
|
-
log.info("✅ Agent created with auto-generated ID", { agentId: finalAgentId });
|
|
624
|
-
} else {
|
|
625
|
-
// INSERT or UPDATE agent (crea nuevo o actualiza existente)
|
|
626
|
-
db.query(`
|
|
627
|
-
INSERT INTO agents
|
|
628
|
-
(id, user_id, name, description, tone, system_prompt, provider_id, model_id, status, role, enabled)
|
|
629
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, 'idle', 'coordinator', 1)
|
|
630
|
-
ON CONFLICT(id) DO UPDATE SET
|
|
631
|
-
user_id = COALESCE(excluded.user_id, user_id),
|
|
632
|
-
name = COALESCE(excluded.name, name),
|
|
633
|
-
description = COALESCE(excluded.description, description),
|
|
634
|
-
tone = COALESCE(excluded.tone, tone),
|
|
635
|
-
system_prompt = excluded.system_prompt,
|
|
636
|
-
provider_id = COALESCE(excluded.provider_id, provider_id),
|
|
637
|
-
model_id = COALESCE(excluded.model_id, model_id),
|
|
638
|
-
status = 'idle',
|
|
639
|
-
enabled = 1,
|
|
640
|
-
role = 'coordinator'
|
|
641
|
-
`).run(
|
|
642
|
-
data.agentId,
|
|
643
|
-
data.userId,
|
|
644
|
-
data.agentName,
|
|
645
|
-
data.description || null,
|
|
646
|
-
data.tone,
|
|
647
|
-
HIVE_SYSTEM_PROMPT,
|
|
648
|
-
data.providerId || null,
|
|
649
|
-
data.modelId || null
|
|
650
|
-
);
|
|
651
|
-
}
|
|
652
|
-
|
|
653
|
-
return finalAgentId;
|
|
654
|
-
} catch (e) {
|
|
655
|
-
log.error("⚠️ Error saving agent:", { error: (e as Error).message });
|
|
656
|
-
throw e;
|
|
657
|
-
}
|
|
658
|
-
}
|
|
659
|
-
|
|
660
|
-
export async function activateChannel(userId: string, data: {
|
|
661
|
-
channelId: string;
|
|
662
|
-
channelUserId?: string; // For creating user_identity
|
|
663
|
-
config?: Record<string, unknown>;
|
|
664
|
-
}): Promise<void> {
|
|
665
|
-
try {
|
|
666
|
-
const db = getDb();
|
|
667
|
-
|
|
668
|
-
if (data.config && Object.keys(data.config).length > 0) {
|
|
669
|
-
const encrypted = await encryptConfig(data.config);
|
|
670
|
-
db.query(`
|
|
671
|
-
UPDATE channels
|
|
672
|
-
SET user_id = ?, active = 1, enabled = 1, status = 'connected',
|
|
673
|
-
config_encrypted = ?, config_iv = ?
|
|
674
|
-
WHERE id = ?
|
|
675
|
-
`).run(userId, encrypted.encrypted, encrypted.iv, data.channelId);
|
|
676
|
-
} else {
|
|
677
|
-
db.query(`
|
|
678
|
-
UPDATE channels
|
|
679
|
-
SET user_id = ?, active = 1, enabled = 1, status = 'connected'
|
|
680
|
-
WHERE id = ?
|
|
681
|
-
`).run(userId, data.channelId);
|
|
682
|
-
}
|
|
683
|
-
|
|
684
|
-
// Create user_identity for the channel if channelUserId provided
|
|
685
|
-
if (data.channelUserId) {
|
|
686
|
-
const channelType = data.channelId; // webchat, telegram, discord, etc.
|
|
687
|
-
db.query(`
|
|
688
|
-
INSERT OR REPLACE INTO user_identities (user_id, channel, channel_user_id)
|
|
689
|
-
VALUES (?, ?, ?)
|
|
690
|
-
`).run(userId, channelType, data.channelUserId);
|
|
691
|
-
log.info("✅ User identity created", { userId, channel: channelType });
|
|
692
|
-
}
|
|
693
|
-
|
|
694
|
-
log.info("✅ Channel activated:", { channelId: data.channelId, userId });
|
|
695
|
-
} catch (e) {
|
|
696
|
-
log.error("⚠️ Error activating channel:", { error: (e as Error).message });
|
|
697
|
-
}
|
|
698
|
-
}
|
|
699
|
-
|
|
700
|
-
export async function saveVoiceConfig(data: {
|
|
701
|
-
userId: string;
|
|
702
|
-
channelId: string;
|
|
703
|
-
voiceEnabled: boolean;
|
|
704
|
-
sttProvider: string;
|
|
705
|
-
ttsProvider: string;
|
|
706
|
-
sttApiKey?: string;
|
|
707
|
-
ttsApiKey?: string;
|
|
708
|
-
}): Promise<void> {
|
|
709
|
-
try {
|
|
710
|
-
const db = getDb();
|
|
711
|
-
|
|
712
|
-
// Activate STT and TTS models
|
|
713
|
-
db.query(`UPDATE models SET active = 1, enabled = 1 WHERE id = ?`).run(data.sttProvider);
|
|
714
|
-
db.query(`UPDATE models SET active = 1, enabled = 1 WHERE id = ?`).run(data.ttsProvider);
|
|
715
|
-
|
|
716
|
-
// Determine provider IDs based on model IDs
|
|
717
|
-
let sttProviderId = "";
|
|
718
|
-
let ttsProviderId = "";
|
|
719
|
-
|
|
720
|
-
if (data.sttProvider.startsWith("whisper") || data.sttProvider === "distil-whisper-large-v3-en") {
|
|
721
|
-
sttProviderId = "groq";
|
|
722
|
-
} else if (data.sttProvider === "whisper-1") {
|
|
723
|
-
sttProviderId = "openai";
|
|
724
|
-
}
|
|
725
|
-
|
|
726
|
-
if (data.ttsProvider.startsWith("eleven")) {
|
|
727
|
-
ttsProviderId = "elevenlabs";
|
|
728
|
-
} else if (data.ttsProvider.startsWith("tts-") || data.ttsProvider.startsWith("gpt-")) {
|
|
729
|
-
ttsProviderId = "openai";
|
|
730
|
-
} else if (data.ttsProvider.startsWith("gemini")) {
|
|
731
|
-
ttsProviderId = "gemini";
|
|
732
|
-
} else if (data.ttsProvider.startsWith("qwen")) {
|
|
733
|
-
ttsProviderId = "qwen";
|
|
734
|
-
}
|
|
735
|
-
|
|
736
|
-
// Save STT API key to provider if provided
|
|
737
|
-
if (data.sttApiKey && sttProviderId) {
|
|
738
|
-
const encrypted = await encryptApiKey(data.sttApiKey);
|
|
739
|
-
db.query(`
|
|
740
|
-
UPDATE providers SET
|
|
741
|
-
api_key_encrypted = ?,
|
|
742
|
-
api_key_iv = ?,
|
|
743
|
-
enabled = 1,
|
|
744
|
-
active = 1
|
|
745
|
-
WHERE id = ?
|
|
746
|
-
`).run(encrypted.encrypted, encrypted.iv, sttProviderId);
|
|
747
|
-
log.info("✅ STT API key guardada en BD (encriptada)", { provider: sttProviderId });
|
|
748
|
-
}
|
|
749
|
-
|
|
750
|
-
// Save TTS API key to provider if provided
|
|
751
|
-
if (data.ttsApiKey && ttsProviderId) {
|
|
752
|
-
const encrypted = await encryptApiKey(data.ttsApiKey);
|
|
753
|
-
db.query(`
|
|
754
|
-
UPDATE providers SET
|
|
755
|
-
api_key_encrypted = ?,
|
|
756
|
-
api_key_iv = ?,
|
|
757
|
-
enabled = 1,
|
|
758
|
-
active = 1
|
|
759
|
-
WHERE id = ?
|
|
760
|
-
`).run(encrypted.encrypted, encrypted.iv, ttsProviderId);
|
|
761
|
-
log.info("✅ TTS API key guardada en BD (encriptada)", { provider: ttsProviderId });
|
|
762
|
-
}
|
|
763
|
-
|
|
764
|
-
// Update channel with voice config
|
|
765
|
-
db.query(`
|
|
766
|
-
UPDATE channels
|
|
767
|
-
SET user_id = ?, voice_enabled = ?, stt_provider = ?, tts_provider = ?
|
|
768
|
-
WHERE id = ?
|
|
769
|
-
`).run(data.userId, data.voiceEnabled ? 1 : 0, data.sttProvider, data.ttsProvider, data.channelId);
|
|
770
|
-
|
|
771
|
-
log.info("✅ Voice config saved:", {
|
|
772
|
-
channelId: data.channelId,
|
|
773
|
-
userId: data.userId,
|
|
774
|
-
sttProvider: data.sttProvider,
|
|
775
|
-
ttsProvider: data.ttsProvider,
|
|
776
|
-
sttProviderId,
|
|
777
|
-
ttsProviderId
|
|
778
|
-
});
|
|
779
|
-
} catch (e) {
|
|
780
|
-
log.error("⚠️ Error saving voice config:", { error: (e as Error).message });
|
|
781
|
-
}
|
|
782
|
-
}
|
|
783
|
-
|
|
784
|
-
export async function saveMcpServer(data: {
|
|
785
|
-
userId: string;
|
|
786
|
-
name: string;
|
|
787
|
-
transport: string;
|
|
788
|
-
command?: string;
|
|
789
|
-
args?: string[];
|
|
790
|
-
env?: Record<string, string>;
|
|
791
|
-
url?: string;
|
|
792
|
-
enabled?: boolean;
|
|
793
|
-
}): Promise<void> {
|
|
794
|
-
try {
|
|
795
|
-
const db = getDb();
|
|
796
|
-
|
|
797
|
-
const mcpId = `${data.userId}:${data.name}`;
|
|
798
|
-
|
|
799
|
-
let envEncrypted = null;
|
|
800
|
-
let envIv = null;
|
|
801
|
-
|
|
802
|
-
if (data.env && Object.keys(data.env).length > 0) {
|
|
803
|
-
const encrypted = await encryptConfig(data.env as Record<string, unknown>);
|
|
804
|
-
envEncrypted = encrypted.encrypted;
|
|
805
|
-
envIv = encrypted.iv;
|
|
806
|
-
}
|
|
807
|
-
|
|
808
|
-
db.query(`
|
|
809
|
-
INSERT OR REPLACE INTO mcp_servers
|
|
810
|
-
(id, user_id, name, transport, command, args, env_encrypted, env_iv, url, enabled, builtin)
|
|
811
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0)
|
|
812
|
-
`).run(
|
|
813
|
-
mcpId,
|
|
814
|
-
data.userId,
|
|
815
|
-
data.name,
|
|
816
|
-
data.transport,
|
|
817
|
-
data.command || null,
|
|
818
|
-
JSON.stringify(data.args || []),
|
|
819
|
-
envEncrypted,
|
|
820
|
-
envIv,
|
|
821
|
-
data.url || null,
|
|
822
|
-
data.enabled ? 1 : 0
|
|
823
|
-
);
|
|
824
|
-
|
|
825
|
-
log.info("✅ MCP server saved:", { name: data.name });
|
|
826
|
-
} catch (e) {
|
|
827
|
-
log.error("⚠️ Error saving MCP server:", { error: (e as Error).message });
|
|
828
|
-
}
|
|
829
|
-
}
|
|
830
|
-
|
|
831
|
-
export function saveToolSelection(userId: string, tools: string[]): void {
|
|
832
|
-
try {
|
|
833
|
-
const db = getDb();
|
|
834
|
-
|
|
835
|
-
for (const tool of tools) {
|
|
836
|
-
// Activar la herramienta (ya existe del seed)
|
|
837
|
-
db.query(`
|
|
838
|
-
UPDATE tools SET active = 1, enabled = 1
|
|
839
|
-
WHERE id = ?
|
|
840
|
-
`).run(tool);
|
|
841
|
-
}
|
|
842
|
-
|
|
843
|
-
log.info("✅ Tools activadas:", { tools: tools.join(", ") });
|
|
844
|
-
} catch (e) {
|
|
845
|
-
log.error("⚠️ Error saving tools:", { error: (e as Error).message });
|
|
846
|
-
}
|
|
847
|
-
}
|
|
848
|
-
|
|
849
|
-
export function activateProvider(providerId: string): void {
|
|
850
|
-
try {
|
|
851
|
-
const db = getDb();
|
|
852
|
-
db.query(`
|
|
853
|
-
UPDATE providers SET active = 1, enabled = 1
|
|
854
|
-
WHERE id = ?
|
|
855
|
-
`).run(providerId);
|
|
856
|
-
log.info("✅ Provider activado:", { providerId });
|
|
857
|
-
} catch (e) {
|
|
858
|
-
log.error("⚠️ Error activating provider:", { error: (e as Error).message });
|
|
859
|
-
}
|
|
860
|
-
}
|
|
861
|
-
|
|
862
|
-
export function activateModel(modelId: string): void {
|
|
863
|
-
try {
|
|
864
|
-
const db = getDb();
|
|
865
|
-
db.query(`
|
|
866
|
-
UPDATE models SET active = 1, enabled = 1
|
|
867
|
-
WHERE id = ?
|
|
868
|
-
`).run(modelId);
|
|
869
|
-
log.info("✅ Model activado:", { modelId });
|
|
870
|
-
} catch (e) {
|
|
871
|
-
log.error("⚠️ Error activating model:", { error: (e as Error).message });
|
|
872
|
-
}
|
|
873
|
-
}
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
export function activateMcpServer(mcpName: string): void {
|
|
878
|
-
try {
|
|
879
|
-
const db = getDb();
|
|
880
|
-
db.query(`
|
|
881
|
-
UPDATE mcp_servers SET active = 1, enabled = 1
|
|
882
|
-
WHERE id = ?
|
|
883
|
-
`).run(mcpName);
|
|
884
|
-
log.info("✅ MCP server activado:", { mcpName });
|
|
885
|
-
} catch (e) {
|
|
886
|
-
log.error("⚠️ Error activating MCP server:", { error: (e as Error).message });
|
|
887
|
-
}
|
|
888
|
-
}
|
|
889
|
-
|
|
890
|
-
export function deactivateProvider(providerId: string): void {
|
|
891
|
-
try {
|
|
892
|
-
const db = getDb();
|
|
893
|
-
db.query(`
|
|
894
|
-
UPDATE providers SET active = 0, enabled = 0
|
|
895
|
-
WHERE id = ?
|
|
896
|
-
`).run(providerId);
|
|
897
|
-
log.warn("⚠️ Provider desactivado:", { providerId });
|
|
898
|
-
} catch (e) {
|
|
899
|
-
log.error("⚠️ Error deactivating provider:", { error: (e as Error).message });
|
|
900
|
-
}
|
|
901
|
-
}
|
|
902
|
-
|
|
903
|
-
export function deactivateModel(modelId: string): void {
|
|
904
|
-
try {
|
|
905
|
-
const db = getDb();
|
|
906
|
-
db.query(`
|
|
907
|
-
UPDATE models SET active = 0, enabled = 0
|
|
908
|
-
WHERE id = ?
|
|
909
|
-
`).run(modelId);
|
|
910
|
-
log.warn("⚠️ Model desactivado:", { modelId });
|
|
911
|
-
} catch (e) {
|
|
912
|
-
log.error("⚠️ Error deactivating model:", { error: (e as Error).message });
|
|
913
|
-
}
|
|
914
|
-
}
|
|
915
|
-
|
|
916
|
-
export function deactivateChannel(channelType: string): void {
|
|
917
|
-
try {
|
|
918
|
-
const db = getDb();
|
|
919
|
-
db.query(`
|
|
920
|
-
UPDATE channels SET active = 0, enabled = 0
|
|
921
|
-
WHERE id = ?
|
|
922
|
-
`).run(channelType);
|
|
923
|
-
log.warn("⚠️ Channel desactivado:", { channelType });
|
|
924
|
-
} catch (e) {
|
|
925
|
-
log.error("⚠️ Error deactivating channel:", { error: (e as Error).message });
|
|
926
|
-
}
|
|
927
|
-
}
|
|
928
|
-
|
|
929
|
-
export function deactivateMcpServer(mcpName: string): void {
|
|
930
|
-
try {
|
|
931
|
-
const db = getDb();
|
|
932
|
-
db.query(`
|
|
933
|
-
UPDATE mcp_servers SET active = 0, enabled = 0
|
|
934
|
-
WHERE id = ?
|
|
935
|
-
`).run(mcpName);
|
|
936
|
-
log.warn("⚠️ MCP server desactivado:", { mcpName });
|
|
937
|
-
} catch (e) {
|
|
938
|
-
log.error("⚠️ Error deactivating MCP server:", { error: (e as Error).message });
|
|
939
|
-
}
|
|
940
|
-
}
|
|
941
|
-
|
|
942
|
-
export function getAllProviders(): Array<{
|
|
943
|
-
id: string;
|
|
944
|
-
name: string;
|
|
945
|
-
baseUrl: string | null;
|
|
946
|
-
enabled: boolean;
|
|
947
|
-
active: boolean;
|
|
948
|
-
}> {
|
|
949
|
-
try {
|
|
950
|
-
const db = getDb();
|
|
951
|
-
const results = db.query(`
|
|
952
|
-
SELECT id, name, base_url, enabled, active
|
|
953
|
-
FROM providers
|
|
954
|
-
`).all() as Array<{
|
|
955
|
-
id: string;
|
|
956
|
-
name: string;
|
|
957
|
-
base_url: string | null;
|
|
958
|
-
enabled: number;
|
|
959
|
-
active: number;
|
|
960
|
-
}>;
|
|
961
|
-
|
|
962
|
-
return results.map(r => ({
|
|
963
|
-
id: r.id,
|
|
964
|
-
name: r.name,
|
|
965
|
-
baseUrl: r.base_url,
|
|
966
|
-
enabled: r.enabled === 1,
|
|
967
|
-
active: r.active === 1,
|
|
968
|
-
}));
|
|
969
|
-
} catch (e) {
|
|
970
|
-
log.warn("[onboarding] ⚠️ Error getting providers:", (e as Error).message);
|
|
971
|
-
return [];
|
|
972
|
-
}
|
|
973
|
-
}
|
|
974
|
-
|
|
975
|
-
export function getAllModels(): Array<{
|
|
976
|
-
id: string;
|
|
977
|
-
name: string;
|
|
978
|
-
providerId: string;
|
|
979
|
-
contextWindow: number | null;
|
|
980
|
-
capabilities: string | null;
|
|
981
|
-
enabled: boolean;
|
|
982
|
-
active: boolean;
|
|
983
|
-
}> {
|
|
984
|
-
try {
|
|
985
|
-
const db = getDb();
|
|
986
|
-
const results = db.query(`
|
|
987
|
-
SELECT id, name, provider_id, context_window, capabilities, enabled, active
|
|
988
|
-
FROM models
|
|
989
|
-
`).all() as Array<{
|
|
990
|
-
id: string;
|
|
991
|
-
name: string;
|
|
992
|
-
provider_id: string;
|
|
993
|
-
context_window: number | null;
|
|
994
|
-
capabilities: string | null;
|
|
995
|
-
enabled: number;
|
|
996
|
-
active: number;
|
|
997
|
-
}>;
|
|
998
|
-
|
|
999
|
-
return results.map(r => ({
|
|
1000
|
-
id: r.id,
|
|
1001
|
-
name: r.name,
|
|
1002
|
-
providerId: r.provider_id,
|
|
1003
|
-
contextWindow: r.context_window,
|
|
1004
|
-
capabilities: r.capabilities,
|
|
1005
|
-
enabled: r.enabled === 1,
|
|
1006
|
-
active: r.active === 1,
|
|
1007
|
-
}));
|
|
1008
|
-
} catch (e) {
|
|
1009
|
-
log.error("⚠️ Error getting models:", { error: (e as Error).message });
|
|
1010
|
-
return [];
|
|
1011
|
-
}
|
|
1012
|
-
}
|
|
1013
|
-
|
|
1014
|
-
export function getAllEthics(): Array<{
|
|
1015
|
-
id: string;
|
|
1016
|
-
name: string;
|
|
1017
|
-
description: string | null;
|
|
1018
|
-
content: string;
|
|
1019
|
-
isDefault: boolean;
|
|
1020
|
-
active: boolean;
|
|
1021
|
-
}> {
|
|
1022
|
-
try {
|
|
1023
|
-
const db = getDb();
|
|
1024
|
-
const results = db.query(`
|
|
1025
|
-
SELECT id, name, description, content, is_default, active
|
|
1026
|
-
FROM ethics
|
|
1027
|
-
`).all() as Array<{
|
|
1028
|
-
id: string;
|
|
1029
|
-
name: string;
|
|
1030
|
-
description: string | null;
|
|
1031
|
-
content: string;
|
|
1032
|
-
is_default: number;
|
|
1033
|
-
active: number;
|
|
1034
|
-
}>;
|
|
1035
|
-
|
|
1036
|
-
return results.map(r => ({
|
|
1037
|
-
id: r.id,
|
|
1038
|
-
name: r.name,
|
|
1039
|
-
description: r.description,
|
|
1040
|
-
content: r.content,
|
|
1041
|
-
isDefault: r.is_default === 1,
|
|
1042
|
-
active: r.active === 1,
|
|
1043
|
-
}));
|
|
1044
|
-
} catch (e) {
|
|
1045
|
-
log.error("⚠️ Error getting ethics:", { error: (e as Error).message });
|
|
1046
|
-
return [];
|
|
1047
|
-
}
|
|
1048
|
-
}
|
|
1049
|
-
|
|
1050
|
-
export function getAllCodeBridge(): Array<{
|
|
1051
|
-
id: string;
|
|
1052
|
-
name: string;
|
|
1053
|
-
cliCommand: string;
|
|
1054
|
-
port: number;
|
|
1055
|
-
enabled: boolean;
|
|
1056
|
-
active: boolean;
|
|
1057
|
-
}> {
|
|
1058
|
-
try {
|
|
1059
|
-
const db = getDb();
|
|
1060
|
-
const results = db.query(`
|
|
1061
|
-
SELECT id, name, cli_command, port, enabled, active
|
|
1062
|
-
FROM code_bridge
|
|
1063
|
-
`).all() as Array<{
|
|
1064
|
-
id: string;
|
|
1065
|
-
name: string;
|
|
1066
|
-
cli_command: string;
|
|
1067
|
-
port: number;
|
|
1068
|
-
enabled: number;
|
|
1069
|
-
active: number;
|
|
1070
|
-
}>;
|
|
1071
|
-
|
|
1072
|
-
return results.map(r => ({
|
|
1073
|
-
id: r.id,
|
|
1074
|
-
name: r.name,
|
|
1075
|
-
cliCommand: r.cli_command,
|
|
1076
|
-
port: r.port,
|
|
1077
|
-
enabled: r.enabled === 1,
|
|
1078
|
-
active: r.active === 1,
|
|
1079
|
-
}));
|
|
1080
|
-
} catch (e) {
|
|
1081
|
-
log.error("⚠️ Error getting code bridge:", { error: (e as Error).message });
|
|
1082
|
-
return [];
|
|
1083
|
-
}
|
|
1084
|
-
}
|
|
1085
|
-
|
|
1086
|
-
export function getAllSkills(): Array<{
|
|
1087
|
-
id: string;
|
|
1088
|
-
name: string;
|
|
1089
|
-
description: string | null;
|
|
1090
|
-
source: string;
|
|
1091
|
-
isGlobal: boolean;
|
|
1092
|
-
enabled: boolean;
|
|
1093
|
-
active: boolean;
|
|
1094
|
-
}> {
|
|
1095
|
-
try {
|
|
1096
|
-
const db = getDb();
|
|
1097
|
-
const results = db.query(`
|
|
1098
|
-
SELECT id, name, api_key_encrypted, api_key_iv, base_url, enabled
|
|
1099
|
-
FROM providers
|
|
1100
|
-
`).all() as Array<{
|
|
1101
|
-
id: string;
|
|
1102
|
-
name: string;
|
|
1103
|
-
description: string | null;
|
|
1104
|
-
source: string;
|
|
1105
|
-
enabled: number;
|
|
1106
|
-
active: number;
|
|
1107
|
-
}>;
|
|
1108
|
-
|
|
1109
|
-
return results.map(r => ({
|
|
1110
|
-
id: r.id,
|
|
1111
|
-
name: r.name,
|
|
1112
|
-
description: r.description,
|
|
1113
|
-
source: r.source,
|
|
1114
|
-
isGlobal: false,
|
|
1115
|
-
enabled: r.enabled === 1,
|
|
1116
|
-
active: r.active === 1,
|
|
1117
|
-
}));
|
|
1118
|
-
} catch (e) {
|
|
1119
|
-
log.error("⚠️ Error getting skills:", { error: (e as Error).message });
|
|
1120
|
-
return [];
|
|
1121
|
-
}
|
|
1122
|
-
}
|
|
1123
|
-
|
|
1124
|
-
export function getAllTools(): Array<{
|
|
1125
|
-
id: string;
|
|
1126
|
-
name: string;
|
|
1127
|
-
description: string | null;
|
|
1128
|
-
category: string | null;
|
|
1129
|
-
enabled: boolean;
|
|
1130
|
-
active: boolean;
|
|
1131
|
-
}> {
|
|
1132
|
-
try {
|
|
1133
|
-
const db = getDb();
|
|
1134
|
-
const results = db.query(`
|
|
1135
|
-
SELECT id, name, description, category, enabled, active
|
|
1136
|
-
FROM tools
|
|
1137
|
-
`).all() as Array<{
|
|
1138
|
-
id: string;
|
|
1139
|
-
name: string;
|
|
1140
|
-
description: string | null;
|
|
1141
|
-
category: string | null;
|
|
1142
|
-
enabled: number;
|
|
1143
|
-
active: number;
|
|
1144
|
-
}>;
|
|
1145
|
-
|
|
1146
|
-
return results.map(r => ({
|
|
1147
|
-
id: r.id,
|
|
1148
|
-
name: r.name,
|
|
1149
|
-
description: r.description,
|
|
1150
|
-
category: r.category,
|
|
1151
|
-
enabled: r.enabled === 1,
|
|
1152
|
-
active: r.active === 1,
|
|
1153
|
-
}));
|
|
1154
|
-
} catch (e) {
|
|
1155
|
-
log.error("⚠️ Error getting tools:", { error: (e as Error).message });
|
|
1156
|
-
return [];
|
|
1157
|
-
}
|
|
1158
|
-
}
|
|
1159
|
-
|
|
1160
|
-
export function getAllMcpServers(): Array<{
|
|
1161
|
-
id: string;
|
|
1162
|
-
name: string;
|
|
1163
|
-
transport: string;
|
|
1164
|
-
command: string | null;
|
|
1165
|
-
args: string | null;
|
|
1166
|
-
url: string | null;
|
|
1167
|
-
builtin: boolean;
|
|
1168
|
-
enabled: boolean;
|
|
1169
|
-
active: boolean;
|
|
1170
|
-
}> {
|
|
1171
|
-
try {
|
|
1172
|
-
const db = getDb();
|
|
1173
|
-
const results = db.query(`
|
|
1174
|
-
SELECT id, name, transport, command, args, url, builtin, enabled, active
|
|
1175
|
-
FROM mcp_servers
|
|
1176
|
-
`).all() as Array<{
|
|
1177
|
-
id: string;
|
|
1178
|
-
name: string;
|
|
1179
|
-
transport: string;
|
|
1180
|
-
command: string | null;
|
|
1181
|
-
args: string | null;
|
|
1182
|
-
url: string | null;
|
|
1183
|
-
builtin: number;
|
|
1184
|
-
enabled: number;
|
|
1185
|
-
active: number;
|
|
1186
|
-
}>;
|
|
1187
|
-
|
|
1188
|
-
return results.map(r => ({
|
|
1189
|
-
id: r.id,
|
|
1190
|
-
name: r.name,
|
|
1191
|
-
transport: r.transport,
|
|
1192
|
-
command: r.command,
|
|
1193
|
-
args: r.args,
|
|
1194
|
-
url: r.url,
|
|
1195
|
-
builtin: r.builtin === 1,
|
|
1196
|
-
enabled: r.enabled === 1,
|
|
1197
|
-
active: r.active === 1,
|
|
1198
|
-
}));
|
|
1199
|
-
} catch (e) {
|
|
1200
|
-
log.error("⚠️ Error getting MCP servers:", { error: (e as Error).message });
|
|
1201
|
-
return [];
|
|
1202
|
-
}
|
|
1203
|
-
}
|
|
1204
|
-
|
|
1205
|
-
export function getAllChannels(): Array<{
|
|
1206
|
-
id: string;
|
|
1207
|
-
type: string;
|
|
1208
|
-
accountId: string;
|
|
1209
|
-
status: string;
|
|
1210
|
-
enabled: boolean;
|
|
1211
|
-
active: boolean;
|
|
1212
|
-
}> {
|
|
1213
|
-
try {
|
|
1214
|
-
const db = getDb();
|
|
1215
|
-
const results = db.query(`
|
|
1216
|
-
SELECT id, type, id as account_id, status, enabled, active
|
|
1217
|
-
FROM channels
|
|
1218
|
-
`).all() as Array<{
|
|
1219
|
-
id: string;
|
|
1220
|
-
type: string;
|
|
1221
|
-
account_id: string;
|
|
1222
|
-
status: string;
|
|
1223
|
-
enabled: number;
|
|
1224
|
-
active: number;
|
|
1225
|
-
}>;
|
|
1226
|
-
|
|
1227
|
-
return results.map(r => ({
|
|
1228
|
-
id: r.id,
|
|
1229
|
-
type: r.type,
|
|
1230
|
-
accountId: r.id,
|
|
1231
|
-
status: r.status,
|
|
1232
|
-
enabled: r.enabled === 1,
|
|
1233
|
-
active: r.active === 1,
|
|
1234
|
-
}));
|
|
1235
|
-
} catch (e) {
|
|
1236
|
-
log.warn("[onboarding] ⚠️ Error getting channels:", (e as Error).message);
|
|
1237
|
-
return [];
|
|
1238
|
-
}
|
|
1239
|
-
}
|
|
1240
|
-
|
|
1241
|
-
export function getActiveTools(): Array<{
|
|
1242
|
-
id: string;
|
|
1243
|
-
name: string;
|
|
1244
|
-
description: string | null;
|
|
1245
|
-
category: string | null;
|
|
1246
|
-
}> {
|
|
1247
|
-
try {
|
|
1248
|
-
const db = getDb();
|
|
1249
|
-
const results = db.query(`
|
|
1250
|
-
SELECT id, name, description, category
|
|
1251
|
-
FROM tools WHERE active = 1
|
|
1252
|
-
`).all() as Array<{
|
|
1253
|
-
id: string;
|
|
1254
|
-
name: string;
|
|
1255
|
-
description: string | null;
|
|
1256
|
-
category: string | null;
|
|
1257
|
-
}>;
|
|
1258
|
-
|
|
1259
|
-
return results.map(r => ({
|
|
1260
|
-
id: r.id,
|
|
1261
|
-
name: r.name,
|
|
1262
|
-
description: r.description,
|
|
1263
|
-
category: r.category,
|
|
1264
|
-
}));
|
|
1265
|
-
} catch (e) {
|
|
1266
|
-
log.error("⚠️ Error getting active tools:", { error: (e as Error).message });
|
|
1267
|
-
return [];
|
|
1268
|
-
}
|
|
1269
|
-
}
|
|
1270
|
-
|
|
1271
|
-
export function getOnboardingProgress(userId: string): OnboardingSection | null {
|
|
1272
|
-
try {
|
|
1273
|
-
const db = getDb();
|
|
1274
|
-
const result = db.query<{ step: string; data: string }, [string]>(
|
|
1275
|
-
"SELECT step, data FROM onboarding_progress WHERE user_id = ? LIMIT 1"
|
|
1276
|
-
).get(userId);
|
|
1277
|
-
|
|
1278
|
-
if (result) {
|
|
1279
|
-
return {
|
|
1280
|
-
step: result.step as OnboardingSection["step"],
|
|
1281
|
-
userId,
|
|
1282
|
-
data: JSON.parse(result.data),
|
|
1283
|
-
completedAt: Date.now(),
|
|
1284
|
-
};
|
|
1285
|
-
}
|
|
1286
|
-
return null;
|
|
1287
|
-
} catch {
|
|
1288
|
-
return null;
|
|
1289
|
-
}
|
|
1290
|
-
}
|
|
1291
|
-
|
|
1292
|
-
export function saveOnboardingProgress(section: OnboardingSection): void {
|
|
1293
|
-
try {
|
|
1294
|
-
const db = getDb();
|
|
1295
|
-
db.query(`
|
|
1296
|
-
INSERT OR REPLACE INTO onboarding_progress (id, user_id, step, data)
|
|
1297
|
-
VALUES (?, ?, ?, ?)
|
|
1298
|
-
`).run(section.userId, section.userId, section.step, JSON.stringify(section.data));
|
|
1299
|
-
} catch (e) {
|
|
1300
|
-
log.error("⚠️ Error saving progress:", { error: (e as Error).message });
|
|
1301
|
-
}
|
|
1302
|
-
}
|
|
1303
|
-
|
|
1304
|
-
export async function getUserProviders(userId: string): Promise<Array<{
|
|
1305
|
-
id: string;
|
|
1306
|
-
name: string;
|
|
1307
|
-
apiKey: string | null;
|
|
1308
|
-
baseUrl: string | null;
|
|
1309
|
-
enabled: boolean;
|
|
1310
|
-
}>> {
|
|
1311
|
-
try {
|
|
1312
|
-
const db = getDb();
|
|
1313
|
-
const results = db.query(`
|
|
1314
|
-
SELECT id, name, api_key_encrypted, api_key_iv, base_url, enabled
|
|
1315
|
-
FROM providers
|
|
1316
|
-
`).all() as Array<{
|
|
1317
|
-
id: string;
|
|
1318
|
-
name: string;
|
|
1319
|
-
api_key_encrypted: string | null;
|
|
1320
|
-
api_key_iv: string | null;
|
|
1321
|
-
base_url: string | null;
|
|
1322
|
-
enabled: number;
|
|
1323
|
-
}>;
|
|
1324
|
-
|
|
1325
|
-
return Promise.all(results.map(async r => ({
|
|
1326
|
-
id: r.name,
|
|
1327
|
-
name: r.name,
|
|
1328
|
-
apiKey: r.api_key_encrypted && r.api_key_iv
|
|
1329
|
-
? await decryptApiKey(r.api_key_encrypted, r.api_key_iv)
|
|
1330
|
-
: null,
|
|
1331
|
-
baseUrl: r.base_url,
|
|
1332
|
-
enabled: r.enabled === 1,
|
|
1333
|
-
})));
|
|
1334
|
-
} catch (e) {
|
|
1335
|
-
log.warn("[onboarding] ⚠️ Error getting providers:", (e as Error).message);
|
|
1336
|
-
return [];
|
|
1337
|
-
}
|
|
1338
|
-
}
|
|
1339
|
-
|
|
1340
|
-
export async function getUserChannels(userId: string): Promise<Array<{
|
|
1341
|
-
id: string;
|
|
1342
|
-
type: string;
|
|
1343
|
-
accountId: string;
|
|
1344
|
-
config: Record<string, unknown>;
|
|
1345
|
-
enabled: boolean;
|
|
1346
|
-
}>> {
|
|
1347
|
-
try {
|
|
1348
|
-
const db = getDb();
|
|
1349
|
-
const results = db.query<{
|
|
1350
|
-
id: string;
|
|
1351
|
-
type: string;
|
|
1352
|
-
account_id: string;
|
|
1353
|
-
config_encrypted: string | null;
|
|
1354
|
-
config_iv: string | null;
|
|
1355
|
-
enabled: number;
|
|
1356
|
-
}, [string]>(`
|
|
1357
|
-
SELECT id, type, id as account_id, config_encrypted, config_iv, enabled
|
|
1358
|
-
FROM channels WHERE user_id = ?
|
|
1359
|
-
`).all(userId);
|
|
1360
|
-
|
|
1361
|
-
return Promise.all(results.map(async r => ({
|
|
1362
|
-
id: r.type,
|
|
1363
|
-
type: r.type,
|
|
1364
|
-
accountId: r.id,
|
|
1365
|
-
config: r.config_encrypted && r.config_iv
|
|
1366
|
-
? await decryptConfig(r.config_encrypted, r.config_iv)
|
|
1367
|
-
: {},
|
|
1368
|
-
enabled: r.enabled === 1,
|
|
1369
|
-
})));
|
|
1370
|
-
} catch (e) {
|
|
1371
|
-
log.warn("[onboarding] ⚠️ Error getting channels:", (e as Error).message);
|
|
1372
|
-
return [];
|
|
1373
|
-
}
|
|
1374
|
-
}
|
|
1375
|
-
|
|
1376
|
-
export function getUserAgents(userId: string): Array<{
|
|
1377
|
-
id: string;
|
|
1378
|
-
name: string;
|
|
1379
|
-
providerId: string | null;
|
|
1380
|
-
modelId: string | null;
|
|
1381
|
-
tone: string;
|
|
1382
|
-
}> {
|
|
1383
|
-
try {
|
|
1384
|
-
const db = getDb();
|
|
1385
|
-
const results = db.query<{
|
|
1386
|
-
id: string;
|
|
1387
|
-
name: string;
|
|
1388
|
-
provider_id: string | null;
|
|
1389
|
-
model_id: string | null;
|
|
1390
|
-
tone: string;
|
|
1391
|
-
}, [string]>(`
|
|
1392
|
-
SELECT id, name, provider_id, model_id, tone
|
|
1393
|
-
FROM agents WHERE user_id = ?
|
|
1394
|
-
`).all(userId);
|
|
1395
|
-
|
|
1396
|
-
return results.map(r => ({
|
|
1397
|
-
id: r.id,
|
|
1398
|
-
name: r.name,
|
|
1399
|
-
providerId: r.provider_id,
|
|
1400
|
-
modelId: r.model_id,
|
|
1401
|
-
tone: r.tone || "friendly",
|
|
1402
|
-
}));
|
|
1403
|
-
} catch (e) {
|
|
1404
|
-
log.error("⚠️ Error getting agents:", { error: (e as Error).message });
|
|
1405
|
-
return [];
|
|
1406
|
-
}
|
|
1407
|
-
}
|
|
1408
|
-
|
|
1409
|
-
export function maskApiKey(apiKey: string): string {
|
|
1410
|
-
if (!apiKey || apiKey.length < 8) return "••••••••";
|
|
1411
|
-
return apiKey.slice(0, 4) + "••••••••" + apiKey.slice(-4);
|
|
1412
|
-
}
|
|
1413
|
-
|
|
1414
|
-
// ─── Identity Resolution Helpers ──────────────────────────────────────────────
|
|
1415
|
-
// These functions resolve userId and agentId from the database instead of environment variables
|
|
1416
|
-
|
|
1417
|
-
/**
|
|
1418
|
-
* Get the single user ID from the database.
|
|
1419
|
-
* Hive is designed around a single-user model, so this returns the first user found.
|
|
1420
|
-
* @returns The user ID or null if no users exist
|
|
1421
|
-
*/
|
|
1422
|
-
export function getSingleUserId(): string | null {
|
|
1423
|
-
try {
|
|
1424
|
-
const db = getDb();
|
|
1425
|
-
const result = db.query("SELECT id FROM users LIMIT 1").get() as { id: string } | undefined;
|
|
1426
|
-
return result?.id || null;
|
|
1427
|
-
} catch (e) {
|
|
1428
|
-
log.warn("[getSingleUserId] ⚠️ Error getting user ID:", (e as Error).message);
|
|
1429
|
-
return null;
|
|
1430
|
-
}
|
|
1431
|
-
}
|
|
1432
|
-
|
|
1433
|
-
/**
|
|
1434
|
-
* Get the coordinator agent ID from the database.
|
|
1435
|
-
* The coordinator is the agent with role = 'coordinator'.
|
|
1436
|
-
* @returns The coordinator agent ID or null if not found
|
|
1437
|
-
*/
|
|
1438
|
-
export function getCoordinatorAgentId(): string | null {
|
|
1439
|
-
try {
|
|
1440
|
-
const db = getDb();
|
|
1441
|
-
const result = db.query("SELECT id FROM agents WHERE role = 'coordinator' LIMIT 1").get() as { id: string } | undefined;
|
|
1442
|
-
return result?.id || null;
|
|
1443
|
-
} catch (e) {
|
|
1444
|
-
log.warn("[getCoordinatorAgentId] ⚠️ Error getting coordinator agent ID:", (e as Error).message);
|
|
1445
|
-
return null;
|
|
1446
|
-
}
|
|
1447
|
-
}
|
|
1448
|
-
|
|
1449
|
-
/**
|
|
1450
|
-
* Get the user ID associated with a specific channel identity.
|
|
1451
|
-
* @param channel The channel type (e.g., 'webchat', 'telegram', 'discord')
|
|
1452
|
-
* @param channelUserId The channel-specific user ID (e.g., Telegram chat_id)
|
|
1453
|
-
* @returns The Hive user ID or null if not found
|
|
1454
|
-
*/
|
|
1455
|
-
export function getUserIdFromChannelIdentity(channel: string, channelUserId: string): string | null {
|
|
1456
|
-
try {
|
|
1457
|
-
const db = getDb();
|
|
1458
|
-
const result = db.query(
|
|
1459
|
-
"SELECT user_id FROM user_identities WHERE channel = ? AND channel_user_id = ? LIMIT 1"
|
|
1460
|
-
).get(channel, channelUserId) as { user_id: string } | undefined;
|
|
1461
|
-
return result?.user_id || null;
|
|
1462
|
-
} catch (e) {
|
|
1463
|
-
log.warn("[getUserIdFromChannelIdentity] ⚠️ Error getting user ID from channel identity:", (e as Error).message);
|
|
1464
|
-
return null;
|
|
1465
|
-
}
|
|
1466
|
-
}
|
|
1467
|
-
|
|
1468
|
-
/**
|
|
1469
|
-
* Resolve the user ID from various sources with priority:
|
|
1470
|
-
* 1. Explicit userId parameter
|
|
1471
|
-
* 2. Channel identity lookup (if channel and channelUserId provided)
|
|
1472
|
-
* 3. Single user from database
|
|
1473
|
-
* 4. Null (no user found)
|
|
1474
|
-
*/
|
|
1475
|
-
export function resolveUserId(
|
|
1476
|
-
opts: {
|
|
1477
|
-
userId?: string | null;
|
|
1478
|
-
threadId?: string | null;
|
|
1479
|
-
channel?: string | null;
|
|
1480
|
-
channelUserId?: string | null;
|
|
1481
|
-
}
|
|
1482
|
-
): string | null {
|
|
1483
|
-
// Priority 1: Explicit userId
|
|
1484
|
-
if (opts.userId) {
|
|
1485
|
-
return opts.userId;
|
|
1486
|
-
}
|
|
1487
|
-
|
|
1488
|
-
// Priority 2: Channel identity lookup
|
|
1489
|
-
if (opts.channel && opts.channelUserId) {
|
|
1490
|
-
const userId = getUserIdFromChannelIdentity(opts.channel, opts.channelUserId);
|
|
1491
|
-
if (userId) {
|
|
1492
|
-
return userId;
|
|
1493
|
-
}
|
|
1494
|
-
}
|
|
1495
|
-
|
|
1496
|
-
// Priority 3: Single user from database
|
|
1497
|
-
const singleUserId = getSingleUserId();
|
|
1498
|
-
if (singleUserId) {
|
|
1499
|
-
return singleUserId;
|
|
1500
|
-
}
|
|
1501
|
-
|
|
1502
|
-
// Priority 4: No user found
|
|
1503
|
-
return null;
|
|
1504
|
-
}
|
|
1505
|
-
|
|
1506
|
-
/**
|
|
1507
|
-
* Get the default agent ID with priority:
|
|
1508
|
-
* 1. Coordinator agent (role = 'coordinator')
|
|
1509
|
-
* 2. First enabled agent
|
|
1510
|
-
* 3. Null (no agent found)
|
|
1511
|
-
*/
|
|
1512
|
-
export function getDefaultAgentId(): string | null {
|
|
1513
|
-
try {
|
|
1514
|
-
const db = getDb();
|
|
1515
|
-
|
|
1516
|
-
// Try coordinator first
|
|
1517
|
-
const coordinator = db.query(
|
|
1518
|
-
"SELECT id FROM agents WHERE role = 'coordinator' AND enabled = 1 LIMIT 1"
|
|
1519
|
-
).get() as { id: string } | undefined;
|
|
1520
|
-
|
|
1521
|
-
if (coordinator?.id) {
|
|
1522
|
-
return coordinator.id;
|
|
1523
|
-
}
|
|
1524
|
-
|
|
1525
|
-
// Fallback to first enabled agent
|
|
1526
|
-
const firstAgent = db.query(
|
|
1527
|
-
"SELECT id FROM agents WHERE enabled = 1 LIMIT 1"
|
|
1528
|
-
).get() as { id: string } | undefined;
|
|
1529
|
-
|
|
1530
|
-
return firstAgent?.id || null;
|
|
1531
|
-
} catch (e) {
|
|
1532
|
-
log.warn("[getDefaultAgentId] ⚠️ Error getting default agent ID:", (e as Error).message);
|
|
1533
|
-
return null;
|
|
1534
|
-
}
|
|
1535
|
-
}
|
|
1536
|
-
|
|
1537
|
-
/**
|
|
1538
|
-
* Resolve the agent ID with priority:
|
|
1539
|
-
* 1. Explicit agentId parameter
|
|
1540
|
-
* 2. Coordinator agent from database
|
|
1541
|
-
* 3. First enabled agent from database
|
|
1542
|
-
* 4. Null (no agent found)
|
|
1543
|
-
*/
|
|
1544
|
-
export function resolveAgentId(agentId?: string | null): string | null {
|
|
1545
|
-
// Priority 1: Explicit agentId
|
|
1546
|
-
if (agentId) {
|
|
1547
|
-
return agentId;
|
|
1548
|
-
}
|
|
1549
|
-
|
|
1550
|
-
// Priority 2: Default from database (coordinator or first enabled)
|
|
1551
|
-
return getDefaultAgentId();
|
|
1552
|
-
}
|
|
1553
|
-
|
|
1554
|
-
/**
|
|
1555
|
-
* Get user preferences (notes) for a given user ID
|
|
1556
|
-
*/
|
|
1557
|
-
export function getUserPreferences(userId: string): string | null {
|
|
1558
|
-
try {
|
|
1559
|
-
const db = getDb();
|
|
1560
|
-
const result = db.query("SELECT notes FROM users WHERE id = ?").get(userId) as { notes: string | null } | undefined;
|
|
1561
|
-
return result?.notes || null;
|
|
1562
|
-
} catch (e) {
|
|
1563
|
-
log.warn("[getUserPreferences] ⚠️ Error getting user preferences:", (e as Error).message);
|
|
1564
|
-
return null;
|
|
1565
|
-
}
|
|
1566
|
-
}
|
|
1567
|
-
|
|
1568
|
-
/**
|
|
1569
|
-
* Get agent configuration by ID
|
|
1570
|
-
*/
|
|
1571
|
-
export function getAgentConfig(agentId: string): {
|
|
1572
|
-
id: string;
|
|
1573
|
-
user_id: string;
|
|
1574
|
-
name: string;
|
|
1575
|
-
description: string | null;
|
|
1576
|
-
system_prompt: string | null;
|
|
1577
|
-
tone: string | null;
|
|
1578
|
-
provider_id: string | null;
|
|
1579
|
-
model_id: string | null;
|
|
1580
|
-
tools_json: string | null;
|
|
1581
|
-
skills_json: string | null;
|
|
1582
|
-
max_iterations: number;
|
|
1583
|
-
} | null {
|
|
1584
|
-
try {
|
|
1585
|
-
const db = getDb();
|
|
1586
|
-
const result = db.query(`
|
|
1587
|
-
SELECT id, user_id, name, description, system_prompt, tone,
|
|
1588
|
-
provider_id, model_id, tools_json, skills_json, max_iterations
|
|
1589
|
-
FROM agents WHERE id = ?
|
|
1590
|
-
`).get(agentId) as {
|
|
1591
|
-
id: string;
|
|
1592
|
-
user_id: string;
|
|
1593
|
-
name: string;
|
|
1594
|
-
description: string | null;
|
|
1595
|
-
system_prompt: string | null;
|
|
1596
|
-
tone: string | null;
|
|
1597
|
-
provider_id: string | null;
|
|
1598
|
-
model_id: string | null;
|
|
1599
|
-
tools_json: string | null;
|
|
1600
|
-
skills_json: string | null;
|
|
1601
|
-
max_iterations: number;
|
|
1602
|
-
} | undefined;
|
|
1603
|
-
|
|
1604
|
-
return result || null;
|
|
1605
|
-
} catch (e) {
|
|
1606
|
-
log.warn("[getAgentConfig] ⚠️ Error getting agent config:", (e as Error).message);
|
|
1607
|
-
return null;
|
|
1608
|
-
}
|
|
1609
|
-
}
|