@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
|
@@ -17,8 +17,42 @@ const log = getLogger("web-search");
|
|
|
17
17
|
|
|
18
18
|
const BRAVE_API_URL = "https://api.search.brave.com/res/v1/web/search";
|
|
19
19
|
const PERPLEXITY_API_URL = "https://api.perplexity.ai/chat/completions";
|
|
20
|
+
const TAVILY_API_URL = "https://api.tavily.com/search";
|
|
21
|
+
|
|
22
|
+
type WebSearchProvider = "perplexity" | "brave" | "tavily";
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Arguments passed to every {@link WebSearchAdapter}. The full superset is
|
|
26
|
+
* always supplied; individual adapters ignore the fields they don't use
|
|
27
|
+
* (e.g. Perplexity ignores `count`, `offset`, and `freshness`).
|
|
28
|
+
*/
|
|
29
|
+
interface WebSearchAdapterArgs {
|
|
30
|
+
query: string;
|
|
31
|
+
count: number;
|
|
32
|
+
offset: number;
|
|
33
|
+
freshness: string | undefined;
|
|
34
|
+
apiKey: string;
|
|
35
|
+
signal?: AbortSignal;
|
|
36
|
+
}
|
|
20
37
|
|
|
21
|
-
|
|
38
|
+
/**
|
|
39
|
+
* One built-in web-search provider. Each adapter owns its HTTP shape,
|
|
40
|
+
* freshness mapping, retry behaviour, and result formatter. Registering a
|
|
41
|
+
* new provider becomes a single entry in {@link WEB_SEARCH_ADAPTERS}.
|
|
42
|
+
*/
|
|
43
|
+
interface WebSearchAdapter {
|
|
44
|
+
/** Stable provider identifier (matches config + secret-catalog values). */
|
|
45
|
+
readonly id: WebSearchProvider;
|
|
46
|
+
/** Secret-catalog key used to look up the API key via `getProviderKeyAsync`. */
|
|
47
|
+
readonly secretKey: string;
|
|
48
|
+
/**
|
|
49
|
+
* Position in the fallback chain (lower = earlier). Used when the
|
|
50
|
+
* configured provider has no key and we try other BYOK providers.
|
|
51
|
+
*/
|
|
52
|
+
readonly fallbackOrder: number;
|
|
53
|
+
/** Execute one search against the provider's API. */
|
|
54
|
+
execute(args: WebSearchAdapterArgs): Promise<ToolExecutionResult>;
|
|
55
|
+
}
|
|
22
56
|
|
|
23
57
|
interface BraveSearchResult {
|
|
24
58
|
title: string;
|
|
@@ -42,6 +76,20 @@ interface PerplexityResponse {
|
|
|
42
76
|
citations?: string[];
|
|
43
77
|
}
|
|
44
78
|
|
|
79
|
+
interface TavilySearchResult {
|
|
80
|
+
title?: string;
|
|
81
|
+
url?: string;
|
|
82
|
+
content?: string;
|
|
83
|
+
score?: number;
|
|
84
|
+
raw_content?: string | null;
|
|
85
|
+
favicon?: string;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
interface TavilySearchResponse {
|
|
89
|
+
query?: string;
|
|
90
|
+
results?: TavilySearchResult[];
|
|
91
|
+
}
|
|
92
|
+
|
|
45
93
|
function getWebSearchProvider(): WebSearchProvider {
|
|
46
94
|
const config = getConfig();
|
|
47
95
|
const configured = config.services["web-search"].provider ?? "perplexity";
|
|
@@ -54,12 +102,16 @@ function getWebSearchProvider(): WebSearchProvider {
|
|
|
54
102
|
async function getApiKey(
|
|
55
103
|
provider: WebSearchProvider,
|
|
56
104
|
): Promise<string | undefined> {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
105
|
+
const adapter = WEB_SEARCH_ADAPTERS[provider];
|
|
106
|
+
return (await getProviderKeyAsync(adapter.secretKey)) ?? undefined;
|
|
107
|
+
}
|
|
60
108
|
|
|
61
|
-
|
|
62
|
-
|
|
109
|
+
function fallbackProvidersFor(
|
|
110
|
+
provider: WebSearchProvider,
|
|
111
|
+
): readonly WebSearchProvider[] {
|
|
112
|
+
return WEB_SEARCH_FALLBACK_ORDER.filter(
|
|
113
|
+
(candidate) => candidate !== provider,
|
|
114
|
+
);
|
|
63
115
|
}
|
|
64
116
|
|
|
65
117
|
const CITATION_INSTRUCTION =
|
|
@@ -118,6 +170,54 @@ function formatPerplexityResults(
|
|
|
118
170
|
return lines.join("\n");
|
|
119
171
|
}
|
|
120
172
|
|
|
173
|
+
function formatTavilyResults(
|
|
174
|
+
data: TavilySearchResponse,
|
|
175
|
+
query: string,
|
|
176
|
+
): string {
|
|
177
|
+
const results = data.results ?? [];
|
|
178
|
+
|
|
179
|
+
if (results.length === 0) {
|
|
180
|
+
return `No results found for "${query}".`;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const lines: string[] = [`Web search results for "${query}":\n`];
|
|
184
|
+
|
|
185
|
+
for (let i = 0; i < results.length; i++) {
|
|
186
|
+
const r = results[i];
|
|
187
|
+
const title = r.title?.trim() || r.url?.trim() || "Untitled result";
|
|
188
|
+
lines.push(`${i + 1}. ${title}`);
|
|
189
|
+
if (r.url) {
|
|
190
|
+
lines.push(` URL: ${r.url}`);
|
|
191
|
+
}
|
|
192
|
+
if (r.content) {
|
|
193
|
+
lines.push(` ${r.content}`);
|
|
194
|
+
}
|
|
195
|
+
if (typeof r.score === "number") {
|
|
196
|
+
lines.push(` Score: ${r.score.toFixed(3)}`);
|
|
197
|
+
}
|
|
198
|
+
lines.push("");
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
return lines.join("\n");
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function tavilyTimeRangeForFreshness(
|
|
205
|
+
freshness: string | undefined,
|
|
206
|
+
): "day" | "week" | "month" | "year" | undefined {
|
|
207
|
+
switch (freshness) {
|
|
208
|
+
case "pd":
|
|
209
|
+
return "day";
|
|
210
|
+
case "pw":
|
|
211
|
+
return "week";
|
|
212
|
+
case "pm":
|
|
213
|
+
return "month";
|
|
214
|
+
case "py":
|
|
215
|
+
return "year";
|
|
216
|
+
default:
|
|
217
|
+
return undefined;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
121
221
|
async function executeBraveSearch(
|
|
122
222
|
query: string,
|
|
123
223
|
count: number,
|
|
@@ -281,6 +381,147 @@ async function executePerplexitySearch(
|
|
|
281
381
|
};
|
|
282
382
|
}
|
|
283
383
|
|
|
384
|
+
async function executeTavilySearch(
|
|
385
|
+
query: string,
|
|
386
|
+
count: number,
|
|
387
|
+
freshness: string | undefined,
|
|
388
|
+
apiKey: string,
|
|
389
|
+
signal?: AbortSignal,
|
|
390
|
+
): Promise<ToolExecutionResult> {
|
|
391
|
+
const timeRange = tavilyTimeRangeForFreshness(freshness);
|
|
392
|
+
const body: Record<string, unknown> = {
|
|
393
|
+
query,
|
|
394
|
+
search_depth: "advanced",
|
|
395
|
+
max_results: count,
|
|
396
|
+
};
|
|
397
|
+
if (timeRange) {
|
|
398
|
+
body.time_range = timeRange;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
for (let attempt = 0; attempt <= DEFAULT_MAX_RETRIES; attempt++) {
|
|
402
|
+
const response = await fetch(TAVILY_API_URL, {
|
|
403
|
+
method: "POST",
|
|
404
|
+
headers: {
|
|
405
|
+
"Content-Type": "application/json",
|
|
406
|
+
Authorization: `Bearer ${apiKey}`,
|
|
407
|
+
"X-Client-Source": "vellum-assistant",
|
|
408
|
+
},
|
|
409
|
+
body: JSON.stringify(body),
|
|
410
|
+
signal,
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
if (response.ok) {
|
|
414
|
+
const data = (await response.json()) as TavilySearchResponse;
|
|
415
|
+
return {
|
|
416
|
+
content:
|
|
417
|
+
wrapUntrustedContent(formatTavilyResults(data, query), {
|
|
418
|
+
source: "search",
|
|
419
|
+
sourceDetail: "tavily",
|
|
420
|
+
}) + CITATION_INSTRUCTION,
|
|
421
|
+
isError: false,
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
await response.text();
|
|
426
|
+
|
|
427
|
+
if (response.status === 401 || response.status === 403) {
|
|
428
|
+
return {
|
|
429
|
+
content: "Error: Invalid or expired Tavily API key",
|
|
430
|
+
isError: true,
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
if (response.status === 429 && attempt < DEFAULT_MAX_RETRIES) {
|
|
435
|
+
const delayMs = getHttpRetryDelay(
|
|
436
|
+
response,
|
|
437
|
+
attempt,
|
|
438
|
+
DEFAULT_BASE_DELAY_MS,
|
|
439
|
+
);
|
|
440
|
+
log.warn(
|
|
441
|
+
{ attempt: attempt + 1, delayMs },
|
|
442
|
+
"Tavily Search rate limited, retrying",
|
|
443
|
+
);
|
|
444
|
+
await sleep(delayMs);
|
|
445
|
+
continue;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
log.warn({ status: response.status }, "Tavily Search API error");
|
|
449
|
+
if (response.status === 429) {
|
|
450
|
+
return {
|
|
451
|
+
content:
|
|
452
|
+
"Error: Tavily Search rate limit exceeded after retries. Try again shortly.",
|
|
453
|
+
isError: true,
|
|
454
|
+
};
|
|
455
|
+
}
|
|
456
|
+
return {
|
|
457
|
+
content: `Error: Tavily Search API returned status ${response.status}`,
|
|
458
|
+
isError: true,
|
|
459
|
+
};
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
return {
|
|
463
|
+
content:
|
|
464
|
+
"Error: Tavily Search rate limit exceeded after retries. Try again shortly.",
|
|
465
|
+
isError: true,
|
|
466
|
+
};
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
// ----------------------------------------------------------------------------
|
|
470
|
+
// Adapter registry
|
|
471
|
+
//
|
|
472
|
+
// Each built-in provider exposes a {@link WebSearchAdapter} wrapping its
|
|
473
|
+
// existing execute function. Adding a new provider means adding one adapter
|
|
474
|
+
// const and one entry to `WEB_SEARCH_ADAPTERS` — the dispatcher, fallback
|
|
475
|
+
// chain, and api-key lookup all derive from this table.
|
|
476
|
+
// ----------------------------------------------------------------------------
|
|
477
|
+
|
|
478
|
+
const perplexitySearchAdapter: WebSearchAdapter = {
|
|
479
|
+
id: "perplexity",
|
|
480
|
+
secretKey: "perplexity",
|
|
481
|
+
fallbackOrder: 1,
|
|
482
|
+
execute: ({ query, apiKey, signal }) =>
|
|
483
|
+
executePerplexitySearch(query, apiKey, signal),
|
|
484
|
+
};
|
|
485
|
+
|
|
486
|
+
const braveSearchAdapter: WebSearchAdapter = {
|
|
487
|
+
id: "brave",
|
|
488
|
+
secretKey: "brave",
|
|
489
|
+
fallbackOrder: 2,
|
|
490
|
+
execute: ({ query, count, offset, freshness, apiKey, signal }) =>
|
|
491
|
+
executeBraveSearch(query, count, offset, freshness, apiKey, signal),
|
|
492
|
+
};
|
|
493
|
+
|
|
494
|
+
const tavilySearchAdapter: WebSearchAdapter = {
|
|
495
|
+
id: "tavily",
|
|
496
|
+
secretKey: "tavily",
|
|
497
|
+
fallbackOrder: 3,
|
|
498
|
+
execute: ({ query, count, freshness, apiKey, signal }) =>
|
|
499
|
+
executeTavilySearch(query, count, freshness, apiKey, signal),
|
|
500
|
+
};
|
|
501
|
+
|
|
502
|
+
/**
|
|
503
|
+
* All built-in web-search adapters keyed by provider id. The
|
|
504
|
+
* `Record<WebSearchProvider, ...>` shape forces TypeScript to flag any
|
|
505
|
+
* provider added to the union without a corresponding adapter.
|
|
506
|
+
*/
|
|
507
|
+
const WEB_SEARCH_ADAPTERS: Record<WebSearchProvider, WebSearchAdapter> = {
|
|
508
|
+
perplexity: perplexitySearchAdapter,
|
|
509
|
+
brave: braveSearchAdapter,
|
|
510
|
+
tavily: tavilySearchAdapter,
|
|
511
|
+
};
|
|
512
|
+
|
|
513
|
+
/**
|
|
514
|
+
* Fallback chain derived from {@link WEB_SEARCH_ADAPTERS}. Sorted by each
|
|
515
|
+
* adapter's `fallbackOrder` (lower first). Used when the configured provider
|
|
516
|
+
* has no API key and we try other BYOK providers before giving up.
|
|
517
|
+
*/
|
|
518
|
+
const WEB_SEARCH_FALLBACK_ORDER: readonly WebSearchProvider[] = Object.values(
|
|
519
|
+
WEB_SEARCH_ADAPTERS,
|
|
520
|
+
)
|
|
521
|
+
.slice()
|
|
522
|
+
.sort((a, b) => a.fallbackOrder - b.fallbackOrder)
|
|
523
|
+
.map((adapter) => adapter.id);
|
|
524
|
+
|
|
284
525
|
class WebSearchTool implements Tool {
|
|
285
526
|
name = "web_search";
|
|
286
527
|
description =
|
|
@@ -302,7 +543,7 @@ class WebSearchTool implements Tool {
|
|
|
302
543
|
count: {
|
|
303
544
|
type: "number",
|
|
304
545
|
description:
|
|
305
|
-
"Number of results to return (1-20, default 10).
|
|
546
|
+
"Number of results to return (1-20, default 10). Used with Brave and Tavily providers.",
|
|
306
547
|
},
|
|
307
548
|
offset: {
|
|
308
549
|
type: "number",
|
|
@@ -312,7 +553,7 @@ class WebSearchTool implements Tool {
|
|
|
312
553
|
freshness: {
|
|
313
554
|
type: "string",
|
|
314
555
|
description:
|
|
315
|
-
'Filter by recency: "pd" (past day), "pw" (past week), "pm" (past month), "py" (past year).
|
|
556
|
+
'Filter by recency: "pd" (past day), "pw" (past week), "pm" (past month), "py" (past year). Used with Brave and Tavily providers.',
|
|
316
557
|
},
|
|
317
558
|
},
|
|
318
559
|
required: ["query"],
|
|
@@ -335,22 +576,27 @@ class WebSearchTool implements Tool {
|
|
|
335
576
|
let provider = getWebSearchProvider();
|
|
336
577
|
let apiKey = await getApiKey(provider);
|
|
337
578
|
|
|
338
|
-
// Fallback: if the configured provider has no key, try
|
|
579
|
+
// Fallback: if the configured provider has no key, try other BYOK search
|
|
580
|
+
// providers in a stable order. This preserves existing installs that only
|
|
581
|
+
// configured one search-provider key while still allowing new providers to
|
|
582
|
+
// be selected explicitly.
|
|
339
583
|
if (!apiKey) {
|
|
340
|
-
const fallback
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
if (fallbackKey) {
|
|
584
|
+
for (const fallback of fallbackProvidersFor(provider)) {
|
|
585
|
+
const fallbackKey = await getApiKey(fallback);
|
|
586
|
+
if (!fallbackKey) continue;
|
|
344
587
|
log.info(
|
|
345
588
|
{ from: provider, to: fallback },
|
|
346
589
|
"Configured web search provider has no API key, falling back",
|
|
347
590
|
);
|
|
348
591
|
provider = fallback;
|
|
349
592
|
apiKey = fallbackKey;
|
|
350
|
-
|
|
593
|
+
break;
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
if (!apiKey) {
|
|
351
597
|
return {
|
|
352
598
|
content:
|
|
353
|
-
"Error: No web search API key configured. Set it via `keys set perplexity <key
|
|
599
|
+
"Error: No web search API key configured. Set it via `keys set perplexity <key>`, `keys set brave <key>`, or `keys set tavily <key>`, or configure it from the Settings page under API Keys.",
|
|
354
600
|
isError: true,
|
|
355
601
|
};
|
|
356
602
|
}
|
|
@@ -359,28 +605,25 @@ class WebSearchTool implements Tool {
|
|
|
359
605
|
try {
|
|
360
606
|
log.debug({ query, provider }, "Executing web search");
|
|
361
607
|
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
return await executePerplexitySearch(query, apiKey, context.signal);
|
|
608
|
+
const count =
|
|
609
|
+
typeof input.count === "number"
|
|
610
|
+
? Math.min(20, Math.max(1, Math.round(input.count)))
|
|
611
|
+
: 10;
|
|
612
|
+
const offset =
|
|
613
|
+
typeof input.offset === "number"
|
|
614
|
+
? Math.min(9, Math.max(0, Math.round(input.offset)))
|
|
615
|
+
: 0;
|
|
616
|
+
const freshness =
|
|
617
|
+
typeof input.freshness === "string" ? input.freshness : undefined;
|
|
618
|
+
|
|
619
|
+
return await WEB_SEARCH_ADAPTERS[provider].execute({
|
|
620
|
+
query,
|
|
621
|
+
count,
|
|
622
|
+
offset,
|
|
623
|
+
freshness,
|
|
624
|
+
apiKey,
|
|
625
|
+
signal: context.signal,
|
|
626
|
+
});
|
|
384
627
|
} catch (err) {
|
|
385
628
|
const msg = err instanceof Error ? err.message : String(err);
|
|
386
629
|
log.error({ err }, "Web search failed");
|
|
@@ -9,7 +9,11 @@ import {
|
|
|
9
9
|
} from "../permissions/checker.js";
|
|
10
10
|
import { getAutoApproveThreshold } from "../permissions/gateway-threshold-reader.js";
|
|
11
11
|
import type { PermissionPrompter } from "../permissions/prompter.js";
|
|
12
|
-
import type {
|
|
12
|
+
import type {
|
|
13
|
+
ApprovalMode,
|
|
14
|
+
ApprovalReason,
|
|
15
|
+
RiskThreshold,
|
|
16
|
+
} from "../permissions/types.js";
|
|
13
17
|
import { RiskLevel } from "../permissions/types.js";
|
|
14
18
|
import { getLogger } from "../util/logger.js";
|
|
15
19
|
import { buildPolicyContext } from "./policy-context.js";
|
|
@@ -32,6 +36,11 @@ export type PermissionDecision =
|
|
|
32
36
|
riskLevel: string;
|
|
33
37
|
riskReason: string;
|
|
34
38
|
riskScopeOptions: Array<{ pattern: string; label: string }>;
|
|
39
|
+
riskAllowlistOptions?: Array<{
|
|
40
|
+
label: string;
|
|
41
|
+
description: string;
|
|
42
|
+
pattern: string;
|
|
43
|
+
}>;
|
|
35
44
|
riskDirectoryScopeOptions?: Array<{ scope: string; label: string }>;
|
|
36
45
|
isContainerized?: boolean;
|
|
37
46
|
};
|
|
@@ -51,6 +60,11 @@ export type PermissionDecision =
|
|
|
51
60
|
riskLevel: string;
|
|
52
61
|
riskReason: string;
|
|
53
62
|
riskScopeOptions: Array<{ pattern: string; label: string }>;
|
|
63
|
+
riskAllowlistOptions?: Array<{
|
|
64
|
+
label: string;
|
|
65
|
+
description: string;
|
|
66
|
+
pattern: string;
|
|
67
|
+
}>;
|
|
54
68
|
riskDirectoryScopeOptions?: Array<{ scope: string; label: string }>;
|
|
55
69
|
isContainerized?: boolean;
|
|
56
70
|
};
|
|
@@ -111,7 +125,12 @@ export class PermissionChecker {
|
|
|
111
125
|
? {
|
|
112
126
|
riskLevel: cachedAssessment.riskLevel,
|
|
113
127
|
riskReason: cachedAssessment.reason,
|
|
128
|
+
// Display ladder (regex patterns — internal only, not for save).
|
|
114
129
|
riskScopeOptions: cachedAssessment.scopeOptions,
|
|
130
|
+
// Save ladder (Minimatch globs — what the gateway matches against).
|
|
131
|
+
// Populated for classifiers that produce allowlist options
|
|
132
|
+
// (bash, file, skill); undefined otherwise.
|
|
133
|
+
riskAllowlistOptions: cachedAssessment.allowlistOptions,
|
|
115
134
|
riskDirectoryScopeOptions: cachedAssessment.directoryScopeOptions,
|
|
116
135
|
isContainerized: getIsContainerized(),
|
|
117
136
|
}
|
|
@@ -145,9 +164,11 @@ export class PermissionChecker {
|
|
|
145
164
|
);
|
|
146
165
|
const riskThreshold = conversationThreshold as RiskThreshold;
|
|
147
166
|
|
|
148
|
-
//
|
|
149
|
-
//
|
|
150
|
-
//
|
|
167
|
+
// Non-interactive callers (e.g. non-guardian phone voice) force
|
|
168
|
+
// prompting for side-effect tools even when a trust/allow rule would
|
|
169
|
+
// auto-allow, so their auto-deny handler always sees a
|
|
170
|
+
// confirmation_request. Deny decisions are preserved — only
|
|
171
|
+
// allow → prompt promotion happens here.
|
|
151
172
|
if (
|
|
152
173
|
context.forcePromptSideEffects &&
|
|
153
174
|
result.decision === "allow" &&
|
|
@@ -185,7 +206,9 @@ export class PermissionChecker {
|
|
|
185
206
|
reason: result.reason,
|
|
186
207
|
durationMs,
|
|
187
208
|
});
|
|
188
|
-
const provenance = mapApprovalProvenance("denied", {
|
|
209
|
+
const provenance = mapApprovalProvenance("denied", {
|
|
210
|
+
matchedTrustRuleId,
|
|
211
|
+
});
|
|
189
212
|
return {
|
|
190
213
|
allowed: false,
|
|
191
214
|
decision: "denied",
|
package/src/tools/skills/load.ts
CHANGED
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
import {
|
|
20
20
|
collectAllMissing,
|
|
21
21
|
indexCatalogById,
|
|
22
|
-
|
|
22
|
+
validateIncludeCycles,
|
|
23
23
|
} from "../../skills/include-graph.js";
|
|
24
24
|
import { renderInlineCommands } from "../../skills/inline-command-render.js";
|
|
25
25
|
import { parseToolManifestFile } from "../../skills/tool-manifest.js";
|
|
@@ -204,6 +204,7 @@ export class SkillLoadTool implements Tool {
|
|
|
204
204
|
|
|
205
205
|
// Load catalog for include validation and child metadata output
|
|
206
206
|
let catalogIndex: Map<string, SkillSummary> | undefined;
|
|
207
|
+
let missingIncludedSkillIds: string[] = [];
|
|
207
208
|
if (skill.includes && skill.includes.length > 0) {
|
|
208
209
|
let catalog = loadSkillCatalog();
|
|
209
210
|
catalogIndex = indexCatalogById(catalog);
|
|
@@ -260,19 +261,13 @@ export class SkillLoadTool implements Tool {
|
|
|
260
261
|
catalogIndex = indexCatalogById(catalog);
|
|
261
262
|
}
|
|
262
263
|
|
|
263
|
-
|
|
264
|
-
|
|
264
|
+
missingIncludedSkillIds = [...collectAllMissing(skill.id, catalogIndex)];
|
|
265
|
+
|
|
266
|
+
// Validate cycles fail closed. Missing includes are advisory: the parent
|
|
267
|
+
// skill should still load so the assistant can decide whether to search
|
|
268
|
+
// for and install the suggested dependency.
|
|
269
|
+
const validation = validateIncludeCycles(skill.id, catalogIndex);
|
|
265
270
|
if (!validation.ok) {
|
|
266
|
-
if (validation.error === "missing") {
|
|
267
|
-
return {
|
|
268
|
-
content: `Error: skill "${skill.id}" includes "${
|
|
269
|
-
validation.missingChildId
|
|
270
|
-
}" which was not found (referenced by "${
|
|
271
|
-
validation.parentId
|
|
272
|
-
}" via path: ${validation.path.join(" → ")})`,
|
|
273
|
-
isError: true,
|
|
274
|
-
};
|
|
275
|
-
}
|
|
276
271
|
if (validation.error === "cycle") {
|
|
277
272
|
return {
|
|
278
273
|
content: `Error: skill "${
|
|
@@ -283,10 +278,6 @@ export class SkillLoadTool implements Tool {
|
|
|
283
278
|
isError: true,
|
|
284
279
|
};
|
|
285
280
|
}
|
|
286
|
-
return {
|
|
287
|
-
content: `Error: skill "${skill.id}" has an invalid include graph`,
|
|
288
|
-
isError: true,
|
|
289
|
-
};
|
|
290
281
|
}
|
|
291
282
|
}
|
|
292
283
|
|
|
@@ -444,13 +435,25 @@ export class SkillLoadTool implements Tool {
|
|
|
444
435
|
}
|
|
445
436
|
}
|
|
446
437
|
}
|
|
447
|
-
immediateChildrenSection =
|
|
448
|
-
|
|
449
|
-
|
|
438
|
+
immediateChildrenSection =
|
|
439
|
+
childLines.length > 0
|
|
440
|
+
? `Included Skills (immediate):\n${childLines.join("\n")}`
|
|
441
|
+
: "Included Skills (immediate): none";
|
|
450
442
|
} else {
|
|
451
443
|
immediateChildrenSection = "Included Skills (immediate): none";
|
|
452
444
|
}
|
|
453
445
|
|
|
446
|
+
const missingIncludesSection =
|
|
447
|
+
missingIncludedSkillIds.length > 0
|
|
448
|
+
? [
|
|
449
|
+
"Suggested Included Skills (not loaded):",
|
|
450
|
+
...missingIncludedSkillIds.map(
|
|
451
|
+
(id) =>
|
|
452
|
+
` - ${id}: not installed or unavailable. If this task needs it, search for and install this skill, then load it.`,
|
|
453
|
+
),
|
|
454
|
+
].join("\n")
|
|
455
|
+
: undefined;
|
|
456
|
+
|
|
454
457
|
let versionHash: string | undefined;
|
|
455
458
|
try {
|
|
456
459
|
versionHash = computeSkillVersionHash(skill.directoryPath);
|
|
@@ -512,6 +515,7 @@ export class SkillLoadTool implements Tool {
|
|
|
512
515
|
: []),
|
|
513
516
|
...includedBodies.flatMap((b) => [b, ""]),
|
|
514
517
|
immediateChildrenSection,
|
|
518
|
+
...(missingIncludesSection ? [missingIncludesSection] : []),
|
|
515
519
|
"",
|
|
516
520
|
`<loaded_skill id="${skill.id}"${versionAttr} />`,
|
|
517
521
|
...includeMarkers,
|
|
@@ -71,9 +71,9 @@ export async function executeSubagentSpawn(
|
|
|
71
71
|
|
|
72
72
|
// The subagent runs as its own background conversation, so the agent
|
|
73
73
|
// loop's background-skip rule would zero out any inherited profile.
|
|
74
|
-
// Pass the parent's profile explicitly via `SubagentConfig` so
|
|
75
|
-
//
|
|
76
|
-
//
|
|
74
|
+
// Pass the parent's profile explicitly via `SubagentConfig` so
|
|
75
|
+
// `SubagentManager.spawn` forwards it back into the subagent's
|
|
76
|
+
// `runAgentLoop` call as `options.overrideProfile`.
|
|
77
77
|
//
|
|
78
78
|
// Prefer the per-turn `context.overrideProfile` (populated by
|
|
79
79
|
// `runAgentLoopImpl` from its resolved `turnOverrideProfile`) over a
|
|
@@ -17,7 +17,9 @@ import {
|
|
|
17
17
|
registerBackgroundTool,
|
|
18
18
|
removeBackgroundTool,
|
|
19
19
|
} from "../background-tool-registry.js";
|
|
20
|
+
import { getCredentialMetadataById } from "../credentials/metadata-store.js";
|
|
20
21
|
import { resolveCredentialRef } from "../credentials/resolve.js";
|
|
22
|
+
import { isToolAllowed } from "../credentials/tool-policy.js";
|
|
21
23
|
import {
|
|
22
24
|
getOrStartSession,
|
|
23
25
|
getSessionEnv,
|
|
@@ -214,6 +216,48 @@ class ShellTool implements Tool {
|
|
|
214
216
|
},
|
|
215
217
|
"Credential refs resolved",
|
|
216
218
|
);
|
|
219
|
+
|
|
220
|
+
// -------------------------------------------------------------------
|
|
221
|
+
// Tool policy enforcement — deny any credential that does not
|
|
222
|
+
// explicitly allow "bash" in its allowedTools metadata. This check
|
|
223
|
+
// runs after resolution/dedup and before proxy session creation so
|
|
224
|
+
// that a denied credential never reaches getOrStartSession.
|
|
225
|
+
// -------------------------------------------------------------------
|
|
226
|
+
const deniedCredentials: { credentialId: string; reason: string }[] = [];
|
|
227
|
+
for (const credId of credentialIds) {
|
|
228
|
+
const meta = getCredentialMetadataById(credId);
|
|
229
|
+
if (!meta) {
|
|
230
|
+
// Should not happen — we just resolved these IDs — but fail-closed.
|
|
231
|
+
deniedCredentials.push({
|
|
232
|
+
credentialId: credId,
|
|
233
|
+
reason: "metadata not found",
|
|
234
|
+
});
|
|
235
|
+
continue;
|
|
236
|
+
}
|
|
237
|
+
if (!isToolAllowed("bash", meta.allowedTools)) {
|
|
238
|
+
const tools = meta.allowedTools ?? [];
|
|
239
|
+
deniedCredentials.push({
|
|
240
|
+
credentialId: credId,
|
|
241
|
+
reason:
|
|
242
|
+
tools.length === 0
|
|
243
|
+
? `credential ${meta.service}/${meta.field} has no allowed tools`
|
|
244
|
+
: `credential ${meta.service}/${meta.field} allows [${tools.join(", ")}] but not bash`,
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
if (deniedCredentials.length > 0) {
|
|
249
|
+
log.warn(
|
|
250
|
+
{ denied: deniedCredentials },
|
|
251
|
+
"Credential tool policy denied for proxied bash",
|
|
252
|
+
);
|
|
253
|
+
const reasons = deniedCredentials
|
|
254
|
+
.map((d) => `${d.credentialId}: ${d.reason}`)
|
|
255
|
+
.join("; ");
|
|
256
|
+
return {
|
|
257
|
+
content: `Error: credential tool policy denied — ${reasons}. Each credential must include "bash" in its allowed tools to be used in a proxied shell session.`,
|
|
258
|
+
isError: true,
|
|
259
|
+
};
|
|
260
|
+
}
|
|
217
261
|
} else {
|
|
218
262
|
credentialIds.push(...rawCredentialRefs);
|
|
219
263
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
const TOOL_NAME_ALIASES = new Map<string, string>([
|
|
2
|
+
["create_app", "app_create"],
|
|
3
|
+
]);
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Resolve high-confidence compatibility aliases before active-tool gating.
|
|
7
|
+
* Keep this list narrow: aliases should only cover observed model drift where
|
|
8
|
+
* the canonical target is active for the turn.
|
|
9
|
+
*/
|
|
10
|
+
export function resolveToolNameAlias(
|
|
11
|
+
name: string,
|
|
12
|
+
allowedToolNames?: ReadonlySet<string>,
|
|
13
|
+
): string {
|
|
14
|
+
if (allowedToolNames?.has(name)) return name;
|
|
15
|
+
const canonical = TOOL_NAME_ALIASES.get(name);
|
|
16
|
+
if (!canonical) return name;
|
|
17
|
+
if (allowedToolNames && !allowedToolNames.has(canonical)) return name;
|
|
18
|
+
return canonical;
|
|
19
|
+
}
|
package/src/tools/types.ts
CHANGED
|
@@ -115,8 +115,26 @@ export interface ToolExecutionResult {
|
|
|
115
115
|
riskThreshold?: string;
|
|
116
116
|
/** Whether the daemon is running in a containerized (Docker) environment. */
|
|
117
117
|
isContainerized?: boolean;
|
|
118
|
-
/**
|
|
118
|
+
/**
|
|
119
|
+
* Display-only ladder of scope option labels for the rule editor
|
|
120
|
+
* (narrowest to broadest). The `pattern` field here is a regex-style
|
|
121
|
+
* descriptor used internally by the daemon and is NOT a valid trust
|
|
122
|
+
* rule pattern. Use `riskAllowlistOptions` for the pattern that gets
|
|
123
|
+
* saved as a trust rule.
|
|
124
|
+
*/
|
|
119
125
|
riskScopeOptions?: Array<{ pattern: string; label: string }>;
|
|
126
|
+
/**
|
|
127
|
+
* Allowlist options for the rule editor save path (narrowest to
|
|
128
|
+
* broadest). Each `pattern` is a Minimatch-glob compatible string
|
|
129
|
+
* (e.g. raw command for exact match, `action:<program>` for command
|
|
130
|
+
* wildcards) — what the gateway actually matches against. Mirrors
|
|
131
|
+
* the `allowlistOptions` field on `ConfirmationRequest` SSE events.
|
|
132
|
+
*/
|
|
133
|
+
riskAllowlistOptions?: Array<{
|
|
134
|
+
label: string;
|
|
135
|
+
description: string;
|
|
136
|
+
pattern: string;
|
|
137
|
+
}>;
|
|
120
138
|
/** Directory scope ladder for the rule editor (narrowest to broadest). */
|
|
121
139
|
riskDirectoryScopeOptions?: Array<{ scope: string; label: string }>;
|
|
122
140
|
/**
|