@vellumai/assistant 0.10.2-dev.202606250318.5e7cfb0 → 0.10.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/bun.lock +0 -20
- package/docs/workspace-tools.md +33 -42
- package/eslint-rules/cli-no-daemon-internals.js +0 -6
- package/node_modules/@vellumai/gateway-client/src/__tests__/trust-verdict-contract.test.ts +0 -31
- package/node_modules/@vellumai/gateway-client/src/gateway-ipc-contracts.ts +0 -44
- package/node_modules/@vellumai/gateway-client/src/index.ts +0 -14
- package/node_modules/@vellumai/gateway-client/src/trust-verdict-contract.ts +0 -17
- package/node_modules/@vellumai/service-contracts/package.json +0 -1
- package/node_modules/@vellumai/service-contracts/src/index.ts +0 -1
- package/openapi.yaml +0 -155
- package/package.json +1 -4
- package/scripts/test.sh +15 -36
- package/src/__tests__/actor-token-service.test.ts +14 -36
- package/src/__tests__/agent-loop-override-profile.test.ts +0 -1
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +0 -2
- package/src/__tests__/agent-wake-override-profile.test.ts +0 -2
- package/src/__tests__/annotate-activity-metadata.test.ts +0 -2
- package/src/__tests__/annotate-risk-options.test.ts +0 -2
- package/src/__tests__/approval-cascade.test.ts +0 -2
- package/src/__tests__/assistant-attachments.test.ts +0 -42
- package/src/__tests__/background-workers-disk-pressure.test.ts +0 -2
- package/src/__tests__/btw-routes.test.ts +0 -2
- package/src/__tests__/build-persisted-content.test.ts +0 -2
- package/src/__tests__/call-controller.test.ts +0 -19
- package/src/__tests__/channel-guardian.test.ts +58 -94
- package/src/__tests__/channel-reply-delivery.test.ts +0 -2
- package/src/__tests__/compaction-events.test.ts +0 -2
- package/src/__tests__/compaction.benchmark.test.ts +0 -2
- package/src/__tests__/compactor-call-site-logging.test.ts +0 -2
- package/src/__tests__/compactor-low-watermark-cut.test.ts +0 -2
- package/src/__tests__/compactor-preserved-tail-count.test.ts +0 -2
- package/src/__tests__/compactor-summary-call-truncation.test.ts +0 -2
- package/src/__tests__/compactor-web-search-strip.test.ts +0 -2
- package/src/__tests__/config-loader-backfill.test.ts +10 -123
- package/src/__tests__/config-schema.test.ts +0 -1
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +29 -31
- package/src/__tests__/contacts-relay-reads.test.ts +15 -13
- package/src/__tests__/conversation-abort-tool-results.test.ts +0 -2
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +0 -2
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +0 -2
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +0 -2
- package/src/__tests__/conversation-agent-loop.test.ts +0 -134
- package/src/__tests__/conversation-analysis-routes.test.ts +0 -2
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +0 -2
- package/src/__tests__/conversation-confirmation-signals.test.ts +0 -2
- package/src/__tests__/conversation-history-web-search.test.ts +0 -2
- package/src/__tests__/conversation-load-history-repair.test.ts +0 -2
- package/src/__tests__/conversation-load-history-stripped.test.ts +0 -2
- package/src/__tests__/conversation-pairing.test.ts +0 -2
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +0 -2
- package/src/__tests__/conversation-process-callsite.test.ts +0 -2
- package/src/__tests__/conversation-provider-retry-repair.test.ts +0 -2
- package/src/__tests__/conversation-queue.test.ts +0 -91
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +0 -14
- package/src/__tests__/conversation-routes-slash-commands.test.ts +0 -14
- package/src/__tests__/conversation-slash-queue.test.ts +0 -2
- package/src/__tests__/conversation-slash-unknown.test.ts +0 -2
- package/src/__tests__/conversation-speed-override.test.ts +0 -2
- package/src/__tests__/conversation-surfaces-task-progress.test.ts +0 -29
- package/src/__tests__/conversation-title-service.test.ts +0 -2
- package/src/__tests__/conversation-tool-setup-attribution.test.ts +0 -47
- package/src/__tests__/conversation-usage.test.ts +0 -2
- package/src/__tests__/conversation-workspace-cache-state.test.ts +0 -2
- package/src/__tests__/conversation-workspace-injection.test.ts +0 -2
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +0 -2
- package/src/__tests__/credential-security-invariants.test.ts +1 -1
- package/src/__tests__/db-migration-rollback.test.ts +171 -205
- package/src/__tests__/db-test-helpers.ts +4 -5
- package/src/__tests__/deterministic-verification-control-plane.test.ts +2 -4
- package/src/__tests__/disk-pressure-guard.test.ts +0 -41
- package/src/__tests__/dm-persistence.test.ts +0 -2
- package/src/__tests__/emit-signal-routing-intent.test.ts +5 -10
- package/src/__tests__/events-dev-bypass-actor.test.ts +1 -7
- package/src/__tests__/exploration-drift-hook.test.ts +2 -3
- package/src/__tests__/filing-service.test.ts +0 -2
- package/src/__tests__/guardian-binding-drift-heal.test.ts +10 -75
- package/src/__tests__/guardian-dispatch.test.ts +1 -95
- package/src/__tests__/guardian-outbound-http.test.ts +0 -13
- package/src/__tests__/heartbeat-disk-pressure.test.ts +0 -2
- package/src/__tests__/heartbeat-service.test.ts +0 -2
- package/src/__tests__/helpers/channel-test-adapter.ts +7 -1
- package/src/__tests__/host-app-control-routes.test.ts +30 -24
- package/src/__tests__/host-bash-routes.test.ts +41 -31
- package/src/__tests__/host-browser-routes.test.ts +32 -26
- package/src/__tests__/host-cu-routes-targeted.test.ts +33 -25
- package/src/__tests__/host-file-routes-targeted.test.ts +52 -40
- package/src/__tests__/host-transfer-routes-targeted.test.ts +43 -31
- package/src/__tests__/http-user-message-parity.test.ts +8 -290
- package/src/__tests__/inbound-invite-redemption.test.ts +0 -28
- package/src/__tests__/inbound-slack-persistence.test.ts +0 -2
- package/src/__tests__/invite-redemption-service.test.ts +0 -198
- package/src/__tests__/llm-context-normalization.test.ts +0 -105
- package/src/__tests__/llm-request-log-error-payload.test.ts +9 -71
- package/src/__tests__/llm-usage-store.test.ts +0 -25
- package/src/__tests__/mcp-health-check.test.ts +1 -2
- package/src/__tests__/media-stream-server-integration.test.ts +0 -127
- package/src/__tests__/memory-retrieval-hook.test.ts +0 -2
- package/src/__tests__/messaging-send-tool.test.ts +0 -2
- package/src/__tests__/migration-import-from-url.test.ts +2 -2
- package/src/__tests__/mtime-cache.test.ts +5 -146
- package/src/__tests__/native-web-search.test.ts +0 -2
- package/src/__tests__/non-member-access-request.test.ts +17 -189
- package/src/__tests__/notification-broadcaster.test.ts +0 -4
- package/src/__tests__/notification-decision-recipient-context.test.ts +32 -33
- package/src/__tests__/notification-deep-link.test.ts +0 -6
- package/src/__tests__/notification-guardian-path.test.ts +0 -19
- package/src/__tests__/openai-provider.test.ts +12 -22
- package/src/__tests__/openai-responses-provider.test.ts +2 -12
- package/src/__tests__/outbound-slack-persistence.test.ts +0 -2
- package/src/__tests__/pending-interactions-resolved-event.test.ts +4 -7
- package/src/__tests__/persistence-secret-redaction.test.ts +0 -2
- package/src/__tests__/plugin-bootstrap.test.ts +73 -3
- package/src/__tests__/plugin-route-contribution.test.ts +17 -4
- package/src/__tests__/plugin-tool-contribution.test.ts +18 -3
- package/src/__tests__/plugin-types.test.ts +2 -0
- package/src/__tests__/process-message-background-slack.test.ts +0 -2
- package/src/__tests__/process-message-display-content.test.ts +0 -2
- package/src/__tests__/provider-error-scenarios.test.ts +4 -5
- package/src/__tests__/provider-usage-tracking.test.ts +0 -39
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +0 -2
- package/src/__tests__/registry.test.ts +1 -4
- package/src/__tests__/relay-server.test.ts +25 -694
- package/src/__tests__/runtime-attachment-metadata.test.ts +1 -0
- package/src/__tests__/secret-ingress-http.test.ts +0 -14
- package/src/__tests__/send-endpoint-busy.test.ts +8 -30
- package/src/__tests__/skills.test.ts +0 -44
- package/src/__tests__/slack-inbound-verification.test.ts +2 -47
- package/src/__tests__/stt-hints.test.ts +13 -44
- package/src/__tests__/subagent-detail.test.ts +0 -27
- package/src/__tests__/subagent-disposal.test.ts +0 -65
- package/src/__tests__/subagent-notify-parent.test.ts +0 -2
- package/src/__tests__/subagent-role-registry.test.ts +2 -7
- package/src/__tests__/subagent-spawn-tool-fork.test.ts +0 -2
- package/src/__tests__/subagent-tools.test.ts +0 -2
- package/src/__tests__/suggestion-routes.test.ts +0 -2
- package/src/__tests__/title-generate-hook.test.ts +0 -2
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +0 -2
- package/src/__tests__/tool-executor.test.ts +11 -16
- package/src/__tests__/tool-preview-lifecycle.test.ts +0 -2
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +0 -2
- package/src/__tests__/tool-start-timestamp.test.ts +0 -2
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +10 -10
- package/src/__tests__/twilio-routes.test.ts +0 -96
- package/src/__tests__/ui-file-upload-surface.test.ts +0 -86
- package/src/__tests__/verification-control-plane-policy.test.ts +0 -2
- package/src/__tests__/voice-invite-redemption.test.ts +0 -33
- package/src/__tests__/web-search-backend-failure.test.ts +0 -2
- package/src/__tests__/workspace-migration-remove-hooks.test.ts +35 -14
- package/src/__tests__/workspace-tool-loader.test.ts +2 -195
- package/src/__tests__/workspace-tools-watcher-flag.test.ts +70 -0
- package/src/agent/loop.ts +0 -56
- package/src/api/index.ts +1 -19
- package/src/api/responses/llm-request-log-entry.ts +0 -29
- package/src/api/responses/subagent-detail.ts +0 -17
- package/src/api/surfaces.ts +3 -39
- package/src/approvals/guardian-request-resolvers.ts +11 -1
- package/src/calls/__tests__/relay-setup-router.test.ts +4 -262
- package/src/calls/call-domain.ts +3 -3
- package/src/calls/guardian-dispatch.ts +8 -10
- package/src/calls/inbound-trust-reader.ts +1 -17
- package/src/calls/media-stream-server.ts +0 -21
- package/src/calls/relay-server.ts +50 -167
- package/src/calls/relay-setup-router.ts +7 -37
- package/src/calls/relay-verification.ts +4 -4
- package/src/calls/stt-hints.ts +12 -9
- package/src/calls/twilio-routes.ts +4 -14
- package/src/channels/types.ts +20 -10
- package/src/cli/commands/__tests__/cache.test.ts +1 -8
- package/src/cli/commands/cache.ts +181 -194
- package/src/cli/commands/db/__tests__/repair.test.ts +5 -6
- package/src/cli/commands/db/status.ts +1 -37
- package/src/cli/commands/mcp.ts +218 -252
- package/src/cli/commands/memory/index.ts +0 -2
- package/src/cli/commands/plugins.ts +3 -75
- package/src/cli/lib/__tests__/install-from-github.test.ts +0 -102
- package/src/cli/lib/__tests__/list-installed-plugins.test.ts +1 -160
- package/src/cli/lib/list-installed-plugins.ts +1 -179
- package/src/config/__tests__/sync-gated-profiles.test.ts +3 -11
- package/src/config/bundled-skills/contacts/tools/contact-merge.ts +17 -27
- package/src/config/bundled-skills/contacts/tools/contact-search.ts +3 -13
- package/src/config/bundled-skills/subagent/SKILL.md +1 -1
- package/src/config/bundled-skills/subagent/TOOLS.json +1 -1
- package/src/config/feature-flag-registry.json +13 -5
- package/src/config/loader.ts +5 -38
- package/src/config/schemas/__tests__/memory-v3.test.ts +0 -1
- package/src/config/schemas/memory-lifecycle.ts +0 -12
- package/src/config/schemas/memory-v3.ts +0 -7
- package/src/config/schemas/memory.ts +0 -4
- package/src/config/schemas/timeouts.ts +0 -8
- package/src/config/seed-inference-profiles.ts +11 -21
- package/src/config/skills.ts +5 -27
- package/src/config/sync-gated-profiles.ts +13 -12
- package/src/contacts/contacts-write.ts +0 -3
- package/src/daemon/assistant-attachments.ts +4 -27
- package/src/daemon/conversation-agent-loop.ts +0 -28
- package/src/daemon/conversation-process.ts +16 -35
- package/src/daemon/conversation-surfaces.ts +38 -111
- package/src/daemon/conversation-tool-setup.ts +16 -50
- package/src/daemon/conversation.ts +1 -13
- package/src/daemon/disk-pressure-guard.ts +2 -12
- package/src/daemon/event-loop-watchdog.ts +1 -28
- package/src/daemon/external-plugins-bootstrap.ts +34 -4
- package/src/daemon/handlers/__tests__/config-a2a-redeem.test.ts +0 -25
- package/src/daemon/handlers/config-a2a.ts +14 -6
- package/src/daemon/handlers/config-channels.ts +22 -78
- package/src/daemon/handlers/conversations.ts +0 -77
- package/src/daemon/lifecycle.ts +0 -4
- package/src/daemon/mcp-reload-service.ts +0 -10
- package/src/daemon/memory-v2-startup.test.ts +0 -72
- package/src/daemon/memory-v2-startup.ts +19 -87
- package/src/daemon/message-types/conversations.ts +0 -2
- package/src/daemon/message-types/surfaces.ts +12 -12
- package/src/daemon/server.ts +4 -0
- package/src/daemon/shutdown-handlers.ts +0 -20
- package/src/daemon/tool-setup-types.ts +0 -9
- package/src/daemon/workspace-tools-watcher.ts +328 -0
- package/src/ipc/__tests__/clients-list-ipc.test.ts +1 -1
- package/src/ipc/assistant-server.ts +2 -2
- package/src/mcp/__tests__/mcp-auth-orchestrator.test.ts +0 -1
- package/src/mcp/client.ts +1 -15
- package/src/mcp/mcp-auth-orchestrator.ts +1 -6
- package/src/mcp/mcp-oauth-provider.ts +8 -19
- package/src/memory/__tests__/memory-retrospective-job.test.ts +0 -8
- package/src/memory/conversation-crud.ts +0 -38
- package/src/memory/db-connection.ts +3 -22
- package/src/memory/db-init.ts +502 -36
- package/src/memory/db-singleton.ts +4 -6
- package/src/memory/jobs-worker.ts +0 -58
- package/src/memory/llm-request-log-store.ts +1 -26
- package/src/memory/llm-usage-store.ts +20 -48
- package/src/memory/memory-retrospective-job.ts +8 -9
- package/src/memory/migrations/209-strip-thinking-from-consolidated.ts +56 -130
- package/src/memory/migrations/__tests__/run-migrations.test.ts +2 -2
- package/src/memory/migrations/registry.ts +573 -0
- package/src/memory/migrations/run-migrations.ts +6 -90
- package/src/memory/migrations/validate-migration-state.ts +66 -101
- package/src/memory/schema/conversations.ts +0 -9
- package/src/memory/schema/infrastructure.ts +0 -20
- package/src/memory/v2/__tests__/cli-command-store.test.ts +0 -25
- package/src/memory/v2/__tests__/skill-store.test.ts +0 -80
- package/src/memory/v2/cli-command-store.ts +38 -75
- package/src/memory/v2/prompts/consolidation.ts +82 -13
- package/src/memory/v2/prompts/router.ts +93 -21
- package/src/memory/v2/skill-store.ts +31 -68
- package/src/notifications/__tests__/broadcaster.test.ts +8 -16
- package/src/notifications/__tests__/decision-engine.test.ts +9 -78
- package/src/notifications/broadcaster.ts +1 -8
- package/src/notifications/decision-engine.ts +7 -15
- package/src/notifications/destination-resolver.ts +24 -68
- package/src/notifications/emit-signal.ts +14 -39
- package/src/permissions/question-prompter.test.ts +1 -1
- package/src/permissions/question-prompter.ts +4 -7
- package/src/plugin-api/index.ts +6 -6
- package/src/plugin-api/types.ts +5 -3
- package/src/plugin-api/vision-support.test.ts +4 -28
- package/src/plugin-api/vision-support.ts +31 -66
- package/src/plugins/defaults/advisor/__tests__/consult.test.ts +0 -161
- package/src/plugins/defaults/advisor/consult.ts +6 -110
- package/src/plugins/defaults/advisor/steering.ts +2 -14
- package/src/plugins/defaults/advisor/tools/advisor.ts +5 -32
- package/src/plugins/defaults/exploration-drift/hooks/post-tool-use.ts +1 -2
- package/src/plugins/defaults/image-fallback/__tests__/image-fallback.test.ts +7 -47
- package/src/plugins/defaults/image-fallback/hooks/post-tool-use.ts +11 -10
- package/src/plugins/defaults/image-fallback/hooks/user-prompt-submit.ts +20 -12
- package/src/plugins/defaults/image-fallback/src/caption-blocks.ts +11 -42
- package/src/plugins/defaults/memory-v3-shadow/__tests__/injection.test.ts +3 -33
- package/src/plugins/defaults/memory-v3-shadow/__tests__/pool-select.test.ts +4 -48
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +8 -4
- package/src/plugins/defaults/memory-v3-shadow/injector.ts +15 -43
- package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +2 -11
- package/src/plugins/defaults/memory-v3-shadow/pool-select.ts +13 -77
- package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +11 -12
- package/src/plugins/mtime-cache.ts +291 -76
- package/src/plugins/pipeline.ts +13 -111
- package/src/plugins/types.ts +2 -0
- package/src/providers/anthropic/client.ts +0 -5
- package/src/providers/call-site-routing.ts +0 -4
- package/src/providers/model-catalog.ts +0 -16
- package/src/providers/openai/__tests__/api-error-detail.test.ts +120 -0
- package/src/providers/openai/chat-completions-provider.ts +83 -37
- package/src/providers/openai/responses-provider.ts +46 -50
- package/src/providers/openrouter/client.ts +0 -5
- package/src/providers/provider-send-message.ts +0 -4
- package/src/providers/ratelimit.ts +0 -4
- package/src/providers/retry.ts +0 -4
- package/src/providers/types.ts +0 -9
- package/src/providers/usage-tracking.ts +0 -4
- package/src/runtime/__tests__/trust-verdict-consumer.test.ts +3 -335
- package/src/runtime/access-request-helper.ts +39 -19
- package/src/runtime/actor-trust-resolver.ts +2 -2
- package/src/runtime/assistant-event-hub.ts +1 -1
- package/src/runtime/assistant-stream-state.ts +2 -9
- package/src/runtime/auth/require-bound-guardian.ts +11 -21
- package/src/runtime/channel-verification-service.ts +31 -56
- package/src/runtime/confirmation-request-guardian-bridge.ts +3 -3
- package/src/runtime/guardian-vellum-migration.ts +7 -66
- package/src/runtime/invite-redemption-service.ts +187 -198
- package/src/runtime/local-actor-identity.ts +11 -76
- package/src/runtime/pending-interactions.ts +1 -11
- package/src/runtime/routes/__tests__/channel-verification-revoke.test.ts +5 -56
- package/src/runtime/routes/__tests__/channel-verification-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/surface-action-routes.test.ts +0 -187
- package/src/runtime/routes/browser-routes.ts +1 -1
- package/src/runtime/routes/canonical-guardian-expiry-sweep.ts +5 -13
- package/src/runtime/routes/channel-verification-routes.ts +3 -3
- package/src/runtime/routes/contact-routes.ts +32 -8
- package/src/runtime/routes/conversation-cli-routes.ts +5 -4
- package/src/runtime/routes/conversation-list-routes.ts +7 -4
- package/src/runtime/routes/conversation-query-routes.ts +0 -72
- package/src/runtime/routes/conversation-routes.ts +85 -84
- package/src/runtime/routes/events-routes.ts +2 -2
- package/src/runtime/routes/global-search-routes.ts +1 -3
- package/src/runtime/routes/guardian-action-routes.ts +5 -4
- package/src/runtime/routes/host-app-control-routes.ts +4 -5
- package/src/runtime/routes/host-bash-routes.ts +4 -5
- package/src/runtime/routes/host-browser-routes.ts +11 -9
- package/src/runtime/routes/host-cu-routes.ts +4 -5
- package/src/runtime/routes/host-file-routes.ts +4 -5
- package/src/runtime/routes/host-transfer-routes.ts +6 -6
- package/src/runtime/routes/http-adapter.ts +1 -1
- package/src/runtime/routes/identity-routes.ts +2 -3
- package/src/runtime/routes/inbound-message-handler.ts +5 -5
- package/src/runtime/routes/inbound-stages/acl-enforcement.test.ts +5 -97
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +49 -61
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +4 -16
- package/src/runtime/routes/inbound-stages/escalation-intercept.ts +7 -7
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.test.ts +8 -21
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +3 -14
- package/src/runtime/routes/index.ts +0 -2
- package/src/runtime/routes/llm-context-normalization.ts +0 -83
- package/src/runtime/routes/mcp-auth-routes.ts +19 -171
- package/src/runtime/routes/migration-rollback-routes.ts +3 -4
- package/src/runtime/routes/migration-routes.ts +1 -4
- package/src/runtime/routes/subagents-routes.ts +0 -5
- package/src/runtime/routes/surface-action-routes.ts +56 -42
- package/src/runtime/services/__tests__/conversation-serializer.test.ts +0 -1
- package/src/runtime/services/conversation-serializer.ts +9 -7
- package/src/runtime/tool-grant-request-helper.ts +3 -3
- package/src/runtime/trust-verdict-consumer.ts +9 -85
- package/src/runtime/verification-outbound-actions.ts +18 -18
- package/src/signals/user-message.ts +0 -16
- package/src/subagent/manager.ts +0 -9
- package/src/subagent/types.ts +3 -3
- package/src/telemetry/types.ts +1 -34
- package/src/telemetry/usage-telemetry-reporter.test.ts +2 -3
- package/src/telemetry/usage-telemetry-reporter.ts +3 -87
- package/src/tools/ask-question/ask-question-tool.test.ts +0 -29
- package/src/tools/ask-question/ask-question-tool.ts +0 -13
- package/src/tools/executor.ts +4 -4
- package/src/tools/registry.ts +0 -18
- package/src/tools/shared/filesystem/path-policy.ts +5 -12
- package/src/tools/tool-approval-handler.ts +1 -1
- package/src/tools/tool-defaults.ts +2 -9
- package/src/tools/tool-manifest.ts +0 -3
- package/src/tools/types.ts +2 -17
- package/src/tools/workspace-tools/loader.ts +244 -348
- package/src/util/errors.ts +1 -26
- package/src/util/platform.ts +0 -5
- package/src/workflows/library.test.ts +0 -140
- package/src/workflows/library.ts +28 -82
- package/src/workspace/migrations/017-seed-persona-dirs.ts +34 -3
- package/src/workspace/migrations/019-scope-journal-to-guardian.ts +24 -3
- package/src/workspace/migrations/048-remove-workspace-hooks.ts +66 -14
- package/src/workspace/migrations/registry.ts +0 -2
- package/node_modules/@vellumai/gateway-client/src/__tests__/guardian-delivery-contract.test.ts +0 -91
- package/node_modules/@vellumai/gateway-client/src/guardian-delivery-contract.ts +0 -48
- package/node_modules/@vellumai/service-contracts/src/__tests__/channels.test.ts +0 -28
- package/node_modules/@vellumai/service-contracts/src/channels.ts +0 -41
- package/src/__tests__/code-search-tool.test.ts +0 -585
- package/src/__tests__/guardian-expiry-notifier.test.ts +0 -282
- package/src/__tests__/mcp-config-secret-boundary.test.ts +0 -390
- package/src/__tests__/plugin-pipeline.test.ts +0 -96
- package/src/__tests__/sse-actor-principal-guardian-source.test.ts +0 -102
- package/src/__tests__/steer-on-enqueue-question.test.ts +0 -181
- package/src/__tests__/workspace-migration-111-prune-seeded-callsite-defaults.test.ts +0 -208
- package/src/agent/loop-exclusive-tool.test.ts +0 -150
- package/src/api/constants/sse-replay.ts +0 -41
- package/src/api/events/conversation-notice.ts +0 -26
- package/src/approvals/guardian-channel-delivery.ts +0 -30
- package/src/approvals/guardian-expiry-notifier.ts +0 -148
- package/src/cli/commands/memory/__tests__/worker.test.ts +0 -302
- package/src/cli/commands/memory/worker.ts +0 -175
- package/src/config/__tests__/loader-callsite-strip-fallback.test.ts +0 -143
- package/src/config/prune-seeded-callsite-defaults.ts +0 -110
- package/src/contacts/__tests__/contacts-write-revoke-relay.test.ts +0 -129
- package/src/contacts/__tests__/guardian-delivery-reader.test.ts +0 -312
- package/src/contacts/__tests__/member-write-relay.test.ts +0 -202
- package/src/contacts/guardian-delivery-reader.ts +0 -223
- package/src/contacts/member-write-relay.ts +0 -189
- package/src/daemon/conversation-notices.ts +0 -60
- package/src/daemon/handlers/__tests__/config-channels.test.ts +0 -225
- package/src/hooks/hook-loader.ts +0 -341
- package/src/mcp/mcp-header-store.ts +0 -134
- package/src/memory/__tests__/301-create-watchdog-events.test.ts +0 -110
- package/src/memory/__tests__/prompt-override.test.ts +0 -192
- package/src/memory/__tests__/watchdog-events-store.test.ts +0 -161
- package/src/memory/migrations/300-add-processing-started-at.ts +0 -30
- package/src/memory/migrations/301-create-watchdog-events.ts +0 -45
- package/src/memory/migrations/__tests__/209-strip-thinking-from-consolidated.test.ts +0 -224
- package/src/memory/prompt-override.ts +0 -129
- package/src/memory/steps.ts +0 -573
- package/src/memory/watchdog-events-store.ts +0 -87
- package/src/memory/worker-control.ts +0 -118
- package/src/memory/worker-process.ts +0 -72
- package/src/notifications/__tests__/connected-channels.test.ts +0 -114
- package/src/notifications/__tests__/destination-resolver.test.ts +0 -256
- package/src/onboarding/checkin-event.test.ts +0 -222
- package/src/onboarding/checkin-event.ts +0 -321
- package/src/onboarding/schedule-checkin.ts +0 -190
- package/src/plugins/defaults/advisor/__tests__/context-pack-gating.test.ts +0 -106
- package/src/plugins/defaults/advisor/__tests__/context-pack.test.ts +0 -60
- package/src/plugins/defaults/advisor/context-pack.ts +0 -288
- package/src/plugins/defaults/memory-v3-shadow/pool-select.test.ts +0 -146
- package/src/plugins/surface-import.ts +0 -121
- package/src/providers/openai/__tests__/api-error-normalization.test.ts +0 -321
- package/src/providers/openai/api-error-normalization.ts +0 -270
- package/src/runtime/__tests__/channel-verification-service.test.ts +0 -133
- package/src/runtime/__tests__/guardian-vellum-migration.test.ts +0 -181
- package/src/runtime/__tests__/is-guardian-bound-for-channel.test.ts +0 -66
- package/src/runtime/__tests__/local-principal-trust.test.ts +0 -164
- package/src/runtime/anchored-guardian.test.ts +0 -156
- package/src/runtime/anchored-guardian.ts +0 -135
- package/src/runtime/auth/__tests__/require-bound-guardian.test.ts +0 -99
- package/src/runtime/local-principal-trust.ts +0 -52
- package/src/runtime/routes/__tests__/contact-routes.test.ts +0 -212
- package/src/runtime/routes/__tests__/global-search-routes.test.ts +0 -93
- package/src/runtime/routes/onboarding-checkin-routes.ts +0 -86
- package/src/tools/filesystem/search.ts +0 -543
- package/src/util/telemetry-db-path.ts +0 -24
- package/src/workspace/migrations/111-prune-seeded-callsite-defaults.ts +0 -134
|
@@ -4,9 +4,7 @@ import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test";
|
|
|
4
4
|
// Mocks — must be set up before importing the module under test
|
|
5
5
|
// ---------------------------------------------------------------------------
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
// null = gateway unreachable.
|
|
9
|
-
let mockGuardianList: Array<Record<string, unknown>> | null = [];
|
|
7
|
+
let mockGuardian: { contact: unknown; channel: unknown } | null = null;
|
|
10
8
|
let mockActiveSession: Record<string, unknown> | null = null;
|
|
11
9
|
let mockSessionResult = {
|
|
12
10
|
sessionId: "sess-1",
|
|
@@ -22,14 +20,8 @@ let deliverChannelReplyCalls: unknown[][] = [];
|
|
|
22
20
|
let emitNotificationSignalCalls: unknown[] = [];
|
|
23
21
|
let messageIdCounter = 0;
|
|
24
22
|
|
|
25
|
-
mock.module("../../../contacts/
|
|
26
|
-
|
|
27
|
-
getGuardianDeliveryFresh: () => Promise.resolve(mockGuardianList),
|
|
28
|
-
guardianForChannel: (
|
|
29
|
-
list: Array<{ channelType: string; status: string }>,
|
|
30
|
-
channelType: string,
|
|
31
|
-
) =>
|
|
32
|
-
list.find((g) => g.channelType === channelType && g.status === "active"),
|
|
23
|
+
mock.module("../../../contacts/contact-store.js", () => ({
|
|
24
|
+
findGuardianForChannel: () => mockGuardian,
|
|
33
25
|
}));
|
|
34
26
|
|
|
35
27
|
mock.module("../../channel-verification-service.js", () => ({
|
|
@@ -104,7 +96,7 @@ function makeParams(
|
|
|
104
96
|
|
|
105
97
|
describe("handleGuardianActivationIntercept", () => {
|
|
106
98
|
beforeEach(() => {
|
|
107
|
-
|
|
99
|
+
mockGuardian = null;
|
|
108
100
|
mockActiveSession = null;
|
|
109
101
|
mockSessionResult = {
|
|
110
102
|
sessionId: "sess-1",
|
|
@@ -163,15 +155,10 @@ describe("handleGuardianActivationIntercept", () => {
|
|
|
163
155
|
});
|
|
164
156
|
|
|
165
157
|
test("bare /start with existing guardian returns null", async () => {
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
expect(createOutboundSessionCalls).toHaveLength(0);
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
test("null guardian list (gateway unreachable) does NOT auto-start", async () => {
|
|
174
|
-
mockGuardianList = null;
|
|
158
|
+
mockGuardian = {
|
|
159
|
+
contact: { id: "contact-1", role: "guardian" },
|
|
160
|
+
channel: { id: "ch-1", type: "telegram" },
|
|
161
|
+
};
|
|
175
162
|
|
|
176
163
|
const result = await handleGuardianActivationIntercept(makeParams());
|
|
177
164
|
expect(result).toBeNull();
|
|
@@ -9,10 +9,7 @@
|
|
|
9
9
|
* the guardian binding, and sends a success reply.
|
|
10
10
|
*/
|
|
11
11
|
import type { ChannelId } from "../../../channels/types.js";
|
|
12
|
-
import {
|
|
13
|
-
getGuardianDeliveryFresh,
|
|
14
|
-
guardianForChannel,
|
|
15
|
-
} from "../../../contacts/guardian-delivery-reader.js";
|
|
12
|
+
import { findGuardianForChannel } from "../../../contacts/contact-store.js";
|
|
16
13
|
import { emitNotificationSignal } from "../../../notifications/emit-signal.js";
|
|
17
14
|
import { getLogger } from "../../../util/logger.js";
|
|
18
15
|
import {
|
|
@@ -91,16 +88,8 @@ export async function handleGuardianActivationIntercept(
|
|
|
91
88
|
// Only proceed for Telegram (can be extended later)
|
|
92
89
|
if (sourceChannel !== "telegram") return null;
|
|
93
90
|
|
|
94
|
-
// If a guardian already exists for this channel, continue to normal flow
|
|
95
|
-
|
|
96
|
-
// transient miss does NOT spuriously auto-start verification.
|
|
97
|
-
// Read fresh: gateway-side binding writes don't invalidate the daemon cache.
|
|
98
|
-
const guardianList = await getGuardianDeliveryFresh({
|
|
99
|
-
channelTypes: [sourceChannel],
|
|
100
|
-
});
|
|
101
|
-
if (guardianList === null || guardianForChannel(guardianList, sourceChannel)) {
|
|
102
|
-
return null;
|
|
103
|
-
}
|
|
91
|
+
// If a guardian already exists for this channel, continue to normal flow
|
|
92
|
+
if (findGuardianForChannel(sourceChannel)) return null;
|
|
104
93
|
|
|
105
94
|
// Can't bind a session without sender identity
|
|
106
95
|
if (!rawSenderId) return null;
|
|
@@ -102,7 +102,6 @@ import { ROUTES as OAUTH_COMMANDS_ROUTES } from "./oauth-commands-routes.js";
|
|
|
102
102
|
import { ROUTES as OAUTH_CONNECT_ROUTES } from "./oauth-connect-routes.js";
|
|
103
103
|
import { ROUTES as OAUTH_LIFECYCLE_ROUTES } from "./oauth-lifecycle-routes.js";
|
|
104
104
|
import { ROUTES as OAUTH_PROVIDERS_ROUTES } from "./oauth-providers.js";
|
|
105
|
-
import { ROUTES as ONBOARDING_CHECKIN_ROUTES } from "./onboarding-checkin-routes.js";
|
|
106
105
|
import { ROUTES as PLATFORM_ROUTES } from "./platform-routes.js";
|
|
107
106
|
import { ROUTES as PLAYGROUND_ROUTES } from "./playground/index.js";
|
|
108
107
|
import { ROUTES as PLUGINS_ROUTES } from "./plugins-routes.js";
|
|
@@ -235,7 +234,6 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
235
234
|
...OAUTH_LIFECYCLE_ROUTES,
|
|
236
235
|
...OAUTH_COMMANDS_ROUTES,
|
|
237
236
|
...OAUTH_PROVIDERS_ROUTES,
|
|
238
|
-
...ONBOARDING_CHECKIN_ROUTES,
|
|
239
237
|
...PLATFORM_ROUTES,
|
|
240
238
|
...PLAYGROUND_ROUTES,
|
|
241
239
|
...PLUGINS_ROUTES,
|
|
@@ -40,31 +40,10 @@ export interface LlmContextSection {
|
|
|
40
40
|
language?: string;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
/**
|
|
44
|
-
* Structured error extracted from a rejected call's response payload.
|
|
45
|
-
* Mirrors the on-disk `responsePayload.error` shape produced by
|
|
46
|
-
* `buildProviderErrorResponsePayload`. Present only when the call failed
|
|
47
|
-
* before returning a response — consumers branch on its presence to
|
|
48
|
-
* render the call as failed.
|
|
49
|
-
*/
|
|
50
|
-
export interface LlmContextError {
|
|
51
|
-
name?: string;
|
|
52
|
-
message?: string;
|
|
53
|
-
code?: string;
|
|
54
|
-
provider?: string;
|
|
55
|
-
statusCode?: number;
|
|
56
|
-
retryAfterMs?: number;
|
|
57
|
-
apiErrorCode?: string;
|
|
58
|
-
apiErrorType?: string;
|
|
59
|
-
apiErrorParam?: string;
|
|
60
|
-
requestId?: string;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
43
|
export interface LlmContextNormalizationResult {
|
|
64
44
|
summary?: LlmContextSummary;
|
|
65
45
|
requestSections?: LlmContextSection[];
|
|
66
46
|
responseSections?: LlmContextSection[];
|
|
67
|
-
error?: LlmContextError;
|
|
68
47
|
}
|
|
69
48
|
|
|
70
49
|
interface NormalizedPayloadCandidate {
|
|
@@ -76,68 +55,6 @@ interface NormalizedPayloadCandidate {
|
|
|
76
55
|
|
|
77
56
|
export function normalizeLlmContextPayloads(
|
|
78
57
|
input: LlmContextNormalizationInput,
|
|
79
|
-
): LlmContextNormalizationResult {
|
|
80
|
-
const base = normalizeSuccessPayloads(input);
|
|
81
|
-
const error = normalizeProviderErrorPayload(input.responsePayload);
|
|
82
|
-
if (!error) {
|
|
83
|
-
return base;
|
|
84
|
-
}
|
|
85
|
-
// A rejected call has no response sections to render — only the request
|
|
86
|
-
// side normalized. Attach the structured error so the inspector can show
|
|
87
|
-
// a failure banner and treat the cost as $0.00 instead of silently
|
|
88
|
-
// falling back to "section rendering unavailable".
|
|
89
|
-
return { ...base, error };
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Detect a provider/transport error stored in the response payload.
|
|
94
|
-
*
|
|
95
|
-
* Error rows are written as `{ error: { name, message, code?, provider?,
|
|
96
|
-
* statusCode?, retryAfterMs? } }` by `buildProviderErrorResponsePayload`.
|
|
97
|
-
* Successful provider responses never carry a top-level `error` object, so
|
|
98
|
-
* the presence of one (with at least one identifying field) is a reliable
|
|
99
|
-
* signal that the call failed.
|
|
100
|
-
*/
|
|
101
|
-
function normalizeProviderErrorPayload(
|
|
102
|
-
responsePayload: unknown,
|
|
103
|
-
): LlmContextError | null {
|
|
104
|
-
const error = asRecord(asRecord(responsePayload)?.error);
|
|
105
|
-
if (!error) {
|
|
106
|
-
return null;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
const name = asString(error.name);
|
|
110
|
-
const message = asString(error.message);
|
|
111
|
-
const code = asString(error.code);
|
|
112
|
-
// Require at least one identifying field so an unrelated `error` key on a
|
|
113
|
-
// success payload isn't misread as a provider failure.
|
|
114
|
-
if (name === undefined && message === undefined && code === undefined) {
|
|
115
|
-
return null;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
const normalized: LlmContextError = {};
|
|
119
|
-
if (name !== undefined) normalized.name = name;
|
|
120
|
-
if (message !== undefined) normalized.message = message;
|
|
121
|
-
if (code !== undefined) normalized.code = code;
|
|
122
|
-
const provider = asString(error.provider);
|
|
123
|
-
if (provider !== undefined) normalized.provider = provider;
|
|
124
|
-
const statusCode = asNumber(error.statusCode);
|
|
125
|
-
if (statusCode !== undefined) normalized.statusCode = statusCode;
|
|
126
|
-
const retryAfterMs = asNumber(error.retryAfterMs);
|
|
127
|
-
if (retryAfterMs !== undefined) normalized.retryAfterMs = retryAfterMs;
|
|
128
|
-
const apiErrorCode = asString(error.apiErrorCode);
|
|
129
|
-
if (apiErrorCode !== undefined) normalized.apiErrorCode = apiErrorCode;
|
|
130
|
-
const apiErrorType = asString(error.apiErrorType);
|
|
131
|
-
if (apiErrorType !== undefined) normalized.apiErrorType = apiErrorType;
|
|
132
|
-
const apiErrorParam = asString(error.apiErrorParam);
|
|
133
|
-
if (apiErrorParam !== undefined) normalized.apiErrorParam = apiErrorParam;
|
|
134
|
-
const requestId = asString(error.requestId);
|
|
135
|
-
if (requestId !== undefined) normalized.requestId = requestId;
|
|
136
|
-
return normalized;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
function normalizeSuccessPayloads(
|
|
140
|
-
input: LlmContextNormalizationInput,
|
|
141
58
|
): LlmContextNormalizationResult {
|
|
142
59
|
const requestCandidates = [
|
|
143
60
|
normalizeOpenAiRequestPayload(input.requestPayload),
|
|
@@ -21,18 +21,10 @@ import { reloadMcpServers } from "../../daemon/mcp-reload-service.js";
|
|
|
21
21
|
import { McpClient } from "../../mcp/client.js";
|
|
22
22
|
import { orchestrateMcpOAuthConnect } from "../../mcp/mcp-auth-orchestrator.js";
|
|
23
23
|
import { getMcpAuthState } from "../../mcp/mcp-auth-state.js";
|
|
24
|
-
import {
|
|
25
|
-
deleteMcpHeaders,
|
|
26
|
-
getMcpHeaders,
|
|
27
|
-
setMcpHeaders,
|
|
28
|
-
} from "../../mcp/mcp-header-store.js";
|
|
29
|
-
import {
|
|
30
|
-
deleteMcpOAuthCredentials,
|
|
31
|
-
hasMcpOAuthTokens,
|
|
32
|
-
} from "../../mcp/mcp-oauth-provider.js";
|
|
24
|
+
import { deleteMcpOAuthCredentials } from "../../mcp/mcp-oauth-provider.js";
|
|
33
25
|
import { getMcpToolsByServer } from "../../tools/registry.js";
|
|
34
26
|
import { getLogger } from "../../util/logger.js";
|
|
35
|
-
import { ACTOR_PRINCIPALS } from "../auth/route-policy.js";
|
|
27
|
+
import { ACTOR_PRINCIPALS, GATEWAY_PRINCIPALS } from "../auth/route-policy.js";
|
|
36
28
|
import { BadRequestError, InternalError, NotFoundError } from "./errors.js";
|
|
37
29
|
import type { RouteDefinition } from "./types.js";
|
|
38
30
|
|
|
@@ -178,23 +170,13 @@ async function checkMachineReadableHealth(
|
|
|
178
170
|
interface McpServerEntry {
|
|
179
171
|
id: string;
|
|
180
172
|
status: string;
|
|
181
|
-
transport:
|
|
173
|
+
transport: McpServerConfig["transport"];
|
|
182
174
|
enabled: boolean;
|
|
183
175
|
defaultRiskLevel: string;
|
|
184
|
-
hasOAuth: boolean;
|
|
185
|
-
hasStaticAuth: boolean;
|
|
186
|
-
authType: "none" | "bearer" | "api-key";
|
|
187
|
-
authHeaderName?: string;
|
|
188
176
|
allowedTools?: string[];
|
|
189
177
|
blockedTools?: string[];
|
|
190
178
|
}
|
|
191
179
|
|
|
192
|
-
function detectAuthType(headers: Record<string, string>): "bearer" | "api-key" {
|
|
193
|
-
const authValue = headers["Authorization"] ?? headers["authorization"];
|
|
194
|
-
if (authValue?.startsWith("Bearer ")) return "bearer";
|
|
195
|
-
return "api-key";
|
|
196
|
-
}
|
|
197
|
-
|
|
198
180
|
async function handleMcpList(_args: {
|
|
199
181
|
body?: Record<string, unknown>;
|
|
200
182
|
}): Promise<{ servers: McpServerEntry[] }> {
|
|
@@ -214,45 +196,12 @@ async function handleMcpList(_args: {
|
|
|
214
196
|
} else {
|
|
215
197
|
status = await checkMachineReadableHealth(id, config);
|
|
216
198
|
}
|
|
217
|
-
const hasOAuth =
|
|
218
|
-
config.transport.type !== "stdio"
|
|
219
|
-
? await hasMcpOAuthTokens(id)
|
|
220
|
-
: false;
|
|
221
|
-
|
|
222
|
-
// Check credential store for stored static auth headers
|
|
223
|
-
const storedHeaders = await getMcpHeaders(id);
|
|
224
|
-
// Also check legacy config-level headers
|
|
225
|
-
const configHeaders =
|
|
226
|
-
config.transport.type !== "stdio"
|
|
227
|
-
? config.transport.headers
|
|
228
|
-
: undefined;
|
|
229
|
-
const effectiveHeaders = storedHeaders ?? configHeaders;
|
|
230
|
-
const hasStaticAuth =
|
|
231
|
-
!!effectiveHeaders && Object.keys(effectiveHeaders).length > 0;
|
|
232
|
-
const authType: "none" | "bearer" | "api-key" = hasStaticAuth
|
|
233
|
-
? detectAuthType(effectiveHeaders!)
|
|
234
|
-
: "none";
|
|
235
|
-
const authHeaderName =
|
|
236
|
-
authType === "api-key" && effectiveHeaders
|
|
237
|
-
? Object.keys(effectiveHeaders).find(
|
|
238
|
-
(k) => k.toLowerCase() !== "authorization",
|
|
239
|
-
)
|
|
240
|
-
: undefined;
|
|
241
|
-
|
|
242
|
-
// Strip headers from transport — never return secrets
|
|
243
|
-
const { headers: _stripped, ...safeTransport } =
|
|
244
|
-
config.transport as Record<string, unknown>;
|
|
245
|
-
|
|
246
199
|
return {
|
|
247
200
|
id,
|
|
248
201
|
status,
|
|
249
|
-
transport:
|
|
202
|
+
transport: config.transport,
|
|
250
203
|
enabled,
|
|
251
204
|
defaultRiskLevel: config.defaultRiskLevel ?? "high",
|
|
252
|
-
hasOAuth,
|
|
253
|
-
hasStaticAuth,
|
|
254
|
-
authType,
|
|
255
|
-
...(authHeaderName && { authHeaderName }),
|
|
256
205
|
...(config.allowedTools && { allowedTools: config.allowedTools }),
|
|
257
206
|
...(config.blockedTools && { blockedTools: config.blockedTools }),
|
|
258
207
|
};
|
|
@@ -332,7 +281,6 @@ async function handleMcpUpdate({
|
|
|
332
281
|
maxTools,
|
|
333
282
|
allowedTools,
|
|
334
283
|
blockedTools,
|
|
335
|
-
headers,
|
|
336
284
|
} = body as {
|
|
337
285
|
name: string;
|
|
338
286
|
enabled?: boolean;
|
|
@@ -340,7 +288,6 @@ async function handleMcpUpdate({
|
|
|
340
288
|
maxTools?: number;
|
|
341
289
|
allowedTools?: string[] | null;
|
|
342
290
|
blockedTools?: string[] | null;
|
|
343
|
-
headers?: Record<string, string> | null;
|
|
344
291
|
};
|
|
345
292
|
|
|
346
293
|
const raw = loadRawConfig();
|
|
@@ -379,33 +326,6 @@ async function handleMcpUpdate({
|
|
|
379
326
|
server.blockedTools = blockedTools;
|
|
380
327
|
}
|
|
381
328
|
}
|
|
382
|
-
if (headers !== undefined) {
|
|
383
|
-
const transport = server.transport as Record<string, unknown> | undefined;
|
|
384
|
-
if (
|
|
385
|
-
transport &&
|
|
386
|
-
(transport.type === "sse" || transport.type === "streamable-http")
|
|
387
|
-
) {
|
|
388
|
-
// Migrate any legacy config-level headers away
|
|
389
|
-
delete transport.headers;
|
|
390
|
-
|
|
391
|
-
// Store in credential store (or delete if clearing)
|
|
392
|
-
if (headers === null || Object.keys(headers).length === 0) {
|
|
393
|
-
const ok = await deleteMcpHeaders(name);
|
|
394
|
-
if (!ok) {
|
|
395
|
-
throw new InternalError(
|
|
396
|
-
"Failed to clear auth headers from credential store",
|
|
397
|
-
);
|
|
398
|
-
}
|
|
399
|
-
} else {
|
|
400
|
-
const ok = await setMcpHeaders(name, headers);
|
|
401
|
-
if (!ok) {
|
|
402
|
-
throw new InternalError(
|
|
403
|
-
"Failed to persist auth headers to credential store",
|
|
404
|
-
);
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
329
|
|
|
410
330
|
saveRawConfig(raw);
|
|
411
331
|
triggerReload("internal_mcp_update");
|
|
@@ -422,17 +342,15 @@ async function handleMcpAdd({
|
|
|
422
342
|
}: {
|
|
423
343
|
body?: Record<string, unknown>;
|
|
424
344
|
}): Promise<{ added: true }> {
|
|
425
|
-
const { name, transportType, url, command, args, risk, disabled
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
headers?: Record<string, string>;
|
|
435
|
-
};
|
|
345
|
+
const { name, transportType, url, command, args, risk, disabled } = body as {
|
|
346
|
+
name: string;
|
|
347
|
+
transportType: string;
|
|
348
|
+
url?: string;
|
|
349
|
+
command?: string;
|
|
350
|
+
args?: string[];
|
|
351
|
+
risk?: string;
|
|
352
|
+
disabled?: boolean;
|
|
353
|
+
};
|
|
436
354
|
|
|
437
355
|
const riskLevel = risk ?? "high";
|
|
438
356
|
if (!["low", "medium", "high"].includes(riskLevel)) {
|
|
@@ -482,60 +400,12 @@ async function handleMcpAdd({
|
|
|
482
400
|
defaultRiskLevel: riskLevel,
|
|
483
401
|
};
|
|
484
402
|
|
|
485
|
-
// Store auth headers in credential store, not config
|
|
486
|
-
if (headers && Object.keys(headers).length > 0) {
|
|
487
|
-
const ok = await setMcpHeaders(name, headers);
|
|
488
|
-
if (!ok) {
|
|
489
|
-
throw new InternalError(
|
|
490
|
-
"Failed to persist auth headers to credential store",
|
|
491
|
-
);
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
|
|
495
403
|
saveRawConfig(raw);
|
|
496
404
|
triggerReload("internal_mcp_add");
|
|
497
405
|
|
|
498
406
|
return { added: true };
|
|
499
407
|
}
|
|
500
408
|
|
|
501
|
-
// ---------------------------------------------------------------------------
|
|
502
|
-
// Revoke OAuth
|
|
503
|
-
// ---------------------------------------------------------------------------
|
|
504
|
-
|
|
505
|
-
async function handleMcpAuthRevoke({
|
|
506
|
-
body,
|
|
507
|
-
}: {
|
|
508
|
-
body?: Record<string, unknown>;
|
|
509
|
-
}): Promise<{ revoked: true }> {
|
|
510
|
-
const { serverId } = body as { serverId: string };
|
|
511
|
-
|
|
512
|
-
const raw = loadRawConfig();
|
|
513
|
-
const servers = (raw.mcp as Partial<McpConfig> | undefined)?.servers ?? {};
|
|
514
|
-
const serverConfig = servers[serverId];
|
|
515
|
-
|
|
516
|
-
if (!serverConfig) {
|
|
517
|
-
throw new NotFoundError(`MCP server "${serverId}" not found`);
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
let result: { ok: boolean; failedKeys: string[] };
|
|
521
|
-
try {
|
|
522
|
-
result = await deleteMcpOAuthCredentials(serverId);
|
|
523
|
-
} catch (err) {
|
|
524
|
-
throw new InternalError(
|
|
525
|
-
`Failed to revoke OAuth credentials: ${err instanceof Error ? err.message : String(err)}`,
|
|
526
|
-
);
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
if (!result.ok) {
|
|
530
|
-
throw new InternalError(
|
|
531
|
-
`Failed to delete OAuth credentials for keys: ${result.failedKeys.join(", ")}`,
|
|
532
|
-
);
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
triggerReload("internal_mcp_auth_revoke");
|
|
536
|
-
return { revoked: true };
|
|
537
|
-
}
|
|
538
|
-
|
|
539
409
|
// ---------------------------------------------------------------------------
|
|
540
410
|
// Remove
|
|
541
411
|
// ---------------------------------------------------------------------------
|
|
@@ -555,17 +425,14 @@ async function handleMcpRemove({
|
|
|
555
425
|
throw new NotFoundError(`MCP server "${name}" not found.`);
|
|
556
426
|
}
|
|
557
427
|
|
|
558
|
-
// Best-effort cleanup of credentials stored for this server
|
|
428
|
+
// Best-effort cleanup of any OAuth credentials stored for this server
|
|
559
429
|
const serverConfig = serverMap[name] as Record<string, unknown>;
|
|
560
430
|
const transport = serverConfig?.transport as
|
|
561
431
|
| Record<string, unknown>
|
|
562
432
|
| undefined;
|
|
563
433
|
if (transport?.type === "sse" || transport?.type === "streamable-http") {
|
|
564
434
|
try {
|
|
565
|
-
await
|
|
566
|
-
deleteMcpOAuthCredentials(name),
|
|
567
|
-
deleteMcpHeaders(name),
|
|
568
|
-
]);
|
|
435
|
+
await deleteMcpOAuthCredentials(name);
|
|
569
436
|
} catch {
|
|
570
437
|
// Ignore — credentials may not exist
|
|
571
438
|
}
|
|
@@ -588,8 +455,8 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
588
455
|
endpoint: "internal/mcp/auth/start",
|
|
589
456
|
method: "POST",
|
|
590
457
|
policy: {
|
|
591
|
-
requiredScopes: ["
|
|
592
|
-
allowedPrincipalTypes:
|
|
458
|
+
requiredScopes: ["internal.write"],
|
|
459
|
+
allowedPrincipalTypes: GATEWAY_PRINCIPALS,
|
|
593
460
|
},
|
|
594
461
|
summary: "Start MCP OAuth flow",
|
|
595
462
|
description:
|
|
@@ -603,8 +470,8 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
603
470
|
endpoint: "internal/mcp/auth/status/:serverId",
|
|
604
471
|
method: "GET",
|
|
605
472
|
policy: {
|
|
606
|
-
requiredScopes: ["
|
|
607
|
-
allowedPrincipalTypes:
|
|
473
|
+
requiredScopes: ["internal.write"],
|
|
474
|
+
allowedPrincipalTypes: GATEWAY_PRINCIPALS,
|
|
608
475
|
},
|
|
609
476
|
summary: "Poll MCP OAuth flow status",
|
|
610
477
|
description:
|
|
@@ -654,7 +521,6 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
654
521
|
.passthrough(),
|
|
655
522
|
enabled: z.boolean(),
|
|
656
523
|
defaultRiskLevel: z.string(),
|
|
657
|
-
hasOAuth: z.boolean(),
|
|
658
524
|
allowedTools: z.array(z.string()).optional(),
|
|
659
525
|
blockedTools: z.array(z.string()).optional(),
|
|
660
526
|
}),
|
|
@@ -713,7 +579,6 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
713
579
|
maxTools: z.number().optional(),
|
|
714
580
|
allowedTools: z.array(z.string()).nullable().optional(),
|
|
715
581
|
blockedTools: z.array(z.string()).nullable().optional(),
|
|
716
|
-
headers: z.record(z.string(), z.string()).nullable().optional(),
|
|
717
582
|
}),
|
|
718
583
|
handler: handleMcpUpdate,
|
|
719
584
|
},
|
|
@@ -737,26 +602,9 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
737
602
|
args: z.array(z.string()).optional(),
|
|
738
603
|
risk: z.string().optional(),
|
|
739
604
|
disabled: z.boolean().optional(),
|
|
740
|
-
headers: z.record(z.string(), z.string()).optional(),
|
|
741
605
|
}),
|
|
742
606
|
handler: handleMcpAdd,
|
|
743
607
|
},
|
|
744
|
-
{
|
|
745
|
-
operationId: "internal_mcp_auth_revoke",
|
|
746
|
-
endpoint: "internal/mcp/auth/revoke",
|
|
747
|
-
method: "POST",
|
|
748
|
-
policy: {
|
|
749
|
-
requiredScopes: ["settings.write"],
|
|
750
|
-
allowedPrincipalTypes: ACTOR_PRINCIPALS,
|
|
751
|
-
},
|
|
752
|
-
summary: "Revoke MCP OAuth credentials",
|
|
753
|
-
description:
|
|
754
|
-
"Deletes stored OAuth tokens for an MCP server and triggers a reload.",
|
|
755
|
-
tags: ["internal"],
|
|
756
|
-
requestBody: z.object({ serverId: z.string() }),
|
|
757
|
-
responseBody: z.object({ revoked: z.boolean() }),
|
|
758
|
-
handler: handleMcpAuthRevoke,
|
|
759
|
-
},
|
|
760
608
|
{
|
|
761
609
|
operationId: "internal_mcp_remove",
|
|
762
610
|
endpoint: "internal/mcp/remove",
|
|
@@ -10,9 +10,8 @@
|
|
|
10
10
|
import { z } from "zod";
|
|
11
11
|
|
|
12
12
|
import { getDb } from "../../memory/db-connection.js";
|
|
13
|
-
import {
|
|
13
|
+
import { getMaxMigrationVersion } from "../../memory/migrations/registry.js";
|
|
14
14
|
import { rollbackMemoryMigration } from "../../memory/migrations/validate-migration-state.js";
|
|
15
|
-
import { migrationSteps } from "../../memory/steps.js";
|
|
16
15
|
import { getWorkspaceDir } from "../../util/platform.js";
|
|
17
16
|
import { WORKSPACE_MIGRATIONS } from "../../workspace/migrations/registry.js";
|
|
18
17
|
import {
|
|
@@ -44,7 +43,7 @@ async function handleRollbackMigrations({ body = {} }: RouteHandlerArgs) {
|
|
|
44
43
|
|
|
45
44
|
if (rollbackToRegistryCeiling === true) {
|
|
46
45
|
if (effectiveDbVersion === undefined)
|
|
47
|
-
effectiveDbVersion =
|
|
46
|
+
effectiveDbVersion = getMaxMigrationVersion();
|
|
48
47
|
if (effectiveWorkspaceMigrationId === undefined)
|
|
49
48
|
effectiveWorkspaceMigrationId =
|
|
50
49
|
getLastWorkspaceMigrationId(WORKSPACE_MIGRATIONS) ?? undefined;
|
|
@@ -105,7 +104,7 @@ async function handleRollbackMigrations({ body = {} }: RouteHandlerArgs) {
|
|
|
105
104
|
// Roll back DB migrations if requested.
|
|
106
105
|
if (effectiveDbVersion !== undefined) {
|
|
107
106
|
try {
|
|
108
|
-
rolledBack.db = rollbackMemoryMigration(getDb(), effectiveDbVersion
|
|
107
|
+
rolledBack.db = rollbackMemoryMigration(getDb(), effectiveDbVersion);
|
|
109
108
|
} catch (err) {
|
|
110
109
|
const detail = err instanceof Error ? err.message : "Unknown error";
|
|
111
110
|
throw new InternalError(`DB migration rollback failed: ${detail}`);
|
|
@@ -28,11 +28,9 @@ import {
|
|
|
28
28
|
getDb,
|
|
29
29
|
getLogsSqlite,
|
|
30
30
|
getMemorySqlite,
|
|
31
|
-
getTelemetrySqlite,
|
|
32
31
|
resetDb,
|
|
33
32
|
} from "../../memory/db-connection.js";
|
|
34
33
|
import { validateMigrationState } from "../../memory/migrations/validate-migration-state.js";
|
|
35
|
-
import { migrationSteps } from "../../memory/steps.js";
|
|
36
34
|
import { credentialKey } from "../../security/credential-key.js";
|
|
37
35
|
import {
|
|
38
36
|
bulkSetSecureKeysAsync,
|
|
@@ -182,7 +180,6 @@ async function checkpointDbsForExport(): Promise<void> {
|
|
|
182
180
|
for (const [label, sqlite] of [
|
|
183
181
|
["logs", getLogsSqlite()],
|
|
184
182
|
["memory", getMemorySqlite()],
|
|
185
|
-
["telemetry", getTelemetrySqlite()],
|
|
186
183
|
] as const) {
|
|
187
184
|
if (!sqlite) {
|
|
188
185
|
log.warn(
|
|
@@ -1715,7 +1712,7 @@ function appendNewerMigrationWarningsIfAny(report: ImportCommitReport): void {
|
|
|
1715
1712
|
return;
|
|
1716
1713
|
}
|
|
1717
1714
|
try {
|
|
1718
|
-
const migrationValidation = validateMigrationState(getDb()
|
|
1715
|
+
const migrationValidation = validateMigrationState(getDb());
|
|
1719
1716
|
if (migrationValidation.unknownCheckpoints.length > 0) {
|
|
1720
1717
|
report.warnings.push(
|
|
1721
1718
|
`Imported data contains ${migrationValidation.unknownCheckpoints.length} migration(s) from a newer version. Some data may not be fully compatible.`,
|
|
@@ -39,8 +39,6 @@ export interface SubagentDetailResult {
|
|
|
39
39
|
toolName?: string;
|
|
40
40
|
isError?: boolean;
|
|
41
41
|
messageId?: string;
|
|
42
|
-
toolUseId?: string;
|
|
43
|
-
input?: Record<string, unknown>;
|
|
44
42
|
}>;
|
|
45
43
|
}
|
|
46
44
|
|
|
@@ -114,8 +112,6 @@ export function parseSubagentMessages(
|
|
|
114
112
|
type: "tool_use",
|
|
115
113
|
content: JSON.stringify(input),
|
|
116
114
|
toolName: name,
|
|
117
|
-
toolUseId: id || undefined,
|
|
118
|
-
input,
|
|
119
115
|
});
|
|
120
116
|
if (id) pendingTools.set(id, name);
|
|
121
117
|
} else if (
|
|
@@ -151,7 +147,6 @@ export function parseSubagentMessages(
|
|
|
151
147
|
content: resultContent,
|
|
152
148
|
toolName: toolName ?? "unknown",
|
|
153
149
|
isError,
|
|
154
|
-
toolUseId: toolUseId || undefined,
|
|
155
150
|
});
|
|
156
151
|
}
|
|
157
152
|
}
|