@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
|
@@ -232,7 +232,11 @@ describe("channel-permission cell layer", () => {
|
|
|
232
232
|
expect(countCalls("get_global_thresholds")).toBe(0);
|
|
233
233
|
});
|
|
234
234
|
|
|
235
|
-
|
|
235
|
+
// For non-guardian actors the cell layer is total: a successful walk that
|
|
236
|
+
// finds no cell resolves the room default — the owner's global interactive
|
|
237
|
+
// threshold collapsed to the channel's two levels — so a contact's turn
|
|
238
|
+
// never consumes a raw global threshold.
|
|
239
|
+
test("no cell resolves the collapsed global for a contact", async () => {
|
|
236
240
|
ipcHandlers.set("get_conversation_threshold", () => null);
|
|
237
241
|
ipcHandlers.set("resolve_channel_permission_threshold", () => ({
|
|
238
242
|
resolved: null,
|
|
@@ -241,6 +245,36 @@ describe("channel-permission cell layer", () => {
|
|
|
241
245
|
|
|
242
246
|
expect(
|
|
243
247
|
await getAutoApproveThreshold("conv-c3", "conversation", CELL_QUERY),
|
|
248
|
+
).toBe("low");
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
// The collapse keeps `none`: a Strict global yields Strict rooms.
|
|
252
|
+
test("no cell under a Strict global resolves Strict for a contact", async () => {
|
|
253
|
+
ipcHandlers.set("get_conversation_threshold", () => null);
|
|
254
|
+
ipcHandlers.set("resolve_channel_permission_threshold", () => ({
|
|
255
|
+
resolved: null,
|
|
256
|
+
}));
|
|
257
|
+
setGlobals("none");
|
|
258
|
+
|
|
259
|
+
expect(
|
|
260
|
+
await getAutoApproveThreshold("conv-c3s", "conversation", CELL_QUERY),
|
|
261
|
+
).toBe("none");
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
// The channel setting governs other people in the room — a guardian query
|
|
265
|
+
// with no cell keeps falling through to the global thresholds.
|
|
266
|
+
test("no cell falls through to global for a guardian query", async () => {
|
|
267
|
+
ipcHandlers.set("get_conversation_threshold", () => null);
|
|
268
|
+
ipcHandlers.set("resolve_channel_permission_threshold", () => ({
|
|
269
|
+
resolved: null,
|
|
270
|
+
}));
|
|
271
|
+
setGlobals("medium");
|
|
272
|
+
|
|
273
|
+
expect(
|
|
274
|
+
await getAutoApproveThreshold("conv-c3g", "conversation", {
|
|
275
|
+
...CELL_QUERY,
|
|
276
|
+
contactType: "guardian",
|
|
277
|
+
}),
|
|
244
278
|
).toBe("medium");
|
|
245
279
|
});
|
|
246
280
|
|
|
@@ -275,28 +309,31 @@ describe("channel-permission cell layer", () => {
|
|
|
275
309
|
expect(countCalls("resolve_channel_permission_threshold")).toBe(0);
|
|
276
310
|
});
|
|
277
311
|
|
|
278
|
-
|
|
312
|
+
// An unreadable cell may be a Strict cell, so a contact's read fails
|
|
313
|
+
// closed rather than consuming the raw global.
|
|
314
|
+
test("a cell transport failure resolves Strict for a contact on the cached read", async () => {
|
|
279
315
|
ipcHandlers.set("get_conversation_threshold", () => null);
|
|
280
316
|
// No resolve handler registered → ipcCall returns undefined.
|
|
281
317
|
setGlobals("medium");
|
|
282
318
|
|
|
283
319
|
expect(
|
|
284
320
|
await getAutoApproveThreshold("conv-c5", "conversation", CELL_QUERY),
|
|
285
|
-
).toBe("
|
|
321
|
+
).toBe("none");
|
|
286
322
|
});
|
|
287
323
|
|
|
288
324
|
test("a bare-null cell response is a transport failure, not a null-deref or a cached negative", async () => {
|
|
289
325
|
// The route contract always wraps the resolution ({ resolved: … }); a
|
|
290
326
|
// bare null is malformed. It must behave exactly like a transport
|
|
291
|
-
// failure: hot path
|
|
292
|
-
// is cached so a real cell is seen as soon as the
|
|
327
|
+
// failure: a contact's hot path resolves Strict, refresh keeps its
|
|
328
|
+
// prompt, nothing is cached so a real cell is seen as soon as the
|
|
329
|
+
// response is healthy.
|
|
293
330
|
ipcHandlers.set("get_conversation_threshold", () => null);
|
|
294
331
|
ipcHandlers.set("resolve_channel_permission_threshold", () => null);
|
|
295
332
|
setGlobals("high");
|
|
296
333
|
|
|
297
334
|
expect(
|
|
298
335
|
await getAutoApproveThreshold("conv-c12", "conversation", CELL_QUERY),
|
|
299
|
-
).toBe("
|
|
336
|
+
).toBe("none");
|
|
300
337
|
expect(
|
|
301
338
|
await refreshAutoApproveThreshold("conv-c12", "conversation", CELL_QUERY),
|
|
302
339
|
).toBeNull();
|
|
@@ -309,6 +346,9 @@ describe("channel-permission cell layer", () => {
|
|
|
309
346
|
).toBe("none");
|
|
310
347
|
});
|
|
311
348
|
|
|
349
|
+
// An invalid threshold value is never trusted — it degrades to the no-cell
|
|
350
|
+
// resolution, which for a contact is the room default rather than the
|
|
351
|
+
// (possibly looser) global threshold.
|
|
312
352
|
test("an invalid cell threshold value is treated as no cell", async () => {
|
|
313
353
|
ipcHandlers.set("get_conversation_threshold", () => null);
|
|
314
354
|
ipcHandlers.set("resolve_channel_permission_threshold", () => ({
|
|
@@ -318,7 +358,7 @@ describe("channel-permission cell layer", () => {
|
|
|
318
358
|
|
|
319
359
|
expect(
|
|
320
360
|
await getAutoApproveThreshold("conv-c6", "conversation", CELL_QUERY),
|
|
321
|
-
).toBe("
|
|
361
|
+
).toBe("low");
|
|
322
362
|
});
|
|
323
363
|
|
|
324
364
|
test("cell resolutions are cached within the TTL, including negatives", async () => {
|
|
@@ -335,7 +375,8 @@ describe("channel-permission cell layer", () => {
|
|
|
335
375
|
).toBe("low");
|
|
336
376
|
expect(countCalls("resolve_channel_permission_threshold")).toBe(1);
|
|
337
377
|
|
|
338
|
-
// A different coordinate is a different cache entry.
|
|
378
|
+
// A different coordinate is a different cache entry. The negative
|
|
379
|
+
// resolution resolves the contact default, not the global threshold.
|
|
339
380
|
ipcHandlers.set("resolve_channel_permission_threshold", () => ({
|
|
340
381
|
resolved: null,
|
|
341
382
|
}));
|
|
@@ -343,10 +384,10 @@ describe("channel-permission cell layer", () => {
|
|
|
343
384
|
const otherChannel = { ...CELL_QUERY, channelExternalId: "C999" };
|
|
344
385
|
expect(
|
|
345
386
|
await getAutoApproveThreshold("conv-c7", "conversation", otherChannel),
|
|
346
|
-
).toBe("
|
|
387
|
+
).toBe("low");
|
|
347
388
|
expect(
|
|
348
389
|
await getAutoApproveThreshold("conv-c7", "conversation", otherChannel),
|
|
349
|
-
).toBe("
|
|
390
|
+
).toBe("low");
|
|
350
391
|
expect(countCalls("resolve_channel_permission_threshold")).toBe(2);
|
|
351
392
|
});
|
|
352
393
|
|
|
@@ -354,19 +395,20 @@ describe("channel-permission cell layer", () => {
|
|
|
354
395
|
ipcHandlers.set("get_conversation_threshold", () => null);
|
|
355
396
|
setGlobals("high");
|
|
356
397
|
|
|
357
|
-
// First read: cell lookup fails
|
|
398
|
+
// First read: cell lookup fails — the contact resolves Strict.
|
|
358
399
|
expect(
|
|
359
400
|
await getAutoApproveThreshold("conv-c8", "conversation", CELL_QUERY),
|
|
360
|
-
).toBe("
|
|
401
|
+
).toBe("none");
|
|
361
402
|
|
|
362
|
-
// The IPC recovers — the next read must see the
|
|
363
|
-
//
|
|
403
|
+
// The IPC recovers — the next read must see the real cell instead of a
|
|
404
|
+
// cached failure. The cell's threshold is distinguishable from the
|
|
405
|
+
// fail-closed value, so this passes only if the retry truly re-reads.
|
|
364
406
|
ipcHandlers.set("resolve_channel_permission_threshold", () => ({
|
|
365
|
-
resolved: { threshold: "
|
|
407
|
+
resolved: { threshold: "low", scope: "channel" },
|
|
366
408
|
}));
|
|
367
409
|
expect(
|
|
368
410
|
await getAutoApproveThreshold("conv-c8", "conversation", CELL_QUERY),
|
|
369
|
-
).toBe("
|
|
411
|
+
).toBe("low");
|
|
370
412
|
});
|
|
371
413
|
|
|
372
414
|
test("refresh bypasses a stale cell cache and returns the fresh cell", async () => {
|
|
@@ -414,7 +456,10 @@ describe("channel-permission cell layer", () => {
|
|
|
414
456
|
expect(countCalls("get_global_thresholds")).toBe(0);
|
|
415
457
|
});
|
|
416
458
|
|
|
417
|
-
|
|
459
|
+
// The refresh resolves the same room default the cached read resolves, so
|
|
460
|
+
// a prompt re-evaluated mid-turn cannot flip to a looser global than the
|
|
461
|
+
// level the room advertises.
|
|
462
|
+
test("refresh resolves the collapsed global when no cell exists", async () => {
|
|
418
463
|
ipcHandlers.set("get_conversation_threshold", () => null);
|
|
419
464
|
ipcHandlers.set("resolve_channel_permission_threshold", () => ({
|
|
420
465
|
resolved: null,
|
|
@@ -423,6 +468,168 @@ describe("channel-permission cell layer", () => {
|
|
|
423
468
|
|
|
424
469
|
expect(
|
|
425
470
|
await refreshAutoApproveThreshold("conv-c11", "conversation", CELL_QUERY),
|
|
471
|
+
).toBe("low");
|
|
472
|
+
});
|
|
473
|
+
|
|
474
|
+
test("refresh falls through to the raw global for a guardian query", async () => {
|
|
475
|
+
ipcHandlers.set("get_conversation_threshold", () => null);
|
|
476
|
+
ipcHandlers.set("resolve_channel_permission_threshold", () => ({
|
|
477
|
+
resolved: null,
|
|
478
|
+
}));
|
|
479
|
+
setGlobals("medium");
|
|
480
|
+
|
|
481
|
+
expect(
|
|
482
|
+
await refreshAutoApproveThreshold("conv-c11g", "conversation", {
|
|
483
|
+
...CELL_QUERY,
|
|
484
|
+
contactType: "guardian",
|
|
485
|
+
}),
|
|
426
486
|
).toBe("medium");
|
|
427
487
|
});
|
|
428
488
|
});
|
|
489
|
+
|
|
490
|
+
// ---------------------------------------------------------------------------
|
|
491
|
+
// Two-level collapse of non-guardian channel cells
|
|
492
|
+
// ---------------------------------------------------------------------------
|
|
493
|
+
|
|
494
|
+
// The channel picker offers two levels; medium/high cells are accepted from
|
|
495
|
+
// the schema and other writers and behave as low. The collapse lives at the
|
|
496
|
+
// resolve point so a stored cell can never authorize more than the level the
|
|
497
|
+
// picker displays for it — in either consumer lane.
|
|
498
|
+
describe("channel cell two-level collapse", () => {
|
|
499
|
+
beforeEach(() => {
|
|
500
|
+
_clearGlobalCacheForTesting();
|
|
501
|
+
_resetFailureCoalesceForTesting();
|
|
502
|
+
ipcHandlers.clear();
|
|
503
|
+
ipcCallLog.length = 0;
|
|
504
|
+
});
|
|
505
|
+
|
|
506
|
+
test.each(["medium", "high"] as const)(
|
|
507
|
+
"a stored %s cell resolves as low for a contact",
|
|
508
|
+
async (stored) => {
|
|
509
|
+
ipcHandlers.set("get_conversation_threshold", () => null);
|
|
510
|
+
ipcHandlers.set("resolve_channel_permission_threshold", () => ({
|
|
511
|
+
resolved: { threshold: stored, scope: "channel" },
|
|
512
|
+
}));
|
|
513
|
+
|
|
514
|
+
expect(
|
|
515
|
+
await getAutoApproveThreshold("conv-cl1", "conversation", CELL_QUERY),
|
|
516
|
+
).toBe("low");
|
|
517
|
+
},
|
|
518
|
+
);
|
|
519
|
+
|
|
520
|
+
test.each(["none", "low"] as const)(
|
|
521
|
+
"a %s cell is untouched by the collapse",
|
|
522
|
+
async (stored) => {
|
|
523
|
+
ipcHandlers.set("get_conversation_threshold", () => null);
|
|
524
|
+
ipcHandlers.set("resolve_channel_permission_threshold", () => ({
|
|
525
|
+
resolved: { threshold: stored, scope: "channel" },
|
|
526
|
+
}));
|
|
527
|
+
|
|
528
|
+
expect(
|
|
529
|
+
await getAutoApproveThreshold("conv-cl2", "conversation", CELL_QUERY),
|
|
530
|
+
).toBe(stored);
|
|
531
|
+
},
|
|
532
|
+
);
|
|
533
|
+
|
|
534
|
+
// The channel setting governs other people in the room; the guardian's own
|
|
535
|
+
// lane is out of its scope, so a guardian-contact-type cell keeps its value.
|
|
536
|
+
test("a guardian-contact-type cell keeps its stored threshold", async () => {
|
|
537
|
+
ipcHandlers.set("get_conversation_threshold", () => null);
|
|
538
|
+
ipcHandlers.set("resolve_channel_permission_threshold", () => ({
|
|
539
|
+
resolved: { threshold: "high", scope: "channel" },
|
|
540
|
+
}));
|
|
541
|
+
|
|
542
|
+
expect(
|
|
543
|
+
await getAutoApproveThreshold("conv-cl3", "conversation", {
|
|
544
|
+
...CELL_QUERY,
|
|
545
|
+
contactType: "guardian",
|
|
546
|
+
}),
|
|
547
|
+
).toBe("high");
|
|
548
|
+
});
|
|
549
|
+
|
|
550
|
+
// The cache stores the raw resolution; the collapse is applied on the read
|
|
551
|
+
// side, so a cache hit collapses identically to a fresh resolve.
|
|
552
|
+
test("cache hits collapse the same as fresh resolves", async () => {
|
|
553
|
+
ipcHandlers.set("get_conversation_threshold", () => null);
|
|
554
|
+
ipcHandlers.set("resolve_channel_permission_threshold", () => ({
|
|
555
|
+
resolved: { threshold: "high", scope: "channel" },
|
|
556
|
+
}));
|
|
557
|
+
|
|
558
|
+
const first = await getAutoApproveThreshold(
|
|
559
|
+
"conv-cl4",
|
|
560
|
+
"conversation",
|
|
561
|
+
CELL_QUERY,
|
|
562
|
+
);
|
|
563
|
+
const second = await getAutoApproveThreshold(
|
|
564
|
+
"conv-cl4",
|
|
565
|
+
"conversation",
|
|
566
|
+
CELL_QUERY,
|
|
567
|
+
);
|
|
568
|
+
|
|
569
|
+
expect(first).toBe("low");
|
|
570
|
+
expect(second).toBe("low");
|
|
571
|
+
// One IPC round-trip: the second read came from the cell cache.
|
|
572
|
+
expect(countCalls("resolve_channel_permission_threshold")).toBe(1);
|
|
573
|
+
});
|
|
574
|
+
});
|
|
575
|
+
|
|
576
|
+
// ---------------------------------------------------------------------------
|
|
577
|
+
// Contact fail-closed on cell-read failure; refresh default bypasses caches
|
|
578
|
+
// ---------------------------------------------------------------------------
|
|
579
|
+
|
|
580
|
+
describe("contact cell layer failure semantics", () => {
|
|
581
|
+
beforeEach(() => {
|
|
582
|
+
_clearGlobalCacheForTesting();
|
|
583
|
+
_resetFailureCoalesceForTesting();
|
|
584
|
+
ipcHandlers.clear();
|
|
585
|
+
ipcCallLog.length = 0;
|
|
586
|
+
});
|
|
587
|
+
|
|
588
|
+
// An unreadable cell may be a Strict cell — a transient IPC failure must
|
|
589
|
+
// not hand a contact the raw global instead.
|
|
590
|
+
test("a failed cell read resolves Strict for a contact, not the global", async () => {
|
|
591
|
+
ipcHandlers.set("get_conversation_threshold", () => null);
|
|
592
|
+
// No resolve handler registered → transport failure.
|
|
593
|
+
setGlobals("high");
|
|
594
|
+
|
|
595
|
+
expect(
|
|
596
|
+
await getAutoApproveThreshold("conv-fc1", "conversation", CELL_QUERY),
|
|
597
|
+
).toBe("none");
|
|
598
|
+
});
|
|
599
|
+
|
|
600
|
+
test("a failed cell read falls through to global for a guardian query", async () => {
|
|
601
|
+
ipcHandlers.set("get_conversation_threshold", () => null);
|
|
602
|
+
setGlobals("high");
|
|
603
|
+
|
|
604
|
+
expect(
|
|
605
|
+
await getAutoApproveThreshold("conv-fc2", "conversation", {
|
|
606
|
+
...CELL_QUERY,
|
|
607
|
+
contactType: "guardian",
|
|
608
|
+
}),
|
|
609
|
+
).toBe("high");
|
|
610
|
+
});
|
|
611
|
+
|
|
612
|
+
// The refresh exists to see writes the caches hide — the no-cell default
|
|
613
|
+
// must read the globals fresh, not the 30s cache.
|
|
614
|
+
test("refresh derives the no-cell default from fresh globals", async () => {
|
|
615
|
+
ipcHandlers.set("get_conversation_threshold", () => null);
|
|
616
|
+
ipcHandlers.set("resolve_channel_permission_threshold", () => ({
|
|
617
|
+
resolved: null,
|
|
618
|
+
}));
|
|
619
|
+
// Prime the global cache at Strict.
|
|
620
|
+
setGlobals("none");
|
|
621
|
+
expect(
|
|
622
|
+
await getAutoApproveThreshold("conv-fc3", "conversation", CELL_QUERY),
|
|
623
|
+
).toBe("none");
|
|
624
|
+
|
|
625
|
+
// The owner loosens the global; the cached read still sees Strict, the
|
|
626
|
+
// refresh must not.
|
|
627
|
+
setGlobals("medium");
|
|
628
|
+
expect(
|
|
629
|
+
await getAutoApproveThreshold("conv-fc3", "conversation", CELL_QUERY),
|
|
630
|
+
).toBe("none");
|
|
631
|
+
expect(
|
|
632
|
+
await refreshAutoApproveThreshold("conv-fc3", "conversation", CELL_QUERY),
|
|
633
|
+
).toBe("low");
|
|
634
|
+
});
|
|
635
|
+
});
|
|
@@ -18,6 +18,10 @@ import type {
|
|
|
18
18
|
AutoApproveThreshold,
|
|
19
19
|
ExecutionContext,
|
|
20
20
|
} from "./approval-policy.js";
|
|
21
|
+
import {
|
|
22
|
+
collapseChannelThresholdForContact,
|
|
23
|
+
effectiveChannelCellThreshold,
|
|
24
|
+
} from "./channel-permission-query.js";
|
|
21
25
|
|
|
22
26
|
const log = getLogger("gateway-threshold-reader");
|
|
23
27
|
|
|
@@ -222,8 +226,11 @@ export type ChannelPermissionCellResult =
|
|
|
222
226
|
|
|
223
227
|
/**
|
|
224
228
|
* Resolve the permission-matrix cell for a channel/actor coordinate via the
|
|
225
|
-
* gateway (`resolve_channel_permission_threshold` IPC): the winning cell
|
|
229
|
+
* gateway (`resolve_channel_permission_threshold` IPC): the raw winning cell
|
|
226
230
|
* threshold + scope, or a null resolution when no cascade level has a cell.
|
|
231
|
+
* What a resolution authorizes for the actor — the two-level collapse and
|
|
232
|
+
* the room default — is `effectiveChannelCellThreshold`'s single rule;
|
|
233
|
+
* consumers go through it rather than reading the threshold directly.
|
|
227
234
|
*
|
|
228
235
|
* Transport failures are not cached, so a transient IPC failure cannot
|
|
229
236
|
* suppress a real cell for the TTL window.
|
|
@@ -269,6 +276,47 @@ export async function resolveChannelPermissionCell(
|
|
|
269
276
|
return { ok: true, resolved };
|
|
270
277
|
}
|
|
271
278
|
|
|
279
|
+
/**
|
|
280
|
+
* The room default a cell-less coordinate inherits for non-guardian contact
|
|
281
|
+
* types: the owner's global interactive threshold, collapsed to the two
|
|
282
|
+
* levels a channel distinguishes. This is the level the picker's "· default"
|
|
283
|
+
* marker and the legend advertise, so resolving it here is what keeps the
|
|
284
|
+
* displayed default and the enforced one the same value. Returns `undefined`
|
|
285
|
+
* when the global thresholds cannot be read — callers fail safe, and the
|
|
286
|
+
* shared fetch's own failure accounting covers the logging.
|
|
287
|
+
*/
|
|
288
|
+
async function resolveContactRoomDefaultThreshold(options?: {
|
|
289
|
+
bypassCache?: boolean;
|
|
290
|
+
}): Promise<AutoApproveThreshold | undefined> {
|
|
291
|
+
try {
|
|
292
|
+
const global = await fetchGlobalThresholds(options);
|
|
293
|
+
if (!isValidThreshold(global.interactive)) {
|
|
294
|
+
return undefined;
|
|
295
|
+
}
|
|
296
|
+
return collapseChannelThresholdForContact(global.interactive);
|
|
297
|
+
} catch {
|
|
298
|
+
return undefined;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* The `noCellDefault` argument for {@link effectiveChannelCellThreshold}:
|
|
304
|
+
* derived only when it can matter — a successful walk that found no cell,
|
|
305
|
+
* for a non-guardian contact type. One guard for every cell consumer, so
|
|
306
|
+
* none of them can apply the room default to a guardian query or pay the
|
|
307
|
+
* global read on a path where the rule would discard it.
|
|
308
|
+
*/
|
|
309
|
+
export async function channelNoCellDefault(
|
|
310
|
+
cell: ChannelPermissionCellResult,
|
|
311
|
+
contactType: ResolveChannelPermissionRequest["contactType"],
|
|
312
|
+
options?: { bypassCache?: boolean },
|
|
313
|
+
): Promise<AutoApproveThreshold | undefined> {
|
|
314
|
+
if (!cell.ok || cell.resolved || contactType === "guardian") {
|
|
315
|
+
return undefined;
|
|
316
|
+
}
|
|
317
|
+
return resolveContactRoomDefaultThreshold(options);
|
|
318
|
+
}
|
|
319
|
+
|
|
272
320
|
// ── Main export ──────────────────────────────────────────────────────────────
|
|
273
321
|
|
|
274
322
|
/**
|
|
@@ -338,14 +386,25 @@ export async function getAutoApproveThreshold(
|
|
|
338
386
|
}
|
|
339
387
|
}
|
|
340
388
|
|
|
341
|
-
// Channel-permission matrix cell:
|
|
342
|
-
//
|
|
343
|
-
//
|
|
344
|
-
//
|
|
389
|
+
// Channel-permission matrix cell: for non-guardian actors this layer is
|
|
390
|
+
// total in every direction — a successful walk that finds no cell resolves
|
|
391
|
+
// the room default (the collapsed global), and a failed read resolves
|
|
392
|
+
// Strict, so a contact's turn never consumes a raw global threshold. An
|
|
393
|
+
// unreadable cell may be a Strict cell (this module's header rule: an
|
|
394
|
+
// unreachable gateway auto-approves nothing). Guardian queries fall
|
|
395
|
+
// through to the global block below in both cases — their lane.
|
|
345
396
|
if (cellQuery) {
|
|
346
397
|
const cell = await resolveChannelPermissionCell(cellQuery);
|
|
347
|
-
if (cell.ok &&
|
|
348
|
-
return
|
|
398
|
+
if (!cell.ok && cellQuery.contactType !== "guardian") {
|
|
399
|
+
return "none";
|
|
400
|
+
}
|
|
401
|
+
const effective = effectiveChannelCellThreshold(
|
|
402
|
+
cell,
|
|
403
|
+
cellQuery.contactType,
|
|
404
|
+
await channelNoCellDefault(cell, cellQuery.contactType),
|
|
405
|
+
);
|
|
406
|
+
if (effective !== undefined) {
|
|
407
|
+
return effective;
|
|
349
408
|
}
|
|
350
409
|
}
|
|
351
410
|
|
|
@@ -375,9 +434,12 @@ export async function getAutoApproveThreshold(
|
|
|
375
434
|
}
|
|
376
435
|
}
|
|
377
436
|
|
|
378
|
-
async function fetchGlobalThresholds(
|
|
437
|
+
async function fetchGlobalThresholds(options?: {
|
|
438
|
+
bypassCache?: boolean;
|
|
439
|
+
}): Promise<GlobalThresholds> {
|
|
379
440
|
const now = Date.now();
|
|
380
441
|
if (
|
|
442
|
+
!options?.bypassCache &&
|
|
381
443
|
cachedGlobalThresholds &&
|
|
382
444
|
now - cachedGlobalTimestamp < GLOBAL_CACHE_TTL_MS
|
|
383
445
|
) {
|
|
@@ -479,8 +541,18 @@ export async function refreshAutoApproveThreshold(
|
|
|
479
541
|
if (!cell.ok) {
|
|
480
542
|
return null;
|
|
481
543
|
}
|
|
482
|
-
|
|
483
|
-
|
|
544
|
+
// The refresh exists to see writes the caches hide, so the derived
|
|
545
|
+
// default reads the globals fresh (and primes the cache) exactly like
|
|
546
|
+
// the cell read above bypasses the cell cache.
|
|
547
|
+
const effective = effectiveChannelCellThreshold(
|
|
548
|
+
cell,
|
|
549
|
+
cellQuery.contactType,
|
|
550
|
+
await channelNoCellDefault(cell, cellQuery.contactType, {
|
|
551
|
+
bypassCache: true,
|
|
552
|
+
}),
|
|
553
|
+
);
|
|
554
|
+
if (effective !== undefined) {
|
|
555
|
+
return effective;
|
|
484
556
|
}
|
|
485
557
|
}
|
|
486
558
|
|
|
@@ -103,6 +103,14 @@ export interface ClassifyRiskParams {
|
|
|
103
103
|
* protected directory. Falls back to lexical `path` resolution when absent.
|
|
104
104
|
*/
|
|
105
105
|
resolvedPath?: string;
|
|
106
|
+
/**
|
|
107
|
+
* The sandbox file tool's working directory with symlinks resolved
|
|
108
|
+
* (canonicalized by the daemon). Paired with `resolvedPath` for the
|
|
109
|
+
* workspace-boundary check so a symlinked workspace prefix (e.g. macOS
|
|
110
|
+
* /var → /private/var) does not read as an escape. Absent for host tools;
|
|
111
|
+
* the gateway falls back to a lexical-vs-lexical comparison when unset.
|
|
112
|
+
*/
|
|
113
|
+
resolvedWorkingDir?: string;
|
|
106
114
|
skill?: string;
|
|
107
115
|
mode?: string;
|
|
108
116
|
script?: string;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { v4 as uuid } from "uuid";
|
|
2
2
|
|
|
3
|
+
import type { AssistantEvent } from "../api/index.js";
|
|
3
4
|
import { getConfig } from "../config/loader.js";
|
|
4
|
-
import type { ServerMessage } from "../daemon/message-protocol.js";
|
|
5
5
|
import * as pendingInteractions from "../runtime/pending-interactions.js";
|
|
6
6
|
import { redactSensitiveFields } from "../security/redaction.js";
|
|
7
7
|
import type { ExecutionTarget } from "../tools/tool-types.js";
|
|
@@ -36,10 +36,10 @@ export class PermissionPrompter {
|
|
|
36
36
|
* pendingInteractions, matching the host proxy pattern.
|
|
37
37
|
*/
|
|
38
38
|
private ownedIds = new Set<string>();
|
|
39
|
-
private sendToClient: (msg:
|
|
39
|
+
private sendToClient: (msg: AssistantEvent) => void;
|
|
40
40
|
private onStateChanged?: ConfirmationStateCallback;
|
|
41
41
|
|
|
42
|
-
constructor(sendToClient: (msg:
|
|
42
|
+
constructor(sendToClient: (msg: AssistantEvent) => void) {
|
|
43
43
|
this.sendToClient = sendToClient;
|
|
44
44
|
}
|
|
45
45
|
|
|
@@ -47,7 +47,7 @@ export class PermissionPrompter {
|
|
|
47
47
|
this.onStateChanged = cb;
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
updateSender(sendToClient: (msg:
|
|
50
|
+
updateSender(sendToClient: (msg: AssistantEvent) => void): void {
|
|
51
51
|
this.sendToClient = sendToClient;
|
|
52
52
|
}
|
|
53
53
|
|
|
@@ -145,7 +145,7 @@ export class PermissionPrompter {
|
|
|
145
145
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
146
146
|
}
|
|
147
147
|
|
|
148
|
-
const confirmationMsg:
|
|
148
|
+
const confirmationMsg: AssistantEvent & {
|
|
149
149
|
type: "confirmation_request";
|
|
150
150
|
} = {
|
|
151
151
|
type: "confirmation_request",
|