@agentprojectcontext/apx 1.25.0 → 1.27.2
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/package.json +42 -12
- package/skills/apx/SKILL.md +50 -119
- package/skills/apx-agency-agents/SKILL.md +141 -0
- package/skills/apx-agent/SKILL.md +100 -0
- package/skills/apx-mcp/SKILL.md +114 -0
- package/skills/apx-mcp-builder/SKILL.md +186 -0
- package/skills/apx-project/SKILL.md +100 -0
- package/skills/apx-routine/SKILL.md +138 -0
- package/skills/apx-runtime/SKILL.md +115 -0
- package/skills/apx-sessions/SKILL.md +281 -0
- package/skills/apx-skill-builder/SKILL.md +149 -0
- package/skills/apx-task/SKILL.md +95 -0
- package/skills/apx-telegram/SKILL.md +115 -0
- package/skills/apx-voice/SKILL.md +135 -0
- package/src/core/agent/constants.js +3 -0
- package/src/core/agent/ghost-guard.js +24 -0
- package/src/core/agent/index.js +35 -0
- package/src/core/agent/model-router.js +257 -0
- package/src/core/agent/prompt-builder.js +313 -0
- package/src/core/agent/prompts/channels/api.md +7 -0
- package/src/core/agent/prompts/channels/cli.md +6 -0
- package/src/core/agent/prompts/channels/code.md +20 -0
- package/src/core/agent/prompts/channels/deck.md +6 -0
- package/src/core/agent/prompts/channels/desktop.md +24 -0
- package/src/core/agent/prompts/channels/routine.md +9 -0
- package/src/core/agent/prompts/channels/telegram.md +9 -0
- package/src/core/agent/prompts/channels/terminal.md +16 -0
- package/src/core/agent/prompts/channels/web.md +7 -0
- package/src/core/agent/prompts/channels/web_sidebar.md +7 -0
- package/src/core/agent/prompts/modes/voice.md +4 -0
- package/src/core/agent/prompts/super-agent-base.md +42 -0
- package/src/core/agent/pseudo-tools.js +40 -0
- package/src/core/agent/retry.js +85 -0
- package/src/core/agent/run-agent.js +423 -0
- package/src/core/agent/self-memory.js +155 -0
- package/src/{daemon → core/agent}/tool-call-parser.js +83 -10
- package/src/core/agent/tools-overlap.js +66 -0
- package/src/core/apc-skill-sync.js +97 -0
- package/src/core/code-sessions-store.js +150 -0
- package/src/core/config.js +473 -11
- package/src/core/desktop/autostart.js +162 -0
- package/src/core/engines/_health.js +63 -0
- package/src/{daemon → core}/engines/anthropic.js +16 -0
- package/src/core/engines/gemini.js +168 -0
- package/src/core/engines/groq.js +8 -0
- package/src/{daemon → core}/engines/index.js +3 -1
- package/src/{daemon → core}/engines/mock.js +22 -0
- package/src/{daemon → core}/engines/ollama.js +35 -0
- package/src/core/engines/openai-compatible.js +145 -0
- package/src/core/engines/openai.js +8 -0
- package/src/core/engines/openrouter.js +8 -0
- package/src/core/git-baseline.js +147 -0
- package/src/core/identity.js +21 -0
- package/src/core/logging.js +1 -1
- package/src/core/mcp/index.js +14 -0
- package/src/{daemon/mcp-runner.js → core/mcp/runner.js} +18 -6
- package/src/core/mcp/sources.js +246 -0
- package/src/core/memory/active-threads.js +124 -0
- package/src/core/memory/broker.js +144 -0
- package/src/core/memory/compactor.js +186 -0
- package/src/core/memory/embed-engines/gemini.js +62 -0
- package/src/core/memory/embed-engines/index.js +148 -0
- package/src/core/memory/embed-engines/ollama.js +55 -0
- package/src/core/memory/embed-engines/openai.js +64 -0
- package/src/core/memory/embed-engines/tf.js +20 -0
- package/src/core/memory/embeddings.js +132 -0
- package/src/core/memory/index.js +161 -0
- package/src/core/memory/indexer.js +257 -0
- package/src/core/memory/store.js +231 -0
- package/src/core/messages-store.js +143 -25
- package/src/core/parser.js +78 -16
- package/src/core/scaffold.js +175 -79
- package/src/core/tasks-store.js +264 -0
- package/src/core/telegram-identity.js +126 -0
- package/src/core/tools/index.js +6 -0
- package/src/core/voice/engines/elevenlabs.js +96 -0
- package/src/core/voice/engines/gemini.js +148 -0
- package/src/core/voice/engines/index.js +144 -0
- package/src/core/voice/engines/mock.js +59 -0
- package/src/core/voice/engines/openai.js +82 -0
- package/src/core/voice/engines/piper.js +93 -0
- package/src/core/voice/index.js +3 -0
- package/src/core/voice/tts.js +89 -0
- package/src/{daemon → host/daemon}/apc-runtime-context.js +1 -1
- package/src/host/daemon/api/admin-config.js +159 -0
- package/src/host/daemon/api/admin.js +72 -0
- package/src/host/daemon/api/agents.js +284 -0
- package/src/host/daemon/api/artifacts.js +52 -0
- package/src/host/daemon/api/code.js +351 -0
- package/src/host/daemon/api/config.js +104 -0
- package/src/host/daemon/api/connections.js +42 -0
- package/src/host/daemon/api/conversations.js +161 -0
- package/src/host/daemon/api/deck.js +511 -0
- package/src/host/daemon/api/desktop.js +71 -0
- package/src/host/daemon/api/embeddings.js +65 -0
- package/src/host/daemon/api/engines.js +80 -0
- package/src/host/daemon/api/exec.js +193 -0
- package/src/host/daemon/api/health.js +10 -0
- package/src/host/daemon/api/identity.js +36 -0
- package/src/host/daemon/api/mcps.js +205 -0
- package/src/host/daemon/api/messages.js +83 -0
- package/src/host/daemon/api/pairing.js +194 -0
- package/src/host/daemon/api/plugins.js +19 -0
- package/src/host/daemon/api/projects.js +35 -0
- package/src/host/daemon/api/routines.js +84 -0
- package/src/host/daemon/api/run.js +55 -0
- package/src/host/daemon/api/runtimes.js +219 -0
- package/src/host/daemon/api/sessions-search.js +177 -0
- package/src/host/daemon/api/sessions.js +115 -0
- package/src/host/daemon/api/shared.js +217 -0
- package/src/host/daemon/api/super-agent.js +208 -0
- package/src/host/daemon/api/tasks.js +118 -0
- package/src/host/daemon/api/telegram.js +325 -0
- package/src/host/daemon/api/tools.js +21 -0
- package/src/host/daemon/api/top-level.js +131 -0
- package/src/host/daemon/api/transcribe.js +35 -0
- package/src/host/daemon/api/tts.js +44 -0
- package/src/host/daemon/api/voice.js +519 -0
- package/src/host/daemon/api/web.js +123 -0
- package/src/host/daemon/api.js +152 -0
- package/src/{daemon → host/daemon}/compact.js +1 -1
- package/src/{daemon → host/daemon}/db.js +19 -5
- package/src/{daemon/overlay-ws.js → host/daemon/desktop-ws.js} +7 -7
- package/src/host/daemon/engine-sessions.js +245 -0
- package/src/{daemon → host/daemon}/index.js +27 -10
- package/src/{daemon/plugins/overlay.js → host/daemon/plugins/desktop.js} +36 -28
- package/src/{daemon → host/daemon}/plugins/index.js +2 -2
- package/src/{daemon → host/daemon}/plugins/telegram.js +165 -33
- package/src/{daemon → host/daemon}/project-config.js +31 -7
- package/src/{daemon → host/daemon}/routines.js +27 -8
- package/src/{daemon → host/daemon}/skills-loader.js +4 -2
- package/src/{daemon → host/daemon}/smoke.js +9 -5
- package/src/{daemon → host/daemon}/super-agent-tools/helpers.js +1 -1
- package/src/host/daemon/super-agent-tools/index.js +157 -0
- package/src/{daemon → host/daemon}/super-agent-tools/registry-bridge.js +1 -1
- package/src/{daemon → host/daemon}/super-agent-tools/tools/add-project.js +2 -2
- package/src/{daemon → host/daemon}/super-agent-tools/tools/ask-questions.js +4 -0
- package/src/{daemon → host/daemon}/super-agent-tools/tools/call-agent.js +5 -2
- package/src/{daemon → host/daemon}/super-agent-tools/tools/call-runtime.js +117 -8
- package/src/host/daemon/super-agent-tools/tools/create-task.js +52 -0
- package/src/{daemon → host/daemon}/super-agent-tools/tools/import-agent.js +2 -3
- package/src/{daemon → host/daemon}/super-agent-tools/tools/list-agents.js +1 -1
- package/src/host/daemon/super-agent-tools/tools/list-tasks.js +52 -0
- package/src/{daemon → host/daemon}/super-agent-tools/tools/list-vault-agents.js +1 -1
- package/src/host/daemon/super-agent-tools/tools/read-self-memory.js +21 -0
- package/src/host/daemon/super-agent-tools/tools/remember.js +40 -0
- package/src/{daemon → host/daemon}/super-agent-tools/tools/search-messages.js +1 -1
- package/src/host/daemon/super-agent-tools/tools/search-sessions.js +134 -0
- package/src/{daemon → host/daemon}/super-agent-tools/tools/send-telegram.js +2 -2
- package/src/{daemon → host/daemon}/super-agent-tools/tools/set-identity.js +1 -1
- package/src/{daemon → host/daemon}/super-agent-tools/tools/set-permission-mode.js +1 -1
- package/src/{daemon → host/daemon}/super-agent-tools/tools/tail-messages.js +1 -1
- package/src/host/daemon/super-agent.js +129 -0
- package/src/host/daemon/token-store.js +118 -0
- package/src/host/daemon/tool-call-parser.js +2 -0
- package/src/{daemon → host/daemon}/transcription.js +1 -1
- package/src/{daemon → host/daemon}/wakeup.js +2 -2
- package/src/interfaces/cli/claude-permissions.js +33 -0
- package/src/{cli → interfaces/cli}/commands/agent.js +43 -8
- package/src/{cli → interfaces/cli}/commands/command.js +1 -1
- package/src/{cli → interfaces/cli}/commands/config.js +1 -1
- package/src/{cli → interfaces/cli}/commands/daemon.js +67 -0
- package/src/interfaces/cli/commands/desktop.js +335 -0
- package/src/interfaces/cli/commands/exec.js +92 -0
- package/src/{cli → interfaces/cli}/commands/identity.js +6 -63
- package/src/{cli → interfaces/cli}/commands/init.js +1 -1
- package/src/{cli → interfaces/cli}/commands/mcp.js +69 -10
- package/src/{cli → interfaces/cli}/commands/memory.js +2 -2
- package/src/interfaces/cli/commands/model.js +136 -0
- package/src/interfaces/cli/commands/pair.js +170 -0
- package/src/interfaces/cli/commands/project-config.js +131 -0
- package/src/{cli → interfaces/cli}/commands/project.js +1 -1
- package/src/{cli → interfaces/cli}/commands/search.js +1 -1
- package/src/interfaces/cli/commands/session.js +892 -0
- package/src/interfaces/cli/commands/sessions.js +997 -0
- package/src/{cli → interfaces/cli}/commands/setup.js +98 -4
- package/src/{cli → interfaces/cli}/commands/skills.js +117 -9
- package/src/{cli → interfaces/cli}/commands/status.js +9 -1
- package/src/{cli → interfaces/cli}/commands/sys.js +96 -17
- package/src/interfaces/cli/commands/task.js +179 -0
- package/src/interfaces/cli/commands/telegram.js +366 -0
- package/src/{cli → interfaces/cli}/commands/update.js +1 -1
- package/src/interfaces/cli/commands/voice.js +258 -0
- package/src/{cli → interfaces/cli}/http.js +6 -2
- package/src/{cli → interfaces/cli}/index.js +955 -63
- package/src/interfaces/cli/postinstall.js +34 -0
- package/src/interfaces/desktop/assets/app-icon-180.png +0 -0
- package/src/interfaces/desktop/assets/app-icon-32.png +0 -0
- package/src/interfaces/desktop/assets/app-icon.png +0 -0
- package/src/interfaces/desktop/assets/apx-logo.png +0 -0
- package/src/interfaces/desktop/assets/superagent.png +0 -0
- package/src/interfaces/desktop/assets/tray-icon.png +0 -0
- package/src/interfaces/desktop/index.html +18 -0
- package/src/interfaces/desktop/main.js +652 -0
- package/src/interfaces/desktop/preload.js +48 -0
- package/src/interfaces/desktop/renderer.js +1006 -0
- package/src/interfaces/desktop/style.css +400 -0
- package/src/{mcp → interfaces/mcp-server}/index.js +2 -2
- package/src/interfaces/tui/_shims/util-which.ts +53 -0
- package/src/{tui → interfaces/tui}/app.tsx +2 -2
- package/src/{tui → interfaces/tui}/component/prompt/index.tsx +4 -1
- package/src/{tui → interfaces/tui}/context/sdk-apx.tsx +84 -16
- package/src/interfaces/tui/context/sync-apx.tsx +398 -0
- package/src/interfaces/tui/routes/session/index.tsx +368 -0
- package/src/interfaces/tui/routes/session/message-actions.tsx +58 -0
- package/src/interfaces/tui/routes/session/sidebar-apx.tsx +114 -0
- package/src/{tui → interfaces/tui}/tsconfig.json +1 -0
- package/src/{tui → interfaces/tui}/util/clipboard.ts +1 -1
- package/src/interfaces/web/README.md +102 -0
- package/src/interfaces/web/coming-soon.html +65 -0
- package/src/interfaces/web/components.json +25 -0
- package/src/interfaces/web/dist/assets/index-BDUsA6L6.css +1 -0
- package/src/interfaces/web/dist/assets/index-CfWyjPBa.js +548 -0
- package/src/interfaces/web/dist/assets/index-CfWyjPBa.js.map +1 -0
- package/src/interfaces/web/dist/favicon/dark/android-chrome-192x192.png +0 -0
- package/src/interfaces/web/dist/favicon/dark/android-chrome-512x512.png +0 -0
- package/src/interfaces/web/dist/favicon/dark/apple-touch-icon.png +0 -0
- package/src/interfaces/web/dist/favicon/dark/favicon-16x16.png +0 -0
- package/src/interfaces/web/dist/favicon/dark/favicon-32x32.png +0 -0
- package/src/interfaces/web/dist/favicon/dark/favicon-48x48.png +0 -0
- package/src/interfaces/web/dist/favicon/dark/favicon.ico +0 -0
- package/src/interfaces/web/dist/favicon/dark/favicon.webp +0 -0
- package/src/interfaces/web/dist/favicon/dark/site.webmanifest +18 -0
- package/src/interfaces/web/dist/favicon/white/android-chrome-192x192.png +0 -0
- package/src/interfaces/web/dist/favicon/white/android-chrome-512x512.png +0 -0
- package/src/interfaces/web/dist/favicon/white/apple-touch-icon.png +0 -0
- package/src/interfaces/web/dist/favicon/white/favicon-16x16.png +0 -0
- package/src/interfaces/web/dist/favicon/white/favicon-32x32.png +0 -0
- package/src/interfaces/web/dist/favicon/white/favicon-48x48.png +0 -0
- package/src/interfaces/web/dist/favicon/white/favicon.ico +0 -0
- package/src/interfaces/web/dist/favicon/white/favicon.webp +0 -0
- package/src/interfaces/web/dist/favicon/white/site.webmanifest +18 -0
- package/src/interfaces/web/dist/index.html +27 -0
- package/src/interfaces/web/dist/logo/logo_dark.webp +0 -0
- package/src/interfaces/web/dist/logo/logo_only_dark.webp +0 -0
- package/src/interfaces/web/dist/logo/logo_only_white.webp +0 -0
- package/src/interfaces/web/dist/logo/logo_vertical_dark.webp +0 -0
- package/src/interfaces/web/dist/logo/logo_vertical_white.webp +0 -0
- package/src/interfaces/web/dist/logo/logo_white.webp +0 -0
- package/src/interfaces/web/dist/modules/superagent.png +0 -0
- package/src/interfaces/web/index.html +26 -0
- package/src/interfaces/web/package-lock.json +4253 -0
- package/src/interfaces/web/package.json +55 -0
- package/src/interfaces/web/playwright.config.ts +45 -0
- package/src/interfaces/web/pnpm-lock.yaml +2946 -0
- package/src/interfaces/web/public/favicon/dark/android-chrome-192x192.png +0 -0
- package/src/interfaces/web/public/favicon/dark/android-chrome-512x512.png +0 -0
- package/src/interfaces/web/public/favicon/dark/apple-touch-icon.png +0 -0
- package/src/interfaces/web/public/favicon/dark/favicon-16x16.png +0 -0
- package/src/interfaces/web/public/favicon/dark/favicon-32x32.png +0 -0
- package/src/interfaces/web/public/favicon/dark/favicon-48x48.png +0 -0
- package/src/interfaces/web/public/favicon/dark/favicon.ico +0 -0
- package/src/interfaces/web/public/favicon/dark/favicon.webp +0 -0
- package/src/interfaces/web/public/favicon/dark/site.webmanifest +18 -0
- package/src/interfaces/web/public/favicon/white/android-chrome-192x192.png +0 -0
- package/src/interfaces/web/public/favicon/white/android-chrome-512x512.png +0 -0
- package/src/interfaces/web/public/favicon/white/apple-touch-icon.png +0 -0
- package/src/interfaces/web/public/favicon/white/favicon-16x16.png +0 -0
- package/src/interfaces/web/public/favicon/white/favicon-32x32.png +0 -0
- package/src/interfaces/web/public/favicon/white/favicon-48x48.png +0 -0
- package/src/interfaces/web/public/favicon/white/favicon.ico +0 -0
- package/src/interfaces/web/public/favicon/white/favicon.webp +0 -0
- package/src/interfaces/web/public/favicon/white/site.webmanifest +18 -0
- package/src/interfaces/web/public/logo/logo_dark.webp +0 -0
- package/src/interfaces/web/public/logo/logo_only_dark.webp +0 -0
- package/src/interfaces/web/public/logo/logo_only_white.webp +0 -0
- package/src/interfaces/web/public/logo/logo_vertical_dark.webp +0 -0
- package/src/interfaces/web/public/logo/logo_vertical_white.webp +0 -0
- package/src/interfaces/web/public/logo/logo_white.webp +0 -0
- package/src/interfaces/web/public/modules/superagent.png +0 -0
- package/src/interfaces/web/src/App.tsx +199 -0
- package/src/interfaces/web/src/components/AddProjectDialog.tsx +121 -0
- package/src/interfaces/web/src/components/ModelCombobox.tsx +96 -0
- package/src/interfaces/web/src/components/RobyBubble.tsx +213 -0
- package/src/interfaces/web/src/components/Section.tsx +44 -0
- package/src/interfaces/web/src/components/TelegramChannelDialog.tsx +97 -0
- package/src/interfaces/web/src/components/TelegramSendDialog.tsx +48 -0
- package/src/interfaces/web/src/components/Toast.tsx +84 -0
- package/src/interfaces/web/src/components/UiSelect.tsx +74 -0
- package/src/interfaces/web/src/components/chat/Composer.tsx +43 -0
- package/src/interfaces/web/src/components/chat/ContextBar.tsx +111 -0
- package/src/interfaces/web/src/components/chat/MessageBubble.tsx +95 -0
- package/src/interfaces/web/src/components/chat/MessageList.tsx +35 -0
- package/src/interfaces/web/src/components/chat/ModelPicker.tsx +145 -0
- package/src/interfaces/web/src/components/chat/ToolCall.tsx +141 -0
- package/src/interfaces/web/src/components/code/CodeChangesTab.tsx +87 -0
- package/src/interfaces/web/src/components/code/CodeComposer.tsx +87 -0
- package/src/interfaces/web/src/components/code/CodeContextTab.tsx +83 -0
- package/src/interfaces/web/src/components/code/CodeProjectPicker.tsx +39 -0
- package/src/interfaces/web/src/components/code/CodeSessionList.tsx +97 -0
- package/src/interfaces/web/src/components/code/CodeSidePanel.tsx +44 -0
- package/src/interfaces/web/src/components/code/CodeToolTrail.tsx +29 -0
- package/src/interfaces/web/src/components/code/DiffView.tsx +67 -0
- package/src/interfaces/web/src/components/common/Qr.tsx +27 -0
- package/src/interfaces/web/src/components/common/TabLayout.tsx +46 -0
- package/src/interfaces/web/src/components/common/TabNav.tsx +113 -0
- package/src/interfaces/web/src/components/config/ConfigTabsEditor.tsx +202 -0
- package/src/interfaces/web/src/components/config/GlobalConfigEditor.tsx +42 -0
- package/src/interfaces/web/src/components/config/global-config-sections.ts +60 -0
- package/src/interfaces/web/src/components/config/project-config-sections.ts +58 -0
- package/src/interfaces/web/src/components/deck/DaemonCard.tsx +58 -0
- package/src/interfaces/web/src/components/deck/DesktopGroup.tsx +33 -0
- package/src/interfaces/web/src/components/deck/WidgetRow.tsx +100 -0
- package/src/interfaces/web/src/components/layout/Logo.tsx +59 -0
- package/src/interfaces/web/src/components/layout/ProjectAvatar.tsx +116 -0
- package/src/interfaces/web/src/components/layout/ProjectSidebar.tsx +151 -0
- package/src/interfaces/web/src/components/settings/AdvancedPanel.tsx +45 -0
- package/src/interfaces/web/src/components/settings/AppearancePanel.tsx +72 -0
- package/src/interfaces/web/src/components/settings/DefaultRouterCard.tsx +232 -0
- package/src/interfaces/web/src/components/settings/DevicesPanel.tsx +60 -0
- package/src/interfaces/web/src/components/settings/EnginesPanel.tsx +127 -0
- package/src/interfaces/web/src/components/settings/IdentityPanel.tsx +69 -0
- package/src/interfaces/web/src/components/settings/MemoryPanel.tsx +226 -0
- package/src/interfaces/web/src/components/settings/PairDeviceDialog.tsx +175 -0
- package/src/interfaces/web/src/components/settings/SuperAgentPanel.tsx +93 -0
- package/src/interfaces/web/src/components/settings/TelegramChannelsPanel.tsx +90 -0
- package/src/interfaces/web/src/components/settings/TelegramContactsPanel.tsx +101 -0
- package/src/interfaces/web/src/components/settings/TelegramGlobalPanel.tsx +100 -0
- package/src/interfaces/web/src/components/settings/TelegramRolesPanel.tsx +108 -0
- package/src/interfaces/web/src/components/settings/TelegramSettingsTabs.tsx +55 -0
- package/src/interfaces/web/src/components/settings/providers/ProviderCard.tsx +95 -0
- package/src/interfaces/web/src/components/settings/providers/ProviderModal.tsx +405 -0
- package/src/interfaces/web/src/components/settings/providers/typeStyles.ts +155 -0
- package/src/interfaces/web/src/components/settings/providers/types.ts +26 -0
- package/src/interfaces/web/src/components/ui/accordion.tsx +72 -0
- package/src/interfaces/web/src/components/ui/alert-dialog.tsx +187 -0
- package/src/interfaces/web/src/components/ui/alert.tsx +76 -0
- package/src/interfaces/web/src/components/ui/aspect-ratio.tsx +22 -0
- package/src/interfaces/web/src/components/ui/avatar.tsx +107 -0
- package/src/interfaces/web/src/components/ui/badge.tsx +52 -0
- package/src/interfaces/web/src/components/ui/breadcrumb.tsx +125 -0
- package/src/interfaces/web/src/components/ui/button-group.tsx +87 -0
- package/src/interfaces/web/src/components/ui/button.tsx +58 -0
- package/src/interfaces/web/src/components/ui/calendar.tsx +221 -0
- package/src/interfaces/web/src/components/ui/card.tsx +103 -0
- package/src/interfaces/web/src/components/ui/carousel.tsx +242 -0
- package/src/interfaces/web/src/components/ui/chart.tsx +371 -0
- package/src/interfaces/web/src/components/ui/chat-input.tsx +122 -0
- package/src/interfaces/web/src/components/ui/checkbox.tsx +29 -0
- package/src/interfaces/web/src/components/ui/collapsible.tsx +19 -0
- package/src/interfaces/web/src/components/ui/combobox.tsx +295 -0
- package/src/interfaces/web/src/components/ui/command.tsx +196 -0
- package/src/interfaces/web/src/components/ui/context-menu.tsx +271 -0
- package/src/interfaces/web/src/components/ui/dialog.tsx +158 -0
- package/src/interfaces/web/src/components/ui/direction.tsx +4 -0
- package/src/interfaces/web/src/components/ui/drawer.tsx +134 -0
- package/src/interfaces/web/src/components/ui/dropdown-menu.tsx +266 -0
- package/src/interfaces/web/src/components/ui/empty.tsx +104 -0
- package/src/interfaces/web/src/components/ui/field.tsx +236 -0
- package/src/interfaces/web/src/components/ui/hover-card.tsx +51 -0
- package/src/interfaces/web/src/components/ui/input-group.tsx +158 -0
- package/src/interfaces/web/src/components/ui/input-otp.tsx +85 -0
- package/src/interfaces/web/src/components/ui/input.tsx +20 -0
- package/src/interfaces/web/src/components/ui/item.tsx +201 -0
- package/src/interfaces/web/src/components/ui/kbd.tsx +26 -0
- package/src/interfaces/web/src/components/ui/label.tsx +20 -0
- package/src/interfaces/web/src/components/ui/menubar.tsx +280 -0
- package/src/interfaces/web/src/components/ui/native-select.tsx +61 -0
- package/src/interfaces/web/src/components/ui/navigation-menu.tsx +168 -0
- package/src/interfaces/web/src/components/ui/pagination.tsx +130 -0
- package/src/interfaces/web/src/components/ui/popover.tsx +88 -0
- package/src/interfaces/web/src/components/ui/progress.tsx +83 -0
- package/src/interfaces/web/src/components/ui/radio-group.tsx +36 -0
- package/src/interfaces/web/src/components/ui/resizable.tsx +50 -0
- package/src/interfaces/web/src/components/ui/scroll-area.tsx +53 -0
- package/src/interfaces/web/src/components/ui/select.tsx +201 -0
- package/src/interfaces/web/src/components/ui/separator.tsx +23 -0
- package/src/interfaces/web/src/components/ui/sheet.tsx +138 -0
- package/src/interfaces/web/src/components/ui/sidebar.tsx +723 -0
- package/src/interfaces/web/src/components/ui/skeleton.tsx +13 -0
- package/src/interfaces/web/src/components/ui/slider.tsx +52 -0
- package/src/interfaces/web/src/components/ui/sonner.tsx +49 -0
- package/src/interfaces/web/src/components/ui/spinner.tsx +10 -0
- package/src/interfaces/web/src/components/ui/switch.tsx +30 -0
- package/src/interfaces/web/src/components/ui/table.tsx +116 -0
- package/src/interfaces/web/src/components/ui/tabs.tsx +72 -0
- package/src/interfaces/web/src/components/ui/textarea.tsx +18 -0
- package/src/interfaces/web/src/components/ui/tip.tsx +21 -0
- package/src/interfaces/web/src/components/ui/toggle-group.tsx +87 -0
- package/src/interfaces/web/src/components/ui/toggle.tsx +45 -0
- package/src/interfaces/web/src/components/ui/tooltip.tsx +64 -0
- package/src/interfaces/web/src/components/ui.tsx +211 -0
- package/src/interfaces/web/src/components/voice/VoiceProviderList.tsx +197 -0
- package/src/interfaces/web/src/components/voice/VoiceProviderModal.tsx +213 -0
- package/src/interfaces/web/src/components/voice/VoiceSttCard.tsx +72 -0
- package/src/interfaces/web/src/components/voice/VoiceTestCard.tsx +112 -0
- package/src/interfaces/web/src/components/voice/useTtsPlayer.ts +59 -0
- package/src/interfaces/web/src/constants/index.ts +91 -0
- package/src/interfaces/web/src/hooks/use-mobile.ts +19 -0
- package/src/interfaces/web/src/hooks/useChat.ts +276 -0
- package/src/interfaces/web/src/hooks/useDaemonStatus.ts +12 -0
- package/src/interfaces/web/src/hooks/useDevices.ts +12 -0
- package/src/interfaces/web/src/hooks/useEngines.ts +10 -0
- package/src/interfaces/web/src/hooks/useGlobalConfig.ts +24 -0
- package/src/interfaces/web/src/hooks/useIdentity.ts +16 -0
- package/src/interfaces/web/src/hooks/useProjects.ts +27 -0
- package/src/interfaces/web/src/hooks/useTelegram.ts +35 -0
- package/src/interfaces/web/src/hooks/useTheme.tsx +57 -0
- package/src/interfaces/web/src/hooks/useTokenBootstrap.ts +122 -0
- package/src/interfaces/web/src/i18n/en.ts +767 -0
- package/src/interfaces/web/src/i18n/es.ts +770 -0
- package/src/interfaces/web/src/i18n/index.ts +86 -0
- package/src/interfaces/web/src/lib/api/admin.ts +30 -0
- package/src/interfaces/web/src/lib/api/agents.ts +46 -0
- package/src/interfaces/web/src/lib/api/code.ts +122 -0
- package/src/interfaces/web/src/lib/api/conversations.ts +16 -0
- package/src/interfaces/web/src/lib/api/deck.ts +106 -0
- package/src/interfaces/web/src/lib/api/desktop.ts +54 -0
- package/src/interfaces/web/src/lib/api/embeddings.ts +44 -0
- package/src/interfaces/web/src/lib/api/engines.ts +17 -0
- package/src/interfaces/web/src/lib/api/filesystem.ts +12 -0
- package/src/interfaces/web/src/lib/api/health.ts +6 -0
- package/src/interfaces/web/src/lib/api/identity.ts +7 -0
- package/src/interfaces/web/src/lib/api/mcps.ts +29 -0
- package/src/interfaces/web/src/lib/api/messages.ts +24 -0
- package/src/interfaces/web/src/lib/api/projects.ts +29 -0
- package/src/interfaces/web/src/lib/api/routines.ts +14 -0
- package/src/interfaces/web/src/lib/api/sessions.ts +16 -0
- package/src/interfaces/web/src/lib/api/super_agent.ts +29 -0
- package/src/interfaces/web/src/lib/api/tasks.ts +19 -0
- package/src/interfaces/web/src/lib/api/telegram.ts +57 -0
- package/src/interfaces/web/src/lib/api/tools.ts +13 -0
- package/src/interfaces/web/src/lib/api/voice.ts +169 -0
- package/src/interfaces/web/src/lib/api.ts +48 -0
- package/src/interfaces/web/src/lib/cn.ts +6 -0
- package/src/interfaces/web/src/lib/code-context.ts +83 -0
- package/src/interfaces/web/src/lib/config-values.ts +29 -0
- package/src/interfaces/web/src/lib/device.ts +10 -0
- package/src/interfaces/web/src/lib/http.ts +104 -0
- package/src/interfaces/web/src/lib/secrets.ts +15 -0
- package/src/interfaces/web/src/lib/utils.ts +6 -0
- package/src/interfaces/web/src/main.tsx +16 -0
- package/src/interfaces/web/src/screens/ApxAdminScreen.tsx +174 -0
- package/src/interfaces/web/src/screens/PairingScreen.tsx +105 -0
- package/src/interfaces/web/src/screens/ProjectScreen.tsx +178 -0
- package/src/interfaces/web/src/screens/SettingsScreen.tsx +111 -0
- package/src/interfaces/web/src/screens/base/AgentDefaultsTab.tsx +274 -0
- package/src/interfaces/web/src/screens/base/ComingSoon.tsx +16 -0
- package/src/interfaces/web/src/screens/base/GlobalTasksTab.tsx +53 -0
- package/src/interfaces/web/src/screens/base/LogsTab.tsx +188 -0
- package/src/interfaces/web/src/screens/base/ModelsTab.tsx +13 -0
- package/src/interfaces/web/src/screens/base/SessionsTab.tsx +58 -0
- package/src/interfaces/web/src/screens/base/WorkspacesTab.tsx +49 -0
- package/src/interfaces/web/src/screens/modules/CodeScreen.tsx +295 -0
- package/src/interfaces/web/src/screens/modules/DeckScreen.tsx +173 -0
- package/src/interfaces/web/src/screens/modules/DesktopScreen.tsx +304 -0
- package/src/interfaces/web/src/screens/modules/VoiceScreen.tsx +174 -0
- package/src/interfaces/web/src/screens/project/AgentBrainGraph.tsx +152 -0
- package/src/interfaces/web/src/screens/project/AgentDetailScreen.tsx +455 -0
- package/src/interfaces/web/src/screens/project/AgentsTab.tsx +364 -0
- package/src/interfaces/web/src/screens/project/ChatTab.tsx +198 -0
- package/src/interfaces/web/src/screens/project/ConfigTab.tsx +94 -0
- package/src/interfaces/web/src/screens/project/McpsTab.tsx +149 -0
- package/src/interfaces/web/src/screens/project/MemoriesTab.tsx +134 -0
- package/src/interfaces/web/src/screens/project/Overview.tsx +37 -0
- package/src/interfaces/web/src/screens/project/RoutinesTab.tsx +386 -0
- package/src/interfaces/web/src/screens/project/TasksTab.tsx +116 -0
- package/src/interfaces/web/src/screens/project/TelegramTab.tsx +126 -0
- package/src/interfaces/web/src/screens/project/ThreadsTab.tsx +100 -0
- package/src/interfaces/web/src/styles.css +128 -0
- package/src/interfaces/web/src/types/daemon.ts +289 -0
- package/src/interfaces/web/tailwind.config.js +53 -0
- package/src/interfaces/web/tsconfig.json +24 -0
- package/src/interfaces/web/vite.config.ts +50 -0
- package/src/cli/commands/exec.js +0 -56
- package/src/cli/commands/overlay.js +0 -253
- package/src/cli/commands/session.js +0 -395
- package/src/cli/commands/sessions.js +0 -517
- package/src/cli/commands/telegram.js +0 -77
- package/src/cli/postinstall.js +0 -75
- package/src/cli-ts/commands/agent.ts +0 -173
- package/src/cli-ts/commands/chat.ts +0 -119
- package/src/cli-ts/commands/daemon.ts +0 -112
- package/src/cli-ts/commands/exec.ts +0 -109
- package/src/cli-ts/commands/mcp.ts +0 -235
- package/src/cli-ts/commands/session.ts +0 -224
- package/src/cli-ts/commands/status.ts +0 -61
- package/src/cli-ts/http.ts +0 -36
- package/src/cli-ts/index.ts +0 -73
- package/src/cli-ts/ui.ts +0 -107
- package/src/daemon/api.js +0 -1558
- package/src/daemon/engines/gemini.js +0 -56
- package/src/daemon/engines/openai.js +0 -79
- package/src/daemon/mcp-sources.js +0 -114
- package/src/daemon/super-agent-tools/index.js +0 -84
- package/src/daemon/super-agent-tools.js +0 -1
- package/src/daemon/super-agent.js +0 -541
- package/src/overlay/index.html +0 -44
- package/src/overlay/main.js +0 -480
- package/src/overlay/preload.js +0 -34
- package/src/overlay/renderer.js +0 -371
- package/src/overlay/style.css +0 -250
- package/src/tui/context/sync-apx.tsx +0 -284
- package/src/tui/routes/session/index.tsx +0 -274
- package/src/tui/routes/session/sidebar-apx.tsx +0 -90
- /package/src/{daemon → core}/tools/browser.js +0 -0
- /package/src/{daemon → core}/tools/fetch.js +0 -0
- /package/src/{daemon → core}/tools/glob.js +0 -0
- /package/src/{daemon → core}/tools/grep.js +0 -0
- /package/src/{daemon → core}/tools/registry.js +0 -0
- /package/src/{daemon → core}/tools/search.js +0 -0
- /package/src/{daemon → host/daemon}/conversations.js +0 -0
- /package/src/{daemon → host/daemon}/env-detect.js +0 -0
- /package/src/{daemon → host/daemon}/runtimes/_spawn.js +0 -0
- /package/src/{daemon → host/daemon}/runtimes/aider.js +0 -0
- /package/src/{daemon → host/daemon}/runtimes/claude-code.js +0 -0
- /package/src/{daemon → host/daemon}/runtimes/codex.js +0 -0
- /package/src/{daemon → host/daemon}/runtimes/cursor-agent.js +0 -0
- /package/src/{daemon → host/daemon}/runtimes/gemini-cli.js +0 -0
- /package/src/{daemon → host/daemon}/runtimes/index.js +0 -0
- /package/src/{daemon → host/daemon}/runtimes/opencode.js +0 -0
- /package/src/{daemon → host/daemon}/runtimes/qwen-code.js +0 -0
- /package/src/{daemon → host/daemon}/super-agent-tools/tools/call-mcp.js +0 -0
- /package/src/{daemon → host/daemon}/super-agent-tools/tools/edit-file.js +0 -0
- /package/src/{daemon → host/daemon}/super-agent-tools/tools/list-files.js +0 -0
- /package/src/{daemon → host/daemon}/super-agent-tools/tools/list-mcps.js +0 -0
- /package/src/{daemon → host/daemon}/super-agent-tools/tools/list-projects.js +0 -0
- /package/src/{daemon → host/daemon}/super-agent-tools/tools/list-skills.js +0 -0
- /package/src/{daemon → host/daemon}/super-agent-tools/tools/load-skill.js +0 -0
- /package/src/{daemon → host/daemon}/super-agent-tools/tools/read-agent-memory.js +0 -0
- /package/src/{daemon → host/daemon}/super-agent-tools/tools/read-file.js +0 -0
- /package/src/{daemon → host/daemon}/super-agent-tools/tools/run-shell.js +0 -0
- /package/src/{daemon → host/daemon}/super-agent-tools/tools/search-files.js +0 -0
- /package/src/{daemon → host/daemon}/super-agent-tools/tools/transcribe-audio.js +0 -0
- /package/src/{daemon → host/daemon}/super-agent-tools/tools/write-file.js +0 -0
- /package/src/{daemon → host/daemon}/thinking.js +0 -0
- /package/src/{daemon → host/daemon}/whisper-server.py +0 -0
- /package/src/{daemon → host/daemon}/whisper-transcribe.py +0 -0
- /package/src/{cli → interfaces/cli}/commands/a2a.js +0 -0
- /package/src/{cli → interfaces/cli}/commands/artifact.js +0 -0
- /package/src/{cli → interfaces/cli}/commands/chat.js +0 -0
- /package/src/{cli → interfaces/cli}/commands/log.js +0 -0
- /package/src/{cli → interfaces/cli}/commands/messages.js +0 -0
- /package/src/{cli → interfaces/cli}/commands/plugins.js +0 -0
- /package/src/{cli → interfaces/cli}/commands/routine.js +0 -0
- /package/src/{cli → interfaces/cli}/commands/runtime.js +0 -0
- /package/src/{cli → interfaces/cli}/terminal-chat/renderer.js +0 -0
- /package/src/{overlay → interfaces/desktop}/package.json +0 -0
- /package/src/{tui → interfaces/tui}/_shims/cli-error.ts +0 -0
- /package/src/{tui → interfaces/tui}/_shims/cli-logo.ts +0 -0
- /package/src/{tui → interfaces/tui}/_shims/cli-ui.ts +0 -0
- /package/src/{tui → interfaces/tui}/_shims/config-console-state.ts +0 -0
- /package/src/{tui → interfaces/tui}/_shims/core-any.ts +0 -0
- /package/src/{tui → interfaces/tui}/_shims/core-binary.ts +0 -0
- /package/src/{tui → interfaces/tui}/_shims/core-flag.ts +0 -0
- /package/src/{tui → interfaces/tui}/_shims/core-log.ts +0 -0
- /package/src/{tui → interfaces/tui}/_shims/lsp-language.ts +0 -0
- /package/src/{tui → interfaces/tui}/_shims/opencode-any.ts +0 -0
- /package/src/{tui → interfaces/tui}/_shims/opencode-sdk-v2.ts +0 -0
- /package/src/{tui → interfaces/tui}/_shims/plugin-tui.ts +0 -0
- /package/src/{tui → interfaces/tui}/_shims/prompt-display.ts +0 -0
- /package/src/{tui → interfaces/tui}/_shims/provider-provider.ts +0 -0
- /package/src/{tui → interfaces/tui}/_shims/session-retry.ts +0 -0
- /package/src/{tui → interfaces/tui}/_shims/session-schema.ts +0 -0
- /package/src/{tui → interfaces/tui}/_shims/session-session.ts +0 -0
- /package/src/{tui → interfaces/tui}/_shims/snapshot.ts +0 -0
- /package/src/{tui → interfaces/tui}/_shims/tool-any.ts +0 -0
- /package/src/{tui → interfaces/tui}/_shims/util-error.ts +0 -0
- /package/src/{tui → interfaces/tui}/_shims/util-filesystem.ts +0 -0
- /package/src/{tui → interfaces/tui}/_shims/util-format.ts +0 -0
- /package/src/{tui → interfaces/tui}/_shims/util-iife.ts +0 -0
- /package/src/{tui → interfaces/tui}/_shims/util-locale.ts +0 -0
- /package/src/{tui → interfaces/tui}/_shims/util-process.ts +0 -0
- /package/src/{tui → interfaces/tui}/asset/charge.wav +0 -0
- /package/src/{tui → interfaces/tui}/asset/pulse-a.wav +0 -0
- /package/src/{tui → interfaces/tui}/asset/pulse-b.wav +0 -0
- /package/src/{tui → interfaces/tui}/asset/pulse-c.wav +0 -0
- /package/src/{tui → interfaces/tui}/attach.ts +0 -0
- /package/src/{tui → interfaces/tui}/component/bg-pulse-render.ts +0 -0
- /package/src/{tui → interfaces/tui}/component/bg-pulse.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/border.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/dialog-agent.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/dialog-console-org.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/dialog-mcp.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/dialog-model.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/dialog-provider.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/dialog-retry-action.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/dialog-session-delete-failed.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/dialog-session-list.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/dialog-session-rename.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/dialog-skill.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/dialog-stash.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/dialog-status.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/dialog-tag.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/dialog-theme-list.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/dialog-variant.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/dialog-workspace-create.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/dialog-workspace-file-changes.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/dialog-workspace-unavailable.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/error-component.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/logo.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/plugin-route-missing.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/prompt/autocomplete.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/prompt/cwd.ts +0 -0
- /package/src/{tui → interfaces/tui}/component/prompt/frecency.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/prompt/history.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/prompt/part.ts +0 -0
- /package/src/{tui → interfaces/tui}/component/prompt/stash.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/prompt/traits.ts +0 -0
- /package/src/{tui → interfaces/tui}/component/spinner.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/startup-loading.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/todo-item.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/use-connected.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/workspace-label.tsx +0 -0
- /package/src/{tui → interfaces/tui}/config/cwd.ts +0 -0
- /package/src/{tui → interfaces/tui}/config/keybind.ts +0 -0
- /package/src/{tui → interfaces/tui}/config/tui-migrate.ts +0 -0
- /package/src/{tui → interfaces/tui}/config/tui-schema.ts +0 -0
- /package/src/{tui → interfaces/tui}/config/tui.ts +0 -0
- /package/src/{tui → interfaces/tui}/context/aggregate-failures.ts +0 -0
- /package/src/{tui → interfaces/tui}/context/args.tsx +0 -0
- /package/src/{tui → interfaces/tui}/context/command-palette.tsx +0 -0
- /package/src/{tui → interfaces/tui}/context/directory.ts +0 -0
- /package/src/{tui → interfaces/tui}/context/editor-zed.ts +0 -0
- /package/src/{tui → interfaces/tui}/context/editor.ts +0 -0
- /package/src/{tui → interfaces/tui}/context/event-apx.ts +0 -0
- /package/src/{tui → interfaces/tui}/context/event.ts +0 -0
- /package/src/{tui → interfaces/tui}/context/exit.tsx +0 -0
- /package/src/{tui → interfaces/tui}/context/helper.tsx +0 -0
- /package/src/{tui → interfaces/tui}/context/kv.tsx +0 -0
- /package/src/{tui → interfaces/tui}/context/local.tsx +0 -0
- /package/src/{tui → interfaces/tui}/context/path-format.tsx +0 -0
- /package/src/{tui → interfaces/tui}/context/project-apx.tsx +0 -0
- /package/src/{tui → interfaces/tui}/context/project.tsx +0 -0
- /package/src/{tui → interfaces/tui}/context/prompt.tsx +0 -0
- /package/src/{tui → interfaces/tui}/context/route.tsx +0 -0
- /package/src/{tui → interfaces/tui}/context/sdk.tsx +0 -0
- /package/src/{tui → interfaces/tui}/context/sync-v2.tsx +0 -0
- /package/src/{tui → interfaces/tui}/context/sync.tsx +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/aura.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/ayu.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/carbonfox.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/catppuccin-frappe.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/catppuccin-macchiato.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/catppuccin.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/cobalt2.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/cursor.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/dracula.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/everforest.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/flexoki.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/github.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/gruvbox.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/kanagawa.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/lucent-orng.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/material.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/matrix.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/mercury.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/monokai.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/nightowl.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/nord.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/one-dark.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/opencode.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/orng.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/osaka-jade.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/palenight.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/rosepine.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/solarized.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/synthwave84.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/tokyonight.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/vercel.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/vesper.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/zenburn.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme.tsx +0 -0
- /package/src/{tui → interfaces/tui}/context/tui-config.tsx +0 -0
- /package/src/{tui → interfaces/tui}/event.ts +0 -0
- /package/src/{tui → interfaces/tui}/feature-plugins/home/footer.tsx +0 -0
- /package/src/{tui → interfaces/tui}/feature-plugins/home/tips-view.tsx +0 -0
- /package/src/{tui → interfaces/tui}/feature-plugins/home/tips.tsx +0 -0
- /package/src/{tui → interfaces/tui}/feature-plugins/sidebar/context.tsx +0 -0
- /package/src/{tui → interfaces/tui}/feature-plugins/sidebar/files.tsx +0 -0
- /package/src/{tui → interfaces/tui}/feature-plugins/sidebar/footer.tsx +0 -0
- /package/src/{tui → interfaces/tui}/feature-plugins/sidebar/lsp.tsx +0 -0
- /package/src/{tui → interfaces/tui}/feature-plugins/sidebar/mcp.tsx +0 -0
- /package/src/{tui → interfaces/tui}/feature-plugins/sidebar/todo.tsx +0 -0
- /package/src/{tui → interfaces/tui}/feature-plugins/system/plugins.tsx +0 -0
- /package/src/{tui → interfaces/tui}/feature-plugins/system/session-v2.tsx +0 -0
- /package/src/{tui → interfaces/tui}/feature-plugins/system/which-key.tsx +0 -0
- /package/src/{tui → interfaces/tui}/keymap.tsx +0 -0
- /package/src/{tui → interfaces/tui}/layer.ts +0 -0
- /package/src/{tui → interfaces/tui}/plugin/api.tsx +0 -0
- /package/src/{tui → interfaces/tui}/plugin/command-shim.ts +0 -0
- /package/src/{tui → interfaces/tui}/plugin/internal.ts +0 -0
- /package/src/{tui → interfaces/tui}/plugin/runtime.ts +0 -0
- /package/src/{tui → interfaces/tui}/plugin/slots.tsx +0 -0
- /package/src/{tui → interfaces/tui}/routes/home.tsx +0 -0
- /package/src/{tui → interfaces/tui}/routes/session/dialog-fork-from-timeline.tsx +0 -0
- /package/src/{tui → interfaces/tui}/routes/session/dialog-message.tsx +0 -0
- /package/src/{tui → interfaces/tui}/routes/session/dialog-subagent.tsx +0 -0
- /package/src/{tui → interfaces/tui}/routes/session/dialog-timeline.tsx +0 -0
- /package/src/{tui → interfaces/tui}/routes/session/footer.tsx +0 -0
- /package/src/{tui → interfaces/tui}/routes/session/permission.tsx +0 -0
- /package/src/{tui → interfaces/tui}/routes/session/question.tsx +0 -0
- /package/src/{tui → interfaces/tui}/routes/session/sidebar.tsx +0 -0
- /package/src/{tui → interfaces/tui}/routes/session/subagent-footer.tsx +0 -0
- /package/src/{tui → interfaces/tui}/run.ts +0 -0
- /package/src/{tui → interfaces/tui}/thread.ts +0 -0
- /package/src/{tui → interfaces/tui}/ui/dialog-alert.tsx +0 -0
- /package/src/{tui → interfaces/tui}/ui/dialog-confirm.tsx +0 -0
- /package/src/{tui → interfaces/tui}/ui/dialog-export-options.tsx +0 -0
- /package/src/{tui → interfaces/tui}/ui/dialog-help.tsx +0 -0
- /package/src/{tui → interfaces/tui}/ui/dialog-prompt.tsx +0 -0
- /package/src/{tui → interfaces/tui}/ui/dialog-select.tsx +0 -0
- /package/src/{tui → interfaces/tui}/ui/dialog.tsx +0 -0
- /package/src/{tui → interfaces/tui}/ui/link.tsx +0 -0
- /package/src/{tui → interfaces/tui}/ui/spinner.ts +0 -0
- /package/src/{tui → interfaces/tui}/ui/toast.tsx +0 -0
- /package/src/{tui → interfaces/tui}/util/editor.ts +0 -0
- /package/src/{tui → interfaces/tui}/util/model.ts +0 -0
- /package/src/{tui → interfaces/tui}/util/provider-origin.ts +0 -0
- /package/src/{tui → interfaces/tui}/util/revert-diff.ts +0 -0
- /package/src/{tui → interfaces/tui}/util/scroll.ts +0 -0
- /package/src/{tui → interfaces/tui}/util/selection.ts +0 -0
- /package/src/{tui → interfaces/tui}/util/signal.ts +0 -0
- /package/src/{tui → interfaces/tui}/util/sound.ts +0 -0
- /package/src/{tui → interfaces/tui}/util/transcript.ts +0 -0
- /package/src/{tui → interfaces/tui}/validate-session.ts +0 -0
- /package/src/{tui → interfaces/tui}/win32.ts +0 -0
- /package/src/{tui → interfaces/tui}/worker.ts +0 -0
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
// Memory Broker (Pieza 4) — runs before each super-agent turn and assembles the
|
|
2
|
+
// [MEMORIA RELEVANTE] block injected into the system prompt.
|
|
3
|
+
//
|
|
4
|
+
// incoming message
|
|
5
|
+
// → embed it + RAG retriever (Pieza 2) → top-K relevant chunks
|
|
6
|
+
// → read the last N entries of memory.md
|
|
7
|
+
// → merge, dedupe, format as a [MEMORIA RELEVANTE] block
|
|
8
|
+
//
|
|
9
|
+
// Silent and bounded: the whole thing races an 800 ms budget. If RAG is slow
|
|
10
|
+
// (Ollama lagging), the block still returns with whatever memory.md gave us —
|
|
11
|
+
// it NEVER blocks the reply or throws into the request path.
|
|
12
|
+
|
|
13
|
+
import fs from "node:fs";
|
|
14
|
+
import { embedOne } from "./embeddings.js";
|
|
15
|
+
import { SELF_MEMORY_PATH, parseSelfMemoryEntries } from "../agent/self-memory.js";
|
|
16
|
+
|
|
17
|
+
const DEFAULT_BUDGET_MS = 800;
|
|
18
|
+
const DEFAULT_TOP_K = 5;
|
|
19
|
+
const BULLET_CAP = 160; // chars per bullet line
|
|
20
|
+
const MIN_SCORE = { ollama: 0.35, tf: 0.08 }; // floor per embedder family
|
|
21
|
+
|
|
22
|
+
function withTimeout(promise, ms, fallback) {
|
|
23
|
+
return new Promise((resolve) => {
|
|
24
|
+
let done = false;
|
|
25
|
+
const timer = setTimeout(() => {
|
|
26
|
+
if (!done) {
|
|
27
|
+
done = true;
|
|
28
|
+
resolve(fallback);
|
|
29
|
+
}
|
|
30
|
+
}, ms);
|
|
31
|
+
promise.then(
|
|
32
|
+
(v) => {
|
|
33
|
+
if (!done) {
|
|
34
|
+
done = true;
|
|
35
|
+
clearTimeout(timer);
|
|
36
|
+
resolve(v);
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
() => {
|
|
40
|
+
if (!done) {
|
|
41
|
+
done = true;
|
|
42
|
+
clearTimeout(timer);
|
|
43
|
+
resolve(fallback);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function dateOf(ts) {
|
|
51
|
+
return ts ? String(ts).slice(0, 10) : "";
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function clean(text) {
|
|
55
|
+
return String(text || "")
|
|
56
|
+
.replace(/\s+/g, " ")
|
|
57
|
+
.trim();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function trunc(text, n = BULLET_CAP) {
|
|
61
|
+
const t = clean(text);
|
|
62
|
+
return t.length > n ? t.slice(0, n - 1).trimEnd() + "…" : t;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Last N entries of memory.md, newest first, as {date, channel, text}.
|
|
66
|
+
function lastMemoryEntries(memoryPath, n) {
|
|
67
|
+
try {
|
|
68
|
+
const text = fs.readFileSync(memoryPath, "utf8");
|
|
69
|
+
const entries = parseSelfMemoryEntries(text);
|
|
70
|
+
return entries.slice(-n).reverse();
|
|
71
|
+
} catch {
|
|
72
|
+
return [];
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function bulletFor({ date, channel, text }) {
|
|
77
|
+
const d = date ? `[${date}]` : "";
|
|
78
|
+
const c = channel && channel !== "memory" ? `[${channel}]` : channel === "memory" ? "[memory]" : "";
|
|
79
|
+
return `• ${d}${c} ${trunc(text)}`.replace(/\s+/g, " ").trim();
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Build the [MEMORIA RELEVANTE] block. Returns "" when there's nothing useful.
|
|
83
|
+
//
|
|
84
|
+
// opts: { store, config, memoryPath, budgetMs, topK, channel, embed }
|
|
85
|
+
export async function buildMemoryBlock(message, opts = {}) {
|
|
86
|
+
const memoryPath = opts.memoryPath || SELF_MEMORY_PATH;
|
|
87
|
+
const budgetMs = opts.budgetMs || DEFAULT_BUDGET_MS;
|
|
88
|
+
const topK = opts.topK || DEFAULT_TOP_K;
|
|
89
|
+
const store = opts.store || null;
|
|
90
|
+
const query = clean(message);
|
|
91
|
+
|
|
92
|
+
// memory.md entries are read synchronously and always make the deadline.
|
|
93
|
+
const memEntries = lastMemoryEntries(memoryPath, 10);
|
|
94
|
+
|
|
95
|
+
// RAG retrieval is the slow part — race it against the budget.
|
|
96
|
+
let hits = [];
|
|
97
|
+
if (store && query) {
|
|
98
|
+
const rag = (async () => {
|
|
99
|
+
const { vector, embedder, dim } = await embedOne(query, opts.embed || {});
|
|
100
|
+
const family = embedder.startsWith("ollama") ? "ollama" : "tf";
|
|
101
|
+
const floor = MIN_SCORE[family] ?? 0;
|
|
102
|
+
const results = store.search(vector, { embedder, k: topK + 3 });
|
|
103
|
+
return results.filter((r) => r.score >= floor && (r.dim ?? dim) === dim);
|
|
104
|
+
})();
|
|
105
|
+
hits = await withTimeout(rag, budgetMs, []);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Merge RAG hits + recent memory entries, dedupe by normalised text.
|
|
109
|
+
const seen = new Set();
|
|
110
|
+
const bullets = [];
|
|
111
|
+
const push = (entry) => {
|
|
112
|
+
const key = clean(entry.text).toLowerCase().slice(0, 80);
|
|
113
|
+
if (!key || seen.has(key)) return;
|
|
114
|
+
// Don't echo the user's own incoming message back at them.
|
|
115
|
+
if (key && query.toLowerCase().includes(key) && key.length > 30) return;
|
|
116
|
+
seen.add(key);
|
|
117
|
+
bullets.push(bulletFor(entry));
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
for (const h of hits.slice(0, topK)) {
|
|
121
|
+
push({
|
|
122
|
+
date: dateOf(h.ts),
|
|
123
|
+
channel: h.tag === "memory" ? "memory" : h.channel,
|
|
124
|
+
text: h.text.replace(/^\[tool result: [^\]]+\]\s*/, ""),
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
for (const e of memEntries) {
|
|
128
|
+
if (bullets.length >= topK + 5) break;
|
|
129
|
+
push({ date: e.date, channel: e.channel || "memory", text: e.text });
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (bullets.length === 0) return "";
|
|
133
|
+
|
|
134
|
+
return [
|
|
135
|
+
"# Memoria relevante (cross-channel)",
|
|
136
|
+
"Contexto recuperado de tu memoria y del historial de todos los canales. Tratá",
|
|
137
|
+
"como hechos conocidos; si arrancás una sesión nueva y algo de acá sigue abierto,",
|
|
138
|
+
"mencionalo naturalmente (\"ayer estuvimos con X, ¿seguimos?\") sin que te pregunten.",
|
|
139
|
+
"",
|
|
140
|
+
"[MEMORIA RELEVANTE]",
|
|
141
|
+
...bullets,
|
|
142
|
+
"[/MEMORIA RELEVANTE]",
|
|
143
|
+
].join("\n");
|
|
144
|
+
}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
// Progressive history compaction (Pieza 3).
|
|
2
|
+
//
|
|
3
|
+
// When a channel chat accumulates more than `maxTurns` (60) conversational
|
|
4
|
+
// turns in the rolling window, the oldest turns beyond `keepRecent` (40) are
|
|
5
|
+
// collapsed into a dense summary by a light LLM (ollama:gemma2 → haiku
|
|
6
|
+
// fallback) and persisted as a `type:"compact"` record in the channel JSONL.
|
|
7
|
+
//
|
|
8
|
+
// The reader (getRecentChannelTurnsFromFs) then prepends that summary as a
|
|
9
|
+
// [RESUMEN COMPACTADO] system turn and drops the raw turns it covers, keeping
|
|
10
|
+
// the model context bounded while preserving decisions / tasks / tool results.
|
|
11
|
+
//
|
|
12
|
+
// This runs OUT of the reply hot path (fire-and-forget) — generating a summary
|
|
13
|
+
// costs an LLM call, so the current turn uses whatever compact already exists
|
|
14
|
+
// and the next turn benefits. Best-effort: any failure logs and returns.
|
|
15
|
+
|
|
16
|
+
import fs from "node:fs";
|
|
17
|
+
import path from "node:path";
|
|
18
|
+
import { GLOBAL_MESSAGES_DIR } from "../config.js";
|
|
19
|
+
import { parseDayJsonl, appendGlobalMessage } from "../messages-store.js";
|
|
20
|
+
import { callEngine } from "../engines/index.js";
|
|
21
|
+
|
|
22
|
+
const DEFAULT_MAX_TURNS = 60;
|
|
23
|
+
const DEFAULT_KEEP_RECENT = 40;
|
|
24
|
+
const COMPACT_MAX_TOKENS = 1000; // ~800-token target + headroom
|
|
25
|
+
|
|
26
|
+
const COMPACT_SYSTEM =
|
|
27
|
+
"Compactás conversaciones para continuidad de contexto de un agente. " +
|
|
28
|
+
"Otro modelo va a leer esto para seguir el trabajo: sé denso y factual.";
|
|
29
|
+
|
|
30
|
+
function compactPrompt(transcript) {
|
|
31
|
+
return (
|
|
32
|
+
"Compactá estos turnos en un resumen estructurado de máximo 800 tokens, " +
|
|
33
|
+
"preservando: decisiones tomadas, tareas asignadas, resultados de tools, y " +
|
|
34
|
+
"datos acordados. Sin saludos ni meta-comentarios. Sólo los hechos.\n\n" +
|
|
35
|
+
"---\n\n" +
|
|
36
|
+
transcript
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function resolveCompactModels(config = {}) {
|
|
41
|
+
const mem = config.memory || {};
|
|
42
|
+
// Primary: a light, local-endpoint model (Ollama, incl. *-cloud models served
|
|
43
|
+
// via localhost). Fallback: whatever the user configured, else the APX
|
|
44
|
+
// default super-agent model — never silently a paid service the user didn't
|
|
45
|
+
// pick. A blank fallback resolves to super_agent.model at call time.
|
|
46
|
+
return {
|
|
47
|
+
primary: mem.compact_model || "ollama:gemma4:31b-cloud",
|
|
48
|
+
fallback: mem.compact_fallback_model || config.super_agent?.model || "",
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Read every record for a chat in the rolling window, oldest first.
|
|
53
|
+
function readChatRecords({ channel, chat_id, max_age_hours, messagesDir }) {
|
|
54
|
+
const cutoff = new Date(Date.now() - max_age_hours * 3600_000)
|
|
55
|
+
.toISOString()
|
|
56
|
+
.replace(/\.\d{3}Z$/, "Z");
|
|
57
|
+
const dir = path.join(messagesDir, channel);
|
|
58
|
+
if (!fs.existsSync(dir)) return [];
|
|
59
|
+
const all = [];
|
|
60
|
+
for (const f of fs.readdirSync(dir).sort()) {
|
|
61
|
+
if (!/^\d{4}-\d{2}-\d{2}\.jsonl$/.test(f)) continue;
|
|
62
|
+
let text;
|
|
63
|
+
try {
|
|
64
|
+
text = fs.readFileSync(path.join(dir, f), "utf8");
|
|
65
|
+
} catch {
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
for (const m of parseDayJsonl(text)) {
|
|
69
|
+
if (m.ts < cutoff) continue;
|
|
70
|
+
if (String(m.meta?.chat_id ?? "") !== String(chat_id)) continue;
|
|
71
|
+
all.push(m);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
all.sort((a, b) => (a.ts || "").localeCompare(b.ts || ""));
|
|
75
|
+
return all;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function renderTurn(m) {
|
|
79
|
+
if (m.type === "tool") {
|
|
80
|
+
const name = m.meta?.tool_name || m.meta?.tool || "tool";
|
|
81
|
+
return `[TOOL ${name}]\n${String(m.body || "").slice(0, 600)}`;
|
|
82
|
+
}
|
|
83
|
+
const who = m.type === "user" ? "USER" : "ASSISTANT";
|
|
84
|
+
return `[${who}]\n${String(m.body || "")}`;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async function summarize({ transcript, models, config }) {
|
|
88
|
+
for (const modelId of [models.primary, models.fallback]) {
|
|
89
|
+
if (!modelId) continue;
|
|
90
|
+
try {
|
|
91
|
+
const r = await callEngine({
|
|
92
|
+
modelId,
|
|
93
|
+
system: COMPACT_SYSTEM,
|
|
94
|
+
messages: [{ role: "user", content: compactPrompt(transcript) }],
|
|
95
|
+
config,
|
|
96
|
+
maxTokens: COMPACT_MAX_TOKENS,
|
|
97
|
+
temperature: 0.2,
|
|
98
|
+
});
|
|
99
|
+
const text = String(r.text || "").trim();
|
|
100
|
+
if (text) return { text, model: modelId };
|
|
101
|
+
} catch {
|
|
102
|
+
/* try next model */
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Compact one channel chat if it's over threshold. Returns a small status obj.
|
|
109
|
+
// opts: { channel, chat_id, config, log, maxTurns, keepRecent, max_age_hours,
|
|
110
|
+
// messagesDir } (messagesDir overridable for tests)
|
|
111
|
+
export async function compactChannelIfNeeded(opts = {}) {
|
|
112
|
+
const channel = opts.channel || "telegram";
|
|
113
|
+
const chat_id = opts.chat_id;
|
|
114
|
+
const config = opts.config || {};
|
|
115
|
+
const log = typeof opts.log === "function" ? opts.log : () => {};
|
|
116
|
+
const maxTurns = opts.maxTurns ?? config.memory?.compact_threshold ?? DEFAULT_MAX_TURNS;
|
|
117
|
+
const keepRecent = opts.keepRecent ?? config.memory?.keep_recent ?? DEFAULT_KEEP_RECENT;
|
|
118
|
+
const max_age_hours = opts.max_age_hours ?? 24;
|
|
119
|
+
const messagesDir = opts.messagesDir || GLOBAL_MESSAGES_DIR;
|
|
120
|
+
if (!chat_id) return { skipped: "no chat_id" };
|
|
121
|
+
|
|
122
|
+
const records = readChatRecords({ channel, chat_id, max_age_hours, messagesDir });
|
|
123
|
+
|
|
124
|
+
// Find the latest existing compact and what it already covers.
|
|
125
|
+
let prevCompact = null;
|
|
126
|
+
for (const m of records) if (m.type === "compact") prevCompact = m;
|
|
127
|
+
const coverUntil = prevCompact ? prevCompact.meta?.covers_until_ts || prevCompact.ts : "";
|
|
128
|
+
const prevCount = prevCompact ? prevCompact.meta?.count || 0 : 0;
|
|
129
|
+
|
|
130
|
+
// Conversational turns not yet covered by a compact.
|
|
131
|
+
const fresh = records.filter(
|
|
132
|
+
(m) =>
|
|
133
|
+
(m.type === "user" || m.type === "agent" || m.type === "tool") &&
|
|
134
|
+
(!coverUntil || m.ts > coverUntil)
|
|
135
|
+
);
|
|
136
|
+
const realTurns = fresh.filter((m) => m.type === "user" || m.type === "agent");
|
|
137
|
+
if (realTurns.length <= maxTurns) {
|
|
138
|
+
return { skipped: "below threshold", turns: realTurns.length };
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Compact the oldest turns, leaving the most recent `keepRecent` real turns
|
|
142
|
+
// verbatim. We compact everything (incl. interleaved tools) up to the ts of
|
|
143
|
+
// the (realTurns.length - keepRecent)-th real turn.
|
|
144
|
+
const boundaryReal = realTurns[realTurns.length - keepRecent - 1];
|
|
145
|
+
const boundaryTs = boundaryReal.ts;
|
|
146
|
+
const toCompact = fresh.filter((m) => m.ts <= boundaryTs);
|
|
147
|
+
const compactedReal = toCompact.filter((m) => m.type === "user" || m.type === "agent").length;
|
|
148
|
+
if (compactedReal === 0) return { skipped: "nothing to compact" };
|
|
149
|
+
|
|
150
|
+
let transcript = toCompact.map(renderTurn).join("\n\n");
|
|
151
|
+
if (prevCompact && String(prevCompact.body || "").trim()) {
|
|
152
|
+
transcript =
|
|
153
|
+
`[RESUMEN PREVIO]\n${String(prevCompact.body).trim()}\n\n---\n\n` + transcript;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const models = resolveCompactModels(config);
|
|
157
|
+
const summary = await summarize({ transcript, models, config });
|
|
158
|
+
if (!summary) {
|
|
159
|
+
log(`memory: compaction for ${channel}/${chat_id} skipped — no model available`);
|
|
160
|
+
return { skipped: "no model" };
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const totalCovered = prevCount + compactedReal;
|
|
164
|
+
appendGlobalMessage({
|
|
165
|
+
channel,
|
|
166
|
+
direction: "out",
|
|
167
|
+
type: "compact",
|
|
168
|
+
actor_id: "compact",
|
|
169
|
+
actor_kind: "compact",
|
|
170
|
+
author: "compact",
|
|
171
|
+
body: summary.text,
|
|
172
|
+
meta: {
|
|
173
|
+
chat_id,
|
|
174
|
+
compact: true,
|
|
175
|
+
range: [1, totalCovered],
|
|
176
|
+
count: totalCovered,
|
|
177
|
+
covers_until_ts: boundaryTs,
|
|
178
|
+
compacted_turns: compactedReal,
|
|
179
|
+
model: summary.model,
|
|
180
|
+
},
|
|
181
|
+
});
|
|
182
|
+
log(
|
|
183
|
+
`memory: compacted ${compactedReal} turn(s) for ${channel}/${chat_id} via ${summary.model} (covers 1-${totalCovered})`
|
|
184
|
+
);
|
|
185
|
+
return { compacted: true, turns: compactedReal, covers: totalCovered, model: summary.model };
|
|
186
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// Google Gemini embeddings adapter (default: text-embedding-004, 768 dims).
|
|
2
|
+
// Free tier available with a Gemini API key. Reuses engines.gemini.api_key.
|
|
3
|
+
|
|
4
|
+
import { l2normalize } from "../embeddings.js";
|
|
5
|
+
|
|
6
|
+
const DEFAULT_MODEL = "text-embedding-004";
|
|
7
|
+
const BASE = "https://generativelanguage.googleapis.com/v1beta";
|
|
8
|
+
|
|
9
|
+
function getKey(config = {}, parentEnginesCfg) {
|
|
10
|
+
return (
|
|
11
|
+
config.api_key ||
|
|
12
|
+
parentEnginesCfg?.gemini?.api_key ||
|
|
13
|
+
process.env.GEMINI_API_KEY ||
|
|
14
|
+
process.env.GOOGLE_API_KEY ||
|
|
15
|
+
""
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export default {
|
|
20
|
+
id: "gemini",
|
|
21
|
+
|
|
22
|
+
async isAvailable(config = {}, parentEnginesCfg) {
|
|
23
|
+
return Boolean(getKey(config, parentEnginesCfg));
|
|
24
|
+
},
|
|
25
|
+
|
|
26
|
+
async embed({ text, config = {}, parentEnginesCfg, timeoutMs = 8000, signal }) {
|
|
27
|
+
const key = getKey(config, parentEnginesCfg);
|
|
28
|
+
if (!key) throw new Error("gemini embeddings: no api_key");
|
|
29
|
+
const model = config.model || DEFAULT_MODEL;
|
|
30
|
+
const ctrl = new AbortController();
|
|
31
|
+
const onParentAbort = () => ctrl.abort();
|
|
32
|
+
if (signal) signal.addEventListener("abort", onParentAbort, { once: true });
|
|
33
|
+
const timer = setTimeout(() => ctrl.abort(), timeoutMs);
|
|
34
|
+
try {
|
|
35
|
+
const res = await fetch(
|
|
36
|
+
`${BASE}/models/${model}:embedContent?key=${encodeURIComponent(key)}`,
|
|
37
|
+
{
|
|
38
|
+
method: "POST",
|
|
39
|
+
headers: { "content-type": "application/json" },
|
|
40
|
+
body: JSON.stringify({
|
|
41
|
+
model: `models/${model}`,
|
|
42
|
+
content: { parts: [{ text }] },
|
|
43
|
+
}),
|
|
44
|
+
signal: ctrl.signal,
|
|
45
|
+
}
|
|
46
|
+
);
|
|
47
|
+
if (!res.ok) {
|
|
48
|
+
const err = await res.text().catch(() => "");
|
|
49
|
+
throw new Error(`gemini embeddings ${res.status}: ${err.slice(0, 200)}`);
|
|
50
|
+
}
|
|
51
|
+
const json = await res.json();
|
|
52
|
+
const vector = json?.embedding?.values;
|
|
53
|
+
if (!Array.isArray(vector) || vector.length === 0) {
|
|
54
|
+
throw new Error("gemini embeddings: empty vector");
|
|
55
|
+
}
|
|
56
|
+
return { vector: l2normalize(vector), embedder: `gemini:${model}`, dim: vector.length };
|
|
57
|
+
} finally {
|
|
58
|
+
clearTimeout(timer);
|
|
59
|
+
if (signal) signal.removeEventListener("abort", onParentAbort);
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
};
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
// Embeddings engine registry for the cross-channel memory RAG. Mirrors the TTS
|
|
2
|
+
// engine selector at src/core/voice/engines/index.js so configuring an
|
|
3
|
+
// embeddings provider feels identical to configuring TTS/STT.
|
|
4
|
+
//
|
|
5
|
+
// Config lives at config.memory.embeddings:
|
|
6
|
+
// provider: "auto" | "ollama" | "openai" | "gemini" | "tf"
|
|
7
|
+
// mode: "chain" (ordered fallback router) | "single" (use provider verbatim)
|
|
8
|
+
// order: custom chain order (ids); the rest of AUTO_PREFERENCE is appended
|
|
9
|
+
// <id>: per-engine settings ({ model, api_key, base_url, timeout_ms })
|
|
10
|
+
//
|
|
11
|
+
// Two selection modes:
|
|
12
|
+
// "chain" — walk the order, skip engines turned off (<id>.enabled === false),
|
|
13
|
+
// pick the first whose isAvailable() returns true. "tf" is always
|
|
14
|
+
// kept as the final guaranteed fallback.
|
|
15
|
+
// "single" — use exactly memory.embeddings.provider, no fallback.
|
|
16
|
+
//
|
|
17
|
+
// An explicit `provider` argument always wins (used by the "test embedding" UI).
|
|
18
|
+
// Cosine similarity is only meaningful within one embedder space, so every
|
|
19
|
+
// vector is tagged with its `embedder` and the store filters search() on it —
|
|
20
|
+
// switching provider strands the old index until it is re-embedded.
|
|
21
|
+
|
|
22
|
+
import ollama from "./ollama.js";
|
|
23
|
+
import openai from "./openai.js";
|
|
24
|
+
import gemini from "./gemini.js";
|
|
25
|
+
import tf from "./tf.js";
|
|
26
|
+
|
|
27
|
+
const ADAPTERS = { ollama, openai, gemini, tf };
|
|
28
|
+
export const EMBED_ENGINE_IDS = Object.keys(ADAPTERS);
|
|
29
|
+
|
|
30
|
+
// Local-first, then free-with-key, then paid, then offline fallback.
|
|
31
|
+
export const AUTO_PREFERENCE = ["ollama", "gemini", "openai", "tf"];
|
|
32
|
+
|
|
33
|
+
export function getEmbedAdapter(provider) {
|
|
34
|
+
const a = ADAPTERS[provider];
|
|
35
|
+
if (!a) {
|
|
36
|
+
throw new Error(
|
|
37
|
+
`unknown embeddings provider "${provider}". Known: ${EMBED_ENGINE_IDS.join(", ")}`
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
return a;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function embeddingsConfig(globalConfig) {
|
|
44
|
+
const mem = globalConfig?.memory || {};
|
|
45
|
+
// Back-compat: older configs only had the flat memory.embed_* keys. Fold them
|
|
46
|
+
// into a synthetic ollama engine config so they keep working unchanged.
|
|
47
|
+
const section = mem.embeddings || {};
|
|
48
|
+
if (!section.ollama && (mem.embed_model || mem.embed_base_url || mem.embed_timeout_ms)) {
|
|
49
|
+
return {
|
|
50
|
+
provider: section.provider || "auto",
|
|
51
|
+
mode: section.mode,
|
|
52
|
+
order: section.order,
|
|
53
|
+
...section,
|
|
54
|
+
ollama: {
|
|
55
|
+
model: mem.embed_model || "nomic-embed-text",
|
|
56
|
+
base_url: mem.embed_base_url || "",
|
|
57
|
+
timeout_ms: mem.embed_timeout_ms || 4000,
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
return section;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function providerConfig(globalConfig, provider) {
|
|
65
|
+
return embeddingsConfig(globalConfig)?.[provider] || {};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function isEnabled(embedCfg, id) {
|
|
69
|
+
return embedCfg?.[id]?.enabled !== false;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** Effective routing mode for the chain/single decision. */
|
|
73
|
+
export function resolveMode(embedCfg) {
|
|
74
|
+
if (embedCfg?.mode === "chain" || embedCfg?.mode === "single") return embedCfg.mode;
|
|
75
|
+
const p = embedCfg?.provider;
|
|
76
|
+
return p && p !== "auto" ? "single" : "chain";
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** Full chain order: user's custom order (known ids only) then the rest; tf last. */
|
|
80
|
+
export function resolveChainOrder(embedCfg) {
|
|
81
|
+
const custom = Array.isArray(embedCfg?.order)
|
|
82
|
+
? embedCfg.order.filter((id) => EMBED_ENGINE_IDS.includes(id))
|
|
83
|
+
: [];
|
|
84
|
+
const rest = AUTO_PREFERENCE.filter((id) => !custom.includes(id));
|
|
85
|
+
const full = [...custom, ...rest];
|
|
86
|
+
if (!full.includes("tf")) full.push("tf");
|
|
87
|
+
return full;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Resolve which embeddings engine should handle this call.
|
|
92
|
+
* Returns { provider, adapter, engineConfig }.
|
|
93
|
+
*/
|
|
94
|
+
export async function selectEmbedEngine({ globalConfig, provider }) {
|
|
95
|
+
const embedCfg = embeddingsConfig(globalConfig);
|
|
96
|
+
|
|
97
|
+
// 1. Explicit override (tester / API caller) always wins.
|
|
98
|
+
if (provider && provider !== "auto") {
|
|
99
|
+
const adapter = getEmbedAdapter(provider);
|
|
100
|
+
return { provider, adapter, engineConfig: providerConfig(globalConfig, provider) };
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const mode = resolveMode(embedCfg);
|
|
104
|
+
|
|
105
|
+
// 2. Single mode: use the configured engine verbatim, no fallback.
|
|
106
|
+
if (mode === "single") {
|
|
107
|
+
const id = embedCfg?.provider;
|
|
108
|
+
if (id && id !== "auto") {
|
|
109
|
+
const adapter = getEmbedAdapter(id);
|
|
110
|
+
return { provider: id, adapter, engineConfig: providerConfig(globalConfig, id) };
|
|
111
|
+
}
|
|
112
|
+
// Misconfigured single mode → fall through to chain.
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// 3. Chain mode: probe the (enabled) order, first available wins.
|
|
116
|
+
for (const id of resolveChainOrder(embedCfg)) {
|
|
117
|
+
if (id !== "tf" && !isEnabled(embedCfg, id)) continue;
|
|
118
|
+
const adapter = ADAPTERS[id];
|
|
119
|
+
const cfg = providerConfig(globalConfig, id);
|
|
120
|
+
try {
|
|
121
|
+
if (await adapter.isAvailable(cfg, globalConfig?.engines)) {
|
|
122
|
+
return { provider: id, adapter, engineConfig: cfg };
|
|
123
|
+
}
|
|
124
|
+
} catch { /* probe failures fall through */ }
|
|
125
|
+
}
|
|
126
|
+
return { provider: "tf", adapter: tf, engineConfig: providerConfig(globalConfig, "tf") };
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/** Discover which engines are configured/available right now. */
|
|
130
|
+
export async function listAvailableEmbedEngines(globalConfig) {
|
|
131
|
+
const embedCfg = embeddingsConfig(globalConfig);
|
|
132
|
+
const out = [];
|
|
133
|
+
for (const id of EMBED_ENGINE_IDS) {
|
|
134
|
+
const adapter = ADAPTERS[id];
|
|
135
|
+
const cfg = providerConfig(globalConfig, id);
|
|
136
|
+
let available = false;
|
|
137
|
+
try {
|
|
138
|
+
available = await adapter.isAvailable(cfg, globalConfig?.engines);
|
|
139
|
+
} catch { available = false; }
|
|
140
|
+
out.push({
|
|
141
|
+
id,
|
|
142
|
+
available,
|
|
143
|
+
configured: Object.keys(cfg).filter((k) => k !== "enabled").length > 0,
|
|
144
|
+
enabled: isEnabled(embedCfg, id),
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
return out;
|
|
148
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// Ollama embeddings adapter (default: nomic-embed-text). Local, no API key.
|
|
2
|
+
// base_url falls back to config.engines.ollama.base_url, then env, then
|
|
3
|
+
// localhost:11434 — the same endpoint that serves local + Ollama-cloud models.
|
|
4
|
+
|
|
5
|
+
import { l2normalize } from "../embeddings.js";
|
|
6
|
+
|
|
7
|
+
const DEFAULT_MODEL = "nomic-embed-text";
|
|
8
|
+
|
|
9
|
+
function resolveBaseUrl(config = {}, parentEnginesCfg) {
|
|
10
|
+
const base =
|
|
11
|
+
config.base_url ||
|
|
12
|
+
parentEnginesCfg?.ollama?.base_url ||
|
|
13
|
+
process.env.APX_EMBED_URL ||
|
|
14
|
+
process.env.OLLAMA_HOST ||
|
|
15
|
+
"http://localhost:11434";
|
|
16
|
+
return String(base).replace(/\/$/, "");
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export default {
|
|
20
|
+
id: "ollama",
|
|
21
|
+
|
|
22
|
+
// Local Ollama is "available" as a configured choice without probing a
|
|
23
|
+
// network round-trip here — the embed() call itself falls back to tf on any
|
|
24
|
+
// connection error, so the chain selector stays fast.
|
|
25
|
+
async isAvailable() {
|
|
26
|
+
return true;
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
async embed({ text, config = {}, parentEnginesCfg, timeoutMs = 4000, signal }) {
|
|
30
|
+
const model = config.model || DEFAULT_MODEL;
|
|
31
|
+
const base = resolveBaseUrl(config, parentEnginesCfg);
|
|
32
|
+
const ctrl = new AbortController();
|
|
33
|
+
const onParentAbort = () => ctrl.abort();
|
|
34
|
+
if (signal) signal.addEventListener("abort", onParentAbort, { once: true });
|
|
35
|
+
const timer = setTimeout(() => ctrl.abort(), timeoutMs);
|
|
36
|
+
try {
|
|
37
|
+
const res = await fetch(`${base}/api/embeddings`, {
|
|
38
|
+
method: "POST",
|
|
39
|
+
headers: { "content-type": "application/json" },
|
|
40
|
+
body: JSON.stringify({ model, prompt: text }),
|
|
41
|
+
signal: ctrl.signal,
|
|
42
|
+
});
|
|
43
|
+
if (!res.ok) throw new Error(`ollama embeddings ${res.status}`);
|
|
44
|
+
const json = await res.json();
|
|
45
|
+
const vector = json.embedding;
|
|
46
|
+
if (!Array.isArray(vector) || vector.length === 0) {
|
|
47
|
+
throw new Error("ollama embeddings: empty vector");
|
|
48
|
+
}
|
|
49
|
+
return { vector: l2normalize(vector), embedder: `ollama:${model}`, dim: vector.length };
|
|
50
|
+
} finally {
|
|
51
|
+
clearTimeout(timer);
|
|
52
|
+
if (signal) signal.removeEventListener("abort", onParentAbort);
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// OpenAI embeddings adapter (default: text-embedding-3-small, 1536 dims).
|
|
2
|
+
// Reuses engines.openai.api_key + base_url; per-section overrides live under
|
|
3
|
+
// memory.embeddings.openai. Works with any OpenAI-compatible /embeddings
|
|
4
|
+
// endpoint (OpenAI, OpenRouter, local LiteLLM) by overriding base_url.
|
|
5
|
+
|
|
6
|
+
import { l2normalize } from "../embeddings.js";
|
|
7
|
+
|
|
8
|
+
const DEFAULT_MODEL = "text-embedding-3-small";
|
|
9
|
+
const DEFAULT_BASE = "https://api.openai.com/v1";
|
|
10
|
+
|
|
11
|
+
function getKey(config = {}, parentEnginesCfg) {
|
|
12
|
+
return (
|
|
13
|
+
config.api_key ||
|
|
14
|
+
parentEnginesCfg?.openai?.api_key ||
|
|
15
|
+
process.env.OPENAI_API_KEY ||
|
|
16
|
+
""
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function getBase(config = {}, parentEnginesCfg) {
|
|
21
|
+
return String(
|
|
22
|
+
config.base_url || parentEnginesCfg?.openai?.base_url || DEFAULT_BASE
|
|
23
|
+
).replace(/\/$/, "");
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export default {
|
|
27
|
+
id: "openai",
|
|
28
|
+
|
|
29
|
+
async isAvailable(config = {}, parentEnginesCfg) {
|
|
30
|
+
return Boolean(getKey(config, parentEnginesCfg));
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
async embed({ text, config = {}, parentEnginesCfg, timeoutMs = 8000, signal }) {
|
|
34
|
+
const key = getKey(config, parentEnginesCfg);
|
|
35
|
+
if (!key) throw new Error("openai embeddings: no api_key");
|
|
36
|
+
const model = config.model || DEFAULT_MODEL;
|
|
37
|
+
const base = getBase(config, parentEnginesCfg);
|
|
38
|
+
const ctrl = new AbortController();
|
|
39
|
+
const onParentAbort = () => ctrl.abort();
|
|
40
|
+
if (signal) signal.addEventListener("abort", onParentAbort, { once: true });
|
|
41
|
+
const timer = setTimeout(() => ctrl.abort(), timeoutMs);
|
|
42
|
+
try {
|
|
43
|
+
const res = await fetch(`${base}/embeddings`, {
|
|
44
|
+
method: "POST",
|
|
45
|
+
headers: { authorization: `Bearer ${key}`, "content-type": "application/json" },
|
|
46
|
+
body: JSON.stringify({ model, input: text }),
|
|
47
|
+
signal: ctrl.signal,
|
|
48
|
+
});
|
|
49
|
+
if (!res.ok) {
|
|
50
|
+
const err = await res.text().catch(() => "");
|
|
51
|
+
throw new Error(`openai embeddings ${res.status}: ${err.slice(0, 200)}`);
|
|
52
|
+
}
|
|
53
|
+
const json = await res.json();
|
|
54
|
+
const vector = json?.data?.[0]?.embedding;
|
|
55
|
+
if (!Array.isArray(vector) || vector.length === 0) {
|
|
56
|
+
throw new Error("openai embeddings: empty vector");
|
|
57
|
+
}
|
|
58
|
+
return { vector: l2normalize(vector), embedder: `openai:${model}`, dim: vector.length };
|
|
59
|
+
} finally {
|
|
60
|
+
clearTimeout(timer);
|
|
61
|
+
if (signal) signal.removeEventListener("abort", onParentAbort);
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Offline term-frequency fallback embedder. Deterministic, dependency-free,
|
|
2
|
+
// always available. NOT as good as a real embedding model, but it keeps the
|
|
3
|
+
// retriever working when no provider is reachable — the memory system must
|
|
4
|
+
// degrade gracefully, never throw into the daemon's request path. This is the
|
|
5
|
+
// guaranteed final link in the chain (the embeddings analogue of TTS "mock").
|
|
6
|
+
|
|
7
|
+
import { tfEmbed } from "../embeddings.js";
|
|
8
|
+
|
|
9
|
+
export default {
|
|
10
|
+
id: "tf",
|
|
11
|
+
|
|
12
|
+
async isAvailable() {
|
|
13
|
+
return true;
|
|
14
|
+
},
|
|
15
|
+
|
|
16
|
+
async embed({ text }) {
|
|
17
|
+
const vector = tfEmbed(text);
|
|
18
|
+
return { vector, embedder: "tf", dim: vector.length };
|
|
19
|
+
},
|
|
20
|
+
};
|