@vellumai/assistant 0.7.3 → 0.8.1
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/AGENTS.md +11 -0
- package/ARCHITECTURE.md +29 -28
- package/Dockerfile +6 -4
- package/README.md +2 -2
- package/__tests__/permissions/gateway-threshold-reader.test.ts +236 -9
- package/bun.lock +3 -0
- package/docker-entrypoint.sh +16 -0
- package/eslint-rules/__tests__/cli-no-daemon-internals.test.ts +420 -0
- package/eslint-rules/cli-no-daemon-internals.js +283 -0
- package/eslint.config.mjs +12 -0
- package/knip.json +3 -1
- package/node_modules/@vellumai/ipc-server-utils/bun.lock +24 -0
- package/node_modules/@vellumai/ipc-server-utils/package.json +18 -0
- package/node_modules/@vellumai/ipc-server-utils/src/index.ts +6 -0
- package/node_modules/@vellumai/ipc-server-utils/src/socket-watchdog.test.ts +430 -0
- package/node_modules/@vellumai/ipc-server-utils/src/socket-watchdog.ts +221 -0
- package/node_modules/@vellumai/ipc-server-utils/tsconfig.json +20 -0
- package/node_modules/@vellumai/skill-host-contracts/src/client.ts +10 -1
- package/openapi.yaml +4126 -959
- package/package.json +5 -1
- package/scripts/generate-openapi.ts +52 -4
- package/scripts/sync-llm-catalog.ts +165 -0
- package/scripts/sync-web-search-catalog.ts +107 -0
- package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +169 -0
- package/src/__tests__/agent-loop-override-profile.test.ts +26 -1
- package/src/__tests__/annotate-risk-options.test.ts +291 -0
- package/src/__tests__/anthropic-provider.test.ts +92 -2
- package/src/__tests__/app-control-flow.test.ts +7 -0
- package/src/__tests__/approval-cascade.test.ts +8 -16
- package/src/__tests__/approval-routes-http.test.ts +6 -0
- package/src/__tests__/assistant-events-sse-shed.test.ts +232 -0
- package/src/__tests__/auto-analysis-end-to-end.test.ts +12 -25
- package/src/__tests__/avatar-identity-sync.test.ts +87 -0
- package/src/__tests__/background-workers-disk-pressure.test.ts +11 -22
- package/src/__tests__/btw-routes.test.ts +1 -0
- package/src/__tests__/call-constants.test.ts +10 -1
- package/src/__tests__/call-controller.test.ts +127 -0
- package/src/__tests__/call-site-routing-provider.test.ts +172 -45
- package/src/__tests__/cancel-resolves-conversation-key.test.ts +44 -3
- package/src/__tests__/channel-policy.test.ts +12 -0
- package/src/__tests__/checker.test.ts +89 -0
- package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +88 -30
- package/src/__tests__/compact-event-conversation-id-guard.test.ts +33 -5
- package/src/__tests__/compaction-strip-metadata-clear.test.ts +26 -1
- package/src/__tests__/config-loader-backfill.test.ts +526 -102
- package/src/__tests__/config-loader-corrupt.test.ts +68 -0
- package/src/__tests__/config-loader-platform-defaults.test.ts +345 -8
- package/src/__tests__/config-schema-cmd.test.ts +63 -29
- package/src/__tests__/config-schema.test.ts +14 -3
- package/src/__tests__/config-set-platform-guard.test.ts +75 -152
- package/src/__tests__/config-set-route.test.ts +198 -0
- package/src/__tests__/config-watcher.test.ts +6 -0
- package/src/__tests__/contacts-tools.test.ts +51 -199
- package/src/__tests__/context-search-agent-protocol.test.ts +21 -2
- package/src/__tests__/context-search-agent-runner.test.ts +22 -138
- package/src/__tests__/context-search-conversations-source.test.ts +42 -16
- package/src/__tests__/context-search-fanout.test.ts +20 -157
- package/src/__tests__/context-search-memory-source.test.ts +3 -26
- package/src/__tests__/context-search-memory-v2-source.test.ts +3 -3
- package/src/__tests__/context-search-types.test.ts +7 -2
- package/src/__tests__/context-window-manager.test.ts +389 -1
- package/src/__tests__/conversation-abort-tool-results.test.ts +1 -6
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +1 -1
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +2 -1
- package/src/__tests__/conversation-agent-loop.test.ts +3 -3
- package/src/__tests__/conversation-confirmation-signals.test.ts +5 -13
- package/src/__tests__/conversation-crud-inference-profile.test.ts +100 -0
- package/src/__tests__/conversation-error.test.ts +38 -0
- package/src/__tests__/conversation-fork-crud.test.ts +241 -1
- package/src/__tests__/conversation-inference-profile-route.test.ts +14 -14
- package/src/__tests__/conversation-init.benchmark.test.ts +2 -1
- package/src/__tests__/conversation-lifecycle.test.ts +124 -0
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +100 -1
- package/src/__tests__/conversation-process-callsite.test.ts +22 -7
- package/src/__tests__/conversation-provider-retry-repair.test.ts +1 -6
- package/src/__tests__/conversation-runtime-assembly.test.ts +19 -10
- package/src/__tests__/conversation-slash-commands.test.ts +194 -2
- package/src/__tests__/conversation-slash-unknown.test.ts +1 -6
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +170 -9
- package/src/__tests__/conversation-surfaces-app-control.test.ts +323 -3
- package/src/__tests__/conversation-surfaces-data-persist.test.ts +73 -1
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +59 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +1 -7
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +1 -7
- package/src/__tests__/credential-security-invariants.test.ts +5 -6
- package/src/__tests__/daemon-credential-client.test.ts +56 -1
- package/src/__tests__/db-activation-state-fk-cascade.test.ts +132 -0
- package/src/__tests__/db-conversation-inference-profile-migration.test.ts +37 -0
- package/src/__tests__/db-memory-graph-event-date-repair.test.ts +43 -20
- package/src/__tests__/db-proxy-transaction.test.ts +206 -0
- package/src/__tests__/external-plugin-loader.test.ts +458 -0
- package/src/__tests__/filing-service.test.ts +25 -22
- package/src/__tests__/fixtures/mock-chrome-extension.ts +5 -0
- package/src/__tests__/gateway-only-guard.test.ts +0 -1
- package/src/__tests__/graph-extraction-event-date.test.ts +34 -0
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +10 -34
- package/src/__tests__/heartbeat-disk-pressure.test.ts +21 -8
- package/src/__tests__/heartbeat-service.test.ts +50 -233
- package/src/__tests__/history-repair.test.ts +89 -0
- package/src/__tests__/host-app-control-proxy.test.ts +109 -1
- package/src/__tests__/host-app-control-routes.test.ts +247 -1
- package/src/__tests__/host-browser-proxy.test.ts +416 -20
- package/src/__tests__/host-browser-routes.test.ts +325 -33
- package/src/__tests__/host-proxy-preactivation.test.ts +211 -0
- package/src/__tests__/inference-no-mode-boot-e2e.test.ts +246 -0
- package/src/__tests__/inference-profile-reaper.test.ts +154 -0
- package/src/__tests__/inference-profile-session-handler.test.ts +398 -0
- package/src/__tests__/inference-profile-session-ipc.test.ts +236 -0
- package/src/__tests__/injector-chain.test.ts +24 -16
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +10 -7
- package/src/__tests__/inline-skill-load-permissions.test.ts +6 -1
- package/src/__tests__/install-skill-routing.test.ts +2 -2
- package/src/__tests__/lifecycle-memory-v2-seed.test.ts +169 -67
- package/src/__tests__/llm-callsite-catalog.test.ts +20 -1
- package/src/__tests__/llm-catalog-parity.test.ts +146 -0
- package/src/__tests__/llm-request-log-source-clickhouse.test.ts +188 -0
- package/src/__tests__/llm-request-log-source-factory.test.ts +124 -0
- package/src/__tests__/llm-resolver.test.ts +46 -0
- package/src/__tests__/managed-profile-guard.test.ts +131 -2
- package/src/__tests__/mcp-auth-routes.test.ts +1 -0
- package/src/__tests__/mcp-cli.test.ts +182 -220
- package/src/__tests__/mcp-health-check.test.ts +56 -27
- package/src/__tests__/memory-jobs-worker-lanes.test.ts +18 -11
- package/src/__tests__/message-complete-display-id.test.ts +175 -0
- package/src/__tests__/notification-decision-fallback.test.ts +91 -0
- package/src/__tests__/notification-decision-strategy.test.ts +22 -0
- package/src/__tests__/notification-platform-adapter.test.ts +229 -0
- package/src/__tests__/oauth-cli.test.ts +38 -1888
- package/src/__tests__/oauth-commands-routes.test.ts +711 -0
- package/src/__tests__/oauth-connect-routes.test.ts +174 -11
- package/src/__tests__/oauth-providers-routes.test.ts +14 -10
- package/src/__tests__/openai-responses-cutover-guard.test.ts +33 -12
- package/src/__tests__/openai-responses-provider.test.ts +17 -0
- package/src/__tests__/plugin-bootstrap.test.ts +31 -2
- package/src/__tests__/plugin-route-contribution.test.ts +31 -3
- package/src/__tests__/plugin-tool-contribution.test.ts +31 -3
- package/src/__tests__/plugin-types.test.ts +13 -11
- package/src/__tests__/process-message-background-slack.test.ts +46 -0
- package/src/__tests__/profile-entry-status.test.ts +43 -0
- package/src/__tests__/provider-managed-proxy-integration.test.ts +12 -4
- package/src/__tests__/provider-registry-ollama.test.ts +12 -4
- package/src/__tests__/provider-send-message-override-profile.test.ts +10 -4
- package/src/__tests__/relay-server.test.ts +164 -2
- package/src/__tests__/retry-thinking-tool-choice.test.ts +15 -0
- package/src/__tests__/schedule-retry.test.ts +56 -4
- package/src/__tests__/schedule-routes.test.ts +104 -0
- package/src/__tests__/scheduler-disk-pressure.test.ts +0 -4
- package/src/__tests__/scheduler-recurrence.test.ts +87 -34
- package/src/__tests__/scheduler-reuse-conversation.test.ts +161 -5
- package/src/__tests__/scheduler-wake.test.ts +0 -63
- package/src/__tests__/secret-allowlist.test.ts +1 -0
- package/src/__tests__/secret-prompt-log-hygiene.test.ts +7 -5
- package/src/__tests__/secret-prompter-channel-fallback.test.ts +7 -5
- package/src/__tests__/secret-response-routing.test.ts +7 -5
- package/src/__tests__/secret-routes-managed-proxy.test.ts +12 -4
- package/src/__tests__/server-history-render.test.ts +82 -0
- package/src/__tests__/shell-credential-ref.test.ts +95 -3
- package/src/__tests__/shell-tool-proxy-mode.test.ts +14 -0
- package/src/__tests__/skill-include-graph.test.ts +31 -0
- package/src/__tests__/skill-load-feature-flag.test.ts +1 -0
- package/src/__tests__/skill-load-tool.test.ts +42 -16
- package/src/__tests__/skills.test.ts +39 -0
- package/src/__tests__/subagent-call-site-routing.test.ts +78 -16
- package/src/__tests__/suggestion-routes.test.ts +3 -3
- package/src/__tests__/sync-message-contract.test.ts +63 -0
- package/src/__tests__/task-scheduler.test.ts +88 -23
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +0 -42
- package/src/__tests__/tool-executor.test.ts +155 -0
- package/src/__tests__/update-bulletin-job.test.ts +96 -193
- package/src/__tests__/usage-cli.test.ts +11 -73
- package/src/__tests__/user-plugin-loader.test.ts +145 -0
- package/src/__tests__/vercel-config.test.ts +168 -0
- package/src/__tests__/voice-session-bridge.test.ts +3 -0
- package/src/__tests__/web-search-catalog-parity.test.ts +86 -0
- package/src/__tests__/web-search.test.ts +303 -2
- package/src/__tests__/workspace-migration-039-drop-legacy-llm-keys.test.ts +1 -21
- package/src/__tests__/workspace-migration-057-repair-stale-gemini-model-ids.test.ts +58 -0
- package/src/__tests__/workspace-migration-069-seed-onboarding-threads.test.ts +153 -0
- package/src/__tests__/workspace-migration-071-remove-safe-storage-release-note.test.ts +206 -0
- package/src/__tests__/workspace-migration-072-seed-reply-suggestion-callsite.test.ts +191 -0
- package/src/__tests__/workspace-migration-076-drop-services-inference-mode.test.ts +211 -0
- package/src/__tests__/workspace-migration-077-seed-memory-router-callsite.test.ts +174 -0
- package/src/__tests__/workspace-migration-079-home-feed-notification-only.test.ts +323 -0
- package/src/__tests__/workspace-migration-080-restrict-vercel-api-token-metadata.test.ts +299 -0
- package/src/__tests__/workspace-migration-081-backfill-bash-allowed-tools.test.ts +410 -0
- package/src/__tests__/workspace-migration-082-backfill-managed-profile-labels.test.ts +268 -0
- package/src/__tests__/workspace-migration-safe-storage-limits-release.test.ts +15 -27
- package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +3 -3
- package/src/__tests__/workspace-release-notes-feature-flag-guard.test.ts +115 -0
- package/src/acp/__tests__/helpers/which-stub.ts +4 -2
- package/src/acp/resolve-agent.test.ts +25 -0
- package/src/acp/resolve-agent.ts +13 -2
- package/src/acp/session-manager.ts +14 -0
- package/src/agent/loop.ts +11 -0
- package/src/approvals/guardian-decision-primitive.ts +0 -13
- package/src/approvals/guardian-request-resolvers.ts +19 -102
- package/src/calls/call-constants.ts +5 -8
- package/src/calls/call-controller.ts +130 -67
- package/src/calls/relay-server.ts +42 -1
- package/src/calls/relay-setup-router.ts +36 -0
- package/src/calls/types.ts +1 -0
- package/src/calls/voice-session-bridge.ts +24 -5
- package/src/channels/config.ts +14 -1
- package/src/channels/types.ts +1 -0
- package/src/cli/AGENTS.md +164 -4
- package/src/cli/__tests__/notifications.test.ts +54 -0
- package/src/cli/commands/__tests__/avatar.test.ts +540 -0
- package/src/cli/commands/__tests__/backup.test.ts +236 -776
- package/src/cli/commands/__tests__/cache.test.ts +1 -1
- package/src/cli/commands/__tests__/changelog.test.ts +593 -0
- package/src/cli/commands/__tests__/channel-verification-sessions.test.ts +503 -0
- package/src/cli/commands/__tests__/conversations-import.test.ts +515 -0
- package/src/cli/commands/__tests__/domain-register.test.ts +140 -167
- package/src/cli/commands/__tests__/domain-status.test.ts +137 -76
- package/src/cli/commands/__tests__/email-attachment.test.ts +314 -337
- package/src/cli/commands/__tests__/email-core.test.ts +579 -0
- package/src/cli/commands/__tests__/image-generation.test.ts +87 -824
- package/src/cli/commands/__tests__/inference-send.test.ts +30 -266
- package/src/cli/commands/__tests__/inference-session.test.ts +423 -0
- package/src/cli/commands/__tests__/memory-v2.test.ts +81 -110
- package/src/cli/commands/__tests__/skills.test.ts +563 -0
- package/src/cli/commands/__tests__/status.test.ts +249 -0
- package/src/cli/commands/__tests__/stt.test.ts +320 -0
- package/src/cli/commands/__tests__/tts-synthesize.test.ts +4 -603
- package/src/cli/commands/__tests__/tts.test.ts +321 -0
- package/src/cli/commands/__tests__/webhooks.test.ts +86 -511
- package/src/cli/commands/attachment.ts +8 -3
- package/src/cli/commands/audit.ts +95 -64
- package/src/cli/commands/auth.ts +61 -58
- package/src/cli/commands/avatar.ts +276 -390
- package/src/cli/commands/backup.ts +409 -505
- package/src/cli/commands/bash.ts +9 -5
- package/src/cli/commands/browser.ts +28 -9
- package/src/cli/commands/cache.ts +9 -4
- package/src/cli/commands/changelog.ts +414 -0
- package/src/cli/commands/channel-verification-sessions.ts +238 -317
- package/src/cli/commands/clients.ts +8 -3
- package/src/cli/commands/completions.ts +9 -9
- package/src/cli/commands/config.ts +102 -72
- package/src/cli/commands/contacts.ts +575 -696
- package/src/cli/commands/conversations-defer.ts +17 -69
- package/src/cli/commands/conversations-import.ts +90 -253
- package/src/cli/commands/conversations.ts +346 -436
- package/src/cli/commands/credential-execution.ts +9 -6
- package/src/cli/commands/credentials.ts +456 -736
- package/src/cli/commands/domain.ts +128 -206
- package/src/cli/commands/email.ts +606 -794
- package/src/cli/commands/gateway.ts +8 -1
- package/src/cli/commands/image-generation.ts +157 -205
- package/src/cli/commands/inference-providers.ts +352 -0
- package/src/cli/commands/inference-session.ts +415 -0
- package/src/cli/commands/inference.ts +87 -65
- package/src/cli/commands/keys.ts +8 -3
- package/src/cli/commands/mcp.ts +103 -287
- package/src/cli/commands/memory-v2.ts +163 -517
- package/src/cli/commands/notifications.ts +33 -7
- package/src/cli/commands/oauth/apps.ts +292 -261
- package/src/cli/commands/oauth/connect.ts +182 -345
- package/src/cli/commands/oauth/disconnect.ts +16 -215
- package/src/cli/commands/oauth/index.ts +49 -45
- package/src/cli/commands/oauth/mode.ts +43 -199
- package/src/cli/commands/oauth/ping.ts +17 -125
- package/src/cli/commands/oauth/providers.ts +732 -921
- package/src/cli/commands/oauth/request.ts +60 -350
- package/src/cli/commands/oauth/shared.ts +11 -121
- package/src/cli/commands/oauth/status.ts +31 -121
- package/src/cli/commands/oauth/token.ts +13 -55
- package/src/cli/commands/pending.ts +19 -10
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +133 -183
- package/src/cli/commands/platform/__tests__/connect.test.ts +66 -181
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +71 -227
- package/src/cli/commands/platform/__tests__/status.test.ts +169 -287
- package/src/cli/commands/platform/connect.ts +16 -80
- package/src/cli/commands/platform/disconnect.ts +14 -112
- package/src/cli/commands/platform/index.ts +177 -246
- package/src/cli/commands/routes.ts +153 -336
- package/src/cli/commands/sequence.ts +316 -360
- package/src/cli/commands/skills.ts +449 -671
- package/src/cli/commands/status.ts +58 -37
- package/src/cli/commands/stt.ts +94 -262
- package/src/cli/commands/task.ts +14 -40
- package/src/cli/commands/trust.ts +8 -3
- package/src/cli/commands/tts.ts +162 -167
- package/src/cli/commands/ui.ts +35 -42
- package/src/cli/commands/usage.ts +188 -126
- package/src/cli/commands/watchers.ts +8 -3
- package/src/cli/commands/webhooks.ts +99 -193
- package/src/cli/lib/__tests__/register-command.test.ts +85 -0
- package/src/cli/lib/daemon-credential-client.ts +4 -5
- package/src/cli/lib/nested-value.ts +44 -0
- package/src/cli/lib/open-browser.ts +36 -0
- package/src/cli/lib/register-command.ts +19 -0
- package/src/cli/lib/time-ago.ts +34 -0
- package/src/cli/program.ts +2 -4
- package/src/cli/utils/__tests__/conversation-id.test.ts +66 -0
- package/src/cli/utils/__tests__/parse-duration.test.ts +49 -0
- package/src/cli/utils/conversation-id.ts +30 -0
- package/src/cli/utils/parse-duration.ts +41 -0
- package/src/config/acp-defaults.test.ts +5 -1
- package/src/config/acp-defaults.ts +11 -4
- package/src/config/bundled-skills/acp/TOOLS.json +2 -2
- package/src/config/bundled-skills/app-builder/SKILL.md +1 -3
- package/src/config/bundled-skills/app-control/TOOLS.json +32 -0
- package/src/config/bundled-skills/contacts/SKILL.md +12 -45
- package/src/config/bundled-skills/contacts/TOOLS.json +0 -57
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +0 -12
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +0 -58
- package/src/config/bundled-tool-registry.ts +0 -2
- package/src/config/feature-flag-registry.json +17 -17
- package/src/config/llm-resolver.ts +16 -1
- package/src/config/loader.ts +148 -33
- package/src/config/raw-config-utils.ts +2 -30
- package/src/config/schema.ts +4 -0
- package/src/config/schemas/__tests__/memory-v2.test.ts +49 -0
- package/src/config/schemas/call-site-catalog.ts +29 -7
- package/src/config/schemas/llm-request-logs.ts +57 -0
- package/src/config/schemas/llm.ts +52 -2
- package/src/config/schemas/memory-retrospective.ts +48 -0
- package/src/config/schemas/memory-v2.ts +33 -2
- package/src/config/schemas/memory.ts +4 -0
- package/src/config/schemas/services.ts +15 -12
- package/src/config/seed-inference-profiles.ts +195 -134
- package/src/contacts/contact-store.ts +0 -61
- package/src/context/window-manager.ts +191 -5
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +111 -0
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +109 -4
- package/src/daemon/__tests__/daemon-skill-host.test.ts +10 -4
- package/src/daemon/approval-generators.ts +23 -29
- package/src/daemon/config-watcher.ts +2 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +56 -0
- package/src/daemon/conversation-agent-loop.ts +140 -107
- package/src/daemon/conversation-error.ts +21 -0
- package/src/daemon/conversation-lifecycle.ts +68 -13
- package/src/daemon/conversation-process.ts +36 -19
- package/src/daemon/conversation-runtime-assembly.ts +14 -5
- package/src/daemon/conversation-slash.ts +175 -23
- package/src/daemon/conversation-store.ts +17 -10
- package/src/daemon/conversation-surfaces.ts +92 -26
- package/src/daemon/conversation-tool-setup.ts +33 -19
- package/src/daemon/conversation.ts +49 -10
- package/src/daemon/external-plugins-bootstrap.ts +18 -8
- package/src/daemon/guardian-action-generators.ts +7 -22
- package/src/daemon/handlers/config-model.ts +8 -126
- package/src/daemon/handlers/config-slack-channel.ts +10 -7
- package/src/daemon/handlers/config-vercel.ts +3 -1
- package/src/daemon/handlers/shared.ts +26 -0
- package/src/daemon/handlers/skills.ts +84 -5
- package/src/daemon/history-repair.ts +33 -6
- package/src/daemon/host-app-control-proxy.ts +44 -19
- package/src/daemon/host-bash-proxy.ts +85 -158
- package/src/daemon/host-browser-proxy.ts +97 -36
- package/src/daemon/host-cu-proxy.ts +1 -1
- package/src/daemon/host-file-proxy.ts +1 -1
- package/src/daemon/host-proxy-base.ts +13 -1
- package/src/daemon/host-proxy-preactivation.ts +25 -1
- package/src/daemon/host-transfer-proxy.ts +2 -2
- package/src/daemon/identity-helpers.ts +19 -0
- package/src/daemon/lifecycle.ts +128 -114
- package/src/daemon/meet-host-supervisor.ts +15 -15
- package/src/daemon/memory-v2-startup.ts +62 -14
- package/src/daemon/message-protocol.ts +6 -0
- package/src/daemon/message-types/bookmarks.ts +18 -0
- package/src/daemon/message-types/conversations.ts +12 -9
- package/src/daemon/message-types/messages.ts +28 -2
- package/src/daemon/message-types/sync.ts +60 -0
- package/src/daemon/pkb-reminder-builder.test.ts +54 -13
- package/src/daemon/pkb-reminder-builder.ts +21 -7
- package/src/daemon/process-message.ts +56 -23
- package/src/daemon/server.ts +23 -18
- package/src/daemon/shutdown-handlers.ts +0 -2
- package/src/daemon/tool-setup-types.ts +9 -0
- package/src/daemon/tool-side-effects.ts +6 -4
- package/src/daemon/wake-target-adapter.ts +11 -0
- package/src/documents/document-store.ts +35 -1
- package/src/export/transcript-formatter.ts +61 -2
- package/src/filing/filing-service.ts +42 -56
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +359 -0
- package/src/heartbeat/heartbeat-run-store.ts +2 -1
- package/src/heartbeat/heartbeat-service.ts +149 -128
- package/src/home/__tests__/feed-types.test.ts +63 -131
- package/src/home/__tests__/feed-writer.test.ts +77 -278
- package/src/home/__tests__/post-connect-feed.test.ts +9 -12
- package/src/home/feed-types.ts +19 -73
- package/src/home/feed-writer.ts +25 -156
- package/src/home/post-connect-feed.ts +1 -3
- package/src/ipc/__tests__/cli-ipc.test.ts +2 -0
- package/src/ipc/__tests__/email-ipc.test.ts +506 -0
- package/src/ipc/__tests__/exit-helper.test.ts +104 -0
- package/src/ipc/__tests__/streaming-client.test.ts +237 -0
- package/src/ipc/__tests__/streaming-framing.test.ts +142 -0
- package/src/ipc/assistant-server.ts +148 -42
- package/src/ipc/cli-client.ts +370 -50
- package/src/ipc/routes/db-proxy-transaction.ts +151 -0
- package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +60 -0
- package/src/ipc/skill-routes/events.ts +30 -3
- package/src/ipc/skill-server.ts +99 -42
- package/src/live-voice/__tests__/live-voice-session-manager.test.ts +46 -0
- package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +1 -0
- package/src/live-voice/live-voice-session-manager.ts +11 -4
- package/src/live-voice/live-voice-session.ts +14 -6
- package/src/memory/__tests__/bookmark-crud.test.ts +258 -0
- package/src/memory/__tests__/bookmark-schema.test.ts +181 -0
- package/src/memory/__tests__/conversation-types.test.ts +36 -0
- package/src/memory/__tests__/find-most-recent-retrospective-for.test.ts +130 -0
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +10 -57
- package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +177 -0
- package/src/memory/__tests__/memory-retrospective-job.test.ts +328 -0
- package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +213 -0
- package/src/memory/__tests__/memory-retrospective-trigger-check.test.ts +90 -0
- package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +69 -0
- package/src/memory/__tests__/memory-v2-concept-frequency.test.ts +3 -0
- package/src/memory/bookmark-crud.ts +179 -0
- package/src/memory/context-search/__tests__/agent-runner-redaction.test.ts +31 -9
- package/src/memory/context-search/agent-protocol.ts +5 -1
- package/src/memory/context-search/agent-runner.ts +60 -85
- package/src/memory/context-search/limits.ts +1 -4
- package/src/memory/context-search/search.ts +23 -113
- package/src/memory/context-search/sources/conversations.ts +18 -6
- package/src/memory/context-search/sources/memory-v2.ts +40 -31
- package/src/memory/context-search/sources/memory.ts +9 -2
- package/src/memory/context-search/sources/workspace.ts +13 -10
- package/src/memory/context-search/types.ts +1 -1
- package/src/memory/conversation-bootstrap.ts +11 -0
- package/src/memory/conversation-crud.ts +312 -10
- package/src/memory/conversation-queries.ts +9 -5
- package/src/memory/conversation-title-service.ts +1 -0
- package/src/memory/conversation-types.ts +16 -0
- package/src/memory/db-init.ts +14 -0
- package/src/memory/embedding-backend.ts +2 -1
- package/src/memory/embedding-runtime-manager.ts +1 -2
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +104 -61
- package/src/memory/graph/__tests__/handle-remember-v2.test.ts +11 -26
- package/src/memory/graph/__tests__/remember-description.test.ts +55 -0
- package/src/memory/graph/conversation-graph-memory.ts +108 -14
- package/src/memory/graph/extraction.ts +4 -0
- package/src/memory/graph/graph-memory-state-store.ts +16 -3
- package/src/memory/graph/graph-search.test.ts +6 -5
- package/src/memory/graph/graph-search.ts +3 -4
- package/src/memory/graph/retriever.test.ts +12 -7
- package/src/memory/graph/retriever.ts +4 -5
- package/src/memory/graph/tool-handlers.ts +20 -11
- package/src/memory/graph/tools.ts +48 -9
- package/src/memory/indexer.ts +18 -2
- package/src/memory/jobs/__tests__/embed-concept-page.test.ts +120 -6
- package/src/memory/jobs/embed-concept-page.ts +261 -89
- package/src/memory/jobs-store.ts +51 -1
- package/src/memory/jobs-worker.ts +60 -7
- package/src/memory/llm-request-log-source-clickhouse.ts +317 -0
- package/src/memory/llm-request-log-source-local.ts +26 -0
- package/src/memory/llm-request-log-source.ts +97 -0
- package/src/memory/llm-request-log-store.ts +1 -1
- package/src/memory/memory-retrospective-constants.ts +13 -0
- package/src/memory/memory-retrospective-enqueue.ts +114 -0
- package/src/memory/memory-retrospective-job.ts +351 -0
- package/src/memory/memory-retrospective-startup-cleanup.ts +108 -0
- package/src/memory/memory-retrospective-state.ts +162 -0
- package/src/memory/memory-retrospective-trigger-check.ts +91 -0
- package/src/memory/memory-v2-activation-log-store.ts +49 -5
- package/src/memory/memory-v2-concept-frequency.ts +4 -0
- package/src/memory/message-content.ts +38 -1
- package/src/memory/migrations/227-add-conversation-inference-profile.ts +6 -1
- package/src/memory/migrations/228-rename-inference-profile-snake-case.ts +20 -7
- package/src/memory/migrations/229-delete-private-conversations.test.ts +70 -1
- package/src/memory/migrations/229-delete-private-conversations.ts +12 -0
- package/src/memory/migrations/231-repair-memory-graph-event-dates.ts +16 -2
- package/src/memory/migrations/240-conversation-inference-profile-session.ts +25 -0
- package/src/memory/migrations/241-activation-state-fk-cascade.ts +50 -0
- package/src/memory/migrations/242-message-bookmarks.ts +38 -0
- package/src/memory/migrations/243-provider-connections.ts +68 -0
- package/src/memory/migrations/244-provider-connection-status-label.ts +23 -0
- package/src/memory/migrations/245-memory-retrospective-state.ts +36 -0
- package/src/memory/migrations/246-backfill-provider-connection-label.ts +81 -0
- package/src/memory/migrations/__tests__/244-provider-connection-status-label.test.ts +84 -0
- package/src/memory/migrations/__tests__/245-memory-retrospective-state.test.ts +125 -0
- package/src/memory/migrations/__tests__/246-backfill-provider-connection-label.test.ts +192 -0
- package/src/memory/migrations/index.ts +7 -0
- package/src/memory/pkb/pkb-search.test.ts +6 -5
- package/src/memory/pkb/pkb-search.ts +4 -5
- package/src/memory/published-pages-store.ts +16 -0
- package/src/memory/qdrant-client.ts +3 -0
- package/src/memory/schema/bookmarks.ts +38 -0
- package/src/memory/schema/conversations.ts +2 -0
- package/src/memory/schema/index.ts +2 -0
- package/src/memory/schema/inference.ts +29 -0
- package/src/memory/schema/memory-core.ts +9 -0
- package/src/memory/search/semantic.ts +5 -9
- package/src/memory/v2/__tests__/__snapshots__/prompts-router.test.ts.snap +27 -0
- package/src/memory/v2/__tests__/activation-store.test.ts +5 -5
- package/src/memory/v2/__tests__/activation.test.ts +46 -9
- package/src/memory/v2/__tests__/backfill-jobs.test.ts +38 -21
- package/src/memory/v2/__tests__/consolidation-job.test.ts +140 -163
- package/src/memory/v2/__tests__/edge-index.test.ts +1 -1
- package/src/memory/v2/__tests__/frontmatter-sweep.test.ts +111 -0
- package/src/memory/v2/__tests__/injection.test.ts +768 -33
- package/src/memory/v2/__tests__/migration.test.ts +7 -3
- package/src/memory/v2/__tests__/page-index.test.ts +277 -0
- package/src/memory/v2/__tests__/page-store.test.ts +14 -1
- package/src/memory/v2/__tests__/prompts-router.test.ts +257 -0
- package/src/memory/v2/__tests__/qdrant.test.ts +382 -9
- package/src/memory/v2/__tests__/reranker.test.ts +4 -4
- package/src/memory/v2/__tests__/router.test.ts +516 -0
- package/src/memory/v2/__tests__/sim.test.ts +163 -8
- package/src/memory/v2/__tests__/skill-store.test.ts +58 -3
- package/src/memory/v2/__tests__/static-context.test.ts +8 -35
- package/src/memory/v2/__tests__/sweep-job.test.ts +114 -33
- package/src/memory/v2/activation-store.ts +34 -5
- package/src/memory/v2/activation.ts +40 -27
- package/src/memory/v2/backfill-jobs.ts +17 -84
- package/src/memory/v2/consolidation-job.ts +92 -86
- package/src/memory/v2/frontmatter-sweep.ts +91 -0
- package/src/memory/v2/injection.ts +466 -115
- package/src/memory/v2/migration.ts +117 -20
- package/src/memory/v2/page-index.ts +191 -0
- package/src/memory/v2/page-store.ts +42 -0
- package/src/memory/v2/prompts/consolidation.ts +14 -7
- package/src/memory/v2/prompts/router.ts +192 -0
- package/src/memory/v2/qdrant.ts +307 -133
- package/src/memory/v2/reranker.ts +14 -7
- package/src/memory/v2/router.ts +322 -0
- package/src/memory/v2/sim.ts +88 -34
- package/src/memory/v2/skill-store.ts +118 -29
- package/src/memory/v2/static-context.ts +20 -17
- package/src/memory/v2/sweep-job.ts +127 -102
- package/src/memory/v2/types.ts +16 -5
- package/src/memory/validation.ts +13 -0
- package/src/notifications/__tests__/emit-signal-home-feed.test.ts +182 -0
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +199 -0
- package/src/notifications/__tests__/signal-registry.test.ts +17 -0
- package/src/notifications/adapters/platform.ts +171 -0
- package/src/notifications/conversation-pairing.ts +2 -2
- package/src/notifications/copy-composer.ts +61 -12
- package/src/notifications/decision-engine.ts +46 -0
- package/src/notifications/destination-resolver.ts +21 -0
- package/src/notifications/emit-signal.ts +28 -1
- package/src/notifications/home-feed-side-effect.ts +111 -0
- package/src/notifications/signal.ts +5 -0
- package/src/permissions/checker.ts +12 -0
- package/src/permissions/gateway-threshold-reader.ts +116 -8
- package/src/permissions/ipc-risk-types.ts +2 -0
- package/src/permissions/prompter.ts +86 -96
- package/src/permissions/secret-prompter.ts +31 -31
- package/src/plugin-api/index.ts +13 -0
- package/src/plugin-api/package.json +12 -0
- package/src/plugin-api/types.ts +62 -0
- package/src/plugins/defaults/injectors.ts +20 -5
- package/src/plugins/external-plugin-loader.ts +294 -0
- package/src/plugins/types.ts +46 -30
- package/src/plugins/user-loader.ts +64 -41
- package/src/proactive-artifact/job.test.ts +63 -8
- package/src/proactive-artifact/job.ts +20 -2
- package/src/proactive-artifact/message-copy.ts +18 -1
- package/src/proactive-artifact/trigger-state.test.ts +9 -0
- package/src/proactive-artifact/trigger-state.ts +4 -0
- package/src/prompts/__tests__/system-prompt.test.ts +105 -0
- package/src/prompts/system-prompt.ts +22 -1
- package/src/prompts/templates/SOUL.md +13 -28
- package/src/prompts/update-bulletin-job.ts +61 -73
- package/src/providers/__tests__/dispatch-connection-routing.test.ts +279 -0
- package/src/providers/__tests__/inference.test.ts +288 -0
- package/src/providers/__tests__/provider-env-vars.test.ts +6 -0
- package/src/providers/__tests__/provider-secret-catalog.test.ts +6 -0
- package/src/providers/__tests__/retry-callsite.test.ts +14 -32
- package/src/providers/__tests__/satellite-connection-routing.test.ts +510 -0
- package/src/providers/__tests__/search-provider-catalog.test.ts +80 -0
- package/src/providers/anthropic/client.ts +95 -26
- package/src/providers/call-site-routing.ts +94 -16
- package/src/providers/connection-resolution.ts +163 -0
- package/src/providers/inference/__tests__/connections-status-label.test.ts +250 -0
- package/src/providers/inference/adapter-factory.ts +173 -0
- package/src/providers/inference/auth.ts +112 -0
- package/src/providers/inference/backfill.ts +196 -0
- package/src/providers/inference/connections.ts +356 -0
- package/src/providers/inference/resolve-auth.ts +65 -0
- package/src/providers/model-catalog.ts +104 -6
- package/src/providers/openai/responses-provider.ts +4 -2
- package/src/providers/provider-env-vars.ts +17 -7
- package/src/providers/provider-secret-catalog.ts +49 -30
- package/src/providers/provider-send-message.ts +41 -20
- package/src/providers/registry.ts +143 -159
- package/src/providers/retry.ts +18 -10
- package/src/providers/search-provider-catalog.ts +121 -0
- package/src/runtime/AGENTS.md +18 -5
- package/src/runtime/__tests__/background-job-runner.test.ts +357 -0
- package/src/runtime/__tests__/pre-first-message-gate.test.ts +82 -0
- package/src/runtime/actor-trust-resolver.ts +32 -10
- package/src/runtime/agent-wake.ts +35 -6
- package/src/runtime/assistant-event-hub.ts +3 -85
- package/src/runtime/auth/route-policy.ts +304 -8
- package/src/runtime/auth/same-actor.ts +2 -0
- package/src/runtime/background-job-runner.ts +339 -0
- package/src/runtime/btw-sidechain.ts +1 -0
- package/src/runtime/channel-approvals.ts +3 -2
- package/src/runtime/guardian-reply-router.ts +0 -10
- package/src/runtime/http-router.ts +36 -1
- package/src/runtime/http-server.ts +31 -5
- package/src/runtime/http-types.ts +2 -0
- package/src/runtime/middleware/__tests__/request-logger.test.ts +162 -0
- package/src/runtime/middleware/request-logger.ts +62 -1
- package/src/runtime/pending-interactions.ts +19 -15
- package/src/runtime/pre-first-message-gate.ts +83 -0
- package/src/runtime/routes/__tests__/backup-routes.test.ts +8 -1
- package/src/runtime/routes/__tests__/bookmark-routes.test.ts +251 -0
- package/src/runtime/routes/__tests__/connection-routes-vs-cli-parity.test.ts +142 -0
- package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +315 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +189 -0
- package/src/runtime/routes/__tests__/home-feed-routes.test.ts +15 -136
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +736 -0
- package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +147 -0
- package/src/runtime/routes/__tests__/stt-routes.test.ts +5 -1
- package/src/runtime/routes/__tests__/surface-action-routes.test.ts +384 -0
- package/src/runtime/routes/__tests__/tts-routes.test.ts +6 -2
- package/src/runtime/routes/acp-routes.ts +10 -8
- package/src/runtime/routes/app-management-routes.ts +228 -3
- package/src/runtime/routes/approval-routes.ts +7 -21
- package/src/runtime/routes/audit-routes.ts +43 -0
- package/src/runtime/routes/auth-routes.ts +72 -0
- package/src/runtime/routes/avatar-routes.ts +273 -20
- package/src/runtime/routes/backup-routes.ts +406 -2
- package/src/runtime/routes/bookmark-routes.ts +154 -0
- package/src/runtime/routes/channel-verification-routes.ts +2 -1
- package/src/runtime/routes/consolidation-routes.ts +8 -9
- package/src/runtime/routes/contact-routes.ts +0 -160
- package/src/runtime/routes/conversation-cli-routes.ts +192 -0
- package/src/runtime/routes/conversation-management-routes.ts +30 -43
- package/src/runtime/routes/conversation-query-routes.ts +373 -82
- package/src/runtime/routes/conversation-routes.ts +31 -10
- package/src/runtime/routes/conversations-import-routes.ts +229 -0
- package/src/runtime/routes/credential-routes.ts +540 -0
- package/src/runtime/routes/debug-bash-routes.ts +2 -0
- package/src/runtime/routes/debug-routes.ts +2 -2
- package/src/runtime/routes/document-pdf-renderer.ts +5 -1
- package/src/runtime/routes/domain-routes.ts +167 -0
- package/src/runtime/routes/email-routes.ts +603 -0
- package/src/runtime/routes/errors.ts +2 -2
- package/src/runtime/routes/events-routes.ts +192 -0
- package/src/runtime/routes/filing-routes.ts +2 -3
- package/src/runtime/routes/home-feed-routes.ts +6 -78
- package/src/runtime/routes/host-app-control-routes.ts +44 -2
- package/src/runtime/routes/host-browser-routes.ts +103 -22
- package/src/runtime/routes/http-adapter.ts +2 -0
- package/src/runtime/routes/identity-routes.ts +5 -0
- package/src/runtime/routes/image-generation-routes.ts +99 -0
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +137 -1
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +87 -7
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +156 -0
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +22 -7
- package/src/runtime/routes/index.ts +36 -0
- package/src/runtime/routes/inference-profile-session-handler.ts +312 -0
- package/src/runtime/routes/inference-profile-session-reaper.ts +98 -0
- package/src/runtime/routes/inference-profile-session-routes.ts +146 -0
- package/src/runtime/routes/inference-provider-connection-routes.ts +317 -0
- package/src/runtime/routes/inference-send-routes.ts +115 -0
- package/src/runtime/routes/integrations/twilio.ts +1 -0
- package/src/runtime/routes/mcp-auth-routes.ts +283 -9
- package/src/runtime/routes/memory-item-routes.test.ts +3 -9
- package/src/runtime/routes/memory-item-routes.ts +5 -6
- package/src/runtime/routes/memory-v2-routes.ts +105 -404
- package/src/runtime/routes/notification-routes.ts +2 -0
- package/src/runtime/routes/oauth-apps.ts +112 -7
- package/src/runtime/routes/oauth-commands-routes.ts +1007 -0
- package/src/runtime/routes/oauth-connect-routes.ts +67 -5
- package/src/runtime/routes/oauth-providers.ts +298 -8
- package/src/runtime/routes/platform-routes.ts +336 -0
- package/src/runtime/routes/playground/inject-failures.ts +2 -1
- package/src/runtime/routes/playground/reset-circuit.ts +2 -1
- package/src/runtime/routes/playground/state.ts +2 -1
- package/src/runtime/routes/publish-routes.ts +221 -0
- package/src/runtime/routes/schedule-routes.ts +82 -0
- package/src/runtime/routes/sequence-routes.ts +291 -0
- package/src/runtime/routes/settings-routes.ts +2 -10
- package/src/runtime/routes/skills-routes.ts +31 -1
- package/src/runtime/routes/stt-routes.ts +240 -3
- package/src/runtime/routes/surface-action-routes.ts +43 -7
- package/src/runtime/routes/tts-routes.ts +67 -0
- package/src/runtime/routes/types.ts +32 -0
- package/src/runtime/routes/user-routes-cli.ts +243 -0
- package/src/runtime/routes/webhook-routes.ts +165 -0
- package/src/runtime/sync/resource-sync-events.ts +25 -0
- package/src/runtime/sync/sync-publisher.test.ts +105 -0
- package/src/runtime/sync/sync-publisher.ts +21 -0
- package/src/schedule/scheduler.ts +200 -123
- package/src/security/__tests__/provider-key-env-fallback.test.ts +12 -6
- package/src/security/secret-patterns.ts +3 -0
- package/src/sequence/engine.ts +38 -40
- package/src/skills/include-graph.ts +35 -13
- package/src/subagent/manager.ts +20 -15
- package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +206 -0
- package/src/tools/browser/browser-execution.ts +15 -4
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +174 -0
- package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +16 -13
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +24 -1
- package/src/tools/browser/cdp-client/factory.ts +66 -5
- package/src/tools/browser/runtime-check.ts +77 -0
- package/src/tools/document/document-tool.ts +20 -0
- package/src/tools/executor.ts +18 -2
- package/src/tools/memory/register.test.ts +10 -8
- package/src/tools/memory/register.ts +9 -1
- package/src/tools/network/__tests__/web-search.test.ts +156 -0
- package/src/tools/network/web-search.ts +280 -37
- package/src/tools/permission-checker.ts +28 -5
- package/src/tools/skills/load.ts +24 -20
- package/src/tools/subagent/spawn.ts +3 -3
- package/src/tools/terminal/shell.ts +44 -0
- package/src/tools/tool-name-aliases.ts +19 -0
- package/src/tools/types.ts +19 -1
- package/src/usage/attribution.ts +3 -2
- package/src/util/pricing.ts +86 -160
- package/src/watcher/__tests__/engine.test.ts +301 -0
- package/src/watcher/constants.ts +7 -0
- package/src/watcher/engine.ts +90 -90
- package/src/workspace/migrations/046-seed-conversation-starters-callsite.ts +6 -9
- package/src/workspace/migrations/054-seed-recall-callsite.ts +10 -1
- package/src/workspace/migrations/057-repair-stale-gemini-model-ids.ts +28 -4
- package/src/workspace/migrations/067-release-notes-safe-storage-limits.ts +4 -62
- package/src/workspace/migrations/069-seed-onboarding-threads.ts +34 -0
- package/src/workspace/migrations/070-memory-v2-summary-schema-rebuild.ts +31 -0
- package/src/workspace/migrations/071-remove-safe-storage-release-note.ts +111 -0
- package/src/workspace/migrations/072-seed-reply-suggestion-callsite.ts +104 -0
- package/src/workspace/migrations/073-repair-recall-callsite-empty-profile.ts +93 -0
- package/src/workspace/migrations/074-drop-deprecated-secret-detection-keys.ts +117 -0
- package/src/workspace/migrations/075-memory-v2-bm25-b-default-reembed.ts +61 -0
- package/src/workspace/migrations/076-drop-services-inference-mode.ts +62 -0
- package/src/workspace/migrations/077-seed-memory-router-callsite.ts +89 -0
- package/src/workspace/migrations/078-release-notes-tavily-web-search.ts +66 -0
- package/src/workspace/migrations/079-home-feed-notification-only.ts +197 -0
- package/src/workspace/migrations/080-restrict-vercel-api-token-metadata.ts +182 -0
- package/src/workspace/migrations/081-backfill-bash-allowed-tools-for-injection-credentials.ts +160 -0
- package/src/workspace/migrations/082-backfill-managed-profile-labels.ts +154 -0
- package/src/workspace/migrations/registry.ts +28 -0
- package/src/workspace/migrations/runner.ts +13 -2
- package/src/workspace/migrations/types.ts +13 -3
- package/src/workspace/provider-commit-message-generator.ts +3 -2
- package/src/__tests__/context-search-pkb-source.test.ts +0 -492
- package/src/__tests__/credentials-cli.test.ts +0 -1225
- package/src/__tests__/memory-admin-recall.test.ts +0 -213
- package/src/approvals/__tests__/guardian-feed-event.test.ts +0 -303
- package/src/cli/commands/__tests__/email-download.test.ts +0 -260
- package/src/cli/commands/__tests__/email-list.test.ts +0 -216
- package/src/cli/commands/__tests__/email-register.test.ts +0 -186
- package/src/cli/commands/__tests__/email-send.test.ts +0 -416
- package/src/cli/commands/__tests__/email-status.test.ts +0 -185
- package/src/cli/commands/__tests__/email-unregister.test.ts +0 -168
- package/src/cli/commands/__tests__/routes.test.ts +0 -562
- package/src/cli/commands/__tests__/stt-transcribe.test.ts +0 -454
- package/src/cli/commands/autonomy.ts +0 -365
- package/src/cli/commands/memory.ts +0 -424
- package/src/cli/commands/oauth/__tests__/connect.test.ts +0 -1201
- package/src/cli/commands/oauth/__tests__/disconnect.test.ts +0 -686
- package/src/cli/commands/oauth/__tests__/mode.test.ts +0 -632
- package/src/cli/commands/oauth/__tests__/ping.test.ts +0 -631
- package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +0 -573
- package/src/cli/commands/oauth/__tests__/providers-register.test.ts +0 -330
- package/src/cli/commands/oauth/__tests__/providers-update.test.ts +0 -521
- package/src/cli/commands/oauth/__tests__/status.test.ts +0 -551
- package/src/cli/commands/oauth/__tests__/token.test.ts +0 -420
- package/src/cli/lib/daemon-avatar-client.ts +0 -37
- package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +0 -87
- package/src/config/bundled-skills/messaging/tools/__tests__/messaging-feed-events.test.ts +0 -207
- package/src/daemon/__tests__/conversation-feed-event.test.ts +0 -304
- package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +0 -233
- package/src/home/__tests__/assistant-feed-authoring.test.ts +0 -156
- package/src/home/__tests__/emit-feed-event.test.ts +0 -169
- package/src/home/__tests__/feed-population-integration.test.ts +0 -312
- package/src/home/__tests__/feed-scheduler.test.ts +0 -222
- package/src/home/__tests__/phase5-exit-criteria.test.ts +0 -229
- package/src/home/__tests__/platform-gmail-digest.test.ts +0 -222
- package/src/home/__tests__/rollup-producer.test.ts +0 -507
- package/src/home/assistant-feed-authoring.ts +0 -135
- package/src/home/emit-feed-event.ts +0 -169
- package/src/home/feed-scheduler.ts +0 -281
- package/src/home/platform-gmail-digest.ts +0 -163
- package/src/home/rewrite-command-preview.ts +0 -66
- package/src/home/rewrite-feed-title.ts +0 -58
- package/src/home/rollup-producer.ts +0 -426
- package/src/memory/admin.ts +0 -326
- package/src/memory/context-search/sources/pkb.ts +0 -477
- package/src/memory/graph/compaction.ts +0 -299
- /package/src/cli/{commands → lib}/cache-fs.ts +0 -0
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* can delegate without exposing its full surface.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
import { getConfig } from "../config/loader.js";
|
|
7
8
|
import { createContextSummaryMessage } from "../context/window-manager.js";
|
|
8
9
|
import type { EventBus } from "../events/bus.js";
|
|
9
10
|
import type { AssistantDomainEvents } from "../events/domain-events.js";
|
|
@@ -16,6 +17,7 @@ import {
|
|
|
16
17
|
type MessageRow,
|
|
17
18
|
} from "../memory/conversation-crud.js";
|
|
18
19
|
import { enqueueMemoryJob } from "../memory/jobs-store.js";
|
|
20
|
+
import { enqueueMemoryRetrospectiveIfEnabled } from "../memory/memory-retrospective-enqueue.js";
|
|
19
21
|
import type { PermissionPrompter } from "../permissions/prompter.js";
|
|
20
22
|
import type { SecretPrompter } from "../permissions/secret-prompter.js";
|
|
21
23
|
import type { ContentBlock, Message } from "../providers/types.js";
|
|
@@ -182,6 +184,7 @@ export async function loadFromDb(ctx: LoadFromDbContext): Promise<void> {
|
|
|
182
184
|
ctx.contextCompactedAt = conv?.contextCompactedAt ?? null;
|
|
183
185
|
}
|
|
184
186
|
|
|
187
|
+
const personalMemoryAllowed = !isUntrustedTrustClass(trustClass);
|
|
185
188
|
const parsedMessages: Message[] = dbMessages
|
|
186
189
|
.slice(ctx.contextCompactedMessageCount)
|
|
187
190
|
.map((m, index, arr) => {
|
|
@@ -214,7 +217,8 @@ export async function loadFromDb(ctx: LoadFromDbContext): Promise<void> {
|
|
|
214
217
|
// shape right-to-left, since each prepend shifts previously-
|
|
215
218
|
// prepended blocks one slot right:
|
|
216
219
|
// [<workspace>, <turn_context>, <NOW.md>, <memory __injected>,
|
|
217
|
-
// <system_reminder>, <knowledge_base>,
|
|
220
|
+
// <memory>\n…</memory>, <system_reminder>, <knowledge_base>,
|
|
221
|
+
// ...original]
|
|
218
222
|
//
|
|
219
223
|
// Persisted non-tail rows rehydrate the full set so Anthropic's
|
|
220
224
|
// prefix cache keeps matching msg[0] across daemon restarts and
|
|
@@ -237,15 +241,37 @@ export async function loadFromDb(ctx: LoadFromDbContext): Promise<void> {
|
|
|
237
241
|
];
|
|
238
242
|
}
|
|
239
243
|
|
|
244
|
+
// The v2 static memory block (essentials/threads/recent/buffer
|
|
245
|
+
// wrapped in `<memory>…</memory>`) carries personal user memory.
|
|
246
|
+
// Trust-gated to mirror `shouldExposePersonalMemory` at injection
|
|
247
|
+
// time — untrusted-actor views must not read persisted personal
|
|
248
|
+
// memory back through metadata. Skipped on the tail row because
|
|
249
|
+
// the next turn re-injects fresh content on full-mode turns.
|
|
250
|
+
if (
|
|
251
|
+
!isTail &&
|
|
252
|
+
personalMemoryAllowed &&
|
|
253
|
+
typeof meta.memoryV2StaticBlock === "string"
|
|
254
|
+
) {
|
|
255
|
+
content = [
|
|
256
|
+
{ type: "text" as const, text: meta.memoryV2StaticBlock },
|
|
257
|
+
...content,
|
|
258
|
+
];
|
|
259
|
+
}
|
|
260
|
+
|
|
240
261
|
// Memory remains rehydrated on all rows (existing behavior).
|
|
241
262
|
// Strip any pre-existing wrapper before re-wrapping so historical
|
|
242
263
|
// rows persisted with the wrapper (v2 path before the
|
|
243
264
|
// injectedBlockText contract was unified with v1's unwrapped form)
|
|
244
|
-
// don't render double-wrapped after rehydrate.
|
|
265
|
+
// don't render double-wrapped after rehydrate. Only unwrap when
|
|
266
|
+
// the full <memory>...</memory> pair is present so we don't mutate
|
|
267
|
+
// legitimate unwrapped payloads that happen to start with
|
|
268
|
+
// "<memory>\n" or end with "\n</memory>".
|
|
245
269
|
if (typeof meta.memoryInjectedBlock === "string") {
|
|
246
|
-
const
|
|
247
|
-
|
|
248
|
-
.
|
|
270
|
+
const block = meta.memoryInjectedBlock;
|
|
271
|
+
const inner =
|
|
272
|
+
block.startsWith("<memory>\n") && block.endsWith("\n</memory>")
|
|
273
|
+
? block.slice("<memory>\n".length, -"\n</memory>".length)
|
|
274
|
+
: block;
|
|
249
275
|
content = [
|
|
250
276
|
{
|
|
251
277
|
type: "text" as const,
|
|
@@ -373,16 +399,29 @@ export function disposeConversation(ctx: DisposeContext): void {
|
|
|
373
399
|
// Best-effort — don't block conversation disposal
|
|
374
400
|
}
|
|
375
401
|
if (!isAutoAnalysis) {
|
|
402
|
+
// Suppress v1 graph extraction when memory v2 is active — v2 reads
|
|
403
|
+
// from buffer.md and concept pages, so the v1 graph would be stale
|
|
404
|
+
// data nobody consumes. Mirrors the gate applied in `indexer.ts`
|
|
405
|
+
// for the per-message indexing path. Fail open to v1 if config
|
|
406
|
+
// can't load, since the worker handler also short-circuits.
|
|
407
|
+
let v2Enabled = false;
|
|
376
408
|
try {
|
|
377
|
-
|
|
378
|
-
conversationId: ctx.conversationId,
|
|
379
|
-
scopeId: "default",
|
|
380
|
-
...(ctx.activeContextNodeIds?.length
|
|
381
|
-
? { activeContextNodeIds: ctx.activeContextNodeIds }
|
|
382
|
-
: {}),
|
|
383
|
-
});
|
|
409
|
+
v2Enabled = getConfig().memory.v2.enabled;
|
|
384
410
|
} catch {
|
|
385
|
-
// Best-effort —
|
|
411
|
+
// Best-effort — fall through to legacy v1 enqueue
|
|
412
|
+
}
|
|
413
|
+
if (!v2Enabled) {
|
|
414
|
+
try {
|
|
415
|
+
enqueueMemoryJob("graph_extract", {
|
|
416
|
+
conversationId: ctx.conversationId,
|
|
417
|
+
scopeId: "default",
|
|
418
|
+
...(ctx.activeContextNodeIds?.length
|
|
419
|
+
? { activeContextNodeIds: ctx.activeContextNodeIds }
|
|
420
|
+
: {}),
|
|
421
|
+
});
|
|
422
|
+
} catch {
|
|
423
|
+
// Best-effort — don't block conversation disposal
|
|
424
|
+
}
|
|
386
425
|
}
|
|
387
426
|
}
|
|
388
427
|
|
|
@@ -397,6 +436,22 @@ export function disposeConversation(ctx: DisposeContext): void {
|
|
|
397
436
|
} catch {
|
|
398
437
|
// Best-effort — don't block conversation disposal
|
|
399
438
|
}
|
|
439
|
+
|
|
440
|
+
try {
|
|
441
|
+
// Memory-retrospective lifecycle safety-net. The periodic triggers
|
|
442
|
+
// (interval / message_count / pre-compaction) handle the common
|
|
443
|
+
// path; lifecycle catches the gap between the last interval fire
|
|
444
|
+
// and conversation eviction. The job's `no_new_messages` early
|
|
445
|
+
// return makes this a cheap no-op when the periodic path already
|
|
446
|
+
// covered things. `enqueueMemoryRetrospectiveIfEnabled` has its
|
|
447
|
+
// own internal recursion guard.
|
|
448
|
+
enqueueMemoryRetrospectiveIfEnabled({
|
|
449
|
+
conversationId: ctx.conversationId,
|
|
450
|
+
trigger: "lifecycle",
|
|
451
|
+
});
|
|
452
|
+
} catch {
|
|
453
|
+
// Best-effort — don't block conversation disposal
|
|
454
|
+
}
|
|
400
455
|
}
|
|
401
456
|
|
|
402
457
|
abortConversation(
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
createUserMessage,
|
|
13
13
|
} from "../agent/message-types.js";
|
|
14
14
|
import {
|
|
15
|
+
type InterfaceId,
|
|
15
16
|
parseChannelId,
|
|
16
17
|
parseInterfaceId,
|
|
17
18
|
type TurnChannelContext,
|
|
@@ -179,7 +180,9 @@ export interface ProcessConversationContext {
|
|
|
179
180
|
statusText?: string,
|
|
180
181
|
): void;
|
|
181
182
|
/** Force context compaction regardless of threshold/cooldown. */
|
|
182
|
-
forceCompact(
|
|
183
|
+
forceCompact(options?: {
|
|
184
|
+
targetInputTokensOverride?: number;
|
|
185
|
+
}): Promise<ContextWindowResult>;
|
|
183
186
|
/** Set transport-derived hints for the conversation. */
|
|
184
187
|
setTransportHints(hints: string[] | undefined): void;
|
|
185
188
|
/** IANA timezone reported by the active client for the current turn. */
|
|
@@ -195,6 +198,13 @@ export interface ProcessConversationContext {
|
|
|
195
198
|
applyClientTimezoneFromTransport(
|
|
196
199
|
transport: ConversationTransportMetadata,
|
|
197
200
|
): void;
|
|
201
|
+
/**
|
|
202
|
+
* Instantiate host proxies for capabilities that have become reachable
|
|
203
|
+
* mid-queue (e.g. a macOS client connected after a web turn was enqueued
|
|
204
|
+
* without a proxy). Called from drain paths before preactivation so skills
|
|
205
|
+
* are only activated when the proxy that services them is present.
|
|
206
|
+
*/
|
|
207
|
+
ensureHostProxiesForTurn(sourceInterface: InterfaceId | undefined): void;
|
|
198
208
|
}
|
|
199
209
|
|
|
200
210
|
function resolveQueuedTurnContext(
|
|
@@ -432,19 +442,19 @@ async function drainSingleMessage(
|
|
|
432
442
|
conversation.applyClientTimezoneFromTransport(next.transport);
|
|
433
443
|
}
|
|
434
444
|
|
|
435
|
-
// Re-preactivate host-proxy skills for interactive
|
|
436
|
-
// dequeue path reset `preactivatedSkillIds` above
|
|
437
|
-
// re-adds the relevant skill tools
|
|
438
|
-
//
|
|
439
|
-
//
|
|
440
|
-
//
|
|
445
|
+
// Re-attach and re-preactivate host-proxy skills for interactive turns.
|
|
446
|
+
// The dequeue path reset `preactivatedSkillIds` above; without these
|
|
447
|
+
// re-adds the relevant skill tools won't be projected to the LLM for
|
|
448
|
+
// queued messages 2+. Also instantiates proxies that may not have been
|
|
449
|
+
// present when the message was first enqueued (e.g. a macOS client
|
|
450
|
+
// connects between enqueue and drain). Mirrors the per-message block in
|
|
451
|
+
// `conversation-routes.ts` / `process-message.ts`.
|
|
441
452
|
if (next.isInteractive !== false) {
|
|
442
453
|
const interfaceCtx =
|
|
443
454
|
queuedInterfaceCtx ?? conversation.getTurnInterfaceContext();
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
);
|
|
455
|
+
const sourceInterface = interfaceCtx?.userMessageInterface;
|
|
456
|
+
conversation.ensureHostProxiesForTurn(sourceInterface);
|
|
457
|
+
preactivateHostProxySkills(conversation, sourceInterface);
|
|
448
458
|
}
|
|
449
459
|
|
|
450
460
|
// Snapshot persona context at turn start so later tool turns can't pick up
|
|
@@ -628,7 +638,9 @@ async function drainSingleMessage(
|
|
|
628
638
|
"assistant_turn",
|
|
629
639
|
next.requestId,
|
|
630
640
|
);
|
|
631
|
-
const result = await conversation.forceCompact(
|
|
641
|
+
const result = await conversation.forceCompact({
|
|
642
|
+
targetInputTokensOverride: slashResult.targetInputTokensOverride,
|
|
643
|
+
});
|
|
632
644
|
const responseText = formatCompactResult(result);
|
|
633
645
|
|
|
634
646
|
const assistantMsg = createAssistantMessage(responseText);
|
|
@@ -875,15 +887,14 @@ async function drainBatch(
|
|
|
875
887
|
conversation.applyClientTimezoneFromTransport(head.transport);
|
|
876
888
|
}
|
|
877
889
|
|
|
878
|
-
// Re-preactivate host-proxy skills for interactive
|
|
890
|
+
// Re-attach and re-preactivate host-proxy skills for interactive turns.
|
|
879
891
|
// Mirrors the single-message path exactly — sourced from `head`.
|
|
880
892
|
if (head.isInteractive !== false) {
|
|
881
893
|
const interfaceCtx =
|
|
882
894
|
queuedInterfaceCtx ?? conversation.getTurnInterfaceContext();
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
);
|
|
895
|
+
const sourceInterface = interfaceCtx?.userMessageInterface;
|
|
896
|
+
conversation.ensureHostProxiesForTurn(sourceInterface);
|
|
897
|
+
preactivateHostProxySkills(conversation, sourceInterface);
|
|
887
898
|
}
|
|
888
899
|
|
|
889
900
|
// Snapshot persona context at turn start so later tool turns can't pick up
|
|
@@ -1314,7 +1325,11 @@ export async function processMessage(
|
|
|
1314
1325
|
);
|
|
1315
1326
|
conversation.messages.push(assistantMsg);
|
|
1316
1327
|
|
|
1317
|
-
onEvent({
|
|
1328
|
+
onEvent({
|
|
1329
|
+
type: "assistant_text_delta",
|
|
1330
|
+
text: replyText,
|
|
1331
|
+
conversationId: conversation.conversationId,
|
|
1332
|
+
});
|
|
1318
1333
|
onEvent({
|
|
1319
1334
|
type: "message_complete",
|
|
1320
1335
|
conversationId: conversation.conversationId,
|
|
@@ -1474,7 +1489,9 @@ export async function processMessage(
|
|
|
1474
1489
|
"assistant_turn",
|
|
1475
1490
|
requestId,
|
|
1476
1491
|
);
|
|
1477
|
-
const result = await conversation.forceCompact(
|
|
1492
|
+
const result = await conversation.forceCompact({
|
|
1493
|
+
targetInputTokensOverride: slashResult.targetInputTokensOverride,
|
|
1494
|
+
});
|
|
1478
1495
|
const responseText = formatCompactResult(result);
|
|
1479
1496
|
|
|
1480
1497
|
const assistantMsg = createAssistantMessage(responseText);
|
|
@@ -1641,12 +1641,15 @@ const RUNTIME_INJECTION_PREFIXES = [
|
|
|
1641
1641
|
// blocks persist in history so the assistant retains temporal/actor grounding.
|
|
1642
1642
|
"<memory_context __injected>",
|
|
1643
1643
|
"<memory_context>", // backward-compat: strip legacy blocks from pre-__injected history
|
|
1644
|
-
//
|
|
1645
|
-
//
|
|
1646
|
-
//
|
|
1647
|
-
//
|
|
1648
|
-
//
|
|
1644
|
+
// The static `memory-v2-static` block (opens `<memory>\n…`) IS stripped
|
|
1645
|
+
// so each compaction re-injects the freshest essentials/threads/recent/
|
|
1646
|
+
// buffer view, matching the `<knowledge_base>` cadence. The dynamic
|
|
1647
|
+
// activation block (opens `<memory __injected>…`) is intentionally NOT
|
|
1648
|
+
// stripped — `startsWith("<memory>\n")` does not match it — so per-turn
|
|
1649
|
+
// memory activations persist in history. The activation pipeline dedupes
|
|
1650
|
+
// via `everInjected`, and compaction handles aggregate growth, so
|
|
1649
1651
|
// accumulation does not cause unbounded context growth.
|
|
1652
|
+
"<memory>\n",
|
|
1650
1653
|
"<voice_call_control>",
|
|
1651
1654
|
"<workspace_top_level>", // backward-compat: strip legacy workspace blocks
|
|
1652
1655
|
// NOTE: <workspace> is intentionally NOT stripped — workspace context
|
|
@@ -1736,6 +1739,7 @@ export interface RuntimeInjectionBlocks {
|
|
|
1736
1739
|
workspaceBlock?: string;
|
|
1737
1740
|
nowScratchpadBlock?: string;
|
|
1738
1741
|
pkbContextBlock?: string;
|
|
1742
|
+
memoryV2StaticBlock?: string;
|
|
1739
1743
|
/**
|
|
1740
1744
|
* Composed output of every plugin-registered {@link Injector}, concatenated
|
|
1741
1745
|
* in ascending `order`. Empty string when every injector opted out (returned
|
|
@@ -2153,6 +2157,7 @@ export async function applyRuntimeInjections(
|
|
|
2153
2157
|
let nowScratchpadCaptured: string | undefined;
|
|
2154
2158
|
let pkbContextCaptured: string | undefined;
|
|
2155
2159
|
let pkbSystemReminderCaptured: string | undefined;
|
|
2160
|
+
let memoryV2StaticCaptured: string | undefined;
|
|
2156
2161
|
const initialTail = runMessages[runMessages.length - 1];
|
|
2157
2162
|
const initialTailIsUser = !!initialTail && initialTail.role === "user";
|
|
2158
2163
|
if (initialTailIsUser) {
|
|
@@ -2173,6 +2178,9 @@ export async function applyRuntimeInjections(
|
|
|
2173
2178
|
case "pkb-reminder":
|
|
2174
2179
|
pkbSystemReminderCaptured = block.text;
|
|
2175
2180
|
break;
|
|
2181
|
+
case "memory-v2-static":
|
|
2182
|
+
memoryV2StaticCaptured = block.text;
|
|
2183
|
+
break;
|
|
2176
2184
|
}
|
|
2177
2185
|
}
|
|
2178
2186
|
}
|
|
@@ -2354,6 +2362,7 @@ export async function applyRuntimeInjections(
|
|
|
2354
2362
|
workspaceBlock: workspaceCaptured,
|
|
2355
2363
|
nowScratchpadBlock: nowScratchpadCaptured,
|
|
2356
2364
|
pkbContextBlock: pkbContextCaptured,
|
|
2365
|
+
memoryV2StaticBlock: memoryV2StaticCaptured,
|
|
2357
2366
|
injectorChainBlock,
|
|
2358
2367
|
},
|
|
2359
2368
|
};
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import type { InterfaceId } from "../channels/types.js";
|
|
2
2
|
import { resolveEffectiveContextWindow } from "../config/llm-context-resolution.js";
|
|
3
|
-
import {
|
|
3
|
+
import { resolveCallSiteConfig } from "../config/llm-resolver.js";
|
|
4
|
+
import {
|
|
5
|
+
getConfig,
|
|
6
|
+
invalidateConfigCache,
|
|
7
|
+
loadRawConfig,
|
|
8
|
+
saveRawConfig,
|
|
9
|
+
} from "../config/loader.js";
|
|
4
10
|
import { getConversationOverrideProfile } from "../memory/conversation-crud.js";
|
|
5
11
|
import { PROVIDER_CATALOG } from "../providers/model-catalog.js";
|
|
6
12
|
import { getConfiguredProviders } from "../providers/provider-availability.js";
|
|
@@ -8,7 +14,43 @@ import { getConfiguredProviders } from "../providers/provider-availability.js";
|
|
|
8
14
|
export type SlashResolution =
|
|
9
15
|
| { kind: "passthrough"; content: string }
|
|
10
16
|
| { kind: "unknown"; message: string }
|
|
11
|
-
| { kind: "compact" };
|
|
17
|
+
| { kind: "compact"; targetInputTokensOverride?: number };
|
|
18
|
+
|
|
19
|
+
const COMPACT_USAGE_HINT =
|
|
20
|
+
"Usage: `/compact [<tokens>]` (e.g. `/compact 30000`, `/compact 30k`, `/compact 1m`).";
|
|
21
|
+
|
|
22
|
+
type CompactParse =
|
|
23
|
+
| { kind: "compact"; targetInputTokensOverride?: number }
|
|
24
|
+
| { kind: "unknown"; message: string };
|
|
25
|
+
|
|
26
|
+
const TOKEN_COUNT_PATTERN = /^(\d+(?:\.\d+)?)([km])?$/i;
|
|
27
|
+
const COMPACT_COMMAND_PATTERN = /^\/compact(?:\s+(.+?))?\s*$/i;
|
|
28
|
+
|
|
29
|
+
function parseTokenCount(input: string): number | null {
|
|
30
|
+
const match = input.match(TOKEN_COUNT_PATTERN);
|
|
31
|
+
if (!match) return null;
|
|
32
|
+
const value = Number.parseFloat(match[1]);
|
|
33
|
+
if (!Number.isFinite(value) || value <= 0) return null;
|
|
34
|
+
const suffix = match[2]?.toLowerCase();
|
|
35
|
+
const multiplier = suffix === "m" ? 1_000_000 : suffix === "k" ? 1_000 : 1;
|
|
36
|
+
const tokens = Math.floor(value * multiplier);
|
|
37
|
+
return tokens > 0 ? tokens : null;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function parseCompactCommand(trimmed: string): CompactParse | null {
|
|
41
|
+
const match = trimmed.match(COMPACT_COMMAND_PATTERN);
|
|
42
|
+
if (!match) return null;
|
|
43
|
+
const rest = match[1]?.trim();
|
|
44
|
+
if (!rest) return { kind: "compact" };
|
|
45
|
+
const tokens = parseTokenCount(rest);
|
|
46
|
+
if (tokens == null) {
|
|
47
|
+
return {
|
|
48
|
+
kind: "unknown",
|
|
49
|
+
message: `Unrecognized argument to \`/compact\`: \`${rest}\`. ${COMPACT_USAGE_HINT}`,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
return { kind: "compact", targetInputTokensOverride: tokens };
|
|
53
|
+
}
|
|
12
54
|
|
|
13
55
|
// ── /context and /status commands ────────────────────────────────────
|
|
14
56
|
|
|
@@ -71,10 +113,125 @@ const DEPRECATED_MODEL_SHORTCUTS = new Set([
|
|
|
71
113
|
"grok-multi",
|
|
72
114
|
]);
|
|
73
115
|
|
|
116
|
+
// ── /model command (inference profile switcher) ──────────────────────
|
|
117
|
+
|
|
118
|
+
type ModelCommandParse =
|
|
119
|
+
| { kind: "list" }
|
|
120
|
+
| { kind: "switch"; profileName: string };
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Parse `/model` and `/model <name>` forms. Returns `null` for any input
|
|
124
|
+
* that isn't a `/model` invocation (so the caller can fall through).
|
|
125
|
+
*/
|
|
126
|
+
function parseModelCommand(trimmed: string): ModelCommandParse | null {
|
|
127
|
+
if (trimmed === "/model") return { kind: "list" };
|
|
128
|
+
if (!trimmed.startsWith("/model ")) return null;
|
|
129
|
+
const rest = trimmed.slice("/model ".length).trim();
|
|
130
|
+
if (rest.length === 0) return { kind: "list" };
|
|
131
|
+
return { kind: "switch", profileName: rest };
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function orderedProfileNames(
|
|
135
|
+
profiles: Record<string, { label?: string; description?: string; status?: "active" | "disabled" }>,
|
|
136
|
+
profileOrder: readonly string[] | undefined,
|
|
137
|
+
): string[] {
|
|
138
|
+
const order = profileOrder ?? [];
|
|
139
|
+
const seen = new Set<string>();
|
|
140
|
+
const ordered: string[] = [];
|
|
141
|
+
for (const name of order) {
|
|
142
|
+
if (profiles[name] != null && !seen.has(name)) {
|
|
143
|
+
ordered.push(name);
|
|
144
|
+
seen.add(name);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
const tail = Object.keys(profiles)
|
|
148
|
+
.filter((n) => !seen.has(n))
|
|
149
|
+
.sort();
|
|
150
|
+
return [...ordered, ...tail];
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
async function resolveModelCommand(
|
|
154
|
+
parse: ModelCommandParse,
|
|
155
|
+
): Promise<SlashResolution> {
|
|
156
|
+
const config = getConfig();
|
|
157
|
+
const profiles = (config.llm.profiles ?? {}) as Record<
|
|
158
|
+
string,
|
|
159
|
+
{ label?: string; description?: string; status?: "active" | "disabled" }
|
|
160
|
+
>;
|
|
161
|
+
const profileNames = orderedProfileNames(profiles, config.llm.profileOrder);
|
|
162
|
+
const activeProfile = config.llm.activeProfile;
|
|
163
|
+
|
|
164
|
+
if (parse.kind === "list") {
|
|
165
|
+
if (profileNames.length === 0) {
|
|
166
|
+
return {
|
|
167
|
+
kind: "unknown",
|
|
168
|
+
message:
|
|
169
|
+
"No inference profiles are defined. Use **Settings → Models & Services** to create one.",
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
const lines = ["Inference profiles:\n"];
|
|
173
|
+
for (const name of profileNames) {
|
|
174
|
+
const profile = profiles[name];
|
|
175
|
+
const label = profile.label ?? name;
|
|
176
|
+
const isCurrent = name === activeProfile;
|
|
177
|
+
const isDisabled = profile.status === "disabled";
|
|
178
|
+
const marker = isCurrent ? " **[current]**" : "";
|
|
179
|
+
const disabled = isDisabled ? " *(disabled)*" : "";
|
|
180
|
+
const description = profile.description ? ` — ${profile.description}` : "";
|
|
181
|
+
lines.push(` - \`${name}\` (${label})${marker}${disabled}${description}`);
|
|
182
|
+
}
|
|
183
|
+
lines.push("\nSwitch with `/model <name>`.");
|
|
184
|
+
return { kind: "unknown", message: lines.join("\n") };
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const target = parse.profileName;
|
|
188
|
+
if (!(target in profiles)) {
|
|
189
|
+
const available = profileNames.map((n) => `\`${n}\``).join(", ");
|
|
190
|
+
const hint = available.length > 0 ? ` Available: ${available}.` : "";
|
|
191
|
+
return {
|
|
192
|
+
kind: "unknown",
|
|
193
|
+
message: `Profile \`${target}\` not found.${hint}`,
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
if (profiles[target].status === "disabled") {
|
|
197
|
+
return {
|
|
198
|
+
kind: "unknown",
|
|
199
|
+
message: `Profile \`${target}\` is disabled. Enable it in **Settings → Models & Services** first.`,
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
if (target === activeProfile) {
|
|
203
|
+
const label = profiles[target].label ?? target;
|
|
204
|
+
return {
|
|
205
|
+
kind: "unknown",
|
|
206
|
+
message: `Already using profile \`${target}\` (${label}).`,
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Write `llm.activeProfile` directly to the raw config file. We invalidate
|
|
211
|
+
// the in-process cache so the very next `getConfig()` reflects the switch;
|
|
212
|
+
// the file watcher will also pick this up but its debounce can lag a tick.
|
|
213
|
+
const raw = loadRawConfig();
|
|
214
|
+
const llm: Record<string, unknown> =
|
|
215
|
+
raw.llm != null && typeof raw.llm === "object" && !Array.isArray(raw.llm)
|
|
216
|
+
? (raw.llm as Record<string, unknown>)
|
|
217
|
+
: {};
|
|
218
|
+
llm.activeProfile = target;
|
|
219
|
+
raw.llm = llm;
|
|
220
|
+
saveRawConfig(raw);
|
|
221
|
+
invalidateConfigCache();
|
|
222
|
+
|
|
223
|
+
const label = profiles[target].label ?? target;
|
|
224
|
+
return {
|
|
225
|
+
kind: "unknown",
|
|
226
|
+
message: `Switched to profile \`${target}\` (${label}).`,
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
|
|
74
230
|
// ── /models command ──────────────────────────────────────────────────
|
|
75
231
|
|
|
76
232
|
async function resolveModelList(): Promise<SlashResolution> {
|
|
77
233
|
const config = getConfig();
|
|
234
|
+
const resolvedMainAgent = resolveCallSiteConfig("mainAgent", config.llm);
|
|
78
235
|
const configuredProviders = new Set<string>(await getConfiguredProviders());
|
|
79
236
|
|
|
80
237
|
const lines = ["Available models:\n"];
|
|
@@ -89,8 +246,8 @@ async function resolveModelList(): Promise<SlashResolution> {
|
|
|
89
246
|
lines.push(`**${providerName}** ${status}`);
|
|
90
247
|
for (const { id, displayName } of models) {
|
|
91
248
|
const isCurrent =
|
|
92
|
-
|
|
93
|
-
|
|
249
|
+
resolvedMainAgent.provider === provider &&
|
|
250
|
+
resolvedMainAgent.model === id;
|
|
94
251
|
const current = isCurrent ? " **[current]**" : "";
|
|
95
252
|
lines.push(` - ${displayName} (\`${id}\`)${current}`);
|
|
96
253
|
}
|
|
@@ -146,6 +303,7 @@ function resolveCommandsList(context?: SlashContext): string[] {
|
|
|
146
303
|
if (context) {
|
|
147
304
|
fallbackLines.push("/context — Show conversation context usage");
|
|
148
305
|
}
|
|
306
|
+
fallbackLines.push("/model — List or switch inference profile");
|
|
149
307
|
fallbackLines.push("/models — List all available models");
|
|
150
308
|
if (context) {
|
|
151
309
|
fallbackLines.push("/status — Show conversation status and context usage");
|
|
@@ -158,6 +316,7 @@ function resolveCommandsList(context?: SlashContext): string[] {
|
|
|
158
316
|
"/commands — List all available commands",
|
|
159
317
|
"/compact — Force context compaction immediately",
|
|
160
318
|
"/context — Show conversation context usage",
|
|
319
|
+
"/model — List or switch inference profile",
|
|
161
320
|
"/models — List all available models",
|
|
162
321
|
"/status — Show conversation status and context usage",
|
|
163
322
|
"/btw — Ask a side question while the assistant is working",
|
|
@@ -170,6 +329,7 @@ function resolveCommandsList(context?: SlashContext): string[] {
|
|
|
170
329
|
"/commands — List all available commands",
|
|
171
330
|
"/compact — Force context compaction immediately",
|
|
172
331
|
"/context — Show conversation context usage",
|
|
332
|
+
"/model — List or switch inference profile",
|
|
173
333
|
"/models — List all available models",
|
|
174
334
|
"/status — Show conversation status and context usage",
|
|
175
335
|
"/btw — Ask a side question while the assistant is working",
|
|
@@ -181,6 +341,7 @@ function resolveCommandsList(context?: SlashContext): string[] {
|
|
|
181
341
|
"/commands — List all available commands",
|
|
182
342
|
"/compact — Force context compaction immediately",
|
|
183
343
|
"/context — Show conversation context usage",
|
|
344
|
+
"/model — List or switch inference profile",
|
|
184
345
|
"/models — List all available models",
|
|
185
346
|
"/status — Show conversation status and context usage",
|
|
186
347
|
"/btw — Ask a side question while the assistant is working",
|
|
@@ -200,10 +361,7 @@ export function classifySlash(
|
|
|
200
361
|
content: string,
|
|
201
362
|
): "passthrough" | "compact" | "unknown" {
|
|
202
363
|
const trimmed = content.trim();
|
|
203
|
-
if (
|
|
204
|
-
trimmed === "/model" ||
|
|
205
|
-
(trimmed.startsWith("/model ") && trimmed !== "/models")
|
|
206
|
-
) {
|
|
364
|
+
if (parseModelCommand(trimmed) != null) {
|
|
207
365
|
return "unknown";
|
|
208
366
|
}
|
|
209
367
|
const shortcutMatch = trimmed.match(/^\/([a-z0-9-]+)(\s|$)/i);
|
|
@@ -214,7 +372,8 @@ export function classifySlash(
|
|
|
214
372
|
return "unknown";
|
|
215
373
|
}
|
|
216
374
|
if (trimmed === "/models") return "unknown";
|
|
217
|
-
|
|
375
|
+
const compactParse = parseCompactCommand(trimmed);
|
|
376
|
+
if (compactParse) return compactParse.kind;
|
|
218
377
|
if (trimmed === "/context") return "unknown";
|
|
219
378
|
if (trimmed === "/status") return "unknown";
|
|
220
379
|
if (trimmed === "/commands") return "unknown";
|
|
@@ -230,17 +389,11 @@ export async function resolveSlash(
|
|
|
230
389
|
content: string,
|
|
231
390
|
context?: SlashContext,
|
|
232
391
|
): Promise<SlashResolution> {
|
|
233
|
-
// Handle
|
|
392
|
+
// Handle `/model` — list profiles (no arg) or switch active profile.
|
|
234
393
|
const trimmed = content.trim();
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
) {
|
|
239
|
-
return {
|
|
240
|
-
kind: "unknown",
|
|
241
|
-
message:
|
|
242
|
-
"The `/model` command has been removed. Use **Settings → Models & Services** to change your model and provider.",
|
|
243
|
-
};
|
|
394
|
+
const modelParse = parseModelCommand(trimmed);
|
|
395
|
+
if (modelParse != null) {
|
|
396
|
+
return await resolveModelCommand(modelParse);
|
|
244
397
|
}
|
|
245
398
|
|
|
246
399
|
// Reject deprecated provider shortcut commands (/opus, /sonnet, /haiku, etc.)
|
|
@@ -260,10 +413,9 @@ export async function resolveSlash(
|
|
|
260
413
|
return await resolveModelList();
|
|
261
414
|
}
|
|
262
415
|
|
|
263
|
-
// Handle /compact command
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
}
|
|
416
|
+
// Handle /compact command (with optional `<tokens>` override).
|
|
417
|
+
const compactParse = parseCompactCommand(trimmed);
|
|
418
|
+
if (compactParse) return compactParse;
|
|
267
419
|
|
|
268
420
|
// Handle /context and legacy /status commands
|
|
269
421
|
if (trimmed === "/context" || trimmed === "/status") {
|
|
@@ -14,12 +14,13 @@
|
|
|
14
14
|
* shared rate-limit timestamps, broadcast).
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
+
import { resolveCallSiteConfig } from "../config/llm-resolver.js";
|
|
17
18
|
import { getConfig } from "../config/loader.js";
|
|
18
19
|
import type { CesClient } from "../credential-execution/client.js";
|
|
19
20
|
import { buildSystemPrompt } from "../prompts/system-prompt.js";
|
|
20
|
-
import {
|
|
21
|
+
import { wrapWithCallSiteRouting } from "../providers/call-site-routing.js";
|
|
22
|
+
import { resolveDefaultProvider } from "../providers/connection-resolution.js";
|
|
21
23
|
import { RateLimitProvider } from "../providers/ratelimit.js";
|
|
22
|
-
import { getProvider } from "../providers/registry.js";
|
|
23
24
|
import { getSubagentManager } from "../subagent/index.js";
|
|
24
25
|
import { getSandboxWorkingDir } from "../util/platform.js";
|
|
25
26
|
import { Conversation } from "./conversation.js";
|
|
@@ -222,14 +223,20 @@ export async function getOrCreateConversation(
|
|
|
222
223
|
|
|
223
224
|
const createPromise = (async () => {
|
|
224
225
|
const config = getConfig();
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
226
|
+
// Connection-aware default-provider resolution. Throws
|
|
227
|
+
// `ConnectionResolutionError` when the default profile's
|
|
228
|
+
// `provider_connection` is unset / unknown / mismatched (config
|
|
229
|
+
// bugs). Returns null on soft credential failures (handled below
|
|
230
|
+
// as "default provider not registered").
|
|
231
|
+
const baseProvider = await resolveDefaultProvider(config);
|
|
232
|
+
if (!baseProvider) {
|
|
233
|
+
throw new Error(
|
|
234
|
+
`Conversation: default provider '${resolveCallSiteConfig("mainAgent", config.llm).provider}' is not registered`,
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
// Per-call `callSite` routing layered on top, with connection-awareness
|
|
238
|
+
// for alternate profiles (matches the canonical dispatch path).
|
|
239
|
+
let provider = wrapWithCallSiteRouting(baseProvider, config);
|
|
233
240
|
const { rateLimit } = config;
|
|
234
241
|
if (rateLimit.maxRequestsPerMinute > 0) {
|
|
235
242
|
provider = new RateLimitProvider(
|