@vellumai/assistant 0.10.12 → 0.11.0-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 +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 +264 -14
- 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__/app-conversation-ids-backfill.test.ts +33 -2
- package/src/__tests__/app-conversation-ids.test.ts +204 -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-group-tools.test.ts +279 -0
- 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-lineage.test.ts +235 -0
- 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__/platform-callback-registration.test.ts +10 -10
- 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__/resolve-app-id.test.ts +32 -0
- 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 +26 -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 +587 -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-side-effects-slack-dm.test.ts +1 -0
- 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 +482 -2
- 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/api/responses/subagent-detail.ts +13 -0
- package/src/approvals/AGENTS.md +2 -0
- package/src/approvals/guardian-request-resolvers.ts +118 -24
- package/src/apps/app-store.ts +95 -4
- package/src/calls/__tests__/voice-control-protocol.test.ts +57 -0
- package/src/calls/__tests__/voice-session-bridge.test.ts +229 -7
- 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 +178 -65
- 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/commands/webhooks.help.ts +9 -4
- 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/conversation-groups/SKILL.md +29 -0
- package/src/config/bundled-skills/conversation-groups/TOOLS.json +58 -0
- package/src/config/bundled-skills/conversation-groups/tools/group-create.ts +12 -0
- package/src/config/bundled-skills/conversation-groups/tools/group-list.ts +12 -0
- package/src/config/bundled-skills/conversation-groups/tools/move-to-group.ts +12 -0
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +13 -7
- package/src/config/bundled-skills/schedule/SKILL.md +2 -0
- package/src/config/feature-flag-cache.ts +6 -16
- package/src/config/feature-flag-registry.json +14 -38
- 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-lineage.ts +76 -0
- 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 +8 -14
- 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 +32 -16
- 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-continuation-fork-hydration.test.ts +286 -0
- 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 +1154 -636
- 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 +1288 -439
- 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 +298 -15
- package/src/permissions/checker.ts +102 -36
- 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 +269 -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/conversation-parent.ts +27 -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/migrations/354-backfill-app-conversation-lineage.ts +41 -0
- package/src/persistence/schema/infrastructure.ts +11 -0
- package/src/persistence/steps.ts +9 -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/prompts/sections.ts +4 -16
- 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/__tests__/subagents-routes.test.ts +250 -0
- package/src/runtime/routes/__tests__/webhook-routes.test.ts +201 -0
- 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/subagents-routes.ts +35 -8
- package/src/runtime/routes/upgrade-broadcast-routes.ts +4 -5
- package/src/runtime/routes/webhook-routes.ts +89 -30
- 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__/conversation-group-tool-input-schemas.test.ts +61 -0
- 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/apps/resolve-app-id.ts +15 -3
- 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/conversation-groups/group_create.ts +63 -0
- package/src/tools/conversation-groups/group_list.ts +20 -0
- package/src/tools/conversation-groups/group_shared.ts +52 -0
- package/src/tools/conversation-groups/move_to_group.ts +106 -0
- 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/util/platform.ts +15 -0
- 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/tsconfig.plugin-api.json +1 -1
- 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
|
@@ -0,0 +1,468 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared prefix-based secret patterns — the single source of truth.
|
|
3
|
+
*
|
|
4
|
+
* Ingress blocking, tool output scanning, log redaction, and client-side
|
|
5
|
+
* composer detection all consume this list. When adding a new integration,
|
|
6
|
+
* add its API key pattern here.
|
|
7
|
+
*
|
|
8
|
+
* This module is intentionally data-only: no imports, no entropy logic,
|
|
9
|
+
* no config — safe for hot-path consumers like log serializers, and
|
|
10
|
+
* browser-safe so web clients can bundle it directly.
|
|
11
|
+
*
|
|
12
|
+
* The exported `PATTERNS`/constants are shared verbatim by the daemon and the
|
|
13
|
+
* web clients, so the two sides agree on what a secret *looks like*. The web
|
|
14
|
+
* composer scanner is a conservative superset pre-filter of the daemon ingress
|
|
15
|
+
* check, not an identical twin: the daemon additionally applies a per-user
|
|
16
|
+
* secret allowlist and config gating (`secretDetection.enabled` /
|
|
17
|
+
* `blockIngress`) on top of these shared patterns, so the client may warn on a
|
|
18
|
+
* few values the server would accept (e.g. an allowlisted token). Only the
|
|
19
|
+
* shared patterns and length bounds in this module are guaranteed identical
|
|
20
|
+
* across client and server.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
// Types
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
|
|
27
|
+
export interface SecretPrefixPattern {
|
|
28
|
+
/** Human-readable label shown in block notices and redaction tags. */
|
|
29
|
+
label: string;
|
|
30
|
+
/**
|
|
31
|
+
* Regex that matches the token value. Must NOT include the `g` flag or
|
|
32
|
+
* capture groups — consumers add those as needed.
|
|
33
|
+
*/
|
|
34
|
+
regex: RegExp;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
// Prefix patterns
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* High-confidence, prefix-based secret patterns.
|
|
43
|
+
*
|
|
44
|
+
* Each entry matches a known API key / token format by its distinctive
|
|
45
|
+
* prefix. Patterns that require surrounding context (entropy analysis,
|
|
46
|
+
* keyword proximity, URL structure) do NOT belong here — they stay in
|
|
47
|
+
* `secret-scanner.ts` as scanner-only patterns.
|
|
48
|
+
*
|
|
49
|
+
* **When adding a new third-party integration, add its API key pattern
|
|
50
|
+
* here.** If the service uses only opaque OAuth access tokens (no fixed
|
|
51
|
+
* prefix), no pattern is needed.
|
|
52
|
+
*/
|
|
53
|
+
/** Detection label for PEM private-key matches. */
|
|
54
|
+
export const PRIVATE_KEY_LABEL = "Private Key";
|
|
55
|
+
|
|
56
|
+
// PEM private-key header/footer type variants, shared by the Private Key
|
|
57
|
+
// pattern and the complete-block check.
|
|
58
|
+
const PEM_KEY_TYPE = String.raw`(?:RSA |DSA |EC |OPENSSH |PGP )?PRIVATE KEY(?:\s+BLOCK)?`;
|
|
59
|
+
const PEM_BEGIN = String.raw`-----BEGIN ${PEM_KEY_TYPE}-----`;
|
|
60
|
+
const PEM_END = String.raw`-----END ${PEM_KEY_TYPE}-----`;
|
|
61
|
+
|
|
62
|
+
const PEM_COMPLETE_BLOCK = new RegExp(`${PEM_END}$`);
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Whole-block PEM body atom: one tempered body character. `(?!-----BEGIN)`
|
|
66
|
+
* keeps the body from crossing into an adjacent block, so two keys never
|
|
67
|
+
* merge into one span.
|
|
68
|
+
*/
|
|
69
|
+
const PEM_BLOCK_TAIL = String.raw`(?:(?!-----BEGIN)[\s\S])`;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Upper bound on the PEM body scan distance for the redaction matcher. An
|
|
73
|
+
* RSA-8192 PEM is ~6.4 KB, so 16 KiB clears real keys with headroom while
|
|
74
|
+
* capping the per-header rescan distance. The bound is what keeps the
|
|
75
|
+
* redaction matcher O(n) on large serialized strings full of footerless
|
|
76
|
+
* `-----BEGIN … PRIVATE KEY-----` headers: each header rescans at most this
|
|
77
|
+
* far looking for a footer instead of to EOF, which is what the unbounded
|
|
78
|
+
* whole-block matcher does (its O(n²) worst case).
|
|
79
|
+
*/
|
|
80
|
+
export const PEM_REDACTION_MAX_BODY_LENGTH = 16384;
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Whole-block private-key matcher for detect-AND-REDACT consumers (log
|
|
84
|
+
* serializers, the tool-output scanner, staged-export rewrite).
|
|
85
|
+
*
|
|
86
|
+
* These consumers replace the matched span in place, so the match must cover
|
|
87
|
+
* the ENTIRE key — header → body → footer — or the base64 body and `-----END-----`
|
|
88
|
+
* footer survive redaction. This captures the whole block, but with a
|
|
89
|
+
* length-BOUNDED body quantifier ({@link PEM_REDACTION_MAX_BODY_LENGTH}) so a
|
|
90
|
+
* stream of footerless headers cannot drive the O(n²) worst case the unbounded
|
|
91
|
+
* whole-block matcher incurs. The footer group is optional, so a truncated /
|
|
92
|
+
* footerless key still matches header-only — preserving the detection-fires
|
|
93
|
+
* guarantee ingress blocking relies on. Tempered + lazy + bounded ⇒ no
|
|
94
|
+
* catastrophic backtracking.
|
|
95
|
+
*
|
|
96
|
+
* `detectSecretsInText` (chat) keeps the unbounded whole-block
|
|
97
|
+
* {@link PREFIX_PATTERNS} entry, which the store/rewrite path relies on to
|
|
98
|
+
* capture arbitrarily large keys in full.
|
|
99
|
+
*/
|
|
100
|
+
export const PRIVATE_KEY_REDACTION_REGEX = new RegExp(
|
|
101
|
+
`${PEM_BEGIN}(?:${PEM_BLOCK_TAIL}{0,${PEM_REDACTION_MAX_BODY_LENGTH}}?${PEM_END})?`,
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* True when a `Private Key` match is a complete PEM block — it ends at an
|
|
106
|
+
* `-----END … PRIVATE KEY-----` footer (the pattern guarantees it starts at
|
|
107
|
+
* the BEGIN header). A header-only match means the footer is absent from
|
|
108
|
+
* the scanned text (truncated or partial paste), so the match does NOT
|
|
109
|
+
* cover the key body: storing or replacing such a value would leave key
|
|
110
|
+
* material behind.
|
|
111
|
+
*/
|
|
112
|
+
export function isCompletePrivateKeyBlock(value: string): boolean {
|
|
113
|
+
return PEM_COMPLETE_BLOCK.test(value);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export const PREFIX_PATTERNS: SecretPrefixPattern[] = [
|
|
117
|
+
// -- Private keys --
|
|
118
|
+
// First in the list on purpose: `detectSecretsInText` resolves overlapping
|
|
119
|
+
// spans by list order, and a PEM body is base64 — it can embed runs that
|
|
120
|
+
// look like other tokens (e.g. `AKIA` + 16 chars). The whole-block match
|
|
121
|
+
// must win those overlaps or the block would be fragmented.
|
|
122
|
+
{
|
|
123
|
+
label: PRIVATE_KEY_LABEL,
|
|
124
|
+
// Matches the entire PEM block (header through footer) when the END
|
|
125
|
+
// footer is present, so consumers that store or replace the matched
|
|
126
|
+
// value handle the whole key. The block tail is optional: a header with
|
|
127
|
+
// no footer (truncated or streamed partial paste) still matches alone,
|
|
128
|
+
// which ingress blocking relies on. The body is tempered — it never
|
|
129
|
+
// crosses another BEGIN header — so adjacent blocks match separately.
|
|
130
|
+
regex: new RegExp(`${PEM_BEGIN}(?:${PEM_BLOCK_TAIL}*?${PEM_END})?`),
|
|
131
|
+
},
|
|
132
|
+
|
|
133
|
+
// -- AWS --
|
|
134
|
+
{ label: "AWS Access Key", regex: /AKIA[0-9A-Z]{16}/ },
|
|
135
|
+
|
|
136
|
+
// -- GitHub --
|
|
137
|
+
{ label: "GitHub Token", regex: /gh[pousr]_[A-Za-z0-9_]{36,}/ },
|
|
138
|
+
{ label: "GitHub Fine-Grained PAT", regex: /github_pat_[A-Za-z0-9_]{22,}/ },
|
|
139
|
+
|
|
140
|
+
// -- GitLab --
|
|
141
|
+
{ label: "GitLab Token", regex: /glpat-[A-Za-z0-9\-_]{20,}/ },
|
|
142
|
+
|
|
143
|
+
// -- Stripe --
|
|
144
|
+
{ label: "Stripe Secret Key", regex: /sk_live_[A-Za-z0-9]{24,}/ },
|
|
145
|
+
{ label: "Stripe Restricted Key", regex: /rk_live_[A-Za-z0-9]{24,}/ },
|
|
146
|
+
|
|
147
|
+
// -- Slack --
|
|
148
|
+
{
|
|
149
|
+
label: "Slack Bot Token",
|
|
150
|
+
regex: /xoxb-[0-9]{10,}-[0-9]{10,}-[A-Za-z0-9]{24,}/,
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
label: "Slack User Token",
|
|
154
|
+
regex: /xoxp-[0-9]{10,}-[0-9]{10,}-[0-9]{10,}-[a-f0-9]{32}/,
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
label: "Slack App Token",
|
|
158
|
+
regex: /xapp-[0-9]+-[A-Za-z0-9]+-[0-9]+-[A-Za-z0-9]+/,
|
|
159
|
+
},
|
|
160
|
+
|
|
161
|
+
// -- Telegram --
|
|
162
|
+
{
|
|
163
|
+
label: "Telegram Bot Token",
|
|
164
|
+
// Format: <bot_id>:<secret> where bot_id is 8–10 digits, secret is 35 chars
|
|
165
|
+
regex: /[0-9]{8,10}:[A-Za-z0-9_-]{35}/,
|
|
166
|
+
},
|
|
167
|
+
|
|
168
|
+
// -- Anthropic --
|
|
169
|
+
{ label: "Anthropic API Key", regex: /sk-ant-[A-Za-z0-9\-_]{80,}/ },
|
|
170
|
+
|
|
171
|
+
// -- OpenAI --
|
|
172
|
+
{
|
|
173
|
+
label: "OpenAI API Key",
|
|
174
|
+
regex: /sk-[A-Za-z0-9]{20}T3BlbkFJ[A-Za-z0-9]{20}/,
|
|
175
|
+
},
|
|
176
|
+
{ label: "OpenAI Project Key", regex: /sk-proj-[A-Za-z0-9\-_]{40,}/ },
|
|
177
|
+
|
|
178
|
+
// -- Google --
|
|
179
|
+
{ label: "Google API Key", regex: /AIza[A-Za-z0-9\-_]{35}/ },
|
|
180
|
+
{
|
|
181
|
+
label: "Google OAuth Client Secret",
|
|
182
|
+
regex: /GOCSPX-[A-Za-z0-9\-_]{28}/,
|
|
183
|
+
},
|
|
184
|
+
|
|
185
|
+
// -- Twilio --
|
|
186
|
+
{ label: "Twilio API Key", regex: /SK[0-9a-f]{32}/ },
|
|
187
|
+
|
|
188
|
+
// -- SendGrid --
|
|
189
|
+
{
|
|
190
|
+
label: "SendGrid API Key",
|
|
191
|
+
regex: /SG\.[A-Za-z0-9\-_]{22}\.[A-Za-z0-9\-_]{43}/,
|
|
192
|
+
},
|
|
193
|
+
|
|
194
|
+
// -- Mailgun --
|
|
195
|
+
{ label: "Mailgun API Key", regex: /key-[A-Za-z0-9]{32}/ },
|
|
196
|
+
|
|
197
|
+
// -- npm --
|
|
198
|
+
{ label: "npm Token", regex: /npm_[A-Za-z0-9]{36}/ },
|
|
199
|
+
|
|
200
|
+
// -- PyPI --
|
|
201
|
+
{ label: "PyPI API Token", regex: /pypi-[A-Za-z0-9\-_]{50,}/ },
|
|
202
|
+
|
|
203
|
+
// -- Linear --
|
|
204
|
+
{ label: "Linear API Key", regex: /lin_api_[A-Za-z0-9]{32,}/ },
|
|
205
|
+
|
|
206
|
+
// -- Notion --
|
|
207
|
+
{ label: "Notion Integration Token", regex: /ntn_[A-Za-z0-9]{40,}/ },
|
|
208
|
+
|
|
209
|
+
// -- OpenRouter --
|
|
210
|
+
{ label: "OpenRouter API Key", regex: /sk-or-v1-[A-Za-z0-9\-_]{40,}/ },
|
|
211
|
+
|
|
212
|
+
// -- Vercel AI Gateway --
|
|
213
|
+
{ label: "Vercel AI Gateway API Key", regex: /vck_[A-Za-z0-9\-_]{24,}/ },
|
|
214
|
+
|
|
215
|
+
// -- Fireworks --
|
|
216
|
+
{ label: "Fireworks API Key", regex: /fw_[A-Za-z0-9]{32,}/ },
|
|
217
|
+
|
|
218
|
+
// -- Perplexity --
|
|
219
|
+
{ label: "Perplexity API Key", regex: /pplx-[A-Za-z0-9]{40,}/ },
|
|
220
|
+
|
|
221
|
+
// -- Tavily --
|
|
222
|
+
{ label: "Tavily API Key", regex: /tvly-[A-Za-z0-9]{20,}/ },
|
|
223
|
+
|
|
224
|
+
// -- Firecrawl --
|
|
225
|
+
{ label: "Firecrawl API Key", regex: /fc-[A-Za-z0-9]{20,}/ },
|
|
226
|
+
];
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* {@link PREFIX_PATTERNS} variant for detect-AND-redact consumers (log
|
|
230
|
+
* serializers, the tool-output scanner, staged-export rewrite). Identical to
|
|
231
|
+
* `PREFIX_PATTERNS` except the private-key entry uses the length-BOUNDED
|
|
232
|
+
* whole-block matcher ({@link PRIVATE_KEY_REDACTION_REGEX}): those consumers
|
|
233
|
+
* replace the matched span in place, so the match must cover the whole key
|
|
234
|
+
* (header → body → footer) or the body leaks — but they route to the bounded
|
|
235
|
+
* matcher to avoid the unbounded whole-block matcher's O(n²) worst case on
|
|
236
|
+
* large serialized strings. `detectSecretsInText` (chat) uses `PREFIX_PATTERNS`
|
|
237
|
+
* for unbounded full-block capture.
|
|
238
|
+
*/
|
|
239
|
+
export const REDACTION_PREFIX_PATTERNS: SecretPrefixPattern[] =
|
|
240
|
+
PREFIX_PATTERNS.map((p) =>
|
|
241
|
+
p.label === PRIVATE_KEY_LABEL
|
|
242
|
+
? { label: PRIVATE_KEY_LABEL, regex: PRIVATE_KEY_REDACTION_REGEX }
|
|
243
|
+
: p,
|
|
244
|
+
);
|
|
245
|
+
|
|
246
|
+
// ---------------------------------------------------------------------------
|
|
247
|
+
// Token-shape heuristic (whole-message only)
|
|
248
|
+
// ---------------------------------------------------------------------------
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* A single token-shaped value: an alphanumeric head, a separator-delimited
|
|
252
|
+
* secret keyword infix, and a >=16-char tail (e.g. `virlo_tkn_JF…`). The
|
|
253
|
+
* capture group isolates the tail for placeholder checks. Applied only when
|
|
254
|
+
* the entire trimmed message is one such token — the whole-message and
|
|
255
|
+
* keyword-infix requirements keep false positives near zero without any
|
|
256
|
+
* entropy scoring.
|
|
257
|
+
*/
|
|
258
|
+
export const TOKEN_SHAPE =
|
|
259
|
+
/^[A-Za-z0-9][A-Za-z0-9_-]*[_-](?:tkn|token|key|secret|api|pat|sk|auth)[_-]([A-Za-z0-9_-]{16,})$/i;
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Length bounds for the whole-message token-shape heuristic, shared by the
|
|
263
|
+
* daemon ingress check and the web composer scanner so both accept and reject
|
|
264
|
+
* the same whole-message tokens. Below the min a "token" is too short to be a
|
|
265
|
+
* plausible secret; above the max it is almost certainly a paste of something
|
|
266
|
+
* else (a base64 blob, a minified line) rather than a single credential.
|
|
267
|
+
*/
|
|
268
|
+
export const TOKEN_SHAPE_MIN_LENGTH = 20;
|
|
269
|
+
export const TOKEN_SHAPE_MAX_LENGTH = 512;
|
|
270
|
+
|
|
271
|
+
/** Detection label for a whole-message token-shape match, shared by the daemon
|
|
272
|
+
* ingress check and the web composer scanner so both report the same
|
|
273
|
+
* user-facing type. */
|
|
274
|
+
export const TOKEN_SHAPE_LABEL = "Token-shaped value";
|
|
275
|
+
|
|
276
|
+
// ---------------------------------------------------------------------------
|
|
277
|
+
// Placeholder suppression (ingress semantics: user-typed input, near-zero
|
|
278
|
+
// false positives)
|
|
279
|
+
// ---------------------------------------------------------------------------
|
|
280
|
+
|
|
281
|
+
export const KNOWN_PLACEHOLDERS = new Set([
|
|
282
|
+
"your-api-key-here",
|
|
283
|
+
"your_api_key_here",
|
|
284
|
+
"insert-your-key-here",
|
|
285
|
+
"insert_your_key_here",
|
|
286
|
+
"replace-with-your-key",
|
|
287
|
+
"replace_with_your_key",
|
|
288
|
+
"xxx",
|
|
289
|
+
"xxxxxxxx",
|
|
290
|
+
"test",
|
|
291
|
+
"example",
|
|
292
|
+
"sample",
|
|
293
|
+
"demo",
|
|
294
|
+
"placeholder",
|
|
295
|
+
"changeme",
|
|
296
|
+
"CHANGEME",
|
|
297
|
+
"TODO",
|
|
298
|
+
"FIXME",
|
|
299
|
+
"your-token-here",
|
|
300
|
+
"your_token_here",
|
|
301
|
+
"my-api-key",
|
|
302
|
+
"my_api_key",
|
|
303
|
+
]);
|
|
304
|
+
|
|
305
|
+
export const PLACEHOLDER_PREFIXES = [
|
|
306
|
+
"sk-test-",
|
|
307
|
+
"sk_test_",
|
|
308
|
+
"fake_",
|
|
309
|
+
"fake-",
|
|
310
|
+
"dummy_",
|
|
311
|
+
"dummy-",
|
|
312
|
+
"test_",
|
|
313
|
+
"test-",
|
|
314
|
+
"example_",
|
|
315
|
+
"example-",
|
|
316
|
+
"sample_",
|
|
317
|
+
"sample-",
|
|
318
|
+
"mock_",
|
|
319
|
+
"mock-",
|
|
320
|
+
];
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* Check if the text immediately before a matched value indicates a
|
|
324
|
+
* placeholder context (e.g. "fake_", "test_"): true when the pre-context
|
|
325
|
+
* window ends with any `PLACEHOLDER_PREFIXES` entry, case-insensitive.
|
|
326
|
+
*/
|
|
327
|
+
export function isPlaceholderContext(preContext: string): boolean {
|
|
328
|
+
const lower = preContext.toLowerCase();
|
|
329
|
+
for (const prefix of PLACEHOLDER_PREFIXES) {
|
|
330
|
+
if (lower.endsWith(prefix)) {
|
|
331
|
+
return true;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
return false;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* Check if a matched value is a placeholder/test value that should not be
|
|
339
|
+
* reported: exact `KNOWN_PLACEHOLDERS` membership, a `PLACEHOLDER_PREFIXES`
|
|
340
|
+
* prefix (both case-insensitive), or a variable portion that is one repeated
|
|
341
|
+
* character (e.g. `AKIA` + `X` x 16).
|
|
342
|
+
*/
|
|
343
|
+
export function isPlaceholderValue(value: string): boolean {
|
|
344
|
+
const lower = value.toLowerCase();
|
|
345
|
+
if (KNOWN_PLACEHOLDERS.has(lower)) {
|
|
346
|
+
return true;
|
|
347
|
+
}
|
|
348
|
+
for (const prefix of PLACEHOLDER_PREFIXES) {
|
|
349
|
+
if (lower.startsWith(prefix)) {
|
|
350
|
+
return true;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// Repeated characters in the variable portion (e.g. "AKIA" + "X" x 16)
|
|
355
|
+
// Strip known prefixes to isolate the variable part
|
|
356
|
+
const variablePart = value
|
|
357
|
+
.replace(
|
|
358
|
+
/^(?: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-----)/,
|
|
359
|
+
"",
|
|
360
|
+
)
|
|
361
|
+
.replace(/[^A-Za-z0-9]/g, "");
|
|
362
|
+
if (variablePart.length >= 8) {
|
|
363
|
+
const firstChar = variablePart[0];
|
|
364
|
+
if (variablePart.split("").every((c) => c === firstChar)) {
|
|
365
|
+
return true;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
return false;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
// ---------------------------------------------------------------------------
|
|
373
|
+
// Draft scanner
|
|
374
|
+
// ---------------------------------------------------------------------------
|
|
375
|
+
|
|
376
|
+
export interface DetectedSecret {
|
|
377
|
+
/** Human-readable secret type label, e.g. "Anthropic API Key". */
|
|
378
|
+
label: string;
|
|
379
|
+
/** The matched secret text. */
|
|
380
|
+
value: string;
|
|
381
|
+
/** Start offset of the match in the scanned text (inclusive). */
|
|
382
|
+
start: number;
|
|
383
|
+
/** End offset of the match in the scanned text (exclusive). */
|
|
384
|
+
end: number;
|
|
385
|
+
/** True when the entire trimmed text is one token-shaped value. */
|
|
386
|
+
wholeMessage: boolean;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
/**
|
|
390
|
+
* Global clones of {@link PREFIX_PATTERNS}, compiled once so the draft
|
|
391
|
+
* scanner never mutates the shared pattern objects' `lastIndex` and never
|
|
392
|
+
* recompiles on the hot path (the composer scans on every draft change).
|
|
393
|
+
*/
|
|
394
|
+
const GLOBAL_PREFIX_PATTERNS: SecretPrefixPattern[] = PREFIX_PATTERNS.map(
|
|
395
|
+
({ label, regex }) => ({
|
|
396
|
+
label,
|
|
397
|
+
regex: new RegExp(
|
|
398
|
+
regex.source,
|
|
399
|
+
regex.flags.includes("g") ? regex.flags : regex.flags + "g",
|
|
400
|
+
),
|
|
401
|
+
}),
|
|
402
|
+
);
|
|
403
|
+
|
|
404
|
+
/**
|
|
405
|
+
* Scan a draft message for high-confidence secrets.
|
|
406
|
+
*
|
|
407
|
+
* Runs every `PREFIX_PATTERNS` entry over the text, suppressing placeholder
|
|
408
|
+
* values and matches immediately preceded by a placeholder context (e.g.
|
|
409
|
+
* `fake_` before a real-looking token) — the same suppression the daemon
|
|
410
|
+
* applies at ingress, so client and server accept the same placeholders.
|
|
411
|
+
* When no prefix pattern matches, the trimmed whole message is
|
|
412
|
+
* tested against {@link TOKEN_SHAPE} — the same whole-message token-shape
|
|
413
|
+
* heuristic the daemon blocks at ingress. Overlapping spans are deduped
|
|
414
|
+
* (first pattern in list order wins); results are sorted by `start`.
|
|
415
|
+
*/
|
|
416
|
+
export function detectSecretsInText(text: string): DetectedSecret[] {
|
|
417
|
+
const matches: DetectedSecret[] = [];
|
|
418
|
+
|
|
419
|
+
for (const { label, regex } of GLOBAL_PREFIX_PATTERNS) {
|
|
420
|
+
// Reset lastIndex — the compiled global regexes are shared across calls.
|
|
421
|
+
regex.lastIndex = 0;
|
|
422
|
+
let match: RegExpExecArray | null;
|
|
423
|
+
|
|
424
|
+
while ((match = regex.exec(text)) !== null) {
|
|
425
|
+
const value = match[0];
|
|
426
|
+
|
|
427
|
+
// Skip placeholders and test values (check both the match and
|
|
428
|
+
// a small window before it for placeholder prefixes like "fake_")
|
|
429
|
+
const contextStart = Math.max(0, match.index - 10);
|
|
430
|
+
const preContext = text.slice(contextStart, match.index);
|
|
431
|
+
if (isPlaceholderValue(value) || isPlaceholderContext(preContext)) {
|
|
432
|
+
continue;
|
|
433
|
+
}
|
|
434
|
+
const start = match.index;
|
|
435
|
+
const end = start + value.length;
|
|
436
|
+
// Overlap dedupe: the first pattern in list order wins.
|
|
437
|
+
if (matches.some((m) => start < m.end && end > m.start)) {
|
|
438
|
+
continue;
|
|
439
|
+
}
|
|
440
|
+
matches.push({ label, value, start, end, wholeMessage: false });
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
if (matches.length === 0) {
|
|
445
|
+
const trimmed = text.trim();
|
|
446
|
+
const shapeMatch =
|
|
447
|
+
trimmed.length >= TOKEN_SHAPE_MIN_LENGTH &&
|
|
448
|
+
trimmed.length <= TOKEN_SHAPE_MAX_LENGTH
|
|
449
|
+
? TOKEN_SHAPE.exec(trimmed)
|
|
450
|
+
: null;
|
|
451
|
+
if (
|
|
452
|
+
shapeMatch !== null &&
|
|
453
|
+
!isPlaceholderValue(trimmed) &&
|
|
454
|
+
!isPlaceholderValue(shapeMatch[1]!)
|
|
455
|
+
) {
|
|
456
|
+
const start = text.length - text.trimStart().length;
|
|
457
|
+
matches.push({
|
|
458
|
+
label: TOKEN_SHAPE_LABEL,
|
|
459
|
+
value: trimmed,
|
|
460
|
+
start,
|
|
461
|
+
end: start + trimmed.length,
|
|
462
|
+
wholeMessage: true,
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
return matches.sort((a, b) => a.start - b.start);
|
|
468
|
+
}
|
|
@@ -79,10 +79,16 @@ export function isAdmissionPolicyExemptChannel(channelType: string): boolean {
|
|
|
79
79
|
*
|
|
80
80
|
* `vellum` is the local desktop/web client surface; the guardian is always
|
|
81
81
|
* max-rank there, so the seed default admits them regardless of the floor.
|
|
82
|
+
*
|
|
83
|
+
* `discord` has no ingress implementation, so there is nothing for a floor to
|
|
84
|
+
* gate and nothing for the user to configure. Hiding keeps it pinned at the
|
|
85
|
+
* seed default rather than offering a Channel Trust Floors row for a channel
|
|
86
|
+
* that receives nothing.
|
|
82
87
|
*/
|
|
83
88
|
export const ADMISSION_POLICY_HIDDEN_CHANNELS: ReadonlySet<string> = new Set([
|
|
84
89
|
"vellum",
|
|
85
90
|
"whatsapp",
|
|
91
|
+
"discord",
|
|
86
92
|
]);
|
|
87
93
|
|
|
88
94
|
export function isAdmissionPolicyHiddenChannel(channelType: string): boolean {
|
|
@@ -75,6 +75,40 @@ export const SourceMetadataSchema = z
|
|
|
75
75
|
*/
|
|
76
76
|
actorTeamId: z.string().optional(),
|
|
77
77
|
|
|
78
|
+
/**
|
|
79
|
+
* Slack-specific: what the sender had open when they messaged the app,
|
|
80
|
+
* ordered by relevance. Slack attaches this to `message.im` once the app
|
|
81
|
+
* subscribes to `app_context_changed` (which requires `agent_view`), so a
|
|
82
|
+
* DM like "summarise this" can be resolved against the channel, thread, or
|
|
83
|
+
* canvas the sender was actually looking at.
|
|
84
|
+
*
|
|
85
|
+
* Entity values are Slack ids; the entity `type` is a Slack type URI such
|
|
86
|
+
* as `slack#/types/channel_id`. Absent when the sender had nothing open.
|
|
87
|
+
*/
|
|
88
|
+
appContext: z
|
|
89
|
+
.object({
|
|
90
|
+
entities: z.array(
|
|
91
|
+
z.object({
|
|
92
|
+
type: z.string(),
|
|
93
|
+
/**
|
|
94
|
+
* An id string for channel / canvas / list entities; an object for
|
|
95
|
+
* `slack#/types/message_context`, which points at a specific
|
|
96
|
+
* message or thread.
|
|
97
|
+
*/
|
|
98
|
+
value: z.union([
|
|
99
|
+
z.string(),
|
|
100
|
+
z.object({
|
|
101
|
+
messageTs: z.string().optional(),
|
|
102
|
+
channelId: z.string().optional(),
|
|
103
|
+
}),
|
|
104
|
+
]),
|
|
105
|
+
teamId: z.string().optional(),
|
|
106
|
+
enterpriseId: z.string().optional(),
|
|
107
|
+
}),
|
|
108
|
+
),
|
|
109
|
+
})
|
|
110
|
+
.optional(),
|
|
111
|
+
|
|
78
112
|
/**
|
|
79
113
|
* Per-channel inbound admission policy attached by the gateway. The
|
|
80
114
|
* runtime admission-policy stage enforces the floor against the
|
|
@@ -18,8 +18,16 @@ describe("isChannelId", () => {
|
|
|
18
18
|
expect(isChannelId("vellum")).toBe(true);
|
|
19
19
|
});
|
|
20
20
|
|
|
21
|
+
test("includes discord", () => {
|
|
22
|
+
// Discord is canonical vocabulary ahead of its ingress implementation:
|
|
23
|
+
// the gateway's inbound list and the admission-policy seed both derive
|
|
24
|
+
// from CHANNEL_IDS, so it must be here for a Discord message to be
|
|
25
|
+
// routable and to carry an admission floor at all.
|
|
26
|
+
expect(isChannelId("discord")).toBe(true);
|
|
27
|
+
});
|
|
28
|
+
|
|
21
29
|
test("rejects unknown strings and non-string values", () => {
|
|
22
|
-
expect(isChannelId("
|
|
30
|
+
expect(isChannelId("mastodon")).toBe(false);
|
|
23
31
|
expect(isChannelId("")).toBe(false);
|
|
24
32
|
expect(isChannelId(undefined)).toBe(false);
|
|
25
33
|
expect(isChannelId(null)).toBe(false);
|