@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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { beforeEach, describe, expect, test } from "bun:test";
|
|
2
2
|
|
|
3
|
-
import type {
|
|
3
|
+
import type { AssistantEventEnvelope } from "../api/index.js";
|
|
4
4
|
import {
|
|
5
5
|
AssistantEventHub,
|
|
6
6
|
broadcastMessage,
|
|
@@ -12,7 +12,9 @@ import {
|
|
|
12
12
|
} from "../runtime/assistant-stream-state.js";
|
|
13
13
|
import * as pendingInteractions from "../runtime/pending-interactions.js";
|
|
14
14
|
|
|
15
|
-
function makeEvent(
|
|
15
|
+
function makeEvent(
|
|
16
|
+
overrides: Partial<AssistantEventEnvelope> = {},
|
|
17
|
+
): AssistantEventEnvelope {
|
|
16
18
|
return {
|
|
17
19
|
id: "evt_test",
|
|
18
20
|
conversationId: "sess_1",
|
|
@@ -31,7 +33,7 @@ function makeEvent(overrides: Partial<AssistantEvent> = {}): AssistantEvent {
|
|
|
31
33
|
describe("AssistantEventHub — fanout", () => {
|
|
32
34
|
test("delivers event to a single matching subscriber", async () => {
|
|
33
35
|
const hub = new AssistantEventHub();
|
|
34
|
-
const received:
|
|
36
|
+
const received: AssistantEventEnvelope[] = [];
|
|
35
37
|
|
|
36
38
|
hub.subscribe({
|
|
37
39
|
type: "process",
|
|
@@ -75,8 +77,8 @@ describe("AssistantEventHub — fanout", () => {
|
|
|
75
77
|
|
|
76
78
|
test("conversationId filter further restricts delivery", async () => {
|
|
77
79
|
const hub = new AssistantEventHub();
|
|
78
|
-
const receivedA:
|
|
79
|
-
const receivedB:
|
|
80
|
+
const receivedA: AssistantEventEnvelope[] = [];
|
|
81
|
+
const receivedB: AssistantEventEnvelope[] = [];
|
|
80
82
|
|
|
81
83
|
hub.subscribe({
|
|
82
84
|
type: "process",
|
|
@@ -101,7 +103,7 @@ describe("AssistantEventHub — fanout", () => {
|
|
|
101
103
|
|
|
102
104
|
test("subscriber without conversationId filter receives all conversations", async () => {
|
|
103
105
|
const hub = new AssistantEventHub();
|
|
104
|
-
const received:
|
|
106
|
+
const received: AssistantEventEnvelope[] = [];
|
|
105
107
|
|
|
106
108
|
hub.subscribe({
|
|
107
109
|
type: "process",
|
|
@@ -159,7 +161,7 @@ describe("AssistantEventHub — fanout", () => {
|
|
|
159
161
|
describe("AssistantEventHub — unsubscribe cleanup", () => {
|
|
160
162
|
test("dispose stops event delivery", async () => {
|
|
161
163
|
const hub = new AssistantEventHub();
|
|
162
|
-
const received:
|
|
164
|
+
const received: AssistantEventEnvelope[] = [];
|
|
163
165
|
|
|
164
166
|
const s = hub.subscribe({
|
|
165
167
|
type: "process",
|
|
@@ -234,8 +236,8 @@ describe("AssistantEventHub — unsubscribe cleanup", () => {
|
|
|
234
236
|
|
|
235
237
|
test("disposing one subscription does not affect others", async () => {
|
|
236
238
|
const hub = new AssistantEventHub();
|
|
237
|
-
const received1:
|
|
238
|
-
const received2:
|
|
239
|
+
const received1: AssistantEventEnvelope[] = [];
|
|
240
|
+
const received2: AssistantEventEnvelope[] = [];
|
|
239
241
|
|
|
240
242
|
const s1 = hub.subscribe({
|
|
241
243
|
type: "process",
|
|
@@ -341,7 +343,7 @@ describe("AssistantEventHub — exception isolation", () => {
|
|
|
341
343
|
describe("AssistantEventHub — re-entrancy / snapshot isolation", () => {
|
|
342
344
|
test("subscriber added during publish does not receive the in-flight event", async () => {
|
|
343
345
|
const hub = new AssistantEventHub();
|
|
344
|
-
const lateReceived:
|
|
346
|
+
const lateReceived: AssistantEventEnvelope[] = [];
|
|
345
347
|
|
|
346
348
|
hub.subscribe({
|
|
347
349
|
type: "process",
|
|
@@ -363,7 +365,7 @@ describe("AssistantEventHub — re-entrancy / snapshot isolation", () => {
|
|
|
363
365
|
|
|
364
366
|
test("subscriber that disposes itself mid-publish does not affect remaining subscribers", async () => {
|
|
365
367
|
const hub = new AssistantEventHub();
|
|
366
|
-
const received:
|
|
368
|
+
const received: AssistantEventEnvelope[] = [];
|
|
367
369
|
let s: ReturnType<typeof hub.subscribe>;
|
|
368
370
|
|
|
369
371
|
// eslint-disable-next-line prefer-const
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, expect, test } from "bun:test";
|
|
2
2
|
|
|
3
|
-
import type {
|
|
3
|
+
import type { AssistantEventEnvelope } from "../api/index.js";
|
|
4
4
|
import {
|
|
5
5
|
formatSseFrame,
|
|
6
6
|
formatSseHeartbeat,
|
|
@@ -8,9 +8,9 @@ import {
|
|
|
8
8
|
|
|
9
9
|
// ── Type / shape tests ────────────────────────────────────────────────────────
|
|
10
10
|
|
|
11
|
-
describe("
|
|
11
|
+
describe("AssistantEventEnvelope shape", () => {
|
|
12
12
|
test("accepts a minimal valid event", () => {
|
|
13
|
-
const event:
|
|
13
|
+
const event: AssistantEventEnvelope = {
|
|
14
14
|
id: "evt_001",
|
|
15
15
|
emittedAt: "2026-02-18T21:20:00.000Z",
|
|
16
16
|
message: {
|
|
@@ -27,7 +27,7 @@ describe("AssistantEvent shape", () => {
|
|
|
27
27
|
});
|
|
28
28
|
|
|
29
29
|
test("accepts a full event with conversationId", () => {
|
|
30
|
-
const event:
|
|
30
|
+
const event: AssistantEventEnvelope = {
|
|
31
31
|
id: "evt_002",
|
|
32
32
|
conversationId: "conv_456",
|
|
33
33
|
emittedAt: "2026-02-18T21:20:00.000Z",
|
|
@@ -45,7 +45,7 @@ describe("AssistantEvent shape", () => {
|
|
|
45
45
|
// ── SSE framing tests ─────────────────────────────────────────────────────────
|
|
46
46
|
|
|
47
47
|
describe("formatSseFrame", () => {
|
|
48
|
-
const baseEvent:
|
|
48
|
+
const baseEvent: AssistantEventEnvelope = {
|
|
49
49
|
id: "evt_003",
|
|
50
50
|
conversationId: "sess_xyz",
|
|
51
51
|
emittedAt: "2026-02-18T00:00:00.000Z",
|
|
@@ -73,7 +73,7 @@ describe("formatSseFrame", () => {
|
|
|
73
73
|
const dataLine = frame.split("\n").find((l) => l.startsWith("data: "))!;
|
|
74
74
|
const parsed = JSON.parse(
|
|
75
75
|
dataLine.slice("data: ".length),
|
|
76
|
-
) as
|
|
76
|
+
) as AssistantEventEnvelope;
|
|
77
77
|
|
|
78
78
|
expect(parsed.id).toBe(baseEvent.id);
|
|
79
79
|
expect(parsed.conversationId).toBe(baseEvent.conversationId);
|
|
@@ -82,13 +82,16 @@ describe("formatSseFrame", () => {
|
|
|
82
82
|
});
|
|
83
83
|
|
|
84
84
|
test("id line uses the event id verbatim", () => {
|
|
85
|
-
const event:
|
|
85
|
+
const event: AssistantEventEnvelope = {
|
|
86
|
+
...baseEvent,
|
|
87
|
+
id: "unique-evt-id-xyz",
|
|
88
|
+
};
|
|
86
89
|
const frame = formatSseFrame(event);
|
|
87
90
|
expect(frame).toContain("id: unique-evt-id-xyz\n");
|
|
88
91
|
});
|
|
89
92
|
|
|
90
93
|
test("strips newline characters from event.id to prevent SSE frame injection", () => {
|
|
91
|
-
const event:
|
|
94
|
+
const event: AssistantEventEnvelope = {
|
|
92
95
|
...baseEvent,
|
|
93
96
|
id: 'foo\ndata: {"injected":true}',
|
|
94
97
|
};
|
|
@@ -113,7 +116,7 @@ describe("formatSseFrame", () => {
|
|
|
113
116
|
});
|
|
114
117
|
|
|
115
118
|
test("seq lands in the JSON payload (envelope) when set, never in SSE id", () => {
|
|
116
|
-
const event:
|
|
119
|
+
const event: AssistantEventEnvelope = {
|
|
117
120
|
...baseEvent,
|
|
118
121
|
id: "uuid-event-id",
|
|
119
122
|
seq: 42,
|
|
@@ -7,7 +7,7 @@ import { describe, expect, test } from "bun:test";
|
|
|
7
7
|
* Guard tests for assistant feature flags.
|
|
8
8
|
*
|
|
9
9
|
* 1. Key format validation: ensure production code uses the canonical
|
|
10
|
-
* simple kebab-case format (e.g., "browser", "
|
|
10
|
+
* simple kebab-case format (e.g., "browser", "contacts"), not the
|
|
11
11
|
* legacy `skills.<id>.enabled` format.
|
|
12
12
|
*
|
|
13
13
|
* 2. Declaration coverage: ensure all assistant-scope flag keys in the
|
|
@@ -123,7 +123,7 @@ describe("assistant feature flag guard", () => {
|
|
|
123
123
|
if (violations.length > 0) {
|
|
124
124
|
const message = [
|
|
125
125
|
"Found production files using the legacy `skills.<id>.enabled` key format.",
|
|
126
|
-
'New code must use the canonical simple kebab-case format (e.g., "browser", "
|
|
126
|
+
'New code must use the canonical simple kebab-case format (e.g., "browser", "contacts").',
|
|
127
127
|
'See AGENTS.md "Assistant Feature Flags" for the convention.',
|
|
128
128
|
"",
|
|
129
129
|
"Violations:",
|
|
@@ -153,7 +153,7 @@ describe("assistant feature flag guard", () => {
|
|
|
153
153
|
if (violations.length > 0) {
|
|
154
154
|
const message = [
|
|
155
155
|
"Found assistant-scope keys in the unified registry that do not match the canonical format.",
|
|
156
|
-
'Expected format: simple kebab-case (e.g., "browser", "
|
|
156
|
+
'Expected format: simple kebab-case (e.g., "browser", "contacts")',
|
|
157
157
|
"",
|
|
158
158
|
"Violations:",
|
|
159
159
|
...violations.map((k) => ` - ${k}`),
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Guard tests for assistant feature flag conventions:
|
|
3
3
|
*
|
|
4
4
|
* 1. Key format: all feature flag keys used in production code must use
|
|
5
|
-
* simple kebab-case format (e.g., "browser", "
|
|
5
|
+
* simple kebab-case format (e.g., "browser", "contacts"). Any remaining
|
|
6
6
|
* `skills.<id>.enabled` usage outside of migration/backward-compat code is
|
|
7
7
|
* flagged — including template literal forms like `skills.${skillId}.enabled`.
|
|
8
8
|
*
|
|
@@ -312,64 +312,6 @@ describe("assistant ID boundary", () => {
|
|
|
312
312
|
// surfaces invites callers to pass external IDs into daemon scoping.
|
|
313
313
|
// -------------------------------------------------------------------------
|
|
314
314
|
|
|
315
|
-
test("message contract types do not contain assistantId for guardian requests", () => {
|
|
316
|
-
const contractPath = join(
|
|
317
|
-
import.meta.dir,
|
|
318
|
-
"..",
|
|
319
|
-
"daemon",
|
|
320
|
-
"message-types",
|
|
321
|
-
"integrations.ts",
|
|
322
|
-
);
|
|
323
|
-
const content = readFileSync(contractPath, "utf-8");
|
|
324
|
-
|
|
325
|
-
// Extract the interface blocks for the request types and verify
|
|
326
|
-
// none of them declare an assistantId property.
|
|
327
|
-
const requestTypeNames = ["ChannelVerificationSessionRequest"];
|
|
328
|
-
|
|
329
|
-
for (const typeName of requestTypeNames) {
|
|
330
|
-
// Find the interface/type block — match from the type name to the next
|
|
331
|
-
// closing brace at the same indentation level. We use a simple heuristic:
|
|
332
|
-
// find the line declaring the type, then scan forward to the closing '}'.
|
|
333
|
-
const typeIndex = content.indexOf(typeName);
|
|
334
|
-
expect(
|
|
335
|
-
typeIndex,
|
|
336
|
-
`Expected to find ${typeName} in message contract`,
|
|
337
|
-
).toBeGreaterThan(-1);
|
|
338
|
-
|
|
339
|
-
// Extract from the type declaration to the next '}' line
|
|
340
|
-
const blockStart = content.indexOf("{", typeIndex);
|
|
341
|
-
if (blockStart === -1) continue;
|
|
342
|
-
let braceDepth = 0;
|
|
343
|
-
let blockEnd = blockStart;
|
|
344
|
-
for (let i = blockStart; i < content.length; i++) {
|
|
345
|
-
if (content[i] === "{") braceDepth++;
|
|
346
|
-
if (content[i] === "}") braceDepth--;
|
|
347
|
-
if (braceDepth === 0) {
|
|
348
|
-
blockEnd = i + 1;
|
|
349
|
-
break;
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
const block = content.slice(blockStart, blockEnd);
|
|
353
|
-
|
|
354
|
-
// The block should not contain an assistantId property declaration
|
|
355
|
-
// (matches "assistantId?" or "assistantId:" on a non-comment line)
|
|
356
|
-
const lines = block.split("\n");
|
|
357
|
-
for (const line of lines) {
|
|
358
|
-
const trimmed = line.trim();
|
|
359
|
-
if (
|
|
360
|
-
trimmed.startsWith("//") ||
|
|
361
|
-
trimmed.startsWith("*") ||
|
|
362
|
-
trimmed.startsWith("/*")
|
|
363
|
-
)
|
|
364
|
-
continue;
|
|
365
|
-
expect(
|
|
366
|
-
/\bassistantId\s*[?:]/.test(trimmed),
|
|
367
|
-
`${typeName} must not declare an assistantId property. Found: "${trimmed}"`,
|
|
368
|
-
).toBe(false);
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
});
|
|
372
|
-
|
|
373
315
|
test("guardian outbound param interfaces do not contain assistantId", () => {
|
|
374
316
|
const actionsPath = join(
|
|
375
317
|
import.meta.dir,
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
import { dirname, join } from "node:path";
|
|
9
9
|
import { beforeEach, describe, expect, test } from "bun:test";
|
|
10
10
|
|
|
11
|
-
import type {
|
|
11
|
+
import type { AssistantEventEnvelope } from "../api/index.js";
|
|
12
12
|
import type {
|
|
13
13
|
EventTargeting,
|
|
14
14
|
ReplaySubscriber,
|
|
@@ -26,7 +26,9 @@ import {
|
|
|
26
26
|
|
|
27
27
|
const CONV = "conv_test";
|
|
28
28
|
|
|
29
|
-
function mkEvent(
|
|
29
|
+
function mkEvent(
|
|
30
|
+
overrides: Partial<AssistantEventEnvelope> = {},
|
|
31
|
+
): AssistantEventEnvelope {
|
|
30
32
|
const conversationId =
|
|
31
33
|
"conversationId" in overrides ? overrides.conversationId : CONV;
|
|
32
34
|
return {
|
|
@@ -39,7 +41,7 @@ function mkEvent(overrides: Partial<AssistantEvent> = {}): AssistantEvent {
|
|
|
39
41
|
text: "x",
|
|
40
42
|
},
|
|
41
43
|
...overrides,
|
|
42
|
-
} as
|
|
44
|
+
} as AssistantEventEnvelope;
|
|
43
45
|
}
|
|
44
46
|
|
|
45
47
|
describe("assistant-stream-state", () => {
|
|
@@ -142,7 +144,9 @@ describe("assistant-stream-state", () => {
|
|
|
142
144
|
|
|
143
145
|
describe("ring buffer eviction", () => {
|
|
144
146
|
test("evicts oldest entries past the 200-event count cap", () => {
|
|
145
|
-
for (let i = 0; i < 250; i++)
|
|
147
|
+
for (let i = 0; i < 250; i++) {
|
|
148
|
+
stampAndBuffer(mkEvent());
|
|
149
|
+
}
|
|
146
150
|
const peek = _peekStreamForTesting();
|
|
147
151
|
expect(peek.ringLength).toBe(200);
|
|
148
152
|
// Newest is 250, oldest should be 51 (250 - 200 + 1)
|
|
@@ -212,7 +216,9 @@ describe("assistant-stream-state", () => {
|
|
|
212
216
|
|
|
213
217
|
test("returns null when lastSeenSeq is older than oldest buffered entry", () => {
|
|
214
218
|
// Force eviction by pushing past the count cap.
|
|
215
|
-
for (let i = 0; i < 250; i++)
|
|
219
|
+
for (let i = 0; i < 250; i++) {
|
|
220
|
+
stampAndBuffer(mkEvent());
|
|
221
|
+
}
|
|
216
222
|
const peek = _peekStreamForTesting();
|
|
217
223
|
expect(peek.oldestSeq).toBe(51);
|
|
218
224
|
// Client claims to have last seen seq=10 — that's far below oldest.
|
|
@@ -730,7 +736,9 @@ describe("assistant-stream-state", () => {
|
|
|
730
736
|
|
|
731
737
|
test("stamping within a reserved block does not advance the persisted ceiling", () => {
|
|
732
738
|
// GIVEN many stamps within one block
|
|
733
|
-
for (let i = 0; i < 100; i++)
|
|
739
|
+
for (let i = 0; i < 100; i++) {
|
|
740
|
+
stampAndBuffer(mkEvent());
|
|
741
|
+
}
|
|
734
742
|
|
|
735
743
|
// WHEN the daemon restarts
|
|
736
744
|
_simulateRestartForTesting();
|
|
@@ -784,7 +792,9 @@ describe("assistant-stream-state", () => {
|
|
|
784
792
|
|
|
785
793
|
// Stamp past the 200-event ring cap so the restarted process's
|
|
786
794
|
// earliest events are genuinely evicted.
|
|
787
|
-
for (let i = 0; i < 205; i++)
|
|
795
|
+
for (let i = 0; i < 205; i++) {
|
|
796
|
+
stampAndBuffer(mkEvent());
|
|
797
|
+
}
|
|
788
798
|
|
|
789
799
|
// The gap now includes evicted post-restart events, so replay must
|
|
790
800
|
// signal the snapshot fallback.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { describe, expect, test } from "bun:test";
|
|
2
2
|
|
|
3
|
+
import type { AssistantEventEnvelope } from "../api/index.js";
|
|
3
4
|
import { SYNC_TAGS } from "../daemon/message-types/sync.js";
|
|
4
|
-
import type { AssistantEvent } from "../runtime/assistant-event.js";
|
|
5
5
|
import { assistantEventHub } from "../runtime/assistant-event-hub.js";
|
|
6
6
|
import { ROUTES as AVATAR_ROUTES } from "../runtime/routes/avatar-routes.js";
|
|
7
7
|
import { publishIdentityChanged } from "../runtime/sync/resource-sync-events.js";
|
|
@@ -19,7 +19,7 @@ async function waitFor(predicate: () => boolean): Promise<void> {
|
|
|
19
19
|
|
|
20
20
|
describe("avatar and identity sync events", () => {
|
|
21
21
|
test("notify_avatar_updated emits legacy avatar event and sync tag", async () => {
|
|
22
|
-
const received:
|
|
22
|
+
const received: AssistantEventEnvelope[] = [];
|
|
23
23
|
const subscription = assistantEventHub.subscribe({
|
|
24
24
|
type: "process",
|
|
25
25
|
callback: (event) => {
|
|
@@ -50,7 +50,7 @@ describe("avatar and identity sync events", () => {
|
|
|
50
50
|
});
|
|
51
51
|
|
|
52
52
|
test("identity changes emit legacy identity event and identity sync tags", async () => {
|
|
53
|
-
const received:
|
|
53
|
+
const received: AssistantEventEnvelope[] = [];
|
|
54
54
|
const subscription = assistantEventHub.subscribe({
|
|
55
55
|
type: "process",
|
|
56
56
|
callback: (event) => {
|
|
@@ -151,6 +151,7 @@ mock.module("../persistence/jobs-store.js", () => ({
|
|
|
151
151
|
MESSAGE_LEXICAL_JOB_TYPES: [],
|
|
152
152
|
rescheduleMemoryJob: mock(() => {}),
|
|
153
153
|
resetRunningJobsToPending: mock(() => 0),
|
|
154
|
+
upsertEmbedGraphNodeJob: mock(() => "job-embed-node"),
|
|
154
155
|
SLOW_LLM_JOB_TYPES: [],
|
|
155
156
|
upsertDebouncedJob: mock(() => "job-debounced"),
|
|
156
157
|
upsertMemoryRetrospectiveJob: mock(() => "job-memory-retrospective"),
|
|
@@ -9,10 +9,11 @@ import {
|
|
|
9
9
|
recordCallEvent,
|
|
10
10
|
updateCallSession,
|
|
11
11
|
} from "../calls/call-store.js";
|
|
12
|
-
import { getMessages } from "../persistence/conversation-crud.js";
|
|
12
|
+
import { addMessage, getMessages } from "../persistence/conversation-crud.js";
|
|
13
13
|
import { getDb } from "../persistence/db-connection.js";
|
|
14
14
|
import { initializeDb } from "../persistence/db-init.js";
|
|
15
15
|
import { conversations } from "../persistence/schema/index.js";
|
|
16
|
+
import { contentBlockArraySchema } from "../providers/content-block-schema.js";
|
|
16
17
|
|
|
17
18
|
await initializeDb();
|
|
18
19
|
|
|
@@ -38,25 +39,57 @@ function resetTables(): void {
|
|
|
38
39
|
db.run("DELETE FROM conversations");
|
|
39
40
|
}
|
|
40
41
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
type PersistedBlock = {
|
|
43
|
+
type: string;
|
|
44
|
+
text?: string;
|
|
45
|
+
surfaceType?: string;
|
|
46
|
+
surfaceId?: string;
|
|
47
|
+
data?: { summaryText?: string };
|
|
48
|
+
_surfaceFallback?: boolean;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* The blocks of the latest assistant message carrying a `call_summary` card.
|
|
53
|
+
*
|
|
54
|
+
* Selecting on the card rather than on "latest assistant row" keeps these
|
|
55
|
+
* assertions independent of rows other test files leave in the shared
|
|
56
|
+
* workspace DB when the suite runs as one process.
|
|
57
|
+
*/
|
|
58
|
+
function getLatestAssistantBlocks(conversationId: string): PersistedBlock[] {
|
|
59
|
+
const rows = getMessages(conversationId).filter((m) => {
|
|
60
|
+
if (m.role !== "assistant") {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
const blocks = m.content as unknown as PersistedBlock[];
|
|
64
|
+
return (
|
|
65
|
+
Array.isArray(blocks) &&
|
|
66
|
+
blocks.some(
|
|
67
|
+
(b) => b.type === "ui_surface" && b.surfaceType === "call_summary",
|
|
68
|
+
)
|
|
69
|
+
);
|
|
70
|
+
});
|
|
45
71
|
expect(rows.length).toBeGreaterThan(0);
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
72
|
+
return rows[rows.length - 1].content as unknown as PersistedBlock[];
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* The message's model-visible copy. A call summary persists as a
|
|
77
|
+
* `[ui_surface, text]` pair carrying the SAME sentence, so text blocks win and
|
|
78
|
+
* the card is read only for legacy rows that predate the fallback sibling —
|
|
79
|
+
* concatenating both would double the summary.
|
|
80
|
+
*/
|
|
81
|
+
function getLatestAssistantText(conversationId: string): string {
|
|
82
|
+
const parsed = getLatestAssistantBlocks(conversationId);
|
|
83
|
+
const text = parsed
|
|
84
|
+
.filter((b) => b.type === "text")
|
|
85
|
+
.map((b) => b.text ?? "")
|
|
86
|
+
.join("");
|
|
87
|
+
if (text) {
|
|
88
|
+
return text;
|
|
89
|
+
}
|
|
53
90
|
return parsed
|
|
54
|
-
.
|
|
55
|
-
|
|
56
|
-
if (b.type === "ui_surface" && b.surfaceType === "call_summary")
|
|
57
|
-
return b.data?.summaryText ?? "";
|
|
58
|
-
return "";
|
|
59
|
-
})
|
|
91
|
+
.filter((b) => b.type === "ui_surface" && b.surfaceType === "call_summary")
|
|
92
|
+
.map((b) => b.data?.summaryText ?? "")
|
|
60
93
|
.join("");
|
|
61
94
|
}
|
|
62
95
|
|
|
@@ -127,4 +160,87 @@ describe("call-conversation-messages", () => {
|
|
|
127
160
|
"**Call completed**. 1 event(s) recorded.",
|
|
128
161
|
);
|
|
129
162
|
});
|
|
163
|
+
|
|
164
|
+
test("persistCallCompletionMessage pairs the card with a flagged text fallback", async () => {
|
|
165
|
+
// Every provider drops `ui_surface` when serializing history, so the card
|
|
166
|
+
// alone left the model unable to tell that a call happened — the turn
|
|
167
|
+
// reached the wire as a "blocks omitted" sentinel (LUM-2869). The
|
|
168
|
+
// `_surfaceFallback` sibling is what carries the summary to the model,
|
|
169
|
+
// search indexing, CLI display, and channel replies; its flag keeps
|
|
170
|
+
// surface-capable clients from rendering the card AND a duplicate line.
|
|
171
|
+
const conversationId = "conv-call-msg-fallback";
|
|
172
|
+
ensureConversation(conversationId);
|
|
173
|
+
const session = createCallSession({
|
|
174
|
+
conversationId,
|
|
175
|
+
provider: "twilio",
|
|
176
|
+
fromNumber: "+12025550101",
|
|
177
|
+
toNumber: "+12025550102",
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
updateCallSession(session.id, { status: "in_progress", startedAt: 1_000 });
|
|
181
|
+
updateCallSession(session.id, { status: "completed", endedAt: 43_000 });
|
|
182
|
+
recordCallEvent(session.id, "call_ended");
|
|
183
|
+
|
|
184
|
+
const summary = await persistCallCompletionMessage(
|
|
185
|
+
conversationId,
|
|
186
|
+
session.id,
|
|
187
|
+
);
|
|
188
|
+
const blocks = getLatestAssistantBlocks(conversationId);
|
|
189
|
+
|
|
190
|
+
expect(blocks).toHaveLength(2);
|
|
191
|
+
const [surface, fallback] = blocks;
|
|
192
|
+
|
|
193
|
+
expect(surface!.type).toBe("ui_surface");
|
|
194
|
+
expect(surface!.surfaceType).toBe("call_summary");
|
|
195
|
+
expect(surface!.surfaceId).toBeTruthy();
|
|
196
|
+
expect(surface!.data?.summaryText).toBe(summary);
|
|
197
|
+
|
|
198
|
+
expect(fallback!.type).toBe("text");
|
|
199
|
+
expect(fallback!._surfaceFallback).toBe(true);
|
|
200
|
+
expect(fallback!.text).toBe(summary);
|
|
201
|
+
expect(fallback!.text).toContain("(42s)");
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
test("persisted call-summary blocks satisfy the ContentBlock schema", async () => {
|
|
205
|
+
// The pair is JSON-serialized straight into `messages.content`. If it did
|
|
206
|
+
// not validate, every read of the row would pay the per-block repair —
|
|
207
|
+
// the read-path noise that spiked with voice GA (LUM-2869).
|
|
208
|
+
const conversationId = "conv-call-msg-schema";
|
|
209
|
+
ensureConversation(conversationId);
|
|
210
|
+
const session = createCallSession({
|
|
211
|
+
conversationId,
|
|
212
|
+
provider: "twilio",
|
|
213
|
+
fromNumber: "+12025550101",
|
|
214
|
+
toNumber: "+12025550102",
|
|
215
|
+
});
|
|
216
|
+
updateCallSession(session.id, { status: "completed" });
|
|
217
|
+
recordCallEvent(session.id, "call_ended");
|
|
218
|
+
await persistCallCompletionMessage(conversationId, session.id);
|
|
219
|
+
|
|
220
|
+
const blocks = getLatestAssistantBlocks(conversationId);
|
|
221
|
+
expect(contentBlockArraySchema.safeParse(blocks).success).toBe(true);
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
test("persisting a card-only message throws in tests (model-invisible guard)", async () => {
|
|
225
|
+
// The guard in `insertMessageCore` is what stops LUM-2869 recurring: a
|
|
226
|
+
// producer that persists a card with no model-readable sibling fails its
|
|
227
|
+
// own suite instead of silently shipping turns the model cannot see.
|
|
228
|
+
// (In production the same condition only warns — never-block posture.)
|
|
229
|
+
const conversationId = "conv-card-only-guard";
|
|
230
|
+
ensureConversation(conversationId);
|
|
231
|
+
await expect(
|
|
232
|
+
addMessage(
|
|
233
|
+
conversationId,
|
|
234
|
+
"assistant",
|
|
235
|
+
JSON.stringify([
|
|
236
|
+
{
|
|
237
|
+
type: "ui_surface",
|
|
238
|
+
surfaceId: "bare-1",
|
|
239
|
+
surfaceType: "call_summary",
|
|
240
|
+
data: { summaryText: "orphaned card" },
|
|
241
|
+
},
|
|
242
|
+
]),
|
|
243
|
+
),
|
|
244
|
+
).rejects.toThrow(/only content is ui_surface/);
|
|
245
|
+
});
|
|
130
246
|
});
|
|
@@ -111,3 +111,30 @@ describe("call_start guardian verification guard", () => {
|
|
|
111
111
|
expect(startCallInputs.length).toBe(1);
|
|
112
112
|
});
|
|
113
113
|
});
|
|
114
|
+
|
|
115
|
+
describe("call tools — model-input schema validation (LUM-2856)", () => {
|
|
116
|
+
test("call_start rejects a non-string phone_number before reaching startCall", async () => {
|
|
117
|
+
const before = startCallInputs.length;
|
|
118
|
+
const result = await executeCallStart(
|
|
119
|
+
{ phone_number: 4155550100, task: "call someone" },
|
|
120
|
+
makeContext(),
|
|
121
|
+
);
|
|
122
|
+
expect(result.isError).toBe(true);
|
|
123
|
+
expect(result.content).toContain('Invalid input for tool "call_start"');
|
|
124
|
+
expect(result.content).toContain("phone_number");
|
|
125
|
+
expect(startCallInputs.length).toBe(before);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
test("call_start rejects an unknown caller_identity_mode", async () => {
|
|
129
|
+
const result = await executeCallStart(
|
|
130
|
+
{
|
|
131
|
+
phone_number: "+14155550100",
|
|
132
|
+
task: "call someone",
|
|
133
|
+
caller_identity_mode: "spoofed",
|
|
134
|
+
},
|
|
135
|
+
makeContext(),
|
|
136
|
+
);
|
|
137
|
+
expect(result.isError).toBe(true);
|
|
138
|
+
expect(result.content).toContain("caller_identity_mode");
|
|
139
|
+
});
|
|
140
|
+
});
|
|
@@ -17,7 +17,6 @@ import type { PendingApprovalInfo } from "../runtime/channel-approvals.js";
|
|
|
17
17
|
import {
|
|
18
18
|
buildApprovalUIMetadata,
|
|
19
19
|
buildGuardianApprovalPrompt,
|
|
20
|
-
channelSupportsRichApprovalUI,
|
|
21
20
|
getChannelApprovalPrompt,
|
|
22
21
|
handleChannelDecision,
|
|
23
22
|
} from "../runtime/channel-approvals.js";
|
|
@@ -343,29 +342,3 @@ describe("buildGuardianApprovalPrompt", () => {
|
|
|
343
342
|
expect(prompt.actions.map((a) => a.id)).toEqual(["approve_once", "reject"]);
|
|
344
343
|
});
|
|
345
344
|
});
|
|
346
|
-
|
|
347
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
348
|
-
// 5. channelSupportsRichApprovalUI
|
|
349
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
350
|
-
|
|
351
|
-
describe("channelSupportsRichApprovalUI", () => {
|
|
352
|
-
test("returns true for telegram", () => {
|
|
353
|
-
expect(channelSupportsRichApprovalUI("telegram")).toBe(true);
|
|
354
|
-
});
|
|
355
|
-
|
|
356
|
-
test("returns false for vellum", () => {
|
|
357
|
-
expect(channelSupportsRichApprovalUI("vellum")).toBe(false);
|
|
358
|
-
});
|
|
359
|
-
|
|
360
|
-
test("returns false for voice", () => {
|
|
361
|
-
expect(channelSupportsRichApprovalUI("phone")).toBe(false);
|
|
362
|
-
});
|
|
363
|
-
|
|
364
|
-
test("returns true for slack", () => {
|
|
365
|
-
expect(channelSupportsRichApprovalUI("slack")).toBe(true);
|
|
366
|
-
});
|
|
367
|
-
|
|
368
|
-
test("returns false for unknown channels", () => {
|
|
369
|
-
expect(channelSupportsRichApprovalUI("")).toBe(false);
|
|
370
|
-
});
|
|
371
|
-
});
|