@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,85 @@
|
|
|
1
|
+
import type { z } from "zod";
|
|
2
|
+
|
|
3
|
+
import { askQuestionInputSchema } from "./ask-question/ask-question-tool.js";
|
|
4
|
+
import { fileEditInputSchema } from "./filesystem/edit.js";
|
|
5
|
+
import { fileListInputSchema } from "./filesystem/list.js";
|
|
6
|
+
import { fileReadInputSchema } from "./filesystem/read.js";
|
|
7
|
+
import { fileWriteInputSchema } from "./filesystem/write.js";
|
|
8
|
+
import { hostFileEditInputSchema } from "./host-filesystem/edit.js";
|
|
9
|
+
import { hostFileReadInputSchema } from "./host-filesystem/read.js";
|
|
10
|
+
import { hostFileWriteInputSchema } from "./host-filesystem/write.js";
|
|
11
|
+
import { hostShellInputSchema } from "./host-terminal/host-shell.js";
|
|
12
|
+
import { formatToolInputError } from "./shared/zod-tool-schema.js";
|
|
13
|
+
import { notifyParentInputSchema } from "./subagent/notify-parent.js";
|
|
14
|
+
import { requestSystemPermissionInputSchema } from "./system/request-permission.js";
|
|
15
|
+
import { shellInputSchema } from "./terminal/shell.js";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Per-tool Zod input schemas, keyed by tool name. Tool calls are a
|
|
19
|
+
* discriminated payload — the tool name determines the shape of `input` —
|
|
20
|
+
* but the model's JSON arrives untrusted, so the pre-execution gate
|
|
21
|
+
* (`ToolApprovalHandler.checkPreExecutionGates`) parses it against this
|
|
22
|
+
* registry (via {@link parseToolInput}) before any executor reads a field —
|
|
23
|
+
* and, crucially, before any one-time grant is consumed or guardian
|
|
24
|
+
* escalation starts, so a malformed call can never interrupt the guardian.
|
|
25
|
+
* Each schema is also the source the tool derives its advertised
|
|
26
|
+
* `input_schema` from (`toToolInputSchema` in `shared/zod-tool-schema.ts`),
|
|
27
|
+
* so the model-facing contract and the runtime validation cannot drift.
|
|
28
|
+
*
|
|
29
|
+
* Covers built-in (`default`-owned) tools only — skill / plugin / MCP /
|
|
30
|
+
* workspace tools own their schemas elsewhere, and the executor skips this
|
|
31
|
+
* registry for them (a workspace override of a built-in name must not be
|
|
32
|
+
* validated against the built-in's schema).
|
|
33
|
+
*
|
|
34
|
+
* Authoring rules, so validation never tightens behavior a tool already
|
|
35
|
+
* tolerates:
|
|
36
|
+
*
|
|
37
|
+
* - Top-level schemas are `z.looseObject` — unknown keys (including the
|
|
38
|
+
* injected `activity` field, see `schema-transforms.ts`) pass through.
|
|
39
|
+
* - A field the tool silently ignores when malformed gets
|
|
40
|
+
* `.optional().catch(undefined)` so a bad value degrades exactly as the
|
|
41
|
+
* tool always degraded, instead of failing the call.
|
|
42
|
+
* - Fields the advertised schema requires only to guide the model (e.g.
|
|
43
|
+
* `activity`, which is status-only and never read by the tool) stay
|
|
44
|
+
* optional-with-`.catch(undefined)` here; the derivation marks them
|
|
45
|
+
* required via `advertiseRequired`.
|
|
46
|
+
*/
|
|
47
|
+
export const TOOL_INPUT_SCHEMAS: Readonly<Record<string, z.ZodType>> = {
|
|
48
|
+
ask_question: askQuestionInputSchema,
|
|
49
|
+
bash: shellInputSchema,
|
|
50
|
+
file_edit: fileEditInputSchema,
|
|
51
|
+
file_list: fileListInputSchema,
|
|
52
|
+
file_read: fileReadInputSchema,
|
|
53
|
+
file_write: fileWriteInputSchema,
|
|
54
|
+
host_bash: hostShellInputSchema,
|
|
55
|
+
host_file_edit: hostFileEditInputSchema,
|
|
56
|
+
host_file_read: hostFileReadInputSchema,
|
|
57
|
+
host_file_write: hostFileWriteInputSchema,
|
|
58
|
+
notify_parent: notifyParentInputSchema,
|
|
59
|
+
request_system_permission: requestSystemPermissionInputSchema,
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Validate model-supplied tool input against the registered schema for
|
|
64
|
+
* `name`, returning the parsed value (with `.catch()` recoveries applied) or
|
|
65
|
+
* a descriptive, model-correctable error message. A tool with no registered
|
|
66
|
+
* schema passes through unchanged.
|
|
67
|
+
*/
|
|
68
|
+
export function parseToolInput(
|
|
69
|
+
name: string,
|
|
70
|
+
input: Record<string, unknown>,
|
|
71
|
+
):
|
|
72
|
+
| { ok: true; data: Record<string, unknown> }
|
|
73
|
+
| { ok: false; message: string } {
|
|
74
|
+
const schema = TOOL_INPUT_SCHEMAS[name];
|
|
75
|
+
if (!schema) {
|
|
76
|
+
return { ok: true, data: input };
|
|
77
|
+
}
|
|
78
|
+
const result = schema.safeParse(input);
|
|
79
|
+
if (!result.success) {
|
|
80
|
+
return { ok: false, message: formatToolInputError(name, result.error) };
|
|
81
|
+
}
|
|
82
|
+
// Every registry schema is an object schema, so the parsed value is a
|
|
83
|
+
// plain record; `z.ZodType`'s output is just too wide to say so statically.
|
|
84
|
+
return { ok: true, data: result.data as Record<string, unknown> };
|
|
85
|
+
}
|
package/src/tools/tool-types.ts
CHANGED
|
@@ -240,6 +240,13 @@ export interface ToolContext {
|
|
|
240
240
|
* equivalent instead of emitting a surface the channel silently drops.
|
|
241
241
|
*/
|
|
242
242
|
supportsDynamicUi?: boolean;
|
|
243
|
+
/**
|
|
244
|
+
* Whether a parked `ask_question` on this turn's channel can be delivered as
|
|
245
|
+
* a guardian-request card with tappable answer options; `undefined`/`false`
|
|
246
|
+
* means no card delivery is possible. See the ToolContext field of the same
|
|
247
|
+
* name in `types.ts`.
|
|
248
|
+
*/
|
|
249
|
+
supportsGuardianQuestionCards?: boolean;
|
|
243
250
|
/** When true, tools with side effects should always prompt for confirmation. */
|
|
244
251
|
forcePromptSideEffects?: boolean;
|
|
245
252
|
/**
|
package/src/tools/types.ts
CHANGED
|
@@ -198,6 +198,14 @@ export interface ToolContext {
|
|
|
198
198
|
* supported (desktop/web/app clients).
|
|
199
199
|
*/
|
|
200
200
|
supportsDynamicUi?: boolean;
|
|
201
|
+
/**
|
|
202
|
+
* Whether a parked `ask_question` on this turn's channel can be delivered as
|
|
203
|
+
* a guardian-request card with tappable answer options (via the notification
|
|
204
|
+
* pipeline's channel adapters). `ask_question` parks when this is true even
|
|
205
|
+
* without dynamic UI; otherwise channel turns degrade to the plain-text
|
|
206
|
+
* fallback. `undefined`/`false` means no card delivery is possible.
|
|
207
|
+
*/
|
|
208
|
+
supportsGuardianQuestionCards?: boolean;
|
|
201
209
|
/**
|
|
202
210
|
* When set, the tool execution is part of a task run. Used to retrieve ephemeral permission rules.
|
|
203
211
|
* @legacy
|
|
@@ -13,19 +13,45 @@
|
|
|
13
13
|
* by the type checker.
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
+
import { z } from "zod";
|
|
17
|
+
|
|
16
18
|
import { getEffectiveProfiles } from "../../config/default-profile-catalog.js";
|
|
17
19
|
import { loadConfig } from "../../config/loader.js";
|
|
18
20
|
import { callerOwnsWorkflowRun } from "../../workflows/capabilities.js";
|
|
19
21
|
import type { WorkflowRun } from "../../workflows/journal-store.js";
|
|
20
22
|
import { getWorkflowRunManager } from "../../workflows/run-manager.js";
|
|
23
|
+
import {
|
|
24
|
+
invalidToolInputResult,
|
|
25
|
+
nullAsOmitted,
|
|
26
|
+
} from "../shared/zod-tool-schema.js";
|
|
21
27
|
import type { ToolContext, ToolExecutionResult } from "../types.js";
|
|
22
28
|
|
|
29
|
+
/**
|
|
30
|
+
* Model-input schema, `safeParse`d at the top of
|
|
31
|
+
* {@link executeManageWorkflows}. Same in-tool pattern and TOOLS.json drift
|
|
32
|
+
* guard as the other bundled-skill tools — see the schema block in
|
|
33
|
+
* `tools/document/document-tool.ts` for the framework.
|
|
34
|
+
*
|
|
35
|
+
* `action` is deliberately UNDECLARED (loose passthrough): the switch's
|
|
36
|
+
* default case owns the unknown-action error, and `executor.ts` reads
|
|
37
|
+
* `input.action` / `input.run_id` pre-execution for the requireFreshApproval
|
|
38
|
+
* promotion (those reads are already defensive and see the raw input either
|
|
39
|
+
* way).
|
|
40
|
+
*/
|
|
41
|
+
export const manageWorkflowsInputSchema = z.looseObject({
|
|
42
|
+
run_id: nullAsOmitted(z.string()),
|
|
43
|
+
});
|
|
44
|
+
|
|
23
45
|
export async function executeManageWorkflows(
|
|
24
46
|
input: Record<string, unknown>,
|
|
25
47
|
context: ToolContext,
|
|
26
48
|
): Promise<ToolExecutionResult> {
|
|
49
|
+
const parsedInput = manageWorkflowsInputSchema.safeParse(input);
|
|
50
|
+
if (!parsedInput.success) {
|
|
51
|
+
return invalidToolInputResult("manage_workflows", parsedInput.error);
|
|
52
|
+
}
|
|
27
53
|
const action = input.action as string | undefined;
|
|
28
|
-
const runId =
|
|
54
|
+
const runId = parsedInput.data.run_id;
|
|
29
55
|
const manager = getWorkflowRunManager();
|
|
30
56
|
|
|
31
57
|
// Authorization scope ({@link callerOwnsWorkflowRun}, shared with the
|
|
@@ -104,7 +130,9 @@ export async function executeManageWorkflows(
|
|
|
104
130
|
// Only signal a run the caller owns. A non-owned (or absent) run is a
|
|
105
131
|
// no-op with the same response shape, so existence is never revealed.
|
|
106
132
|
const run = manager.status(runId);
|
|
107
|
-
if (run && ownsRun(run))
|
|
133
|
+
if (run && ownsRun(run)) {
|
|
134
|
+
manager.abort(runId);
|
|
135
|
+
}
|
|
108
136
|
return {
|
|
109
137
|
content: JSON.stringify({
|
|
110
138
|
runId,
|
|
@@ -27,7 +27,9 @@ mock.module("../../daemon/conversation-registry.js", () => ({
|
|
|
27
27
|
let lastStartArgs: Record<string, unknown> | null = null;
|
|
28
28
|
let startThrows: Error | null = null;
|
|
29
29
|
const startMock = mock((opts: Record<string, unknown>) => {
|
|
30
|
-
if (startThrows)
|
|
30
|
+
if (startThrows) {
|
|
31
|
+
throw startThrows;
|
|
32
|
+
}
|
|
31
33
|
lastStartArgs = opts;
|
|
32
34
|
return { runId: "run-123" };
|
|
33
35
|
});
|
|
@@ -36,7 +38,9 @@ const abortMock = mock(() => {});
|
|
|
36
38
|
const listMock = mock(() => [] as unknown[]);
|
|
37
39
|
let resumeThrows: Error | null = null;
|
|
38
40
|
const resumeMock = mock((runId: string) => {
|
|
39
|
-
if (resumeThrows)
|
|
41
|
+
if (resumeThrows) {
|
|
42
|
+
throw resumeThrows;
|
|
43
|
+
}
|
|
40
44
|
return { runId };
|
|
41
45
|
});
|
|
42
46
|
|
|
@@ -421,3 +425,51 @@ describe("manage_workflows", () => {
|
|
|
421
425
|
expect(abortMock).toHaveBeenCalledWith("mine");
|
|
422
426
|
});
|
|
423
427
|
});
|
|
428
|
+
|
|
429
|
+
// ── model-input schema validation (LUM-2855) ────────────────────────
|
|
430
|
+
|
|
431
|
+
describe("workflow tools — model-input schema validation", () => {
|
|
432
|
+
test("run_workflow rejects a non-string script", async () => {
|
|
433
|
+
const result = await executeRunWorkflow({ script: 42 }, makeContext());
|
|
434
|
+
expect(result.isError).toBe(true);
|
|
435
|
+
expect(result.content).toContain('Invalid input for tool "run_workflow"');
|
|
436
|
+
expect(result.content).toContain("script");
|
|
437
|
+
expect(startMock).not.toHaveBeenCalled();
|
|
438
|
+
});
|
|
439
|
+
|
|
440
|
+
test("run_workflow treats explicit null script/name as omitted (bespoke exactly-one error)", async () => {
|
|
441
|
+
const result = await executeRunWorkflow(
|
|
442
|
+
{ script: null, name: null },
|
|
443
|
+
makeContext(),
|
|
444
|
+
);
|
|
445
|
+
expect(result.isError).toBe(true);
|
|
446
|
+
expect(result.content).toContain("exactly one");
|
|
447
|
+
});
|
|
448
|
+
|
|
449
|
+
test("run_workflow passes args through unvalidated (workflow runtime accepts any JSON)", async () => {
|
|
450
|
+
const result = await executeRunWorkflow(
|
|
451
|
+
{ script: "export const meta = {}", args: ["positional"] },
|
|
452
|
+
makeContext(),
|
|
453
|
+
);
|
|
454
|
+
expect(result.isError).toBe(false);
|
|
455
|
+
expect(lastStartArgs?.args).toEqual(["positional"]);
|
|
456
|
+
});
|
|
457
|
+
|
|
458
|
+
test("manage_workflows rejects a non-string run_id", async () => {
|
|
459
|
+
const result = await executeManageWorkflows(
|
|
460
|
+
{ action: "status", run_id: 42 },
|
|
461
|
+
makeContext(),
|
|
462
|
+
);
|
|
463
|
+
expect(result.isError).toBe(true);
|
|
464
|
+
expect(result.content).toContain(
|
|
465
|
+
'Invalid input for tool "manage_workflows"',
|
|
466
|
+
);
|
|
467
|
+
expect(result.content).toContain("run_id");
|
|
468
|
+
});
|
|
469
|
+
|
|
470
|
+
test("manage_workflows keeps the bespoke unknown-action error", async () => {
|
|
471
|
+
const result = await executeManageWorkflows({ action: 42 }, makeContext());
|
|
472
|
+
expect(result.isError).toBe(true);
|
|
473
|
+
expect(result.content).toContain("Unknown action");
|
|
474
|
+
});
|
|
475
|
+
});
|
|
@@ -15,13 +15,37 @@
|
|
|
15
15
|
* of truth the model reads when generating the `script`.
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
+
import { z } from "zod";
|
|
19
|
+
|
|
18
20
|
import { findConversation } from "../../daemon/conversation-registry.js";
|
|
19
21
|
import { FALLBACK_TURN_TRUST } from "../../daemon/trust-context.js";
|
|
20
22
|
import type { TrustContext } from "../../daemon/trust-context-types.js";
|
|
21
23
|
import { CapabilityManifestSchema } from "../../workflows/capabilities.js";
|
|
22
24
|
import { getWorkflowRunManager } from "../../workflows/run-manager.js";
|
|
25
|
+
import {
|
|
26
|
+
invalidToolInputResult,
|
|
27
|
+
nullAsOmitted,
|
|
28
|
+
} from "../shared/zod-tool-schema.js";
|
|
23
29
|
import type { ToolContext, ToolExecutionResult } from "../types.js";
|
|
24
30
|
|
|
31
|
+
/**
|
|
32
|
+
* Model-input schema, `safeParse`d at the top of {@link executeRunWorkflow}.
|
|
33
|
+
* Same in-tool pattern and TOOLS.json drift guard as the other bundled-skill
|
|
34
|
+
* tools — see the schema block in `tools/document/document-tool.ts` for the
|
|
35
|
+
* framework.
|
|
36
|
+
*
|
|
37
|
+
* `args` (the workflow runtime accepts any JSON value) and `capabilities`
|
|
38
|
+
* (`CapabilityManifestSchema` is the single validation authority, and
|
|
39
|
+
* `executor.ts` reads it pre-execution for the requireFreshApproval
|
|
40
|
+
* promotion) are deliberately UNDECLARED — loose passthrough. The
|
|
41
|
+
* exactly-one-of script/name rule stays a bespoke check below.
|
|
42
|
+
*/
|
|
43
|
+
export const runWorkflowInputSchema = z.looseObject({
|
|
44
|
+
script: nullAsOmitted(z.string()),
|
|
45
|
+
name: nullAsOmitted(z.string()),
|
|
46
|
+
label: nullAsOmitted(z.string()),
|
|
47
|
+
});
|
|
48
|
+
|
|
25
49
|
/**
|
|
26
50
|
* Resolve the {@link TrustContext} to forward to the run's leaves. Prefer the
|
|
27
51
|
* originating conversation's per-turn snapshot (the same context the live turn
|
|
@@ -33,7 +57,9 @@ function resolveTrustContext(context: ToolContext): TrustContext {
|
|
|
33
57
|
const conversation = findConversation(context.conversationId);
|
|
34
58
|
const fromConversation =
|
|
35
59
|
conversation?.currentTurnTrustContext ?? conversation?.trustContext;
|
|
36
|
-
if (fromConversation)
|
|
60
|
+
if (fromConversation) {
|
|
61
|
+
return fromConversation;
|
|
62
|
+
}
|
|
37
63
|
return { ...FALLBACK_TURN_TRUST, trustClass: context.trustClass };
|
|
38
64
|
}
|
|
39
65
|
|
|
@@ -41,8 +67,11 @@ export async function executeRunWorkflow(
|
|
|
41
67
|
input: Record<string, unknown>,
|
|
42
68
|
context: ToolContext,
|
|
43
69
|
): Promise<ToolExecutionResult> {
|
|
44
|
-
const
|
|
45
|
-
|
|
70
|
+
const parsedInput = runWorkflowInputSchema.safeParse(input);
|
|
71
|
+
if (!parsedInput.success) {
|
|
72
|
+
return invalidToolInputResult("run_workflow", parsedInput.error);
|
|
73
|
+
}
|
|
74
|
+
const { script, name, label } = parsedInput.data;
|
|
46
75
|
|
|
47
76
|
// Exactly one of script/name is required.
|
|
48
77
|
if ((script == null) === (name == null)) {
|
|
@@ -54,7 +83,6 @@ export async function executeRunWorkflow(
|
|
|
54
83
|
}
|
|
55
84
|
|
|
56
85
|
const args = (input.args as Record<string, unknown> | undefined) ?? {};
|
|
57
|
-
const label = input.label as string | undefined;
|
|
58
86
|
const trustContext = resolveTrustContext(context);
|
|
59
87
|
|
|
60
88
|
try {
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { lstatSync, readlinkSync } from "node:fs";
|
|
2
|
+
import { dirname, resolve } from "node:path";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Follow a trailing symlink chain manually so a DANGLING link reports its
|
|
6
|
+
* destination. `realpathSync` throws on a link whose destination does not
|
|
7
|
+
* exist, which makes canonicalization fall back to the benign link path —
|
|
8
|
+
* but a write through the link creates the destination, so containment and
|
|
9
|
+
* security checks must see it. The bound sits above every supported
|
|
10
|
+
* platform's own traversal limit (Linux follows at most 40 links per
|
|
11
|
+
* resolution, macOS 32), so any chain this loop cannot exhaust is one the
|
|
12
|
+
* filesystem itself refuses to follow (ELOOP) — the eventual operation
|
|
13
|
+
* fails rather than writing through an unchecked destination.
|
|
14
|
+
*/
|
|
15
|
+
export function resolveTrailingLinkTarget(path: string): string {
|
|
16
|
+
let current = path;
|
|
17
|
+
for (let depth = 0; depth < 64; depth++) {
|
|
18
|
+
let linkTarget: string;
|
|
19
|
+
try {
|
|
20
|
+
if (!lstatSync(current).isSymbolicLink()) {
|
|
21
|
+
return current;
|
|
22
|
+
}
|
|
23
|
+
linkTarget = readlinkSync(current);
|
|
24
|
+
} catch {
|
|
25
|
+
return current;
|
|
26
|
+
}
|
|
27
|
+
current = resolve(dirname(current), linkTarget);
|
|
28
|
+
}
|
|
29
|
+
return current;
|
|
30
|
+
}
|
package/src/util/log-redact.ts
CHANGED
|
@@ -11,15 +11,19 @@
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import { memoizePluginPatternDerivation } from "../security/plugin-secret-patterns.js";
|
|
14
|
-
import {
|
|
14
|
+
import { REDACTION_PREFIX_PATTERNS } from "../security/secret-patterns.js";
|
|
15
15
|
|
|
16
16
|
// ---------------------------------------------------------------------------
|
|
17
|
-
// Sensitive-value patterns (derived from shared
|
|
17
|
+
// Sensitive-value patterns (derived from shared REDACTION_PREFIX_PATTERNS)
|
|
18
18
|
// ---------------------------------------------------------------------------
|
|
19
19
|
|
|
20
20
|
const BEARER_RE = /Bearer [A-Za-z0-9._\-]+/g;
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
// This serializer redacts by replacing the matched span in place, so it uses
|
|
23
|
+
// the bounded whole-block private-key matcher (via REDACTION_PREFIX_PATTERNS):
|
|
24
|
+
// the match must cover header → body → footer or the key body would survive
|
|
25
|
+
// redaction. The body bound keeps it O(n) on large serialized strings.
|
|
26
|
+
const STATIC_API_KEY_PATTERNS: RegExp[] = REDACTION_PREFIX_PATTERNS.map(
|
|
23
27
|
(p) => new RegExp(p.regex.source, "g"),
|
|
24
28
|
);
|
|
25
29
|
|
package/src/util/platform.ts
CHANGED
|
@@ -434,6 +434,21 @@ export function getWorkspacePromptPath(file: string): string {
|
|
|
434
434
|
return join(getWorkspaceDir(), file);
|
|
435
435
|
}
|
|
436
436
|
|
|
437
|
+
/**
|
|
438
|
+
* Returns `<workspaceDir>/prompts/system` — the workspace override layer for
|
|
439
|
+
* system prompt sections. Layout: `prompts/system/<NN-name>.md`.
|
|
440
|
+
*
|
|
441
|
+
* The bundled section registry (`prompts/templates/system-sections.ts`) is
|
|
442
|
+
* the source of default truth; a file here with the same id replaces the
|
|
443
|
+
* bundled body (or, stripped to nothing, silences it), and a brand-new
|
|
444
|
+
* `<NN-name>` adds a workspace-only section. Because that includes the
|
|
445
|
+
* security-policy sections, writes under this directory are gated as a
|
|
446
|
+
* control-plane prompt surface (`permissions/workspace-policy.ts`).
|
|
447
|
+
*/
|
|
448
|
+
export function getWorkspaceSystemPromptDir(): string {
|
|
449
|
+
return join(getWorkspaceDir(), "prompts", "system");
|
|
450
|
+
}
|
|
451
|
+
|
|
437
452
|
// ── Profiler filesystem layout ──────────────────────────────────────────
|
|
438
453
|
// Managed profiler runs live under <workspace>/data/profiler/. These
|
|
439
454
|
// helpers enforce a single canonical layout so every runtime caller
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The single shape of `globalThis.vellumAssistant` — the per-process namespace
|
|
3
|
+
* that holds the assistant's process-global singletons.
|
|
4
|
+
*
|
|
5
|
+
* Several modules keep process-global state on `globalThis.vellumAssistant.*`
|
|
6
|
+
* (see the slots below). Each such slot is read/written by a production module
|
|
7
|
+
* AND, independently, by a test helper in `src/__tests__/` that must NOT import
|
|
8
|
+
* that production module (importing it would run its load-time side effects
|
|
9
|
+
* before the test preload establishes the per-process workspace override — the
|
|
10
|
+
* coupling behind the May 2026 DB-ghost incidents). This file is how both sides
|
|
11
|
+
* agree on the shape without a runtime import between them.
|
|
12
|
+
*
|
|
13
|
+
* It is an **ambient** declaration (no top-level `import`/`export`), so
|
|
14
|
+
* `VellumAssistantNamespace`, the slot types, and the `vellumAssistant` binding
|
|
15
|
+
* are global — every module and test helper refers to them by name with zero
|
|
16
|
+
* imports, and nothing here reaches into a `src/` module even at the type
|
|
17
|
+
* level. Referring to these types therefore never adds anything to any file's
|
|
18
|
+
* runtime import graph, so the test-machinery isolation invariant holds.
|
|
19
|
+
*
|
|
20
|
+
* Adding a slot: declare its value type here, add the optional property to
|
|
21
|
+
* `VellumAssistantNamespace`, and have the owning module + its test helper
|
|
22
|
+
* reference these globals instead of declaring their own copies.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/** Slot value: the encrypted credential store path override. Managed by `security/store-path-override.ts`. */
|
|
26
|
+
interface VellumStorePathOverride {
|
|
27
|
+
storePath: string | null;
|
|
28
|
+
storeKeyPath: string | null;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** Which assistant DB connection a singleton slot holds. */
|
|
32
|
+
type VellumDbSlotKey =
|
|
33
|
+
| "main"
|
|
34
|
+
| "main-readonly"
|
|
35
|
+
| "logs"
|
|
36
|
+
| "memory"
|
|
37
|
+
| "telemetry";
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Slot value: one lazily-opened DB connection and the closer that drops it.
|
|
41
|
+
* `db` is `unknown` so this shape never has to name a Drizzle type; callers in
|
|
42
|
+
* `persistence/db-connection.ts` narrow it via `getStoredDb<T>()`.
|
|
43
|
+
*/
|
|
44
|
+
interface VellumDbSlot {
|
|
45
|
+
db: unknown;
|
|
46
|
+
closer: (() => void) | null;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** Slot value: the assistant DB connection singletons, keyed by connection. Managed by `persistence/db-singleton.ts`. */
|
|
50
|
+
type VellumDbSlots = Record<VellumDbSlotKey, VellumDbSlot>;
|
|
51
|
+
|
|
52
|
+
/** Slot value: the resolved feature-flag override cache. Managed by `config/feature-flag-cache.ts`. */
|
|
53
|
+
interface VellumFeatureFlagCache {
|
|
54
|
+
overrides: Record<string, boolean | string> | null;
|
|
55
|
+
fromGateway: boolean;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** The per-process `globalThis.vellumAssistant` namespace. */
|
|
59
|
+
interface VellumAssistantNamespace {
|
|
60
|
+
/**
|
|
61
|
+
* Whether this OS process is the main assistant daemon. Set once by the
|
|
62
|
+
* daemon entrypoint; absent elsewhere. See `runtime/process-role.ts`.
|
|
63
|
+
*/
|
|
64
|
+
mainDaemonProcess?: boolean;
|
|
65
|
+
/** See `security/store-path-override.ts`. */
|
|
66
|
+
storePathOverride?: VellumStorePathOverride;
|
|
67
|
+
/** See `persistence/db-singleton.ts`. */
|
|
68
|
+
dbSingletons?: VellumDbSlots;
|
|
69
|
+
/** See `config/feature-flag-cache.ts`. */
|
|
70
|
+
featureFlagCache?: VellumFeatureFlagCache;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Types `globalThis.vellumAssistant`. Undefined until the first slot accessor
|
|
75
|
+
* seeds it (`globalThis.vellumAssistant ??= {}`). Must be `var`: only `var`
|
|
76
|
+
* declarations at global scope become typed properties of `globalThis`
|
|
77
|
+
* (`let`/`const` do not), so this is the one idiomatic way to type the binding.
|
|
78
|
+
*/
|
|
79
|
+
// eslint-disable-next-line no-var
|
|
80
|
+
declare var vellumAssistant: VellumAssistantNamespace | undefined;
|
|
@@ -2,6 +2,7 @@ import { and, asc, desc, eq, gte, lte } from "drizzle-orm";
|
|
|
2
2
|
import { v4 as uuid } from "uuid";
|
|
3
3
|
|
|
4
4
|
import { getDb } from "../persistence/db-connection.js";
|
|
5
|
+
import { isLifecycleQuiesced } from "../persistence/lifecycle-quiesce.js";
|
|
5
6
|
import { rawChanges } from "../persistence/raw-query.js";
|
|
6
7
|
import { watcherEvents, watchers } from "../persistence/schema/index.js";
|
|
7
8
|
import { truncate } from "../util/truncate.js";
|
|
@@ -158,6 +159,13 @@ export function deleteWatcher(id: string): boolean {
|
|
|
158
159
|
* to 'polling' using optimistic locking on the current nextPollAt.
|
|
159
160
|
*/
|
|
160
161
|
export function claimDueWatchers(now: number): Watcher[] {
|
|
162
|
+
// Drain gate: while a quiesce lease is active, claim nothing — a watcher
|
|
163
|
+
// poll runs provider requests that create no row the drain snapshot can
|
|
164
|
+
// see, so it must not start at all. Fail-open via the lease read.
|
|
165
|
+
if (isLifecycleQuiesced()) {
|
|
166
|
+
return [];
|
|
167
|
+
}
|
|
168
|
+
|
|
161
169
|
const db = getDb();
|
|
162
170
|
const candidates = db
|
|
163
171
|
.select()
|
|
@@ -472,6 +472,105 @@ describe("runLeaf — tool path", () => {
|
|
|
472
472
|
expect(countConversations()).toBe(before);
|
|
473
473
|
});
|
|
474
474
|
|
|
475
|
+
test("rejects out-of-workspace paths for sandbox file tools", async () => {
|
|
476
|
+
// Leaf tool calls bypass the ToolExecutor permission lane, so the file
|
|
477
|
+
// tools' out-of-workspace host fallback must be unreachable from a leaf.
|
|
478
|
+
const calls: Array<Record<string, unknown>> = [];
|
|
479
|
+
const fileRead: Tool = {
|
|
480
|
+
name: "file_read",
|
|
481
|
+
description: "Tool file_read",
|
|
482
|
+
category: "filesystem",
|
|
483
|
+
defaultRiskLevel: "low" as never,
|
|
484
|
+
executionTarget: "sandbox",
|
|
485
|
+
input_schema: { type: "object", properties: {}, required: [] },
|
|
486
|
+
async execute(
|
|
487
|
+
input: Record<string, unknown>,
|
|
488
|
+
): Promise<ToolExecutionResult> {
|
|
489
|
+
calls.push(input);
|
|
490
|
+
return { content: "read ok", isError: false };
|
|
491
|
+
},
|
|
492
|
+
};
|
|
493
|
+
|
|
494
|
+
responseQueue = [
|
|
495
|
+
{
|
|
496
|
+
content: [
|
|
497
|
+
{
|
|
498
|
+
type: "tool_use",
|
|
499
|
+
name: "file_read",
|
|
500
|
+
id: "tu-1",
|
|
501
|
+
input: { path: "/etc/hosts" },
|
|
502
|
+
},
|
|
503
|
+
],
|
|
504
|
+
model: "test",
|
|
505
|
+
usage: { inputTokens: 5, outputTokens: 2 },
|
|
506
|
+
stopReason: "tool_use",
|
|
507
|
+
},
|
|
508
|
+
{
|
|
509
|
+
content: [{ type: "text", text: "done" }],
|
|
510
|
+
model: "test",
|
|
511
|
+
usage: { inputTokens: 2, outputTokens: 1 },
|
|
512
|
+
stopReason: "end_turn",
|
|
513
|
+
},
|
|
514
|
+
];
|
|
515
|
+
|
|
516
|
+
const result = await runLeaf({
|
|
517
|
+
prompt: "read the file",
|
|
518
|
+
tools: [fileRead],
|
|
519
|
+
trustContext,
|
|
520
|
+
});
|
|
521
|
+
expect(result.output).toBe("done");
|
|
522
|
+
// The workspace-bound guard fired before execute — the tool never ran.
|
|
523
|
+
expect(calls).toEqual([]);
|
|
524
|
+
});
|
|
525
|
+
|
|
526
|
+
test("in-workspace file tool paths still execute from a leaf", async () => {
|
|
527
|
+
const calls: Array<Record<string, unknown>> = [];
|
|
528
|
+
const fileRead: Tool = {
|
|
529
|
+
name: "file_read",
|
|
530
|
+
description: "Tool file_read",
|
|
531
|
+
category: "filesystem",
|
|
532
|
+
defaultRiskLevel: "low" as never,
|
|
533
|
+
executionTarget: "sandbox",
|
|
534
|
+
input_schema: { type: "object", properties: {}, required: [] },
|
|
535
|
+
async execute(
|
|
536
|
+
input: Record<string, unknown>,
|
|
537
|
+
): Promise<ToolExecutionResult> {
|
|
538
|
+
calls.push(input);
|
|
539
|
+
return { content: "read ok", isError: false };
|
|
540
|
+
},
|
|
541
|
+
};
|
|
542
|
+
|
|
543
|
+
responseQueue = [
|
|
544
|
+
{
|
|
545
|
+
content: [
|
|
546
|
+
{
|
|
547
|
+
type: "tool_use",
|
|
548
|
+
name: "file_read",
|
|
549
|
+
id: "tu-1",
|
|
550
|
+
input: { path: "notes.txt" },
|
|
551
|
+
},
|
|
552
|
+
],
|
|
553
|
+
model: "test",
|
|
554
|
+
usage: { inputTokens: 5, outputTokens: 2 },
|
|
555
|
+
stopReason: "tool_use",
|
|
556
|
+
},
|
|
557
|
+
{
|
|
558
|
+
content: [{ type: "text", text: "done" }],
|
|
559
|
+
model: "test",
|
|
560
|
+
usage: { inputTokens: 2, outputTokens: 1 },
|
|
561
|
+
stopReason: "end_turn",
|
|
562
|
+
},
|
|
563
|
+
];
|
|
564
|
+
|
|
565
|
+
const result = await runLeaf({
|
|
566
|
+
prompt: "read the file",
|
|
567
|
+
tools: [fileRead],
|
|
568
|
+
trustContext,
|
|
569
|
+
});
|
|
570
|
+
expect(result.output).toBe("done");
|
|
571
|
+
expect(calls).toEqual([{ path: "notes.txt" }]);
|
|
572
|
+
});
|
|
573
|
+
|
|
475
574
|
test("a leaf with no schema and an empty tool set runs the tool path (no throw)", async () => {
|
|
476
575
|
// An empty resolved tool set with no schema must NOT fall through to the
|
|
477
576
|
// schema path (where schemaToInputSchema(undefined) throws) — it runs the
|
|
@@ -702,8 +801,11 @@ describe("runLeaf — persona path", () => {
|
|
|
702
801
|
}>;
|
|
703
802
|
expect(messages[0]?.content[0]?.text).not.toBe(MEMORY_BLOCK_TEXT);
|
|
704
803
|
} finally {
|
|
705
|
-
if (savedAuth === undefined)
|
|
706
|
-
|
|
804
|
+
if (savedAuth === undefined) {
|
|
805
|
+
delete process.env.DISABLE_HTTP_AUTH;
|
|
806
|
+
} else {
|
|
807
|
+
process.env.DISABLE_HTTP_AUTH = savedAuth;
|
|
808
|
+
}
|
|
707
809
|
}
|
|
708
810
|
});
|
|
709
811
|
});
|