@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
|
@@ -1,38 +1,16 @@
|
|
|
1
|
+
import { resolveCallSiteConfig } from "../../config/llm-resolver.js";
|
|
1
2
|
import {
|
|
2
3
|
getConfig,
|
|
3
4
|
loadRawConfig,
|
|
4
5
|
saveRawConfig,
|
|
5
6
|
} from "../../config/loader.js";
|
|
6
|
-
import {
|
|
7
|
-
setLlmDefaultField,
|
|
8
|
-
setServiceField,
|
|
9
|
-
} from "../../config/raw-config-utils.js";
|
|
10
|
-
import { VALID_INFERENCE_PROVIDERS } from "../../config/schemas/services.js";
|
|
7
|
+
import { setServiceField } from "../../config/raw-config-utils.js";
|
|
11
8
|
import { providerForImageModelPrefix } from "../../media/types.js";
|
|
12
9
|
import type { ProviderCatalogEntry } from "../../providers/model-catalog.js";
|
|
13
|
-
import {
|
|
14
|
-
|
|
15
|
-
PROVIDER_CATALOG,
|
|
16
|
-
} from "../../providers/model-catalog.js";
|
|
17
|
-
import { getProviderDefaultModel } from "../../providers/model-intents.js";
|
|
18
|
-
import {
|
|
19
|
-
getConfiguredProviders,
|
|
20
|
-
isProviderAvailable,
|
|
21
|
-
} from "../../providers/provider-availability.js";
|
|
22
|
-
import { initializeProviders } from "../../providers/registry.js";
|
|
23
|
-
import {
|
|
24
|
-
conversationEntries,
|
|
25
|
-
deleteConversation,
|
|
26
|
-
} from "../conversation-store.js";
|
|
10
|
+
import { PROVIDER_CATALOG } from "../../providers/model-catalog.js";
|
|
11
|
+
import { getConfiguredProviders } from "../../providers/provider-availability.js";
|
|
27
12
|
import { CONFIG_RELOAD_DEBOUNCE_MS, log } from "./shared.js";
|
|
28
13
|
|
|
29
|
-
/** Reverse lookup: model ID → provider, derived from PROVIDER_CATALOG. */
|
|
30
|
-
const MODEL_TO_PROVIDER: Record<string, string> = Object.fromEntries(
|
|
31
|
-
PROVIDER_CATALOG.flatMap((provider) =>
|
|
32
|
-
provider.models.map(({ id }) => [id, provider.id]),
|
|
33
|
-
),
|
|
34
|
-
);
|
|
35
|
-
|
|
36
14
|
// ---------------------------------------------------------------------------
|
|
37
15
|
// Shared business logic (transport-agnostic)
|
|
38
16
|
// ---------------------------------------------------------------------------
|
|
@@ -85,10 +63,11 @@ export function projectProviderForWire(
|
|
|
85
63
|
/** Return current model configuration. */
|
|
86
64
|
export async function getModelInfo(): Promise<ModelInfo> {
|
|
87
65
|
const config = getConfig();
|
|
88
|
-
const
|
|
66
|
+
const resolved = resolveCallSiteConfig("mainAgent", config.llm);
|
|
67
|
+
const provider = resolved.provider;
|
|
89
68
|
|
|
90
69
|
return {
|
|
91
|
-
model:
|
|
70
|
+
model: resolved.model,
|
|
92
71
|
provider,
|
|
93
72
|
configuredProviders: await getConfiguredProviders(),
|
|
94
73
|
availableModels: PROVIDER_CATALOG.find(
|
|
@@ -99,7 +78,7 @@ export async function getModelInfo(): Promise<ModelInfo> {
|
|
|
99
78
|
}
|
|
100
79
|
|
|
101
80
|
/**
|
|
102
|
-
* Minimal interface for the side-effects needed by
|
|
81
|
+
* Minimal interface for the side-effects needed by setImageGenModel.
|
|
103
82
|
* Keeps the business logic decoupled from transport-specific server context.
|
|
104
83
|
*/
|
|
105
84
|
export interface ModelSetContext {
|
|
@@ -109,103 +88,6 @@ export interface ModelSetContext {
|
|
|
109
88
|
debounceTimers: { schedule(key: string, fn: () => void, ms: number): void };
|
|
110
89
|
}
|
|
111
90
|
|
|
112
|
-
/**
|
|
113
|
-
* Set the active model. Returns the resulting ModelInfo, or throws on failure.
|
|
114
|
-
* The caller is responsible for sending the response to the client.
|
|
115
|
-
*
|
|
116
|
-
* When `explicitProvider` is supplied, it takes precedence over automatic
|
|
117
|
-
* provider inference from the model ID. If the provider changes and the
|
|
118
|
-
* current model doesn't belong to the new provider's catalog, the model
|
|
119
|
-
* is auto-reset to the provider's default.
|
|
120
|
-
*/
|
|
121
|
-
export async function setModel(
|
|
122
|
-
modelId: string,
|
|
123
|
-
ctx: ModelSetContext,
|
|
124
|
-
explicitProvider?: string,
|
|
125
|
-
): Promise<ModelInfo> {
|
|
126
|
-
const validProviders = new Set<string>(VALID_INFERENCE_PROVIDERS);
|
|
127
|
-
|
|
128
|
-
// Validate explicit provider against allowlist
|
|
129
|
-
if (explicitProvider && !validProviders.has(explicitProvider)) {
|
|
130
|
-
throw new Error(
|
|
131
|
-
`Invalid provider "${explicitProvider}". Valid providers: ${[...validProviders].join(", ")}`,
|
|
132
|
-
);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
// Resolve provider: explicit > MODEL_TO_PROVIDER lookup > current
|
|
136
|
-
const current = getConfig();
|
|
137
|
-
const resolvedProvider =
|
|
138
|
-
explicitProvider ??
|
|
139
|
-
MODEL_TO_PROVIDER[modelId] ??
|
|
140
|
-
current.llm.default.provider;
|
|
141
|
-
|
|
142
|
-
// Auto-reset model when provider changes and current modelId doesn't
|
|
143
|
-
// belong to the new provider's catalog.
|
|
144
|
-
if (
|
|
145
|
-
resolvedProvider !== current.llm.default.provider &&
|
|
146
|
-
!isModelInCatalog(resolvedProvider, modelId)
|
|
147
|
-
) {
|
|
148
|
-
modelId = getProviderDefaultModel(resolvedProvider);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
// No-op guard: skip expensive reinitialization when nothing changed
|
|
152
|
-
if (
|
|
153
|
-
modelId === current.llm.default.model &&
|
|
154
|
-
resolvedProvider === current.llm.default.provider
|
|
155
|
-
) {
|
|
156
|
-
return await getModelInfo();
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// Validate provider availability (secure key, env var, or managed proxy) before switching
|
|
160
|
-
if (!(await isProviderAvailable(resolvedProvider))) {
|
|
161
|
-
// Return current model_info so the client resyncs its optimistic state
|
|
162
|
-
return await getModelInfo();
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
// Use raw config to avoid persisting env-var API keys to disk
|
|
166
|
-
const raw = loadRawConfig();
|
|
167
|
-
setLlmDefaultField(raw, "model", modelId);
|
|
168
|
-
setLlmDefaultField(raw, "provider", resolvedProvider);
|
|
169
|
-
|
|
170
|
-
// Suppress the file watcher callback — setModel already does
|
|
171
|
-
// the full reload sequence; a redundant watcher-triggered reload
|
|
172
|
-
// would incorrectly evict sessions created after this method returns.
|
|
173
|
-
const wasSuppressed = ctx.suppressConfigReload;
|
|
174
|
-
ctx.setSuppressConfigReload(true);
|
|
175
|
-
try {
|
|
176
|
-
saveRawConfig(raw);
|
|
177
|
-
} catch (err) {
|
|
178
|
-
ctx.setSuppressConfigReload(wasSuppressed);
|
|
179
|
-
throw err;
|
|
180
|
-
}
|
|
181
|
-
ctx.debounceTimers.schedule(
|
|
182
|
-
"__suppress_reset__",
|
|
183
|
-
() => {
|
|
184
|
-
ctx.setSuppressConfigReload(false);
|
|
185
|
-
},
|
|
186
|
-
CONFIG_RELOAD_DEBOUNCE_MS,
|
|
187
|
-
);
|
|
188
|
-
|
|
189
|
-
// Re-initialize provider with the new model so LLM calls use it
|
|
190
|
-
const config = getConfig();
|
|
191
|
-
await initializeProviders(config);
|
|
192
|
-
|
|
193
|
-
// Evict idle conversations immediately; mark busy ones as stale so they
|
|
194
|
-
// get recreated with the new provider once they finish processing.
|
|
195
|
-
for (const [id, conversation] of conversationEntries()) {
|
|
196
|
-
if (!conversation.isProcessing()) {
|
|
197
|
-
conversation.dispose();
|
|
198
|
-
deleteConversation(id);
|
|
199
|
-
} else {
|
|
200
|
-
conversation.markStale();
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
ctx.updateConfigFingerprint();
|
|
205
|
-
|
|
206
|
-
return await getModelInfo();
|
|
207
|
-
}
|
|
208
|
-
|
|
209
91
|
/**
|
|
210
92
|
* Set the image generation model. Throws on failure.
|
|
211
93
|
*/
|
|
@@ -54,6 +54,7 @@ const SLACK_INJECTION_TEMPLATES = [
|
|
|
54
54
|
/** Ensure the bot token credential has injection templates for the proxy. */
|
|
55
55
|
function ensureBotTokenInjectionTemplates(): void {
|
|
56
56
|
upsertCredentialMetadata("slack_channel", "bot_token", {
|
|
57
|
+
allowedTools: ["bash"],
|
|
57
58
|
allowedDomains: ["slack.com"],
|
|
58
59
|
injectionTemplates: SLACK_INJECTION_TEMPLATES,
|
|
59
60
|
});
|
|
@@ -62,6 +63,7 @@ function ensureBotTokenInjectionTemplates(): void {
|
|
|
62
63
|
/** Ensure the user token credential has injection templates for the proxy. */
|
|
63
64
|
function ensureUserTokenInjectionTemplates(): void {
|
|
64
65
|
upsertCredentialMetadata("slack_channel", "user_token", {
|
|
66
|
+
allowedTools: ["bash"],
|
|
65
67
|
allowedDomains: ["slack.com"],
|
|
66
68
|
injectionTemplates: SLACK_INJECTION_TEMPLATES,
|
|
67
69
|
});
|
|
@@ -209,7 +211,9 @@ export async function setSlackChannelConfig(
|
|
|
209
211
|
botToken,
|
|
210
212
|
);
|
|
211
213
|
if (!stored) {
|
|
212
|
-
return currentErrorSnapshot(
|
|
214
|
+
return currentErrorSnapshot(
|
|
215
|
+
"Failed to store bot token in secure storage",
|
|
216
|
+
);
|
|
213
217
|
}
|
|
214
218
|
|
|
215
219
|
ensureBotTokenInjectionTemplates();
|
|
@@ -262,8 +266,7 @@ export async function setSlackChannelConfig(
|
|
|
262
266
|
data.team_id !== metadata.teamId
|
|
263
267
|
) {
|
|
264
268
|
shouldClear = true;
|
|
265
|
-
clearReason =
|
|
266
|
-
"User token from a different workspace was removed.";
|
|
269
|
+
clearReason = "User token from a different workspace was removed.";
|
|
267
270
|
}
|
|
268
271
|
} catch (err) {
|
|
269
272
|
// Transient failure (DNS error, network blip, connection reset,
|
|
@@ -310,7 +313,9 @@ export async function setSlackChannelConfig(
|
|
|
310
313
|
appToken,
|
|
311
314
|
);
|
|
312
315
|
if (!stored) {
|
|
313
|
-
return currentErrorSnapshot(
|
|
316
|
+
return currentErrorSnapshot(
|
|
317
|
+
"Failed to store app token in secure storage",
|
|
318
|
+
);
|
|
314
319
|
}
|
|
315
320
|
|
|
316
321
|
upsertCredentialMetadata("slack_channel", "app_token", {});
|
|
@@ -344,9 +349,7 @@ export async function setSlackChannelConfig(
|
|
|
344
349
|
userTeamId = data.team_id;
|
|
345
350
|
} catch (err) {
|
|
346
351
|
const message = err instanceof Error ? err.message : String(err);
|
|
347
|
-
return currentErrorSnapshot(
|
|
348
|
-
`Failed to validate user token: ${message}`,
|
|
349
|
-
);
|
|
352
|
+
return currentErrorSnapshot(`Failed to validate user token: ${message}`);
|
|
350
353
|
}
|
|
351
354
|
|
|
352
355
|
// Cross-check: if a bot token has already been configured, the user token
|
|
@@ -59,7 +59,9 @@ export async function setVercelConfig(
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
upsertCredentialMetadata("vercel", "api_token", {
|
|
62
|
-
allowedTools: ["
|
|
62
|
+
allowedTools: ["publish_page", "unpublish_page"],
|
|
63
|
+
allowedDomains: [],
|
|
64
|
+
injectionTemplates: null,
|
|
63
65
|
});
|
|
64
66
|
|
|
65
67
|
log.info("Vercel API token stored successfully");
|
|
@@ -63,6 +63,20 @@ export interface HistoryToolCall {
|
|
|
63
63
|
approvalReason?: string;
|
|
64
64
|
/** Snapshot of the auto-approve threshold at execution time. */
|
|
65
65
|
riskThreshold?: string;
|
|
66
|
+
/**
|
|
67
|
+
* Display-only regex ladder for the rule editor (narrowest → broadest).
|
|
68
|
+
* Persisted on tool_use blocks by `annotatePersistedAssistantMessage` so
|
|
69
|
+
* historical chips render the same ladder as live tool_result events.
|
|
70
|
+
*/
|
|
71
|
+
riskScopeOptions?: Array<{ pattern: string; label: string }>;
|
|
72
|
+
/** Minimatch save patterns for the rule editor (narrowest → broadest). */
|
|
73
|
+
riskAllowlistOptions?: Array<{
|
|
74
|
+
label: string;
|
|
75
|
+
description: string;
|
|
76
|
+
pattern: string;
|
|
77
|
+
}>;
|
|
78
|
+
/** Directory scope ladder for the rule editor. */
|
|
79
|
+
riskDirectoryScopeOptions?: Array<{ scope: string; label: string }>;
|
|
66
80
|
}
|
|
67
81
|
|
|
68
82
|
export interface HistorySurface {
|
|
@@ -368,6 +382,18 @@ export function renderHistoryContent(content: unknown): RenderedHistoryContent {
|
|
|
368
382
|
entry.approvalReason = block._approvalReason;
|
|
369
383
|
if (typeof block._riskThreshold === "string")
|
|
370
384
|
entry.riskThreshold = block._riskThreshold;
|
|
385
|
+
// Read back the 3 risk-option arrays persisted by
|
|
386
|
+
// `annotatePersistedAssistantMessage`. Validate the array shape only
|
|
387
|
+
// — element shapes are best-effort (we trust our own writer).
|
|
388
|
+
if (Array.isArray(block._riskScopeOptions))
|
|
389
|
+
entry.riskScopeOptions =
|
|
390
|
+
block._riskScopeOptions as HistoryToolCall["riskScopeOptions"];
|
|
391
|
+
if (Array.isArray(block._riskAllowlistOptions))
|
|
392
|
+
entry.riskAllowlistOptions =
|
|
393
|
+
block._riskAllowlistOptions as HistoryToolCall["riskAllowlistOptions"];
|
|
394
|
+
if (Array.isArray(block._riskDirectoryScopeOptions))
|
|
395
|
+
entry.riskDirectoryScopeOptions =
|
|
396
|
+
block._riskDirectoryScopeOptions as HistoryToolCall["riskDirectoryScopeOptions"];
|
|
371
397
|
toolCalls.push(entry);
|
|
372
398
|
if (id) pendingToolUses.set(id, entry);
|
|
373
399
|
contentOrder.push(`tool:${toolCalls.length - 1}`);
|
|
@@ -691,6 +691,65 @@ export async function getSkill(
|
|
|
691
691
|
return { skill: detail };
|
|
692
692
|
}
|
|
693
693
|
|
|
694
|
+
export function getSkillLocalDetail(
|
|
695
|
+
skillId: string,
|
|
696
|
+
): {
|
|
697
|
+
ok: true;
|
|
698
|
+
id: string;
|
|
699
|
+
name: string;
|
|
700
|
+
description: string;
|
|
701
|
+
emoji: string | null;
|
|
702
|
+
source: string;
|
|
703
|
+
state: string;
|
|
704
|
+
directoryPath: string;
|
|
705
|
+
featureFlag: string | null;
|
|
706
|
+
includes: string[] | null;
|
|
707
|
+
activationHints: string[] | null;
|
|
708
|
+
avoidWhen: string[] | null;
|
|
709
|
+
toolManifest: { valid: boolean; toolCount: number; toolNames: string[] } | null;
|
|
710
|
+
installMeta: Record<string, unknown> | null;
|
|
711
|
+
config: { enabled: boolean; envKeys: string[]; configKeys: string[] } | null;
|
|
712
|
+
} | { ok: false; error: string; status: 404 | 500 } {
|
|
713
|
+
try {
|
|
714
|
+
const catalog = loadSkillCatalog();
|
|
715
|
+
const config = getConfig();
|
|
716
|
+
const resolved = resolveSkillStates(catalog, config);
|
|
717
|
+
const match = resolved.find((r) => r.summary.id === skillId);
|
|
718
|
+
if (!match) {
|
|
719
|
+
return { ok: false, error: `Skill "${skillId}" not found. Run 'assistant skills list' to see available skills.`, status: 404 };
|
|
720
|
+
}
|
|
721
|
+
const { summary, state, configEntry } = match;
|
|
722
|
+
const installMeta = readInstallMeta(summary.directoryPath);
|
|
723
|
+
return {
|
|
724
|
+
ok: true,
|
|
725
|
+
id: summary.id,
|
|
726
|
+
name: summary.displayName,
|
|
727
|
+
description: summary.description,
|
|
728
|
+
emoji: summary.emoji ?? null,
|
|
729
|
+
source: summary.source,
|
|
730
|
+
state,
|
|
731
|
+
directoryPath: summary.directoryPath,
|
|
732
|
+
featureFlag: summary.featureFlag ?? null,
|
|
733
|
+
includes: summary.includes ?? null,
|
|
734
|
+
activationHints: summary.activationHints ?? null,
|
|
735
|
+
avoidWhen: summary.avoidWhen ?? null,
|
|
736
|
+
toolManifest: summary.toolManifest
|
|
737
|
+
? { valid: summary.toolManifest.valid, toolCount: summary.toolManifest.toolCount, toolNames: summary.toolManifest.toolNames }
|
|
738
|
+
: null,
|
|
739
|
+
installMeta: installMeta ? (installMeta as unknown as Record<string, unknown>) : null,
|
|
740
|
+
config: configEntry
|
|
741
|
+
? {
|
|
742
|
+
enabled: configEntry.enabled !== false,
|
|
743
|
+
envKeys: configEntry.env ? Object.keys(configEntry.env) : [],
|
|
744
|
+
configKeys: configEntry.config ? Object.keys(configEntry.config) : [],
|
|
745
|
+
}
|
|
746
|
+
: null,
|
|
747
|
+
};
|
|
748
|
+
} catch (err) {
|
|
749
|
+
return { ok: false, error: err instanceof Error ? err.message : String(err), status: 500 };
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
|
|
694
753
|
// ─── Skill file listing ──────────────────────────────────────────────────────
|
|
695
754
|
|
|
696
755
|
// `SkillFileEntry` lives in `../../skills/catalog-files.ts` to keep a single
|
|
@@ -1017,6 +1076,8 @@ export async function installSkill(spec: {
|
|
|
1017
1076
|
slug: string;
|
|
1018
1077
|
version?: string;
|
|
1019
1078
|
origin?: "clawhub" | "skillssh";
|
|
1079
|
+
catalogOnly?: boolean;
|
|
1080
|
+
overwrite?: boolean;
|
|
1020
1081
|
contactId?: string;
|
|
1021
1082
|
}): Promise<
|
|
1022
1083
|
{ success: true; skillId: string } | { success: false; error: string }
|
|
@@ -1078,10 +1139,14 @@ export async function installSkill(spec: {
|
|
|
1078
1139
|
const vellumCatalog = await getCatalog();
|
|
1079
1140
|
const catalogEntry = vellumCatalog.find((s) => s.id === spec.slug);
|
|
1080
1141
|
if (catalogEntry) {
|
|
1142
|
+
// Default `overwrite` to true at the handler boundary to preserve
|
|
1143
|
+
// pre-existing HTTP API behaviour. CLI callers always pass an
|
|
1144
|
+
// explicit boolean (`opts.overwrite ?? false`) so the CLI surface
|
|
1145
|
+
// still defaults to non-destructive installs.
|
|
1081
1146
|
await installSkillLocally(
|
|
1082
1147
|
spec.slug,
|
|
1083
1148
|
catalogEntry,
|
|
1084
|
-
true,
|
|
1149
|
+
spec.overwrite ?? true,
|
|
1085
1150
|
spec.contactId,
|
|
1086
1151
|
);
|
|
1087
1152
|
|
|
@@ -1090,13 +1155,19 @@ export async function installSkill(spec: {
|
|
|
1090
1155
|
return { success: true, skillId: spec.slug };
|
|
1091
1156
|
}
|
|
1092
1157
|
} catch (err) {
|
|
1093
|
-
|
|
1158
|
+
if (spec.catalogOnly) {
|
|
1159
|
+
return { success: false, error: `Failed to install catalog skill "${spec.slug}"` };
|
|
1160
|
+
}
|
|
1094
1161
|
log.warn(
|
|
1095
1162
|
{ err, skillId: spec.slug },
|
|
1096
1163
|
"Vellum catalog install failed, falling back to community registry",
|
|
1097
1164
|
);
|
|
1098
1165
|
}
|
|
1099
1166
|
|
|
1167
|
+
if (spec.catalogOnly) {
|
|
1168
|
+
return { success: false, error: `Skill "${spec.slug}" not found in the Vellum catalog` };
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1100
1171
|
// skills.sh install path: route here when origin is explicitly "skillssh"
|
|
1101
1172
|
// or when the slug looks like a skills.sh multi-segment format (owner/repo/skill)
|
|
1102
1173
|
if (
|
|
@@ -1104,11 +1175,14 @@ export async function installSkill(spec: {
|
|
|
1104
1175
|
(spec.origin !== "clawhub" && looksLikeSkillsShSlug(spec.slug))
|
|
1105
1176
|
) {
|
|
1106
1177
|
const resolved = resolveSkillSource(spec.slug);
|
|
1178
|
+
// Default `overwrite` to true at the handler boundary to preserve
|
|
1179
|
+
// pre-existing HTTP API behaviour (same rationale as the catalog
|
|
1180
|
+
// install path above).
|
|
1107
1181
|
await installExternalSkill(
|
|
1108
1182
|
resolved.owner,
|
|
1109
1183
|
resolved.repo,
|
|
1110
1184
|
resolved.skillSlug,
|
|
1111
|
-
|
|
1185
|
+
spec.overwrite ?? true,
|
|
1112
1186
|
resolved.ref ?? spec.version,
|
|
1113
1187
|
spec.contactId,
|
|
1114
1188
|
);
|
|
@@ -1209,6 +1283,10 @@ export async function uninstallSkill(
|
|
|
1209
1283
|
state: "uninstalled",
|
|
1210
1284
|
});
|
|
1211
1285
|
|
|
1286
|
+
// Without this, an uninstalled skill remains queryable in v2 until the
|
|
1287
|
+
// next incidental seed event (enable/disable/install).
|
|
1288
|
+
maybeSeedMemoryV2Skills(getConfig());
|
|
1289
|
+
|
|
1212
1290
|
return { success: true };
|
|
1213
1291
|
} catch (err) {
|
|
1214
1292
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -1250,6 +1328,7 @@ export async function checkSkillUpdates(): Promise<
|
|
|
1250
1328
|
|
|
1251
1329
|
export async function searchSkills(
|
|
1252
1330
|
query: string,
|
|
1331
|
+
limit: number = 25,
|
|
1253
1332
|
): Promise<
|
|
1254
1333
|
| { success: true; skills: SlimSkillResponse[] }
|
|
1255
1334
|
| { success: false; error: string }
|
|
@@ -1290,8 +1369,8 @@ export async function searchSkills(
|
|
|
1290
1369
|
|
|
1291
1370
|
// Search both community registries in parallel (non-fatal on failure)
|
|
1292
1371
|
const [clawhubResult, skillsshResult] = await Promise.allSettled([
|
|
1293
|
-
clawhubSearch(query),
|
|
1294
|
-
searchSkillsRegistry(query,
|
|
1372
|
+
clawhubSearch(query, { limit }),
|
|
1373
|
+
searchSkillsRegistry(query, limit),
|
|
1295
1374
|
]);
|
|
1296
1375
|
|
|
1297
1376
|
let clawhubSkills: SlimSkillResponse[] = [];
|
|
@@ -68,11 +68,14 @@ export function repairHistory(messages: Message[]): RepairResult {
|
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
//
|
|
72
|
-
//
|
|
73
|
-
//
|
|
74
|
-
//
|
|
75
|
-
// ensureToolPairing's split at tool_use
|
|
71
|
+
// Pair server-side tool blocks within the same assistant message.
|
|
72
|
+
// Server tools (e.g. web_search) emit server_tool_use + matching
|
|
73
|
+
// web_search_tool_result. Either side can go missing — the synthetic
|
|
74
|
+
// result is inserted IMMEDIATELY AFTER the orphan server_tool_use (not
|
|
75
|
+
// appended to the end) so ensureToolPairing's split at tool_use
|
|
76
|
+
// boundaries cannot separate the pair. An orphan
|
|
77
|
+
// web_search_tool_result (no preceding server_tool_use) is downgraded
|
|
78
|
+
// to text — Anthropic rejects the request otherwise.
|
|
76
79
|
const serverToolIds = new Set(
|
|
77
80
|
cleanedContent
|
|
78
81
|
.filter(
|
|
@@ -91,11 +94,35 @@ export function repairHistory(messages: Message[]): RepairResult {
|
|
|
91
94
|
orphanedServerIds.add(id);
|
|
92
95
|
}
|
|
93
96
|
}
|
|
97
|
+
const orphanedWebSearchResultIds = new Set<string>();
|
|
98
|
+
for (const id of matchedServerIds) {
|
|
99
|
+
if (!serverToolIds.has(id)) {
|
|
100
|
+
orphanedWebSearchResultIds.add(id);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
94
103
|
|
|
95
104
|
let repairedContent: ContentBlock[];
|
|
96
|
-
if (orphanedServerIds.size > 0) {
|
|
105
|
+
if (orphanedServerIds.size > 0 || orphanedWebSearchResultIds.size > 0) {
|
|
97
106
|
repairedContent = [];
|
|
98
107
|
for (const block of cleanedContent) {
|
|
108
|
+
if (
|
|
109
|
+
block.type === "web_search_tool_result" &&
|
|
110
|
+
orphanedWebSearchResultIds.has(
|
|
111
|
+
(block as { tool_use_id: string }).tool_use_id,
|
|
112
|
+
)
|
|
113
|
+
) {
|
|
114
|
+
repairedContent.push(
|
|
115
|
+
downgradeResult(
|
|
116
|
+
block as {
|
|
117
|
+
type: "web_search_tool_result";
|
|
118
|
+
tool_use_id: string;
|
|
119
|
+
content: unknown;
|
|
120
|
+
},
|
|
121
|
+
),
|
|
122
|
+
);
|
|
123
|
+
stats.orphanToolResultsDowngraded++;
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
99
126
|
repairedContent.push(block);
|
|
100
127
|
if (
|
|
101
128
|
block.type === "server_tool_use" &&
|
|
@@ -15,9 +15,11 @@
|
|
|
15
15
|
* session at a time, and that session is bound to a specific target app.
|
|
16
16
|
* The lock is module-level (`activeAppControlSession`) because the session
|
|
17
17
|
* targets the user's actual desktop application, which is a host-wide
|
|
18
|
-
* resource. It is acquired
|
|
19
|
-
* `(conversationId, app)`)
|
|
20
|
-
*
|
|
18
|
+
* resource. It is acquired optimistically when `app_control_start` is
|
|
19
|
+
* dispatched (storing `(conversationId, app)`) so that the synchronous
|
|
20
|
+
* guard and the asynchronous host round-trip cannot race; it is released
|
|
21
|
+
* when the host returns a non-running state, the dispatch fails, or the
|
|
22
|
+
* owning proxy's `dispose()` fires.
|
|
21
23
|
*
|
|
22
24
|
* `app_control_start` is the only tool that can acquire the lock — the
|
|
23
25
|
* user's medium-risk approval at start time is the consent boundary. All
|
|
@@ -144,12 +146,12 @@ function checkNonStartAuthorization(
|
|
|
144
146
|
// except `stop`, and `stop` short-circuits in conversation-surfaces and
|
|
145
147
|
// does not reach this method in production. A stop reaching here would
|
|
146
148
|
// be a defensive bug — surface it explicitly rather than dispatch.
|
|
147
|
-
const requestedApp = (input as { app?:
|
|
148
|
-
if (requestedApp
|
|
149
|
+
const requestedApp = (input as { app?: unknown }).app;
|
|
150
|
+
if (typeof requestedApp !== "string") {
|
|
149
151
|
return {
|
|
150
152
|
content:
|
|
151
|
-
"Tool input missing required 'app' field; cannot validate
|
|
152
|
-
"the active app-control session.",
|
|
153
|
+
"Tool input missing required string 'app' field; cannot validate " +
|
|
154
|
+
"against the active app-control session.",
|
|
153
155
|
isError: true,
|
|
154
156
|
};
|
|
155
157
|
}
|
|
@@ -222,6 +224,8 @@ export class HostAppControlProxy extends HostProxyBase<
|
|
|
222
224
|
input: HostAppControlInput,
|
|
223
225
|
conversationId: string,
|
|
224
226
|
signal: AbortSignal,
|
|
227
|
+
sourceActorPrincipalId?: string,
|
|
228
|
+
targetClientId?: string,
|
|
225
229
|
): Promise<ToolExecutionResult> {
|
|
226
230
|
if (signal.aborted) {
|
|
227
231
|
return { content: "Aborted", isError: true };
|
|
@@ -235,7 +239,7 @@ export class HostAppControlProxy extends HostProxyBase<
|
|
|
235
239
|
if (input.tool === "start") {
|
|
236
240
|
if (
|
|
237
241
|
activeAppControlSession != null &&
|
|
238
|
-
activeAppControlSession.conversationId !== conversationId
|
|
242
|
+
activeAppControlSession.conversationId !== this.conversationId
|
|
239
243
|
) {
|
|
240
244
|
return {
|
|
241
245
|
content:
|
|
@@ -245,8 +249,21 @@ export class HostAppControlProxy extends HostProxyBase<
|
|
|
245
249
|
isError: true,
|
|
246
250
|
};
|
|
247
251
|
}
|
|
252
|
+
// Acquire optimistically to close the TOCTOU window between this
|
|
253
|
+
// synchronous guard and the asynchronous `dispatchRequest` below. Two
|
|
254
|
+
// concurrent starts from different conversations would otherwise both
|
|
255
|
+
// see `activeAppControlSession == null` and both pass the guard. The
|
|
256
|
+
// lock is released below if dispatch fails or the host returns a
|
|
257
|
+
// non-running state.
|
|
258
|
+
activeAppControlSession = {
|
|
259
|
+
conversationId: this.conversationId,
|
|
260
|
+
app: input.app,
|
|
261
|
+
};
|
|
248
262
|
} else {
|
|
249
|
-
const sessionError = checkNonStartAuthorization(
|
|
263
|
+
const sessionError = checkNonStartAuthorization(
|
|
264
|
+
input,
|
|
265
|
+
this.conversationId,
|
|
266
|
+
);
|
|
250
267
|
if (sessionError != null) {
|
|
251
268
|
return sessionError;
|
|
252
269
|
}
|
|
@@ -258,9 +275,14 @@ export class HostAppControlProxy extends HostProxyBase<
|
|
|
258
275
|
input,
|
|
259
276
|
conversationId,
|
|
260
277
|
signal,
|
|
278
|
+
undefined,
|
|
279
|
+
targetClientId,
|
|
261
280
|
);
|
|
262
281
|
return this.handleSuccess(input, payload);
|
|
263
282
|
} catch (err) {
|
|
283
|
+
if (input.tool === "start") {
|
|
284
|
+
this.releaseSessionIfHeld();
|
|
285
|
+
}
|
|
264
286
|
if (err instanceof HostProxyRequestError) {
|
|
265
287
|
if (err.reason === "timeout") {
|
|
266
288
|
log.warn({ toolName }, "Host app-control proxy request timed out");
|
|
@@ -279,6 +301,12 @@ export class HostAppControlProxy extends HostProxyBase<
|
|
|
279
301
|
}
|
|
280
302
|
}
|
|
281
303
|
|
|
304
|
+
private releaseSessionIfHeld(): void {
|
|
305
|
+
if (activeAppControlSession?.conversationId === this.conversationId) {
|
|
306
|
+
activeAppControlSession = undefined;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
282
310
|
// ---------------------------------------------------------------------------
|
|
283
311
|
// Result handling
|
|
284
312
|
// ---------------------------------------------------------------------------
|
|
@@ -304,13 +332,12 @@ export class HostAppControlProxy extends HostProxyBase<
|
|
|
304
332
|
}
|
|
305
333
|
}
|
|
306
334
|
|
|
307
|
-
//
|
|
308
|
-
//
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
};
|
|
335
|
+
// The optimistic lock acquired in `request()` for `start` stays held
|
|
336
|
+
// only when the host confirms the session is running. Non-running
|
|
337
|
+
// outcomes (missing/minimized) release it so a retry or another
|
|
338
|
+
// conversation can acquire.
|
|
339
|
+
if (input.tool === "start" && payload.state !== "running") {
|
|
340
|
+
this.releaseSessionIfHeld();
|
|
314
341
|
}
|
|
315
342
|
|
|
316
343
|
return this.formatResult(payload, stuck);
|
|
@@ -382,8 +409,6 @@ export class HostAppControlProxy extends HostProxyBase<
|
|
|
382
409
|
*/
|
|
383
410
|
override dispose(): void {
|
|
384
411
|
super.dispose();
|
|
385
|
-
|
|
386
|
-
activeAppControlSession = undefined;
|
|
387
|
-
}
|
|
412
|
+
this.releaseSessionIfHeld();
|
|
388
413
|
}
|
|
389
414
|
}
|