@vellumai/assistant 0.11.4 → 0.11.5-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 +2 -2
- package/ARCHITECTURE.md +29 -4
- package/README.md +1 -1
- package/docs/architecture/memory.md +17 -5
- package/docs/architecture/security.md +96 -152
- package/docs/guardian-request-flow.md +13 -2
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/package.json +1 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/__tests__/url-normalization.test.ts +135 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/index.ts +1 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/url-normalization.ts +107 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/package.json +1 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/__tests__/url-normalization.test.ts +135 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/index.ts +1 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/url-normalization.ts +107 -0
- package/node_modules/@vellumai/gateway-client/src/gateway-ipc-contracts.ts +166 -1
- package/node_modules/@vellumai/gateway-client/src/http-delivery.ts +7 -14
- package/node_modules/@vellumai/gateway-client/src/index.ts +2 -0
- package/node_modules/@vellumai/gateway-client/src/outbound-contract.ts +29 -31
- package/node_modules/@vellumai/service-contracts/package.json +1 -0
- package/node_modules/@vellumai/service-contracts/src/__tests__/url-normalization.test.ts +135 -0
- package/node_modules/@vellumai/service-contracts/src/index.ts +1 -0
- package/node_modules/@vellumai/service-contracts/src/url-normalization.ts +107 -0
- package/openapi.yaml +193 -3
- package/package.json +1 -1
- package/src/__tests__/anthropic-provider.test.ts +10 -3
- package/src/__tests__/approval-interception-trust-gates.test.ts +40 -0
- package/src/__tests__/background-workers-disk-pressure.test.ts +1 -1
- package/src/__tests__/channel-approval-routes.test.ts +4 -0
- package/src/__tests__/channel-inbound-disk-pressure.test.ts +5 -6
- package/src/__tests__/channel-reply-delivery.test.ts +26 -13
- package/src/__tests__/checker.test.ts +20 -314
- package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +6 -2
- package/src/__tests__/client-os-metadata-persistence.test.ts +16 -0
- package/src/__tests__/compactor-retained-image-validation.test.ts +142 -0
- package/src/__tests__/config-loader-backfill.test.ts +19 -10
- package/src/__tests__/container-cpu-sampler.test.ts +153 -0
- package/src/__tests__/context-search-memory-v2-source.test.ts +0 -1
- package/src/__tests__/conversation-attachments.test.ts +0 -1
- package/src/__tests__/conversation-error.test.ts +17 -0
- package/src/__tests__/conversation-lifecycle.test.ts +20 -26
- package/src/__tests__/conversation-pairing.test.ts +186 -0
- package/src/__tests__/conversation-runtime-assembly.test.ts +21 -2
- package/src/__tests__/credential-broker-server-use.test.ts +24 -5
- package/src/__tests__/credential-routes.test.ts +22 -3
- package/src/__tests__/credential-security-invariants.test.ts +2 -1
- package/src/__tests__/daemon-credential-client.test.ts +88 -0
- package/src/__tests__/default-plugin-names-guard.test.ts +12 -1
- package/src/__tests__/dm-backfill.test.ts +63 -0
- package/src/__tests__/dynamic-skill-background-guard.test.ts +0 -2
- package/src/__tests__/edit-propagation.test.ts +107 -4
- package/src/__tests__/events-client-registration.test.ts +28 -0
- package/src/__tests__/file-write-tool.test.ts +4 -2
- package/src/__tests__/guardian-prompt-notice-privacy.test.ts +133 -0
- package/src/__tests__/guardian-verify-setup-skill-regression.test.ts +143 -97
- package/src/__tests__/helpers/gateway-classify-mock.ts +27 -6
- package/src/__tests__/host-proxy-interface.test.ts +11 -1
- package/src/__tests__/host-shell-tool.test.ts +23 -4
- package/src/__tests__/image-conversion.test.ts +143 -1
- package/src/__tests__/inline-skill-load-permissions.test.ts +47 -36
- package/src/__tests__/input-repairs.test.ts +207 -0
- package/src/__tests__/live-workspace-guard.test.ts +75 -0
- package/src/__tests__/managed-profile-guard.test.ts +4 -2
- package/src/__tests__/mcp-abort-signal.test.ts +1 -1
- package/src/__tests__/mcp-client-auth.test.ts +1 -1
- package/src/__tests__/mcp-tool-annotations-risk.test.ts +1 -1
- package/src/__tests__/media-resolve-image-validation.test.ts +310 -0
- package/src/__tests__/mtime-cache.test.ts +2 -0
- package/src/__tests__/notification-vellum-adapter.test.ts +124 -1
- package/src/__tests__/openai-provider.test.ts +22 -0
- package/src/__tests__/personal-memory-auth-bypass.test.ts +22 -6
- package/src/__tests__/platform-bash-auto-approve.test.ts +0 -4
- package/src/__tests__/platform.test.ts +16 -1
- package/src/__tests__/plugin-api-resolve-credential.test.ts +22 -13
- package/src/__tests__/plugin-api-shim.test.ts +5 -0
- package/src/__tests__/plugin-api-store-credential.test.ts +268 -0
- package/src/__tests__/plugin-config-data-migration.test.ts +8 -1
- package/src/__tests__/plugin-disabled-state.test.ts +2 -0
- package/src/__tests__/plugin-effective-enabled-set.test.ts +55 -3
- package/src/__tests__/plugin-execution-context.test.ts +73 -0
- package/src/__tests__/plugin-import-boundary-guard.test.ts +0 -1
- package/src/__tests__/plugin-import-boundary-reverse-guard.test.ts +0 -1
- package/src/__tests__/reaction-persistence.test.ts +200 -7
- package/src/__tests__/require-fresh-approval.test.ts +0 -4
- package/src/__tests__/resource-pressure-guard.test.ts +428 -0
- package/src/__tests__/resource-pressure-routes.test.ts +113 -0
- package/src/__tests__/risk-classification-boundary-guard.test.ts +115 -0
- package/src/__tests__/run-conversation-turn-persistence.test.ts +27 -1
- package/src/__tests__/secret-routes-platform-proxy.test.ts +7 -0
- package/src/__tests__/skill-tool-factory.test.ts +161 -0
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +1 -1
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +132 -5
- package/src/__tests__/tool-executor.test.ts +63 -38
- package/src/__tests__/tool-policy.test.ts +97 -1
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +7 -4
- package/src/__tests__/user-plugin-loader.test.ts +2 -0
- package/src/__tests__/validate-input.test.ts +243 -7
- package/src/__tests__/verification-control-plane-policy.test.ts +0 -2
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +2 -0
- package/src/__tests__/voice-session-bridge.test.ts +42 -0
- package/src/acp/__tests__/acp-claude-oauth.test.ts +97 -29
- package/src/acp/__tests__/prepare-agent-env.test.ts +376 -153
- package/src/acp/acp-claude-oauth.ts +38 -21
- package/src/acp/prepare-agent-env.ts +146 -55
- package/src/agent/loop-tool-dedup.test.ts +161 -0
- package/src/agent/loop.ts +68 -22
- package/src/api/constants/app-tools.ts +34 -0
- package/src/api/events/resource-pressure-status-changed.ts +53 -0
- package/src/api/index.ts +19 -0
- package/src/api/responses/resource-pressure-status.ts +25 -0
- package/src/approvals/guardian-channel-delivery.ts +70 -6
- package/src/approvals/guardian-request-resolvers.ts +32 -66
- package/src/calls/__tests__/voice-session-bridge.test.ts +114 -0
- package/src/calls/voice-session-bridge.ts +60 -6
- package/src/channels/__tests__/message-audience.test.ts +49 -0
- package/src/channels/__tests__/types.test.ts +17 -3
- package/src/channels/message-audience.ts +40 -0
- package/src/channels/types.ts +16 -12
- package/src/cli/__tests__/catalog-search-help.test.ts +50 -0
- package/src/cli/commands/__tests__/channel-verification-sessions.test.ts +31 -0
- package/src/cli/commands/__tests__/conversations-search.test.ts +289 -0
- package/src/cli/commands/__tests__/conversations-slack.test.ts +1 -0
- package/src/cli/commands/__tests__/inference-providers.test.ts +68 -0
- package/src/cli/commands/__tests__/keys.test.ts +89 -8
- package/src/cli/commands/__tests__/plugins.test.ts +57 -1
- package/src/cli/commands/channel-verification-sessions.help.ts +11 -9
- package/src/cli/commands/channel-verification-sessions.ts +11 -21
- package/src/cli/commands/conversations.help.ts +34 -0
- package/src/cli/commands/conversations.ts +125 -0
- package/src/cli/commands/inference-providers.ts +9 -4
- package/src/cli/commands/inference.help.ts +9 -4
- package/src/cli/commands/keys.help.ts +13 -1
- package/src/cli/commands/keys.ts +26 -15
- package/src/cli/commands/memory/__tests__/memory-v2.test.ts +57 -7
- package/src/cli/commands/memory/index.help.ts +41 -27
- package/src/cli/commands/memory/index.ts +2 -0
- package/src/cli/commands/memory/memory-v2.ts +58 -54
- package/src/cli/commands/memory/memory-validate.ts +18 -0
- package/src/cli/commands/monitoring.ts +1 -0
- package/src/cli/commands/plugins.help.ts +28 -31
- package/src/cli/commands/plugins.ts +10 -0
- package/src/cli/commands/skills.help.ts +13 -16
- package/src/cli/commands/trust.ts +3 -14
- package/src/cli/lib/__tests__/install-from-github.test.ts +38 -0
- package/src/cli/lib/__tests__/merge-plugin-tree.test.ts +34 -0
- package/src/cli/lib/__tests__/plugin-surfaces.test.ts +32 -1
- package/src/cli/lib/__tests__/toggle-plugin.test.ts +2 -1
- package/src/cli/lib/__tests__/upgrade-plugin.test.ts +64 -0
- package/src/cli/lib/bundled-marketplace.json +13 -0
- package/src/cli/lib/daemon-credential-client.ts +25 -3
- package/src/cli/lib/install-from-github.ts +35 -24
- package/src/cli/lib/merge-plugin-tree.ts +22 -4
- package/src/cli/lib/plugin-surfaces.ts +27 -0
- package/src/config/__tests__/balanced-model-experiment.test.ts +7 -7
- package/src/config/__tests__/default-profile-catalog.test.ts +3 -3
- package/src/config/default-profile-catalog.ts +5 -6
- package/src/config/feature-flag-registry.json +32 -32
- package/src/config/webhook-routing.ts +8 -0
- package/src/context/compactor.ts +31 -2
- package/src/daemon/__tests__/provider-rejection-log-fields.test.ts +272 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +4 -1
- package/src/daemon/conversation-error.ts +13 -0
- package/src/daemon/conversation-messaging.ts +22 -2
- package/src/daemon/conversation-process.ts +11 -0
- package/src/daemon/conversation-store.ts +10 -0
- package/src/daemon/conversation-surfaces.ts +21 -8
- package/src/daemon/conversation.ts +12 -10
- package/src/daemon/lifecycle.ts +6 -2
- package/src/daemon/message-types/conversations.ts +5 -7
- package/src/daemon/provider-rejection-log-fields.ts +124 -0
- package/src/daemon/resource-pressure-guard-lifecycle.ts +66 -0
- package/src/daemon/resource-pressure-guard.ts +387 -0
- package/src/daemon/shutdown-handlers.ts +2 -0
- package/src/daemon/startup-error.ts +16 -0
- package/src/daemon/trust-context.ts +14 -10
- package/src/daemon/unsendable-image-notice.ts +76 -0
- package/src/hooks/registry.ts +65 -51
- package/src/ipc/__tests__/socket-path.test.ts +15 -7
- package/src/ipc/gateway-client.test.ts +1 -1
- package/src/ipc/gateway-client.ts +14 -21
- package/src/ipc/socket-cleanup.ts +2 -11
- package/src/mcp/__tests__/mcp-auth-orchestrator.test.ts +1 -1
- package/src/messaging/provider-message-metadata.ts +128 -0
- package/src/messaging/providers/__tests__/transport-dispatch.test.ts +116 -68
- package/src/messaging/providers/channel-transport.ts +90 -13
- package/src/messaging/providers/discord/send.ts +16 -0
- package/src/messaging/providers/discord/transport.ts +11 -1
- package/src/messaging/providers/index.ts +109 -16
- package/src/messaging/providers/slack/message-metadata.ts +45 -0
- package/src/messaging/providers/slack/render-transcript.ts +1 -4
- package/src/messaging/providers/slack/send.test.ts +6 -9
- package/src/messaging/providers/slack/send.ts +40 -28
- package/src/messaging/providers/slack/transport.ts +22 -26
- package/src/messaging/providers/telegram-bot/send.test.ts +2 -8
- package/src/messaging/providers/telegram-bot/transport.ts +3 -6
- package/src/messaging/read-provider-metadata.test.ts +157 -0
- package/src/messaging/read-provider-metadata.ts +51 -0
- package/src/notifications/__tests__/assistant-reply-producer.test.ts +94 -0
- package/src/notifications/__tests__/edit-notification.test.ts +174 -2
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +536 -4
- package/src/notifications/adapters/macos.ts +55 -0
- package/src/notifications/adapters/slack.ts +10 -5
- package/src/notifications/assistant-reply-producer.ts +37 -4
- package/src/notifications/conversation-pairing.ts +111 -21
- package/src/notifications/edit-notification.ts +38 -8
- package/src/notifications/emit-signal.ts +12 -14
- package/src/notifications/home-feed-side-effect.ts +218 -15
- package/src/notifications/types.ts +5 -0
- package/src/permissions/AGENTS.md +16 -0
- package/src/permissions/checker.test.ts +75 -122
- package/src/permissions/checker.ts +44 -560
- package/src/permissions/confirmation-guardian-request.test.ts +28 -3
- package/src/permissions/confirmation-guardian-request.ts +5 -1
- package/src/persistence/conversation-crud.ts +23 -20
- package/src/persistence/conversation-queries.ts +14 -1
- package/src/persistence/conversation-types.ts +22 -0
- package/src/persistence/delivery-crud.ts +122 -15
- package/src/plugin-api/__tests__/import-graph-partial-mock.test.ts +67 -0
- package/src/plugin-api/conversation-turn.ts +27 -0
- package/src/plugin-api/credential-scope.test.ts +15 -0
- package/src/plugin-api/credential-scope.ts +14 -0
- package/src/plugin-api/index.ts +19 -1
- package/src/plugin-api/resolve-credential.ts +15 -10
- package/src/plugin-api/store-credential.ts +148 -0
- package/src/plugin-api/system-card.ts +36 -0
- package/src/plugin-api/vision-support.test.ts +82 -0
- package/src/plugin-api/vision-support.ts +14 -2
- package/src/plugins/defaults/image-fallback/__tests__/image-fallback.test.ts +361 -110
- package/src/plugins/defaults/image-fallback/__tests__/vision-recovery.test.ts +4 -0
- package/src/plugins/defaults/image-fallback/hooks/user-prompt-submit.ts +58 -0
- package/src/plugins/defaults/image-fallback/src/caption-blocks.ts +64 -23
- package/src/plugins/defaults/image-recovery/detect.ts +24 -1
- package/src/plugins/defaults/main.ts +15 -0
- package/src/plugins/defaults/memory/AGENTS.md +11 -3
- package/src/plugins/defaults/memory/__tests__/memory-tier-boundary-guard.test.ts +0 -1
- package/src/plugins/defaults/memory/graph-topology/pending-buffer.ts +9 -12
- package/src/plugins/defaults/memory/memory-retrospective-prompt.ts +1 -1
- package/src/plugins/defaults/memory/src/memory-v2-routes.ts +12 -10
- package/src/plugins/defaults/memory/substrate/__tests__/consolidation-job.test.ts +114 -0
- package/src/plugins/defaults/memory/substrate/__tests__/consolidation-prompt-flag-gating-guard.test.ts +8 -0
- package/src/plugins/defaults/memory/substrate/__tests__/edge-index.test.ts +0 -30
- package/src/plugins/defaults/memory/substrate/__tests__/ingest.test.ts +73 -1
- package/src/plugins/defaults/memory/substrate/__tests__/page-index.test.ts +37 -0
- package/src/plugins/defaults/memory/substrate/__tests__/page-links.test.ts +208 -0
- package/src/plugins/defaults/memory/substrate/__tests__/prompts-consolidation.test.ts +158 -1
- package/src/plugins/defaults/memory/substrate/__tests__/static-context.test.ts +1 -61
- package/src/plugins/defaults/memory/substrate/consolidation-job.ts +68 -6
- package/src/plugins/defaults/memory/substrate/edge-index.ts +0 -31
- package/src/plugins/defaults/memory/substrate/ingest.ts +59 -0
- package/src/plugins/defaults/memory/substrate/page-index.ts +35 -8
- package/src/plugins/defaults/memory/substrate/page-links.ts +133 -0
- package/src/plugins/defaults/memory/substrate/page-store.ts +10 -0
- package/src/plugins/defaults/memory/substrate/prompts/consolidation.ts +124 -34
- package/src/plugins/defaults/memory/substrate/static-context.ts +0 -29
- package/src/plugins/defaults/memory/v3/__tests__/shadow-plugin.test.ts +3 -1
- package/src/plugins/defaults/memory/v3/card.ts +9 -9
- package/src/plugins/defaults/memory/v3/core-set.test.ts +7 -0
- package/src/plugins/defaults/memory/v3/core-set.ts +5 -1
- package/src/plugins/defaults/memory/v3/edge.ts +13 -57
- package/src/plugins/mtime-cache.ts +1 -1
- package/src/plugins/pipeline.ts +14 -7
- package/src/plugins/plugin-execution-context.ts +35 -11
- package/src/plugins/plugin-tree-walk.ts +63 -4
- package/src/providers/anthropic/__tests__/pause-turn-continuation.test.ts +170 -0
- package/src/providers/anthropic/client.ts +332 -241
- package/src/providers/connection-resolution.ts +2 -1
- package/src/providers/content-blocks.ts +22 -0
- package/src/providers/gemini/client.ts +5 -2
- package/src/providers/inference/__tests__/adapter-factory-litellm.test.ts +47 -1
- package/src/providers/inference/__tests__/adapter-factory-ollama.test.ts +83 -0
- package/src/providers/inference/__tests__/adapter-factory-openai-compatible.test.ts +98 -1
- package/src/providers/inference/__tests__/base-url-route-validation.test.ts +38 -0
- package/src/providers/inference/__tests__/base-url-security.test.ts +10 -0
- package/src/providers/inference/__tests__/connections-ollama.test.ts +90 -0
- package/src/providers/inference/__tests__/missing-credential-guard.test.ts +117 -0
- package/src/providers/inference/adapter-factory.ts +33 -2
- package/src/providers/inference/auth.ts +13 -2
- package/src/providers/inference/credential-usage.ts +37 -0
- package/src/providers/inference/missing-credential-guard.ts +110 -0
- package/src/providers/inference/resolve-auth.ts +7 -7
- package/src/providers/media-resolve.ts +176 -15
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +576 -46
- package/src/providers/openai/__tests__/tool-choice-mapping.test.ts +125 -2
- package/src/providers/openai/chat-completions-provider.ts +322 -42
- package/src/routes/route-host-protocol.ts +7 -0
- package/src/routes/worker.ts +31 -10
- package/src/runtime/AGENTS.md +35 -0
- package/src/runtime/__tests__/runtime-http-port-collision.test.ts +131 -0
- package/src/runtime/__tests__/web-presence.test.ts +234 -0
- package/src/runtime/assistant-event-hub.ts +38 -0
- package/src/runtime/channel-reply-delivery.ts +54 -31
- package/src/runtime/channel-retry-sweep.ts +6 -4
- package/src/runtime/effective-capabilities.test.ts +19 -0
- package/src/runtime/effective-capabilities.ts +25 -0
- package/src/runtime/guardian-reply-router.ts +6 -2
- package/src/runtime/http-errors.ts +1 -0
- package/src/runtime/http-server.ts +20 -5
- package/src/runtime/routes/__tests__/client-routes.test.ts +150 -0
- package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +133 -0
- package/src/runtime/routes/__tests__/credential-delete-in-use.test.ts +155 -0
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +52 -1
- package/src/runtime/routes/__tests__/monitoring-routes.test.ts +1 -0
- package/src/runtime/routes/__tests__/pending-interactions-route.test.ts +175 -0
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +88 -35
- package/src/runtime/routes/__tests__/surface-action-routes.test.ts +55 -6
- package/src/runtime/routes/__tests__/system-card-turn-termination.test.ts +107 -0
- package/src/runtime/routes/__tests__/user-route-dispatcher-host.test.ts +52 -1
- package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +75 -4
- package/src/runtime/routes/approval-routes.ts +37 -4
- package/src/runtime/routes/approval-strategies/guardian-text-engine-strategy.ts +16 -22
- package/src/runtime/routes/canned-message-complete.ts +68 -29
- package/src/runtime/routes/client-routes.ts +113 -0
- package/src/runtime/routes/conversation-list-routes.ts +22 -7
- package/src/runtime/routes/conversation-management-routes.ts +15 -9
- package/src/runtime/routes/conversation-routes.ts +36 -22
- package/src/runtime/routes/credential-in-use.ts +85 -0
- package/src/runtime/routes/credential-routes.ts +55 -85
- package/src/runtime/routes/guardian-approval-interception.ts +22 -22
- package/src/runtime/routes/guardian-approval-reply-helpers.ts +14 -12
- package/src/runtime/routes/identity-routes.ts +5 -121
- package/src/runtime/routes/inbound-message-handler.ts +71 -27
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +16 -17
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +77 -50
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +61 -97
- package/src/runtime/routes/inbound-stages/edit-intercept.ts +101 -77
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +17 -8
- package/src/runtime/routes/inbound-stages/reaction-intercept.test.ts +91 -7
- package/src/runtime/routes/inbound-stages/reaction-intercept.ts +72 -70
- package/src/runtime/routes/index.ts +2 -0
- package/src/runtime/routes/inference-provider-connection-routes.ts +9 -7
- package/src/runtime/routes/monitoring-routes.ts +9 -1
- package/src/runtime/routes/plugins-routes.ts +17 -5
- package/src/runtime/routes/resource-pressure-routes.ts +22 -0
- package/src/runtime/routes/secret-routes.ts +39 -8
- package/src/runtime/routes/settings-routes.ts +6 -6
- package/src/runtime/routes/surface-action-routes.ts +20 -19
- package/src/runtime/routes/user-route-dispatcher.ts +31 -2
- package/src/runtime/routes/user-route-resolution.ts +18 -1
- package/src/runtime/slack-reply-session.test.ts +23 -13
- package/src/runtime/slack-reply-session.ts +38 -55
- package/src/runtime/web-presence.ts +90 -0
- package/src/skills/validate-input.ts +177 -40
- package/src/subagent/__tests__/consult-context-gating.test.ts +6 -10
- package/src/subagent/consult-context.ts +7 -23
- package/src/tools/credentials/broker.ts +24 -79
- package/src/tools/credentials/ref-parse.ts +35 -0
- package/src/tools/credentials/resolve.ts +4 -10
- package/src/tools/credentials/store.ts +168 -0
- package/src/tools/credentials/tool-policy.ts +67 -0
- package/src/tools/executor.ts +53 -15
- package/src/tools/network/__tests__/web-search.test.ts +41 -1
- package/src/tools/network/url-safety.ts +9 -16
- package/src/tools/network/web-search.ts +21 -3
- package/src/tools/permission-checker.ts +43 -52
- package/src/tools/schema-transforms.ts +40 -5
- package/src/tools/shared/input-repairs.ts +160 -0
- package/src/tools/skills/skill-tool-factory.ts +18 -4
- package/src/tools/subagent/spawn.ts +0 -1
- package/src/tools/tool-approval-handler.ts +16 -10
- package/src/tools/tool-types.ts +26 -13
- package/src/tools/types.ts +6 -6
- package/src/util/__tests__/cgroup-memory.test.ts +3 -0
- package/src/util/cgroup-memory.ts +3 -0
- package/src/util/container-cpu-sampler.ts +250 -0
- package/src/util/image-conversion.ts +178 -14
- package/src/util/platform.ts +93 -10
- package/src/permissions/ipc-risk-types.ts +0 -143
- package/src/permissions/risk-types.ts +0 -76
|
@@ -18,9 +18,7 @@ mock.module("../permissions/checker.js", () => ({
|
|
|
18
18
|
isDynamicSkillLoadInvocation: () => false,
|
|
19
19
|
classifyRisk: async () => ({ level: "low" }),
|
|
20
20
|
check: async () => ({ decision: "allow", reason: "allowed" }),
|
|
21
|
-
generateAllowlistOptions: () => [],
|
|
22
21
|
generateScopeOptions: () => [],
|
|
23
|
-
getCachedAssessment: () => undefined,
|
|
24
22
|
}));
|
|
25
23
|
|
|
26
24
|
mock.module("../persistence/conversation-crud.js", () => ({
|
|
@@ -74,6 +74,8 @@ function makeStreamingSession(events: AssistantEvent[]): Conversation {
|
|
|
74
74
|
}
|
|
75
75
|
},
|
|
76
76
|
handleConfirmationResponse: () => {},
|
|
77
|
+
// The image-bearing profile pin reads the leg's history.
|
|
78
|
+
getMessages: () => [],
|
|
77
79
|
abort: () => {},
|
|
78
80
|
} as unknown as Conversation;
|
|
79
81
|
}
|
|
@@ -133,6 +135,8 @@ function makePersistingStreamingSession(
|
|
|
133
135
|
},
|
|
134
136
|
handleConfirmationResponse: () => {},
|
|
135
137
|
abort: () => {},
|
|
138
|
+
// The image-bearing profile pin reads the leg's history.
|
|
139
|
+
getMessages: () => [],
|
|
136
140
|
} as unknown as Conversation &
|
|
137
141
|
PersistUserMessageContext & {
|
|
138
142
|
callSessionId?: string;
|
|
@@ -263,6 +267,8 @@ describe("voice-session-bridge", () => {
|
|
|
263
267
|
abort: () => {
|
|
264
268
|
abortCalled = true;
|
|
265
269
|
},
|
|
270
|
+
// The image-bearing profile pin reads the leg's history.
|
|
271
|
+
getMessages: () => [],
|
|
266
272
|
} as unknown as Conversation;
|
|
267
273
|
|
|
268
274
|
injectDeps(() => session);
|
|
@@ -302,6 +308,8 @@ describe("voice-session-bridge", () => {
|
|
|
302
308
|
onEvent(event);
|
|
303
309
|
}
|
|
304
310
|
},
|
|
311
|
+
// The image-bearing profile pin reads the leg's history.
|
|
312
|
+
getMessages: () => [],
|
|
305
313
|
} as unknown as Conversation;
|
|
306
314
|
|
|
307
315
|
injectDeps(() => session);
|
|
@@ -348,6 +356,8 @@ describe("voice-session-bridge", () => {
|
|
|
348
356
|
onEvent(event);
|
|
349
357
|
}
|
|
350
358
|
},
|
|
359
|
+
// The image-bearing profile pin reads the leg's history.
|
|
360
|
+
getMessages: () => [],
|
|
351
361
|
} as unknown as Conversation;
|
|
352
362
|
|
|
353
363
|
injectDeps(() => session);
|
|
@@ -393,6 +403,8 @@ describe("voice-session-bridge", () => {
|
|
|
393
403
|
abort: () => {
|
|
394
404
|
abortCalled = true;
|
|
395
405
|
},
|
|
406
|
+
// The image-bearing profile pin reads the leg's history.
|
|
407
|
+
getMessages: () => [],
|
|
396
408
|
} as unknown as Conversation;
|
|
397
409
|
|
|
398
410
|
injectDeps(() => session);
|
|
@@ -430,6 +442,8 @@ describe("voice-session-bridge", () => {
|
|
|
430
442
|
setTurnChannelContext: (ctx: unknown) => {
|
|
431
443
|
capturedTurnChannelContext = ctx;
|
|
432
444
|
},
|
|
445
|
+
// The image-bearing profile pin reads the leg's history.
|
|
446
|
+
getMessages: () => [],
|
|
433
447
|
} as unknown as Conversation;
|
|
434
448
|
|
|
435
449
|
injectDeps(() => session);
|
|
@@ -586,6 +600,8 @@ describe("voice-session-bridge", () => {
|
|
|
586
600
|
capturedTrustContext = ctx;
|
|
587
601
|
}
|
|
588
602
|
},
|
|
603
|
+
// The image-bearing profile pin reads the leg's history.
|
|
604
|
+
getMessages: () => [],
|
|
589
605
|
} as unknown as Conversation;
|
|
590
606
|
|
|
591
607
|
injectDeps(() => session);
|
|
@@ -629,6 +645,8 @@ describe("voice-session-bridge", () => {
|
|
|
629
645
|
capturedPrompt = prompt;
|
|
630
646
|
}
|
|
631
647
|
},
|
|
648
|
+
// The image-bearing profile pin reads the leg's history.
|
|
649
|
+
getMessages: () => [],
|
|
632
650
|
} as unknown as Conversation;
|
|
633
651
|
|
|
634
652
|
injectDeps(() => session);
|
|
@@ -690,6 +708,8 @@ describe("voice-session-bridge", () => {
|
|
|
690
708
|
capturedPrompt = prompt;
|
|
691
709
|
}
|
|
692
710
|
},
|
|
711
|
+
// The image-bearing profile pin reads the leg's history.
|
|
712
|
+
getMessages: () => [],
|
|
693
713
|
} as unknown as Conversation;
|
|
694
714
|
|
|
695
715
|
injectDeps(() => session);
|
|
@@ -782,6 +802,8 @@ describe("voice-session-bridge", () => {
|
|
|
782
802
|
});
|
|
783
803
|
},
|
|
784
804
|
abort: () => {},
|
|
805
|
+
// The image-bearing profile pin reads the leg's history.
|
|
806
|
+
getMessages: () => [],
|
|
785
807
|
} as unknown as Conversation;
|
|
786
808
|
|
|
787
809
|
injectDeps(() => session);
|
|
@@ -870,6 +892,8 @@ describe("voice-session-bridge", () => {
|
|
|
870
892
|
});
|
|
871
893
|
},
|
|
872
894
|
abort: () => {},
|
|
895
|
+
// The image-bearing profile pin reads the leg's history.
|
|
896
|
+
getMessages: () => [],
|
|
873
897
|
} as unknown as Conversation;
|
|
874
898
|
|
|
875
899
|
injectDeps(() => session);
|
|
@@ -946,6 +970,8 @@ describe("voice-session-bridge", () => {
|
|
|
946
970
|
handleConfirmationCalls.push({ requestId, decision });
|
|
947
971
|
},
|
|
948
972
|
abort: () => {},
|
|
973
|
+
// The image-bearing profile pin reads the leg's history.
|
|
974
|
+
getMessages: () => [],
|
|
949
975
|
} as unknown as Conversation;
|
|
950
976
|
|
|
951
977
|
injectDeps(() => session);
|
|
@@ -1014,6 +1040,8 @@ describe("voice-session-bridge", () => {
|
|
|
1014
1040
|
handleConfirmationCalls.push({ requestId, decision });
|
|
1015
1041
|
},
|
|
1016
1042
|
abort: () => {},
|
|
1043
|
+
// The image-bearing profile pin reads the leg's history.
|
|
1044
|
+
getMessages: () => [],
|
|
1017
1045
|
} as unknown as Conversation;
|
|
1018
1046
|
|
|
1019
1047
|
injectDeps(() => session);
|
|
@@ -1080,6 +1108,8 @@ describe("voice-session-bridge", () => {
|
|
|
1080
1108
|
handleConfirmationCalls.push({ requestId, decision });
|
|
1081
1109
|
},
|
|
1082
1110
|
abort: () => {},
|
|
1111
|
+
// The image-bearing profile pin reads the leg's history.
|
|
1112
|
+
getMessages: () => [],
|
|
1083
1113
|
} as unknown as Conversation;
|
|
1084
1114
|
|
|
1085
1115
|
injectDeps(() => session);
|
|
@@ -1164,6 +1194,8 @@ describe("voice-session-bridge", () => {
|
|
|
1164
1194
|
} as AssistantEvent);
|
|
1165
1195
|
},
|
|
1166
1196
|
abort: () => {},
|
|
1197
|
+
// The image-bearing profile pin reads the leg's history.
|
|
1198
|
+
getMessages: () => [],
|
|
1167
1199
|
} as unknown as Conversation;
|
|
1168
1200
|
}
|
|
1169
1201
|
|
|
@@ -1303,6 +1335,8 @@ describe("voice-session-bridge", () => {
|
|
|
1303
1335
|
handleSecretCalls.push({ requestId, value, delivery });
|
|
1304
1336
|
},
|
|
1305
1337
|
abort: () => {},
|
|
1338
|
+
// The image-bearing profile pin reads the leg's history.
|
|
1339
|
+
getMessages: () => [],
|
|
1306
1340
|
} as unknown as Conversation;
|
|
1307
1341
|
|
|
1308
1342
|
injectDeps(() => session);
|
|
@@ -1354,6 +1388,8 @@ describe("voice-session-bridge", () => {
|
|
|
1354
1388
|
runAgentLoop: async () => {},
|
|
1355
1389
|
handleConfirmationResponse: () => {},
|
|
1356
1390
|
abort: () => {},
|
|
1391
|
+
// The image-bearing profile pin reads the leg's history.
|
|
1392
|
+
getMessages: () => [],
|
|
1357
1393
|
} as unknown as Conversation & { forcePromptSideEffects: boolean };
|
|
1358
1394
|
|
|
1359
1395
|
injectDeps(() => session);
|
|
@@ -1413,6 +1449,8 @@ describe("voice-session-bridge", () => {
|
|
|
1413
1449
|
runAgentLoop: async () => {},
|
|
1414
1450
|
handleConfirmationResponse: () => {},
|
|
1415
1451
|
abort: () => {},
|
|
1452
|
+
// The image-bearing profile pin reads the leg's history.
|
|
1453
|
+
getMessages: () => [],
|
|
1416
1454
|
} as unknown as Conversation & {
|
|
1417
1455
|
forcePromptSideEffects: boolean;
|
|
1418
1456
|
callSessionId?: string;
|
|
@@ -1479,6 +1517,8 @@ describe("voice-session-bridge", () => {
|
|
|
1479
1517
|
runAgentLoop: async () => {},
|
|
1480
1518
|
handleConfirmationResponse: () => {},
|
|
1481
1519
|
abort: () => {},
|
|
1520
|
+
// The image-bearing profile pin reads the leg's history.
|
|
1521
|
+
getMessages: () => [],
|
|
1482
1522
|
} as unknown as Conversation & {
|
|
1483
1523
|
forcePromptSideEffects: boolean;
|
|
1484
1524
|
callSessionId?: string;
|
|
@@ -1540,6 +1580,8 @@ describe("voice-session-bridge", () => {
|
|
|
1540
1580
|
abort: () => {
|
|
1541
1581
|
abortCalled = true;
|
|
1542
1582
|
},
|
|
1583
|
+
// The image-bearing profile pin reads the leg's history.
|
|
1584
|
+
getMessages: () => [],
|
|
1543
1585
|
} as unknown as Conversation;
|
|
1544
1586
|
|
|
1545
1587
|
injectDeps(() => session);
|
|
@@ -1,13 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Tests for the Claude OAuth config + capture/store helpers.
|
|
3
3
|
*
|
|
4
|
-
* The store helper reaches into secure-keys
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* The store helper reaches into secure-keys, so we mock that (wired BEFORE
|
|
5
|
+
* importing the module under test via dynamic import) and assert the vault
|
|
6
|
+
* write targets `credential/acp/claude_oauth_token` and throws when the backend
|
|
7
|
+
* rejects the write.
|
|
8
|
+
*
|
|
9
|
+
* The ACP credential policy is NOT mocked: `hasAcpClaudeToken` has to answer
|
|
10
|
+
* exactly what the spawn-time broker read would, so it is exercised against the
|
|
11
|
+
* real metadata store (pointed at a temp dir) and the real policy evaluation.
|
|
8
12
|
*/
|
|
9
13
|
|
|
10
|
-
import {
|
|
14
|
+
import { randomBytes } from "node:crypto";
|
|
15
|
+
import { mkdirSync, rmSync } from "node:fs";
|
|
16
|
+
import { tmpdir } from "node:os";
|
|
17
|
+
import { join } from "node:path";
|
|
18
|
+
import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test";
|
|
11
19
|
|
|
12
20
|
// ---------------------------------------------------------------------------
|
|
13
21
|
// Mocks — wired BEFORE importing the module via dynamic import.
|
|
@@ -19,20 +27,17 @@ const setSecureKeyAsync = mock(
|
|
|
19
27
|
async (_account: string, _value: string) => storeReturn,
|
|
20
28
|
);
|
|
21
29
|
const getSecureKeyAsync = mock(async (_account: string) => getReturn);
|
|
22
|
-
const grantAcpSpawnPolicy = mock(
|
|
23
|
-
(_field: string, _usageDescription: string) => {},
|
|
24
|
-
);
|
|
25
|
-
let spawnCanRead = true;
|
|
26
|
-
const acpSpawnCanReadCredential = mock((_field: string) => spawnCanRead);
|
|
27
30
|
|
|
28
31
|
mock.module("../../security/secure-keys.js", () => ({
|
|
29
32
|
setSecureKeyAsync,
|
|
30
33
|
getSecureKeyAsync,
|
|
31
34
|
}));
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
35
|
+
|
|
36
|
+
const { _setMetadataPath, getCredentialMetadata, upsertCredentialMetadata } =
|
|
37
|
+
await import("../../tools/credentials/metadata-store.js");
|
|
38
|
+
|
|
39
|
+
const { acpSpawnCredentialDenialReason } =
|
|
40
|
+
await import("../prepare-agent-env.js");
|
|
36
41
|
|
|
37
42
|
const {
|
|
38
43
|
CLAUDE_OAUTH_CONFIG,
|
|
@@ -43,14 +48,31 @@ const {
|
|
|
43
48
|
hasAcpClaudeToken,
|
|
44
49
|
} = await import("../acp-claude-oauth.js");
|
|
45
50
|
|
|
51
|
+
const ACP_SERVICE = "acp";
|
|
52
|
+
const OAUTH_FIELD = "claude_oauth_token";
|
|
53
|
+
const ACP_SPAWN_TOOL = "acp_spawn";
|
|
54
|
+
|
|
55
|
+
const TEST_DIR = join(
|
|
56
|
+
tmpdir(),
|
|
57
|
+
`vellum-acp-claude-oauth-test-${randomBytes(4).toString("hex")}`,
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
function oauthMetadata() {
|
|
61
|
+
return getCredentialMetadata(ACP_SERVICE, OAUTH_FIELD);
|
|
62
|
+
}
|
|
63
|
+
|
|
46
64
|
beforeEach(() => {
|
|
65
|
+
mkdirSync(TEST_DIR, { recursive: true });
|
|
66
|
+
_setMetadataPath(join(TEST_DIR, "metadata.json"));
|
|
47
67
|
storeReturn = true;
|
|
48
68
|
getReturn = undefined;
|
|
49
|
-
spawnCanRead = true;
|
|
50
69
|
setSecureKeyAsync.mockClear();
|
|
51
70
|
getSecureKeyAsync.mockClear();
|
|
52
|
-
|
|
53
|
-
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
afterEach(() => {
|
|
74
|
+
_setMetadataPath(null);
|
|
75
|
+
rmSync(TEST_DIR, { recursive: true, force: true });
|
|
54
76
|
});
|
|
55
77
|
|
|
56
78
|
// ---------------------------------------------------------------------------
|
|
@@ -149,7 +171,7 @@ describe("parseManualClaudeCode", () => {
|
|
|
149
171
|
// ---------------------------------------------------------------------------
|
|
150
172
|
|
|
151
173
|
describe("storeAcpClaudeToken", () => {
|
|
152
|
-
test("writes the token
|
|
174
|
+
test("writes the token to the acp/claude_oauth_token vault field", async () => {
|
|
153
175
|
await storeAcpClaudeToken("sk-ant-oat-token");
|
|
154
176
|
|
|
155
177
|
expect(setSecureKeyAsync).toHaveBeenCalledTimes(1);
|
|
@@ -157,10 +179,25 @@ describe("storeAcpClaudeToken", () => {
|
|
|
157
179
|
"credential/acp/claude_oauth_token",
|
|
158
180
|
"sk-ant-oat-token",
|
|
159
181
|
);
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
test("takes a domain-restricted credential from not-connected to connected", async () => {
|
|
185
|
+
// Invariant: when the vault holds a usable token whose domain policy
|
|
186
|
+
// makes the spawn read fail, the status check keeps the Connect card
|
|
187
|
+
// offered, and completing Connect repairs the policy so the retry after
|
|
188
|
+
// a successful sign-in succeeds. The per-shape repair details are covered
|
|
189
|
+
// by the repairAcpSpawnPolicy suite in prepare-agent-env.test.ts.
|
|
190
|
+
upsertCredentialMetadata(ACP_SERVICE, OAUTH_FIELD, {
|
|
191
|
+
allowedTools: [ACP_SPAWN_TOOL],
|
|
192
|
+
allowedDomains: ["api.anthropic.com"],
|
|
193
|
+
});
|
|
194
|
+
getReturn = "sk-ant-oat-token";
|
|
195
|
+
expect(await hasAcpClaudeToken()).toBe(false);
|
|
196
|
+
|
|
197
|
+
await storeAcpClaudeToken("sk-ant-oat-token");
|
|
198
|
+
|
|
199
|
+
expect(await hasAcpClaudeToken()).toBe(true);
|
|
200
|
+
expect(acpSpawnCredentialDenialReason(OAUTH_FIELD)).toBeUndefined();
|
|
164
201
|
});
|
|
165
202
|
|
|
166
203
|
test("throws when the secure store rejects the write", async () => {
|
|
@@ -169,7 +206,7 @@ describe("storeAcpClaudeToken", () => {
|
|
|
169
206
|
await expect(storeAcpClaudeToken("sk-ant-oat-token")).rejects.toThrow(
|
|
170
207
|
/Failed to store/,
|
|
171
208
|
);
|
|
172
|
-
expect(
|
|
209
|
+
expect(oauthMetadata()).toBeUndefined();
|
|
173
210
|
});
|
|
174
211
|
});
|
|
175
212
|
|
|
@@ -202,13 +239,44 @@ describe("hasAcpClaudeToken", () => {
|
|
|
202
239
|
expect(await hasAcpClaudeToken()).toBe(false);
|
|
203
240
|
});
|
|
204
241
|
|
|
205
|
-
test("reports
|
|
206
|
-
//
|
|
207
|
-
//
|
|
208
|
-
|
|
209
|
-
// it stays not-connected to keep the repair CTA visible.
|
|
242
|
+
test("reports true for metadata with an empty allowedTools (the spawn would grant acp_spawn)", async () => {
|
|
243
|
+
// One allow-state case: the full policy matrix is guarded by the parity
|
|
244
|
+
// suite in prepare-agent-env.test.ts and the tool-policy unit tests.
|
|
245
|
+
upsertCredentialMetadata(ACP_SERVICE, OAUTH_FIELD, { allowedTools: [] });
|
|
210
246
|
getReturn = "sk-ant-oat-token";
|
|
211
|
-
|
|
247
|
+
|
|
248
|
+
expect(await hasAcpClaudeToken()).toBe(true);
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
test("reports false for a domain-restricted credential the broker refuses server-side", async () => {
|
|
252
|
+
// acp_spawn is allowed, but a non-empty allowedDomains scopes the credential
|
|
253
|
+
// to browser fills, so every spawn read is denied. The status check has to
|
|
254
|
+
// see that too, otherwise the Connect card self-dismisses while acp_spawn
|
|
255
|
+
// keeps failing with the missing-token marker.
|
|
256
|
+
upsertCredentialMetadata(ACP_SERVICE, OAUTH_FIELD, {
|
|
257
|
+
allowedTools: [ACP_SPAWN_TOOL],
|
|
258
|
+
allowedDomains: ["api.anthropic.com"],
|
|
259
|
+
});
|
|
260
|
+
getReturn = "sk-ant-oat-token";
|
|
261
|
+
|
|
212
262
|
expect(await hasAcpClaudeToken()).toBe(false);
|
|
213
263
|
});
|
|
264
|
+
|
|
265
|
+
test("writes nothing to the metadata store (the status route is a GET)", async () => {
|
|
266
|
+
upsertCredentialMetadata(ACP_SERVICE, OAUTH_FIELD, { allowedTools: [] });
|
|
267
|
+
getReturn = "sk-ant-oat-token";
|
|
268
|
+
const before = oauthMetadata();
|
|
269
|
+
|
|
270
|
+
await hasAcpClaudeToken();
|
|
271
|
+
|
|
272
|
+
expect(oauthMetadata()).toEqual(before);
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
test("creates no metadata when there is none to begin with", async () => {
|
|
276
|
+
getReturn = "sk-ant-oat-token";
|
|
277
|
+
|
|
278
|
+
await hasAcpClaudeToken();
|
|
279
|
+
|
|
280
|
+
expect(oauthMetadata()).toBeUndefined();
|
|
281
|
+
});
|
|
214
282
|
});
|