@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,7 +4,6 @@
|
|
|
4
4
|
* context inspection, and queued message deletion.
|
|
5
5
|
*
|
|
6
6
|
* GET /v1/model — current model info
|
|
7
|
-
* PUT /v1/model — set model
|
|
8
7
|
* PUT /v1/model/image-gen — set image-gen model
|
|
9
8
|
* GET /v1/config/embeddings — current embedding config
|
|
10
9
|
* PUT /v1/config/embeddings — set embedding provider/model
|
|
@@ -22,14 +21,18 @@ import { z } from "zod";
|
|
|
22
21
|
|
|
23
22
|
import {
|
|
24
23
|
deepMergeOverwrite,
|
|
24
|
+
fillContextDefaultsForMissingKeys,
|
|
25
25
|
getConfig,
|
|
26
|
+
getDeploymentContextDefaults,
|
|
26
27
|
invalidateConfigCache,
|
|
27
28
|
loadRawConfig,
|
|
28
29
|
saveRawConfig,
|
|
30
|
+
setNestedValue,
|
|
29
31
|
} from "../../config/loader.js";
|
|
32
|
+
import { AssistantConfigSchema } from "../../config/schema.js";
|
|
33
|
+
import { getSchemaAtPath } from "../../config/schema-utils.js";
|
|
30
34
|
import { ProfileEntry } from "../../config/schemas/llm.js";
|
|
31
35
|
import { VALID_MEMORY_EMBEDDING_PROVIDERS } from "../../config/schemas/memory-storage.js";
|
|
32
|
-
import { VALID_INFERENCE_PROVIDERS } from "../../config/schemas/services.js";
|
|
33
36
|
import { getConfigWatcher } from "../../daemon/config-watcher.js";
|
|
34
37
|
import {
|
|
35
38
|
getEmbeddingConfigInfo,
|
|
@@ -39,7 +42,6 @@ import {
|
|
|
39
42
|
getModelInfo,
|
|
40
43
|
type ModelSetContext,
|
|
41
44
|
setImageGenModel,
|
|
42
|
-
setModel,
|
|
43
45
|
} from "../../daemon/handlers/config-model.js";
|
|
44
46
|
import {
|
|
45
47
|
getMessageContent,
|
|
@@ -56,14 +58,12 @@ import {
|
|
|
56
58
|
getMessageById,
|
|
57
59
|
} from "../../memory/conversation-crud.js";
|
|
58
60
|
import { clearEmbeddingBackendCache } from "../../memory/embedding-backend.js";
|
|
59
|
-
import {
|
|
60
|
-
getRequestLogById,
|
|
61
|
-
getRequestLogsByMessageId,
|
|
62
|
-
} from "../../memory/llm-request-log-store.js";
|
|
61
|
+
import { getLlmRequestLogSource } from "../../memory/llm-request-log-source.js";
|
|
63
62
|
import { getMemoryRecallLogByMessageIds } from "../../memory/memory-recall-log-store.js";
|
|
64
63
|
import { getMemoryV2ActivationLogByMessageIds } from "../../memory/memory-v2-activation-log-store.js";
|
|
65
64
|
import { MEMORY_V2_CONSOLIDATION_SOURCE } from "../../memory/v2/constants.js";
|
|
66
65
|
import { initializeProviders } from "../../providers/registry.js";
|
|
66
|
+
import { validateAllowlistFile } from "../../security/secret-allowlist.js";
|
|
67
67
|
import { resolvePricingForUsage } from "../../util/pricing.js";
|
|
68
68
|
import { BadRequestError, InternalError, NotFoundError } from "./errors.js";
|
|
69
69
|
import {
|
|
@@ -72,7 +72,6 @@ import {
|
|
|
72
72
|
} from "./llm-context-normalization.js";
|
|
73
73
|
import type { RouteDefinition, RouteHandlerArgs } from "./types.js";
|
|
74
74
|
|
|
75
|
-
const validProviderSet = new Set<string>(VALID_INFERENCE_PROVIDERS);
|
|
76
75
|
const validEmbeddingProviderSet = new Set<string>(
|
|
77
76
|
VALID_MEMORY_EMBEDDING_PROVIDERS,
|
|
78
77
|
);
|
|
@@ -93,8 +92,15 @@ type LlmContextRouteResult = Omit<LlmContextNormalizationResult, "summary"> & {
|
|
|
93
92
|
|
|
94
93
|
import { MANAGED_PROFILE_NAMES } from "../../config/seed-inference-profiles.js";
|
|
95
94
|
|
|
95
|
+
const RESERVED_PROFILE_NAMES = new Set([
|
|
96
|
+
"__proto__",
|
|
97
|
+
"constructor",
|
|
98
|
+
"prototype",
|
|
99
|
+
]);
|
|
100
|
+
|
|
96
101
|
const INFERENCE_PROFILE_UI_KEYS = new Set([
|
|
97
102
|
"provider",
|
|
103
|
+
"provider_connection",
|
|
98
104
|
"model",
|
|
99
105
|
"maxTokens",
|
|
100
106
|
"effort",
|
|
@@ -237,33 +243,6 @@ async function handleGetModel() {
|
|
|
237
243
|
return getModelInfo();
|
|
238
244
|
}
|
|
239
245
|
|
|
240
|
-
async function handleSetModel({ body }: RouteHandlerArgs) {
|
|
241
|
-
if (!body || typeof body !== "object") {
|
|
242
|
-
throw new BadRequestError("Request body is required");
|
|
243
|
-
}
|
|
244
|
-
const { modelId, provider } = body as {
|
|
245
|
-
modelId?: string;
|
|
246
|
-
provider?: string;
|
|
247
|
-
};
|
|
248
|
-
if (!modelId || typeof modelId !== "string") {
|
|
249
|
-
throw new BadRequestError("Missing required field: modelId");
|
|
250
|
-
}
|
|
251
|
-
if (
|
|
252
|
-
provider !== undefined &&
|
|
253
|
-
(typeof provider !== "string" || !validProviderSet.has(provider))
|
|
254
|
-
) {
|
|
255
|
-
throw new BadRequestError(
|
|
256
|
-
`Invalid provider "${provider}". Valid providers: ${[...validProviderSet].join(", ")}`,
|
|
257
|
-
);
|
|
258
|
-
}
|
|
259
|
-
try {
|
|
260
|
-
return await setModel(modelId, getModelSetContext(), provider);
|
|
261
|
-
} catch (err) {
|
|
262
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
263
|
-
throw new InternalError(`Failed to set model: ${message}`);
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
|
|
267
246
|
async function handleSetImageGenModel({ body }: RouteHandlerArgs) {
|
|
268
247
|
if (!body || typeof body !== "object") {
|
|
269
248
|
throw new BadRequestError("Request body is required");
|
|
@@ -312,15 +291,131 @@ async function handleSetEmbeddingConfig({ body }: RouteHandlerArgs) {
|
|
|
312
291
|
}
|
|
313
292
|
}
|
|
314
293
|
|
|
294
|
+
/**
|
|
295
|
+
* Apply deployment-context defaults to a raw config payload before it goes
|
|
296
|
+
* out over the wire from `GET /v1/config`. The in-memory `loadConfig()`
|
|
297
|
+
* already layers these defaults for daemon-internal consumers; the GET
|
|
298
|
+
* response needs the same treatment so external clients (macOS, web, CLI)
|
|
299
|
+
* see the effective value rather than `undefined` when the daemon hasn't
|
|
300
|
+
* persisted an explicit choice yet. For example, on a freshly-hatched
|
|
301
|
+
* platform-managed assistant, `services.image-generation.mode` may be absent
|
|
302
|
+
* from disk (only `llm.profiles` was written by `seedInferenceProfiles`); the
|
|
303
|
+
* fill pass ensures clients receive `"managed"` rather than falling back to
|
|
304
|
+
* their own defaults.
|
|
305
|
+
*
|
|
306
|
+
* Guards against `loadRawConfig()` handing us a value that is technically
|
|
307
|
+
* valid JSON but not a plain object (e.g. literal `null`, a number, or an
|
|
308
|
+
* array). `loadRawConfig` is typed `Record<string, unknown>` but `JSON.parse`
|
|
309
|
+
* itself doesn't enforce that — a malformed-but-parseable `config.json`
|
|
310
|
+
* would blow up `fillContextDefaultsForMissingKeys` on its `target[key]` /
|
|
311
|
+
* `fileConfig[key]` accesses, turning `GET /v1/config` into a 500 where it
|
|
312
|
+
* used to succeed (returning the malformed payload as-is). When `raw` is
|
|
313
|
+
* not a plain object, we return it unchanged.
|
|
314
|
+
*
|
|
315
|
+
* Exported for direct unit testing.
|
|
316
|
+
*/
|
|
317
|
+
export function applyContextDefaultsToRawConfig(raw: unknown): unknown {
|
|
318
|
+
const contextDefaults = getDeploymentContextDefaults();
|
|
319
|
+
if (
|
|
320
|
+
Object.keys(contextDefaults).length === 0 ||
|
|
321
|
+
raw === null ||
|
|
322
|
+
typeof raw !== "object" ||
|
|
323
|
+
Array.isArray(raw)
|
|
324
|
+
) {
|
|
325
|
+
return raw;
|
|
326
|
+
}
|
|
327
|
+
fillContextDefaultsForMissingKeys(
|
|
328
|
+
raw as Record<string, unknown>,
|
|
329
|
+
raw as Record<string, unknown>,
|
|
330
|
+
contextDefaults,
|
|
331
|
+
);
|
|
332
|
+
synthesizeLegacyInferenceModeForPlatform(raw as Record<string, unknown>);
|
|
333
|
+
return raw;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Backwards-compat wire field for `GET /v1/config`. PR removed
|
|
338
|
+
* `services.inference.mode` from the typed schema (routing is now governed
|
|
339
|
+
* by `provider_connections` rows + `llm.default.provider_connection`), but
|
|
340
|
+
* the macOS settings client (`SettingsStore.swift:loadServiceModes`) still
|
|
341
|
+
* reads this field and falls back to its `@Published` default of "your-own"
|
|
342
|
+
* when absent. On a platform-managed assistant served by a newer daemon and
|
|
343
|
+
* an older macOS client, that fallback would show the wrong mode in the UI
|
|
344
|
+
* until the user explicitly saved. Synthesize the value here so the wire
|
|
345
|
+
* shape stays compatible during the rollout window. Remove once the macOS
|
|
346
|
+
* Providers UI (the follow-up PR that retires this field on the client) has
|
|
347
|
+
* shipped to the majority of installs.
|
|
348
|
+
*
|
|
349
|
+
* The synthesis is wire-only: it never persists to disk and never reaches
|
|
350
|
+
* the typed `AssistantConfig` consumed by daemon-internal code. The on-disk
|
|
351
|
+
* config is stripped of `mode` by workspace migration 076.
|
|
352
|
+
*
|
|
353
|
+
* Only runs when this function is reached, which is guarded by
|
|
354
|
+
* `getDeploymentContextDefaults()` returning non-empty (IS_PLATFORM=true).
|
|
355
|
+
*/
|
|
356
|
+
function synthesizeLegacyInferenceModeForPlatform(
|
|
357
|
+
root: Record<string, unknown>,
|
|
358
|
+
): void {
|
|
359
|
+
const services = readPlainObject(root.services);
|
|
360
|
+
if (!services) return;
|
|
361
|
+
let inference = readPlainObject(services.inference);
|
|
362
|
+
if (!inference) {
|
|
363
|
+
inference = {};
|
|
364
|
+
services.inference = inference;
|
|
365
|
+
}
|
|
366
|
+
if (inference.mode === undefined) {
|
|
367
|
+
inference.mode = "managed";
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
function readPlainObject(value: unknown): Record<string, unknown> | undefined {
|
|
372
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
373
|
+
return undefined;
|
|
374
|
+
}
|
|
375
|
+
return value as Record<string, unknown>;
|
|
376
|
+
}
|
|
377
|
+
|
|
315
378
|
function handleGetConfig() {
|
|
316
379
|
try {
|
|
317
|
-
return loadRawConfig();
|
|
380
|
+
return applyContextDefaultsToRawConfig(loadRawConfig());
|
|
318
381
|
} catch (err) {
|
|
319
382
|
const message = err instanceof Error ? err.message : String(err);
|
|
320
383
|
throw new InternalError(`Failed to read config: ${message}`);
|
|
321
384
|
}
|
|
322
385
|
}
|
|
323
386
|
|
|
387
|
+
/**
|
|
388
|
+
* Return the JSON Schema for the assistant config (full or scoped).
|
|
389
|
+
*
|
|
390
|
+
* The schema is derived from `AssistantConfigSchema` at runtime via
|
|
391
|
+
* `z.toJSONSchema()`. Pure read; no daemon state involved.
|
|
392
|
+
*/
|
|
393
|
+
function handleGetConfigSchema({ queryParams = {} }: RouteHandlerArgs) {
|
|
394
|
+
const rawPath = queryParams.path;
|
|
395
|
+
const path = typeof rawPath === "string" ? rawPath.trim() : "";
|
|
396
|
+
|
|
397
|
+
if (!path) {
|
|
398
|
+
return {
|
|
399
|
+
schema: z.toJSONSchema(AssistantConfigSchema, {
|
|
400
|
+
unrepresentable: "any",
|
|
401
|
+
io: "input",
|
|
402
|
+
}),
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
const subSchema = getSchemaAtPath(AssistantConfigSchema, path);
|
|
407
|
+
if (!subSchema) {
|
|
408
|
+
throw new BadRequestError(`No schema found at path: ${path}`);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
return {
|
|
412
|
+
schema: z.toJSONSchema(subSchema, {
|
|
413
|
+
unrepresentable: "any",
|
|
414
|
+
io: "input",
|
|
415
|
+
}),
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
|
|
324
419
|
function rejectManagedProfileDeletion(body: Record<string, unknown>): void {
|
|
325
420
|
const llm = asMutablePlainObject(body.llm);
|
|
326
421
|
if (!llm) return;
|
|
@@ -338,28 +433,24 @@ function rejectManagedProfileDeletion(body: Record<string, unknown>): void {
|
|
|
338
433
|
}
|
|
339
434
|
}
|
|
340
435
|
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
const raw = loadRawConfig();
|
|
353
|
-
const patch = body as Record<string, unknown>;
|
|
354
|
-
deepMergeOverwrite(raw, patch);
|
|
355
|
-
|
|
436
|
+
/**
|
|
437
|
+
* Persist a mutated raw config object to disk and synchronize the running
|
|
438
|
+
* daemon (file-watcher, embedding cache, provider registry).
|
|
439
|
+
*
|
|
440
|
+
* Shared by `handlePatchConfig` and `handleSetConfig` so both write paths get
|
|
441
|
+
* identical post-write side effects.
|
|
442
|
+
*/
|
|
443
|
+
async function commitConfigWrite(
|
|
444
|
+
raw: Record<string, unknown>,
|
|
445
|
+
opLabel: string,
|
|
446
|
+
): Promise<void> {
|
|
356
447
|
// Suppress the file-watcher callback for the duration of the debounce
|
|
357
448
|
// window. Without this, the ConfigWatcher detects the config.json write
|
|
358
449
|
// ~200ms later, sees a stale fingerprint, and calls initializeProviders a
|
|
359
|
-
// second time
|
|
450
|
+
// second time - starting with providers.clear() which races with the
|
|
360
451
|
// explicit reinit below. The watcher also fires onConversationEvict(),
|
|
361
|
-
// which would evict all cached conversations on every
|
|
362
|
-
// suppress/reset pattern used in
|
|
452
|
+
// which would evict all cached conversations on every write. Mirror the
|
|
453
|
+
// suppress/reset pattern used in setImageGenModel (config-model.ts).
|
|
363
454
|
const configWatcher = getConfigWatcher();
|
|
364
455
|
const wasSuppressed = configWatcher.suppressConfigReload;
|
|
365
456
|
configWatcher.suppressConfigReload = true;
|
|
@@ -368,7 +459,7 @@ async function handlePatchConfig({ body }: RouteHandlerArgs) {
|
|
|
368
459
|
} catch (err) {
|
|
369
460
|
configWatcher.suppressConfigReload = wasSuppressed;
|
|
370
461
|
const message = err instanceof Error ? err.message : String(err);
|
|
371
|
-
throw new InternalError(`Failed to
|
|
462
|
+
throw new InternalError(`Failed to ${opLabel} config: ${message}`);
|
|
372
463
|
}
|
|
373
464
|
configWatcher.timers.schedule(
|
|
374
465
|
"__suppress_reset__",
|
|
@@ -383,7 +474,7 @@ async function handlePatchConfig({ body }: RouteHandlerArgs) {
|
|
|
383
474
|
// Reinitialize providers so the live registry reflects the new config
|
|
384
475
|
// (e.g. a mode flip between managed and your-own). Isolated try/catch so
|
|
385
476
|
// a provider reinit failure doesn't mask the successful config save.
|
|
386
|
-
// Only advance the config fingerprint on success
|
|
477
|
+
// Only advance the config fingerprint on success - if reinit failed, leave
|
|
387
478
|
// it stale so the watcher can detect the saved config on the next event
|
|
388
479
|
// and retry provider initialization.
|
|
389
480
|
try {
|
|
@@ -391,11 +482,101 @@ async function handlePatchConfig({ body }: RouteHandlerArgs) {
|
|
|
391
482
|
configWatcher.updateFingerprint();
|
|
392
483
|
} catch (err) {
|
|
393
484
|
const message = err instanceof Error ? err.message : String(err);
|
|
394
|
-
log.error({ err },
|
|
485
|
+
log.error({ err }, `${opLabel} config: provider reinit failed: ${message}`);
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
async function handlePatchConfig({ body }: RouteHandlerArgs) {
|
|
490
|
+
if (
|
|
491
|
+
!body ||
|
|
492
|
+
typeof body !== "object" ||
|
|
493
|
+
Array.isArray(body) ||
|
|
494
|
+
Object.keys(body).length === 0
|
|
495
|
+
) {
|
|
496
|
+
throw new BadRequestError("Body must be a non-empty JSON object");
|
|
497
|
+
}
|
|
498
|
+
rejectManagedProfileDeletion(body as Record<string, unknown>);
|
|
499
|
+
|
|
500
|
+
const raw = loadRawConfig();
|
|
501
|
+
const patch = body as Record<string, unknown>;
|
|
502
|
+
deepMergeOverwrite(raw, patch);
|
|
503
|
+
|
|
504
|
+
await commitConfigWrite(raw, "patch");
|
|
505
|
+
return { ok: true };
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
/**
|
|
509
|
+
* Direct path assignment - replaces `config_patch` for the `assistant
|
|
510
|
+
* config set <key> <value>` CLI path.
|
|
511
|
+
*
|
|
512
|
+
* `config_patch` uses `deepMergeOverwrite` semantics, which strips `null`
|
|
513
|
+
* leaves when the target subtree doesn't exist and merges (rather than
|
|
514
|
+
* replaces) object subtrees. That's correct for partial updates (embedding
|
|
515
|
+
* config, profile patches) but breaks single-key `set` semantics, where the
|
|
516
|
+
* user expects:
|
|
517
|
+
* - `set heartbeat.activeHoursStart null` to persist explicit `null`
|
|
518
|
+
* - `set llm {}` to replace `llm`, not merge into it
|
|
519
|
+
*
|
|
520
|
+
* `config_set` performs `setNestedValue` directly on the loaded raw config
|
|
521
|
+
* (no merge), then runs the same post-write side effects as patch.
|
|
522
|
+
*/
|
|
523
|
+
async function handleSetConfig({ body }: RouteHandlerArgs) {
|
|
524
|
+
if (!body || typeof body !== "object" || Array.isArray(body)) {
|
|
525
|
+
throw new BadRequestError(
|
|
526
|
+
"Body must be a JSON object with `path` and `value`",
|
|
527
|
+
);
|
|
395
528
|
}
|
|
529
|
+
const bodyRecord = body as Record<string, unknown>;
|
|
530
|
+
const { path, value } = bodyRecord as { path?: unknown; value?: unknown };
|
|
531
|
+
if (typeof path !== "string" || path.length === 0) {
|
|
532
|
+
throw new BadRequestError("`path` must be a non-empty string");
|
|
533
|
+
}
|
|
534
|
+
// `value` must be present (use explicit `null` to clear a key). Without
|
|
535
|
+
// this check, `undefined` flows into `setNestedValue` and gets dropped by
|
|
536
|
+
// `JSON.stringify` at save time, silently removing the key - which is
|
|
537
|
+
// distinct from the documented "set to null" semantics.
|
|
538
|
+
if (!("value" in bodyRecord)) {
|
|
539
|
+
throw new BadRequestError(
|
|
540
|
+
"`value` is required (use `null` to clear a key)",
|
|
541
|
+
);
|
|
542
|
+
}
|
|
543
|
+
// Build the equivalent patch shape so the managed-profile guard can
|
|
544
|
+
// inspect the touched subtree.
|
|
545
|
+
const patchShape: Record<string, unknown> = {};
|
|
546
|
+
setNestedValue(patchShape, path, value);
|
|
547
|
+
rejectManagedProfileDeletion(patchShape);
|
|
548
|
+
|
|
549
|
+
const raw = loadRawConfig();
|
|
550
|
+
setNestedValue(raw, path, value);
|
|
551
|
+
|
|
552
|
+
await commitConfigWrite(raw, "set");
|
|
396
553
|
return { ok: true };
|
|
397
554
|
}
|
|
398
555
|
|
|
556
|
+
/**
|
|
557
|
+
* Validate the regex patterns inside the workspace's
|
|
558
|
+
* `secret-allowlist.json` file.
|
|
559
|
+
*
|
|
560
|
+
* Pure read: opens the file, attempts to compile each pattern, returns
|
|
561
|
+
* structured errors. The handler returns `{ exists: false }` if the file is
|
|
562
|
+
* absent, or `{ exists: true, errors: [...] }` otherwise.
|
|
563
|
+
*/
|
|
564
|
+
function handleValidateAllowlist() {
|
|
565
|
+
try {
|
|
566
|
+
const errors = validateAllowlistFile();
|
|
567
|
+
if (errors == null) return { exists: false } as const;
|
|
568
|
+
return { exists: true, errors } as const;
|
|
569
|
+
} catch (err) {
|
|
570
|
+
// `validateAllowlistFile` does a raw `JSON.parse` on
|
|
571
|
+
// `secret-allowlist.json` and can throw on malformed JSON. Surface
|
|
572
|
+
// that as a structured `parseError` in the response payload instead
|
|
573
|
+
// of letting it propagate as a 500. Preserves the pre-IPC CLI
|
|
574
|
+
// behavior, which printed a user-readable failure and exited 1.
|
|
575
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
576
|
+
return { exists: true, parseError: message, errors: [] } as const;
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
|
|
399
580
|
function handleReplaceInferenceProfile({
|
|
400
581
|
pathParams = {},
|
|
401
582
|
body,
|
|
@@ -407,9 +588,9 @@ function handleReplaceInferenceProfile({
|
|
|
407
588
|
if (!body || typeof body !== "object" || Array.isArray(body)) {
|
|
408
589
|
throw new BadRequestError("Body must be a JSON object");
|
|
409
590
|
}
|
|
410
|
-
if (
|
|
591
|
+
if (RESERVED_PROFILE_NAMES.has(name)) {
|
|
411
592
|
throw new BadRequestError(
|
|
412
|
-
`
|
|
593
|
+
`Profile name "${name}" is reserved and cannot be used.`,
|
|
413
594
|
);
|
|
414
595
|
}
|
|
415
596
|
const parsed = ProfileEntry.safeParse(body);
|
|
@@ -417,13 +598,44 @@ function handleReplaceInferenceProfile({
|
|
|
417
598
|
const detail = parsed.error.issues.map((issue) => issue.message).join("; ");
|
|
418
599
|
throw new BadRequestError(`Invalid profile fragment: ${detail}`);
|
|
419
600
|
}
|
|
601
|
+
const isManaged = MANAGED_PROFILE_NAMES.has(name);
|
|
602
|
+
if (isManaged) {
|
|
603
|
+
// Managed profiles are daemon-seeded — provider, model, advanced params,
|
|
604
|
+
// and the connection binding all belong to the seed contract and can't
|
|
605
|
+
// be reshaped by the user. The two fields that ARE user policy (display
|
|
606
|
+
// label and enabled status) are allowed through so users can rename a
|
|
607
|
+
// managed profile or temporarily disable it without duplicating it.
|
|
608
|
+
const requestedKeys = Object.keys(parsed.data);
|
|
609
|
+
const disallowed = requestedKeys.filter(
|
|
610
|
+
(k) => k !== "label" && k !== "status",
|
|
611
|
+
);
|
|
612
|
+
if (disallowed.length > 0) {
|
|
613
|
+
throw new BadRequestError(
|
|
614
|
+
`Cannot edit managed profile "${name}" fields [${disallowed.join(", ")}]. ` +
|
|
615
|
+
`Only label and status may be edited; duplicate to a custom profile to change other fields.`,
|
|
616
|
+
);
|
|
617
|
+
}
|
|
618
|
+
}
|
|
420
619
|
try {
|
|
421
620
|
const raw = loadRawConfig();
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
621
|
+
if (isManaged) {
|
|
622
|
+
// Partial overlay: keep every existing key intact, only update label
|
|
623
|
+
// and/or status from the fragment. Using `replaceInferenceProfileConfig`
|
|
624
|
+
// here would wipe the UI-owned seed fields (provider, model, advanced
|
|
625
|
+
// params) because that function assumes the body carries the full UI
|
|
626
|
+
// surface.
|
|
627
|
+
patchManagedProfileFields(
|
|
628
|
+
raw,
|
|
629
|
+
name,
|
|
630
|
+
parsed.data as Record<string, unknown>,
|
|
631
|
+
);
|
|
632
|
+
} else {
|
|
633
|
+
replaceInferenceProfileConfig(
|
|
634
|
+
raw,
|
|
635
|
+
name,
|
|
636
|
+
parsed.data as Record<string, unknown>,
|
|
637
|
+
);
|
|
638
|
+
}
|
|
427
639
|
saveRawConfig(raw);
|
|
428
640
|
return { ok: true };
|
|
429
641
|
} catch (err) {
|
|
@@ -432,6 +644,45 @@ function handleReplaceInferenceProfile({
|
|
|
432
644
|
}
|
|
433
645
|
}
|
|
434
646
|
|
|
647
|
+
/**
|
|
648
|
+
* Apply a `{label?, status?}` patch to a managed profile entry, preserving
|
|
649
|
+
* every other field already on disk (provider, model, advanced params, etc).
|
|
650
|
+
* Caller is responsible for having already restricted the fragment to the
|
|
651
|
+
* managed-allowed keys.
|
|
652
|
+
*/
|
|
653
|
+
function patchManagedProfileFields(
|
|
654
|
+
raw: Record<string, unknown>,
|
|
655
|
+
name: string,
|
|
656
|
+
fragment: Record<string, unknown>,
|
|
657
|
+
): void {
|
|
658
|
+
const existingLlm = asMutablePlainObject(raw.llm);
|
|
659
|
+
const llm = existingLlm ?? {};
|
|
660
|
+
if (!existingLlm) raw.llm = llm;
|
|
661
|
+
|
|
662
|
+
const existingProfiles = asMutablePlainObject(llm.profiles);
|
|
663
|
+
const profiles = existingProfiles ?? {};
|
|
664
|
+
if (!existingProfiles) llm.profiles = profiles;
|
|
665
|
+
|
|
666
|
+
const existingProfile = asMutablePlainObject(profiles[name]) ?? {};
|
|
667
|
+
const nextProfile: Record<string, unknown> = { ...existingProfile };
|
|
668
|
+
// Send `null` to clear; omit to leave untouched.
|
|
669
|
+
if ("label" in fragment) {
|
|
670
|
+
if (fragment.label === null) {
|
|
671
|
+
delete nextProfile.label;
|
|
672
|
+
} else {
|
|
673
|
+
nextProfile.label = fragment.label;
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
if ("status" in fragment) {
|
|
677
|
+
if (fragment.status === null) {
|
|
678
|
+
delete nextProfile.status;
|
|
679
|
+
} else {
|
|
680
|
+
nextProfile.status = fragment.status;
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
profiles[name] = nextProfile;
|
|
684
|
+
}
|
|
685
|
+
|
|
435
686
|
function handleSearchConversations({ queryParams = {} }: RouteHandlerArgs) {
|
|
436
687
|
const q = queryParams.q;
|
|
437
688
|
if (!q) {
|
|
@@ -484,12 +735,13 @@ function resolveConversationKind(
|
|
|
484
735
|
return "user";
|
|
485
736
|
}
|
|
486
737
|
|
|
487
|
-
function handleGetLlmContext({ pathParams = {} }: RouteHandlerArgs) {
|
|
738
|
+
async function handleGetLlmContext({ pathParams = {} }: RouteHandlerArgs) {
|
|
488
739
|
const messageId = pathParams.id;
|
|
489
740
|
if (!messageId) {
|
|
490
741
|
throw new BadRequestError("message id is required");
|
|
491
742
|
}
|
|
492
|
-
const
|
|
743
|
+
const source = await getLlmRequestLogSource();
|
|
744
|
+
const logs = await source.getRequestLogsByMessageId(messageId);
|
|
493
745
|
const turnMessageIds = getAssistantMessageIdsInTurn(messageId);
|
|
494
746
|
const memoryRecallLog = getMemoryRecallLogByMessageIds(turnMessageIds);
|
|
495
747
|
const memoryV2Activation =
|
|
@@ -502,9 +754,15 @@ function handleGetLlmContext({ pathParams = {} }: RouteHandlerArgs) {
|
|
|
502
754
|
conversation.conversationType,
|
|
503
755
|
)
|
|
504
756
|
: "user";
|
|
757
|
+
// Running total of estimated USD cost across every priced LLM call in
|
|
758
|
+
// the conversation. Maintained by `updateConversationUsage` whenever a
|
|
759
|
+
// turn finishes — see `assistant/src/memory/conversation-crud.ts`.
|
|
760
|
+
const conversationTotalEstimatedCostUsd =
|
|
761
|
+
conversation?.totalEstimatedCost ?? null;
|
|
505
762
|
return {
|
|
506
763
|
messageId,
|
|
507
764
|
conversationKind,
|
|
765
|
+
conversationTotalEstimatedCostUsd,
|
|
508
766
|
logs: logs.map((log) => {
|
|
509
767
|
let requestPayload: unknown;
|
|
510
768
|
try {
|
|
@@ -540,12 +798,15 @@ function handleGetLlmContext({ pathParams = {} }: RouteHandlerArgs) {
|
|
|
540
798
|
};
|
|
541
799
|
}
|
|
542
800
|
|
|
543
|
-
function handleGetLlmRequestLogPayload({
|
|
801
|
+
async function handleGetLlmRequestLogPayload({
|
|
802
|
+
pathParams = {},
|
|
803
|
+
}: RouteHandlerArgs) {
|
|
544
804
|
const logId = pathParams.id;
|
|
545
805
|
if (!logId) {
|
|
546
806
|
throw new BadRequestError("log id is required");
|
|
547
807
|
}
|
|
548
|
-
const
|
|
808
|
+
const source = await getLlmRequestLogSource();
|
|
809
|
+
const log = await source.getRequestLogById(logId);
|
|
549
810
|
if (!log) {
|
|
550
811
|
throw new NotFoundError("log not found");
|
|
551
812
|
}
|
|
@@ -600,20 +861,6 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
600
861
|
tags: ["config"],
|
|
601
862
|
handler: handleGetModel,
|
|
602
863
|
},
|
|
603
|
-
{
|
|
604
|
-
operationId: "model_set",
|
|
605
|
-
endpoint: "model",
|
|
606
|
-
method: "PUT",
|
|
607
|
-
policyKey: "model",
|
|
608
|
-
summary: "Set LLM model",
|
|
609
|
-
description: "Change the active LLM model and optionally its provider.",
|
|
610
|
-
tags: ["config"],
|
|
611
|
-
requestBody: z.object({
|
|
612
|
-
modelId: z.string(),
|
|
613
|
-
provider: z.string().describe("Optional provider override").optional(),
|
|
614
|
-
}),
|
|
615
|
-
handler: handleSetModel,
|
|
616
|
-
},
|
|
617
864
|
{
|
|
618
865
|
operationId: "model_image_gen_set",
|
|
619
866
|
endpoint: "model/image-gen",
|
|
@@ -671,6 +918,49 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
671
918
|
tags: ["config"],
|
|
672
919
|
handler: handlePatchConfig,
|
|
673
920
|
},
|
|
921
|
+
{
|
|
922
|
+
operationId: "config_set",
|
|
923
|
+
endpoint: "config/set",
|
|
924
|
+
method: "POST",
|
|
925
|
+
policyKey: "config/set",
|
|
926
|
+
summary: "Set a single config path",
|
|
927
|
+
description:
|
|
928
|
+
"Assign a value at a dotted config path with direct-replacement semantics " +
|
|
929
|
+
"(preserves explicit null, replaces object subtrees instead of merging). " +
|
|
930
|
+
"Used by the `assistant config set <key> <value>` CLI command.",
|
|
931
|
+
tags: ["config"],
|
|
932
|
+
handler: handleSetConfig,
|
|
933
|
+
},
|
|
934
|
+
{
|
|
935
|
+
operationId: "config_allowlist_validate",
|
|
936
|
+
endpoint: "config/allowlist/validate",
|
|
937
|
+
method: "GET",
|
|
938
|
+
policyKey: "config/allowlist/validate",
|
|
939
|
+
summary: "Validate secret-allowlist.json regex patterns",
|
|
940
|
+
description:
|
|
941
|
+
"Compile each regex pattern in secret-allowlist.json and return any " +
|
|
942
|
+
"syntax errors. Returns { exists: false } if no file is present.",
|
|
943
|
+
tags: ["config"],
|
|
944
|
+
handler: handleValidateAllowlist,
|
|
945
|
+
},
|
|
946
|
+
{
|
|
947
|
+
operationId: "config_schema_get",
|
|
948
|
+
endpoint: "config/schema",
|
|
949
|
+
method: "GET",
|
|
950
|
+
policyKey: "config/schema",
|
|
951
|
+
summary: "Get config JSON Schema",
|
|
952
|
+
description:
|
|
953
|
+
"Return the JSON Schema for the assistant config, optionally scoped to a dotted-path sub-schema (e.g. ?path=calls).",
|
|
954
|
+
tags: ["config"],
|
|
955
|
+
queryParams: [
|
|
956
|
+
{
|
|
957
|
+
name: "path",
|
|
958
|
+
schema: { type: "string" },
|
|
959
|
+
description: "Optional dotted path to a config sub-key",
|
|
960
|
+
},
|
|
961
|
+
],
|
|
962
|
+
handler: handleGetConfigSchema,
|
|
963
|
+
},
|
|
674
964
|
{
|
|
675
965
|
operationId: "config_llm_profiles_replace",
|
|
676
966
|
endpoint: "config/llm/profiles/:name",
|
|
@@ -744,6 +1034,7 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
744
1034
|
responseBody: z.object({
|
|
745
1035
|
messageId: z.string(),
|
|
746
1036
|
conversationKind: z.enum(CONVERSATION_KINDS),
|
|
1037
|
+
conversationTotalEstimatedCostUsd: z.number().nullable(),
|
|
747
1038
|
logs: z.array(z.unknown()),
|
|
748
1039
|
memoryRecall: z.object({}).passthrough().nullable(),
|
|
749
1040
|
memoryV2Activation: z.object({}).passthrough().nullable(),
|