@vellumai/assistant 0.10.12 → 0.11.0-staging.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +1 -1
- package/ARCHITECTURE.md +4 -5
- package/README.md +1 -1
- package/docs/architecture/memory.md +60 -23
- package/docs/error-handling.md +3 -3
- package/docs/guardian-request-flow.md +112 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/package.json +1 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/__tests__/channels.test.ts +9 -1
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/__tests__/secret-detection.test.ts +449 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/channels.ts +1 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/secret-detection.ts +468 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/app.d.ts +28 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/app.d.ts.map +1 -1
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/index.d.ts +2 -2
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/index.d.ts.map +1 -1
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/index.js.map +1 -1
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/message.d.ts +2 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/message.d.ts.map +1 -1
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/package.json +1 -1
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/package.json +1 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/__tests__/channels.test.ts +9 -1
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/__tests__/secret-detection.test.ts +449 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/channels.ts +1 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/secret-detection.ts +468 -0
- package/node_modules/@vellumai/gateway-client/package.json +1 -1
- package/node_modules/@vellumai/gateway-client/src/admission-policy-contract.ts +6 -0
- package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +34 -0
- package/node_modules/@vellumai/service-contracts/package.json +1 -0
- package/node_modules/@vellumai/service-contracts/src/__tests__/channels.test.ts +9 -1
- package/node_modules/@vellumai/service-contracts/src/__tests__/secret-detection.test.ts +449 -0
- package/node_modules/@vellumai/service-contracts/src/channels.ts +1 -0
- package/node_modules/@vellumai/service-contracts/src/secret-detection.ts +468 -0
- package/openapi.yaml +264 -14
- package/package.json +2 -2
- package/src/__tests__/acp-session.test.ts +3 -3
- package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +3 -0
- package/src/__tests__/anthropic-provider.test.ts +40 -0
- package/src/__tests__/app-conversation-ids-backfill.test.ts +33 -2
- package/src/__tests__/app-conversation-ids.test.ts +204 -0
- package/src/__tests__/approval-cascade.test.ts +5 -5
- package/src/__tests__/approval-routes-http.test.ts +3 -3
- package/src/__tests__/ask-question-resolver.test.ts +207 -0
- package/src/__tests__/assistant-event-hub-self-exclusion.test.ts +16 -16
- package/src/__tests__/assistant-event-hub-targeted.test.ts +13 -11
- package/src/__tests__/assistant-event-hub.test.ts +13 -11
- package/src/__tests__/assistant-event.test.ts +12 -9
- package/src/__tests__/assistant-feature-flag-guard.test.ts +3 -3
- package/src/__tests__/assistant-feature-flag-guardrails.test.ts +1 -1
- package/src/__tests__/assistant-id-boundary-guard.test.ts +0 -58
- package/src/__tests__/assistant-stream-state.test.ts +17 -7
- package/src/__tests__/avatar-identity-sync.test.ts +3 -3
- package/src/__tests__/background-workers-disk-pressure.test.ts +1 -0
- package/src/__tests__/call-conversation-messages.test.ts +134 -18
- package/src/__tests__/call-start-guardian-guard.test.ts +27 -0
- package/src/__tests__/channel-approvals.test.ts +0 -27
- package/src/__tests__/channel-guardian.test.ts +85 -512
- package/src/__tests__/channel-readiness-slack-remote.test.ts +151 -3
- package/src/__tests__/channel-retry-sweep.test.ts +88 -1
- package/src/__tests__/channel-setup-panel-ack.test.ts +12 -9
- package/src/__tests__/chat-reveal-guard-priming.test.ts +31 -34
- package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +2 -2
- package/src/__tests__/compaction-events.test.ts +8 -8
- package/src/__tests__/config-loader-platform-defaults.test.ts +54 -28
- package/src/__tests__/config-model-image-provider.test.ts +20 -0
- package/src/__tests__/config-schema-memory-substrate.test.ts +306 -0
- package/src/__tests__/config-schema.test.ts +14 -2
- package/src/__tests__/config-set-platform-guard.test.ts +11 -12
- package/src/__tests__/config-sounds-sync.test.ts +4 -4
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +5 -0
- package/src/__tests__/context-search-memory-source.test.ts +1 -1
- package/src/__tests__/context-search-memory-v2-source.test.ts +6 -6
- package/src/__tests__/context-token-estimator.test.ts +54 -1
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +12 -3
- package/src/__tests__/conversation-agent-loop-fatal-cleanup.test.ts +13 -4
- package/src/__tests__/conversation-agent-loop-handlers-max-tokens.test.ts +4 -4
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +10 -1
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +22 -13
- package/src/__tests__/conversation-agent-loop.test.ts +39 -30
- package/src/__tests__/conversation-confirmation-signals.test.ts +14 -14
- package/src/__tests__/conversation-evictor.test.ts +49 -0
- package/src/__tests__/conversation-fork-crud.test.ts +1 -1
- package/src/__tests__/conversation-group-tools.test.ts +279 -0
- package/src/__tests__/conversation-history-web-search.test.ts +1 -1
- package/src/__tests__/conversation-key-store-disk-view.test.ts +5 -5
- package/src/__tests__/conversation-lineage.test.ts +235 -0
- package/src/__tests__/conversation-loop-db-lock-resilience.test.ts +5 -5
- package/src/__tests__/conversation-message-sync-tags.test.ts +4 -4
- package/src/__tests__/conversation-queue.test.ts +81 -81
- package/src/__tests__/conversation-routes-enabled-plugins.test.ts +8 -1
- package/src/__tests__/conversation-routes-hidden-queue.test.ts +8 -1
- package/src/__tests__/conversation-routes-slash-commands.test.ts +10 -1
- package/src/__tests__/conversation-runtime-assembly.test.ts +29 -2
- package/src/__tests__/conversation-slash-queue.test.ts +11 -11
- package/src/__tests__/conversation-slash-unknown.test.ts +2 -2
- package/src/__tests__/conversation-speed-override.test.ts +2 -2
- package/src/__tests__/conversation-summarize-route.test.ts +9 -0
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +18 -16
- package/src/__tests__/conversation-surfaces-activation-emit.test.ts +17 -17
- package/src/__tests__/conversation-surfaces-app-open.test.ts +7 -4
- package/src/__tests__/conversation-surfaces-data-persist.test.ts +7 -7
- package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +9 -9
- package/src/__tests__/conversation-surfaces-standalone.test.ts +12 -12
- package/src/__tests__/conversation-surfaces-state-update.test.ts +8 -5
- package/src/__tests__/conversation-surfaces-table-action.test.ts +6 -3
- package/src/__tests__/conversation-surfaces-task-progress.test.ts +46 -46
- package/src/__tests__/conversation-sync-tags.test.ts +5 -5
- package/src/__tests__/conversation-wait-for-idle.test.ts +2 -2
- package/src/__tests__/conversation-workspace-cache-state.test.ts +0 -4
- package/src/__tests__/conversation-workspace-injection.test.ts +0 -3
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +0 -3
- package/src/__tests__/copy-composer-tc-templates.test.ts +3 -131
- package/src/__tests__/credential-security-invariants.test.ts +1 -0
- package/src/__tests__/daemon-assistant-events.test.ts +14 -15
- package/src/__tests__/db-test-helpers.ts +13 -27
- package/src/__tests__/disk-pressure-routes.test.ts +12 -3
- package/src/__tests__/document-tool-security.test.ts +95 -0
- package/src/__tests__/drain-kick-guard.test.ts +232 -0
- package/src/__tests__/dynamic-skill-background-guard.test.ts +19 -6
- package/src/__tests__/emit-event-signal.test.ts +5 -6
- package/src/__tests__/encrypted-store-test-helpers.ts +10 -20
- package/src/__tests__/events-tail-route.test.ts +6 -4
- package/src/__tests__/feature-flag-test-helpers.ts +10 -20
- package/src/__tests__/file-edit-tool.test.ts +24 -4
- package/src/__tests__/file-list-tool.test.ts +2 -1
- package/src/__tests__/file-read-tool.test.ts +62 -10
- package/src/__tests__/file-write-tool.test.ts +24 -5
- package/src/__tests__/followup-tools.test.ts +58 -0
- package/src/__tests__/gateway-threshold-reader-mock.ts +99 -0
- package/src/__tests__/graph-extraction-event-date.test.ts +1 -1
- package/src/__tests__/guardian-question-mode.test.ts +42 -3
- package/src/__tests__/guardian-reply-router-answer-mode.test.ts +283 -0
- package/src/__tests__/guardian-vellum-destination-pinning.test.ts +221 -0
- package/src/__tests__/heartbeat-disk-pressure.test.ts +1 -0
- package/src/__tests__/heartbeat-service.test.ts +1 -0
- package/src/__tests__/helpers/native-web-search-harness.ts +10 -10
- package/src/__tests__/host-browser-proxy.test.ts +1 -1
- package/src/__tests__/host-file-edit-tool.test.ts +3 -3
- package/src/__tests__/host-file-read-tool.test.ts +2 -2
- package/src/__tests__/host-file-write-tool.test.ts +7 -3
- package/src/__tests__/host-shell-tool.test.ts +17 -5
- package/src/__tests__/host-transfer-pending-interactions.test.ts +8 -8
- package/src/__tests__/image-credentials.test.ts +65 -8
- package/src/__tests__/injection-block.test.ts +4 -4
- package/src/__tests__/injector-chain.test.ts +1 -1
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +2 -2
- package/src/__tests__/injector-registry-order-guard.test.ts +4 -9
- package/src/__tests__/injector-v3-suppression.test.ts +6 -4
- package/src/__tests__/lifecycle-memory-v2-seed.test.ts +27 -28
- package/src/__tests__/list-messages-page-latest.test.ts +2 -2
- package/src/__tests__/llm-usage-store.test.ts +67 -4
- package/src/__tests__/log-redact.test.ts +18 -0
- package/src/__tests__/managed-profile-guard.test.ts +27 -0
- package/src/__tests__/managed-skill-lifecycle.test.ts +2 -2
- package/src/__tests__/media-generate-image.test.ts +62 -11
- package/src/__tests__/memory-identity-context-parity.test.ts +1 -1
- package/src/__tests__/memory-jobs-worker-lanes.test.ts +9 -1
- package/src/__tests__/memory-retrieval-hook.test.ts +4 -4
- package/src/__tests__/notification-decision-strategy.test.ts +115 -11
- package/src/__tests__/notification-deep-link.test.ts +12 -12
- package/src/__tests__/notification-vellum-adapter.test.ts +8 -8
- package/src/__tests__/outbound-slack-persistence.test.ts +8 -8
- package/src/__tests__/path-policy.test.ts +315 -0
- package/src/__tests__/pending-interactions-resolved-event.test.ts +6 -6
- package/src/__tests__/persistence-layering-guard.test.ts +2 -2
- package/src/__tests__/pkb-autoinject.test.ts +1 -1
- package/src/__tests__/platform-bash-auto-approve.test.ts +1 -0
- package/src/__tests__/platform-callback-registration.test.ts +10 -10
- package/src/__tests__/plugin-event-hub-facade.test.ts +22 -15
- package/src/__tests__/plugin-import-boundary-guard.test.ts +15 -15
- package/src/__tests__/processing-flag-persist-failure.test.ts +0 -4
- package/src/__tests__/provider-platform-proxy-integration.test.ts +0 -1
- package/src/__tests__/rebuild-index-graph-nodes.test.ts +1 -1
- package/src/__tests__/request-secret-standalone-channel-gate.test.ts +5 -5
- package/src/__tests__/require-fresh-approval.test.ts +38 -38
- package/src/__tests__/resolve-app-id.test.ts +32 -0
- package/src/__tests__/run-due-schedules.test.ts +72 -1
- package/src/__tests__/runtime-events-sse-parity.test.ts +11 -10
- package/src/__tests__/runtime-events-sse.test.ts +1 -1
- package/src/__tests__/schedule-routes.test.ts +44 -5
- package/src/__tests__/schedule-store.test.ts +3 -3
- package/src/__tests__/schedule-tools.test.ts +176 -0
- package/src/__tests__/secret-prompt-log-hygiene.test.ts +3 -3
- package/src/__tests__/secret-prompter-channel-fallback.test.ts +3 -3
- package/src/__tests__/secret-response-routing.test.ts +3 -3
- package/src/__tests__/secret-routes-platform-proxy.test.ts +4 -7
- package/src/__tests__/secret-scanner.test.ts +36 -0
- package/src/__tests__/send-endpoint-busy.test.ts +7 -7
- package/src/__tests__/slack-required-scopes-mirror.test.ts +81 -0
- package/src/__tests__/starter-task-flow.test.ts +26 -3
- package/src/__tests__/subagent-call-site-routing.test.ts +2 -2
- package/src/__tests__/subagent-disposal.test.ts +40 -11
- package/src/__tests__/subagent-fork-notifications.test.ts +4 -4
- package/src/__tests__/subagent-fork-prompt-role.test.ts +3 -3
- package/src/__tests__/subagent-fork-spawn.test.ts +4 -4
- package/src/__tests__/subagent-manager-notify.test.ts +73 -14
- package/src/__tests__/subagent-notify-parent.test.ts +48 -4
- package/src/__tests__/subagent-spawn-and-await.test.ts +62 -14
- package/src/__tests__/subagent-tools.test.ts +64 -0
- package/src/__tests__/sync-message-contract.test.ts +3 -3
- package/src/__tests__/terminal-tools.test.ts +12 -3
- package/src/__tests__/test-preload.ts +9 -0
- package/src/__tests__/tool-approval-handler.test.ts +587 -43
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +7 -4
- package/src/__tests__/tool-executor.test.ts +116 -0
- package/src/__tests__/tool-grant-request-escalation.test.ts +5 -0
- package/src/__tests__/tool-preview-lifecycle.test.ts +32 -29
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +5 -5
- package/src/__tests__/tool-side-effects-slack-dm.test.ts +1 -0
- package/src/__tests__/tool-start-timestamp.test.ts +4 -4
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +9 -22
- package/src/__tests__/ui-choice-copy-surfaces.test.ts +13 -13
- package/src/__tests__/ui-work-result-surface.test.ts +3 -3
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +6 -6
- package/src/__tests__/voice-session-bridge.test.ts +44 -44
- package/src/__tests__/workspace-migration-134-image-generation-mode-to-provider.test.ts +284 -0
- package/src/__tests__/workspace-policy.test.ts +482 -2
- package/src/acp/__tests__/client-handler.test.ts +3 -3
- package/src/acp/__tests__/session-manager-persistence.test.ts +10 -10
- package/src/acp/__tests__/session-manager-resume.test.ts +7 -7
- package/src/acp/client-handler.ts +3 -3
- package/src/acp/session-manager.ts +8 -8
- package/src/api/events/subagent-event.ts +2 -2
- package/src/api/responses/memory-v2-activation-log.ts +2 -2
- package/src/api/responses/subagent-detail.ts +13 -0
- package/src/approvals/AGENTS.md +2 -0
- package/src/approvals/guardian-request-resolvers.ts +118 -24
- package/src/apps/app-store.ts +95 -4
- package/src/calls/__tests__/voice-control-protocol.test.ts +57 -0
- package/src/calls/__tests__/voice-session-bridge.test.ts +229 -7
- package/src/calls/__tests__/voice-triage-escalate.test.ts +3 -4
- package/src/calls/call-controller.ts +27 -27
- package/src/calls/call-conversation-messages.ts +58 -18
- package/src/calls/voice-control-protocol.ts +56 -0
- package/src/calls/voice-session-bridge.ts +178 -65
- package/src/calls/voice-triage-escalate.ts +2 -3
- package/src/channels/config.ts +8 -0
- package/src/channels/types.ts +1 -0
- package/src/cli/commands/config.ts +49 -13
- package/src/cli/commands/memory/index.help.ts +4 -2
- package/src/cli/commands/memory/memory-retrospective.ts +5 -0
- package/src/cli/commands/webhooks.help.ts +9 -4
- package/src/cli/lib/bundled-marketplace.json +12 -0
- package/src/cli.ts +2 -109
- package/src/config/__tests__/deployment-context-defaults.test.ts +9 -0
- package/src/config/__tests__/substrate-twin-shadowing.test.ts +191 -0
- package/src/config/assistant-feature-flags.ts +1 -1
- package/src/config/bundled-skills/conversation-groups/SKILL.md +29 -0
- package/src/config/bundled-skills/conversation-groups/TOOLS.json +58 -0
- package/src/config/bundled-skills/conversation-groups/tools/group-create.ts +12 -0
- package/src/config/bundled-skills/conversation-groups/tools/group-list.ts +12 -0
- package/src/config/bundled-skills/conversation-groups/tools/move-to-group.ts +12 -0
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +13 -7
- package/src/config/bundled-skills/schedule/SKILL.md +2 -0
- package/src/config/feature-flag-cache.ts +6 -16
- package/src/config/feature-flag-registry.json +14 -38
- package/src/config/loader.ts +7 -1
- package/src/config/memory-tier.ts +15 -10
- package/src/config/memory-v3-gate.test.ts +278 -1
- package/src/config/memory-v3-gate.ts +88 -26
- package/src/config/raw-config-utils.ts +1 -1
- package/src/config/schemas/__tests__/live-voice.test.ts +27 -16
- package/src/config/schemas/__tests__/memory-v3.test.ts +1 -0
- package/src/config/schemas/live-voice.ts +33 -7
- package/src/config/schemas/llm.ts +1 -0
- package/src/config/schemas/memory-retrospective.ts +13 -0
- package/src/config/schemas/memory-substrate.ts +183 -0
- package/src/config/schemas/memory-v2.ts +3 -2
- package/src/config/schemas/memory-v3.ts +11 -4
- package/src/config/schemas/memory.ts +35 -1
- package/src/config/schemas/services.ts +10 -2
- package/src/config/substrate-twin-shadowing.ts +195 -0
- package/src/config/webhook-routing.ts +67 -0
- package/src/context/compactor.ts +10 -3
- package/src/context/token-estimator.ts +21 -0
- package/src/daemon/__tests__/channel-ui-capability.test.ts +85 -0
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +3 -3
- package/src/daemon/__tests__/embedding-reconcile.test.ts +3 -3
- package/src/daemon/__tests__/inference-profile-notification.test.ts +3 -6
- package/src/daemon/__tests__/native-web-search-metadata.test.ts +5 -5
- package/src/daemon/__tests__/web-search-status-text.test.ts +2 -2
- package/src/daemon/channel-ui-capability.ts +70 -1
- package/src/daemon/conversation-agent-loop-handlers.ts +4 -4
- package/src/daemon/conversation-agent-loop.ts +12 -5
- package/src/daemon/conversation-evictor.ts +26 -4
- package/src/daemon/conversation-launch.ts +11 -14
- package/src/daemon/conversation-lineage.ts +76 -0
- package/src/daemon/conversation-messaging.ts +14 -14
- package/src/daemon/conversation-notifiers.ts +2 -2
- package/src/daemon/conversation-process.ts +133 -21
- package/src/daemon/conversation-queue-manager.ts +7 -7
- package/src/daemon/conversation-runtime-assembly.ts +16 -0
- package/src/daemon/conversation-store.ts +11 -3
- package/src/daemon/conversation-surfaces.ts +8 -14
- package/src/daemon/conversation-tool-setup.ts +13 -7
- package/src/daemon/conversation-usage.ts +12 -11
- package/src/daemon/conversation.ts +38 -15
- package/src/daemon/disk-pressure-guard.ts +5 -12
- package/src/daemon/embedding-reconcile.ts +14 -9
- package/src/daemon/handlers/config-channels.ts +40 -134
- package/src/daemon/handlers/config-model.ts +15 -7
- package/src/daemon/handlers/conversations.ts +4 -2
- package/src/daemon/handlers/shared.ts +29 -0
- package/src/daemon/host-proxy-base.ts +4 -4
- package/src/daemon/lifecycle.ts +13 -0
- package/src/daemon/message-protocol.ts +8 -144
- package/src/daemon/message-types/computer-use.ts +0 -12
- package/src/daemon/message-types/conversations.ts +9 -345
- package/src/daemon/message-types/host-app-control.ts +0 -9
- package/src/daemon/message-types/host-browser.ts +0 -7
- package/src/daemon/message-types/host-ui-snapshot.ts +0 -7
- package/src/daemon/message-types/messages.ts +0 -48
- package/src/daemon/message-types/notifications.ts +0 -7
- package/src/daemon/message-types/skills.ts +0 -5
- package/src/daemon/message-types/surfaces.ts +0 -9
- package/src/daemon/message-types/sync.ts +0 -2
- package/src/daemon/process-message.ts +5 -5
- package/src/daemon/skill-memory-refresh.ts +5 -5
- package/src/daemon/tool-side-effects.ts +32 -16
- package/src/daemon/trust-context.ts +1 -1
- package/src/daemon/wake-conversation-ops.ts +4 -4
- package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +100 -7
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +67 -0
- package/src/heartbeat/heartbeat-run-store.ts +81 -4
- package/src/heartbeat/heartbeat-service.ts +32 -1
- package/src/home/__tests__/feed-writer.test.ts +7 -7
- package/src/home/__tests__/home-content-refresh.test.ts +3 -0
- package/src/home/__tests__/suggested-prompts.test.ts +1 -0
- package/src/home/feed-writer.ts +6 -13
- package/src/home/home-content-refresh.ts +6 -9
- package/src/home/relationship-state-writer.ts +5 -12
- package/src/home/suggested-prompts-cache.ts +6 -19
- package/src/ipc/__tests__/events-publish-client.test.ts +67 -0
- package/src/ipc/events-publish-client.ts +44 -0
- package/src/ipc/routes/__tests__/conversation-sync-ipc-routes.test.ts +2 -2
- package/src/ipc/routes/__tests__/events-ipc-routes.test.ts +38 -9
- package/src/ipc/routes/events-ipc-routes.ts +11 -31
- package/src/live-voice/__tests__/front-decision.test.ts +4 -176
- package/src/live-voice/__tests__/live-voice-agent-turn.test.ts +276 -68
- package/src/live-voice/__tests__/live-voice-continuation-fork-hydration.test.ts +286 -0
- package/src/live-voice/__tests__/live-voice-events.test.ts +6 -3
- package/src/live-voice/__tests__/live-voice-progress.test.ts +185 -46
- package/src/live-voice/__tests__/live-voice-triage-escalate.test.ts +24 -59
- package/src/live-voice/__tests__/live-voice-tts-session.test.ts +38 -54
- package/src/live-voice/__tests__/live-voice-vad.test.ts +1154 -636
- package/src/live-voice/front-decision.ts +5 -155
- package/src/live-voice/live-voice-metrics.ts +4 -1
- package/src/live-voice/live-voice-session.ts +1288 -439
- package/src/live-voice/progress-phrases.ts +17 -0
- package/src/live-voice/protocol.ts +15 -0
- package/src/media/app-icon-generator.ts +15 -8
- package/src/media/avatar-router.ts +9 -5
- package/src/media/image-credentials.ts +42 -10
- package/src/media/image-service.ts +1 -13
- package/src/media/types.ts +26 -3
- package/src/notifications/AGENTS.md +2 -0
- package/src/notifications/__tests__/broadcaster.test.ts +95 -0
- package/src/notifications/adapters/macos.ts +3 -3
- package/src/notifications/broadcaster.ts +57 -0
- package/src/notifications/copy-composer.ts +0 -15
- package/src/notifications/decision-engine.ts +21 -22
- package/src/notifications/guardian-question-mode.ts +57 -2
- package/src/notifications/home-feed-side-effect.ts +4 -0
- package/src/notifications/signal.ts +6 -4
- package/src/notifications/trusted-contact-payloads.ts +3 -4
- package/src/notifications/vellum-card-affinity.ts +39 -0
- package/src/oauth/AGENTS.md +1 -1
- package/src/permissions/channel-permission-query.test.ts +69 -0
- package/src/permissions/channel-permission-query.ts +73 -1
- package/src/permissions/checker.test.ts +298 -15
- package/src/permissions/checker.ts +102 -36
- package/src/permissions/confirmation-guardian-request.test.ts +2 -2
- package/src/permissions/confirmation-guardian-request.ts +2 -2
- package/src/permissions/gateway-threshold-reader.test.ts +224 -17
- package/src/permissions/gateway-threshold-reader.ts +82 -10
- package/src/permissions/ipc-risk-types.ts +8 -0
- package/src/permissions/prompter.ts +5 -5
- package/src/permissions/question-guardian-request.test.ts +222 -0
- package/src/permissions/question-guardian-request.ts +179 -0
- package/src/permissions/question-prompter.test.ts +8 -8
- package/src/permissions/question-prompter.ts +18 -0
- package/src/permissions/secret-prompter.ts +2 -4
- package/src/permissions/workspace-policy.ts +269 -34
- package/src/persistence/__tests__/lifecycle-quiesce.test.ts +82 -0
- package/src/persistence/__tests__/message-content-file.test.ts +58 -3
- package/src/persistence/conversation-crud.ts +93 -0
- package/src/persistence/conversation-key-store.ts +63 -0
- package/src/persistence/conversation-parent.ts +27 -0
- package/src/persistence/db-async-query.ts +1 -1
- package/src/persistence/db-singleton.ts +14 -27
- package/src/persistence/delivery-crud.ts +45 -0
- package/src/persistence/embeddings/embedding-backend.ts +2 -1
- package/src/persistence/embeddings/embedding-identity.ts +7 -3
- package/src/persistence/job-utils.ts +32 -27
- package/src/persistence/jobs-store.ts +92 -3
- package/src/persistence/lifecycle-quiesce.ts +80 -0
- package/src/persistence/llm-usage-store.ts +45 -8
- package/src/persistence/message-content-file.ts +4 -4
- package/src/persistence/migrations/336-move-memory-v2-activation-logs-to-memory-db.ts +1 -1
- package/src/persistence/migrations/351-schedule-skill-script-handoff.ts +39 -0
- package/src/persistence/migrations/352-drop-schedule-skill-script-handoff.test.ts +83 -0
- package/src/persistence/migrations/352-drop-schedule-skill-script-handoff.ts +36 -0
- package/src/persistence/migrations/353-add-llm-usage-conversation-type.test.ts +110 -0
- package/src/persistence/migrations/353-add-llm-usage-conversation-type.ts +49 -0
- package/src/persistence/migrations/354-backfill-app-conversation-lineage.ts +41 -0
- package/src/persistence/schema/infrastructure.ts +11 -0
- package/src/persistence/steps.ts +9 -1
- package/src/plugin-api/__tests__/publish-event-forwarding.test.ts +113 -0
- package/src/plugin-api/__tests__/publish-event.test.ts +57 -0
- package/src/plugin-api/conversation-turn.ts +4 -4
- package/src/plugin-api/event-hub-facade.ts +15 -6
- package/src/plugin-api/index.ts +10 -4
- package/src/plugin-api/publish-event.ts +36 -0
- package/src/plugins/AGENTS.md +2 -0
- package/src/plugins/defaults/compaction/window-manager.ts +9 -0
- package/src/plugins/defaults/index.ts +9 -13
- package/src/plugins/defaults/memory/AGENTS.md +775 -0
- package/src/plugins/defaults/memory/__tests__/capability-seed-embed-gate.test.ts +186 -0
- package/src/plugins/defaults/memory/__tests__/fixtures/memory-v2-activation-fixtures.ts +1 -1
- package/src/plugins/defaults/memory/__tests__/indexer-tier-dispatch.test.ts +129 -0
- package/src/plugins/defaults/memory/__tests__/jobs-worker-quiesce-gate.test.ts +91 -0
- package/src/plugins/defaults/memory/__tests__/jobs-worker-v1-graph-substrate-noop.test.ts +342 -0
- package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-graph-trigger-embed.test.ts +9 -1
- package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-schedule.test.ts +36 -1
- package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-sweep-defer.test.ts +9 -1
- package/src/plugins/defaults/memory/__tests__/memory-log-stores-degraded.test.ts +2 -2
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +44 -10
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-sweep.test.ts +151 -10
- package/src/plugins/defaults/memory/__tests__/memory-tier-boundary-guard.test.ts +1155 -0
- package/src/plugins/defaults/memory/__tests__/memory-v2-activation-log-store.test.ts +1 -1
- package/src/plugins/defaults/memory/__tests__/memory-v2-concept-frequency.test.ts +3 -3
- package/src/plugins/defaults/memory/__tests__/tools-delete-memory-page.test.ts +1 -1
- package/src/plugins/defaults/memory/context-search/sources/memory-v2.ts +71 -35
- package/src/plugins/defaults/memory/context-search/sources/memory.ts +5 -1
- package/src/plugins/defaults/memory/fork-conversation-memory.ts +4 -4
- package/src/plugins/defaults/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +80 -10
- package/src/plugins/defaults/memory/graph/__tests__/handle-remember-v2.test.ts +1 -1
- package/src/plugins/defaults/memory/graph/capability-seed.ts +24 -10
- package/src/plugins/defaults/memory/graph/conversation-graph-memory.ts +123 -49
- package/src/plugins/defaults/memory/graph/graph-search.ts +6 -118
- package/src/plugins/defaults/memory/graph/in-context-tracker.test.ts +173 -0
- package/src/plugins/defaults/memory/graph/in-context-tracker.ts +109 -0
- package/src/plugins/defaults/memory/graph/store.ts +1 -0
- package/src/plugins/defaults/memory/graph/tool-handlers.test.ts +1 -1
- package/src/plugins/defaults/memory/graph/tool-handlers.ts +5 -2
- package/src/plugins/defaults/memory/graph-topology/__tests__/build-memory-graph.test.ts +1 -1
- package/src/plugins/defaults/memory/graph-topology/build-memory-graph.ts +6 -9
- package/src/plugins/defaults/memory/hooks/__tests__/user-prompt-submit.test.ts +30 -16
- package/src/plugins/defaults/memory/hooks/user-prompt-submit.ts +18 -14
- package/src/plugins/defaults/memory/indexer.ts +146 -89
- package/src/plugins/defaults/memory/injectors.ts +86 -41
- package/src/plugins/defaults/memory/job-handlers.ts +130 -39
- package/src/plugins/defaults/memory/jobs/__tests__/embed-concept-page.test.ts +2 -2
- package/src/plugins/defaults/memory/jobs/embed-concept-page.ts +22 -10
- package/src/plugins/defaults/memory/jobs-worker.ts +279 -208
- package/src/plugins/defaults/memory/memory-retrospective-enqueue.ts +4 -2
- package/src/plugins/defaults/memory/memory-retrospective-job.ts +40 -3
- package/src/plugins/defaults/memory/memory-retrospective-sweep.ts +99 -11
- package/src/plugins/defaults/memory/src/__tests__/memory-v2-routes.test.ts +5 -3
- package/src/plugins/defaults/memory/src/__tests__/memory-v2-simulate-route.test.ts +3 -4
- package/src/plugins/defaults/memory/src/memory-graph-routes.ts +2 -1
- package/src/plugins/defaults/memory/src/memory-item-routes.test.ts +7 -5
- package/src/plugins/defaults/memory/src/memory-item-routes.ts +51 -19
- package/src/plugins/defaults/memory/src/memory-v2-routes.ts +31 -20
- package/src/plugins/defaults/memory/startup.ts +58 -21
- package/src/plugins/defaults/memory/substrate/__tests__/boot-maintenance.test.ts +335 -0
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/cli-command-store.test.ts +14 -8
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/consolidation-job.test.ts +51 -21
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/edge-index.test.ts +1 -1
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/frontmatter-sweep.test.ts +3 -3
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/page-index.test.ts +1 -1
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/page-store.test.ts +1 -1
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/prompts-consolidation.test.ts +2 -2
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/qdrant.test.ts +23 -14
- package/src/plugins/defaults/memory/substrate/__tests__/reembed-job.test.ts +262 -0
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/sim.test.ts +9 -12
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/skill-content.test.ts +2 -2
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/skill-store.test.ts +9 -9
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/sparse-bm25.test.ts +12 -5
- package/src/plugins/defaults/memory/substrate/__tests__/spread.test.ts +276 -0
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/static-context.test.ts +17 -8
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/sweep-job.test.ts +9 -9
- package/src/plugins/defaults/memory/{v3/substrate/memory-v2-startup.ts → substrate/boot-maintenance.ts} +43 -24
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/cli-command-store.ts +13 -8
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/consolidation-job.ts +51 -27
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/constants.ts +1 -0
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/edge-index.ts +28 -9
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/frontmatter-sweep.ts +14 -7
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/injected-block-slugs.ts +9 -3
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/page-index.ts +29 -10
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/page-store.ts +35 -12
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/prompts/consolidation.ts +14 -8
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/prompts/sweep.ts +4 -1
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/qdrant.ts +96 -36
- package/src/plugins/defaults/memory/substrate/reembed-job.ts +54 -0
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/sim.ts +26 -15
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/skill-content.ts +1 -1
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/skill-store.ts +13 -8
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/sparse-bm25.ts +27 -10
- package/src/plugins/defaults/memory/substrate/spread.ts +165 -0
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/static-context.ts +12 -7
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/sweep-job.ts +20 -15
- package/src/plugins/defaults/memory/substrate/tuning.ts +93 -0
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/types.ts +7 -4
- package/src/plugins/defaults/memory/tools.test.ts +1 -1
- package/src/plugins/defaults/memory/tools.ts +1 -1
- package/src/plugins/defaults/memory/v1/README.md +5 -0
- package/src/plugins/defaults/memory/{__tests__ → v1/__tests__}/filing-jobs.test.ts +4 -4
- package/src/plugins/defaults/memory/{filing-jobs.ts → v1/filing-jobs.ts} +3 -3
- package/src/plugins/defaults/memory/{graph → v1/graph}/bootstrap.test.ts +68 -6
- package/src/plugins/defaults/memory/{graph → v1/graph}/bootstrap.ts +40 -21
- package/src/plugins/defaults/memory/{graph → v1/graph}/consolidation.ts +14 -14
- package/src/plugins/defaults/memory/{graph → v1/graph}/decay.test.ts +1 -1
- package/src/plugins/defaults/memory/{graph → v1/graph}/decay.ts +3 -3
- package/src/plugins/defaults/memory/{graph → v1/graph}/extraction-job.ts +5 -5
- package/src/plugins/defaults/memory/{graph → v1/graph}/extraction.test.ts +1 -1
- package/src/plugins/defaults/memory/{graph → v1/graph}/extraction.ts +20 -14
- package/src/plugins/defaults/memory/{graph → v1/graph}/graph-search.test.ts +3 -3
- package/src/plugins/defaults/memory/v1/graph/graph-search.ts +123 -0
- package/src/plugins/defaults/memory/{graph → v1/graph}/injection.test.ts +1 -118
- package/src/plugins/defaults/memory/{graph → v1/graph}/injection.ts +9 -111
- package/src/plugins/defaults/memory/{graph → v1/graph}/narrative.ts +6 -6
- package/src/plugins/defaults/memory/{graph → v1/graph}/pattern-scan.ts +5 -5
- package/src/plugins/defaults/memory/{graph → v1/graph}/retriever.test.ts +135 -42
- package/src/plugins/defaults/memory/{graph → v1/graph}/retriever.ts +40 -22
- package/src/plugins/defaults/memory/{graph → v1/graph}/scoring.test.ts +1 -1
- package/src/plugins/defaults/memory/{graph → v1/graph}/scoring.ts +1 -1
- package/src/plugins/defaults/memory/{graph → v1/graph}/serendipity.ts +1 -1
- package/src/plugins/defaults/memory/{graph → v1/graph}/triggers.test.ts +1 -1
- package/src/plugins/defaults/memory/{graph → v1/graph}/triggers.ts +1 -1
- package/src/plugins/defaults/memory/{identity-context.ts → v1/identity-context.ts} +4 -4
- package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/backfill.ts +6 -6
- package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/embedding.test.ts +6 -6
- package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/embedding.ts +6 -6
- package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/index-maintenance.ts +8 -8
- package/src/plugins/defaults/memory/{jobs → v1/jobs}/embed-pkb-file.test.ts +7 -7
- package/src/plugins/defaults/memory/{jobs → v1/jobs}/embed-pkb-file.ts +5 -5
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/autoinject.ts +1 -1
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/context.ts +2 -2
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-index.test.ts +3 -3
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-index.ts +2 -2
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-reconcile.test.ts +3 -3
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-reconcile.ts +2 -2
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-search.test.ts +3 -3
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-search.ts +6 -6
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/types.ts +3 -5
- package/src/plugins/defaults/memory/{pkb-schedule.ts → v1/pkb-schedule.ts} +2 -2
- package/src/plugins/defaults/memory/{search/semantic.ts → v1/semantic-search.ts} +1 -1
- package/src/plugins/defaults/memory/v2/__tests__/activation-store.test.ts +1 -1
- package/src/plugins/defaults/memory/v2/__tests__/activation.test.ts +11 -274
- package/src/plugins/defaults/memory/v2/__tests__/backfill-jobs.test.ts +9 -131
- package/src/plugins/defaults/memory/v2/__tests__/harness-compare.test.ts +1 -1
- package/src/plugins/defaults/memory/v2/__tests__/harness-oracle.test.ts +1 -1
- package/src/plugins/defaults/memory/v2/__tests__/harness-replay-input.test.ts +1 -1
- package/src/plugins/defaults/memory/v2/__tests__/injection.test.ts +14 -10
- package/src/plugins/defaults/memory/v2/__tests__/reranker.test.ts +7 -5
- package/src/plugins/defaults/memory/v2/__tests__/router.test.ts +12 -6
- package/src/plugins/defaults/memory/{memory-v2-activation-log-store.ts → v2/activation-log-store.ts} +2 -2
- package/src/plugins/defaults/memory/v2/activation-store.ts +22 -8
- package/src/plugins/defaults/memory/v2/activation.ts +30 -163
- package/src/plugins/defaults/memory/v2/backfill-jobs.ts +7 -54
- package/src/plugins/defaults/memory/{memory-v2-concept-frequency.ts → v2/concept-frequency.ts} +3 -3
- package/src/plugins/defaults/memory/v2/harness/oracle.ts +1 -1
- package/src/plugins/defaults/memory/v2/harness/replay-input.ts +2 -2
- package/src/plugins/defaults/memory/v2/harness/retriever.ts +1 -1
- package/src/plugins/defaults/memory/v2/injection.ts +36 -26
- package/src/plugins/defaults/memory/v2/migration.ts +2 -2
- package/src/plugins/defaults/memory/{rerank-local.ts → v2/rerank-local.ts} +44 -18
- package/src/plugins/defaults/memory/v2/reranker.ts +29 -11
- package/src/plugins/defaults/memory/v2/router.ts +38 -15
- package/src/plugins/defaults/memory/v3/__tests__/candidate-match.test.ts +5 -3
- package/src/plugins/defaults/memory/v3/__tests__/carry-integration.test.ts +21 -8
- package/src/plugins/defaults/memory/v3/__tests__/edge.test.ts +1 -1
- package/src/plugins/defaults/memory/v3/__tests__/live-integration.test.ts +1 -1
- package/src/plugins/defaults/memory/v3/__tests__/maintain-job.test.ts +4 -1
- package/src/plugins/defaults/memory/v3/__tests__/orchestrate.test.ts +181 -3
- package/src/plugins/defaults/memory/v3/__tests__/selection-log-store.test.ts +3 -0
- package/src/plugins/defaults/memory/v3/__tests__/shadow-integration.test.ts +14 -5
- package/src/plugins/defaults/memory/v3/__tests__/shadow-plugin.test.ts +40 -50
- package/src/plugins/defaults/memory/v3/__tests__/tuning-profile.test.ts +1 -0
- package/src/plugins/defaults/memory/v3/candidate-match.ts +2 -2
- package/src/plugins/defaults/memory/v3/capabilities.ts +6 -4
- package/src/plugins/defaults/memory/v3/card.ts +25 -9
- package/src/plugins/defaults/memory/v3/edge.ts +52 -18
- package/src/plugins/defaults/memory/v3/gate.ts +4 -4
- package/src/plugins/defaults/memory/v3/injector.ts +10 -3
- package/src/plugins/defaults/memory/v3/maintain-job.ts +3 -3
- package/src/plugins/defaults/memory/v3/orchestrate.ts +100 -18
- package/src/plugins/defaults/memory/v3/page-content.ts +26 -10
- package/src/plugins/defaults/memory/v3/prune.ts +40 -16
- package/src/plugins/defaults/memory/v3/selection-log-store.ts +34 -12
- package/src/plugins/defaults/memory/v3/shadow-plugin.ts +9 -13
- package/src/plugins/defaults/memory/v3/span-query.test.ts +86 -0
- package/src/plugins/defaults/memory/v3/span-query.ts +71 -0
- package/src/plugins/defaults/memory/v3/tuning-profile.ts +3 -0
- package/src/plugins/defaults/memory/v3/types.ts +4 -1
- package/src/plugins/defaults/memory/v3-eval/eval-packets.ts +2 -2
- package/src/plugins/defaults/memory/validation.ts +1 -1
- package/src/plugins/defaults/memory/worker.ts +2 -1
- package/src/plugins/defaults/platform-hosted/__tests__/reengage.test.ts +104 -12
- package/src/plugins/defaults/platform-hosted/routes/reengage.ts +104 -12
- package/src/plugins/types.ts +2 -2
- package/src/prompts/sections.ts +4 -16
- package/src/providers/__tests__/registry-native-web-search.test.ts +47 -2
- package/src/providers/anthropic/client.ts +15 -6
- package/src/providers/content-block-schema.ts +26 -0
- package/src/providers/inference/__tests__/connections-credential-normalize.test.ts +87 -0
- package/src/providers/inference/adapter-factory.ts +6 -0
- package/src/providers/inference/connections.ts +30 -14
- package/src/providers/model-catalog.ts +77 -0
- package/src/providers/openai/__tests__/chat-completions-input-audio.test.ts +260 -0
- package/src/providers/openai/chat-completions-provider.ts +65 -17
- package/src/providers/openai/input-audio.ts +76 -0
- package/src/providers/openrouter/client.ts +0 -2
- package/src/providers/platform-proxy/constants.ts +4 -0
- package/src/providers/poolside/client.ts +42 -0
- package/src/providers/registry.ts +40 -8
- package/src/providers/retry.ts +2 -0
- package/src/providers/types.ts +39 -1
- package/src/providers/vercel-ai-gateway/client.ts +0 -2
- package/src/runtime/AGENTS.md +7 -5
- package/src/runtime/__tests__/question-request-guardian-bridge.test.ts +173 -0
- package/src/runtime/__tests__/question-resolution.test.ts +111 -0
- package/src/runtime/access-request-helper.ts +7 -15
- package/src/runtime/assistant-event-hub.ts +43 -31
- package/src/runtime/assistant-event-publish-options.ts +31 -0
- package/src/runtime/assistant-event.ts +19 -30
- package/src/runtime/assistant-stream-state.ts +4 -4
- package/src/runtime/channel-approvals.ts +0 -25
- package/src/runtime/channel-readiness-service.ts +99 -40
- package/src/runtime/channel-retry-sweep.ts +38 -15
- package/src/runtime/confirmation-request-guardian-bridge.ts +4 -0
- package/src/runtime/guardian-reply-router.ts +108 -0
- package/src/runtime/http-server.ts +8 -0
- package/src/runtime/http-types.ts +2 -2
- package/src/runtime/process-role.ts +42 -0
- package/src/runtime/question-request-guardian-bridge.ts +184 -0
- package/src/runtime/question-resolution.ts +153 -0
- package/src/runtime/routes/__tests__/bookmark-routes.test.ts +6 -2
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/subagents-routes.test.ts +250 -0
- package/src/runtime/routes/__tests__/webhook-routes.test.ts +201 -0
- package/src/runtime/routes/acp-routes.ts +2 -2
- package/src/runtime/routes/bookmark-routes.ts +3 -15
- package/src/runtime/routes/canned-message-complete.ts +2 -2
- package/src/runtime/routes/consolidation-routes.ts +8 -2
- package/src/runtime/routes/conversation-list-routes.ts +3 -19
- package/src/runtime/routes/conversation-management-routes.ts +1 -5
- package/src/runtime/routes/conversation-query-routes.ts +52 -8
- package/src/runtime/routes/conversation-routes.ts +36 -22
- package/src/runtime/routes/credential-request-routes.ts +0 -1
- package/src/runtime/routes/filing-routes.ts +7 -7
- package/src/runtime/routes/global-search-routes.ts +1 -1
- package/src/runtime/routes/guardian-approval-prompt.ts +2 -2
- package/src/runtime/routes/image-generation-routes.ts +12 -9
- package/src/runtime/routes/inbound-message-handler.ts +17 -0
- package/src/runtime/routes/inbound-stages/acl-enforcement.test.ts +50 -0
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +19 -0
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +4 -4
- package/src/runtime/routes/inbound-stages/inbound-content-prep.test.ts +129 -0
- package/src/runtime/routes/inbound-stages/inbound-content-prep.ts +141 -9
- package/src/runtime/routes/index.ts +2 -0
- package/src/runtime/routes/lifecycle-routes.ts +199 -0
- package/src/runtime/routes/platform-routes.ts +3 -8
- package/src/runtime/routes/playground/__tests__/inject-failures.test.ts +7 -7
- package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +5 -5
- package/src/runtime/routes/question-routes.ts +34 -87
- package/src/runtime/routes/secret-routes.ts +11 -1
- package/src/runtime/routes/settings-routes.ts +8 -18
- package/src/runtime/routes/subagents-routes.ts +35 -8
- package/src/runtime/routes/upgrade-broadcast-routes.ts +4 -5
- package/src/runtime/routes/webhook-routes.ts +89 -30
- package/src/runtime/routes/workspace-routes.test.ts +7 -4
- package/src/runtime/slack-reply-session.test.ts +12 -12
- package/src/runtime/slack-reply-session.ts +17 -17
- package/src/runtime/sync/sync-publisher.test.ts +7 -5
- package/src/runtime/tool-grant-request-helper.ts +4 -0
- package/src/schedule/schedule-store.ts +70 -0
- package/src/schedule/scheduler.ts +27 -0
- package/src/security/AGENTS.md +1 -1
- package/src/security/credential-key.ts +17 -0
- package/src/security/secret-ingress.ts +14 -105
- package/src/security/secret-patterns.ts +8 -139
- package/src/security/secret-scanner.ts +8 -3
- package/src/security/store-path-override.ts +6 -16
- package/src/sequence/store.ts +8 -0
- package/src/signals/emit-event.ts +5 -10
- package/src/signals/event-stream.ts +20 -10
- package/src/subagent/manager.ts +76 -25
- package/src/subagent/notify.ts +8 -0
- package/src/subagent/types.ts +13 -3
- package/src/telegram/__tests__/webhook-health.test.ts +442 -0
- package/src/telegram/webhook-health.ts +478 -0
- package/src/telemetry/AGENTS.md +6 -0
- package/src/telemetry/memory-corpus-size.test.ts +129 -0
- package/src/telemetry/memory-corpus-size.ts +184 -0
- package/src/telemetry/memory-tier-reporter.test.ts +67 -2
- package/src/telemetry/memory-tier-reporter.ts +30 -3
- package/src/tools/__tests__/conversation-group-tool-input-schemas.test.ts +61 -0
- package/src/tools/__tests__/document-tool-input-schemas.test.ts +103 -0
- package/src/tools/__tests__/followup-call-acp-tool-input-schemas.test.ts +125 -0
- package/src/tools/__tests__/schedule-tool-input-schemas.test.ts +83 -0
- package/src/tools/__tests__/subagent-workflow-tool-input-schemas.test.ts +116 -0
- package/src/tools/__tests__/tool-input-schemas.test.ts +192 -0
- package/src/tools/__tests__/tool-schema-drift-harness.ts +142 -0
- package/src/tools/acp/abort.ts +21 -1
- package/src/tools/acp/context.ts +5 -5
- package/src/tools/acp/spawn.test.ts +15 -5
- package/src/tools/acp/spawn.ts +26 -3
- package/src/tools/acp/status.ts +20 -1
- package/src/tools/acp/steer.test.ts +20 -0
- package/src/tools/acp/steer.ts +23 -2
- package/src/tools/apps/resolve-app-id.ts +15 -3
- package/src/tools/ask-question/ask-question-tool.test.ts +65 -0
- package/src/tools/ask-question/ask-question-tool.ts +68 -92
- package/src/tools/browser/browser-screencast.ts +6 -6
- package/src/tools/calls/call-end.ts +24 -3
- package/src/tools/calls/call-start.ts +35 -11
- package/src/tools/calls/call-status.ts +20 -1
- package/src/tools/conversation-groups/group_create.ts +63 -0
- package/src/tools/conversation-groups/group_list.ts +20 -0
- package/src/tools/conversation-groups/group_shared.ts +52 -0
- package/src/tools/conversation-groups/move_to_group.ts +106 -0
- package/src/tools/document/document-comment-tool.test.ts +49 -0
- package/src/tools/document/document-comment-tool.ts +45 -6
- package/src/tools/document/document-tool.ts +142 -24
- package/src/tools/executor.ts +27 -13
- package/src/tools/filesystem/edit.ts +62 -60
- package/src/tools/filesystem/list.ts +36 -29
- package/src/tools/filesystem/read.ts +56 -39
- package/src/tools/filesystem/write.ts +44 -38
- package/src/tools/followups/followup_create.ts +41 -12
- package/src/tools/followups/followup_list.ts +34 -6
- package/src/tools/followups/followup_resolve.ts +26 -4
- package/src/tools/host-filesystem/edit.ts +50 -60
- package/src/tools/host-filesystem/read.ts +45 -39
- package/src/tools/host-filesystem/write.ts +31 -36
- package/src/tools/host-terminal/host-shell.ts +76 -62
- package/src/tools/policy-context.ts +27 -10
- package/src/tools/schedule/create.ts +76 -33
- package/src/tools/schedule/delete.ts +21 -2
- package/src/tools/schedule/list.ts +25 -3
- package/src/tools/schedule/update.ts +105 -48
- package/src/tools/shared/filesystem/path-policy.ts +246 -40
- package/src/tools/shared/zod-tool-schema.ts +117 -0
- package/src/tools/subagent/abort.ts +12 -4
- package/src/tools/subagent/consult-deadline.ts +9 -3
- package/src/tools/subagent/message.ts +21 -5
- package/src/tools/subagent/notify-parent.ts +44 -23
- package/src/tools/subagent/read.ts +15 -4
- package/src/tools/subagent/resolve.ts +26 -4
- package/src/tools/subagent/spawn.ts +37 -13
- package/src/tools/subagent/status.ts +12 -4
- package/src/tools/system/request-permission.ts +35 -26
- package/src/tools/terminal/shell.ts +68 -55
- package/src/tools/tool-approval-handler.ts +327 -53
- package/src/tools/tool-input-schemas.ts +85 -0
- package/src/tools/tool-types.ts +7 -0
- package/src/tools/types.ts +8 -0
- package/src/tools/workflows/manage-workflows.ts +30 -2
- package/src/tools/workflows/run-workflow.test.ts +54 -2
- package/src/tools/workflows/run-workflow.ts +32 -4
- package/src/util/fs-symlinks.ts +30 -0
- package/src/util/log-redact.ts +7 -3
- package/src/util/platform.ts +15 -0
- package/src/vellum-assistant-namespace.d.ts +80 -0
- package/src/watcher/watcher-store.ts +8 -0
- package/src/workflows/leaf-runner.test.ts +104 -2
- package/src/workflows/leaf-runner.ts +31 -6
- package/src/workspace/migrations/070-memory-v2-summary-schema-rebuild.ts +2 -2
- package/src/workspace/migrations/134-image-generation-mode-to-provider.ts +128 -0
- package/src/workspace/migrations/135-copy-substrate-tunables.ts +248 -0
- package/src/workspace/migrations/__tests__/135-copy-substrate-tunables.test.ts +446 -0
- package/src/workspace/migrations/__tests__/backfill-v3-leaves.test.ts +2 -2
- package/src/workspace/migrations/registry.ts +4 -0
- package/tsconfig.plugin-api.json +1 -1
- package/src/__tests__/memory-retrieval-budget.test.ts +0 -49
- package/src/__tests__/secret-patterns.test.ts +0 -27
- package/src/config/__tests__/proc-to-skills.test.ts +0 -21
- package/src/config/memory-tier.test.ts +0 -44
- package/src/daemon/message-types/acp.ts +0 -20
- package/src/daemon/message-types/apps.ts +0 -11
- package/src/daemon/message-types/background-tools.ts +0 -14
- package/src/daemon/message-types/bookmarks.ts +0 -13
- package/src/daemon/message-types/contacts.ts +0 -13
- package/src/daemon/message-types/document-comments.ts +0 -14
- package/src/daemon/message-types/documents.ts +0 -13
- package/src/daemon/message-types/home.ts +0 -15
- package/src/daemon/message-types/host-bash.ts +0 -12
- package/src/daemon/message-types/host-cu.ts +0 -10
- package/src/daemon/message-types/host-file.ts +0 -12
- package/src/daemon/message-types/host-transfer.ts +0 -12
- package/src/daemon/message-types/integrations.ts +0 -90
- package/src/daemon/message-types/memory.ts +0 -10
- package/src/daemon/message-types/schedules.ts +0 -14
- package/src/daemon/message-types/settings.ts +0 -17
- package/src/daemon/message-types/subagents.ts +0 -63
- package/src/daemon/message-types/upgrades.ts +0 -14
- package/src/daemon/message-types/workflows.ts +0 -25
- package/src/daemon/message-types/workspace.ts +0 -137
- package/src/live-voice/ack-phrases.ts +0 -58
- package/src/plugins/defaults/memory/retrieval-budget.ts +0 -29
- package/src/plugins/defaults/memory/v3/__tests__/gate-flag.test.ts +0 -69
- package/src/plugins/defaults/memory/v3/gate-flag.ts +0 -20
- package/src/plugins/defaults/memory/v3/substrate/__tests__/memory-v2-startup.test.ts +0 -86
- package/src/plugins/defaults/memory/v3/substrate/memory-v2-startup.test.ts +0 -205
- /package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/concept-page-frontmatter-schema.test.ts +0 -0
- /package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/consolidation-prompt-flag-gating-guard.test.ts +0 -0
- /package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/injected-block-slugs.test.ts +0 -0
- /package/src/plugins/defaults/memory/{v3/substrate → substrate}/cli-command-content.ts +0 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolution of a conversation's subagent lineage — the chain of forks that
|
|
3
|
+
* leads back to the user-visible thread a background run belongs to.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { getPersistedParentConversationId } from "../persistence/conversation-parent.js";
|
|
7
|
+
import { findConversationOrSubagent } from "./conversation-registry.js";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Depth cap: a subagent chain deeper than this is a bug, not a hierarchy.
|
|
11
|
+
* Matches the fork-chain cap in the memory plugin's ancestor walk so the two
|
|
12
|
+
* conversation-ancestry walks agree on what counts as pathological.
|
|
13
|
+
*/
|
|
14
|
+
export const MAX_LINEAGE_DEPTH = 16;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* The spawner of a conversation: the in-memory registry's record, falling back
|
|
18
|
+
* to the persisted `parent_conversation_id` column. Returns `undefined` at the
|
|
19
|
+
* top of the chain.
|
|
20
|
+
*
|
|
21
|
+
* Both sources are consulted because residency is short-lived —
|
|
22
|
+
* `SubagentManager` drops a subagent's index entry the moment its run goes
|
|
23
|
+
* terminal, and the evictor sweeps idle top-level conversations — and because
|
|
24
|
+
* a resident instance does not necessarily carry the parentage its row does.
|
|
25
|
+
* The column is stamped at subagent bootstrap and outlives both.
|
|
26
|
+
*
|
|
27
|
+
* A failed durable read is swallowed: linking artifacts to a partial chain is
|
|
28
|
+
* better than failing the caller, which is always a best-effort side effect.
|
|
29
|
+
*/
|
|
30
|
+
function parentOf(conversationId: string): string | undefined {
|
|
31
|
+
const resident = findConversationOrSubagent(conversationId);
|
|
32
|
+
if (resident?.parentConversationId) {
|
|
33
|
+
return resident.parentConversationId;
|
|
34
|
+
}
|
|
35
|
+
try {
|
|
36
|
+
return getPersistedParentConversationId(conversationId);
|
|
37
|
+
} catch {
|
|
38
|
+
return undefined;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* The conversation itself plus every subagent ancestor above it, nearest
|
|
44
|
+
* first. A subagent Conversation records its spawner in the readonly
|
|
45
|
+
* `parentConversationId` set at construction (see subagent/manager.ts) and in
|
|
46
|
+
* the `parent_conversation_id` column written at bootstrap, so walking that
|
|
47
|
+
* chain reaches the user-visible thread a background run was forked from.
|
|
48
|
+
*
|
|
49
|
+
* Resident hops resolve through {@link findConversationOrSubagent}, because
|
|
50
|
+
* the seed is typically a background subagent and `SubagentManager` keeps live
|
|
51
|
+
* subagent conversations in their own index rather than the eviction-managed
|
|
52
|
+
* top-level store. Non-resident hops fall back to the durable column, so a
|
|
53
|
+
* link attempted after the run went terminal or the thread was evicted still
|
|
54
|
+
* reaches the user-visible ancestor.
|
|
55
|
+
*
|
|
56
|
+
* Never throws: a failed database read degrades to the chain resolved so far,
|
|
57
|
+
* which can therefore be shorter than the true ancestry. Bounded by
|
|
58
|
+
* {@link MAX_LINEAGE_DEPTH} and a visited set, so a cycle terminates.
|
|
59
|
+
*/
|
|
60
|
+
export function resolveConversationLineage(conversationId: string): string[] {
|
|
61
|
+
const lineage = [conversationId];
|
|
62
|
+
const visited = new Set([conversationId]);
|
|
63
|
+
|
|
64
|
+
let current = conversationId;
|
|
65
|
+
while (lineage.length < MAX_LINEAGE_DEPTH) {
|
|
66
|
+
const parent = parentOf(current);
|
|
67
|
+
if (!parent || visited.has(parent)) {
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
lineage.push(parent);
|
|
71
|
+
visited.add(parent);
|
|
72
|
+
current = parent;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return lineage;
|
|
76
|
+
}
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
} from "../agent/attachments.js";
|
|
17
17
|
import { optimizeImageForTransport } from "../agent/image-optimize.js";
|
|
18
18
|
import { createUserMessage } from "../agent/message-types.js";
|
|
19
|
+
import type { AssistantEvent } from "../api/index.js";
|
|
19
20
|
import type {
|
|
20
21
|
TurnChannelContext,
|
|
21
22
|
TurnInterfaceContext,
|
|
@@ -64,7 +65,6 @@ import { withSqliteRetry } from "../util/sqlite-retry.js";
|
|
|
64
65
|
import type { MessageQueue } from "./conversation-queue-manager.js";
|
|
65
66
|
import type { SlackInboundMessageMetadata } from "./handlers/shared.js";
|
|
66
67
|
import type {
|
|
67
|
-
ServerMessage,
|
|
68
68
|
UserMessageAttachment,
|
|
69
69
|
} from "./message-protocol.js";
|
|
70
70
|
import type { ConversationTransportMetadata } from "./message-types/conversations.js";
|
|
@@ -187,10 +187,10 @@ function resolveIngressSecretTarget(
|
|
|
187
187
|
for (const detectedType of detectedTypes) {
|
|
188
188
|
const normalizedType = normalizeIngressSecretTypeLabel(detectedType);
|
|
189
189
|
const mapped = INGRESS_SECRET_TARGETS[normalizedType];
|
|
190
|
-
if (!mapped) continue;
|
|
190
|
+
if (!mapped) {continue;}
|
|
191
191
|
mappedTargets.set(`${mapped.service}:${mapped.field}`, mapped);
|
|
192
192
|
}
|
|
193
|
-
if (mappedTargets.size === 1) return mappedTargets.values().next().value!;
|
|
193
|
+
if (mappedTargets.size === 1) {return mappedTargets.values().next().value!;}
|
|
194
194
|
|
|
195
195
|
return {
|
|
196
196
|
service: "detected",
|
|
@@ -275,7 +275,7 @@ function computeReferenceImageDimensions(
|
|
|
275
275
|
mediaType: string,
|
|
276
276
|
): { width: number; height: number } | null {
|
|
277
277
|
const bytes = getAttachmentContent(attachmentId);
|
|
278
|
-
if (!bytes) return null;
|
|
278
|
+
if (!bytes) {return null;}
|
|
279
279
|
const optimized = optimizeImageForTransport(
|
|
280
280
|
bytes.toString("base64"),
|
|
281
281
|
mediaType,
|
|
@@ -330,7 +330,7 @@ function materializeUserAttachment(
|
|
|
330
330
|
);
|
|
331
331
|
return stored ? { kind: "stored", stored } : { kind: "transient" };
|
|
332
332
|
}
|
|
333
|
-
if (!a.data) return { kind: "rejected" };
|
|
333
|
+
if (!a.data) {return { kind: "rejected" };}
|
|
334
334
|
const validation = validateAttachmentUpload(a.filename, a.mimeType);
|
|
335
335
|
if (!validation.ok) {
|
|
336
336
|
log.warn(
|
|
@@ -395,7 +395,7 @@ function referenceBlockForAttachment(
|
|
|
395
395
|
function inlineBlockForAttachment(
|
|
396
396
|
a: MessageAttachmentInput,
|
|
397
397
|
): ContentBlock | null {
|
|
398
|
-
if (!a.data) return null;
|
|
398
|
+
if (!a.data) {return null;}
|
|
399
399
|
return attachmentsToContentBlocks([a])[0] ?? null;
|
|
400
400
|
}
|
|
401
401
|
|
|
@@ -431,7 +431,7 @@ function prepareUserAttachmentReferences(
|
|
|
431
431
|
});
|
|
432
432
|
continue;
|
|
433
433
|
}
|
|
434
|
-
if (outcome.kind === "rejected") continue;
|
|
434
|
+
if (outcome.kind === "rejected") {continue;}
|
|
435
435
|
// transient: keep the upload by inlining its bytes (dropped only when the
|
|
436
436
|
// recoverable failure left us with no bytes to inline).
|
|
437
437
|
const inline = inlineBlockForAttachment(a);
|
|
@@ -450,24 +450,24 @@ function prepareUserAttachmentReferences(
|
|
|
450
450
|
function extractTurnChannelContext(
|
|
451
451
|
metadata?: Record<string, unknown>,
|
|
452
452
|
): TurnChannelContext | null {
|
|
453
|
-
if (!metadata) return null;
|
|
453
|
+
if (!metadata) {return null;}
|
|
454
454
|
const userMessageChannel = parseChannelId(metadata.userMessageChannel);
|
|
455
455
|
const assistantMessageChannel = parseChannelId(
|
|
456
456
|
metadata.assistantMessageChannel,
|
|
457
457
|
);
|
|
458
|
-
if (!userMessageChannel || !assistantMessageChannel) return null;
|
|
458
|
+
if (!userMessageChannel || !assistantMessageChannel) {return null;}
|
|
459
459
|
return { userMessageChannel, assistantMessageChannel };
|
|
460
460
|
}
|
|
461
461
|
|
|
462
462
|
function extractTurnInterfaceContext(
|
|
463
463
|
metadata?: Record<string, unknown>,
|
|
464
464
|
): TurnInterfaceContext | null {
|
|
465
|
-
if (!metadata) return null;
|
|
465
|
+
if (!metadata) {return null;}
|
|
466
466
|
const userMessageInterface = parseInterfaceId(metadata.userMessageInterface);
|
|
467
467
|
const assistantMessageInterface = parseInterfaceId(
|
|
468
468
|
metadata.assistantMessageInterface,
|
|
469
469
|
);
|
|
470
|
-
if (!userMessageInterface || !assistantMessageInterface) return null;
|
|
470
|
+
if (!userMessageInterface || !assistantMessageInterface) {return null;}
|
|
471
471
|
return { userMessageInterface, assistantMessageInterface };
|
|
472
472
|
}
|
|
473
473
|
|
|
@@ -530,7 +530,7 @@ export function buildSlackMetaForPersistence(params: {
|
|
|
530
530
|
export interface EnqueueMessageOptions {
|
|
531
531
|
content: string;
|
|
532
532
|
attachments?: UserMessageAttachment[];
|
|
533
|
-
onEvent?: (msg:
|
|
533
|
+
onEvent?: (msg: AssistantEvent) => void;
|
|
534
534
|
requestId?: string;
|
|
535
535
|
activeSurfaceId?: string;
|
|
536
536
|
currentPage?: string;
|
|
@@ -890,7 +890,7 @@ export async function persistQueuedMessageBody(
|
|
|
890
890
|
// though the store anchor was lost, then persist the corrected content.
|
|
891
891
|
let repairedBlocks: ContentBlock[] | null = null;
|
|
892
892
|
preparedAttachments.forEach((p, idx) => {
|
|
893
|
-
if (!p.link) return;
|
|
893
|
+
if (!p.link) {return;}
|
|
894
894
|
try {
|
|
895
895
|
const scopedAttachmentId = linkAttachmentToMessage(
|
|
896
896
|
persistedUserMessage.id,
|
|
@@ -982,7 +982,7 @@ export function redirectToSecurePrompt(
|
|
|
982
982
|
conversationId,
|
|
983
983
|
)
|
|
984
984
|
.then(async (result): Promise<void> => {
|
|
985
|
-
if (!result.value) return;
|
|
985
|
+
if (!result.value) {return;}
|
|
986
986
|
|
|
987
987
|
const { setSecureKeyAsync } = await import("../security/secure-keys.js");
|
|
988
988
|
const { upsertCredentialMetadata } =
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { createAssistantMessage } from "../agent/message-types.js";
|
|
11
|
+
import type { AssistantEvent } from "../api/index.js";
|
|
11
12
|
import { buildCallCompletionMessage } from "../calls/call-conversation-messages.js";
|
|
12
13
|
import {
|
|
13
14
|
registerCallCompletionNotifier,
|
|
@@ -23,7 +24,6 @@ import {
|
|
|
23
24
|
provenanceFromTrustContext,
|
|
24
25
|
} from "../persistence/conversation-crud.js";
|
|
25
26
|
import type { Message } from "../providers/types.js";
|
|
26
|
-
import type { ServerMessage } from "./message-protocol.js";
|
|
27
27
|
import type { TrustContext } from "./trust-context-types.js";
|
|
28
28
|
|
|
29
29
|
/**
|
|
@@ -31,7 +31,7 @@ import type { TrustContext } from "./trust-context-types.js";
|
|
|
31
31
|
* invocation time. Properties are read lazily from this reference.
|
|
32
32
|
*/
|
|
33
33
|
export interface NotifierConversationContext {
|
|
34
|
-
sendToClient: (msg:
|
|
34
|
+
sendToClient: (msg: AssistantEvent) => void;
|
|
35
35
|
messages: Message[];
|
|
36
36
|
trustContext?: TrustContext;
|
|
37
37
|
}
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
createAssistantMessage,
|
|
12
12
|
createUserMessage,
|
|
13
13
|
} from "../agent/message-types.js";
|
|
14
|
+
import type { AssistantEvent } from "../api/index.js";
|
|
14
15
|
import { listPendingRequestsByScopeOrEmpty } from "../channels/gateway-guardian-requests.js";
|
|
15
16
|
import {
|
|
16
17
|
parseChannelId,
|
|
@@ -56,10 +57,7 @@ import {
|
|
|
56
57
|
} from "./conversation-slash.js";
|
|
57
58
|
import { getModelInfo } from "./handlers/config-model.js";
|
|
58
59
|
import { preactivateHostProxySkills } from "./host-proxy-preactivation.js";
|
|
59
|
-
import type {
|
|
60
|
-
ServerMessage,
|
|
61
|
-
UserMessageAttachment,
|
|
62
|
-
} from "./message-protocol.js";
|
|
60
|
+
import type { UserMessageAttachment } from "./message-protocol.js";
|
|
63
61
|
import { buildTransportHints } from "./transport-hints.js";
|
|
64
62
|
import { resolveVerificationSessionIntent } from "./verification-session-intent.js";
|
|
65
63
|
|
|
@@ -192,7 +190,7 @@ export function formatCleanResult(result: CleanResult): string {
|
|
|
192
190
|
/** Build a model_info event with fresh config data. */
|
|
193
191
|
export async function buildModelInfoEvent(
|
|
194
192
|
conversationId?: string,
|
|
195
|
-
): Promise<
|
|
193
|
+
): Promise<AssistantEvent> {
|
|
196
194
|
return { type: "model_info", conversationId, ...(await getModelInfo()) };
|
|
197
195
|
}
|
|
198
196
|
|
|
@@ -438,13 +436,15 @@ function repairPendingToolUseBlocks(conversation: Conversation): void {
|
|
|
438
436
|
|
|
439
437
|
/**
|
|
440
438
|
* Restore drained messages to the front of the queue, in their original
|
|
441
|
-
* order, when another turn (e.g. a barged-in
|
|
442
|
-
* transition) owns the processing lock
|
|
443
|
-
*
|
|
444
|
-
*
|
|
445
|
-
*
|
|
439
|
+
* order, when the drain cannot run them: another turn (e.g. a barged-in
|
|
440
|
+
* voice turn woken by the idle transition) owns the processing lock, or the
|
|
441
|
+
* dispatch threw before the turn took over. The next drain trigger (the lock
|
|
442
|
+
* holder's own finally block, or `kickQueueDrain`'s retry) picks them back
|
|
443
|
+
* up. A steered drain also re-arms `pendingSteerRepair` so the re-drain
|
|
444
|
+
* promotes the steered head on its own instead of batching it with tails;
|
|
445
|
+
* the tool-use repair it re-triggers is idempotent.
|
|
446
446
|
*/
|
|
447
|
-
function
|
|
447
|
+
function requeueDrainedMessages(
|
|
448
448
|
conversation: Conversation,
|
|
449
449
|
messages: QueuedMessage[],
|
|
450
450
|
steered: boolean,
|
|
@@ -493,7 +493,9 @@ export async function drainQueue(
|
|
|
493
493
|
if (!next) {
|
|
494
494
|
return;
|
|
495
495
|
}
|
|
496
|
-
return
|
|
496
|
+
return dispatchDrainWithRestore(conversation, [next], true, () =>
|
|
497
|
+
drainSingleMessage(conversation, next, reason, true),
|
|
498
|
+
);
|
|
497
499
|
}
|
|
498
500
|
|
|
499
501
|
const batch = await buildPassthroughBatch(conversation);
|
|
@@ -505,12 +507,122 @@ export async function drainQueue(
|
|
|
505
507
|
if (!next) {
|
|
506
508
|
return;
|
|
507
509
|
}
|
|
508
|
-
return
|
|
510
|
+
return dispatchDrainWithRestore(conversation, [next], false, () =>
|
|
511
|
+
drainSingleMessage(conversation, next, reason),
|
|
512
|
+
);
|
|
509
513
|
}
|
|
510
514
|
if (batch.length === 1) {
|
|
511
|
-
return
|
|
515
|
+
return dispatchDrainWithRestore(conversation, batch, false, () =>
|
|
516
|
+
drainSingleMessage(conversation, batch[0], reason),
|
|
517
|
+
);
|
|
518
|
+
}
|
|
519
|
+
return dispatchDrainWithRestore(conversation, batch, false, () =>
|
|
520
|
+
drainBatch(conversation, batch, reason),
|
|
521
|
+
);
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
/**
|
|
525
|
+
* Errors that already triggered a queue restore on their way up. Drains
|
|
526
|
+
* recurse (a dropped message's error path re-drains the remaining queue), so
|
|
527
|
+
* without the marker an inner dispatch failure would also restore the outer
|
|
528
|
+
* dispatch's messages — resurrecting a message whose sender was already told
|
|
529
|
+
* it failed.
|
|
530
|
+
*/
|
|
531
|
+
const restoredDrainErrors = new WeakSet<object>();
|
|
532
|
+
|
|
533
|
+
/**
|
|
534
|
+
* Run a drain dispatch whose messages are already removed from the queue,
|
|
535
|
+
* restoring them to the front if the dispatch throws. `drainQueue` pops
|
|
536
|
+
* messages before the throw-prone turn-start steps (slash resolution,
|
|
537
|
+
* per-turn context application), so without the restore a retry would skip
|
|
538
|
+
* the failed message entirely: it drains the NEXT item, succeeds, and the
|
|
539
|
+
* removed message is silently lost with no `queue_drain_failed` event.
|
|
540
|
+
*/
|
|
541
|
+
async function dispatchDrainWithRestore(
|
|
542
|
+
conversation: Conversation,
|
|
543
|
+
messages: QueuedMessage[],
|
|
544
|
+
steered: boolean,
|
|
545
|
+
dispatch: () => Promise<void>,
|
|
546
|
+
): Promise<void> {
|
|
547
|
+
try {
|
|
548
|
+
return await dispatch();
|
|
549
|
+
} catch (err) {
|
|
550
|
+
const alreadyRestored =
|
|
551
|
+
typeof err === "object" && err !== null && restoredDrainErrors.has(err);
|
|
552
|
+
if (!alreadyRestored) {
|
|
553
|
+
if (typeof err === "object" && err !== null) {
|
|
554
|
+
restoredDrainErrors.add(err);
|
|
555
|
+
}
|
|
556
|
+
requeueDrainedMessages(
|
|
557
|
+
conversation,
|
|
558
|
+
messages,
|
|
559
|
+
steered,
|
|
560
|
+
"Requeueing drained messages: drain dispatch threw",
|
|
561
|
+
);
|
|
562
|
+
}
|
|
563
|
+
throw err;
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
/**
|
|
568
|
+
* Fire-and-forget entry point for drain triggers that sit outside the drain
|
|
569
|
+
* promise chain (the agent loop's `finally`, route handlers releasing the
|
|
570
|
+
* processing lock). `drainQueue` is async — batch building awaits slash
|
|
571
|
+
* resolution and can throw — and nothing re-triggers a drain whose promise
|
|
572
|
+
* rejects: the queued messages would sit stranded until an unrelated later
|
|
573
|
+
* turn completes. This wrapper never rejects. A failed drain is retried
|
|
574
|
+
* once — `dispatchDrainWithRestore` has already returned any popped
|
|
575
|
+
* messages to the queue head, so the retry retries the same messages. If
|
|
576
|
+
* the retry also fails, every queued sender is notified so the stall is
|
|
577
|
+
* visible to the user instead of silent, and the messages remain queued
|
|
578
|
+
* for the next drain trigger.
|
|
579
|
+
*
|
|
580
|
+
* `origin` names the triggering site for log correlation.
|
|
581
|
+
*/
|
|
582
|
+
export async function kickQueueDrain(
|
|
583
|
+
conversation: Conversation,
|
|
584
|
+
reason: QueueDrainReason = "loop_complete",
|
|
585
|
+
origin?: string,
|
|
586
|
+
): Promise<void> {
|
|
587
|
+
try {
|
|
588
|
+
await drainQueue(conversation, reason);
|
|
589
|
+
return;
|
|
590
|
+
} catch (err) {
|
|
591
|
+
log.error(
|
|
592
|
+
{
|
|
593
|
+
err,
|
|
594
|
+
conversationId: conversation.conversationId,
|
|
595
|
+
reason,
|
|
596
|
+
origin,
|
|
597
|
+
queueDepth: conversation.queue.length,
|
|
598
|
+
},
|
|
599
|
+
"drainQueue rejected; retrying once",
|
|
600
|
+
);
|
|
601
|
+
}
|
|
602
|
+
try {
|
|
603
|
+
await drainQueue(conversation, reason);
|
|
604
|
+
} catch (err) {
|
|
605
|
+
log.error(
|
|
606
|
+
{
|
|
607
|
+
err,
|
|
608
|
+
conversationId: conversation.conversationId,
|
|
609
|
+
reason,
|
|
610
|
+
origin,
|
|
611
|
+
queueDepth: conversation.queue.length,
|
|
612
|
+
},
|
|
613
|
+
"drainQueue retry rejected; queued messages remain stranded until the next drain trigger",
|
|
614
|
+
);
|
|
615
|
+
for (const queued of conversation.queue.snapshot()) {
|
|
616
|
+
queued.onEvent({
|
|
617
|
+
type: "error",
|
|
618
|
+
conversationId: conversation.conversationId,
|
|
619
|
+
requestId: queued.requestId,
|
|
620
|
+
message:
|
|
621
|
+
"The assistant couldn't start your queued message due to an internal error. The message is still queued and will be retried after the next reply; you can also cancel and resend it.",
|
|
622
|
+
category: "queue_drain_failed",
|
|
623
|
+
});
|
|
624
|
+
}
|
|
512
625
|
}
|
|
513
|
-
return drainBatch(conversation, batch, reason);
|
|
514
626
|
}
|
|
515
627
|
|
|
516
628
|
async function drainSingleMessage(
|
|
@@ -526,7 +638,7 @@ async function drainSingleMessage(
|
|
|
526
638
|
// requeue below stays as the TOCTOU backstop for a lock taken after
|
|
527
639
|
// this check.
|
|
528
640
|
if (conversation.isProcessing()) {
|
|
529
|
-
|
|
641
|
+
requeueDrainedMessages(
|
|
530
642
|
conversation,
|
|
531
643
|
[next],
|
|
532
644
|
steered,
|
|
@@ -952,7 +1064,7 @@ async function drainSingleMessage(
|
|
|
952
1064
|
// Another turn took the lock between this drain's dequeue and its
|
|
953
1065
|
// persist. The message is still valid — requeue it at the front and
|
|
954
1066
|
// stop; the lock holder's own finally re-drains the queue.
|
|
955
|
-
|
|
1067
|
+
requeueDrainedMessages(
|
|
956
1068
|
conversation,
|
|
957
1069
|
[next],
|
|
958
1070
|
steered,
|
|
@@ -1110,7 +1222,7 @@ async function drainBatch(
|
|
|
1110
1222
|
// The head persist-busy requeue below stays as the TOCTOU backstop.
|
|
1111
1223
|
// Steered drains never batch, so there is no steer promotion to restore.
|
|
1112
1224
|
if (conversation.isProcessing()) {
|
|
1113
|
-
|
|
1225
|
+
requeueDrainedMessages(
|
|
1114
1226
|
conversation,
|
|
1115
1227
|
batch,
|
|
1116
1228
|
false,
|
|
@@ -1329,7 +1441,7 @@ async function drainBatch(
|
|
|
1329
1441
|
// whole batch is still valid — requeue it at the front in order
|
|
1330
1442
|
// and stop; the lock holder's finally re-drains the queue.
|
|
1331
1443
|
conversation.preactivatedSkillIds = undefined;
|
|
1332
|
-
|
|
1444
|
+
requeueDrainedMessages(
|
|
1333
1445
|
conversation,
|
|
1334
1446
|
batch,
|
|
1335
1447
|
false,
|
|
@@ -1503,7 +1615,7 @@ async function drainBatch(
|
|
|
1503
1615
|
const successfulEventSinks = Array.from(
|
|
1504
1616
|
new Set(successfulBatch.map((qm) => qm.onEvent)),
|
|
1505
1617
|
);
|
|
1506
|
-
const fanOutOnEvent = (msg:
|
|
1618
|
+
const fanOutOnEvent = (msg: AssistantEvent) => {
|
|
1507
1619
|
for (const onEvent of successfulEventSinks) {
|
|
1508
1620
|
onEvent(msg);
|
|
1509
1621
|
}
|
|
@@ -1567,7 +1679,7 @@ async function drainBatch(
|
|
|
1567
1679
|
export interface ProcessMessageOptions {
|
|
1568
1680
|
content: string;
|
|
1569
1681
|
attachments: UserMessageAttachment[];
|
|
1570
|
-
onEvent?: (msg:
|
|
1682
|
+
onEvent?: (msg: AssistantEvent) => void;
|
|
1571
1683
|
requestId?: string;
|
|
1572
1684
|
activeSurfaceId?: string;
|
|
1573
1685
|
currentPage?: string;
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* agent loop is in flight.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
+
import type { AssistantEvent } from "../api/index.js";
|
|
8
9
|
import type {
|
|
9
10
|
TurnChannelContext,
|
|
10
11
|
TurnInterfaceContext,
|
|
@@ -12,7 +13,6 @@ import type {
|
|
|
12
13
|
import type { AuthContext } from "../runtime/auth/types.js";
|
|
13
14
|
import { getLogger } from "../util/logger.js";
|
|
14
15
|
import type {
|
|
15
|
-
ServerMessage,
|
|
16
16
|
UserMessageAttachment,
|
|
17
17
|
} from "./message-protocol.js";
|
|
18
18
|
import type { ConversationTransportMetadata } from "./message-types/conversations.js";
|
|
@@ -23,7 +23,7 @@ export interface QueuedMessage {
|
|
|
23
23
|
content: string;
|
|
24
24
|
attachments: UserMessageAttachment[];
|
|
25
25
|
requestId: string;
|
|
26
|
-
onEvent: (msg:
|
|
26
|
+
onEvent: (msg: AssistantEvent) => void;
|
|
27
27
|
activeSurfaceId?: string;
|
|
28
28
|
currentPage?: string;
|
|
29
29
|
metadata?: Record<string, unknown>;
|
|
@@ -156,7 +156,7 @@ export class MessageQueue {
|
|
|
156
156
|
*/
|
|
157
157
|
shiftN(count: number): QueuedMessage[] {
|
|
158
158
|
const n = Math.min(Math.max(0, count), this.items.length);
|
|
159
|
-
if (n === 0) return [];
|
|
159
|
+
if (n === 0) {return [];}
|
|
160
160
|
const removed = this.items.splice(0, n);
|
|
161
161
|
for (const item of removed) {
|
|
162
162
|
this.currentBytes -= estimateItemBytes(item);
|
|
@@ -188,8 +188,8 @@ export class MessageQueue {
|
|
|
188
188
|
*/
|
|
189
189
|
promoteToHead(requestId: string): QueuedMessage | undefined {
|
|
190
190
|
const idx = this.items.findIndex((m) => m.requestId === requestId);
|
|
191
|
-
if (idx === -1) return undefined;
|
|
192
|
-
if (idx === 0) return this.items[0]; // already at head
|
|
191
|
+
if (idx === -1) {return undefined;}
|
|
192
|
+
if (idx === 0) {return this.items[0];} // already at head
|
|
193
193
|
const [promoted] = this.items.splice(idx, 1);
|
|
194
194
|
this.items.unshift(promoted);
|
|
195
195
|
return promoted;
|
|
@@ -201,7 +201,7 @@ export class MessageQueue {
|
|
|
201
201
|
*/
|
|
202
202
|
removeByRequestId(requestId: string): QueuedMessage | undefined {
|
|
203
203
|
const idx = this.items.findIndex((m) => m.requestId === requestId);
|
|
204
|
-
if (idx === -1) return undefined;
|
|
204
|
+
if (idx === -1) {return undefined;}
|
|
205
205
|
const [removed] = this.items.splice(idx, 1);
|
|
206
206
|
this.currentBytes -= estimateItemBytes(removed);
|
|
207
207
|
return removed;
|
|
@@ -220,7 +220,7 @@ function estimateItemBytes(item: QueuedMessage): number {
|
|
|
220
220
|
let bytes = item.content.length * 2; // JS strings are UTF-16
|
|
221
221
|
for (const a of item.attachments) {
|
|
222
222
|
bytes += a.data.length * 2;
|
|
223
|
-
if (a.extractedText) bytes += a.extractedText.length * 2;
|
|
223
|
+
if (a.extractedText) {bytes += a.extractedText.length * 2;}
|
|
224
224
|
}
|
|
225
225
|
// Include transport metadata in the estimate so large transport
|
|
226
226
|
// payloads (e.g. hostHomeDir, hostUsername) count against the budget.
|
|
@@ -74,6 +74,7 @@ import { resolveCapabilities } from "../runtime/capabilities.js";
|
|
|
74
74
|
import type { SubagentState } from "../subagent/types.js";
|
|
75
75
|
import { TERMINAL_STATUSES } from "../subagent/types.js";
|
|
76
76
|
import { canonicalizeInboundIdentity } from "../util/canonicalize-identity.js";
|
|
77
|
+
import { channelSupportsInlineOptions } from "./channel-ui-capability.js";
|
|
77
78
|
import { findConversationOrSubagent } from "./conversation-registry.js";
|
|
78
79
|
import type { SurfaceShowPair } from "./conversation-surfaces.js";
|
|
79
80
|
import { canonicalizeTimeZone, formatTurnTimestamp } from "./date-context.js";
|
|
@@ -97,6 +98,13 @@ export interface ChannelCapabilities {
|
|
|
97
98
|
dashboardCapable: boolean;
|
|
98
99
|
/** Whether the channel supports dynamic UI surfaces (ui_show / ui_update). */
|
|
99
100
|
supportsDynamicUi: boolean;
|
|
101
|
+
/**
|
|
102
|
+
* Whether the channel's adapter can render inline tappable options — approval
|
|
103
|
+
* buttons and (next) question option pickers. Distinct from `supportsDynamicUi`:
|
|
104
|
+
* a text-only channel can render inline buttons without dynamic UI. Optional;
|
|
105
|
+
* absent is treated as `false`.
|
|
106
|
+
*/
|
|
107
|
+
supportsInlineOptions?: boolean;
|
|
100
108
|
/** Whether the channel supports voice/microphone input. */
|
|
101
109
|
supportsVoiceInput: boolean;
|
|
102
110
|
/** The client OS/interface identifier (e.g. "macos", "ios", "web"). */
|
|
@@ -282,6 +290,7 @@ export function resolveChannelCapabilities(
|
|
|
282
290
|
channel,
|
|
283
291
|
dashboardCapable: supportsDesktopUi,
|
|
284
292
|
supportsDynamicUi: supportsDesktopUi || iface === "web",
|
|
293
|
+
supportsInlineOptions: channelSupportsInlineOptions(channel),
|
|
285
294
|
supportsVoiceInput: supportsDesktopUi,
|
|
286
295
|
clientOS: iface ?? undefined,
|
|
287
296
|
chatType: resolvedChatType,
|
|
@@ -296,6 +305,7 @@ export function resolveChannelCapabilities(
|
|
|
296
305
|
channel,
|
|
297
306
|
dashboardCapable: false,
|
|
298
307
|
supportsDynamicUi: false,
|
|
308
|
+
supportsInlineOptions: channelSupportsInlineOptions(channel),
|
|
299
309
|
supportsVoiceInput: false,
|
|
300
310
|
chatType: resolvedChatType,
|
|
301
311
|
};
|
|
@@ -304,6 +314,7 @@ export function resolveChannelCapabilities(
|
|
|
304
314
|
channel,
|
|
305
315
|
dashboardCapable: false,
|
|
306
316
|
supportsDynamicUi: false,
|
|
317
|
+
supportsInlineOptions: channelSupportsInlineOptions(channel),
|
|
307
318
|
supportsVoiceInput: false,
|
|
308
319
|
chatType: resolvedChatType,
|
|
309
320
|
};
|
|
@@ -974,6 +985,11 @@ function placeholderForBlockType(type: ContentBlock["type"]): string | null {
|
|
|
974
985
|
case "tool_result":
|
|
975
986
|
case "web_search_tool_result":
|
|
976
987
|
return "[tool result]";
|
|
988
|
+
// Surfaces normally ride with a `_surfaceFallback` text sibling that
|
|
989
|
+
// supplies the line, so this label is reached only by legacy rows that
|
|
990
|
+
// carry a bare card — better than rendering an empty transcript line.
|
|
991
|
+
case "ui_surface":
|
|
992
|
+
return "[card]";
|
|
977
993
|
case "thinking":
|
|
978
994
|
case "redacted_thinking":
|
|
979
995
|
case "text":
|
|
@@ -118,6 +118,9 @@ export async function getOrCreateConversation(
|
|
|
118
118
|
(conversation.isStale() && !conversation.isProcessing())
|
|
119
119
|
) {
|
|
120
120
|
if (conversation) {
|
|
121
|
+
// Stale rebuild: the conversation id lives on, so abort in-flight
|
|
122
|
+
// children but keep terminal subagent results readable for the
|
|
123
|
+
// retention window.
|
|
121
124
|
getSubagentManager().abortAllForParent(conversationId);
|
|
122
125
|
conversation.dispose();
|
|
123
126
|
}
|
|
@@ -247,12 +250,15 @@ export async function getOrCreateConversation(
|
|
|
247
250
|
* deleted conversation and trip FK constraints.
|
|
248
251
|
*/
|
|
249
252
|
export function destroyActiveConversation(conversationId: string): void {
|
|
253
|
+
// Subagent teardown is keyed by parent id, not the live instance — an
|
|
254
|
+
// evicted parent still retains its terminal children, and deleting the
|
|
255
|
+
// conversation must take their records with it.
|
|
256
|
+
getSubagentManager().disposeAllForParent(conversationId);
|
|
250
257
|
const conversation = findConversation(conversationId);
|
|
251
258
|
if (!conversation) {
|
|
252
259
|
return;
|
|
253
260
|
}
|
|
254
261
|
removeFromEvictor(conversationId);
|
|
255
|
-
getSubagentManager().abortAllForParent(conversationId);
|
|
256
262
|
conversation.dispose();
|
|
257
263
|
deleteConversation(conversationId);
|
|
258
264
|
deleteConversationOptions(conversationId);
|
|
@@ -277,10 +283,12 @@ export function stopConversations(): void {
|
|
|
277
283
|
*/
|
|
278
284
|
export function clearAllActiveConversations(): number {
|
|
279
285
|
const count = conversationCount();
|
|
280
|
-
|
|
286
|
+
// Dispose subagents across ALL parents, not just the in-memory ones — an
|
|
287
|
+
// evicted parent still retains its terminal children, and clear-all must
|
|
288
|
+
// take their records with it.
|
|
289
|
+
getSubagentManager().disposeAllForAllParents();
|
|
281
290
|
for (const id of conversationIds()) {
|
|
282
291
|
removeFromEvictor(id);
|
|
283
|
-
subagentManager.abortAllForParent(id);
|
|
284
292
|
}
|
|
285
293
|
for (const conversation of allConversations()) {
|
|
286
294
|
conversation.dispose();
|