@vellumai/assistant 0.10.12 → 0.11.0-staging.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +1 -1
- package/ARCHITECTURE.md +4 -5
- package/README.md +1 -1
- package/docs/architecture/memory.md +60 -23
- package/docs/error-handling.md +3 -3
- package/docs/guardian-request-flow.md +112 -0
- 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__/channels.test.ts +9 -1
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/__tests__/secret-detection.test.ts +449 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/channels.ts +1 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/secret-detection.ts +468 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/app.d.ts +28 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/app.d.ts.map +1 -1
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/index.d.ts +2 -2
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/index.d.ts.map +1 -1
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/index.js.map +1 -1
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/message.d.ts +2 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/message.d.ts.map +1 -1
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/package.json +1 -1
- 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__/channels.test.ts +9 -1
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/__tests__/secret-detection.test.ts +449 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/channels.ts +1 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/secret-detection.ts +468 -0
- package/node_modules/@vellumai/gateway-client/package.json +1 -1
- package/node_modules/@vellumai/gateway-client/src/admission-policy-contract.ts +6 -0
- package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +34 -0
- package/node_modules/@vellumai/service-contracts/package.json +1 -0
- package/node_modules/@vellumai/service-contracts/src/__tests__/channels.test.ts +9 -1
- package/node_modules/@vellumai/service-contracts/src/__tests__/secret-detection.test.ts +449 -0
- package/node_modules/@vellumai/service-contracts/src/channels.ts +1 -0
- package/node_modules/@vellumai/service-contracts/src/secret-detection.ts +468 -0
- package/openapi.yaml +246 -10
- package/package.json +2 -2
- package/src/__tests__/acp-session.test.ts +3 -3
- package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +3 -0
- package/src/__tests__/anthropic-provider.test.ts +40 -0
- package/src/__tests__/approval-cascade.test.ts +5 -5
- package/src/__tests__/approval-routes-http.test.ts +3 -3
- package/src/__tests__/ask-question-resolver.test.ts +207 -0
- package/src/__tests__/assistant-event-hub-self-exclusion.test.ts +16 -16
- package/src/__tests__/assistant-event-hub-targeted.test.ts +13 -11
- package/src/__tests__/assistant-event-hub.test.ts +13 -11
- package/src/__tests__/assistant-event.test.ts +12 -9
- package/src/__tests__/assistant-feature-flag-guard.test.ts +3 -3
- package/src/__tests__/assistant-feature-flag-guardrails.test.ts +1 -1
- package/src/__tests__/assistant-id-boundary-guard.test.ts +0 -58
- package/src/__tests__/assistant-stream-state.test.ts +17 -7
- package/src/__tests__/avatar-identity-sync.test.ts +3 -3
- package/src/__tests__/background-workers-disk-pressure.test.ts +1 -0
- package/src/__tests__/call-conversation-messages.test.ts +134 -18
- package/src/__tests__/call-start-guardian-guard.test.ts +27 -0
- package/src/__tests__/channel-approvals.test.ts +0 -27
- package/src/__tests__/channel-guardian.test.ts +85 -512
- package/src/__tests__/channel-readiness-slack-remote.test.ts +151 -3
- package/src/__tests__/channel-retry-sweep.test.ts +88 -1
- package/src/__tests__/channel-setup-panel-ack.test.ts +12 -9
- package/src/__tests__/chat-reveal-guard-priming.test.ts +31 -34
- package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +2 -2
- package/src/__tests__/compaction-events.test.ts +8 -8
- package/src/__tests__/config-loader-platform-defaults.test.ts +54 -28
- package/src/__tests__/config-model-image-provider.test.ts +20 -0
- package/src/__tests__/config-schema-memory-substrate.test.ts +306 -0
- package/src/__tests__/config-schema.test.ts +14 -2
- package/src/__tests__/config-set-platform-guard.test.ts +11 -12
- package/src/__tests__/config-sounds-sync.test.ts +4 -4
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +5 -0
- package/src/__tests__/context-search-memory-source.test.ts +1 -1
- package/src/__tests__/context-search-memory-v2-source.test.ts +6 -6
- package/src/__tests__/context-token-estimator.test.ts +54 -1
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +12 -3
- package/src/__tests__/conversation-agent-loop-fatal-cleanup.test.ts +13 -4
- package/src/__tests__/conversation-agent-loop-handlers-max-tokens.test.ts +4 -4
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +10 -1
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +22 -13
- package/src/__tests__/conversation-agent-loop.test.ts +39 -30
- package/src/__tests__/conversation-confirmation-signals.test.ts +14 -14
- package/src/__tests__/conversation-evictor.test.ts +49 -0
- package/src/__tests__/conversation-fork-crud.test.ts +1 -1
- package/src/__tests__/conversation-history-web-search.test.ts +1 -1
- package/src/__tests__/conversation-key-store-disk-view.test.ts +5 -5
- package/src/__tests__/conversation-loop-db-lock-resilience.test.ts +5 -5
- package/src/__tests__/conversation-message-sync-tags.test.ts +4 -4
- package/src/__tests__/conversation-queue.test.ts +81 -81
- package/src/__tests__/conversation-routes-enabled-plugins.test.ts +8 -1
- package/src/__tests__/conversation-routes-hidden-queue.test.ts +8 -1
- package/src/__tests__/conversation-routes-slash-commands.test.ts +10 -1
- package/src/__tests__/conversation-runtime-assembly.test.ts +29 -2
- package/src/__tests__/conversation-slash-queue.test.ts +11 -11
- package/src/__tests__/conversation-slash-unknown.test.ts +2 -2
- package/src/__tests__/conversation-speed-override.test.ts +2 -2
- package/src/__tests__/conversation-summarize-route.test.ts +9 -0
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +18 -16
- package/src/__tests__/conversation-surfaces-activation-emit.test.ts +17 -17
- package/src/__tests__/conversation-surfaces-app-open.test.ts +7 -4
- package/src/__tests__/conversation-surfaces-data-persist.test.ts +7 -7
- package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +9 -9
- package/src/__tests__/conversation-surfaces-standalone.test.ts +12 -12
- package/src/__tests__/conversation-surfaces-state-update.test.ts +8 -5
- package/src/__tests__/conversation-surfaces-table-action.test.ts +6 -3
- package/src/__tests__/conversation-surfaces-task-progress.test.ts +46 -46
- package/src/__tests__/conversation-sync-tags.test.ts +5 -5
- package/src/__tests__/conversation-wait-for-idle.test.ts +2 -2
- package/src/__tests__/conversation-workspace-cache-state.test.ts +0 -4
- package/src/__tests__/conversation-workspace-injection.test.ts +0 -3
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +0 -3
- package/src/__tests__/copy-composer-tc-templates.test.ts +3 -131
- package/src/__tests__/credential-security-invariants.test.ts +1 -0
- package/src/__tests__/daemon-assistant-events.test.ts +14 -15
- package/src/__tests__/db-test-helpers.ts +13 -27
- package/src/__tests__/disk-pressure-routes.test.ts +12 -3
- package/src/__tests__/document-tool-security.test.ts +95 -0
- package/src/__tests__/drain-kick-guard.test.ts +232 -0
- package/src/__tests__/dynamic-skill-background-guard.test.ts +19 -6
- package/src/__tests__/emit-event-signal.test.ts +5 -6
- package/src/__tests__/encrypted-store-test-helpers.ts +10 -20
- package/src/__tests__/events-tail-route.test.ts +6 -4
- package/src/__tests__/feature-flag-test-helpers.ts +10 -20
- package/src/__tests__/file-edit-tool.test.ts +24 -4
- package/src/__tests__/file-list-tool.test.ts +2 -1
- package/src/__tests__/file-read-tool.test.ts +62 -10
- package/src/__tests__/file-write-tool.test.ts +24 -5
- package/src/__tests__/followup-tools.test.ts +58 -0
- package/src/__tests__/gateway-threshold-reader-mock.ts +99 -0
- package/src/__tests__/graph-extraction-event-date.test.ts +1 -1
- package/src/__tests__/guardian-question-mode.test.ts +42 -3
- package/src/__tests__/guardian-reply-router-answer-mode.test.ts +283 -0
- package/src/__tests__/guardian-vellum-destination-pinning.test.ts +221 -0
- package/src/__tests__/heartbeat-disk-pressure.test.ts +1 -0
- package/src/__tests__/heartbeat-service.test.ts +1 -0
- package/src/__tests__/helpers/native-web-search-harness.ts +10 -10
- package/src/__tests__/host-browser-proxy.test.ts +1 -1
- package/src/__tests__/host-file-edit-tool.test.ts +3 -3
- package/src/__tests__/host-file-read-tool.test.ts +2 -2
- package/src/__tests__/host-file-write-tool.test.ts +7 -3
- package/src/__tests__/host-shell-tool.test.ts +17 -5
- package/src/__tests__/host-transfer-pending-interactions.test.ts +8 -8
- package/src/__tests__/image-credentials.test.ts +65 -8
- package/src/__tests__/injection-block.test.ts +4 -4
- package/src/__tests__/injector-chain.test.ts +1 -1
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +2 -2
- package/src/__tests__/injector-registry-order-guard.test.ts +4 -9
- package/src/__tests__/injector-v3-suppression.test.ts +6 -4
- package/src/__tests__/lifecycle-memory-v2-seed.test.ts +27 -28
- package/src/__tests__/list-messages-page-latest.test.ts +2 -2
- package/src/__tests__/llm-usage-store.test.ts +67 -4
- package/src/__tests__/log-redact.test.ts +18 -0
- package/src/__tests__/managed-profile-guard.test.ts +27 -0
- package/src/__tests__/managed-skill-lifecycle.test.ts +2 -2
- package/src/__tests__/media-generate-image.test.ts +62 -11
- package/src/__tests__/memory-identity-context-parity.test.ts +1 -1
- package/src/__tests__/memory-jobs-worker-lanes.test.ts +9 -1
- package/src/__tests__/memory-retrieval-hook.test.ts +4 -4
- package/src/__tests__/notification-decision-strategy.test.ts +115 -11
- package/src/__tests__/notification-deep-link.test.ts +12 -12
- package/src/__tests__/notification-vellum-adapter.test.ts +8 -8
- package/src/__tests__/outbound-slack-persistence.test.ts +8 -8
- package/src/__tests__/path-policy.test.ts +315 -0
- package/src/__tests__/pending-interactions-resolved-event.test.ts +6 -6
- package/src/__tests__/persistence-layering-guard.test.ts +2 -2
- package/src/__tests__/pkb-autoinject.test.ts +1 -1
- package/src/__tests__/platform-bash-auto-approve.test.ts +1 -0
- package/src/__tests__/plugin-event-hub-facade.test.ts +22 -15
- package/src/__tests__/plugin-import-boundary-guard.test.ts +15 -15
- package/src/__tests__/processing-flag-persist-failure.test.ts +0 -4
- package/src/__tests__/provider-platform-proxy-integration.test.ts +0 -1
- package/src/__tests__/rebuild-index-graph-nodes.test.ts +1 -1
- package/src/__tests__/request-secret-standalone-channel-gate.test.ts +5 -5
- package/src/__tests__/require-fresh-approval.test.ts +38 -38
- package/src/__tests__/run-due-schedules.test.ts +72 -1
- package/src/__tests__/runtime-events-sse-parity.test.ts +11 -10
- package/src/__tests__/runtime-events-sse.test.ts +1 -1
- package/src/__tests__/schedule-routes.test.ts +44 -5
- package/src/__tests__/schedule-store.test.ts +3 -3
- package/src/__tests__/schedule-tools.test.ts +176 -0
- package/src/__tests__/secret-prompt-log-hygiene.test.ts +3 -3
- package/src/__tests__/secret-prompter-channel-fallback.test.ts +3 -3
- package/src/__tests__/secret-response-routing.test.ts +3 -3
- package/src/__tests__/secret-routes-platform-proxy.test.ts +4 -7
- package/src/__tests__/secret-scanner.test.ts +36 -0
- package/src/__tests__/send-endpoint-busy.test.ts +7 -7
- package/src/__tests__/slack-required-scopes-mirror.test.ts +81 -0
- package/src/__tests__/starter-task-flow.test.ts +6 -3
- package/src/__tests__/subagent-call-site-routing.test.ts +2 -2
- package/src/__tests__/subagent-disposal.test.ts +40 -11
- package/src/__tests__/subagent-fork-notifications.test.ts +4 -4
- package/src/__tests__/subagent-fork-prompt-role.test.ts +3 -3
- package/src/__tests__/subagent-fork-spawn.test.ts +4 -4
- package/src/__tests__/subagent-manager-notify.test.ts +73 -14
- package/src/__tests__/subagent-notify-parent.test.ts +48 -4
- package/src/__tests__/subagent-spawn-and-await.test.ts +62 -14
- package/src/__tests__/subagent-tools.test.ts +64 -0
- package/src/__tests__/sync-message-contract.test.ts +3 -3
- package/src/__tests__/terminal-tools.test.ts +12 -3
- package/src/__tests__/test-preload.ts +9 -0
- package/src/__tests__/tool-approval-handler.test.ts +583 -43
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +7 -4
- package/src/__tests__/tool-executor.test.ts +116 -0
- package/src/__tests__/tool-grant-request-escalation.test.ts +5 -0
- package/src/__tests__/tool-preview-lifecycle.test.ts +32 -29
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +5 -5
- package/src/__tests__/tool-start-timestamp.test.ts +4 -4
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +9 -22
- package/src/__tests__/ui-choice-copy-surfaces.test.ts +13 -13
- package/src/__tests__/ui-work-result-surface.test.ts +3 -3
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +6 -6
- package/src/__tests__/voice-session-bridge.test.ts +44 -44
- package/src/__tests__/workspace-migration-134-image-generation-mode-to-provider.test.ts +284 -0
- package/src/__tests__/workspace-policy.test.ts +399 -0
- package/src/acp/__tests__/client-handler.test.ts +3 -3
- package/src/acp/__tests__/session-manager-persistence.test.ts +10 -10
- package/src/acp/__tests__/session-manager-resume.test.ts +7 -7
- package/src/acp/client-handler.ts +3 -3
- package/src/acp/session-manager.ts +8 -8
- package/src/api/events/subagent-event.ts +2 -2
- package/src/api/responses/memory-v2-activation-log.ts +2 -2
- package/src/approvals/AGENTS.md +2 -0
- package/src/approvals/guardian-request-resolvers.ts +118 -24
- package/src/calls/__tests__/voice-control-protocol.test.ts +57 -0
- package/src/calls/__tests__/voice-session-bridge.test.ts +158 -4
- package/src/calls/__tests__/voice-triage-escalate.test.ts +3 -4
- package/src/calls/call-controller.ts +27 -27
- package/src/calls/call-conversation-messages.ts +58 -18
- package/src/calls/voice-control-protocol.ts +56 -0
- package/src/calls/voice-session-bridge.ts +156 -58
- package/src/calls/voice-triage-escalate.ts +2 -3
- package/src/channels/config.ts +8 -0
- package/src/channels/types.ts +1 -0
- package/src/cli/commands/config.ts +49 -13
- package/src/cli/commands/memory/index.help.ts +4 -2
- package/src/cli/commands/memory/memory-retrospective.ts +5 -0
- package/src/cli/lib/bundled-marketplace.json +12 -0
- package/src/cli.ts +2 -109
- package/src/config/__tests__/deployment-context-defaults.test.ts +9 -0
- package/src/config/__tests__/substrate-twin-shadowing.test.ts +191 -0
- package/src/config/assistant-feature-flags.ts +1 -1
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +13 -7
- package/src/config/feature-flag-cache.ts +6 -16
- package/src/config/feature-flag-registry.json +14 -30
- package/src/config/loader.ts +7 -1
- package/src/config/memory-tier.ts +15 -10
- package/src/config/memory-v3-gate.test.ts +278 -1
- package/src/config/memory-v3-gate.ts +88 -26
- package/src/config/raw-config-utils.ts +1 -1
- package/src/config/schemas/__tests__/live-voice.test.ts +27 -16
- package/src/config/schemas/__tests__/memory-v3.test.ts +1 -0
- package/src/config/schemas/live-voice.ts +33 -7
- package/src/config/schemas/llm.ts +1 -0
- package/src/config/schemas/memory-retrospective.ts +13 -0
- package/src/config/schemas/memory-substrate.ts +183 -0
- package/src/config/schemas/memory-v2.ts +3 -2
- package/src/config/schemas/memory-v3.ts +11 -4
- package/src/config/schemas/memory.ts +35 -1
- package/src/config/schemas/services.ts +10 -2
- package/src/config/substrate-twin-shadowing.ts +195 -0
- package/src/config/webhook-routing.ts +67 -0
- package/src/context/compactor.ts +10 -3
- package/src/context/token-estimator.ts +21 -0
- package/src/daemon/__tests__/channel-ui-capability.test.ts +85 -0
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +3 -3
- package/src/daemon/__tests__/embedding-reconcile.test.ts +3 -3
- package/src/daemon/__tests__/inference-profile-notification.test.ts +3 -6
- package/src/daemon/__tests__/native-web-search-metadata.test.ts +5 -5
- package/src/daemon/__tests__/web-search-status-text.test.ts +2 -2
- package/src/daemon/channel-ui-capability.ts +70 -1
- package/src/daemon/conversation-agent-loop-handlers.ts +4 -4
- package/src/daemon/conversation-agent-loop.ts +12 -5
- package/src/daemon/conversation-evictor.ts +26 -4
- package/src/daemon/conversation-launch.ts +11 -14
- package/src/daemon/conversation-messaging.ts +14 -14
- package/src/daemon/conversation-notifiers.ts +2 -2
- package/src/daemon/conversation-process.ts +133 -21
- package/src/daemon/conversation-queue-manager.ts +7 -7
- package/src/daemon/conversation-runtime-assembly.ts +16 -0
- package/src/daemon/conversation-store.ts +11 -3
- package/src/daemon/conversation-surfaces.ts +4 -4
- package/src/daemon/conversation-tool-setup.ts +13 -7
- package/src/daemon/conversation-usage.ts +12 -11
- package/src/daemon/conversation.ts +38 -15
- package/src/daemon/disk-pressure-guard.ts +5 -12
- package/src/daemon/embedding-reconcile.ts +14 -9
- package/src/daemon/handlers/config-channels.ts +40 -134
- package/src/daemon/handlers/config-model.ts +15 -7
- package/src/daemon/handlers/conversations.ts +4 -2
- package/src/daemon/handlers/shared.ts +29 -0
- package/src/daemon/host-proxy-base.ts +4 -4
- package/src/daemon/lifecycle.ts +13 -0
- package/src/daemon/message-protocol.ts +8 -144
- package/src/daemon/message-types/computer-use.ts +0 -12
- package/src/daemon/message-types/conversations.ts +9 -345
- package/src/daemon/message-types/host-app-control.ts +0 -9
- package/src/daemon/message-types/host-browser.ts +0 -7
- package/src/daemon/message-types/host-ui-snapshot.ts +0 -7
- package/src/daemon/message-types/messages.ts +0 -48
- package/src/daemon/message-types/notifications.ts +0 -7
- package/src/daemon/message-types/skills.ts +0 -5
- package/src/daemon/message-types/surfaces.ts +0 -9
- package/src/daemon/message-types/sync.ts +0 -2
- package/src/daemon/process-message.ts +5 -5
- package/src/daemon/skill-memory-refresh.ts +5 -5
- package/src/daemon/tool-side-effects.ts +13 -13
- package/src/daemon/trust-context.ts +1 -1
- package/src/daemon/wake-conversation-ops.ts +4 -4
- package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +100 -7
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +67 -0
- package/src/heartbeat/heartbeat-run-store.ts +81 -4
- package/src/heartbeat/heartbeat-service.ts +32 -1
- package/src/home/__tests__/feed-writer.test.ts +7 -7
- package/src/home/__tests__/home-content-refresh.test.ts +3 -0
- package/src/home/__tests__/suggested-prompts.test.ts +1 -0
- package/src/home/feed-writer.ts +6 -13
- package/src/home/home-content-refresh.ts +6 -9
- package/src/home/relationship-state-writer.ts +5 -12
- package/src/home/suggested-prompts-cache.ts +6 -19
- package/src/ipc/__tests__/events-publish-client.test.ts +67 -0
- package/src/ipc/events-publish-client.ts +44 -0
- package/src/ipc/routes/__tests__/conversation-sync-ipc-routes.test.ts +2 -2
- package/src/ipc/routes/__tests__/events-ipc-routes.test.ts +38 -9
- package/src/ipc/routes/events-ipc-routes.ts +11 -31
- package/src/live-voice/__tests__/front-decision.test.ts +4 -176
- package/src/live-voice/__tests__/live-voice-agent-turn.test.ts +276 -68
- package/src/live-voice/__tests__/live-voice-events.test.ts +6 -3
- package/src/live-voice/__tests__/live-voice-progress.test.ts +185 -46
- package/src/live-voice/__tests__/live-voice-triage-escalate.test.ts +24 -59
- package/src/live-voice/__tests__/live-voice-tts-session.test.ts +38 -54
- package/src/live-voice/__tests__/live-voice-vad.test.ts +218 -422
- package/src/live-voice/front-decision.ts +5 -155
- package/src/live-voice/live-voice-metrics.ts +4 -1
- package/src/live-voice/live-voice-session.ts +650 -333
- package/src/live-voice/progress-phrases.ts +17 -0
- package/src/live-voice/protocol.ts +15 -0
- package/src/media/app-icon-generator.ts +15 -8
- package/src/media/avatar-router.ts +9 -5
- package/src/media/image-credentials.ts +42 -10
- package/src/media/image-service.ts +1 -13
- package/src/media/types.ts +26 -3
- package/src/notifications/AGENTS.md +2 -0
- package/src/notifications/__tests__/broadcaster.test.ts +95 -0
- package/src/notifications/adapters/macos.ts +3 -3
- package/src/notifications/broadcaster.ts +57 -0
- package/src/notifications/copy-composer.ts +0 -15
- package/src/notifications/decision-engine.ts +21 -22
- package/src/notifications/guardian-question-mode.ts +57 -2
- package/src/notifications/home-feed-side-effect.ts +4 -0
- package/src/notifications/signal.ts +6 -4
- package/src/notifications/trusted-contact-payloads.ts +3 -4
- package/src/notifications/vellum-card-affinity.ts +39 -0
- package/src/oauth/AGENTS.md +1 -1
- package/src/permissions/channel-permission-query.test.ts +69 -0
- package/src/permissions/channel-permission-query.ts +73 -1
- package/src/permissions/checker.test.ts +85 -9
- package/src/permissions/checker.ts +17 -22
- package/src/permissions/confirmation-guardian-request.test.ts +2 -2
- package/src/permissions/confirmation-guardian-request.ts +2 -2
- package/src/permissions/gateway-threshold-reader.test.ts +224 -17
- package/src/permissions/gateway-threshold-reader.ts +82 -10
- package/src/permissions/ipc-risk-types.ts +8 -0
- package/src/permissions/prompter.ts +5 -5
- package/src/permissions/question-guardian-request.test.ts +222 -0
- package/src/permissions/question-guardian-request.ts +179 -0
- package/src/permissions/question-prompter.test.ts +8 -8
- package/src/permissions/question-prompter.ts +18 -0
- package/src/permissions/secret-prompter.ts +2 -4
- package/src/permissions/workspace-policy.ts +236 -34
- package/src/persistence/__tests__/lifecycle-quiesce.test.ts +82 -0
- package/src/persistence/__tests__/message-content-file.test.ts +58 -3
- package/src/persistence/conversation-crud.ts +93 -0
- package/src/persistence/conversation-key-store.ts +63 -0
- package/src/persistence/db-async-query.ts +1 -1
- package/src/persistence/db-singleton.ts +14 -27
- package/src/persistence/delivery-crud.ts +45 -0
- package/src/persistence/embeddings/embedding-backend.ts +2 -1
- package/src/persistence/embeddings/embedding-identity.ts +7 -3
- package/src/persistence/job-utils.ts +32 -27
- package/src/persistence/jobs-store.ts +92 -3
- package/src/persistence/lifecycle-quiesce.ts +80 -0
- package/src/persistence/llm-usage-store.ts +45 -8
- package/src/persistence/message-content-file.ts +4 -4
- package/src/persistence/migrations/336-move-memory-v2-activation-logs-to-memory-db.ts +1 -1
- package/src/persistence/migrations/351-schedule-skill-script-handoff.ts +39 -0
- package/src/persistence/migrations/352-drop-schedule-skill-script-handoff.test.ts +83 -0
- package/src/persistence/migrations/352-drop-schedule-skill-script-handoff.ts +36 -0
- package/src/persistence/migrations/353-add-llm-usage-conversation-type.test.ts +110 -0
- package/src/persistence/migrations/353-add-llm-usage-conversation-type.ts +49 -0
- package/src/persistence/schema/infrastructure.ts +11 -0
- package/src/persistence/steps.ts +7 -1
- package/src/plugin-api/__tests__/publish-event-forwarding.test.ts +113 -0
- package/src/plugin-api/__tests__/publish-event.test.ts +57 -0
- package/src/plugin-api/conversation-turn.ts +4 -4
- package/src/plugin-api/event-hub-facade.ts +15 -6
- package/src/plugin-api/index.ts +10 -4
- package/src/plugin-api/publish-event.ts +36 -0
- package/src/plugins/AGENTS.md +2 -0
- package/src/plugins/defaults/compaction/window-manager.ts +9 -0
- package/src/plugins/defaults/index.ts +9 -13
- package/src/plugins/defaults/memory/AGENTS.md +775 -0
- package/src/plugins/defaults/memory/__tests__/capability-seed-embed-gate.test.ts +186 -0
- package/src/plugins/defaults/memory/__tests__/fixtures/memory-v2-activation-fixtures.ts +1 -1
- package/src/plugins/defaults/memory/__tests__/indexer-tier-dispatch.test.ts +129 -0
- package/src/plugins/defaults/memory/__tests__/jobs-worker-quiesce-gate.test.ts +91 -0
- package/src/plugins/defaults/memory/__tests__/jobs-worker-v1-graph-substrate-noop.test.ts +342 -0
- package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-graph-trigger-embed.test.ts +9 -1
- package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-schedule.test.ts +36 -1
- package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-sweep-defer.test.ts +9 -1
- package/src/plugins/defaults/memory/__tests__/memory-log-stores-degraded.test.ts +2 -2
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +44 -10
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-sweep.test.ts +151 -10
- package/src/plugins/defaults/memory/__tests__/memory-tier-boundary-guard.test.ts +1155 -0
- package/src/plugins/defaults/memory/__tests__/memory-v2-activation-log-store.test.ts +1 -1
- package/src/plugins/defaults/memory/__tests__/memory-v2-concept-frequency.test.ts +3 -3
- package/src/plugins/defaults/memory/__tests__/tools-delete-memory-page.test.ts +1 -1
- package/src/plugins/defaults/memory/context-search/sources/memory-v2.ts +71 -35
- package/src/plugins/defaults/memory/context-search/sources/memory.ts +5 -1
- package/src/plugins/defaults/memory/fork-conversation-memory.ts +4 -4
- package/src/plugins/defaults/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +80 -10
- package/src/plugins/defaults/memory/graph/__tests__/handle-remember-v2.test.ts +1 -1
- package/src/plugins/defaults/memory/graph/capability-seed.ts +24 -10
- package/src/plugins/defaults/memory/graph/conversation-graph-memory.ts +123 -49
- package/src/plugins/defaults/memory/graph/graph-search.ts +6 -118
- package/src/plugins/defaults/memory/graph/in-context-tracker.test.ts +173 -0
- package/src/plugins/defaults/memory/graph/in-context-tracker.ts +109 -0
- package/src/plugins/defaults/memory/graph/store.ts +1 -0
- package/src/plugins/defaults/memory/graph/tool-handlers.test.ts +1 -1
- package/src/plugins/defaults/memory/graph/tool-handlers.ts +5 -2
- package/src/plugins/defaults/memory/graph-topology/__tests__/build-memory-graph.test.ts +1 -1
- package/src/plugins/defaults/memory/graph-topology/build-memory-graph.ts +6 -9
- package/src/plugins/defaults/memory/hooks/__tests__/user-prompt-submit.test.ts +30 -16
- package/src/plugins/defaults/memory/hooks/user-prompt-submit.ts +18 -14
- package/src/plugins/defaults/memory/indexer.ts +146 -89
- package/src/plugins/defaults/memory/injectors.ts +86 -41
- package/src/plugins/defaults/memory/job-handlers.ts +130 -39
- package/src/plugins/defaults/memory/jobs/__tests__/embed-concept-page.test.ts +2 -2
- package/src/plugins/defaults/memory/jobs/embed-concept-page.ts +22 -10
- package/src/plugins/defaults/memory/jobs-worker.ts +279 -208
- package/src/plugins/defaults/memory/memory-retrospective-enqueue.ts +4 -2
- package/src/plugins/defaults/memory/memory-retrospective-job.ts +40 -3
- package/src/plugins/defaults/memory/memory-retrospective-sweep.ts +99 -11
- package/src/plugins/defaults/memory/src/__tests__/memory-v2-routes.test.ts +5 -3
- package/src/plugins/defaults/memory/src/__tests__/memory-v2-simulate-route.test.ts +3 -4
- package/src/plugins/defaults/memory/src/memory-graph-routes.ts +2 -1
- package/src/plugins/defaults/memory/src/memory-item-routes.test.ts +7 -5
- package/src/plugins/defaults/memory/src/memory-item-routes.ts +51 -19
- package/src/plugins/defaults/memory/src/memory-v2-routes.ts +31 -20
- package/src/plugins/defaults/memory/startup.ts +58 -21
- package/src/plugins/defaults/memory/substrate/__tests__/boot-maintenance.test.ts +335 -0
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/cli-command-store.test.ts +14 -8
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/consolidation-job.test.ts +51 -21
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/edge-index.test.ts +1 -1
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/frontmatter-sweep.test.ts +3 -3
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/page-index.test.ts +1 -1
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/page-store.test.ts +1 -1
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/prompts-consolidation.test.ts +2 -2
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/qdrant.test.ts +23 -14
- package/src/plugins/defaults/memory/substrate/__tests__/reembed-job.test.ts +262 -0
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/sim.test.ts +9 -12
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/skill-content.test.ts +2 -2
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/skill-store.test.ts +9 -9
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/sparse-bm25.test.ts +12 -5
- package/src/plugins/defaults/memory/substrate/__tests__/spread.test.ts +276 -0
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/static-context.test.ts +17 -8
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/sweep-job.test.ts +9 -9
- package/src/plugins/defaults/memory/{v3/substrate/memory-v2-startup.ts → substrate/boot-maintenance.ts} +43 -24
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/cli-command-store.ts +13 -8
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/consolidation-job.ts +51 -27
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/constants.ts +1 -0
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/edge-index.ts +28 -9
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/frontmatter-sweep.ts +14 -7
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/injected-block-slugs.ts +9 -3
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/page-index.ts +29 -10
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/page-store.ts +35 -12
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/prompts/consolidation.ts +14 -8
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/prompts/sweep.ts +4 -1
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/qdrant.ts +96 -36
- package/src/plugins/defaults/memory/substrate/reembed-job.ts +54 -0
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/sim.ts +26 -15
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/skill-content.ts +1 -1
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/skill-store.ts +13 -8
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/sparse-bm25.ts +27 -10
- package/src/plugins/defaults/memory/substrate/spread.ts +165 -0
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/static-context.ts +12 -7
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/sweep-job.ts +20 -15
- package/src/plugins/defaults/memory/substrate/tuning.ts +93 -0
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/types.ts +7 -4
- package/src/plugins/defaults/memory/tools.test.ts +1 -1
- package/src/plugins/defaults/memory/tools.ts +1 -1
- package/src/plugins/defaults/memory/v1/README.md +5 -0
- package/src/plugins/defaults/memory/{__tests__ → v1/__tests__}/filing-jobs.test.ts +4 -4
- package/src/plugins/defaults/memory/{filing-jobs.ts → v1/filing-jobs.ts} +3 -3
- package/src/plugins/defaults/memory/{graph → v1/graph}/bootstrap.test.ts +68 -6
- package/src/plugins/defaults/memory/{graph → v1/graph}/bootstrap.ts +40 -21
- package/src/plugins/defaults/memory/{graph → v1/graph}/consolidation.ts +14 -14
- package/src/plugins/defaults/memory/{graph → v1/graph}/decay.test.ts +1 -1
- package/src/plugins/defaults/memory/{graph → v1/graph}/decay.ts +3 -3
- package/src/plugins/defaults/memory/{graph → v1/graph}/extraction-job.ts +5 -5
- package/src/plugins/defaults/memory/{graph → v1/graph}/extraction.test.ts +1 -1
- package/src/plugins/defaults/memory/{graph → v1/graph}/extraction.ts +20 -14
- package/src/plugins/defaults/memory/{graph → v1/graph}/graph-search.test.ts +3 -3
- package/src/plugins/defaults/memory/v1/graph/graph-search.ts +123 -0
- package/src/plugins/defaults/memory/{graph → v1/graph}/injection.test.ts +1 -118
- package/src/plugins/defaults/memory/{graph → v1/graph}/injection.ts +9 -111
- package/src/plugins/defaults/memory/{graph → v1/graph}/narrative.ts +6 -6
- package/src/plugins/defaults/memory/{graph → v1/graph}/pattern-scan.ts +5 -5
- package/src/plugins/defaults/memory/{graph → v1/graph}/retriever.test.ts +135 -42
- package/src/plugins/defaults/memory/{graph → v1/graph}/retriever.ts +40 -22
- package/src/plugins/defaults/memory/{graph → v1/graph}/scoring.test.ts +1 -1
- package/src/plugins/defaults/memory/{graph → v1/graph}/scoring.ts +1 -1
- package/src/plugins/defaults/memory/{graph → v1/graph}/serendipity.ts +1 -1
- package/src/plugins/defaults/memory/{graph → v1/graph}/triggers.test.ts +1 -1
- package/src/plugins/defaults/memory/{graph → v1/graph}/triggers.ts +1 -1
- package/src/plugins/defaults/memory/{identity-context.ts → v1/identity-context.ts} +4 -4
- package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/backfill.ts +6 -6
- package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/embedding.test.ts +6 -6
- package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/embedding.ts +6 -6
- package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/index-maintenance.ts +8 -8
- package/src/plugins/defaults/memory/{jobs → v1/jobs}/embed-pkb-file.test.ts +7 -7
- package/src/plugins/defaults/memory/{jobs → v1/jobs}/embed-pkb-file.ts +5 -5
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/autoinject.ts +1 -1
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/context.ts +2 -2
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-index.test.ts +3 -3
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-index.ts +2 -2
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-reconcile.test.ts +3 -3
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-reconcile.ts +2 -2
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-search.test.ts +3 -3
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-search.ts +6 -6
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/types.ts +3 -5
- package/src/plugins/defaults/memory/{pkb-schedule.ts → v1/pkb-schedule.ts} +2 -2
- package/src/plugins/defaults/memory/{search/semantic.ts → v1/semantic-search.ts} +1 -1
- package/src/plugins/defaults/memory/v2/__tests__/activation-store.test.ts +1 -1
- package/src/plugins/defaults/memory/v2/__tests__/activation.test.ts +11 -274
- package/src/plugins/defaults/memory/v2/__tests__/backfill-jobs.test.ts +9 -131
- package/src/plugins/defaults/memory/v2/__tests__/harness-compare.test.ts +1 -1
- package/src/plugins/defaults/memory/v2/__tests__/harness-oracle.test.ts +1 -1
- package/src/plugins/defaults/memory/v2/__tests__/harness-replay-input.test.ts +1 -1
- package/src/plugins/defaults/memory/v2/__tests__/injection.test.ts +14 -10
- package/src/plugins/defaults/memory/v2/__tests__/reranker.test.ts +7 -5
- package/src/plugins/defaults/memory/v2/__tests__/router.test.ts +12 -6
- package/src/plugins/defaults/memory/{memory-v2-activation-log-store.ts → v2/activation-log-store.ts} +2 -2
- package/src/plugins/defaults/memory/v2/activation-store.ts +22 -8
- package/src/plugins/defaults/memory/v2/activation.ts +30 -163
- package/src/plugins/defaults/memory/v2/backfill-jobs.ts +7 -54
- package/src/plugins/defaults/memory/{memory-v2-concept-frequency.ts → v2/concept-frequency.ts} +3 -3
- package/src/plugins/defaults/memory/v2/harness/oracle.ts +1 -1
- package/src/plugins/defaults/memory/v2/harness/replay-input.ts +2 -2
- package/src/plugins/defaults/memory/v2/harness/retriever.ts +1 -1
- package/src/plugins/defaults/memory/v2/injection.ts +36 -26
- package/src/plugins/defaults/memory/v2/migration.ts +2 -2
- package/src/plugins/defaults/memory/{rerank-local.ts → v2/rerank-local.ts} +44 -18
- package/src/plugins/defaults/memory/v2/reranker.ts +29 -11
- package/src/plugins/defaults/memory/v2/router.ts +38 -15
- package/src/plugins/defaults/memory/v3/__tests__/candidate-match.test.ts +5 -3
- package/src/plugins/defaults/memory/v3/__tests__/carry-integration.test.ts +21 -8
- package/src/plugins/defaults/memory/v3/__tests__/edge.test.ts +1 -1
- package/src/plugins/defaults/memory/v3/__tests__/live-integration.test.ts +1 -1
- package/src/plugins/defaults/memory/v3/__tests__/maintain-job.test.ts +4 -1
- package/src/plugins/defaults/memory/v3/__tests__/orchestrate.test.ts +181 -3
- package/src/plugins/defaults/memory/v3/__tests__/selection-log-store.test.ts +3 -0
- package/src/plugins/defaults/memory/v3/__tests__/shadow-integration.test.ts +14 -5
- package/src/plugins/defaults/memory/v3/__tests__/shadow-plugin.test.ts +40 -50
- package/src/plugins/defaults/memory/v3/__tests__/tuning-profile.test.ts +1 -0
- package/src/plugins/defaults/memory/v3/candidate-match.ts +2 -2
- package/src/plugins/defaults/memory/v3/capabilities.ts +6 -4
- package/src/plugins/defaults/memory/v3/card.ts +25 -9
- package/src/plugins/defaults/memory/v3/edge.ts +52 -18
- package/src/plugins/defaults/memory/v3/gate.ts +4 -4
- package/src/plugins/defaults/memory/v3/injector.ts +10 -3
- package/src/plugins/defaults/memory/v3/maintain-job.ts +3 -3
- package/src/plugins/defaults/memory/v3/orchestrate.ts +100 -18
- package/src/plugins/defaults/memory/v3/page-content.ts +26 -10
- package/src/plugins/defaults/memory/v3/prune.ts +40 -16
- package/src/plugins/defaults/memory/v3/selection-log-store.ts +34 -12
- package/src/plugins/defaults/memory/v3/shadow-plugin.ts +9 -13
- package/src/plugins/defaults/memory/v3/span-query.test.ts +86 -0
- package/src/plugins/defaults/memory/v3/span-query.ts +71 -0
- package/src/plugins/defaults/memory/v3/tuning-profile.ts +3 -0
- package/src/plugins/defaults/memory/v3/types.ts +4 -1
- package/src/plugins/defaults/memory/v3-eval/eval-packets.ts +2 -2
- package/src/plugins/defaults/memory/validation.ts +1 -1
- package/src/plugins/defaults/memory/worker.ts +2 -1
- package/src/plugins/defaults/platform-hosted/__tests__/reengage.test.ts +104 -12
- package/src/plugins/defaults/platform-hosted/routes/reengage.ts +104 -12
- package/src/plugins/types.ts +2 -2
- package/src/providers/__tests__/registry-native-web-search.test.ts +47 -2
- package/src/providers/anthropic/client.ts +15 -6
- package/src/providers/content-block-schema.ts +26 -0
- package/src/providers/inference/__tests__/connections-credential-normalize.test.ts +87 -0
- package/src/providers/inference/adapter-factory.ts +6 -0
- package/src/providers/inference/connections.ts +30 -14
- package/src/providers/model-catalog.ts +77 -0
- package/src/providers/openai/__tests__/chat-completions-input-audio.test.ts +260 -0
- package/src/providers/openai/chat-completions-provider.ts +65 -17
- package/src/providers/openai/input-audio.ts +76 -0
- package/src/providers/openrouter/client.ts +0 -2
- package/src/providers/platform-proxy/constants.ts +4 -0
- package/src/providers/poolside/client.ts +42 -0
- package/src/providers/registry.ts +40 -8
- package/src/providers/retry.ts +2 -0
- package/src/providers/types.ts +39 -1
- package/src/providers/vercel-ai-gateway/client.ts +0 -2
- package/src/runtime/AGENTS.md +7 -5
- package/src/runtime/__tests__/question-request-guardian-bridge.test.ts +173 -0
- package/src/runtime/__tests__/question-resolution.test.ts +111 -0
- package/src/runtime/access-request-helper.ts +7 -15
- package/src/runtime/assistant-event-hub.ts +43 -31
- package/src/runtime/assistant-event-publish-options.ts +31 -0
- package/src/runtime/assistant-event.ts +19 -30
- package/src/runtime/assistant-stream-state.ts +4 -4
- package/src/runtime/channel-approvals.ts +0 -25
- package/src/runtime/channel-readiness-service.ts +99 -40
- package/src/runtime/channel-retry-sweep.ts +38 -15
- package/src/runtime/confirmation-request-guardian-bridge.ts +4 -0
- package/src/runtime/guardian-reply-router.ts +108 -0
- package/src/runtime/http-server.ts +8 -0
- package/src/runtime/http-types.ts +2 -2
- package/src/runtime/process-role.ts +42 -0
- package/src/runtime/question-request-guardian-bridge.ts +184 -0
- package/src/runtime/question-resolution.ts +153 -0
- package/src/runtime/routes/__tests__/bookmark-routes.test.ts +6 -2
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +1 -1
- package/src/runtime/routes/acp-routes.ts +2 -2
- package/src/runtime/routes/bookmark-routes.ts +3 -15
- package/src/runtime/routes/canned-message-complete.ts +2 -2
- package/src/runtime/routes/consolidation-routes.ts +8 -2
- package/src/runtime/routes/conversation-list-routes.ts +3 -19
- package/src/runtime/routes/conversation-management-routes.ts +1 -5
- package/src/runtime/routes/conversation-query-routes.ts +52 -8
- package/src/runtime/routes/conversation-routes.ts +36 -22
- package/src/runtime/routes/credential-request-routes.ts +0 -1
- package/src/runtime/routes/filing-routes.ts +7 -7
- package/src/runtime/routes/global-search-routes.ts +1 -1
- package/src/runtime/routes/guardian-approval-prompt.ts +2 -2
- package/src/runtime/routes/image-generation-routes.ts +12 -9
- package/src/runtime/routes/inbound-message-handler.ts +17 -0
- package/src/runtime/routes/inbound-stages/acl-enforcement.test.ts +50 -0
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +19 -0
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +4 -4
- package/src/runtime/routes/inbound-stages/inbound-content-prep.test.ts +129 -0
- package/src/runtime/routes/inbound-stages/inbound-content-prep.ts +141 -9
- package/src/runtime/routes/index.ts +2 -0
- package/src/runtime/routes/lifecycle-routes.ts +199 -0
- package/src/runtime/routes/platform-routes.ts +3 -8
- package/src/runtime/routes/playground/__tests__/inject-failures.test.ts +7 -7
- package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +5 -5
- package/src/runtime/routes/question-routes.ts +34 -87
- package/src/runtime/routes/secret-routes.ts +11 -1
- package/src/runtime/routes/settings-routes.ts +8 -18
- package/src/runtime/routes/upgrade-broadcast-routes.ts +4 -5
- package/src/runtime/routes/workspace-routes.test.ts +7 -4
- package/src/runtime/slack-reply-session.test.ts +12 -12
- package/src/runtime/slack-reply-session.ts +17 -17
- package/src/runtime/sync/sync-publisher.test.ts +7 -5
- package/src/runtime/tool-grant-request-helper.ts +4 -0
- package/src/schedule/schedule-store.ts +70 -0
- package/src/schedule/scheduler.ts +27 -0
- package/src/security/AGENTS.md +1 -1
- package/src/security/credential-key.ts +17 -0
- package/src/security/secret-ingress.ts +14 -105
- package/src/security/secret-patterns.ts +8 -139
- package/src/security/secret-scanner.ts +8 -3
- package/src/security/store-path-override.ts +6 -16
- package/src/sequence/store.ts +8 -0
- package/src/signals/emit-event.ts +5 -10
- package/src/signals/event-stream.ts +20 -10
- package/src/subagent/manager.ts +76 -25
- package/src/subagent/notify.ts +8 -0
- package/src/subagent/types.ts +13 -3
- package/src/telegram/__tests__/webhook-health.test.ts +442 -0
- package/src/telegram/webhook-health.ts +478 -0
- package/src/telemetry/AGENTS.md +6 -0
- package/src/telemetry/memory-corpus-size.test.ts +129 -0
- package/src/telemetry/memory-corpus-size.ts +184 -0
- package/src/telemetry/memory-tier-reporter.test.ts +67 -2
- package/src/telemetry/memory-tier-reporter.ts +30 -3
- package/src/tools/__tests__/document-tool-input-schemas.test.ts +103 -0
- package/src/tools/__tests__/followup-call-acp-tool-input-schemas.test.ts +125 -0
- package/src/tools/__tests__/schedule-tool-input-schemas.test.ts +83 -0
- package/src/tools/__tests__/subagent-workflow-tool-input-schemas.test.ts +116 -0
- package/src/tools/__tests__/tool-input-schemas.test.ts +192 -0
- package/src/tools/__tests__/tool-schema-drift-harness.ts +142 -0
- package/src/tools/acp/abort.ts +21 -1
- package/src/tools/acp/context.ts +5 -5
- package/src/tools/acp/spawn.test.ts +15 -5
- package/src/tools/acp/spawn.ts +26 -3
- package/src/tools/acp/status.ts +20 -1
- package/src/tools/acp/steer.test.ts +20 -0
- package/src/tools/acp/steer.ts +23 -2
- package/src/tools/ask-question/ask-question-tool.test.ts +65 -0
- package/src/tools/ask-question/ask-question-tool.ts +68 -92
- package/src/tools/browser/browser-screencast.ts +6 -6
- package/src/tools/calls/call-end.ts +24 -3
- package/src/tools/calls/call-start.ts +35 -11
- package/src/tools/calls/call-status.ts +20 -1
- package/src/tools/document/document-comment-tool.test.ts +49 -0
- package/src/tools/document/document-comment-tool.ts +45 -6
- package/src/tools/document/document-tool.ts +142 -24
- package/src/tools/executor.ts +27 -13
- package/src/tools/filesystem/edit.ts +62 -60
- package/src/tools/filesystem/list.ts +36 -29
- package/src/tools/filesystem/read.ts +56 -39
- package/src/tools/filesystem/write.ts +44 -38
- package/src/tools/followups/followup_create.ts +41 -12
- package/src/tools/followups/followup_list.ts +34 -6
- package/src/tools/followups/followup_resolve.ts +26 -4
- package/src/tools/host-filesystem/edit.ts +50 -60
- package/src/tools/host-filesystem/read.ts +45 -39
- package/src/tools/host-filesystem/write.ts +31 -36
- package/src/tools/host-terminal/host-shell.ts +76 -62
- package/src/tools/policy-context.ts +27 -10
- package/src/tools/schedule/create.ts +76 -33
- package/src/tools/schedule/delete.ts +21 -2
- package/src/tools/schedule/list.ts +25 -3
- package/src/tools/schedule/update.ts +105 -48
- package/src/tools/shared/filesystem/path-policy.ts +246 -40
- package/src/tools/shared/zod-tool-schema.ts +117 -0
- package/src/tools/subagent/abort.ts +12 -4
- package/src/tools/subagent/consult-deadline.ts +9 -3
- package/src/tools/subagent/message.ts +21 -5
- package/src/tools/subagent/notify-parent.ts +44 -23
- package/src/tools/subagent/read.ts +15 -4
- package/src/tools/subagent/resolve.ts +26 -4
- package/src/tools/subagent/spawn.ts +37 -13
- package/src/tools/subagent/status.ts +12 -4
- package/src/tools/system/request-permission.ts +35 -26
- package/src/tools/terminal/shell.ts +68 -55
- package/src/tools/tool-approval-handler.ts +327 -53
- package/src/tools/tool-input-schemas.ts +85 -0
- package/src/tools/tool-types.ts +7 -0
- package/src/tools/types.ts +8 -0
- package/src/tools/workflows/manage-workflows.ts +30 -2
- package/src/tools/workflows/run-workflow.test.ts +54 -2
- package/src/tools/workflows/run-workflow.ts +32 -4
- package/src/util/fs-symlinks.ts +30 -0
- package/src/util/log-redact.ts +7 -3
- package/src/vellum-assistant-namespace.d.ts +80 -0
- package/src/watcher/watcher-store.ts +8 -0
- package/src/workflows/leaf-runner.test.ts +104 -2
- package/src/workflows/leaf-runner.ts +31 -6
- package/src/workspace/migrations/070-memory-v2-summary-schema-rebuild.ts +2 -2
- package/src/workspace/migrations/134-image-generation-mode-to-provider.ts +128 -0
- package/src/workspace/migrations/135-copy-substrate-tunables.ts +248 -0
- package/src/workspace/migrations/__tests__/135-copy-substrate-tunables.test.ts +446 -0
- package/src/workspace/migrations/__tests__/backfill-v3-leaves.test.ts +2 -2
- package/src/workspace/migrations/registry.ts +4 -0
- package/src/__tests__/memory-retrieval-budget.test.ts +0 -49
- package/src/__tests__/secret-patterns.test.ts +0 -27
- package/src/config/__tests__/proc-to-skills.test.ts +0 -21
- package/src/config/memory-tier.test.ts +0 -44
- package/src/daemon/message-types/acp.ts +0 -20
- package/src/daemon/message-types/apps.ts +0 -11
- package/src/daemon/message-types/background-tools.ts +0 -14
- package/src/daemon/message-types/bookmarks.ts +0 -13
- package/src/daemon/message-types/contacts.ts +0 -13
- package/src/daemon/message-types/document-comments.ts +0 -14
- package/src/daemon/message-types/documents.ts +0 -13
- package/src/daemon/message-types/home.ts +0 -15
- package/src/daemon/message-types/host-bash.ts +0 -12
- package/src/daemon/message-types/host-cu.ts +0 -10
- package/src/daemon/message-types/host-file.ts +0 -12
- package/src/daemon/message-types/host-transfer.ts +0 -12
- package/src/daemon/message-types/integrations.ts +0 -90
- package/src/daemon/message-types/memory.ts +0 -10
- package/src/daemon/message-types/schedules.ts +0 -14
- package/src/daemon/message-types/settings.ts +0 -17
- package/src/daemon/message-types/subagents.ts +0 -63
- package/src/daemon/message-types/upgrades.ts +0 -14
- package/src/daemon/message-types/workflows.ts +0 -25
- package/src/daemon/message-types/workspace.ts +0 -137
- package/src/live-voice/ack-phrases.ts +0 -58
- package/src/plugins/defaults/memory/retrieval-budget.ts +0 -29
- package/src/plugins/defaults/memory/v3/__tests__/gate-flag.test.ts +0 -69
- package/src/plugins/defaults/memory/v3/gate-flag.ts +0 -20
- package/src/plugins/defaults/memory/v3/substrate/__tests__/memory-v2-startup.test.ts +0 -86
- package/src/plugins/defaults/memory/v3/substrate/memory-v2-startup.test.ts +0 -205
- /package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/concept-page-frontmatter-schema.test.ts +0 -0
- /package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/consolidation-prompt-flag-gating-guard.test.ts +0 -0
- /package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/injected-block-slugs.test.ts +0 -0
- /package/src/plugins/defaults/memory/{v3/substrate → substrate}/cli-command-content.ts +0 -0
|
@@ -3,6 +3,7 @@ import { and, asc, desc, eq, isNull, lt, lte, sql } from "drizzle-orm";
|
|
|
3
3
|
import { v4 as uuid } from "uuid";
|
|
4
4
|
|
|
5
5
|
import { getDb } from "../persistence/db-connection.js";
|
|
6
|
+
import { isLifecycleQuiesced } from "../persistence/lifecycle-quiesce.js";
|
|
6
7
|
import { rawChanges } from "../persistence/raw-query.js";
|
|
7
8
|
import { scheduleJobs, scheduleRuns } from "../persistence/schema/index.js";
|
|
8
9
|
import { publishSchedulesChanged } from "../runtime/sync/resource-sync-events.js";
|
|
@@ -465,6 +466,15 @@ export async function deleteSchedule(id: string): Promise<boolean> {
|
|
|
465
466
|
* next_run_at <= now and enabled = true and cron_expression IS NULL.
|
|
466
467
|
*/
|
|
467
468
|
export async function claimDueSchedules(now: number): Promise<ScheduleJob[]> {
|
|
469
|
+
// Drain gate: while a quiesce lease is active, claim nothing so in-flight
|
|
470
|
+
// runs can drain before a stop. The check lives here — immediately before
|
|
471
|
+
// the claim writes — rather than at the tick boundary, to shrink the window
|
|
472
|
+
// in which a lease armed mid-tick could miss a claim that already passed an
|
|
473
|
+
// earlier check. Fail-open via the lease read.
|
|
474
|
+
if (isLifecycleQuiesced()) {
|
|
475
|
+
return [];
|
|
476
|
+
}
|
|
477
|
+
|
|
468
478
|
const db = getDb();
|
|
469
479
|
const claimed: ScheduleJob[] = [];
|
|
470
480
|
|
|
@@ -750,6 +760,27 @@ export async function createScheduleRun(
|
|
|
750
760
|
return id;
|
|
751
761
|
}
|
|
752
762
|
|
|
763
|
+
/** Currently-running schedule runs with their job names, oldest first. */
|
|
764
|
+
export function listRunningScheduleRuns(): Array<{
|
|
765
|
+
runId: string;
|
|
766
|
+
scheduleName: string | null;
|
|
767
|
+
startedAt: number;
|
|
768
|
+
}> {
|
|
769
|
+
const db = getDb();
|
|
770
|
+
return db
|
|
771
|
+
.select({
|
|
772
|
+
runId: scheduleRuns.id,
|
|
773
|
+
scheduleName: scheduleJobs.name,
|
|
774
|
+
startedAt: scheduleRuns.startedAt,
|
|
775
|
+
})
|
|
776
|
+
.from(scheduleRuns)
|
|
777
|
+
.leftJoin(scheduleJobs, eq(scheduleRuns.jobId, scheduleJobs.id))
|
|
778
|
+
.where(eq(scheduleRuns.status, "running"))
|
|
779
|
+
.orderBy(asc(scheduleRuns.startedAt))
|
|
780
|
+
.limit(20)
|
|
781
|
+
.all();
|
|
782
|
+
}
|
|
783
|
+
|
|
753
784
|
export async function setScheduleRunConversationId(
|
|
754
785
|
runId: string,
|
|
755
786
|
conversationId: string,
|
|
@@ -1082,6 +1113,45 @@ export function describeCronExpression(expr: string | null): string {
|
|
|
1082
1113
|
}
|
|
1083
1114
|
}
|
|
1084
1115
|
|
|
1116
|
+
/**
|
|
1117
|
+
* Return a claimed-but-not-started schedule to the queue (drain deferral).
|
|
1118
|
+
*
|
|
1119
|
+
* Restores everything the claim mutated before any execution began:
|
|
1120
|
+
* `nextRunAt` is pulled to `nextRetryAt`, a one-shot's `firing` reverts to
|
|
1121
|
+
* `active`, and `enabled` is restored — a bounded recurring schedule's final
|
|
1122
|
+
* occurrence is claimed by exhausting the job (`enabled = false`,
|
|
1123
|
+
* `nextRunAt = 0`), so without the restore that deferred final occurrence
|
|
1124
|
+
* would never fire.
|
|
1125
|
+
*/
|
|
1126
|
+
export async function deferClaimedSchedule(
|
|
1127
|
+
id: string,
|
|
1128
|
+
nextRetryAt: number,
|
|
1129
|
+
): Promise<void> {
|
|
1130
|
+
const db = getDb();
|
|
1131
|
+
const now = Date.now();
|
|
1132
|
+
await withSqliteRetry(
|
|
1133
|
+
() => {
|
|
1134
|
+
db.update(scheduleJobs)
|
|
1135
|
+
.set({ nextRunAt: nextRetryAt, enabled: true, updatedAt: now })
|
|
1136
|
+
.where(eq(scheduleJobs.id, id))
|
|
1137
|
+
.run();
|
|
1138
|
+
return rawChanges() > 0;
|
|
1139
|
+
},
|
|
1140
|
+
{ op: "deferClaimedSchedule.requeue", context: { scheduleId: id } },
|
|
1141
|
+
);
|
|
1142
|
+
await withSqliteRetry(
|
|
1143
|
+
() => {
|
|
1144
|
+
db.update(scheduleJobs)
|
|
1145
|
+
.set({ status: "active", updatedAt: now })
|
|
1146
|
+
.where(and(eq(scheduleJobs.id, id), eq(scheduleJobs.status, "firing")))
|
|
1147
|
+
.run();
|
|
1148
|
+
return rawChanges() > 0;
|
|
1149
|
+
},
|
|
1150
|
+
{ op: "deferClaimedSchedule.status", context: { scheduleId: id } },
|
|
1151
|
+
);
|
|
1152
|
+
notifySchedulesChanged();
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1085
1155
|
/**
|
|
1086
1156
|
* Set the next retry time for a schedule and revert one-shot status from
|
|
1087
1157
|
* "firing" to "active" so the scheduler will claim it again when nextRetryAt
|
|
@@ -9,6 +9,7 @@ import { processMessage } from "../daemon/process-message.js";
|
|
|
9
9
|
import { INTERNAL_GUARDIAN_TRUST_CONTEXT } from "../daemon/trust-context.js";
|
|
10
10
|
import { emitNotificationSignal } from "../notifications/emit-signal.js";
|
|
11
11
|
import { getConversation } from "../persistence/conversation-crud.js";
|
|
12
|
+
import { isLifecycleQuiesced } from "../persistence/lifecycle-quiesce.js";
|
|
12
13
|
import { invalidateAssistantInferredItemsForConversation } from "../plugins/defaults/memory/task-memory-cleanup.js";
|
|
13
14
|
import { wakeAgentForOpportunity } from "../runtime/agent-wake.js";
|
|
14
15
|
import { broadcastMessage } from "../runtime/assistant-event-hub.js";
|
|
@@ -33,6 +34,7 @@ import {
|
|
|
33
34
|
completeOneShot,
|
|
34
35
|
completeScheduleRun,
|
|
35
36
|
createScheduleRun,
|
|
37
|
+
deferClaimedSchedule,
|
|
36
38
|
failOneShotPermanently,
|
|
37
39
|
getLastScheduleConversationId,
|
|
38
40
|
resetRetryCount,
|
|
@@ -434,6 +436,9 @@ export async function runScheduleDueWorkOnce(
|
|
|
434
436
|
return result;
|
|
435
437
|
}
|
|
436
438
|
|
|
439
|
+
// The drain quiesce gates live inside claimDueWatchers and
|
|
440
|
+
// claimDueEnrollments, immediately before their claim writes.
|
|
441
|
+
|
|
437
442
|
// ── Watchers (event-driven polling) ────────────────────────────────
|
|
438
443
|
try {
|
|
439
444
|
const watcherProcessed = await runWatchersOnce(emitWatcherNotifySignal);
|
|
@@ -463,6 +468,9 @@ export async function runScheduleDueWorkOnce(
|
|
|
463
468
|
* (`worker.ts`). Claims are atomic in the schedule store, so overlapping ticks
|
|
464
469
|
* cannot double-run a job another claim already took.
|
|
465
470
|
*/
|
|
471
|
+
/** How far a claimed-but-quiesced schedule is pushed back into the queue. */
|
|
472
|
+
const QUIESCE_DEFER_MS = 30_000;
|
|
473
|
+
|
|
466
474
|
export async function runDueSchedulesOnce(
|
|
467
475
|
now: number = Date.now(),
|
|
468
476
|
): Promise<SchedulerDueWorkResult> {
|
|
@@ -490,9 +498,28 @@ export async function runDueSchedulesOnce(
|
|
|
490
498
|
return result;
|
|
491
499
|
}
|
|
492
500
|
|
|
501
|
+
// The drain quiesce gate lives inside claimDueSchedules, immediately
|
|
502
|
+
// before the claim writes.
|
|
493
503
|
const jobs = await claimDueSchedules(now);
|
|
494
504
|
result.claimed = jobs.length;
|
|
495
505
|
for (const job of jobs) {
|
|
506
|
+
// Lease re-check per claimed job: a lease armed between the batch claim
|
|
507
|
+
// and this job's start returns the job to the queue untouched instead of
|
|
508
|
+
// starting work the drain snapshot cannot see — notify mode especially,
|
|
509
|
+
// which emits before any run row exists.
|
|
510
|
+
if (isLifecycleQuiesced()) {
|
|
511
|
+
try {
|
|
512
|
+
await deferClaimedSchedule(job.id, Date.now() + QUIESCE_DEFER_MS);
|
|
513
|
+
} catch (err) {
|
|
514
|
+
log.warn(
|
|
515
|
+
{ err, jobId: job.id },
|
|
516
|
+
"Failed to defer claimed schedule under quiesce",
|
|
517
|
+
);
|
|
518
|
+
}
|
|
519
|
+
result.skipped += 1;
|
|
520
|
+
continue;
|
|
521
|
+
}
|
|
522
|
+
|
|
496
523
|
const isOneShot = job.expression == null;
|
|
497
524
|
|
|
498
525
|
// ── Notify mode (one-shot or recurring) ─────────────────────────
|
package/src/security/AGENTS.md
CHANGED
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
## Integration API Key Patterns
|
|
4
4
|
|
|
5
|
-
When adding a new third-party integration, check whether the service uses a recognizable API key prefix (e.g., `lin_api_`, `sk-ant-`, `ghp_`). If it does, add a corresponding entry to `PREFIX_PATTERNS` in `secret-
|
|
5
|
+
When adding a new third-party integration, check whether the service uses a recognizable API key prefix (e.g., `lin_api_`, `sk-ant-`, `ghp_`). If it does, add a corresponding entry to `PREFIX_PATTERNS` in `packages/service-contracts/src/secret-detection.ts` (`@vellumai/service-contracts/secret-detection`). This is the single source of truth for prefix-based secret detection — ingress blocking, tool output scanning, log redaction, and the web composer guard all consume this list. `secret-patterns.ts` in this directory is a re-export that preserves existing daemon import paths.
|
|
6
6
|
|
|
7
7
|
OAuth-only services with opaque access tokens (no fixed prefix) do not need a pattern.
|
|
@@ -12,3 +12,20 @@
|
|
|
12
12
|
export function credentialKey(service: string, field: string): string {
|
|
13
13
|
return `credential/${service}/${field}`;
|
|
14
14
|
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Normalize a credential reference to the vault-key form.
|
|
18
|
+
*
|
|
19
|
+
* The secrets API names credentials `{service}:{field}` on the wire (e.g.
|
|
20
|
+
* `openrouter:api_key`), while the vault stores them as
|
|
21
|
+
* `credential/{service}/{field}`. Callers routinely reuse the wire name where
|
|
22
|
+
* a vault key is expected, producing references that never resolve. Map the
|
|
23
|
+
* wire name to the vault key (same lastIndexOf split the secrets routes use);
|
|
24
|
+
* leave anything else untouched.
|
|
25
|
+
*/
|
|
26
|
+
export function normalizeCredentialRef(ref: string): string {
|
|
27
|
+
if (ref.startsWith("credential/")) return ref;
|
|
28
|
+
const colonIdx = ref.lastIndexOf(":");
|
|
29
|
+
if (colonIdx < 1 || colonIdx === ref.length - 1) return ref;
|
|
30
|
+
return credentialKey(ref.slice(0, colonIdx), ref.slice(colonIdx + 1));
|
|
31
|
+
}
|
|
@@ -9,6 +9,15 @@
|
|
|
9
9
|
* false positives on legitimate user input.
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
+
import {
|
|
13
|
+
isPlaceholderContext,
|
|
14
|
+
isPlaceholderValue,
|
|
15
|
+
TOKEN_SHAPE,
|
|
16
|
+
TOKEN_SHAPE_LABEL,
|
|
17
|
+
TOKEN_SHAPE_MAX_LENGTH,
|
|
18
|
+
TOKEN_SHAPE_MIN_LENGTH,
|
|
19
|
+
} from "@vellumai/service-contracts/secret-detection";
|
|
20
|
+
|
|
12
21
|
import { getConfig } from "../config/loader.js";
|
|
13
22
|
import { memoizePluginPatternDerivation } from "./plugin-secret-patterns.js";
|
|
14
23
|
import { isAllowlisted } from "./secret-allowlist.js";
|
|
@@ -52,112 +61,10 @@ const getGlobalPatterns = memoizePluginPatternDerivation(
|
|
|
52
61
|
],
|
|
53
62
|
);
|
|
54
63
|
|
|
55
|
-
// ---------------------------------------------------------------------------
|
|
56
|
-
// Placeholder detection (inline — not imported from secret-scanner.ts)
|
|
57
|
-
// ---------------------------------------------------------------------------
|
|
58
|
-
|
|
59
|
-
const KNOWN_PLACEHOLDERS = new Set([
|
|
60
|
-
"your-api-key-here",
|
|
61
|
-
"your_api_key_here",
|
|
62
|
-
"insert-your-key-here",
|
|
63
|
-
"insert_your_key_here",
|
|
64
|
-
"replace-with-your-key",
|
|
65
|
-
"replace_with_your_key",
|
|
66
|
-
"xxx",
|
|
67
|
-
"xxxxxxxx",
|
|
68
|
-
"test",
|
|
69
|
-
"example",
|
|
70
|
-
"sample",
|
|
71
|
-
"demo",
|
|
72
|
-
"placeholder",
|
|
73
|
-
"changeme",
|
|
74
|
-
"CHANGEME",
|
|
75
|
-
"TODO",
|
|
76
|
-
"FIXME",
|
|
77
|
-
"your-token-here",
|
|
78
|
-
"your_token_here",
|
|
79
|
-
"my-api-key",
|
|
80
|
-
"my_api_key",
|
|
81
|
-
]);
|
|
82
|
-
|
|
83
|
-
const PLACEHOLDER_PREFIXES = [
|
|
84
|
-
"sk-test-",
|
|
85
|
-
"sk_test_",
|
|
86
|
-
"fake_",
|
|
87
|
-
"fake-",
|
|
88
|
-
"dummy_",
|
|
89
|
-
"dummy-",
|
|
90
|
-
"test_",
|
|
91
|
-
"test-",
|
|
92
|
-
"example_",
|
|
93
|
-
"example-",
|
|
94
|
-
"sample_",
|
|
95
|
-
"sample-",
|
|
96
|
-
"mock_",
|
|
97
|
-
"mock-",
|
|
98
|
-
];
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Check if the text immediately before a matched value indicates
|
|
102
|
-
* a placeholder context (e.g. "fake_", "test_").
|
|
103
|
-
*/
|
|
104
|
-
function isPlaceholderContext(preContext: string): boolean {
|
|
105
|
-
const lower = preContext.toLowerCase();
|
|
106
|
-
for (const prefix of PLACEHOLDER_PREFIXES) {
|
|
107
|
-
if (lower.endsWith(prefix)) return true;
|
|
108
|
-
}
|
|
109
|
-
return false;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* Check if a matched value is a placeholder/test value that should not
|
|
114
|
-
* trigger blocking.
|
|
115
|
-
*/
|
|
116
|
-
function isPlaceholder(value: string): boolean {
|
|
117
|
-
const lower = value.toLowerCase();
|
|
118
|
-
|
|
119
|
-
// Known placeholder values
|
|
120
|
-
if (KNOWN_PLACEHOLDERS.has(lower)) return true;
|
|
121
|
-
|
|
122
|
-
// Placeholder prefixes
|
|
123
|
-
for (const prefix of PLACEHOLDER_PREFIXES) {
|
|
124
|
-
if (lower.startsWith(prefix)) return true;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// Repeated characters in the variable portion (e.g. "AKIA" + "X" x 16)
|
|
128
|
-
// Strip known prefixes to isolate the variable part
|
|
129
|
-
const variablePart = value
|
|
130
|
-
.replace(
|
|
131
|
-
/^(?:AKIA|gh[pousr]_|github_pat_|glpat-|sk_live_|rk_live_|xoxb-|xoxp-|xapp-|sk-ant-|sk-proj-|sk-or-v1-|AIza|GOCSPX-|SK|SG\.|npm_|pypi-|key-|lin_api_|ntn_|fw_|pplx-|-----BEGIN [A-Z ]*PRIVATE KEY-----)/,
|
|
132
|
-
"",
|
|
133
|
-
)
|
|
134
|
-
.replace(/[^A-Za-z0-9]/g, "");
|
|
135
|
-
if (variablePart.length >= 8) {
|
|
136
|
-
const firstChar = variablePart[0];
|
|
137
|
-
if (variablePart.split("").every((c) => c === firstChar)) return true;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
return false;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
64
|
// ---------------------------------------------------------------------------
|
|
144
65
|
// Token-shape heuristic (whole-message only)
|
|
145
66
|
// ---------------------------------------------------------------------------
|
|
146
67
|
|
|
147
|
-
/**
|
|
148
|
-
* A single token-shaped value: an alphanumeric head, a separator-delimited
|
|
149
|
-
* secret keyword infix, and a >=16-char tail (e.g. `virlo_tkn_JF…`). The
|
|
150
|
-
* capture group isolates the tail for placeholder checks. Applied only when
|
|
151
|
-
* the entire trimmed message is one such token — the whole-message and
|
|
152
|
-
* keyword-infix requirements keep false positives near zero without any
|
|
153
|
-
* entropy scoring.
|
|
154
|
-
*/
|
|
155
|
-
const TOKEN_SHAPE =
|
|
156
|
-
/^[A-Za-z0-9][A-Za-z0-9_-]*[_-](?:tkn|token|key|secret|api|pat|sk|auth)[_-]([A-Za-z0-9_-]{16,})$/i;
|
|
157
|
-
|
|
158
|
-
const TOKEN_SHAPE_MIN_LENGTH = 20;
|
|
159
|
-
const TOKEN_SHAPE_MAX_LENGTH = 512;
|
|
160
|
-
|
|
161
68
|
/**
|
|
162
69
|
* Check whether the entire message content is a single token-shaped value
|
|
163
70
|
* that should be blocked (no whitespace, plausible length, keyword infix,
|
|
@@ -181,7 +88,7 @@ function isBlockedTokenShapedMessage(content: string): boolean {
|
|
|
181
88
|
// Check both the full value (test_/fake_ prefixes) and the tail after the
|
|
182
89
|
// keyword infix (repeated-char fillers like "xxxxxxxxxxxxxxxx")
|
|
183
90
|
const tail = match[1]!;
|
|
184
|
-
if (
|
|
91
|
+
if (isPlaceholderValue(trimmed) || isPlaceholderValue(tail)) {
|
|
185
92
|
return false;
|
|
186
93
|
}
|
|
187
94
|
|
|
@@ -226,7 +133,9 @@ export function checkIngressForSecrets(content: string): IngressCheckResult {
|
|
|
226
133
|
// a small window before it for placeholder prefixes like "fake_")
|
|
227
134
|
const contextStart = Math.max(0, match.index - 10);
|
|
228
135
|
const preContext = content.slice(contextStart, match.index);
|
|
229
|
-
if (
|
|
136
|
+
if (isPlaceholderValue(value) || isPlaceholderContext(preContext)) {
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
230
139
|
|
|
231
140
|
// Skip user-allowlisted values
|
|
232
141
|
if (isAllowlisted(value)) continue;
|
|
@@ -242,7 +151,7 @@ export function checkIngressForSecrets(content: string): IngressCheckResult {
|
|
|
242
151
|
secretDetection.blockTokenShapedMessages &&
|
|
243
152
|
isBlockedTokenShapedMessage(content)
|
|
244
153
|
) {
|
|
245
|
-
detectedTypes.push(
|
|
154
|
+
detectedTypes.push(TOKEN_SHAPE_LABEL);
|
|
246
155
|
}
|
|
247
156
|
|
|
248
157
|
if (detectedTypes.length === 0) {
|
|
@@ -1,142 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* this list. When adding a new integration, add its API key pattern here.
|
|
6
|
-
*
|
|
7
|
-
* This module is intentionally data-only: no imports, no entropy logic,
|
|
8
|
-
* no config — safe for hot-path consumers like log serializers.
|
|
2
|
+
* Prefix-based secret patterns — sourced from the shared
|
|
3
|
+
* `@vellumai/service-contracts/secret-detection` module, the single source
|
|
4
|
+
* of truth for prefix-based secret detection across the daemon and clients.
|
|
9
5
|
*/
|
|
10
6
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
/** Human-readable label shown in block notices and redaction tags. */
|
|
17
|
-
label: string;
|
|
18
|
-
/**
|
|
19
|
-
* Regex that matches the token value. Must NOT include the `g` flag or
|
|
20
|
-
* capture groups — consumers add those as needed.
|
|
21
|
-
*/
|
|
22
|
-
regex: RegExp;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// ---------------------------------------------------------------------------
|
|
26
|
-
// Prefix patterns
|
|
27
|
-
// ---------------------------------------------------------------------------
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* High-confidence, prefix-based secret patterns.
|
|
31
|
-
*
|
|
32
|
-
* Each entry matches a known API key / token format by its distinctive
|
|
33
|
-
* prefix. Patterns that require surrounding context (entropy analysis,
|
|
34
|
-
* keyword proximity, URL structure) do NOT belong here — they stay in
|
|
35
|
-
* `secret-scanner.ts` as scanner-only patterns.
|
|
36
|
-
*
|
|
37
|
-
* **When adding a new third-party integration, add its API key pattern
|
|
38
|
-
* here.** If the service uses only opaque OAuth access tokens (no fixed
|
|
39
|
-
* prefix), no pattern is needed.
|
|
40
|
-
*/
|
|
41
|
-
export const PREFIX_PATTERNS: SecretPrefixPattern[] = [
|
|
42
|
-
// -- AWS --
|
|
43
|
-
{ label: "AWS Access Key", regex: /AKIA[0-9A-Z]{16}/ },
|
|
44
|
-
|
|
45
|
-
// -- GitHub --
|
|
46
|
-
{ label: "GitHub Token", regex: /gh[pousr]_[A-Za-z0-9_]{36,}/ },
|
|
47
|
-
{ label: "GitHub Fine-Grained PAT", regex: /github_pat_[A-Za-z0-9_]{22,}/ },
|
|
48
|
-
|
|
49
|
-
// -- GitLab --
|
|
50
|
-
{ label: "GitLab Token", regex: /glpat-[A-Za-z0-9\-_]{20,}/ },
|
|
51
|
-
|
|
52
|
-
// -- Stripe --
|
|
53
|
-
{ label: "Stripe Secret Key", regex: /sk_live_[A-Za-z0-9]{24,}/ },
|
|
54
|
-
{ label: "Stripe Restricted Key", regex: /rk_live_[A-Za-z0-9]{24,}/ },
|
|
55
|
-
|
|
56
|
-
// -- Slack --
|
|
57
|
-
{
|
|
58
|
-
label: "Slack Bot Token",
|
|
59
|
-
regex: /xoxb-[0-9]{10,}-[0-9]{10,}-[A-Za-z0-9]{24,}/,
|
|
60
|
-
},
|
|
61
|
-
{
|
|
62
|
-
label: "Slack User Token",
|
|
63
|
-
regex: /xoxp-[0-9]{10,}-[0-9]{10,}-[0-9]{10,}-[a-f0-9]{32}/,
|
|
64
|
-
},
|
|
65
|
-
{
|
|
66
|
-
label: "Slack App Token",
|
|
67
|
-
regex: /xapp-[0-9]+-[A-Za-z0-9]+-[0-9]+-[A-Za-z0-9]+/,
|
|
68
|
-
},
|
|
69
|
-
|
|
70
|
-
// -- Telegram --
|
|
71
|
-
{
|
|
72
|
-
label: "Telegram Bot Token",
|
|
73
|
-
// Format: <bot_id>:<secret> where bot_id is 8–10 digits, secret is 35 chars
|
|
74
|
-
regex: /[0-9]{8,10}:[A-Za-z0-9_-]{35}/,
|
|
75
|
-
},
|
|
76
|
-
|
|
77
|
-
// -- Anthropic --
|
|
78
|
-
{ label: "Anthropic API Key", regex: /sk-ant-[A-Za-z0-9\-_]{80,}/ },
|
|
79
|
-
|
|
80
|
-
// -- OpenAI --
|
|
81
|
-
{
|
|
82
|
-
label: "OpenAI API Key",
|
|
83
|
-
regex: /sk-[A-Za-z0-9]{20}T3BlbkFJ[A-Za-z0-9]{20}/,
|
|
84
|
-
},
|
|
85
|
-
{ label: "OpenAI Project Key", regex: /sk-proj-[A-Za-z0-9\-_]{40,}/ },
|
|
86
|
-
|
|
87
|
-
// -- Google --
|
|
88
|
-
{ label: "Google API Key", regex: /AIza[A-Za-z0-9\-_]{35}/ },
|
|
89
|
-
{
|
|
90
|
-
label: "Google OAuth Client Secret",
|
|
91
|
-
regex: /GOCSPX-[A-Za-z0-9\-_]{28}/,
|
|
92
|
-
},
|
|
93
|
-
|
|
94
|
-
// -- Twilio --
|
|
95
|
-
{ label: "Twilio API Key", regex: /SK[0-9a-f]{32}/ },
|
|
96
|
-
|
|
97
|
-
// -- SendGrid --
|
|
98
|
-
{
|
|
99
|
-
label: "SendGrid API Key",
|
|
100
|
-
regex: /SG\.[A-Za-z0-9\-_]{22}\.[A-Za-z0-9\-_]{43}/,
|
|
101
|
-
},
|
|
102
|
-
|
|
103
|
-
// -- Mailgun --
|
|
104
|
-
{ label: "Mailgun API Key", regex: /key-[A-Za-z0-9]{32}/ },
|
|
105
|
-
|
|
106
|
-
// -- npm --
|
|
107
|
-
{ label: "npm Token", regex: /npm_[A-Za-z0-9]{36}/ },
|
|
108
|
-
|
|
109
|
-
// -- PyPI --
|
|
110
|
-
{ label: "PyPI API Token", regex: /pypi-[A-Za-z0-9\-_]{50,}/ },
|
|
111
|
-
|
|
112
|
-
// -- Private keys --
|
|
113
|
-
{
|
|
114
|
-
label: "Private Key",
|
|
115
|
-
regex:
|
|
116
|
-
/-----BEGIN (?:RSA |DSA |EC |OPENSSH |PGP )?PRIVATE KEY(?:\s+BLOCK)?-----/,
|
|
117
|
-
},
|
|
118
|
-
|
|
119
|
-
// -- Linear --
|
|
120
|
-
{ label: "Linear API Key", regex: /lin_api_[A-Za-z0-9]{32,}/ },
|
|
121
|
-
|
|
122
|
-
// -- Notion --
|
|
123
|
-
{ label: "Notion Integration Token", regex: /ntn_[A-Za-z0-9]{40,}/ },
|
|
124
|
-
|
|
125
|
-
// -- OpenRouter --
|
|
126
|
-
{ label: "OpenRouter API Key", regex: /sk-or-v1-[A-Za-z0-9\-_]{40,}/ },
|
|
127
|
-
|
|
128
|
-
// -- Vercel AI Gateway --
|
|
129
|
-
{ label: "Vercel AI Gateway API Key", regex: /vck_[A-Za-z0-9\-_]{24,}/ },
|
|
130
|
-
|
|
131
|
-
// -- Fireworks --
|
|
132
|
-
{ label: "Fireworks API Key", regex: /fw_[A-Za-z0-9]{32,}/ },
|
|
133
|
-
|
|
134
|
-
// -- Perplexity --
|
|
135
|
-
{ label: "Perplexity API Key", regex: /pplx-[A-Za-z0-9]{40,}/ },
|
|
136
|
-
|
|
137
|
-
// -- Tavily --
|
|
138
|
-
{ label: "Tavily API Key", regex: /tvly-[A-Za-z0-9]{20,}/ },
|
|
139
|
-
|
|
140
|
-
// -- Firecrawl --
|
|
141
|
-
{ label: "Firecrawl API Key", regex: /fc-[A-Za-z0-9]{20,}/ },
|
|
142
|
-
];
|
|
7
|
+
export {
|
|
8
|
+
PREFIX_PATTERNS,
|
|
9
|
+
REDACTION_PREFIX_PATTERNS,
|
|
10
|
+
type SecretPrefixPattern,
|
|
11
|
+
} from "@vellumai/service-contracts/secret-detection";
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
import { memoizePluginPatternDerivation } from "./plugin-secret-patterns.js";
|
|
13
13
|
import { isAllowlisted } from "./secret-allowlist.js";
|
|
14
14
|
import {
|
|
15
|
-
|
|
15
|
+
REDACTION_PREFIX_PATTERNS,
|
|
16
16
|
type SecretPrefixPattern,
|
|
17
17
|
} from "./secret-patterns.js";
|
|
18
18
|
|
|
@@ -71,9 +71,14 @@ function derivePluginScannerPattern(p: SecretPrefixPattern): SecretPattern {
|
|
|
71
71
|
};
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
// Static patterns derived from the shared source of truth.
|
|
74
|
+
// Static patterns derived from the shared source of truth. This scanner
|
|
75
|
+
// redacts by replacing the matched span in place, so it uses the bounded
|
|
76
|
+
// whole-block private-key matcher (via REDACTION_PREFIX_PATTERNS): the match
|
|
77
|
+
// must cover header → body → footer or the key body would survive redaction.
|
|
78
|
+
// The bound keeps it O(n) on large serialized strings; `detectSecretsInText`
|
|
79
|
+
// (chat) keeps the unbounded whole-block matcher for full-key capture.
|
|
75
80
|
const PREFIX_DERIVED: SecretPattern[] =
|
|
76
|
-
|
|
81
|
+
REDACTION_PREFIX_PATTERNS.map(deriveScannerPattern);
|
|
77
82
|
|
|
78
83
|
// Scanner-only patterns that require surrounding context or are not
|
|
79
84
|
// simple prefix matches — these stay defined here.
|
|
@@ -11,10 +11,10 @@
|
|
|
11
11
|
*
|
|
12
12
|
* State is held on `globalThis.vellumAssistant.storePathOverride` so
|
|
13
13
|
* test helpers in `__tests__/` can read/write it WITHOUT importing this
|
|
14
|
-
* module
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
14
|
+
* module. Both sides reference the shared ambient `VellumStorePathOverride`
|
|
15
|
+
* type (declared in `src/vellum-assistant-namespace.d.ts`), which types the
|
|
16
|
+
* slot without adding a runtime import between them. See
|
|
17
|
+
* `__tests__/encrypted-store-test-helpers.ts` for the test-side writer.
|
|
18
18
|
*
|
|
19
19
|
* Note: the new test preload places `VELLUM_WORKSPACE_DIR` at
|
|
20
20
|
* `<tmpRoot>/workspace`, so `getProtectedDir()` resolves to
|
|
@@ -27,18 +27,8 @@
|
|
|
27
27
|
* - `__tests__/encrypted-store-test-helpers.ts` (writes for tests, via globalThis)
|
|
28
28
|
*/
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
storeKeyPath: string | null;
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
type VellumAssistantNamespace = {
|
|
36
|
-
storePathOverride?: PathSlot;
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
function slot(): PathSlot {
|
|
40
|
-
const g = globalThis as { vellumAssistant?: VellumAssistantNamespace };
|
|
41
|
-
const ns = (g.vellumAssistant ??= {});
|
|
30
|
+
function slot(): VellumStorePathOverride {
|
|
31
|
+
const ns = (globalThis.vellumAssistant ??= {});
|
|
42
32
|
return (ns.storePathOverride ??= { storePath: null, storeKeyPath: null });
|
|
43
33
|
}
|
|
44
34
|
|
package/src/sequence/store.ts
CHANGED
|
@@ -11,6 +11,7 @@ import { and, asc, eq, lte, sql } from "drizzle-orm";
|
|
|
11
11
|
import { v4 as uuid } from "uuid";
|
|
12
12
|
|
|
13
13
|
import { getDb } from "../persistence/db-connection.js";
|
|
14
|
+
import { isLifecycleQuiesced } from "../persistence/lifecycle-quiesce.js";
|
|
14
15
|
import { rawChanges } from "../persistence/raw-query.js";
|
|
15
16
|
import { sequenceEnrollments, sequences } from "../persistence/schema/index.js";
|
|
16
17
|
import { AssistantError, ErrorCode } from "../util/errors.js";
|
|
@@ -224,6 +225,13 @@ export function claimDueEnrollments(
|
|
|
224
225
|
now: number,
|
|
225
226
|
limit = 10,
|
|
226
227
|
): SequenceEnrollment[] {
|
|
228
|
+
// Drain gate: while a quiesce lease is active, claim nothing — a sequence
|
|
229
|
+
// step's outreach starts before any row the drain snapshot can see.
|
|
230
|
+
// Fail-open via the lease read.
|
|
231
|
+
if (isLifecycleQuiesced()) {
|
|
232
|
+
return [];
|
|
233
|
+
}
|
|
234
|
+
|
|
227
235
|
const db = getDb();
|
|
228
236
|
const candidates = db
|
|
229
237
|
.select()
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Handle generic event signals from the CLI.
|
|
3
3
|
*
|
|
4
|
-
* When the CLI writes a JSON-encoded {@link
|
|
4
|
+
* When the CLI writes a JSON-encoded {@link AssistantEvent} to
|
|
5
5
|
* `signals/emit-event`, the daemon's ConfigWatcher detects the file
|
|
6
6
|
* change and invokes {@link handleEmitEventSignal}, which reads the
|
|
7
7
|
* payload and publishes it to connected clients via the in-process
|
|
@@ -15,9 +15,8 @@
|
|
|
15
15
|
import { readFileSync } from "node:fs";
|
|
16
16
|
import { join } from "node:path";
|
|
17
17
|
|
|
18
|
-
import type {
|
|
19
|
-
import {
|
|
20
|
-
import { assistantEventHub } from "../runtime/assistant-event-hub.js";
|
|
18
|
+
import type { AssistantEvent } from "../api/index.js";
|
|
19
|
+
import { broadcastMessage } from "../runtime/assistant-event-hub.js";
|
|
21
20
|
import { getLogger } from "../util/logger.js";
|
|
22
21
|
import { getSignalsDir } from "../util/platform.js";
|
|
23
22
|
|
|
@@ -26,13 +25,9 @@ const log = getLogger("signal:emit-event");
|
|
|
26
25
|
export function handleEmitEventSignal(): void {
|
|
27
26
|
try {
|
|
28
27
|
const content = readFileSync(join(getSignalsDir(), "emit-event"), "utf-8");
|
|
29
|
-
const message = JSON.parse(content) as
|
|
28
|
+
const message = JSON.parse(content) as AssistantEvent;
|
|
30
29
|
|
|
31
|
-
|
|
32
|
-
.publish(buildAssistantEvent(message))
|
|
33
|
-
.catch((err: unknown) => {
|
|
34
|
-
log.error({ err }, "Failed to publish event from signal");
|
|
35
|
-
});
|
|
30
|
+
broadcastMessage(message);
|
|
36
31
|
|
|
37
32
|
log.info({ type: message.type }, "Emit-event signal handled");
|
|
38
33
|
} catch (err) {
|