@vellumai/assistant 0.8.0 → 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/Dockerfile +5 -4
- package/README.md +2 -2
- 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 +2 -1
- package/node_modules/@vellumai/skill-host-contracts/src/client.ts +10 -1
- package/openapi.yaml +4847 -1698
- package/package.json +3 -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__/anthropic-provider.test.ts +92 -2
- package/src/__tests__/app-control-flow.test.ts +7 -0
- package/src/__tests__/assistant-events-sse-shed.test.ts +232 -0
- 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-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 +35 -7
- 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 +77 -23
- 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-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-agent-loop-overflow.test.ts +1 -0
- 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 +1 -0
- 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 +21 -1
- package/src/__tests__/conversation-runtime-assembly.test.ts +4 -4
- package/src/__tests__/conversation-slash-commands.test.ts +194 -2
- package/src/__tests__/conversation-surfaces-app-control.test.ts +323 -3
- 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 +23 -3
- 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 +0 -8
- 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__/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 +15 -0
- 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-platform-adapter.test.ts +229 -0
- package/src/__tests__/oauth-cli.test.ts +38 -2009
- 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 +118 -0
- 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-routes-managed-proxy.test.ts +12 -4
- 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-load-feature-flag.test.ts +1 -0
- package/src/__tests__/skill-load-tool.test.ts +2 -4
- 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__/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__/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 +53 -20
- 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-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/approvals/guardian-request-resolvers.ts +32 -87
- package/src/calls/relay-server.ts +35 -0
- package/src/calls/relay-setup-router.ts +36 -0
- package/src/calls/types.ts +1 -0
- package/src/calls/voice-session-bridge.ts +23 -4
- 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 +162 -516
- package/src/cli/commands/notifications.ts +33 -7
- package/src/cli/commands/oauth/apps.ts +292 -261
- package/src/cli/commands/oauth/connect.ts +176 -297
- 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-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 +16 -0
- package/src/config/llm-resolver.ts +16 -1
- package/src/config/loader.ts +76 -14
- 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 +32 -1
- 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 +79 -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 +24 -0
- package/src/daemon/conversation-agent-loop.ts +127 -97
- package/src/daemon/conversation-error.ts +21 -0
- package/src/daemon/conversation-lifecycle.ts +46 -5
- 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 +76 -12
- package/src/daemon/conversation-tool-setup.ts +24 -14
- package/src/daemon/conversation.ts +48 -9
- 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/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 +96 -35
- package/src/daemon/host-proxy-base.ts +13 -1
- package/src/daemon/host-proxy-preactivation.ts +25 -1
- package/src/daemon/identity-helpers.ts +19 -0
- package/src/daemon/lifecycle.ts +42 -43
- package/src/daemon/meet-host-supervisor.ts +15 -15
- package/src/daemon/memory-v2-startup.ts +9 -2
- 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 +9 -1
- 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/export/transcript-formatter.ts +61 -2
- package/src/filing/filing-service.ts +40 -53
- 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 +148 -127
- 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 +55 -6
- 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/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__/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 +39 -14
- package/src/memory/context-search/sources/memory.ts +7 -0
- 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__/remember-description.test.ts +55 -0
- package/src/memory/graph/conversation-graph-memory.ts +76 -5
- package/src/memory/graph/extraction.ts +4 -0
- package/src/memory/graph/graph-memory-state-store.ts +16 -3
- package/src/memory/graph/tool-handlers.ts +17 -7
- package/src/memory/graph/tools.ts +44 -5
- package/src/memory/indexer.ts +17 -0
- package/src/memory/jobs/__tests__/embed-concept-page.test.ts +13 -15
- package/src/memory/jobs/embed-concept-page.ts +45 -9
- package/src/memory/jobs-store.ts +51 -1
- package/src/memory/jobs-worker.ts +52 -3
- 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/published-pages-store.ts +16 -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 +1 -4
- 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 +11 -4
- package/src/memory/v2/__tests__/backfill-jobs.test.ts +38 -21
- package/src/memory/v2/__tests__/consolidation-job.test.ts +123 -135
- 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 +628 -10
- 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 +72 -0
- 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 +45 -1
- package/src/memory/v2/__tests__/skill-store.test.ts +58 -3
- package/src/memory/v2/__tests__/static-context.test.ts +7 -22
- package/src/memory/v2/__tests__/sweep-job.test.ts +95 -0
- 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 +85 -78
- package/src/memory/v2/frontmatter-sweep.ts +91 -0
- package/src/memory/v2/injection.ts +440 -109
- package/src/memory/v2/migration.ts +117 -20
- package/src/memory/v2/page-index.ts +191 -0
- package/src/memory/v2/page-store.ts +3 -0
- package/src/memory/v2/prompts/consolidation.ts +9 -7
- package/src/memory/v2/prompts/router.ts +192 -0
- package/src/memory/v2/qdrant.ts +100 -87
- package/src/memory/v2/reranker.ts +14 -7
- package/src/memory/v2/router.ts +322 -0
- package/src/memory/v2/sim.ts +25 -12
- package/src/memory/v2/skill-store.ts +118 -29
- package/src/memory/v2/static-context.ts +16 -9
- package/src/memory/v2/sweep-job.ts +122 -96
- package/src/memory/v2/types.ts +10 -6
- 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 +15 -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/ipc-risk-types.ts +2 -0
- 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 +19 -3
- 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 +12 -4
- package/src/proactive-artifact/job.ts +4 -0
- 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/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 +303 -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/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/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 +4 -4
- 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 +0 -18
- 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/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 +334 -86
- 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-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/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 -4
- 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-v2-routes.ts +13 -398
- 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/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/memory/register.test.ts +3 -3
- 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 +13 -5
- package/src/tools/subagent/spawn.ts +3 -3
- package/src/tools/terminal/shell.ts +44 -0
- 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/069-seed-onboarding-threads.ts +8 -2
- 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 +22 -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 -498
- 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 -947
- 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 -476
- package/src/memory/graph/compaction.ts +0 -299
- /package/src/cli/{commands → lib}/cache-fs.ts +0 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { readdirSync, readFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { describe, expect, test } from "bun:test";
|
|
4
|
+
|
|
5
|
+
type Registry = {
|
|
6
|
+
flags: Array<{
|
|
7
|
+
key: string;
|
|
8
|
+
scope: string;
|
|
9
|
+
defaultEnabled: boolean;
|
|
10
|
+
}>;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const LEGACY_FLAGGED_RELEASE_NOTE_ALLOWLIST = new Map<string, string>([
|
|
14
|
+
[
|
|
15
|
+
"045-release-notes-meet-avatar.ts",
|
|
16
|
+
"Historical bulletin that already shipped before this guard existed.",
|
|
17
|
+
],
|
|
18
|
+
]);
|
|
19
|
+
|
|
20
|
+
const FLAGGED_FEATURE_LANGUAGE_PATTERNS: Array<{
|
|
21
|
+
label: string;
|
|
22
|
+
pattern: RegExp;
|
|
23
|
+
}> = [
|
|
24
|
+
{ label: "feature flag", pattern: /\bfeature[- ]flag(?:ged)?\b/i },
|
|
25
|
+
{ label: "rollout flag", pattern: /\brollout flag\b/i },
|
|
26
|
+
{ label: "behind ... flag", pattern: /\bbehind\b[^\n.]{0,120}\bflag\b/i },
|
|
27
|
+
{ label: "gated on", pattern: /\bgated on\b/i },
|
|
28
|
+
{ label: "when enabled", pattern: /\bwhen enabled\b/i },
|
|
29
|
+
];
|
|
30
|
+
|
|
31
|
+
function getRepoRoot(): string {
|
|
32
|
+
return join(process.cwd(), "..");
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function getReleaseNoteMigrationFiles(): string[] {
|
|
36
|
+
const migrationsDir = join(process.cwd(), "src", "workspace", "migrations");
|
|
37
|
+
return readdirSync(migrationsDir)
|
|
38
|
+
.filter((fileName) => /^\d+-release-notes-[a-z0-9-]+\.ts$/.test(fileName))
|
|
39
|
+
.sort();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function loadDefaultDisabledAssistantFlagKeys(): string[] {
|
|
43
|
+
const registryPath = join(
|
|
44
|
+
getRepoRoot(),
|
|
45
|
+
"meta",
|
|
46
|
+
"feature-flags",
|
|
47
|
+
"feature-flag-registry.json",
|
|
48
|
+
);
|
|
49
|
+
const registry = JSON.parse(readFileSync(registryPath, "utf-8")) as Registry;
|
|
50
|
+
return registry.flags
|
|
51
|
+
.filter((flag) => flag.scope === "assistant" && !flag.defaultEnabled)
|
|
52
|
+
.map((flag) => flag.key)
|
|
53
|
+
.sort();
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function escapeRegExp(value: string): string {
|
|
57
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function featureFlagKeyPattern(key: string): RegExp {
|
|
61
|
+
const escaped = escapeRegExp(key);
|
|
62
|
+
if (key.includes("-")) {
|
|
63
|
+
return new RegExp(`(?:^|[^a-z0-9-])${escaped}(?:$|[^a-z0-9-])`, "i");
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return new RegExp("[`'\"]" + escaped + "[`'\"]", "i");
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
describe("workspace release-note migrations feature flag guard", () => {
|
|
70
|
+
test("new release-note migrations do not announce default-disabled feature-flagged work", () => {
|
|
71
|
+
const migrationsDir = join(process.cwd(), "src", "workspace", "migrations");
|
|
72
|
+
const defaultDisabledFlagKeys = loadDefaultDisabledAssistantFlagKeys();
|
|
73
|
+
const violations: string[] = [];
|
|
74
|
+
|
|
75
|
+
for (const fileName of getReleaseNoteMigrationFiles()) {
|
|
76
|
+
if (LEGACY_FLAGGED_RELEASE_NOTE_ALLOWLIST.has(fileName)) {
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const content = readFileSync(join(migrationsDir, fileName), "utf-8");
|
|
81
|
+
|
|
82
|
+
for (const { label, pattern } of FLAGGED_FEATURE_LANGUAGE_PATTERNS) {
|
|
83
|
+
if (pattern.test(content)) {
|
|
84
|
+
violations.push(
|
|
85
|
+
`${fileName}: contains flagged-feature language "${label}"`,
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
for (const key of defaultDisabledFlagKeys) {
|
|
91
|
+
if (featureFlagKeyPattern(key).test(content)) {
|
|
92
|
+
violations.push(
|
|
93
|
+
`${fileName}: references default-disabled assistant feature flag "${key}"`,
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (violations.length > 0) {
|
|
100
|
+
const message = [
|
|
101
|
+
"Release-note migrations write to UPDATES.md, which is processed without checking feature flags.",
|
|
102
|
+
"Do not announce features that are still behind default-disabled assistant flags or rollout flags.",
|
|
103
|
+
"Wait until GA and add a new append-only release-note migration with a new marker.",
|
|
104
|
+
"",
|
|
105
|
+
"Violations:",
|
|
106
|
+
...violations.map((violation) => ` - ${violation}`),
|
|
107
|
+
"",
|
|
108
|
+
"If this is an already-shipped historical bulletin, add a narrow entry to",
|
|
109
|
+
"LEGACY_FLAGGED_RELEASE_NOTE_ALLOWLIST in workspace-release-notes-feature-flag-guard.test.ts.",
|
|
110
|
+
].join("\n");
|
|
111
|
+
|
|
112
|
+
expect(violations, message).toEqual([]);
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
});
|
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
* in `afterAll` so the swap doesn't leak into other files.
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
-
type
|
|
14
|
+
type WhichOptions = { PATH?: string; cwd?: string };
|
|
15
|
+
type WhichStub = (command: string, options?: WhichOptions) => string | null;
|
|
15
16
|
|
|
16
17
|
/**
|
|
17
18
|
* Installs a process-global stub for Bun.which. Returns helpers to drive and
|
|
@@ -30,7 +31,8 @@ export function installWhichStub(): {
|
|
|
30
31
|
const originalWhich = Bun.which;
|
|
31
32
|
let whichStub: WhichStub = () => null;
|
|
32
33
|
|
|
33
|
-
(Bun as unknown as { which: WhichStub }).which = (cmd) =>
|
|
34
|
+
(Bun as unknown as { which: WhichStub }).which = (cmd, options) =>
|
|
35
|
+
whichStub(cmd, options);
|
|
34
36
|
|
|
35
37
|
function setWhich(arg: Record<string, string | null> | WhichStub): void {
|
|
36
38
|
whichStub = typeof arg === "function" ? arg : (cmd) => arg[cmd] ?? null;
|
|
@@ -161,6 +161,31 @@ describe("resolveAcpAgent", () => {
|
|
|
161
161
|
expect(result.hint).toBe("npm i -g @zed-industries/codex-acp");
|
|
162
162
|
});
|
|
163
163
|
|
|
164
|
+
test("binary preflight honors agent.env.PATH override (matches spawn env)", () => {
|
|
165
|
+
// The actual spawn merges `agentConfig.env` into the child env, so a
|
|
166
|
+
// per-agent PATH override wins over the daemon's PATH. The preflight
|
|
167
|
+
// must use the same PATH or it will reject configs that would have
|
|
168
|
+
// spawned successfully.
|
|
169
|
+
config.setConfig({
|
|
170
|
+
agents: {
|
|
171
|
+
custom: {
|
|
172
|
+
command: "my-binary",
|
|
173
|
+
args: [],
|
|
174
|
+
env: { PATH: "/opt/custom/bin" },
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
});
|
|
178
|
+
which.setWhich((cmd, options) =>
|
|
179
|
+
cmd === "my-binary" && options?.PATH === "/opt/custom/bin"
|
|
180
|
+
? "/opt/custom/bin/my-binary"
|
|
181
|
+
: null,
|
|
182
|
+
);
|
|
183
|
+
|
|
184
|
+
const result = resolveAcpAgent("custom");
|
|
185
|
+
|
|
186
|
+
expect(result.ok).toBe(true);
|
|
187
|
+
});
|
|
188
|
+
|
|
164
189
|
test("ok result when user config provides agent and binary is on PATH", () => {
|
|
165
190
|
config.setConfig({
|
|
166
191
|
agents: {
|
package/src/acp/resolve-agent.ts
CHANGED
|
@@ -65,6 +65,17 @@ function installHintFor(command: string): string {
|
|
|
65
65
|
: `Install '${command}' and ensure it is on PATH.`;
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
+
/**
|
|
69
|
+
* Resolve the binary using the same PATH the spawn will see. `AcpAgentProcess`
|
|
70
|
+
* spawns with `{ ...process.env, ...config.env }`, so a per-agent `env.PATH`
|
|
71
|
+
* override wins over the daemon's PATH. Mirror that here so a config that
|
|
72
|
+
* relies on a custom PATH to locate the binary doesn't fail preflight.
|
|
73
|
+
*/
|
|
74
|
+
function findAgentBinary(agent: AcpAgentConfig): string | null {
|
|
75
|
+
const PATH = agent.env?.PATH ?? process.env.PATH;
|
|
76
|
+
return Bun.which(agent.command, PATH ? { PATH } : undefined);
|
|
77
|
+
}
|
|
78
|
+
|
|
68
79
|
/**
|
|
69
80
|
* Resolve an id against user config first, then bundled defaults. Returns the
|
|
70
81
|
* resolved entry plus a `source` label so callers can surface "user override
|
|
@@ -122,7 +133,7 @@ export function resolveAcpAgent(id: string): ResolveAcpAgentResult {
|
|
|
122
133
|
}
|
|
123
134
|
|
|
124
135
|
const { agent } = found;
|
|
125
|
-
if (!
|
|
136
|
+
if (!findAgentBinary(agent)) {
|
|
126
137
|
return {
|
|
127
138
|
ok: false,
|
|
128
139
|
reason: "binary_not_found",
|
|
@@ -157,7 +168,7 @@ export function listAcpAgents(): {
|
|
|
157
168
|
const agents: AcpAgentEntry[] = mergedAgentIds(userAgents).map((id) => {
|
|
158
169
|
// Non-null: ids come from `mergedAgentIds` so the lookup always resolves.
|
|
159
170
|
const { agent, source } = lookupAgent(userAgents, id)!;
|
|
160
|
-
const available =
|
|
171
|
+
const available = findAgentBinary(agent) !== null;
|
|
161
172
|
const entry: AcpAgentEntry = {
|
|
162
173
|
id,
|
|
163
174
|
command: agent.command,
|
|
@@ -278,12 +278,26 @@ export class AcpSessionManager {
|
|
|
278
278
|
|
|
279
279
|
/**
|
|
280
280
|
* Kills the agent process and removes the session from tracking.
|
|
281
|
+
*
|
|
282
|
+
* Persists the buffered event log first so abort paths
|
|
283
|
+
* (`executeAcpAbort`, daemon shutdown) don't drop history. If the
|
|
284
|
+
* session is still in a non-terminal state, mark it cancelled so the
|
|
285
|
+
* persisted row reflects reality. The in-flight prompt's then/catch
|
|
286
|
+
* handler will short-circuit after teardown removes the entry.
|
|
281
287
|
*/
|
|
282
288
|
close(acpSessionId: string): void {
|
|
283
289
|
const entry = this.sessions.get(acpSessionId);
|
|
284
290
|
if (!entry) {
|
|
285
291
|
throw new Error(`ACP session "${acpSessionId}" not found`);
|
|
286
292
|
}
|
|
293
|
+
if (
|
|
294
|
+
entry.state.status === "running" ||
|
|
295
|
+
entry.state.status === "initializing"
|
|
296
|
+
) {
|
|
297
|
+
entry.state.status = "cancelled";
|
|
298
|
+
entry.state.completedAt = Date.now();
|
|
299
|
+
}
|
|
300
|
+
this.persistTerminal(acpSessionId, entry);
|
|
287
301
|
this.teardownSession(acpSessionId, entry);
|
|
288
302
|
}
|
|
289
303
|
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
|
|
14
14
|
import { answerCall } from "../calls/call-domain.js";
|
|
15
15
|
import { findContactChannel } from "../contacts/contact-store.js";
|
|
16
|
+
import { upsertContactChannel } from "../contacts/contacts-write.js";
|
|
16
17
|
import { findConversation } from "../daemon/conversation-store.js";
|
|
17
|
-
import { emitFeedEvent } from "../home/emit-feed-event.js";
|
|
18
18
|
import {
|
|
19
19
|
type CanonicalGuardianRequest,
|
|
20
20
|
getCanonicalGuardianRequest,
|
|
@@ -119,6 +119,12 @@ export type ResolverResult =
|
|
|
119
119
|
applied: true;
|
|
120
120
|
grantMinted?: boolean;
|
|
121
121
|
guardianReplyText?: string;
|
|
122
|
+
activatedContact?: {
|
|
123
|
+
sourceChannel: string;
|
|
124
|
+
externalUserId: string;
|
|
125
|
+
externalChatId?: string;
|
|
126
|
+
displayName?: string;
|
|
127
|
+
};
|
|
122
128
|
}
|
|
123
129
|
| { ok: false; reason: string };
|
|
124
130
|
|
|
@@ -206,21 +212,6 @@ const pendingInteractionResolver: GuardianRequestResolver = {
|
|
|
206
212
|
ctx.emissionContext,
|
|
207
213
|
);
|
|
208
214
|
|
|
209
|
-
const approved = decision.action !== "reject";
|
|
210
|
-
void emitFeedEvent({
|
|
211
|
-
source: "assistant",
|
|
212
|
-
title: approved ? "Tool Request Approved" : "Tool Request Denied",
|
|
213
|
-
summary: `${approved ? "Approved" : "Denied"} access to ${request.toolName ?? "unknown tool"}.`,
|
|
214
|
-
dedupKey: `guardian-approval:${request.id}`,
|
|
215
|
-
urgency: approved ? undefined : "medium",
|
|
216
|
-
detailPanel: { kind: "toolPermission" },
|
|
217
|
-
}).catch((err) => {
|
|
218
|
-
log.warn(
|
|
219
|
-
{ err, requestId: request.id },
|
|
220
|
-
"Failed to emit guardian approval feed event",
|
|
221
|
-
);
|
|
222
|
-
});
|
|
223
|
-
|
|
224
215
|
log.info(
|
|
225
216
|
{
|
|
226
217
|
event: "resolver_tool_approval_applied",
|
|
@@ -467,20 +458,6 @@ const accessRequestResolver: GuardianRequestResolver = {
|
|
|
467
458
|
}
|
|
468
459
|
}
|
|
469
460
|
|
|
470
|
-
void emitFeedEvent({
|
|
471
|
-
source: "assistant",
|
|
472
|
-
title: "Access Request Denied",
|
|
473
|
-
summary: `Denied access request.`,
|
|
474
|
-
dedupKey: `guardian-access:${request.id}`,
|
|
475
|
-
urgency: "medium",
|
|
476
|
-
detailPanel: { kind: "permissionChat" },
|
|
477
|
-
}).catch((err) => {
|
|
478
|
-
log.warn(
|
|
479
|
-
{ err, requestId: request.id },
|
|
480
|
-
"Failed to emit access request feed event",
|
|
481
|
-
);
|
|
482
|
-
});
|
|
483
|
-
|
|
484
461
|
return {
|
|
485
462
|
ok: true,
|
|
486
463
|
applied: true,
|
|
@@ -496,6 +473,21 @@ const accessRequestResolver: GuardianRequestResolver = {
|
|
|
496
473
|
// a verification session. The caller is already on the line and the
|
|
497
474
|
// relay server's in-call wait loop will detect the approved status.
|
|
498
475
|
if (channel === "phone") {
|
|
476
|
+
try {
|
|
477
|
+
upsertContactChannel({
|
|
478
|
+
sourceChannel: "phone",
|
|
479
|
+
externalUserId: requesterExternalUserId,
|
|
480
|
+
externalChatId: requesterChatId,
|
|
481
|
+
status: "active",
|
|
482
|
+
policy: "allow",
|
|
483
|
+
});
|
|
484
|
+
} catch (err) {
|
|
485
|
+
log.error(
|
|
486
|
+
{ err, requesterExternalUserId },
|
|
487
|
+
"Access request resolver: failed to activate voice caller as trusted contact",
|
|
488
|
+
);
|
|
489
|
+
}
|
|
490
|
+
|
|
499
491
|
log.info(
|
|
500
492
|
{
|
|
501
493
|
event: "resolver_access_request_voice_approved",
|
|
@@ -506,21 +498,16 @@ const accessRequestResolver: GuardianRequestResolver = {
|
|
|
506
498
|
"Access request resolver: voice approval — direct trusted-contact activation (no verification session)",
|
|
507
499
|
);
|
|
508
500
|
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
"Failed to emit access request feed event",
|
|
520
|
-
);
|
|
521
|
-
});
|
|
522
|
-
|
|
523
|
-
return { ok: true, applied: true };
|
|
501
|
+
return {
|
|
502
|
+
ok: true,
|
|
503
|
+
applied: true,
|
|
504
|
+
activatedContact: {
|
|
505
|
+
sourceChannel: "phone",
|
|
506
|
+
externalUserId: requesterExternalUserId,
|
|
507
|
+
...(requesterChatId ? { externalChatId: requesterChatId } : {}),
|
|
508
|
+
...(requesterDisplayName ? { displayName: requesterDisplayName } : {}),
|
|
509
|
+
},
|
|
510
|
+
};
|
|
524
511
|
}
|
|
525
512
|
|
|
526
513
|
// Non-voice approvals: mint an identity-bound verification session so the
|
|
@@ -738,20 +725,6 @@ const accessRequestResolver: GuardianRequestResolver = {
|
|
|
738
725
|
? `Access approved for ${requesterLabel}. Give them this verification code: \`${session.secret}\`. The code expires in 10 minutes.`
|
|
739
726
|
: `Access approved for ${requesterLabel}. Give them this verification code: \`${session.secret}\`. The code expires in 10 minutes. I could not notify them automatically, so please tell them to send the code manually.`;
|
|
740
727
|
|
|
741
|
-
void emitFeedEvent({
|
|
742
|
-
source: "assistant",
|
|
743
|
-
title: "Access Request Approved",
|
|
744
|
-
summary: `Granted access request.`,
|
|
745
|
-
dedupKey: `guardian-access:${request.id}`,
|
|
746
|
-
urgency: undefined,
|
|
747
|
-
detailPanel: { kind: "permissionChat" },
|
|
748
|
-
}).catch((err) => {
|
|
749
|
-
log.warn(
|
|
750
|
-
{ err, requestId: request.id },
|
|
751
|
-
"Failed to emit access request feed event",
|
|
752
|
-
);
|
|
753
|
-
});
|
|
754
|
-
|
|
755
728
|
return {
|
|
756
729
|
ok: true,
|
|
757
730
|
applied: true,
|
|
@@ -825,20 +798,6 @@ const toolGrantRequestResolver: GuardianRequestResolver = {
|
|
|
825
798
|
}
|
|
826
799
|
}
|
|
827
800
|
|
|
828
|
-
void emitFeedEvent({
|
|
829
|
-
source: "assistant",
|
|
830
|
-
title: "Tool Grant Denied",
|
|
831
|
-
summary: `Denied grant request for ${request.toolName ?? "unknown tool"}.`,
|
|
832
|
-
dedupKey: `guardian-grant:${request.id}`,
|
|
833
|
-
urgency: "medium",
|
|
834
|
-
detailPanel: { kind: "toolPermission" },
|
|
835
|
-
}).catch((err) => {
|
|
836
|
-
log.warn(
|
|
837
|
-
{ err, requestId: request.id },
|
|
838
|
-
"Failed to emit tool grant denial feed event",
|
|
839
|
-
);
|
|
840
|
-
});
|
|
841
|
-
|
|
842
801
|
return { ok: true, applied: true };
|
|
843
802
|
}
|
|
844
803
|
|
|
@@ -936,20 +895,6 @@ const toolGrantRequestResolver: GuardianRequestResolver = {
|
|
|
936
895
|
}
|
|
937
896
|
}
|
|
938
897
|
|
|
939
|
-
void emitFeedEvent({
|
|
940
|
-
source: "assistant",
|
|
941
|
-
title: "Tool Grant Approved",
|
|
942
|
-
summary: `Approved grant request for ${request.toolName ?? "unknown tool"}.`,
|
|
943
|
-
dedupKey: `guardian-grant:${request.id}`,
|
|
944
|
-
urgency: undefined,
|
|
945
|
-
detailPanel: { kind: "toolPermission" },
|
|
946
|
-
}).catch((err) => {
|
|
947
|
-
log.warn(
|
|
948
|
-
{ err, requestId: request.id },
|
|
949
|
-
"Failed to emit tool grant approval feed event",
|
|
950
|
-
);
|
|
951
|
-
});
|
|
952
|
-
|
|
953
898
|
return { ok: true, applied: true, grantMinted: false };
|
|
954
899
|
},
|
|
955
900
|
};
|
|
@@ -612,6 +612,12 @@ export class RelayConnection {
|
|
|
612
612
|
);
|
|
613
613
|
this.startNameCapture(outcome.assistantId, outcome.fromNumber);
|
|
614
614
|
return;
|
|
615
|
+
case "unverified_caller":
|
|
616
|
+
await this.handleUnverifiedCaller(
|
|
617
|
+
outcome.displayName,
|
|
618
|
+
outcome.isGuardian,
|
|
619
|
+
);
|
|
620
|
+
return;
|
|
615
621
|
case "verification":
|
|
616
622
|
if (this.controller && resolved.actorTrust.trustClass !== "unknown") {
|
|
617
623
|
this.controller.setTrustContext(
|
|
@@ -669,6 +675,35 @@ export class RelayConnection {
|
|
|
669
675
|
});
|
|
670
676
|
}
|
|
671
677
|
|
|
678
|
+
/** Speak verification guidance to a known-but-unverified caller, then disconnect. */
|
|
679
|
+
private async handleUnverifiedCaller(
|
|
680
|
+
displayName: string,
|
|
681
|
+
isGuardian: boolean,
|
|
682
|
+
): Promise<void> {
|
|
683
|
+
recordCallEvent(this.callSessionId, "inbound_acl_unverified_caller", {
|
|
684
|
+
callSessionId: this.callSessionId,
|
|
685
|
+
isGuardian,
|
|
686
|
+
});
|
|
687
|
+
this.connectionState = "disconnecting";
|
|
688
|
+
updateCallSession(this.callSessionId, {
|
|
689
|
+
status: "failed",
|
|
690
|
+
endedAt: Date.now(),
|
|
691
|
+
lastError: "Inbound voice ACL: caller channel unverified",
|
|
692
|
+
});
|
|
693
|
+
const action = isGuardian
|
|
694
|
+
? `To verify, open your assistant's contacts page, click Verify next to the phone channel, ` +
|
|
695
|
+
`and follow the prompts. Then call back once the verification session is active.`
|
|
696
|
+
: `Please reach out to the account guardian to start a new verification session, ` +
|
|
697
|
+
`then call back once the verification session is active.`;
|
|
698
|
+
const message =
|
|
699
|
+
`This number is registered as ${displayName}'s phone but has not been verified yet. ` +
|
|
700
|
+
action;
|
|
701
|
+
await speakSystemPrompt(this, message);
|
|
702
|
+
setTimeout(() => {
|
|
703
|
+
this.endSession("Inbound voice ACL: caller channel unverified");
|
|
704
|
+
}, getTtsPlaybackDelayMs());
|
|
705
|
+
}
|
|
706
|
+
|
|
672
707
|
/** Deny an inbound call with a TTS message and schedule disconnect. */
|
|
673
708
|
private async denyInboundCall(
|
|
674
709
|
from: string,
|
|
@@ -56,6 +56,13 @@ type SetupOutcome =
|
|
|
56
56
|
guardianName: string | null;
|
|
57
57
|
}
|
|
58
58
|
| { action: "name_capture"; assistantId: string; fromNumber: string }
|
|
59
|
+
| {
|
|
60
|
+
action: "unverified_caller";
|
|
61
|
+
assistantId: string;
|
|
62
|
+
fromNumber: string;
|
|
63
|
+
displayName: string;
|
|
64
|
+
isGuardian: boolean;
|
|
65
|
+
}
|
|
59
66
|
| { action: "deny"; message: string; logReason: string };
|
|
60
67
|
|
|
61
68
|
// ── Resolved context produced alongside the outcome ──────────────────
|
|
@@ -234,6 +241,35 @@ export function routeSetup(ctx: SetupContext): {
|
|
|
234
241
|
};
|
|
235
242
|
}
|
|
236
243
|
|
|
244
|
+
// Known caller whose channel hasn't passed verification yet —
|
|
245
|
+
// mirrors the gateway's pre-intercept (twilio-voice-webhook.ts) so
|
|
246
|
+
// calls slipping past it (e.g. canonicalization mismatch between
|
|
247
|
+
// gateway and assistant DBs) still get useful guidance instead of
|
|
248
|
+
// the "I don't recognize this number" name-capture script.
|
|
249
|
+
const unverifiedStatuses = new Set(["unverified", "pending"]);
|
|
250
|
+
const memberChannel = actorTrust.memberRecord?.channel;
|
|
251
|
+
if (memberChannel && unverifiedStatuses.has(memberChannel.status)) {
|
|
252
|
+
log.info(
|
|
253
|
+
{
|
|
254
|
+
callSessionId: ctx.callSessionId,
|
|
255
|
+
from: ctx.from,
|
|
256
|
+
channelId: memberChannel.id,
|
|
257
|
+
channelStatus: memberChannel.status,
|
|
258
|
+
},
|
|
259
|
+
"Inbound voice ACL: known but unverified caller — returning verification guidance",
|
|
260
|
+
);
|
|
261
|
+
return {
|
|
262
|
+
outcome: {
|
|
263
|
+
action: "unverified_caller",
|
|
264
|
+
assistantId,
|
|
265
|
+
fromNumber: ctx.from,
|
|
266
|
+
displayName: actorTrust.memberRecord!.contact.displayName,
|
|
267
|
+
isGuardian: actorTrust.memberRecord!.contact.role === "guardian",
|
|
268
|
+
},
|
|
269
|
+
resolved,
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
|
|
237
273
|
// Unknown caller — name capture flow
|
|
238
274
|
log.info(
|
|
239
275
|
{
|
package/src/calls/types.ts
CHANGED
|
@@ -33,6 +33,7 @@ export type CallEventType =
|
|
|
33
33
|
| "inbound_acl_name_capture_started"
|
|
34
34
|
| "inbound_acl_name_captured"
|
|
35
35
|
| "inbound_acl_name_capture_timeout"
|
|
36
|
+
| "inbound_acl_unverified_caller"
|
|
36
37
|
| "inbound_acl_access_approved"
|
|
37
38
|
| "inbound_acl_access_denied"
|
|
38
39
|
| "inbound_acl_access_timeout"
|
|
@@ -293,7 +293,11 @@ export async function startVoiceTurn(
|
|
|
293
293
|
onMessageComplete: (msg) => {
|
|
294
294
|
opts.onComplete?.();
|
|
295
295
|
opts.callbacks?.message_complete?.(msg);
|
|
296
|
-
if (
|
|
296
|
+
if (
|
|
297
|
+
msg.type === "message_complete" &&
|
|
298
|
+
msg.messageId &&
|
|
299
|
+
msg.source !== "aux"
|
|
300
|
+
) {
|
|
297
301
|
try {
|
|
298
302
|
opts.callbacks?.persisted_assistant_message_id?.(msg.messageId);
|
|
299
303
|
} catch (err) {
|
|
@@ -314,7 +318,8 @@ export async function startVoiceTurn(
|
|
|
314
318
|
|
|
315
319
|
// Phone voice has no interactive permission/secret UI, so apply explicit
|
|
316
320
|
// per-role policies by default. Local live voice opts into the normal
|
|
317
|
-
// client approval path instead.
|
|
321
|
+
// client approval path instead. Side-effect double-defense is wired
|
|
322
|
+
// below at the conversation-configure point.
|
|
318
323
|
const trustClass = opts.trustContext?.trustClass;
|
|
319
324
|
const isGuardian = trustClass === "guardian";
|
|
320
325
|
const approvalMode = opts.approvalMode ?? "phone-call";
|
|
@@ -386,7 +391,13 @@ export async function startVoiceTurn(
|
|
|
386
391
|
}
|
|
387
392
|
}
|
|
388
393
|
|
|
389
|
-
//
|
|
394
|
+
// Non-guardian phone voice forces side-effect tools to prompt so the
|
|
395
|
+
// auto-deny handler below reliably sees a confirmation_request. Without
|
|
396
|
+
// this, a broad allow trust rule (e.g. wildcard bash) would let
|
|
397
|
+
// side-effect tools execute without ever emitting an event for the
|
|
398
|
+
// auto-deny / scoped-grant handler to intercept.
|
|
399
|
+
conversation.forcePromptSideEffects =
|
|
400
|
+
!isGuardian && !usesLocalInteractiveApprovals;
|
|
390
401
|
conversation.setAssistantId(opts.assistantId ?? DAEMON_INTERNAL_ASSISTANT_ID);
|
|
391
402
|
conversation.callSessionId = voiceSessionId;
|
|
392
403
|
conversation.setTrustContext(opts.trustContext ?? null);
|
|
@@ -528,7 +539,14 @@ export async function startVoiceTurn(
|
|
|
528
539
|
return;
|
|
529
540
|
}
|
|
530
541
|
} else if (msg.type === "secret_request") {
|
|
531
|
-
|
|
542
|
+
if (usesLocalInteractiveApprovals) {
|
|
543
|
+
// Local live voice runs alongside the desktop client, which has a
|
|
544
|
+
// secret-entry UI (SecretPromptManager). Forward the broadcast and
|
|
545
|
+
// let the prompter's existing registration handle the response.
|
|
546
|
+
broadcastMessage(msg);
|
|
547
|
+
return;
|
|
548
|
+
}
|
|
549
|
+
// Phone voice has no secret-entry UI, so resolve immediately.
|
|
532
550
|
log.info(
|
|
533
551
|
{ turnId, service: msg.service, field: msg.field },
|
|
534
552
|
"Auto-resolving secret request for voice turn (no secret-entry UI)",
|
|
@@ -549,6 +567,7 @@ export async function startVoiceTurn(
|
|
|
549
567
|
conversation.setAssistantId("self");
|
|
550
568
|
conversation.setVoiceCallControlPrompt(null);
|
|
551
569
|
conversation.callSessionId = undefined;
|
|
570
|
+
conversation.forcePromptSideEffects = false;
|
|
552
571
|
// Reset the conversation's client callback to a no-op so the stale
|
|
553
572
|
// closure doesn't intercept events from future turns on the same conversation.
|
|
554
573
|
conversation.updateClient(() => {}, true);
|
package/src/channels/config.ts
CHANGED
|
@@ -11,7 +11,8 @@ import type { ChannelId } from "./types.js";
|
|
|
11
11
|
export type ConversationStrategy =
|
|
12
12
|
| "start_new_conversation"
|
|
13
13
|
| "continue_existing_conversation"
|
|
14
|
-
| "not_deliverable"
|
|
14
|
+
| "not_deliverable"
|
|
15
|
+
| "push_only";
|
|
15
16
|
|
|
16
17
|
export interface ChannelInvitePolicy {
|
|
17
18
|
/** Whether inbound invite code redemption is supported on this channel. */
|
|
@@ -72,6 +73,18 @@ const CHANNEL_POLICIES = {
|
|
|
72
73
|
codeRedemptionEnabled: true,
|
|
73
74
|
},
|
|
74
75
|
},
|
|
76
|
+
platform: {
|
|
77
|
+
notification: {
|
|
78
|
+
deliveryEnabled: true,
|
|
79
|
+
// Platform is a push-only relay — conversations are owned by the vellum
|
|
80
|
+
// channel. push_only skips pairDeliveryWithConversation without implying
|
|
81
|
+
// the channel is non-deliverable (which not_deliverable would).
|
|
82
|
+
conversationStrategy: "push_only",
|
|
83
|
+
},
|
|
84
|
+
invite: {
|
|
85
|
+
codeRedemptionEnabled: false,
|
|
86
|
+
},
|
|
87
|
+
},
|
|
75
88
|
phone: {
|
|
76
89
|
notification: {
|
|
77
90
|
deliveryEnabled: false,
|