@vellumai/assistant 0.12.1-dev.202609141913.5e16607 → 0.12.1-staging.2
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 +0 -4
- package/ARCHITECTURE.md +12 -11
- package/docs/architecture/turn-actor.md +8 -15
- package/docs/guardian-request-flow.md +0 -16
- package/openapi.yaml +49 -291
- package/package.json +1 -1
- package/src/__tests__/always-loaded-tools-guard.test.ts +10 -18
- package/src/__tests__/app-compiler.test.ts +0 -6
- package/src/__tests__/app-control-tool-schemas.test.ts +2 -5
- package/src/__tests__/app-dir-path-guard.test.ts +3 -1
- package/src/__tests__/app-source-watcher.test.ts +218 -0
- package/src/{calls/__tests__ → __tests__}/call-controller.test.ts +82 -503
- package/src/__tests__/computer-use-skill-proxy-bridge.test.ts +2 -5
- package/src/__tests__/computer-use-tools.test.ts +5 -17
- package/src/__tests__/config-schema-cmd.test.ts +2 -2
- package/src/__tests__/config-schema.test.ts +29 -28
- package/src/__tests__/config-watcher-skill-reseed.test.ts +359 -0
- package/src/__tests__/config-watcher.test.ts +8 -23
- package/src/__tests__/connection-model-compat.test.ts +2 -2
- package/src/__tests__/conversation-key-store-disk-view.test.ts +1 -1
- package/src/__tests__/conversation-pairing.test.ts +0 -26
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +10 -4
- package/src/__tests__/conversation-queue.test.ts +207 -48
- package/src/__tests__/conversation-retry-discard.test.ts +1 -54
- package/src/__tests__/conversation-skill-tools.test.ts +0 -27
- package/src/__tests__/conversation-surfaces-app-control.test.ts +3 -8
- package/src/__tests__/conversation-surfaces-task-progress.test.ts +0 -67
- package/src/__tests__/conversation-title-service.test.ts +10 -14
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +5 -3
- package/src/__tests__/conversation-tool-setup-attribution.test.ts +0 -51
- package/src/__tests__/credential-record-retire.test.ts +1 -171
- package/src/__tests__/credential-routes.test.ts +3 -212
- package/src/__tests__/credential-security-invariants.test.ts +2 -4
- package/src/__tests__/cu-unified-flow.test.ts +2 -8
- package/src/__tests__/document-sync-tags.test.ts +0 -25
- package/src/__tests__/drain-kick-guard.test.ts +2 -0
- package/src/__tests__/drain-requeue-on-contention.test.ts +6 -0
- package/src/__tests__/evict-conversations-for-reload.test.ts +1 -1
- package/src/__tests__/host-bash-proxy.test.ts +45 -26
- package/src/__tests__/host-browser-proxy.test.ts +17 -6
- package/src/__tests__/host-file-proxy-targeted.test.ts +0 -23
- package/src/__tests__/host-file-proxy.test.ts +23 -11
- package/src/__tests__/host-transfer-proxy-targeted.test.ts +9 -30
- package/src/__tests__/llm-catalog-parity.test.ts +0 -25
- package/src/__tests__/mcp-auth-routes.test.ts +9 -6
- package/src/__tests__/mcp-config-secret-boundary.test.ts +136 -78
- package/src/__tests__/mcp-health-check.test.ts +11 -8
- package/src/__tests__/mcp-list-plugin-servers.test.ts +10 -8
- package/src/{calls/__tests__ → __tests__}/media-stream-audio-transcode.test.ts +1 -1
- package/src/{calls/__tests__ → __tests__}/media-stream-output.test.ts +8 -37
- package/src/{calls/__tests__ → __tests__}/media-stream-parser.test.ts +1 -1
- package/src/{calls/__tests__ → __tests__}/media-stream-server-integration.test.ts +57 -150
- package/src/{calls/__tests__ → __tests__}/media-stream-stt-session.test.ts +5 -5
- package/src/{calls/__tests__ → __tests__}/media-turn-detector.test.ts +1 -1
- package/src/__tests__/messages-after-tiebreaker.test.ts +0 -91
- package/src/__tests__/messages-read-boundary-guard.test.ts +1 -1
- package/src/__tests__/messaging-send-tool.test.ts +548 -355
- package/src/__tests__/model-intents.test.ts +0 -3
- package/src/__tests__/notification-vellum-adapter.test.ts +2 -85
- package/src/__tests__/outlook-messaging-provider.test.ts +6 -6
- package/src/__tests__/platform-callback-registration.test.ts +16 -8
- package/src/__tests__/platform-client-verify-credential.test.ts +0 -2
- package/src/__tests__/plugin-import-boundary-guard.test.ts +0 -13
- package/src/__tests__/script-proxy-certs.test.ts +0 -35
- package/src/__tests__/skill-feature-flags-integration.test.ts +1 -1
- package/src/__tests__/skill-feature-flags.test.ts +2 -2
- package/src/__tests__/speaker-identification.test.ts +56 -0
- package/src/__tests__/subagent-tool-gate-mode.test.ts +3 -19
- package/src/__tests__/subagent-tools.test.ts +2 -3
- package/src/__tests__/telephony-tts-guard.test.ts +3 -38
- package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +0 -4
- package/src/{calls/__tests__/voice-session-bridge-turn-flow.test.ts → __tests__/voice-session-bridge.test.ts} +12 -20
- package/src/__tests__/watch-retro-tool-availability.test.ts +17 -8
- package/src/__tests__/workspace-git-service.test.ts +0 -26
- package/src/acp/__tests__/agent-process.test.ts +4 -258
- package/src/acp/__tests__/auth-required.test.ts +0 -96
- package/src/acp/__tests__/client-handler.test.ts +2 -90
- package/src/acp/__tests__/session-manager-persistence.test.ts +1 -5
- package/src/acp/__tests__/session-manager-resume.test.ts +6 -270
- package/src/acp/__tests__/session-manager-usage.test.ts +2 -4
- package/src/acp/__tests__/session-manager.test.ts +4 -895
- package/src/acp/agent-process.test.ts +1 -4
- package/src/acp/agent-process.ts +9 -94
- package/src/acp/auth-required.ts +1 -50
- package/src/acp/auto-install.test.ts +7 -9
- package/src/acp/client-handler.ts +3 -16
- package/src/acp/resolve-agent.test.ts +6 -220
- package/src/acp/resolve-agent.ts +23 -88
- package/src/acp/session-manager.test.ts +3 -196
- package/src/acp/session-manager.ts +18 -441
- package/src/acp/types.ts +5 -50
- package/src/api/events/app-files-changed.ts +3 -4
- package/src/api/events/notification-intent.ts +0 -2
- package/src/api/index.ts +0 -6
- package/src/apps/app-store.ts +1 -1
- package/src/bundler/app-compiler.ts +0 -15
- package/src/calls/__tests__/voice-control-protocol.test.ts +25 -58
- package/src/calls/__tests__/voice-session-bridge.test.ts +1 -37
- package/src/calls/__tests__/voice-triage-escalate.test.ts +0 -105
- package/src/calls/call-constants.ts +4 -24
- package/src/calls/call-controller.ts +199 -499
- package/src/calls/call-transport.ts +0 -16
- package/src/calls/media-stream-output.ts +0 -32
- package/src/calls/media-stream-server.ts +30 -82
- package/src/calls/media-stream-stt-session.ts +0 -15
- package/src/calls/resolve-call-tts-provider.ts +2 -33
- package/src/calls/speaker-identification.ts +233 -0
- package/src/calls/tts-call-strategy.ts +5 -9
- package/src/calls/types.ts +0 -2
- package/src/calls/voice-control-protocol.ts +21 -53
- package/src/calls/voice-session-bridge.ts +46 -59
- package/src/calls/voice-triage-escalate.ts +56 -175
- package/src/cli/commands/apps.help.ts +13 -67
- package/src/cli/commands/apps.ts +0 -183
- package/src/cli/commands/bash.help.ts +13 -8
- package/src/cli/commands/bash.ts +25 -7
- package/src/cli/commands/channels/index.help.ts +2 -70
- package/src/cli/commands/channels/index.ts +3 -16
- package/src/cli/commands/credentials.help.ts +2 -6
- package/src/cli/commands/credentials.ts +2 -2
- package/src/cli/commands/mcp.help.ts +8 -8
- package/src/cli/commands/mcp.ts +1 -1
- package/src/cli/commands/roadmap.help.ts +1 -5
- package/src/cli/commands/roadmap.ts +1 -1
- package/src/cli/lib/bundled-marketplace.json +90 -103
- package/src/config/__tests__/default-profile-catalog.test.ts +0 -22
- package/src/config/__tests__/memory-retrospective-schema.test.ts +1 -15
- package/src/config/__tests__/platform-rehydration.test.ts +9 -99
- package/src/config/acp-defaults.test.ts +3 -13
- package/src/config/acp-defaults.ts +6 -23
- package/src/config/acp-schema.ts +2 -30
- package/src/config/bundled-skills/acp/SKILL.md +14 -22
- package/src/config/bundled-skills/acp/TOOLS.json +1 -5
- package/src/config/bundled-skills/app-builder/SKILL.md +9 -12
- package/src/config/bundled-skills/app-builder/references/CUSTOM_ROUTES.md +1 -1
- package/src/config/bundled-skills/messaging/SKILL.md +3 -3
- package/src/config/bundled-skills/messaging/TOOLS.json +3 -3
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +139 -67
- package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +1 -1
- package/src/config/bundled-skills/schedule/SKILL.md +4 -3
- package/src/config/bundled-skills/screen-annotation/SKILL.md +1 -8
- package/src/config/bundled-skills/screen-annotation/tools/screen-annotation.test.ts +1 -4
- package/src/config/bundled-skills/skill-management/TOOLS.json +2 -2
- package/src/config/default-profile-catalog.ts +1 -1
- package/src/config/env.ts +2 -2
- package/src/config/feature-flag-registry.json +12 -24
- package/src/config/loader.ts +0 -1
- package/src/config/memory-v3-gate.test.ts +0 -31
- package/src/config/memory-v3-gate.ts +16 -20
- package/src/config/platform-rehydration.ts +27 -11
- package/src/config/schema.ts +2 -2
- package/src/config/schemas/__tests__/live-voice.test.ts +158 -8
- package/src/config/schemas/calls.ts +28 -1
- package/src/config/schemas/live-voice.ts +173 -1
- package/src/config/schemas/mcp.ts +1 -1
- package/src/config/schemas/memory-retrospective.ts +0 -10
- package/src/config/schemas/services.ts +0 -8
- package/src/config/schemas/skills.ts +14 -0
- package/src/credential-execution/process-manager.test.ts +19 -18
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +121 -66
- package/src/daemon/__tests__/plugin-mcp-reconcile.test.ts +1 -4
- package/src/daemon/app-source-watcher.ts +218 -0
- package/src/daemon/config-watcher.ts +194 -13
- package/src/daemon/conversation-process.ts +64 -35
- package/src/daemon/conversation-skill-tools.ts +31 -13
- package/src/daemon/conversation-store.ts +1 -1
- package/src/daemon/conversation-surfaces.ts +8 -10
- package/src/daemon/conversation-tool-setup.ts +43 -37
- package/src/daemon/conversation.ts +3 -0
- package/src/daemon/host-bash-proxy.ts +12 -8
- package/src/daemon/host-browser-proxy.ts +1 -15
- package/src/daemon/host-file-proxy.ts +10 -8
- package/src/daemon/host-transfer-proxy.ts +18 -14
- package/src/daemon/lifecycle.ts +5 -0
- package/src/daemon/mcp-reload-service.ts +5 -5
- package/src/daemon/message-types/sync.ts +0 -1
- package/src/daemon/orphan-reaper.ts +1 -1
- package/src/daemon/providers-setup.ts +1 -1
- package/src/daemon/shutdown-handlers.ts +9 -1
- package/src/daemon/skill-memory-refresh.ts +0 -64
- package/src/daemon/tool-side-effects.ts +18 -7
- package/src/home/__tests__/feed-writer.test.ts +0 -22
- package/src/home/feed-writer.ts +2 -11
- package/src/hooks/types.ts +0 -33
- package/src/inbound/platform-callback-registration.ts +5 -4
- package/src/live-voice/__tests__/live-voice-metrics.test.ts +3 -0
- package/src/live-voice/__tests__/live-voice-progress.test.ts +15 -15
- package/src/live-voice/__tests__/live-voice-vad.test.ts +2 -2
- package/src/{calls → live-voice}/__tests__/progress-narration.test.ts +4 -4
- package/src/{calls → live-voice}/__tests__/progress-phrases.test.ts +1 -1
- package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +69 -13
- package/src/live-voice/live-voice-session.ts +693 -213
- package/src/{calls → live-voice}/progress-narration.ts +2 -2
- package/src/live-voice/protocol.ts +2 -0
- package/src/mcp/__tests__/effective-config.test.ts +2 -2
- package/src/mcp/effective-config.ts +3 -3
- package/src/mcp/mcp-header-store.ts +45 -29
- package/src/mcp/startup.ts +4 -8
- package/src/messaging/provider.ts +3 -10
- package/src/messaging/providers/callback-routing.ts +0 -18
- package/src/messaging/providers/channel-transport.ts +0 -56
- package/src/messaging/providers/discord/transport.ts +0 -17
- package/src/messaging/providers/slack/__tests__/adapter-token-routing.test.ts +17 -6
- package/src/messaging/providers/slack/adapter.ts +44 -7
- package/src/messaging/providers/slack/transport.ts +0 -16
- package/src/messaging/providers/telegram-bot/adapter.ts +48 -1
- package/src/messaging/providers/telegram-bot/client.ts +26 -0
- package/src/messaging/providers/telegram-bot/transport.ts +0 -20
- package/src/messaging/providers/whatsapp/adapter.ts +48 -1
- package/src/messaging/providers/whatsapp/client.ts +29 -0
- package/src/messaging/providers/whatsapp/transport.ts +0 -18
- package/src/monitoring/__tests__/workspace-git-heartbeat.test.ts +0 -8
- package/src/notifications/__tests__/assistant-reply-producer.test.ts +0 -55
- package/src/notifications/__tests__/guardian-feed-projection.test.ts +2 -158
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +3 -153
- package/src/notifications/__tests__/schedule-result-producer.test.ts +3 -99
- package/src/notifications/adapters/macos.ts +0 -3
- package/src/notifications/assistant-reply-producer.ts +3 -8
- package/src/notifications/conversation-pairing.ts +16 -36
- package/src/notifications/delivered-post-record.ts +1 -11
- package/src/notifications/guardian-feed-projection.ts +5 -125
- package/src/notifications/home-feed-side-effect.ts +7 -55
- package/src/notifications/schedule-result-producer.ts +22 -66
- package/src/oauth/__tests__/seed-providers-managed.test.ts +0 -54
- package/src/oauth/byo-connection.test.ts +0 -45
- package/src/oauth/byo-connection.ts +6 -36
- package/src/oauth/connection-resolver.test.ts +0 -73
- package/src/oauth/connection-resolver.ts +2 -95
- package/src/oauth/seed-providers.ts +0 -165
- package/src/outbound-proxy/certs.ts +5 -3
- package/src/permissions/checker.test.ts +6 -11
- package/src/persistence/compaction-log-store-clickhouse.ts +3 -3
- package/src/persistence/conversation-crud.ts +63 -71
- package/src/persistence/conversation-lineage.ts +4 -12
- package/src/persistence/conversation-title-service.ts +26 -9
- package/src/persistence/llm-request-log-sink-clickhouse.ts +3 -3
- package/src/persistence/llm-request-log-source-clickhouse.ts +3 -3
- package/src/persistence/message-reads.ts +0 -30
- package/src/persistence/migrations/157-invite-contact-id.ts +6 -18
- package/src/persistence/schema/memory-core.ts +0 -5
- package/src/platform/client.test.ts +2 -4
- package/src/platform/client.ts +10 -2
- package/src/plugin-api/constants.ts +0 -2
- package/src/plugin-api/index.ts +0 -1
- package/src/plugin-api/types.ts +0 -2
- package/src/plugins/defaults/index.ts +0 -2
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-accounting.test.ts +0 -46
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-enqueue.test.ts +5 -9
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +10 -20
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-state.test.ts +0 -219
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-sweep.test.ts +0 -31
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-trigger-check.test.ts +0 -63
- package/src/plugins/defaults/memory/__tests__/shutdown-hook.test.ts +0 -4
- package/src/plugins/defaults/memory/graph/capability-seed.ts +6 -4
- package/src/plugins/defaults/memory/hooks/init.ts +0 -10
- package/src/plugins/defaults/memory/hooks/shutdown.ts +0 -2
- package/src/plugins/defaults/memory/jobs-worker.ts +0 -13
- package/src/plugins/defaults/memory/memory-retrospective-accounting.ts +60 -34
- package/src/plugins/defaults/memory/memory-retrospective-enqueue.ts +5 -3
- package/src/plugins/defaults/memory/memory-retrospective-job.ts +3 -12
- package/src/plugins/defaults/memory/memory-retrospective-state.ts +71 -312
- package/src/plugins/defaults/memory/memory-retrospective-sweep.ts +1 -2
- package/src/plugins/defaults/memory/memory-retrospective-trigger-check.ts +3 -5
- package/src/plugins/defaults/memory/startup.ts +1 -6
- package/src/plugins/defaults/memory/substrate/__tests__/skill-content.test.ts +9 -7
- package/src/plugins/defaults/memory/substrate/skill-content.ts +2 -2
- package/src/plugins/defaults/memory/v3/__tests__/pool-select.test.ts +0 -89
- package/src/plugins/defaults/memory/worker.ts +0 -6
- package/src/plugins/mcp-servers.ts +75 -15
- package/src/providers/__tests__/connection-model-compat.test.ts +3 -3
- package/src/providers/gemini/client.ts +23 -9
- package/src/providers/inference/auth.ts +3 -2
- package/src/providers/inference/connection-availability.ts +8 -27
- package/src/providers/inference/resolve-auth.ts +4 -22
- package/src/providers/model-catalog.ts +0 -34
- package/src/providers/model-intents.ts +5 -10
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +18 -146
- package/src/providers/openai/__tests__/tool-choice-mapping.test.ts +1 -83
- package/src/providers/openai/chat-completions-provider.ts +78 -192
- package/src/providers/openai/codex-models.ts +4 -0
- package/src/runtime/AGENTS.md +0 -2
- package/src/runtime/auth/same-actor.ts +3 -38
- package/src/runtime/http-server.ts +151 -160
- package/src/runtime/routes/__tests__/acp-routes.test.ts +4 -159
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +1 -108
- package/src/runtime/routes/__tests__/default-provider-routes.test.ts +2 -2
- package/src/runtime/routes/__tests__/mcp-add-default-risk.test.ts +12 -16
- package/src/runtime/routes/acp-routes.test.ts +0 -15
- package/src/runtime/routes/acp-routes.ts +9 -72
- package/src/runtime/routes/app-management-routes.ts +0 -73
- package/src/runtime/routes/app-routes.ts +1 -1
- package/src/runtime/routes/conversation-list-routes.ts +3 -14
- package/src/runtime/routes/conversation-query-routes.ts +0 -40
- package/src/runtime/routes/credential-routes.ts +10 -19
- package/src/runtime/routes/debug-bash-routes.ts +173 -0
- package/src/runtime/routes/diagnostics-routes.ts +3 -55
- package/src/runtime/routes/index.ts +2 -4
- package/src/runtime/routes/log-export-routes.ts +0 -2
- package/src/runtime/routes/mcp-auth-routes.ts +47 -39
- package/src/runtime/routes/migration-routes.ts +20 -6
- package/src/runtime/routes/platform-routes.ts +15 -18
- package/src/runtime/services/__tests__/conversation-serializer.test.ts +0 -28
- package/src/runtime/services/conversation-serializer.ts +3 -16
- package/src/runtime/sync/resource-sync-events.ts +1 -2
- package/src/schedule/worker.ts +1 -1
- package/src/security/ces-rpc-record-backend.ts +0 -7
- package/src/subagent/consult-context.ts +25 -12
- package/src/tools/acp/list-agents.test.ts +1 -3
- package/src/tools/acp/spawn.test.ts +11 -146
- package/src/tools/acp/spawn.ts +3 -21
- package/src/tools/acp/status.ts +3 -40
- package/src/tools/app-control/skill-proxy-bridge.ts +1 -2
- package/src/tools/capability-offer.test.ts +2 -22
- package/src/tools/capability-offer.ts +1 -16
- package/src/tools/computer-use/definitions.ts +2 -4
- package/src/tools/computer-use/skill-proxy-bridge.ts +1 -2
- package/src/tools/credentials/metadata-store.ts +0 -100
- package/src/tools/host-filesystem/edit.test.ts +1 -2
- package/src/tools/host-filesystem/edit.ts +2 -2
- package/src/tools/host-filesystem/read.test.ts +1 -2
- package/src/tools/host-filesystem/read.ts +2 -2
- package/src/tools/host-filesystem/transfer.test.ts +1 -2
- package/src/tools/host-filesystem/transfer.ts +2 -2
- package/src/tools/host-filesystem/write.test.ts +1 -2
- package/src/tools/host-filesystem/write.ts +2 -2
- package/src/tools/host-terminal/host-shell.test.ts +0 -16
- package/src/tools/host-terminal/host-shell.ts +20 -4
- package/src/tools/policy-context.ts +7 -6
- package/src/tools/subagent/spawn.ts +8 -5
- package/src/tools/watch/watch-retro-report.ts +8 -0
- package/src/util/__tests__/language-subtag.test.ts +1 -23
- package/src/util/fs-watcher-error.ts +36 -0
- package/src/util/language-subtag.ts +0 -16
- package/src/util/platform.ts +0 -8
- package/src/workspace/git-service.ts +54 -5
- package/src/workspace/migrations/registry.ts +0 -6
- package/scripts/smoke-desktop-window-theme.ts +0 -186
- package/src/__tests__/git-porcelain.test.ts +0 -47
- package/src/__tests__/helpers/set-workspace-mcp.ts +0 -11
- package/src/__tests__/message-deleted-hook-dispatch.test.ts +0 -119
- package/src/__tests__/resolve-app.test.ts +0 -135
- package/src/__tests__/service-account-token.test.ts +0 -247
- package/src/__tests__/source-fingerprint.test.ts +0 -184
- package/src/__tests__/workspace-migration-154-repair-retired-codex-gpt-5-4-model-ids.test.ts +0 -336
- package/src/acp/__tests__/helpers/acp-model-option.ts +0 -51
- package/src/acp/model-config.test.ts +0 -166
- package/src/acp/model-config.ts +0 -138
- package/src/api/events/acp-session-model-update.test.ts +0 -88
- package/src/api/events/acp-session-model-update.ts +0 -46
- package/src/apps/resolve-app.ts +0 -81
- package/src/apps/source-fingerprint.ts +0 -266
- package/src/calls/__tests__/barge-in-guard.test.ts +0 -81
- package/src/calls/__tests__/voice-leg-coordinator.test.ts +0 -229
- package/src/calls/__tests__/voice-progress-cadence.test.ts +0 -274
- package/src/calls/barge-in-guard.ts +0 -118
- package/src/calls/voice-leg-coordinator.ts +0 -189
- package/src/calls/voice-progress-cadence.ts +0 -423
- package/src/cli/commands/__tests__/apps.test.ts +0 -245
- package/src/cli/commands/__tests__/bash.test.ts +0 -53
- package/src/cli/commands/__tests__/roadmap.help.test.ts +0 -19
- package/src/cli/commands/channels/__tests__/send.test.ts +0 -218
- package/src/cli/commands/channels/send.ts +0 -128
- package/src/config/__tests__/platform-identity.test.ts +0 -255
- package/src/config/acp-agent-write.ts +0 -43
- package/src/config/acp-schema.test.ts +0 -81
- package/src/config/platform-identity.ts +0 -201
- package/src/config/schemas/__tests__/voice.test.ts +0 -148
- package/src/config/schemas/voice.ts +0 -150
- package/src/daemon/__tests__/skill-memory-refresh-mtime.test.ts +0 -133
- package/src/daemon/app-change-notify.ts +0 -45
- package/src/desktop/__tests__/fake-desktop.ts +0 -119
- package/src/desktop/desktop-chrome-policy.test.ts +0 -71
- package/src/desktop/desktop-chrome-policy.ts +0 -42
- package/src/desktop/desktop-dependencies.test.ts +0 -102
- package/src/desktop/desktop-dependencies.ts +0 -306
- package/src/desktop/desktop-feature.test.ts +0 -18
- package/src/desktop/desktop-feature.ts +0 -19
- package/src/desktop/desktop-panel-config.test.ts +0 -135
- package/src/desktop/desktop-panel-config.ts +0 -149
- package/src/desktop/desktop-session-manager.test.ts +0 -627
- package/src/desktop/desktop-session-manager.ts +0 -814
- package/src/desktop/desktop-stream-bridge.test.ts +0 -395
- package/src/desktop/desktop-stream-bridge.ts +0 -214
- package/src/desktop/desktop-wallpaper.test.ts +0 -191
- package/src/desktop/desktop-wallpaper.ts +0 -113
- package/src/desktop/desktop-window-theme.ts +0 -170
- package/src/i18n/AGENTS.md +0 -22
- package/src/i18n/__tests__/i18n.test.ts +0 -108
- package/src/i18n/index.ts +0 -16
- package/src/i18n/locales.ts +0 -93
- package/src/i18n/messages.ts +0 -61
- package/src/i18n/title.ts +0 -25
- package/src/mcp/__tests__/workspace-mcp-config.test.ts +0 -135
- package/src/mcp/spec-schema.ts +0 -111
- package/src/mcp/workspace-mcp-config.ts +0 -188
- package/src/messaging/providers/__tests__/proactive-address.test.ts +0 -95
- package/src/persistence/conversation-title-placeholders.ts +0 -23
- package/src/persistence/message-cursor.ts +0 -78
- package/src/persistence/migrations/__tests__/157-invite-contact-id.test.ts +0 -149
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-cursor-backfill.test.ts +0 -118
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-cursor-preserve.test.ts +0 -83
- package/src/plugins/defaults/memory/hooks/message-deleted.ts +0 -21
- package/src/plugins/defaults/memory/memory-retrospective-cursor-backfill.ts +0 -126
- package/src/plugins/defaults/memory/memory-retrospective-cursor-preserve.ts +0 -79
- package/src/plugins/defaults/memory/memory-retrospective-cursor.ts +0 -28
- package/src/plugins/defaults/memory/skill-md-mtime-poll.ts +0 -9
- package/src/providers/gemini-thought-signature.test.ts +0 -63
- package/src/providers/gemini-thought-signature.ts +0 -44
- package/src/providers/inference/service-account-token.ts +0 -248
- package/src/providers/openai/__tests__/chat-completions-provider-thought-signature.test.ts +0 -613
- package/src/providers/openai/__tests__/google-thought-signature.test.ts +0 -235
- package/src/providers/openai/google-thought-signature.ts +0 -320
- package/src/runtime/__tests__/channel-send.test.ts +0 -443
- package/src/runtime/__tests__/desktop-stream-upgrade.test.ts +0 -89
- package/src/runtime/__tests__/live-voice-upgrade.test.ts +0 -58
- package/src/runtime/__tests__/runtime-ws-test-utils.ts +0 -72
- package/src/runtime/__tests__/watch-stream-upgrade.test.ts +0 -59
- package/src/runtime/channel-send.ts +0 -316
- package/src/runtime/routes/__tests__/apps-refresh-route.test.ts +0 -205
- package/src/runtime/routes/__tests__/channel-send-routes.test.ts +0 -127
- package/src/runtime/routes/__tests__/dictation-cleanup-guard.test.ts +0 -107
- package/src/runtime/routes/channel-send-routes.ts +0 -85
- package/src/runtime/routes/desktop-setup-routes.test.ts +0 -74
- package/src/runtime/routes/desktop-setup-routes.ts +0 -35
- package/src/security/__tests__/ces-http-record-backend.test.ts +0 -137
- package/src/security/ces-http-record-backend.ts +0 -120
- package/src/skills/__tests__/workspace-skill-md-signature.test.ts +0 -60
- package/src/skills/workspace-skill-md-signature.ts +0 -50
- package/src/tools/acp/status.test.ts +0 -94
- package/src/tools/terminal/__tests__/sanitized-bash.test.ts +0 -57
- package/src/tools/terminal/sanitized-bash.ts +0 -105
- package/src/util/ca-bundle.ts +0 -13
- package/src/workspace/git-porcelain.ts +0 -66
- package/src/workspace/migrations/154-repair-retired-codex-gpt-5-4-model-ids.ts +0 -258
- package/src/workspace/migrations/155-move-front-model-config-to-voice.ts +0 -78
- package/src/workspace/migrations/156-extract-workspace-mcp-json.ts +0 -214
- package/src/workspace/migrations/__tests__/155-move-front-model-config-to-voice.test.ts +0 -102
- package/src/workspace/migrations/__tests__/156-extract-workspace-mcp-json.test.ts +0 -199
- /package/src/{calls → live-voice}/progress-phrases.ts +0 -0
|
@@ -43,7 +43,7 @@ import {
|
|
|
43
43
|
deleteCredentialMetadata,
|
|
44
44
|
getCredentialMetadata,
|
|
45
45
|
getCredentialMetadataById,
|
|
46
|
-
|
|
46
|
+
listCredentialMetadata,
|
|
47
47
|
} from "../../tools/credentials/metadata-store.js";
|
|
48
48
|
import type { CredentialInjectionTemplate } from "../../tools/credentials/policy-types.js";
|
|
49
49
|
import {
|
|
@@ -228,9 +228,6 @@ function assertNotPlatformManaged(
|
|
|
228
228
|
}
|
|
229
229
|
}
|
|
230
230
|
|
|
231
|
-
const CREDENTIAL_STORE_UNREACHABLE =
|
|
232
|
-
"Credential store is unreachable. Retry in a moment, or check that the credential vault is running.";
|
|
233
|
-
|
|
234
231
|
// ---------------------------------------------------------------------------
|
|
235
232
|
// Handlers
|
|
236
233
|
// ---------------------------------------------------------------------------
|
|
@@ -238,14 +235,9 @@ const CREDENTIAL_STORE_UNREACHABLE =
|
|
|
238
235
|
async function handleCredentialsList({ body }: RouteHandlerArgs) {
|
|
239
236
|
const search = (body as { search?: string } | undefined)?.search;
|
|
240
237
|
|
|
241
|
-
const live = await listCredentialRecordsLive();
|
|
242
|
-
if (live.unreachable) {
|
|
243
|
-
throw new InternalError(CREDENTIAL_STORE_UNREACHABLE);
|
|
244
|
-
}
|
|
245
|
-
|
|
246
238
|
// Platform-provisioned credentials are not the user's to act on, so they
|
|
247
239
|
// never become a Settings row (and never a click-to-reveal).
|
|
248
|
-
let allMetadata =
|
|
240
|
+
let allMetadata = listCredentialMetadata().filter(
|
|
249
241
|
(m) => !isPlatformManagedCredential(m.service, m.field),
|
|
250
242
|
);
|
|
251
243
|
|
|
@@ -280,12 +272,7 @@ async function handleCredentialsList({ body }: RouteHandlerArgs) {
|
|
|
280
272
|
|
|
281
273
|
const credentials = await Promise.all(
|
|
282
274
|
allMetadata.map(async (m) => {
|
|
283
|
-
const
|
|
284
|
-
credentialKey(m.service, m.field),
|
|
285
|
-
);
|
|
286
|
-
if (unreachable) {
|
|
287
|
-
throw new InternalError(CREDENTIAL_STORE_UNREACHABLE);
|
|
288
|
-
}
|
|
275
|
+
const secret = await getSecureKeyAsync(credentialKey(m.service, m.field));
|
|
289
276
|
const connection = connectionsByProvider.get(m.service);
|
|
290
277
|
return buildCredentialOutput(m, secret, connection);
|
|
291
278
|
}),
|
|
@@ -323,7 +310,9 @@ async function handleCredentialsInspect({ body }: RouteHandlerArgs) {
|
|
|
323
310
|
|
|
324
311
|
if (!lookup.metadata && (secret == null || secret.length === 0)) {
|
|
325
312
|
if (unreachable) {
|
|
326
|
-
throw new InternalError(
|
|
313
|
+
throw new InternalError(
|
|
314
|
+
"Credential store is unreachable — ensure the assistant is running",
|
|
315
|
+
);
|
|
327
316
|
}
|
|
328
317
|
throw new BadRequestError("Credential not found");
|
|
329
318
|
}
|
|
@@ -385,7 +374,9 @@ async function handleCredentialsReveal({ body, headers }: RouteHandlerArgs) {
|
|
|
385
374
|
|
|
386
375
|
if (secret == null || secret.length === 0) {
|
|
387
376
|
if (unreachable) {
|
|
388
|
-
throw new InternalError(
|
|
377
|
+
throw new InternalError(
|
|
378
|
+
"Credential store is unreachable — ensure the assistant is running",
|
|
379
|
+
);
|
|
389
380
|
}
|
|
390
381
|
throw new BadRequestError("Credential not found");
|
|
391
382
|
}
|
|
@@ -629,7 +620,7 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
629
620
|
},
|
|
630
621
|
summary: "List all credentials with metadata",
|
|
631
622
|
description:
|
|
632
|
-
"Return
|
|
623
|
+
"Return all stored credentials with metadata, OAuth connection info, and platform-managed credentials.",
|
|
633
624
|
tags: ["credentials"],
|
|
634
625
|
requestBody: z.object({
|
|
635
626
|
search: z.string().optional().describe("Filter by substring match"),
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IPC route for executing shell commands through the assistant process.
|
|
3
|
+
*
|
|
4
|
+
* The CLI sends the command over the IPC socket and receives a single
|
|
5
|
+
* response containing stdout, stderr, and the exit code.
|
|
6
|
+
*
|
|
7
|
+
* **Security**: Gated behind VELLUM_DEBUG=1. When debug mode is off (the
|
|
8
|
+
* default), the handler returns an error immediately so the CLI surfaces a
|
|
9
|
+
* clear rejection instead of hanging. The assistant must be restarted with
|
|
10
|
+
* VELLUM_DEBUG=1 for this route to execute commands.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { spawn } from "node:child_process";
|
|
14
|
+
|
|
15
|
+
import { z } from "zod";
|
|
16
|
+
|
|
17
|
+
import { getIsContainerized } from "../../config/env-registry.js";
|
|
18
|
+
import { buildSanitizedEnv } from "../../tools/terminal/safe-env.js";
|
|
19
|
+
import { getWorkspaceDir } from "../../util/platform.js";
|
|
20
|
+
import { ACTOR_PRINCIPALS } from "../auth/route-policy.js";
|
|
21
|
+
import type { RouteDefinition, RouteHandlerArgs } from "./types.js";
|
|
22
|
+
|
|
23
|
+
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
24
|
+
|
|
25
|
+
function isDebugMode(): boolean {
|
|
26
|
+
return (
|
|
27
|
+
process.env.VELLUM_DEBUG === "1" || process.env.VELLUM_DEBUG === "true"
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
interface DebugBashResult {
|
|
32
|
+
stdout: string;
|
|
33
|
+
stderr: string;
|
|
34
|
+
exitCode: number | null;
|
|
35
|
+
timedOut: boolean;
|
|
36
|
+
error?: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function handleDebugBash({ body }: RouteHandlerArgs): Promise<DebugBashResult> {
|
|
40
|
+
if (getIsContainerized()) {
|
|
41
|
+
return Promise.resolve({
|
|
42
|
+
stdout: "",
|
|
43
|
+
stderr: "",
|
|
44
|
+
exitCode: null,
|
|
45
|
+
timedOut: false,
|
|
46
|
+
error: "debug bash is not available in containerized environments",
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (!isDebugMode()) {
|
|
51
|
+
return Promise.resolve({
|
|
52
|
+
stdout: "",
|
|
53
|
+
stderr: "",
|
|
54
|
+
exitCode: null,
|
|
55
|
+
timedOut: false,
|
|
56
|
+
error:
|
|
57
|
+
"Bash debug execution is disabled. The running assistant process must have been started with VELLUM_DEBUG=1 (setting it on the CLI command alone is not enough). Restart the assistant with: vellum sleep && VELLUM_DEBUG=1 vellum wake",
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const { command, timeoutMs } = body as {
|
|
62
|
+
command?: string;
|
|
63
|
+
timeoutMs?: number;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
if (!command || typeof command !== "string") {
|
|
67
|
+
return Promise.resolve({
|
|
68
|
+
stdout: "",
|
|
69
|
+
stderr: "",
|
|
70
|
+
exitCode: null,
|
|
71
|
+
timedOut: false,
|
|
72
|
+
error: "command is required",
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const effectiveTimeout =
|
|
77
|
+
typeof timeoutMs === "number" && timeoutMs > 0
|
|
78
|
+
? timeoutMs
|
|
79
|
+
: DEFAULT_TIMEOUT_MS;
|
|
80
|
+
|
|
81
|
+
return new Promise<DebugBashResult>((resolve) => {
|
|
82
|
+
const stdoutChunks: Buffer[] = [];
|
|
83
|
+
const stderrChunks: Buffer[] = [];
|
|
84
|
+
let timedOut = false;
|
|
85
|
+
let settled = false;
|
|
86
|
+
|
|
87
|
+
const finish = (result: DebugBashResult) => {
|
|
88
|
+
if (settled) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
settled = true;
|
|
92
|
+
resolve(result);
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const child = spawn("bash", ["-c", command], {
|
|
96
|
+
cwd: getWorkspaceDir(),
|
|
97
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
98
|
+
detached: true,
|
|
99
|
+
env: buildSanitizedEnv(),
|
|
100
|
+
windowsHide: true,
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
const timer = setTimeout(() => {
|
|
104
|
+
timedOut = true;
|
|
105
|
+
try {
|
|
106
|
+
process.kill(-child.pid!, "SIGKILL");
|
|
107
|
+
} catch {
|
|
108
|
+
// Process group may have already exited.
|
|
109
|
+
}
|
|
110
|
+
}, effectiveTimeout);
|
|
111
|
+
|
|
112
|
+
child.stdout.on("data", (data: Buffer) => {
|
|
113
|
+
stdoutChunks.push(data);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
child.stderr.on("data", (data: Buffer) => {
|
|
117
|
+
stderrChunks.push(data);
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
child.on("close", (code) => {
|
|
121
|
+
clearTimeout(timer);
|
|
122
|
+
finish({
|
|
123
|
+
stdout: Buffer.concat(stdoutChunks).toString(),
|
|
124
|
+
stderr: Buffer.concat(stderrChunks).toString(),
|
|
125
|
+
exitCode: code,
|
|
126
|
+
timedOut,
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
child.on("error", (err) => {
|
|
131
|
+
clearTimeout(timer);
|
|
132
|
+
finish({
|
|
133
|
+
stdout: "",
|
|
134
|
+
stderr: "",
|
|
135
|
+
exitCode: null,
|
|
136
|
+
timedOut: false,
|
|
137
|
+
error: err.message,
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export const ROUTES: RouteDefinition[] = [
|
|
144
|
+
{
|
|
145
|
+
operationId: "debug_bash",
|
|
146
|
+
endpoint: "debug/bash",
|
|
147
|
+
method: "POST",
|
|
148
|
+
policy: {
|
|
149
|
+
requiredScopes: ["settings.write"],
|
|
150
|
+
allowedPrincipalTypes: ACTOR_PRINCIPALS,
|
|
151
|
+
},
|
|
152
|
+
requireGuardian: false,
|
|
153
|
+
summary: "Execute a shell command in the assistant process",
|
|
154
|
+
description:
|
|
155
|
+
"Developer debugging tool. Requires the assistant to be running with VELLUM_DEBUG=1.",
|
|
156
|
+
tags: ["debug"],
|
|
157
|
+
requestBody: z.object({
|
|
158
|
+
command: z.string().describe("Shell command to execute via bash -c"),
|
|
159
|
+
timeoutMs: z
|
|
160
|
+
.number()
|
|
161
|
+
.optional()
|
|
162
|
+
.describe("Execution timeout in milliseconds (default: 30000)"),
|
|
163
|
+
}),
|
|
164
|
+
responseBody: z.object({
|
|
165
|
+
stdout: z.string(),
|
|
166
|
+
stderr: z.string(),
|
|
167
|
+
exitCode: z.number().nullable(),
|
|
168
|
+
timedOut: z.boolean(),
|
|
169
|
+
error: z.string().optional(),
|
|
170
|
+
}),
|
|
171
|
+
handler: handleDebugBash,
|
|
172
|
+
},
|
|
173
|
+
];
|
|
@@ -22,7 +22,6 @@ import {
|
|
|
22
22
|
getConfiguredProvider,
|
|
23
23
|
userMessage,
|
|
24
24
|
} from "../../providers/provider-send-message.js";
|
|
25
|
-
import { isMaxTokensStopReason } from "../../providers/stop-reasons.js";
|
|
26
25
|
import { getLogger } from "../../util/logger.js";
|
|
27
26
|
import { ACTOR_PRINCIPALS } from "../auth/route-policy.js";
|
|
28
27
|
import { BadRequestError } from "./errors.js";
|
|
@@ -177,44 +176,9 @@ function buildCommandPrompt(body: DictationBody, stylePrompt?: string): string {
|
|
|
177
176
|
return sections.join("\n");
|
|
178
177
|
}
|
|
179
178
|
|
|
180
|
-
|
|
179
|
+
function computeMaxTokens(inputLength: number): number {
|
|
181
180
|
const estimatedInputTokens = Math.ceil(inputLength / 3);
|
|
182
|
-
|
|
183
|
-
// argument, plus a `reasoning` string and the JSON scaffolding around both,
|
|
184
|
-
// so the budget has to cover well more than the input alone. `max_tokens` is
|
|
185
|
-
// a ceiling rather than a target: a call that stops short of it costs no
|
|
186
|
-
// extra latency.
|
|
187
|
-
return Math.max(512, estimatedInputTokens * 2 + 256);
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
export type CleanupRejection = "truncated";
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* Decide whether the cleanup model's rewrite is safe to use as the payload.
|
|
194
|
-
*
|
|
195
|
-
* The rewrite replaces what the user actually said. A token-cap stop means the
|
|
196
|
-
* tool JSON was cut mid-argument, so however complete the `text` argument
|
|
197
|
-
* happens to look, it is a fragment; the raw transcript is the safer payload
|
|
198
|
-
* then. Unpolished beats wrong.
|
|
199
|
-
*
|
|
200
|
-
* Whether a shorter rewrite still preserved the meaning is the model's call
|
|
201
|
-
* (the prompt asks it to drop fillers and tighten phrasing), so there is no
|
|
202
|
-
* length check here: a deterministic ratio cannot tell a concise cleanup from
|
|
203
|
-
* a summary.
|
|
204
|
-
*/
|
|
205
|
-
export function resolveCleanedDictation(
|
|
206
|
-
raw: string,
|
|
207
|
-
cleaned: string,
|
|
208
|
-
stopReason: string | null | undefined,
|
|
209
|
-
): { text: string; rejected: CleanupRejection | null } {
|
|
210
|
-
const trimmed = cleaned.trim();
|
|
211
|
-
if (!trimmed) {
|
|
212
|
-
return { text: raw, rejected: null };
|
|
213
|
-
}
|
|
214
|
-
if (isMaxTokensStopReason(stopReason)) {
|
|
215
|
-
return { text: raw, rejected: "truncated" };
|
|
216
|
-
}
|
|
217
|
-
return { text: trimmed, rejected: null };
|
|
181
|
+
return Math.max(256, estimatedInputTokens + 128);
|
|
218
182
|
}
|
|
219
183
|
|
|
220
184
|
interface DictationResult {
|
|
@@ -365,23 +329,7 @@ async function handleDictation(body: DictationBody): Promise<DictationResult> {
|
|
|
365
329
|
...profileMeta,
|
|
366
330
|
};
|
|
367
331
|
}
|
|
368
|
-
const
|
|
369
|
-
transcription,
|
|
370
|
-
input.text ?? "",
|
|
371
|
-
response.stopReason,
|
|
372
|
-
);
|
|
373
|
-
if (rejected) {
|
|
374
|
-
// Lengths only -- transcript content must never be logged.
|
|
375
|
-
log.warn(
|
|
376
|
-
{
|
|
377
|
-
rejected,
|
|
378
|
-
stopReason: response.stopReason,
|
|
379
|
-
rawChars: transcription.length,
|
|
380
|
-
cleanedChars: input.text?.trim().length ?? 0,
|
|
381
|
-
},
|
|
382
|
-
"Dictation cleanup rejected, using raw transcription",
|
|
383
|
-
);
|
|
384
|
-
}
|
|
332
|
+
const cleanedText = input.text?.trim() || transcription;
|
|
385
333
|
const normalizedText = applyDictionary(cleanedText, profile.dictionary);
|
|
386
334
|
return {
|
|
387
335
|
text: normalizedText,
|
|
@@ -39,7 +39,6 @@ import { ROUTES as CALL_ROUTES } from "./call-routes.js";
|
|
|
39
39
|
import { ROUTES as CHANNEL_AVAILABILITY_ROUTES } from "./channel-availability-routes.js";
|
|
40
40
|
import { ROUTES as CHANNEL_READINESS_ROUTES } from "./channel-readiness-routes.js";
|
|
41
41
|
import { CHANNEL_ROUTES } from "./channel-route-definitions.js";
|
|
42
|
-
import { ROUTES as CHANNEL_SEND_ROUTES } from "./channel-send-routes.js";
|
|
43
42
|
import { ROUTES as CHANNEL_VERIFICATION_ROUTES } from "./channel-verification-routes.js";
|
|
44
43
|
import { ROUTES as CHATGPT_SUBSCRIPTION_AUTH_ROUTES } from "./chatgpt-subscription-auth-routes.js";
|
|
45
44
|
import { ROUTES as CLIENT_ROUTES } from "./client-routes.js";
|
|
@@ -59,10 +58,10 @@ import { ROUTES as CONVERSATIONS_IMPORT_ROUTES } from "./conversations-import-ro
|
|
|
59
58
|
import { ROUTES as CREDENTIAL_PROMPT_ROUTES } from "./credential-prompt-routes.js";
|
|
60
59
|
import { ROUTES as CREDENTIAL_REQUEST_ROUTES } from "./credential-request-routes.js";
|
|
61
60
|
import { ROUTES as CREDENTIAL_ROUTES } from "./credential-routes.js";
|
|
61
|
+
import { ROUTES as DEBUG_BASH_ROUTES } from "./debug-bash-routes.js";
|
|
62
62
|
import { ROUTES as DEBUG_ROUTES } from "./debug-routes.js";
|
|
63
63
|
import { ROUTES as DEFAULT_PROVIDER_ROUTES } from "./default-provider-routes.js";
|
|
64
64
|
import { ROUTES as DEFER_ROUTES } from "./defer-routes.js";
|
|
65
|
-
import { ROUTES as DESKTOP_SETUP_ROUTES } from "./desktop-setup-routes.js";
|
|
66
65
|
import { ROUTES as DIAGNOSTICS_ROUTES } from "./diagnostics-routes.js";
|
|
67
66
|
import { ROUTES as DISK_PRESSURE_ROUTES } from "./disk-pressure-routes.js";
|
|
68
67
|
import { ROUTES as DOCUMENT_COMMENT_ROUTES } from "./document-comments-routes.js";
|
|
@@ -192,7 +191,6 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
192
191
|
...CHANNEL_VERIFICATION_ROUTES,
|
|
193
192
|
...CHANNEL_AVAILABILITY_ROUTES,
|
|
194
193
|
...CHANNEL_READINESS_ROUTES,
|
|
195
|
-
...CHANNEL_SEND_ROUTES,
|
|
196
194
|
...BROWSER_ROUTES,
|
|
197
195
|
...BROWSER_TABS_ROUTES,
|
|
198
196
|
...BTW_ROUTES,
|
|
@@ -217,9 +215,9 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
217
215
|
...CONVERSATION_QUERY_ROUTES,
|
|
218
216
|
...CONVERSATION_STARTER_ROUTES,
|
|
219
217
|
...ACTIVATION_ROUTES,
|
|
218
|
+
...DEBUG_BASH_ROUTES,
|
|
220
219
|
...DEBUG_ROUTES,
|
|
221
220
|
...DEFAULT_PROVIDER_ROUTES,
|
|
222
|
-
...DESKTOP_SETUP_ROUTES,
|
|
223
221
|
...DIAGNOSTICS_ROUTES,
|
|
224
222
|
...DISK_PRESSURE_ROUTES,
|
|
225
223
|
...RESOURCE_PRESSURE_ROUTES,
|
|
@@ -22,7 +22,6 @@ import { join } from "node:path";
|
|
|
22
22
|
import { and, desc, eq, gte, lte } from "drizzle-orm";
|
|
23
23
|
import { z } from "zod";
|
|
24
24
|
|
|
25
|
-
import { overlayWorkspaceMcpForConfigRead } from "../../mcp/workspace-mcp-config.js";
|
|
26
25
|
import { getDb, getLogsDb } from "../../persistence/db-connection.js";
|
|
27
26
|
import {
|
|
28
27
|
llmRequestLogs,
|
|
@@ -569,7 +568,6 @@ function readSanitizedConfig(): Record<string, unknown> | undefined {
|
|
|
569
568
|
}
|
|
570
569
|
}
|
|
571
570
|
|
|
572
|
-
overlayWorkspaceMcpForConfigRead(config);
|
|
573
571
|
const mcpServers = asRecord(asRecord(config.mcp)?.servers);
|
|
574
572
|
for (const server of Object.values(mcpServers ?? {})) {
|
|
575
573
|
const transport = asRecord(asRecord(server)?.transport);
|
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
|
|
15
15
|
import { z } from "zod";
|
|
16
16
|
|
|
17
|
-
import
|
|
17
|
+
import { loadRawConfig, saveRawConfig } from "../../config/loader.js";
|
|
18
|
+
import type { McpConfig, McpServerConfig } from "../../config/schemas/mcp.js";
|
|
18
19
|
import { estimateToolDefinitionTokens } from "../../context/token-estimator.js";
|
|
19
20
|
import { reloadMcpServers } from "../../daemon/mcp-reload-service.js";
|
|
20
21
|
import { McpClient } from "../../mcp/client.js";
|
|
@@ -30,10 +31,6 @@ import {
|
|
|
30
31
|
deleteMcpOAuthCredentials,
|
|
31
32
|
hasMcpOAuthTokens,
|
|
32
33
|
} from "../../mcp/mcp-oauth-provider.js";
|
|
33
|
-
import {
|
|
34
|
-
loadWorkspaceMcpConfig,
|
|
35
|
-
saveWorkspaceMcpConfig,
|
|
36
|
-
} from "../../mcp/workspace-mcp-config.js";
|
|
37
34
|
import { readPluginMcpServers } from "../../plugins/mcp-servers.js";
|
|
38
35
|
import { getMcpToolsByServer } from "../../tools/registry.js";
|
|
39
36
|
import { getLogger } from "../../util/logger.js";
|
|
@@ -68,18 +65,6 @@ const McpAddParams = z.object({
|
|
|
68
65
|
|
|
69
66
|
const McpRemoveParams = z.object({ name: z.string() });
|
|
70
67
|
|
|
71
|
-
function persistWorkspaceMcpConfig(config: {
|
|
72
|
-
servers: Record<string, McpServerConfig>;
|
|
73
|
-
}): void {
|
|
74
|
-
try {
|
|
75
|
-
saveWorkspaceMcpConfig(config);
|
|
76
|
-
} catch (err) {
|
|
77
|
-
throw new InternalError(
|
|
78
|
-
err instanceof Error ? err.message : String(err),
|
|
79
|
-
);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
68
|
async function handleMcpAuthStart({
|
|
84
69
|
body,
|
|
85
70
|
}: {
|
|
@@ -91,7 +76,8 @@ async function handleMcpAuthStart({
|
|
|
91
76
|
}> {
|
|
92
77
|
const { serverId } = parseBody(McpServerIdParams, body);
|
|
93
78
|
|
|
94
|
-
const
|
|
79
|
+
const raw = loadRawConfig();
|
|
80
|
+
const servers = (raw.mcp as Partial<McpConfig> | undefined)?.servers ?? {};
|
|
95
81
|
const serverConfig = servers[serverId];
|
|
96
82
|
|
|
97
83
|
if (!serverConfig) {
|
|
@@ -267,7 +253,9 @@ function detectAuthType(headers: Record<string, string>): "bearer" | "api-key" {
|
|
|
267
253
|
async function handleMcpList(_args: {
|
|
268
254
|
body?: Record<string, unknown>;
|
|
269
255
|
}): Promise<{ servers: McpServerEntry[] }> {
|
|
270
|
-
const
|
|
256
|
+
const raw = loadRawConfig();
|
|
257
|
+
const mcpConfig = raw.mcp as Partial<McpConfig> | undefined;
|
|
258
|
+
const servers = mcpConfig?.servers ?? {};
|
|
271
259
|
const configEntries = (
|
|
272
260
|
Object.entries(servers) as [string, McpServerConfig][]
|
|
273
261
|
).filter(([, config]) => config && typeof config === "object");
|
|
@@ -446,13 +434,18 @@ async function handleMcpUpdate({
|
|
|
446
434
|
}): Promise<{ updated: true }> {
|
|
447
435
|
const { name, headers } = parseBody(McpUpdateParams, body);
|
|
448
436
|
|
|
449
|
-
const
|
|
450
|
-
const
|
|
437
|
+
const raw = loadRawConfig();
|
|
438
|
+
const mcpConfig = raw.mcp as Record<string, unknown> | undefined;
|
|
439
|
+
const serverMap = mcpConfig?.servers as
|
|
440
|
+
| Record<string, Record<string, unknown>>
|
|
441
|
+
| undefined;
|
|
451
442
|
|
|
452
|
-
if (!
|
|
443
|
+
if (!serverMap || !serverMap[name]) {
|
|
453
444
|
throw new NotFoundError(`MCP server "${name}" not found.`);
|
|
454
445
|
}
|
|
455
446
|
|
|
447
|
+
const server = serverMap[name];
|
|
448
|
+
|
|
456
449
|
if (headers !== undefined) {
|
|
457
450
|
const transport = server.transport as Record<string, unknown> | undefined;
|
|
458
451
|
if (
|
|
@@ -481,7 +474,7 @@ async function handleMcpUpdate({
|
|
|
481
474
|
}
|
|
482
475
|
}
|
|
483
476
|
|
|
484
|
-
|
|
477
|
+
saveRawConfig(raw);
|
|
485
478
|
triggerReload("internal_mcp_update");
|
|
486
479
|
|
|
487
480
|
return { updated: true };
|
|
@@ -501,7 +494,7 @@ async function handleMcpAdd({
|
|
|
501
494
|
body,
|
|
502
495
|
);
|
|
503
496
|
|
|
504
|
-
let transport:
|
|
497
|
+
let transport: Record<string, unknown>;
|
|
505
498
|
switch (transportType) {
|
|
506
499
|
case "stdio":
|
|
507
500
|
if (!command) {
|
|
@@ -524,16 +517,27 @@ async function handleMcpAdd({
|
|
|
524
517
|
);
|
|
525
518
|
}
|
|
526
519
|
|
|
527
|
-
const
|
|
520
|
+
const raw = loadRawConfig();
|
|
521
|
+
if (!raw.mcp) {
|
|
522
|
+
raw.mcp = { servers: {} };
|
|
523
|
+
}
|
|
524
|
+
const mcpConfig = raw.mcp as Record<string, unknown>;
|
|
525
|
+
if (!mcpConfig.servers) {
|
|
526
|
+
mcpConfig.servers = {};
|
|
527
|
+
}
|
|
528
|
+
const serverMap = mcpConfig.servers as Record<string, unknown>;
|
|
528
529
|
|
|
529
|
-
if (
|
|
530
|
+
if (serverMap[name]) {
|
|
530
531
|
throw new BadRequestError(
|
|
531
532
|
`MCP server "${name}" already exists. Remove it first with: assistant mcp remove ${name}`,
|
|
532
533
|
);
|
|
533
534
|
}
|
|
534
535
|
|
|
535
|
-
|
|
536
|
+
serverMap[name] = {
|
|
537
|
+
transport,
|
|
538
|
+
};
|
|
536
539
|
|
|
540
|
+
// Store auth headers in credential store, not config
|
|
537
541
|
if (headers && Object.keys(headers).length > 0) {
|
|
538
542
|
const ok = await setMcpHeaders(name, headers);
|
|
539
543
|
if (!ok) {
|
|
@@ -543,7 +547,7 @@ async function handleMcpAdd({
|
|
|
543
547
|
}
|
|
544
548
|
}
|
|
545
549
|
|
|
546
|
-
|
|
550
|
+
saveRawConfig(raw);
|
|
547
551
|
triggerReload("internal_mcp_add");
|
|
548
552
|
|
|
549
553
|
return { added: true };
|
|
@@ -560,7 +564,8 @@ async function handleMcpAuthRevoke({
|
|
|
560
564
|
}): Promise<{ revoked: true }> {
|
|
561
565
|
const { serverId } = parseBody(McpServerIdParams, body);
|
|
562
566
|
|
|
563
|
-
const
|
|
567
|
+
const raw = loadRawConfig();
|
|
568
|
+
const servers = (raw.mcp as Partial<McpConfig> | undefined)?.servers ?? {};
|
|
564
569
|
const serverConfig = servers[serverId];
|
|
565
570
|
|
|
566
571
|
if (!serverConfig) {
|
|
@@ -597,29 +602,32 @@ async function handleMcpRemove({
|
|
|
597
602
|
}): Promise<{ removed: true }> {
|
|
598
603
|
const { name } = parseBody(McpRemoveParams, body);
|
|
599
604
|
|
|
600
|
-
const
|
|
601
|
-
const
|
|
605
|
+
const raw = loadRawConfig();
|
|
606
|
+
const mcpConfig = raw.mcp as Record<string, unknown> | undefined;
|
|
607
|
+
const serverMap = mcpConfig?.servers as Record<string, unknown> | undefined;
|
|
602
608
|
|
|
603
|
-
if (!
|
|
609
|
+
if (!serverMap || !serverMap[name]) {
|
|
604
610
|
throw new NotFoundError(`MCP server "${name}" not found.`);
|
|
605
611
|
}
|
|
606
612
|
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
613
|
+
// Best-effort cleanup of credentials stored for this server
|
|
614
|
+
const serverConfig = serverMap[name] as Record<string, unknown>;
|
|
615
|
+
const transport = serverConfig?.transport as
|
|
616
|
+
| Record<string, unknown>
|
|
617
|
+
| undefined;
|
|
618
|
+
if (transport?.type === "sse" || transport?.type === "streamable-http") {
|
|
611
619
|
try {
|
|
612
620
|
await Promise.all([
|
|
613
621
|
deleteMcpOAuthCredentials(name),
|
|
614
622
|
deleteMcpHeaders(name),
|
|
615
623
|
]);
|
|
616
624
|
} catch {
|
|
617
|
-
//
|
|
625
|
+
// Ignore — credentials may not exist
|
|
618
626
|
}
|
|
619
627
|
}
|
|
620
628
|
|
|
621
|
-
delete
|
|
622
|
-
|
|
629
|
+
delete serverMap[name];
|
|
630
|
+
saveRawConfig(raw);
|
|
623
631
|
triggerReload("internal_mcp_remove");
|
|
624
632
|
|
|
625
633
|
return { removed: true };
|
|
@@ -22,8 +22,8 @@ import { PassThrough, Readable } from "node:stream";
|
|
|
22
22
|
|
|
23
23
|
import { z } from "zod";
|
|
24
24
|
|
|
25
|
+
import { getPlatformAssistantId } from "../../config/env.js";
|
|
25
26
|
import { invalidateConfigCache } from "../../config/loader.js";
|
|
26
|
-
import { resolvePlatformAssistantId } from "../../config/platform-identity.js";
|
|
27
27
|
import { getAssistantName } from "../../daemon/identity-helpers.js";
|
|
28
28
|
import { runAsyncSqlite } from "../../persistence/db-async-query.js";
|
|
29
29
|
import {
|
|
@@ -236,14 +236,28 @@ interface ExportManifestInputs {
|
|
|
236
236
|
/**
|
|
237
237
|
* Resolve the `assistant.id` for an export.
|
|
238
238
|
*
|
|
239
|
-
*
|
|
240
|
-
*
|
|
239
|
+
* Mirrors `platform/client.ts`'s precedence: in-memory override (set at
|
|
240
|
+
* daemon startup or by secret-routes) → credential store → daemon-internal
|
|
241
|
+
* fallback. The schema requires `id` to be non-empty, so we fall back to
|
|
241
242
|
* `DAEMON_INTERNAL_ASSISTANT_ID` rather than the empty string.
|
|
242
243
|
*/
|
|
243
244
|
async function resolveAssistantId(): Promise<string> {
|
|
244
|
-
const
|
|
245
|
-
if (
|
|
246
|
-
return
|
|
245
|
+
const inMemory = getPlatformAssistantId();
|
|
246
|
+
if (inMemory) {
|
|
247
|
+
return inMemory;
|
|
248
|
+
}
|
|
249
|
+
try {
|
|
250
|
+
const stored = await getSecureKeyAsync(
|
|
251
|
+
credentialKey("vellum", "platform_assistant_id"),
|
|
252
|
+
);
|
|
253
|
+
if (stored) {
|
|
254
|
+
return stored;
|
|
255
|
+
}
|
|
256
|
+
} catch (err) {
|
|
257
|
+
log.warn(
|
|
258
|
+
{ err },
|
|
259
|
+
"Failed to read platform_assistant_id from credential store; falling back to daemon-internal id",
|
|
260
|
+
);
|
|
247
261
|
}
|
|
248
262
|
return DAEMON_INTERNAL_ASSISTANT_ID;
|
|
249
263
|
}
|
|
@@ -39,17 +39,7 @@ import {
|
|
|
39
39
|
} from "@vellumai/service-contracts/platform-credential";
|
|
40
40
|
import { z } from "zod";
|
|
41
41
|
|
|
42
|
-
import {
|
|
43
|
-
setPlatformAssistantId,
|
|
44
|
-
setPlatformBaseUrl,
|
|
45
|
-
setPlatformOrganizationId,
|
|
46
|
-
setPlatformUserId,
|
|
47
|
-
} from "../../config/env.js";
|
|
48
42
|
import { isPlatformRemote } from "../../config/env-registry.js";
|
|
49
|
-
import {
|
|
50
|
-
resolvePlatformOrganizationId,
|
|
51
|
-
resolvePlatformUserId,
|
|
52
|
-
} from "../../config/platform-identity.js";
|
|
53
43
|
import {
|
|
54
44
|
registerCallbackRoute,
|
|
55
45
|
resolvePlatformCallbackRegistrationContext,
|
|
@@ -299,12 +289,24 @@ async function handlePlatformStatus(
|
|
|
299
289
|
): Promise<PlatformStatusResponse> {
|
|
300
290
|
const context = await resolvePlatformCallbackRegistrationContext();
|
|
301
291
|
|
|
302
|
-
const [
|
|
303
|
-
|
|
304
|
-
|
|
292
|
+
const [orgIdRaw, userIdRaw, webhookSecretRaw] = await Promise.all([
|
|
293
|
+
getSecureKeyAsync(
|
|
294
|
+
credentialKey(
|
|
295
|
+
CREDENTIAL_KEYS.organizationId.service,
|
|
296
|
+
CREDENTIAL_KEYS.organizationId.field,
|
|
297
|
+
),
|
|
298
|
+
),
|
|
299
|
+
getSecureKeyAsync(
|
|
300
|
+
credentialKey(
|
|
301
|
+
CREDENTIAL_KEYS.userId.service,
|
|
302
|
+
CREDENTIAL_KEYS.userId.field,
|
|
303
|
+
),
|
|
304
|
+
),
|
|
305
305
|
getSecureKeyAsync(credentialKey("vellum", "webhook_secret")),
|
|
306
306
|
]);
|
|
307
307
|
|
|
308
|
+
const organizationId = orgIdRaw?.trim() ?? "";
|
|
309
|
+
const userId = userIdRaw?.trim() ?? "";
|
|
308
310
|
const hasWebhookSecret = !!webhookSecretRaw;
|
|
309
311
|
|
|
310
312
|
return {
|
|
@@ -465,11 +467,6 @@ async function handlePlatformDisconnect(
|
|
|
465
467
|
);
|
|
466
468
|
}
|
|
467
469
|
|
|
468
|
-
setPlatformBaseUrl(undefined);
|
|
469
|
-
setPlatformAssistantId(undefined);
|
|
470
|
-
setPlatformOrganizationId(undefined);
|
|
471
|
-
setPlatformUserId(undefined);
|
|
472
|
-
|
|
473
470
|
// Notify connected clients
|
|
474
471
|
broadcastMessage({ type: "platform_disconnected" });
|
|
475
472
|
|