@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,423 @@
|
|
|
1
|
+
import { callEngine } from "../engines/index.js";
|
|
2
|
+
import {
|
|
3
|
+
extractPseudoToolCalls,
|
|
4
|
+
cleanTextOfPseudoToolCalls,
|
|
5
|
+
} from "./tool-call-parser.js";
|
|
6
|
+
import { resolveActiveModel, fallbackModels } from "./model-router.js";
|
|
7
|
+
import { MAX_TOOL_ITERS, ACK_ONLY_TOOLS, MAX_CONSECUTIVE_ACKS } from "./constants.js";
|
|
8
|
+
import {
|
|
9
|
+
isShortConfirmation,
|
|
10
|
+
lastAssistantAskedForConfirmation,
|
|
11
|
+
isGhostResponse,
|
|
12
|
+
looksLikeActionRequest,
|
|
13
|
+
} from "./ghost-guard.js";
|
|
14
|
+
import { pseudoToolSystem, shouldRetryWithPseudoTools } from "./pseudo-tools.js";
|
|
15
|
+
import { filterToolSchemas } from "./tools-overlap.js";
|
|
16
|
+
import { isRetryableEngineError, shortRetryReason } from "./retry.js";
|
|
17
|
+
|
|
18
|
+
async function emitProgress(onEvent, event) {
|
|
19
|
+
if (typeof onEvent !== "function") return;
|
|
20
|
+
await onEvent(event);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function summarizeForTrace(r) {
|
|
24
|
+
if (r === null || r === undefined) return r;
|
|
25
|
+
const s = JSON.stringify(r);
|
|
26
|
+
if (s.length <= 400) return r;
|
|
27
|
+
return s.slice(0, 380) + "…(truncated)";
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function fallbackFinalText(trace, error) {
|
|
31
|
+
const lines = [
|
|
32
|
+
"Tool execution completed, but the model failed while composing the final answer.",
|
|
33
|
+
`Engine error: ${String(error?.message || error).slice(0, 220)}`,
|
|
34
|
+
"Trace:",
|
|
35
|
+
];
|
|
36
|
+
for (const item of trace.slice(-8)) {
|
|
37
|
+
lines.push(`- ${item.tool}: ${previewTraceResult(item.result)}`);
|
|
38
|
+
}
|
|
39
|
+
return lines.join("\n");
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function previewTraceResult(result) {
|
|
43
|
+
if (result === null || result === undefined) return "ok";
|
|
44
|
+
if (typeof result === "string") return result.slice(0, 180);
|
|
45
|
+
if (result.error) return `error: ${String(result.error).slice(0, 180)}`;
|
|
46
|
+
if (result.path) return String(result.path).slice(0, 180);
|
|
47
|
+
if (result.content) return String(result.content).slice(0, 180);
|
|
48
|
+
if (result.results) return JSON.stringify(result.results).slice(0, 180);
|
|
49
|
+
return JSON.stringify(result).slice(0, 180);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Loop-control tool injected when `completionContract` is on (coding surfaces).
|
|
53
|
+
// With toolChoice:"required" the model can no longer end a turn by emitting
|
|
54
|
+
// prose ("now I'll edit the file." → stop). It must EITHER call a real tool to
|
|
55
|
+
// take the next step, OR call `finish` to declare the task complete. This makes
|
|
56
|
+
// "keep going until done" enforceable by protocol structure — no language
|
|
57
|
+
// heuristics, so it works regardless of the reply language.
|
|
58
|
+
export const FINISH_TOOL_SCHEMA = {
|
|
59
|
+
type: "function",
|
|
60
|
+
function: {
|
|
61
|
+
name: "finish",
|
|
62
|
+
description:
|
|
63
|
+
"Call this ONLY when the user's request is fully complete and no step " +
|
|
64
|
+
"remains. Put your final answer / summary of what you did in `summary` " +
|
|
65
|
+
"(in the user's language). If anything is still pending, do NOT call " +
|
|
66
|
+
"finish — call the next tool and keep working instead.",
|
|
67
|
+
parameters: {
|
|
68
|
+
type: "object",
|
|
69
|
+
properties: {
|
|
70
|
+
summary: {
|
|
71
|
+
type: "string",
|
|
72
|
+
description: "Final answer or concise summary of the work completed.",
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
required: ["summary"],
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Shared tool-calling agent loop used by super-agent and future surfaces.
|
|
82
|
+
*/
|
|
83
|
+
export async function runAgent({
|
|
84
|
+
globalConfig,
|
|
85
|
+
system,
|
|
86
|
+
prompt,
|
|
87
|
+
previousMessages = [],
|
|
88
|
+
overrideModel = null,
|
|
89
|
+
toolSchemas,
|
|
90
|
+
makeToolHandlers,
|
|
91
|
+
toolHandlerCtx,
|
|
92
|
+
onEvent = null,
|
|
93
|
+
signal,
|
|
94
|
+
onToken = null,
|
|
95
|
+
agentName = "apx",
|
|
96
|
+
suppressTools = null, // optional list of tool names to remove from the registry
|
|
97
|
+
// Per-reply output cap. Defaults to 512 (tuned for chit-chat + small tool
|
|
98
|
+
// args on cheap-tier TPM budgets). Summarization callers raise this because
|
|
99
|
+
// "thinking" models (gemini-2.5-flash) burn the budget reasoning and emit
|
|
100
|
+
// empty text on dense input when it's too low.
|
|
101
|
+
maxTokens = 512,
|
|
102
|
+
// Max tool-loop iterations. Defaults to MAX_TOOL_ITERS (tuned for chit-chat
|
|
103
|
+
// surfaces). The Code module raises this so a multi-step coding task can run
|
|
104
|
+
// to completion (read → edit → run → verify …) instead of stopping early.
|
|
105
|
+
maxIters = MAX_TOOL_ITERS,
|
|
106
|
+
// Structural "keep going until done" contract for coding surfaces. When on:
|
|
107
|
+
// 1. a `finish` tool is injected into the schema set, and
|
|
108
|
+
// 2. toolChoice is forced to "required" on EVERY iteration,
|
|
109
|
+
// so the model can only advance (call a tool) or stop (call finish) — it can
|
|
110
|
+
// never end the turn by narrating the next step. Language-agnostic by design.
|
|
111
|
+
completionContract = false,
|
|
112
|
+
}) {
|
|
113
|
+
const routing = await resolveActiveModel(globalConfig, { overrideModel });
|
|
114
|
+
// Mutable: lazy-retry can rotate to a different model mid-loop on 429/413/5xx.
|
|
115
|
+
let activeModel = routing.modelId;
|
|
116
|
+
|
|
117
|
+
// Build the chain to walk on retryable failures: everything in
|
|
118
|
+
// fallbackModels() that isn't `activeModel` already AND wasn't already
|
|
119
|
+
// marked unhealthy by resolveActiveModel(). No point retrying with Ollama
|
|
120
|
+
// when /api/tags strict check just told us the model isn't pulled.
|
|
121
|
+
const triedHealth = new Map(
|
|
122
|
+
(routing.tried || []).map((t) => [t.modelId, t.healthy !== false])
|
|
123
|
+
);
|
|
124
|
+
const retryChain = fallbackModels(globalConfig).filter((m) => {
|
|
125
|
+
if (m === activeModel) return false;
|
|
126
|
+
if (triedHealth.get(m) === false) return false;
|
|
127
|
+
return true;
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
if (routing.fromFallback) {
|
|
131
|
+
await emitProgress(onEvent, {
|
|
132
|
+
type: "model_routed",
|
|
133
|
+
model: activeModel,
|
|
134
|
+
provider: routing.provider,
|
|
135
|
+
from_fallback: true,
|
|
136
|
+
tried: routing.tried,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Suppression: callers (notably the routine runner) can disable tools whose
|
|
141
|
+
// output would duplicate post_commands. We filter the schemas the engine
|
|
142
|
+
// sees AND keep a deny-set so a model that hallucinates a suppressed tool
|
|
143
|
+
// call gets a clear error rather than firing.
|
|
144
|
+
let effectiveSchemas = Array.isArray(suppressTools) && suppressTools.length > 0
|
|
145
|
+
? filterToolSchemas(toolSchemas, suppressTools)
|
|
146
|
+
: toolSchemas;
|
|
147
|
+
const suppressed = new Set(Array.isArray(suppressTools) ? suppressTools : []);
|
|
148
|
+
if (suppressed.size > 0) {
|
|
149
|
+
await emitProgress(onEvent, {
|
|
150
|
+
type: "tools_suppressed",
|
|
151
|
+
tools: [...suppressed],
|
|
152
|
+
reason: "post_commands_overlap",
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
// Completion contract: only meaningful when there are real tools to choose
|
|
156
|
+
// between. Inject `finish` so the model has a graceful way to end the turn
|
|
157
|
+
// under toolChoice:"required".
|
|
158
|
+
const useContract = completionContract && effectiveSchemas.length > 0;
|
|
159
|
+
if (useContract) {
|
|
160
|
+
effectiveSchemas = [...effectiveSchemas, FINISH_TOOL_SCHEMA];
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const rawHandlers = makeToolHandlers({
|
|
164
|
+
...toolHandlerCtx,
|
|
165
|
+
implicitConfirmation:
|
|
166
|
+
isShortConfirmation(prompt) && lastAssistantAskedForConfirmation(previousMessages),
|
|
167
|
+
});
|
|
168
|
+
const handlers = suppressed.size > 0
|
|
169
|
+
? new Proxy(rawHandlers, {
|
|
170
|
+
get(target, name) {
|
|
171
|
+
if (typeof name === "string" && suppressed.has(name)) {
|
|
172
|
+
return async () => ({
|
|
173
|
+
error: `tool "${name}" is suppressed for this invocation (post_commands already cover this output channel)`,
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
return target[name];
|
|
177
|
+
},
|
|
178
|
+
})
|
|
179
|
+
: rawHandlers;
|
|
180
|
+
|
|
181
|
+
const conversation = [...previousMessages, { role: "user", content: prompt }];
|
|
182
|
+
const trace = [];
|
|
183
|
+
let totalUsage = { input_tokens: 0, output_tokens: 0 };
|
|
184
|
+
let lastText = "";
|
|
185
|
+
let usePseudoTools = false;
|
|
186
|
+
let ackOnlyStreak = 0;
|
|
187
|
+
// Side-effect dedupe. Weaker models (Gemini especially) sometimes
|
|
188
|
+
// re-emit the SAME tool call across iterations — e.g. send_telegram
|
|
189
|
+
// three times with identical args, spamming the user. For tools
|
|
190
|
+
// that mutate the world we remember the (name + args) signature and
|
|
191
|
+
// short-circuit duplicates with a synthetic "already done" result
|
|
192
|
+
// instead of re-running. Read-only tools are exempt (idempotent and
|
|
193
|
+
// sometimes legitimately repeated, like list_tasks before/after).
|
|
194
|
+
const sideEffectExecuted = new Map();
|
|
195
|
+
const SIDE_EFFECT_TOOLS = new Set([
|
|
196
|
+
"send_telegram",
|
|
197
|
+
"create_task",
|
|
198
|
+
"write_file",
|
|
199
|
+
"edit_file",
|
|
200
|
+
"run_shell",
|
|
201
|
+
"call_runtime",
|
|
202
|
+
"add_project",
|
|
203
|
+
"set_identity",
|
|
204
|
+
]);
|
|
205
|
+
const sideEffectSignature = (name, args) => {
|
|
206
|
+
try {
|
|
207
|
+
return `${name}:${JSON.stringify(args)}`;
|
|
208
|
+
} catch {
|
|
209
|
+
return `${name}:<unserializable>`;
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
// Engine call wrapped with lazy retry: on 413/429/5xx/rate-limit/etc, try
|
|
214
|
+
// the next model in `retryChain` instead of bubbling. Stops when the chain
|
|
215
|
+
// is exhausted; non-retryable errors (auth, bad payload) throw immediately.
|
|
216
|
+
// See spec/backlog/13 + src/core/agent/retry.js for the classifier.
|
|
217
|
+
const tryCallEngine = async (params, { allowRetry = true } = {}) => {
|
|
218
|
+
while (true) {
|
|
219
|
+
try {
|
|
220
|
+
return await callEngine({ ...params, modelId: activeModel });
|
|
221
|
+
} catch (e) {
|
|
222
|
+
if (!allowRetry || retryChain.length === 0 || !isRetryableEngineError(e)) throw e;
|
|
223
|
+
const nextModel = retryChain.shift();
|
|
224
|
+
await emitProgress(onEvent, {
|
|
225
|
+
type: "engine_failed",
|
|
226
|
+
model: activeModel,
|
|
227
|
+
reason: shortRetryReason(e),
|
|
228
|
+
retry_with: nextModel,
|
|
229
|
+
});
|
|
230
|
+
activeModel = nextModel;
|
|
231
|
+
// After switching providers the pseudo-tools mode (Ollama-only) is no
|
|
232
|
+
// longer relevant; reset so we use structured tools on the new model.
|
|
233
|
+
if (usePseudoTools) usePseudoTools = false;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
for (let iter = 0; iter < maxIters; iter++) {
|
|
239
|
+
await emitProgress(onEvent, { type: "model_start", iteration: iter + 1, model: activeModel });
|
|
240
|
+
// Force a tool call on iter 0 ONLY when the user message looks like a real
|
|
241
|
+
// action request ("listame…", "mandá…", "buscá…"). For chit-chat ("hola",
|
|
242
|
+
// "qué tal") forcing a tool makes weaker models (llama-3.3 via Groq,
|
|
243
|
+
// qwen3-32b) emit a malformed tool_calls payload — Groq then rejects the
|
|
244
|
+
// whole turn with 400 "Failed to call a function". Better: let the model
|
|
245
|
+
// choose between text and tool when the prompt is conversational.
|
|
246
|
+
const forceTool =
|
|
247
|
+
effectiveSchemas.length > 0 &&
|
|
248
|
+
(useContract ||
|
|
249
|
+
(iter === 0 && looksLikeActionRequest(prompt)) ||
|
|
250
|
+
(ackOnlyStreak > 0 && ackOnlyStreak <= MAX_CONSECUTIVE_ACKS));
|
|
251
|
+
let result;
|
|
252
|
+
try {
|
|
253
|
+
result = await tryCallEngine({
|
|
254
|
+
system: usePseudoTools ? pseudoToolSystem(system, effectiveSchemas) : system,
|
|
255
|
+
messages: conversation,
|
|
256
|
+
config: globalConfig,
|
|
257
|
+
tools: usePseudoTools ? null : effectiveSchemas,
|
|
258
|
+
toolChoice: usePseudoTools ? null : (forceTool ? "required" : "auto"),
|
|
259
|
+
// Smaller cap by default: 1024 ate too much of the cheap-tier TPM
|
|
260
|
+
// budget. The super-agent rarely emits long replies; tool args are
|
|
261
|
+
// small. Summarization callers raise it via the maxTokens arg.
|
|
262
|
+
maxTokens,
|
|
263
|
+
signal,
|
|
264
|
+
onToken: (!forceTool && onToken) ? onToken : null,
|
|
265
|
+
});
|
|
266
|
+
} catch (e) {
|
|
267
|
+
if (usePseudoTools && /^ollama:/i.test(String(activeModel || "")) && /ollama\s+500/i.test(String(e?.message || "")) && trace.length > 0) {
|
|
268
|
+
await emitProgress(onEvent, { type: "model_retry", reason: "ollama_final_response_500", iteration: iter + 1 });
|
|
269
|
+
lastText = fallbackFinalText(trace, e);
|
|
270
|
+
break;
|
|
271
|
+
}
|
|
272
|
+
if (!shouldRetryWithPseudoTools(activeModel, e, usePseudoTools)) throw e;
|
|
273
|
+
usePseudoTools = true;
|
|
274
|
+
await emitProgress(onEvent, { type: "model_retry", reason: "ollama_structured_tools_500", iteration: iter + 1 });
|
|
275
|
+
result = await tryCallEngine({
|
|
276
|
+
system: pseudoToolSystem(system, toolSchemas),
|
|
277
|
+
messages: conversation,
|
|
278
|
+
config: globalConfig,
|
|
279
|
+
tools: null,
|
|
280
|
+
toolChoice: null,
|
|
281
|
+
maxTokens,
|
|
282
|
+
signal,
|
|
283
|
+
onToken: (iter > 0 && onToken) ? onToken : null,
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
totalUsage.input_tokens += result.usage?.input_tokens || 0;
|
|
288
|
+
totalUsage.output_tokens += result.usage?.output_tokens || 0;
|
|
289
|
+
lastText = result.text || "";
|
|
290
|
+
|
|
291
|
+
let toolCalls = result.tool_calls || (result.message && result.message.tool_calls) || null;
|
|
292
|
+
|
|
293
|
+
if ((!toolCalls || toolCalls.length === 0) && lastText) {
|
|
294
|
+
const pseudo = extractPseudoToolCalls(lastText);
|
|
295
|
+
if (pseudo.length > 0) {
|
|
296
|
+
toolCalls = pseudo;
|
|
297
|
+
lastText = cleanTextOfPseudoToolCalls(lastText);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
if (!toolCalls || toolCalls.length === 0) {
|
|
302
|
+
if (iter === 0 && isGhostResponse(lastText) && looksLikeActionRequest(prompt)) {
|
|
303
|
+
await emitProgress(onEvent, { type: "ghost_response_detected", text: lastText });
|
|
304
|
+
conversation.push({ role: "assistant", content: lastText });
|
|
305
|
+
conversation.push({
|
|
306
|
+
role: "user",
|
|
307
|
+
content:
|
|
308
|
+
"Remember: you must execute the action, not just confirm it. " +
|
|
309
|
+
"Call the tool now — action first, report after.",
|
|
310
|
+
});
|
|
311
|
+
continue;
|
|
312
|
+
}
|
|
313
|
+
lastText = cleanTextOfPseudoToolCalls(lastText) || lastText;
|
|
314
|
+
break;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
const visibleText = cleanTextOfPseudoToolCalls(lastText).trim();
|
|
318
|
+
if (visibleText) {
|
|
319
|
+
await emitProgress(onEvent, { type: "assistant_text", text: visibleText, iteration: iter + 1 });
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
conversation.push({
|
|
323
|
+
role: "assistant",
|
|
324
|
+
content: result.text || "",
|
|
325
|
+
tool_calls: toolCalls,
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
let finishSummary = null;
|
|
329
|
+
for (const tc of toolCalls) {
|
|
330
|
+
const fn = tc.function || tc;
|
|
331
|
+
const name = fn.name;
|
|
332
|
+
let args = fn.arguments;
|
|
333
|
+
if (typeof args === "string") {
|
|
334
|
+
try { args = JSON.parse(args); } catch { args = {}; }
|
|
335
|
+
}
|
|
336
|
+
args = args || {};
|
|
337
|
+
|
|
338
|
+
// Completion contract: `finish` declares the task done. Capture its
|
|
339
|
+
// summary as the final text and stop processing the rest of this turn.
|
|
340
|
+
if (name === "finish") {
|
|
341
|
+
finishSummary = typeof args.summary === "string" ? args.summary : "";
|
|
342
|
+
break;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
let toolResult;
|
|
346
|
+
const traceId = `${iter + 1}:${trace.length + 1}`;
|
|
347
|
+
await emitProgress(onEvent, {
|
|
348
|
+
type: "tool_start",
|
|
349
|
+
trace: { id: traceId, tool: name, args, pending: true },
|
|
350
|
+
iteration: iter + 1,
|
|
351
|
+
});
|
|
352
|
+
// Dedupe identical side-effecting calls within this turn.
|
|
353
|
+
const sig = SIDE_EFFECT_TOOLS.has(name) ? sideEffectSignature(name, args) : null;
|
|
354
|
+
if (sig && sideEffectExecuted.has(sig)) {
|
|
355
|
+
toolResult = {
|
|
356
|
+
ok: true,
|
|
357
|
+
deduped: true,
|
|
358
|
+
note: `Ya ejecuté "${name}" con estos mismos argumentos en este turno; no lo repito.`,
|
|
359
|
+
previous: sideEffectExecuted.get(sig),
|
|
360
|
+
};
|
|
361
|
+
await emitProgress(onEvent, {
|
|
362
|
+
type: "tool_deduped",
|
|
363
|
+
trace: { id: traceId, tool: name, args },
|
|
364
|
+
iteration: iter + 1,
|
|
365
|
+
});
|
|
366
|
+
} else {
|
|
367
|
+
try {
|
|
368
|
+
const handler = handlers[name];
|
|
369
|
+
toolResult = handler ? await handler(args) : { error: `unknown tool: ${name}` };
|
|
370
|
+
} catch (e) {
|
|
371
|
+
toolResult = { error: e.message };
|
|
372
|
+
}
|
|
373
|
+
if (sig) sideEffectExecuted.set(sig, summarizeForTrace(toolResult));
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
const traceItem = { id: traceId, tool: name, args, result: summarizeForTrace(toolResult) };
|
|
377
|
+
trace.push(traceItem);
|
|
378
|
+
await emitProgress(onEvent, { type: "tool_result", trace: traceItem, iteration: iter + 1 });
|
|
379
|
+
|
|
380
|
+
// Groq (and strict OpenAI) require tool_call_id to be present and
|
|
381
|
+
// match the id of the tool_call in the previous assistant message.
|
|
382
|
+
// Real engines populate it; the pseudo-tool parser also assigns one
|
|
383
|
+
// (`pseudo_<…>`). Either way, surface it on the tool result message
|
|
384
|
+
// — otherwise Groq returns 400 "tool_call_id is missing".
|
|
385
|
+
conversation.push({
|
|
386
|
+
role: "tool",
|
|
387
|
+
tool_call_id: tc.id || `synth_${iter}_${trace.length}`,
|
|
388
|
+
tool_name: name,
|
|
389
|
+
content: JSON.stringify(toolResult),
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
// Task declared complete via the contract — emit the summary as the final
|
|
394
|
+
// assistant text and exit the loop.
|
|
395
|
+
if (finishSummary !== null) {
|
|
396
|
+
if (finishSummary) {
|
|
397
|
+
lastText = finishSummary;
|
|
398
|
+
await emitProgress(onEvent, { type: "assistant_text", text: finishSummary, iteration: iter + 1 });
|
|
399
|
+
}
|
|
400
|
+
break;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
const allAckOnly = toolCalls.every((tc) => {
|
|
404
|
+
const n = (tc.function?.name) || tc.name;
|
|
405
|
+
return ACK_ONLY_TOOLS.has(n);
|
|
406
|
+
});
|
|
407
|
+
if (allAckOnly) {
|
|
408
|
+
ackOnlyStreak += 1;
|
|
409
|
+
await emitProgress(onEvent, { type: "ack_only_iter", iteration: iter + 1, streak: ackOnlyStreak });
|
|
410
|
+
} else {
|
|
411
|
+
ackOnlyStreak = 0;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
return {
|
|
416
|
+
text: lastText,
|
|
417
|
+
usage: totalUsage,
|
|
418
|
+
name: agentName,
|
|
419
|
+
trace,
|
|
420
|
+
model: activeModel,
|
|
421
|
+
routing,
|
|
422
|
+
};
|
|
423
|
+
}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
// Roby's own notebook — the super-agent's personal, persistent memory.
|
|
2
|
+
//
|
|
3
|
+
// This is distinct from:
|
|
4
|
+
// - identity.json → who Roby is (name, personality, owner)
|
|
5
|
+
// - project agents' .apc/agents/<slug>/memory.md → per-agent, per-project
|
|
6
|
+
// - sessions → raw transcripts of past work (search_sessions)
|
|
7
|
+
//
|
|
8
|
+
// It is a single free-form markdown file at ~/.apx/memory.md that Roby keeps
|
|
9
|
+
// itself: durable facts about the owner, ongoing threads, decisions, and the
|
|
10
|
+
// gist of what it has been working on (which it refreshes by skimming its own
|
|
11
|
+
// recent sessions). A bounded slice is injected into every super-agent prompt;
|
|
12
|
+
// the `remember` / `read_self_memory` tools write and read it.
|
|
13
|
+
import fs from "node:fs";
|
|
14
|
+
import os from "node:os";
|
|
15
|
+
import path from "node:path";
|
|
16
|
+
|
|
17
|
+
export const SELF_MEMORY_PATH = path.join(os.homedir(), ".apx", "memory.md");
|
|
18
|
+
|
|
19
|
+
// How much of the notebook to inline into the system prompt. The full file is
|
|
20
|
+
// always readable via read_self_memory; this only bounds the always-on slice
|
|
21
|
+
// so a long notebook can't blow the token budget on cheap channels.
|
|
22
|
+
export const SELF_MEMORY_PROMPT_LIMIT = 2000;
|
|
23
|
+
|
|
24
|
+
export function readSelfMemory() {
|
|
25
|
+
try {
|
|
26
|
+
return fs.readFileSync(SELF_MEMORY_PATH, "utf8");
|
|
27
|
+
} catch {
|
|
28
|
+
return "";
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** Bounded slice for the system prompt. Returns "" when the notebook is empty. */
|
|
33
|
+
export function readSelfMemoryForPrompt(limit = SELF_MEMORY_PROMPT_LIMIT) {
|
|
34
|
+
const body = readSelfMemory().trim();
|
|
35
|
+
if (!body) return "";
|
|
36
|
+
if (body.length <= limit) return body;
|
|
37
|
+
return body.slice(0, limit).trimEnd() + "\n… (truncated — call read_self_memory for the full notebook)";
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// HH:MM (UTC) for the current time — used to tag notes per the cross-channel
|
|
41
|
+
// format "[HH:MM][canal] nota".
|
|
42
|
+
function nowHm() {
|
|
43
|
+
return new Date().toISOString().slice(11, 16);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Append a dated note to the notebook. Each note is a markdown bullet under a
|
|
48
|
+
* `## YYYY-MM-DD` heading so the file stays chronologically skimmable. Creates
|
|
49
|
+
* the file (and ~/.apx) on first write.
|
|
50
|
+
*
|
|
51
|
+
* opts.channel — when given, the bullet is tagged "[HH:MM][channel] note" so
|
|
52
|
+
* the cross-channel broker (and the RAG indexer) can attribute the note to a
|
|
53
|
+
* surface and time. Without it the legacy "- note" form is kept.
|
|
54
|
+
*/
|
|
55
|
+
export function appendSelfMemory(note, opts = {}) {
|
|
56
|
+
const text = String(note || "").trim();
|
|
57
|
+
if (!text) throw new Error("nothing to remember (empty note)");
|
|
58
|
+
fs.mkdirSync(path.dirname(SELF_MEMORY_PATH), { recursive: true });
|
|
59
|
+
|
|
60
|
+
const today = new Date().toISOString().slice(0, 10);
|
|
61
|
+
const existing = readSelfMemory();
|
|
62
|
+
const heading = `## ${today}`;
|
|
63
|
+
const oneLine = text.replace(/\n+/g, " ").trim();
|
|
64
|
+
const channel = String(opts.channel || "").trim().toLowerCase();
|
|
65
|
+
const tag = channel ? `[${opts.time || nowHm()}][${channel}] ` : "";
|
|
66
|
+
const bullet = `- ${tag}${oneLine}`;
|
|
67
|
+
|
|
68
|
+
let next;
|
|
69
|
+
if (!existing.trim()) {
|
|
70
|
+
next = `# Roby's notebook\n\n${heading}\n${bullet}\n`;
|
|
71
|
+
} else if (existing.includes(heading)) {
|
|
72
|
+
// Append the bullet under today's existing heading.
|
|
73
|
+
const lines = existing.split("\n");
|
|
74
|
+
const idx = lines.lastIndexOf(heading);
|
|
75
|
+
// Find the end of today's block (next heading or EOF).
|
|
76
|
+
let insertAt = lines.length;
|
|
77
|
+
for (let i = idx + 1; i < lines.length; i++) {
|
|
78
|
+
if (lines[i].startsWith("## ")) {
|
|
79
|
+
insertAt = i;
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
// Trim trailing blank lines inside the block before inserting.
|
|
84
|
+
while (insertAt > idx + 1 && lines[insertAt - 1].trim() === "") insertAt--;
|
|
85
|
+
lines.splice(insertAt, 0, bullet);
|
|
86
|
+
next = lines.join("\n");
|
|
87
|
+
if (!next.endsWith("\n")) next += "\n";
|
|
88
|
+
} else {
|
|
89
|
+
const sep = existing.endsWith("\n") ? "" : "\n";
|
|
90
|
+
next = `${existing}${sep}\n${heading}\n${bullet}\n`;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
fs.writeFileSync(SELF_MEMORY_PATH, next);
|
|
94
|
+
return { path: SELF_MEMORY_PATH, note: text };
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Ensure the notebook file exists (created empty-ish on daemon boot, Pieza 1).
|
|
98
|
+
// Returns true if it created the file, false if it already existed.
|
|
99
|
+
export function ensureSelfMemoryFile() {
|
|
100
|
+
try {
|
|
101
|
+
if (fs.existsSync(SELF_MEMORY_PATH)) return false;
|
|
102
|
+
fs.mkdirSync(path.dirname(SELF_MEMORY_PATH), { recursive: true });
|
|
103
|
+
fs.writeFileSync(SELF_MEMORY_PATH, "# Roby's notebook\n");
|
|
104
|
+
return true;
|
|
105
|
+
} catch {
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Parse the notebook into structured entries, oldest first. Tolerant of both
|
|
111
|
+
// the legacy "- note" bullets and the tagged "[HH:MM][channel] note" /
|
|
112
|
+
// "[YYYY-MM-DD HH:MM][channel] note" forms. Each entry:
|
|
113
|
+
// { date, time, channel, ts, text }
|
|
114
|
+
export function parseSelfMemoryEntries(text) {
|
|
115
|
+
const out = [];
|
|
116
|
+
let date = "";
|
|
117
|
+
for (const raw of String(text || "").split("\n")) {
|
|
118
|
+
const line = raw.trim();
|
|
119
|
+
const h = line.match(/^##\s+(\d{4}-\d{2}-\d{2})/);
|
|
120
|
+
if (h) {
|
|
121
|
+
date = h[1];
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
const b = line.match(/^[-*]\s+(.*)$/);
|
|
125
|
+
if (!b) continue;
|
|
126
|
+
let rest = b[1].trim();
|
|
127
|
+
let time = "";
|
|
128
|
+
let channel = "";
|
|
129
|
+
// [YYYY-MM-DD HH:MM] (full timestamp) takes precedence over a bare time.
|
|
130
|
+
let m = rest.match(/^\[(\d{4}-\d{2}-\d{2})\s+(\d{1,2}:\d{2})\]\s*/);
|
|
131
|
+
if (m) {
|
|
132
|
+
date = m[1];
|
|
133
|
+
time = m[2];
|
|
134
|
+
rest = rest.slice(m[0].length);
|
|
135
|
+
} else {
|
|
136
|
+
m = rest.match(/^\[(\d{1,2}:\d{2})\]\s*/);
|
|
137
|
+
if (m) {
|
|
138
|
+
time = m[1];
|
|
139
|
+
rest = rest.slice(m[0].length);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
// [channel]
|
|
143
|
+
const c = rest.match(/^\[([a-z0-9_-]+)\]\s*/i);
|
|
144
|
+
if (c) {
|
|
145
|
+
channel = c[1].toLowerCase();
|
|
146
|
+
rest = rest.slice(c[0].length);
|
|
147
|
+
}
|
|
148
|
+
rest = rest.trim();
|
|
149
|
+
if (!rest) continue;
|
|
150
|
+
const hm = time ? time.padStart(5, "0") : "00:00";
|
|
151
|
+
const ts = date ? `${date}T${hm}:00Z` : "";
|
|
152
|
+
out.push({ date, time, channel: channel || "memory", ts, text: rest });
|
|
153
|
+
}
|
|
154
|
+
return out;
|
|
155
|
+
}
|