@vellumai/assistant 0.8.3 → 0.8.5
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/ARCHITECTURE.md +2 -2
- package/docker-entrypoint.sh +0 -1
- package/docs/browser-use-architecture-phase2.md +1 -1
- package/knip.json +2 -1
- package/node_modules/@vellumai/gateway-client/src/types.ts +2 -0
- package/openapi.yaml +1492 -100
- package/package.json +1 -1
- package/src/__tests__/agent-loop-exit-reason.test.ts +4 -5
- package/src/__tests__/agent-loop-override-profile.test.ts +1 -1
- package/src/__tests__/agent-loop.test.ts +88 -3
- package/src/__tests__/anthropic-provider.test.ts +302 -33
- package/src/__tests__/approval-cascade.test.ts +1 -1
- package/src/__tests__/assistant-event-hub-self-exclusion.test.ts +293 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +3 -3
- package/src/__tests__/audit-log-rotation.test.ts +70 -16
- package/src/__tests__/background-workers-disk-pressure.test.ts +4 -3
- package/src/__tests__/btw-routes.test.ts +2 -3
- package/src/__tests__/call-controller.test.ts +0 -1
- package/src/__tests__/cancel-resolves-conversation-key.test.ts +1 -1
- package/src/__tests__/channel-delivery-store.test.ts +193 -0
- package/src/__tests__/channel-guardian.test.ts +3 -3
- package/src/__tests__/channel-reply-delivery.test.ts +284 -5
- package/src/__tests__/channel-retry-sweep.test.ts +274 -1
- package/src/__tests__/checker.test.ts +6 -15
- package/src/__tests__/compaction-events.test.ts +2 -1
- package/src/__tests__/compactor-call-site-logging.test.ts +214 -0
- package/src/__tests__/compactor-preserved-tail-count.test.ts +110 -0
- package/src/__tests__/computer-use-skill-manifest-regression.test.ts +5 -11
- package/src/__tests__/computer-use-tools.test.ts +2 -4
- package/src/__tests__/config-watcher.test.ts +1 -1
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -1
- package/src/__tests__/context-token-estimator.test.ts +91 -1
- package/src/__tests__/conversation-abort-tool-results.test.ts +1 -1
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +1 -1
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +55 -4
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +228 -8
- package/src/__tests__/conversation-agent-loop.test.ts +188 -129
- package/src/__tests__/conversation-app-control-instantiation.test.ts +2 -5
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +1 -1
- package/src/__tests__/conversation-clean-command.test.ts +137 -0
- package/src/__tests__/conversation-clear-safety.test.ts +25 -25
- package/src/__tests__/conversation-confirmation-signals.test.ts +1 -1
- package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +1 -1
- package/src/__tests__/conversation-disk-view-integration.test.ts +2 -2
- package/src/__tests__/conversation-error.test.ts +31 -0
- package/src/__tests__/conversation-fork-crud.test.ts +324 -0
- package/src/__tests__/conversation-lifecycle.test.ts +53 -12
- package/src/__tests__/conversation-load-history-repair.test.ts +1 -1
- package/src/__tests__/conversation-load-history-stripped.test.ts +279 -0
- package/src/__tests__/conversation-pairing.test.ts +2 -2
- package/src/__tests__/conversation-process-callsite.test.ts +1 -1
- package/src/__tests__/conversation-provider-retry-repair.test.ts +2 -1
- package/src/__tests__/conversation-queue.test.ts +1 -1
- package/src/__tests__/conversation-routes-disk-view.test.ts +109 -0
- package/src/__tests__/conversation-routes-slash-commands.test.ts +35 -0
- package/src/__tests__/conversation-runtime-assembly.test.ts +264 -81
- package/src/__tests__/conversation-seed-composer.test.ts +66 -4
- package/src/__tests__/conversation-skill-tools.test.ts +2 -5
- package/src/__tests__/conversation-slash-commands.test.ts +36 -8
- package/src/__tests__/conversation-slash-queue.test.ts +1 -1
- package/src/__tests__/conversation-slash-unknown.test.ts +1 -1
- package/src/__tests__/conversation-speed-override.test.ts +1 -1
- package/src/__tests__/conversation-store.test.ts +1 -1
- package/src/__tests__/conversation-surfaces-task-progress.test.ts +220 -0
- package/src/__tests__/conversation-sync-tags.test.ts +99 -32
- package/src/__tests__/conversation-workspace-cache-state.test.ts +2 -1
- package/src/__tests__/conversation-workspace-injection.test.ts +5 -1
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +5 -1
- package/src/__tests__/credential-execution-feature-gates.test.ts +9 -7
- package/src/__tests__/credential-execution-tools.test.ts +6 -6
- package/src/__tests__/credential-security-invariants.test.ts +7 -0
- package/src/__tests__/credential-vault-unit.test.ts +2 -2
- package/src/__tests__/cu-unified-flow.test.ts +10 -1
- package/src/__tests__/dm-backfill.test.ts +64 -0
- package/src/__tests__/dm-persistence.test.ts +33 -0
- package/src/__tests__/document-find-replace.test.ts +501 -0
- package/src/__tests__/dynamic-page-surface.test.ts +2 -2
- package/src/__tests__/email-html-renderer.test.ts +12 -0
- package/src/__tests__/first-greeting.test.ts +23 -2
- package/src/__tests__/gateway-flag-listener.test.ts +237 -0
- package/src/__tests__/gemini-provider.test.ts +78 -0
- package/src/__tests__/guardian-dispatch.test.ts +0 -1
- package/src/__tests__/guardian-outbound-http.test.ts +7 -5
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +1 -1
- package/src/__tests__/headless-browser-navigate.test.ts +172 -0
- package/src/__tests__/heartbeat-disk-pressure.test.ts +4 -0
- package/src/__tests__/heartbeat-service.test.ts +4 -0
- package/src/__tests__/host-bash-proxy.test.ts +6 -0
- package/src/__tests__/host-browser-proxy.test.ts +10 -0
- package/src/__tests__/host-cu-proxy.test.ts +8 -1
- package/src/__tests__/host-file-proxy.test.ts +8 -1
- package/src/__tests__/host-shell-tool.test.ts +1 -1
- package/src/__tests__/host-transfer-proxy.test.ts +8 -1
- package/src/__tests__/identity-routes.test.ts +57 -0
- package/src/__tests__/inbound-slack-persistence.test.ts +3 -0
- package/src/__tests__/init-feature-flag-overrides.test.ts +5 -6
- package/src/__tests__/injector-chain.test.ts +2 -0
- package/src/__tests__/injector-document-comments.test.ts +378 -0
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +4 -25
- package/src/__tests__/list-messages-attachments.test.ts +21 -17
- package/src/__tests__/list-messages-hidden-metadata.test.ts +217 -0
- package/src/__tests__/list-messages-page-latest.test.ts +130 -14
- package/src/__tests__/list-messages-tool-merge.test.ts +77 -17
- package/src/__tests__/llm-context-normalization.test.ts +0 -2
- package/src/__tests__/llm-request-log-call-site.test.ts +136 -0
- package/src/__tests__/llm-request-log-source-clickhouse.test.ts +26 -0
- package/src/__tests__/llm-resolver.test.ts +161 -9
- package/src/__tests__/llm-usage-store.test.ts +66 -0
- package/src/__tests__/log-export-routes.test.ts +99 -2
- package/src/__tests__/logger.test.ts +89 -0
- package/src/__tests__/mcp-abort-signal.test.ts +2 -2
- package/src/__tests__/media-generate-image.test.ts +31 -0
- package/src/__tests__/memory-v2-static-injector.test.ts +7 -7
- package/src/__tests__/message-queue-steer.test.ts +114 -0
- package/src/__tests__/model-intents.test.ts +2 -4
- package/src/__tests__/notification-guardian-path.test.ts +0 -1
- package/src/__tests__/onboarding-template-contract.test.ts +1 -1
- package/src/__tests__/openai-provider.test.ts +151 -0
- package/src/__tests__/openai-responses-provider.test.ts +118 -16
- package/src/__tests__/outbound-slack-persistence.test.ts +187 -20
- package/src/__tests__/pending-interactions-resolved-event.test.ts +189 -0
- package/src/__tests__/platform-bash-auto-approve.test.ts +2 -2
- package/src/__tests__/platform.test.ts +2 -5
- package/src/__tests__/plugin-api-tool-definition.test.ts +92 -0
- package/src/__tests__/plugin-bootstrap.test.ts +2 -2
- package/src/__tests__/plugin-source-watcher.test.ts +302 -0
- package/src/__tests__/plugin-tool-contribution.test.ts +13 -6
- package/src/__tests__/plugin-types.test.ts +3 -2
- package/src/__tests__/prechat-onboarding-contract.test.ts +131 -98
- package/src/__tests__/pricing.test.ts +12 -0
- package/src/__tests__/process-message-background-slack.test.ts +1 -51
- package/src/__tests__/process-message-display-content.test.ts +21 -16
- package/src/__tests__/prune-jobs-changes-parser.test.ts +61 -0
- package/src/__tests__/registry.test.ts +2 -8
- package/src/__tests__/require-fresh-approval.test.ts +2 -2
- package/src/__tests__/runtime-events-sse-bilingual.test.ts +154 -0
- package/src/__tests__/server-history-render.test.ts +83 -4
- package/src/__tests__/shell-tool-proxy-mode.test.ts +1 -1
- package/src/__tests__/skill-feature-flags.test.ts +2 -2
- package/src/__tests__/skill-projection-feature-flag.test.ts +4 -7
- package/src/__tests__/skill-projection.benchmark.test.ts +2 -6
- package/src/__tests__/skill-tool-factory.test.ts +1 -1
- package/src/__tests__/steer-tool-repair.test.ts +249 -0
- package/src/__tests__/subagent-notify-parent.test.ts +1 -1
- package/src/__tests__/suggestion-routes.test.ts +1 -0
- package/src/__tests__/sync-message-contract.test.ts +59 -0
- package/src/__tests__/system-prompt.test.ts +161 -124
- package/src/__tests__/terminal-tools.test.ts +12 -2
- package/src/__tests__/thinking-block-replay.test.ts +113 -0
- package/src/__tests__/thread-backfill.test.ts +370 -22
- package/src/__tests__/tool-approval-handler.test.ts +1 -5
- package/src/__tests__/tool-execute-pipeline.test.ts +2 -2
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +2 -5
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +15 -5
- package/src/__tests__/tool-executor.test.ts +89 -53
- package/src/__tests__/tool-grant-request-escalation.test.ts +1 -6
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +167 -0
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +1 -6
- package/src/__tests__/trusted-contact-multichannel.test.ts +0 -1
- package/src/__tests__/twilio-routes.test.ts +1 -1
- package/src/__tests__/ui-file-upload-surface.test.ts +2 -2
- package/src/__tests__/usage-routes.test.ts +3 -0
- package/src/__tests__/verification-control-plane-policy.test.ts +2 -2
- package/src/__tests__/web-fetch.test.ts +2 -2
- package/src/__tests__/workspace-git-service.test.ts +94 -10
- package/src/__tests__/workspace-migration-088-deprecate-background-conversation-override.test.ts +158 -0
- package/src/__tests__/workspace-migration-089-move-memory-tree-out-of-v3.test.ts +86 -0
- package/src/acp/__tests__/prepare-agent-env.test.ts +146 -0
- package/src/acp/prepare-agent-env.ts +78 -0
- package/src/acp/session-manager.ts +1 -1
- package/src/agent/attachments.ts +1 -0
- package/src/agent/loop.ts +65 -20
- package/src/api/README.md +5 -0
- package/src/api/index.ts +4 -0
- package/src/api/package.json +10 -0
- package/src/background-wake/background-wake-routes.test.ts +233 -0
- package/src/background-wake/next-wake.test.ts +289 -0
- package/src/background-wake/next-wake.ts +172 -0
- package/src/background-wake/runtime-registry.ts +24 -0
- package/src/browser/operations.ts +15 -0
- package/src/cli/commands/__tests__/browser.test.ts +23 -5
- package/src/cli/commands/__tests__/conversations-slack.test.ts +572 -0
- package/src/cli/commands/__tests__/domain-register.test.ts +110 -0
- package/src/cli/commands/__tests__/domain-status.test.ts +33 -33
- package/src/cli/commands/__tests__/inference-send.test.ts +108 -5
- package/src/cli/commands/__tests__/memory-v2-compare-render.test.ts +98 -0
- package/src/cli/commands/__tests__/memory-v2.test.ts +10 -12
- package/src/cli/commands/__tests__/memory-v3-render.test.ts +340 -0
- package/src/cli/commands/browser.ts +247 -0
- package/src/cli/commands/conversations.ts +128 -1
- package/src/cli/commands/domain.ts +91 -41
- package/src/cli/commands/inference-providers.ts +147 -1
- package/src/cli/commands/inference.ts +93 -40
- package/src/cli/commands/memory-v2-compare-render.ts +115 -0
- package/src/cli/commands/memory-v2.ts +483 -0
- package/src/cli/commands/memory-v3-render.ts +344 -0
- package/src/cli/commands/memory-v3.ts +316 -0
- package/src/cli/commands/notifications.ts +24 -2
- package/src/cli/program.ts +2 -0
- package/src/cli/utils/conversation-id.ts +17 -5
- package/src/config/assistant-feature-flags.ts +21 -9
- package/src/config/bundled-skills/app-builder/SKILL.md +2 -2
- package/src/config/bundled-skills/document-editor/SKILL.md +124 -0
- package/src/config/bundled-skills/document-editor/TOOLS.json +258 -0
- package/src/config/bundled-skills/document-editor/tools/comment-list.ts +12 -0
- package/src/config/bundled-skills/document-editor/tools/comment-reply.ts +12 -0
- package/src/config/bundled-skills/document-editor/tools/comment-resolve.ts +12 -0
- package/src/config/bundled-skills/document-editor/tools/document-find.ts +12 -0
- package/src/config/bundled-skills/document-editor/tools/document-open.ts +12 -0
- package/src/config/bundled-skills/document-editor/tools/document-replace-text.ts +12 -0
- package/src/config/bundled-skills/image-studio/SKILL.md +4 -0
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +2 -2
- package/src/config/bundled-skills/media-processing/SKILL.md +8 -0
- package/src/config/bundled-skills/media-processing/tools/ingest-media.ts +13 -8
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +10 -3
- package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +16 -14
- package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +7 -2
- package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +7 -2
- package/src/config/bundled-skills/schedule/SKILL.md +8 -0
- package/src/config/bundled-tool-registry.ts +24 -12
- package/src/config/call-site-defaults.ts +20 -0
- package/src/config/feature-flag-registry.json +115 -3
- package/src/config/llm-resolver.ts +16 -2
- package/src/config/schemas/__tests__/memory-v2.test.ts +217 -1
- package/src/config/schemas/call-site-catalog.ts +35 -0
- package/src/config/schemas/llm.ts +14 -0
- package/src/config/schemas/memory-v2.ts +294 -1
- package/src/config/schemas/memory.ts +2 -1
- package/src/context/compactor.ts +60 -1
- package/src/context/token-estimator.ts +47 -4
- package/src/context/window-manager.ts +25 -0
- package/src/conversations/__tests__/message-consolidation.test.ts +350 -0
- package/src/conversations/message-consolidation.ts +404 -0
- package/src/credential-health/credential-health-service.ts +34 -19
- package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +1 -1
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +66 -6
- package/src/daemon/__tests__/meet-manifest-loader.test.ts +1 -1
- package/src/daemon/__tests__/native-web-search-metadata.test.ts +357 -0
- package/src/daemon/__tests__/web-search-status-text.test.ts +287 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +155 -36
- package/src/daemon/conversation-agent-loop.ts +307 -88
- package/src/daemon/conversation-error.ts +31 -1
- package/src/daemon/conversation-lifecycle.ts +149 -118
- package/src/daemon/conversation-messaging.ts +3 -0
- package/src/daemon/conversation-process.ts +273 -0
- package/src/daemon/conversation-queue-manager.ts +14 -0
- package/src/daemon/conversation-runtime-assembly.ts +145 -84
- package/src/daemon/conversation-slash.ts +37 -5
- package/src/daemon/conversation-surfaces.ts +45 -2
- package/src/daemon/conversation-tool-setup.ts +70 -3
- package/src/daemon/conversation-usage.ts +2 -0
- package/src/daemon/conversation.ts +54 -32
- package/src/daemon/disk-pressure-guard.ts +14 -2
- package/src/daemon/first-greeting.ts +10 -0
- package/src/daemon/handlers/__tests__/config-a2a-accept.test.ts +498 -0
- package/src/daemon/handlers/config-a2a.ts +160 -0
- package/src/daemon/handlers/config-model.test.ts +2 -0
- package/src/daemon/handlers/conversations.ts +90 -3
- package/src/daemon/handlers/shared.ts +92 -29
- package/src/daemon/host-bash-proxy.ts +1 -1
- package/src/daemon/host-browser-proxy.ts +5 -5
- package/src/daemon/host-cu-proxy.ts +5 -5
- package/src/daemon/host-file-proxy.ts +5 -5
- package/src/daemon/host-proxy-base.ts +4 -4
- package/src/daemon/host-transfer-proxy.ts +11 -11
- package/src/daemon/lifecycle.ts +40 -23
- package/src/daemon/meet-manifest-loader.ts +1 -7
- package/src/daemon/message-protocol.ts +4 -0
- package/src/daemon/message-types/conversations.ts +14 -9
- package/src/daemon/message-types/document-comments.ts +50 -0
- package/src/daemon/message-types/home.ts +1 -13
- package/src/daemon/message-types/messages.ts +66 -7
- package/src/daemon/message-types/surfaces.ts +3 -1
- package/src/daemon/message-types/sync.ts +14 -0
- package/src/daemon/message-types/web-activity.ts +57 -0
- package/src/daemon/plugin-source-watcher.ts +135 -3
- package/src/daemon/process-message.ts +69 -12
- package/src/daemon/shutdown-handlers.ts +24 -5
- package/src/daemon/switch-inference-profile-tool.ts +52 -0
- package/src/daemon/tool-setup-types.ts +13 -0
- package/src/daemon/trust-context.ts +6 -0
- package/src/documents/document-comments-store.test.ts +338 -0
- package/src/documents/document-comments-store.ts +237 -0
- package/src/documents/document-store.ts +202 -0
- package/src/events/relationship-state-updated.ts +25 -0
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +1 -2
- package/src/heartbeat/heartbeat-service.ts +1 -0
- package/src/home/__tests__/suggested-prompts.test.ts +33 -2
- package/src/home/feed-types.ts +6 -1
- package/src/home/home-content-refresh.ts +52 -0
- package/src/home/home-greeting-cache.ts +69 -0
- package/src/home/home-greeting.ts +85 -0
- package/src/home/suggested-prompts.ts +168 -9
- package/src/ipc/gateway-flag-listener.ts +123 -0
- package/src/ipc/skill-routes/registries.ts +8 -12
- package/src/memory/__tests__/db-async-query.test.ts +165 -0
- package/src/memory/__tests__/db-maintenance.test.ts +115 -0
- package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +241 -0
- package/src/memory/__tests__/jobs-store-job-classes.test.ts +28 -1
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +135 -2
- package/src/memory/__tests__/memory-retrospective-job.test.ts +327 -6
- package/src/memory/auto-analysis-enqueue.ts +5 -1
- package/src/memory/conversation-crud.ts +191 -100
- package/src/memory/conversation-starters-cadence.ts +3 -1
- package/src/memory/conversation-title-service.ts +19 -3
- package/src/memory/db-async-query.ts +214 -0
- package/src/memory/db-init.ts +26 -0
- package/src/memory/db-maintenance.ts +30 -21
- package/src/memory/delivery-crud.ts +41 -0
- package/src/memory/delivery-status.ts +141 -15
- package/src/memory/external-conversation-store.ts +32 -1
- package/src/memory/graph/bootstrap.ts +8 -1
- package/src/memory/graph/capability-seed.ts +7 -3
- package/src/memory/graph/conversation-graph-memory.ts +100 -17
- package/src/memory/graph/extraction.ts +1 -5
- package/src/memory/graph/graph-search.ts +7 -1
- package/src/memory/indexer.ts +28 -18
- package/src/memory/job-handlers/cleanup.ts +76 -18
- package/src/memory/job-handlers/conversation-starters.ts +1 -4
- package/src/memory/jobs/embed-pkb-file.ts +6 -1
- package/src/memory/jobs-store.ts +14 -0
- package/src/memory/jobs-worker.ts +68 -15
- package/src/memory/llm-request-log-source-clickhouse.ts +42 -2
- package/src/memory/llm-request-log-source-local.ts +7 -0
- package/src/memory/llm-request-log-source.ts +9 -2
- package/src/memory/llm-request-log-store.ts +43 -1
- package/src/memory/llm-usage-store.ts +24 -0
- package/src/memory/memory-retrospective-constants.ts +28 -0
- package/src/memory/memory-retrospective-enqueue.ts +11 -3
- package/src/memory/memory-retrospective-job.ts +413 -18
- package/src/memory/memory-retrospective-startup-cleanup.ts +3 -3
- package/src/memory/memory-v2-activation-log-store.ts +41 -14
- package/src/memory/migrations/100-core-tables.ts +1 -0
- package/src/memory/migrations/109-external-conversation-bindings.ts +1 -0
- package/src/memory/migrations/253-conversation-last-notified-profile.ts +15 -0
- package/src/memory/migrations/253-document-comments.ts +47 -0
- package/src/memory/migrations/254-external-conversation-binding-chat-name.ts +43 -0
- package/src/memory/migrations/255-channel-inbound-delivery-attempts.ts +24 -0
- package/src/memory/migrations/256-memory-v2-injection-events.ts +113 -0
- package/src/memory/migrations/257-strip-base-url-non-openai-compatible.ts +22 -0
- package/src/memory/migrations/258-onboarding-events-prior-assistants.ts +13 -0
- package/src/memory/migrations/259-conversation-cleaned-at.ts +33 -0
- package/src/memory/migrations/260-rename-cleaned-at.ts +44 -0
- package/src/memory/migrations/261-llm-usage-add-raw-usage.ts +36 -0
- package/src/memory/migrations/262-memory-v3-coactivation.ts +57 -0
- package/src/memory/migrations/263-memory-v3-auto-edges.ts +50 -0
- package/src/memory/migrations/264-llm-request-log-call-site.ts +29 -0
- package/src/memory/migrations/index.ts +34 -0
- package/src/memory/migrations/registry.ts +58 -0
- package/src/memory/onboarding-events-store.ts +7 -0
- package/src/memory/schema/calls.ts +1 -0
- package/src/memory/schema/conversations.ts +3 -0
- package/src/memory/schema/infrastructure.ts +22 -0
- package/src/memory/tool-usage-store.ts +36 -8
- package/src/memory/v2/__tests__/consolidation-job.test.ts +1 -0
- package/src/memory/v2/__tests__/harness-compare.test.ts +186 -0
- package/src/memory/v2/__tests__/harness-metrics.test.ts +74 -0
- package/src/memory/v2/__tests__/harness-oracle.test.ts +257 -0
- package/src/memory/v2/__tests__/harness-replay-input.test.ts +225 -0
- package/src/memory/v2/__tests__/harness-runner.test.ts +109 -0
- package/src/memory/v2/__tests__/injection-events.test.ts +318 -0
- package/src/memory/v2/__tests__/injection.test.ts +158 -112
- package/src/memory/v2/__tests__/page-index.test.ts +365 -1
- package/src/memory/v2/__tests__/qdrant.test.ts +36 -0
- package/src/memory/v2/__tests__/router.test.ts +660 -4
- package/src/memory/v2/consolidation-job.ts +14 -0
- package/src/memory/v2/harness/compare.ts +57 -0
- package/src/memory/v2/harness/metrics.ts +124 -0
- package/src/memory/v2/harness/oracle.ts +145 -0
- package/src/memory/v2/harness/replay-input.ts +224 -0
- package/src/memory/v2/harness/retriever.ts +74 -0
- package/src/memory/v2/harness/router-retriever.ts +43 -0
- package/src/memory/v2/harness/runner.ts +106 -0
- package/src/memory/v2/harness/trace.ts +58 -0
- package/src/memory/v2/injection-events.ts +101 -0
- package/src/memory/v2/injection.ts +42 -25
- package/src/memory/v2/page-index.ts +209 -7
- package/src/memory/v2/page-store.ts +18 -0
- package/src/memory/v2/prompts/router.ts +26 -1
- package/src/memory/v2/qdrant.ts +14 -2
- package/src/memory/v2/router.ts +369 -62
- package/src/memory/v3/__tests__/coactivation-store.test.ts +422 -0
- package/src/memory/v3/__tests__/consolidation-job.test.ts +468 -0
- package/src/memory/v3/__tests__/edge-learning-job.test.ts +324 -0
- package/src/memory/v3/__tests__/edges.test.ts +563 -0
- package/src/memory/v3/__tests__/filter.test.ts +512 -0
- package/src/memory/v3/__tests__/gate.test.ts +574 -0
- package/src/memory/v3/__tests__/index-composition.test.ts +233 -0
- package/src/memory/v3/__tests__/loop.test.ts +530 -0
- package/src/memory/v3/__tests__/retriever.test.ts +226 -0
- package/src/memory/v3/__tests__/scouts.test.ts +440 -0
- package/src/memory/v3/__tests__/shadow-middleware.test.ts +312 -0
- package/src/memory/v3/__tests__/system-prompts.test.ts +154 -0
- package/src/memory/v3/__tests__/traversal.test.ts +469 -0
- package/src/memory/v3/__tests__/tree-index.test.ts +280 -0
- package/src/memory/v3/__tests__/tree-store.test.ts +529 -0
- package/src/memory/v3/__tests__/tree-walk.test.ts +707 -0
- package/src/memory/v3/__tests__/validate.test.ts +245 -0
- package/src/memory/v3/auto-edges.ts +223 -0
- package/src/memory/v3/coactivation-store.ts +124 -0
- package/src/memory/v3/consolidation-job.ts +323 -0
- package/src/memory/v3/edge-learning-job.ts +160 -0
- package/src/memory/v3/edges.ts +249 -0
- package/src/memory/v3/filter.ts +281 -0
- package/src/memory/v3/gate.ts +334 -0
- package/src/memory/v3/index-composition.ts +113 -0
- package/src/memory/v3/llm-capture.ts +46 -0
- package/src/memory/v3/loop.ts +382 -0
- package/src/memory/v3/maintenance.ts +144 -0
- package/src/memory/v3/prompt-context.ts +33 -0
- package/src/memory/v3/prompts/consolidation.ts +458 -0
- package/src/memory/v3/prompts/system-prompts.ts +196 -0
- package/src/memory/v3/retriever.ts +33 -0
- package/src/memory/v3/scouts.ts +420 -0
- package/src/memory/v3/shadow-middleware.ts +305 -0
- package/src/memory/v3/traversal.ts +206 -0
- package/src/memory/v3/tree-index.ts +237 -0
- package/src/memory/v3/tree-store.ts +394 -0
- package/src/memory/v3/tree-walk.ts +351 -0
- package/src/memory/v3/types.ts +65 -0
- package/src/memory/v3/validate.ts +300 -0
- package/src/messaging/providers/index.ts +7 -1
- package/src/messaging/providers/slack/__tests__/adapter-mention-rendering.test.ts +329 -3
- package/src/messaging/providers/slack/__tests__/adapter-token-routing.test.ts +34 -1
- package/src/messaging/providers/slack/adapter.ts +178 -25
- package/src/messaging/providers/slack/api.test.ts +54 -0
- package/src/messaging/providers/slack/api.ts +119 -3
- package/src/messaging/providers/slack/client.ts +12 -0
- package/src/messaging/providers/slack/deep-link.ts +20 -1
- package/src/messaging/providers/slack/message-metadata.test.ts +48 -0
- package/src/messaging/providers/slack/message-metadata.ts +156 -0
- package/src/messaging/providers/slack/render-transcript.test.ts +107 -75
- package/src/messaging/providers/slack/render-transcript.ts +176 -49
- package/src/messaging/providers/slack/send.test.ts +77 -0
- package/src/messaging/providers/slack/send.ts +8 -2
- package/src/messaging/providers/slack/types.ts +14 -0
- package/src/notifications/__tests__/emit-signal-home-feed.test.ts +4 -1
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +116 -54
- package/src/notifications/adapters/macos.ts +18 -1
- package/src/notifications/adapters/platform.ts +1 -1
- package/src/notifications/conversation-seed-composer.ts +14 -2
- package/src/notifications/decision-engine.ts +1 -4
- package/src/notifications/deferred-emit.ts +135 -0
- package/src/notifications/emit-signal.ts +38 -50
- package/src/notifications/home-feed-side-effect.ts +60 -30
- package/src/oauth/connect-orchestrator.ts +3 -0
- package/src/oauth/credential-token-resolver.ts +2 -0
- package/src/oauth/manual-token-connection.ts +19 -0
- package/src/oauth/oauth-store.ts +12 -0
- package/src/oauth/seed-providers.ts +22 -0
- package/src/permissions/prompter.ts +8 -5
- package/src/permissions/question-prompter.ts +5 -2
- package/src/permissions/secret-prompter.ts +6 -3
- package/src/plugin-api/index.ts +4 -0
- package/src/plugin-api/types.ts +7 -33
- package/src/plugins/defaults/index.ts +6 -0
- package/src/plugins/defaults/injectors.ts +100 -20
- package/src/plugins/external-plugin-loader.ts +5 -68
- package/src/plugins/types.ts +11 -16
- package/src/proactive-artifact/aux-message-injector.ts +17 -4
- package/src/prompts/__tests__/system-prompt.test.ts +46 -2
- package/src/prompts/__tests__/task-progress-hint-section.test.ts +3 -9
- package/src/prompts/normalize-onboarding.ts +40 -0
- package/src/prompts/persona-resolver.ts +36 -21
- package/src/prompts/sections.ts +69 -19
- package/src/prompts/system-prompt.ts +118 -216
- package/src/prompts/template-detection.ts +37 -0
- package/src/prompts/templates/BOOTSTRAP-CONTENT-AUTOMATION.md +141 -0
- package/src/prompts/templates/BOOTSTRAP.md +10 -2
- package/src/prompts/templates/VOICE.md +3 -0
- package/src/prompts/templates/system-sections.ts +281 -9
- package/src/providers/__tests__/connection-model-compat.test.ts +234 -0
- package/src/providers/__tests__/retry-callsite.test.ts +85 -5
- package/src/providers/anthropic/client.ts +159 -66
- package/src/providers/call-site-routing.ts +14 -2
- package/src/providers/connection-model-compat.ts +38 -0
- package/src/providers/connection-resolution.ts +16 -2
- package/src/providers/fireworks/client.ts +20 -2
- package/src/providers/gemini/client.ts +49 -6
- package/src/providers/inference/__tests__/base-url-route-validation.test.ts +342 -0
- package/src/providers/inference/__tests__/base-url-security.test.ts +189 -0
- package/src/providers/inference/__tests__/codex-token-refresh.test.ts +254 -0
- package/src/providers/inference/adapter-factory.ts +18 -1
- package/src/providers/inference/auth.ts +3 -3
- package/src/providers/inference/codex-token-refresh.ts +128 -0
- package/src/providers/inference/resolve-auth.ts +49 -6
- package/src/providers/minimax/client.ts +106 -0
- package/src/providers/model-catalog.ts +91 -1
- package/src/providers/model-intents.ts +1 -1
- package/src/providers/openai/chat-completions-provider.ts +63 -23
- package/src/providers/openai/codex-models.ts +18 -0
- package/src/providers/openai/responses-provider.ts +86 -23
- package/src/providers/openrouter/client.ts +5 -1
- package/src/providers/provider-send-message.ts +7 -1
- package/src/providers/retry.ts +34 -3
- package/src/providers/thinking-config.ts +26 -1
- package/src/providers/types.ts +25 -0
- package/src/providers/usage-tracking.ts +2 -0
- package/src/runtime/AGENTS.md +2 -2
- package/src/runtime/__tests__/agent-wake.test.ts +214 -0
- package/src/runtime/__tests__/background-job-runner.test.ts +128 -0
- package/src/runtime/agent-wake.ts +152 -56
- package/src/runtime/assistant-event-hub.ts +76 -6
- package/src/runtime/auth/route-policy.ts +43 -3
- package/src/runtime/background-job-runner.ts +26 -0
- package/src/runtime/btw-sidechain.ts +0 -6
- package/src/runtime/channel-reply-delivery.ts +182 -47
- package/src/runtime/channel-retry-sweep.ts +141 -16
- package/src/runtime/http-types.ts +7 -6
- package/src/runtime/migrations/vbundle-builder.ts +10 -3
- package/src/runtime/pending-interactions.ts +50 -8
- package/src/runtime/routes/__tests__/content-source-routes.test.ts +162 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +161 -1
- package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +14 -0
- package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +290 -0
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +512 -0
- package/src/runtime/routes/__tests__/sanity-routes.test.ts +280 -0
- package/src/runtime/routes/__tests__/slack-channel-routes.test.ts +266 -0
- package/src/runtime/routes/acp-routes.test.ts +255 -6
- package/src/runtime/routes/acp-routes.ts +8 -1
- package/src/runtime/routes/approval-routes.ts +4 -1
- package/src/runtime/routes/avatar-routes.ts +10 -10
- package/src/runtime/routes/background-wake-routes.ts +188 -0
- package/src/runtime/routes/browser-tabs-routes.ts +200 -0
- package/src/runtime/routes/btw-routes.ts +0 -6
- package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +246 -0
- package/src/runtime/routes/content-source-routes.ts +78 -0
- package/src/runtime/routes/conversation-cli-routes.ts +147 -2
- package/src/runtime/routes/conversation-list-routes.ts +12 -4
- package/src/runtime/routes/conversation-management-routes.ts +77 -20
- package/src/runtime/routes/conversation-query-routes.ts +196 -31
- package/src/runtime/routes/conversation-routes.ts +472 -425
- package/src/runtime/routes/conversation-starter-routes.ts +6 -3
- package/src/runtime/routes/disk-pressure-routes.ts +1 -1
- package/src/runtime/routes/document-comments-routes.ts +287 -0
- package/src/runtime/routes/documents-routes.ts +33 -0
- package/src/runtime/routes/domain-routes.ts +60 -10
- package/src/runtime/routes/email-routes.ts +5 -2
- package/src/runtime/routes/events-routes.ts +54 -10
- package/src/runtime/routes/group-routes.ts +24 -8
- package/src/runtime/routes/home-feed-routes.ts +6 -3
- package/src/runtime/routes/host-app-control-routes.ts +1 -1
- package/src/runtime/routes/host-browser-routes.ts +17 -2
- package/src/runtime/routes/host-cu-routes.ts +2 -2
- package/src/runtime/routes/identity-routes.ts +21 -0
- package/src/runtime/routes/inbound-message-handler.ts +288 -58
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +96 -3
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +365 -6
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +283 -82
- package/src/runtime/routes/index.ts +20 -4
- package/src/runtime/routes/inference-profile-session-handler.ts +22 -12
- package/src/runtime/routes/inference-profile-session-routes.ts +7 -1
- package/src/runtime/routes/inference-provider-connection-routes.ts +63 -7
- package/src/runtime/routes/integrations/a2a.ts +60 -1
- package/src/runtime/routes/llm-call-sites-routes.ts +32 -5
- package/src/runtime/routes/log-export-routes.ts +39 -0
- package/src/runtime/routes/memory-item-routes.ts +8 -3
- package/src/runtime/routes/memory-v2-routes.ts +427 -0
- package/src/runtime/routes/memory-v3-routes.ts +316 -0
- package/src/runtime/routes/migration-routes.ts +21 -24
- package/src/runtime/routes/notification-routes.ts +19 -2
- package/src/runtime/routes/plugins-routes.ts +337 -0
- package/src/runtime/routes/question-routes.ts +4 -1
- package/src/runtime/routes/rename-conversation-routes.ts +6 -2
- package/src/runtime/routes/sanity-routes.ts +159 -0
- package/src/runtime/routes/secret-routes.ts +25 -5
- package/src/runtime/routes/settings-routes.ts +12 -11
- package/src/runtime/routes/slack-channel-routes.ts +188 -0
- package/src/runtime/routes/workspace-routes.ts +25 -10
- package/src/runtime/services/conversation-serializer.ts +30 -4
- package/src/runtime/sync/resource-sync-events.ts +106 -38
- package/src/runtime/sync/sync-publisher.test.ts +49 -0
- package/src/runtime/sync/sync-publisher.ts +2 -1
- package/src/runtime/verification-outbound-actions.ts +73 -1
- package/src/schedule/integration-status.ts +3 -1
- package/src/security/__tests__/oauth2-device-code.test.ts +479 -0
- package/src/security/oauth2-device-code.ts +307 -0
- package/src/security/oauth2.ts +26 -9
- package/src/security/secure-keys.ts +5 -0
- package/src/skills/catalog-install.ts +6 -2
- package/src/telemetry/types.ts +12 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +48 -0
- package/src/telemetry/usage-telemetry-reporter.ts +1 -0
- package/src/tools/acp/spawn.test.ts +119 -0
- package/src/tools/acp/spawn.ts +15 -2
- package/src/tools/apps/definitions.ts +2 -8
- package/src/tools/ask-question/ask-question-tool.test.ts +3 -3
- package/src/tools/ask-question/ask-question-tool.ts +38 -45
- package/src/tools/browser/__tests__/pinned-tabs.test.ts +150 -0
- package/src/tools/browser/browser-execution.ts +106 -0
- package/src/tools/browser/cdp-client/__tests__/browser-tabs-factory.test.ts +402 -0
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +28 -0
- package/src/tools/browser/cdp-client/__tests__/types.test.ts +4 -0
- package/src/tools/browser/cdp-client/cdp-inspect-client.ts +22 -0
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +42 -2
- package/src/tools/browser/cdp-client/factory.ts +171 -4
- package/src/tools/browser/cdp-client/local-cdp-client.ts +21 -0
- package/src/tools/browser/cdp-client/types.ts +101 -0
- package/src/tools/browser/pinned-tabs.ts +146 -0
- package/src/tools/computer-use/definitions.ts +22 -78
- package/src/tools/credential-execution/make-authenticated-request.ts +3 -9
- package/src/tools/credential-execution/manage-secure-command-tool.ts +3 -9
- package/src/tools/credential-execution/run-authenticated-command.ts +3 -9
- package/src/tools/credentials/vault.ts +3 -9
- package/src/tools/document/document-comment-tool.test.ts +379 -0
- package/src/tools/document/document-comment-tool.ts +156 -0
- package/src/tools/document/document-tool.ts +187 -2
- package/src/tools/execution-target.ts +21 -23
- package/src/tools/executor.ts +6 -1
- package/src/tools/filesystem/edit.ts +3 -9
- package/src/tools/filesystem/list.ts +3 -9
- package/src/tools/filesystem/read.ts +3 -9
- package/src/tools/filesystem/write.ts +3 -9
- package/src/tools/host-filesystem/edit.ts +3 -9
- package/src/tools/host-filesystem/read.ts +3 -9
- package/src/tools/host-filesystem/transfer.ts +3 -9
- package/src/tools/host-filesystem/write.ts +3 -9
- package/src/tools/host-terminal/host-shell.ts +3 -9
- package/src/tools/mcp/mcp-tool-factory.ts +1 -8
- package/src/tools/memory/register.test.ts +1 -1
- package/src/tools/memory/register.ts +4 -9
- package/src/tools/network/__tests__/web-fetch-metadata.test.ts +229 -0
- package/src/tools/network/__tests__/web-search-metadata.test.ts +346 -0
- package/src/tools/network/domain-normalize.ts +17 -0
- package/src/tools/network/web-fetch.ts +216 -73
- package/src/tools/network/web-search.ts +216 -98
- package/src/tools/registry.ts +7 -23
- package/src/tools/schema-transforms.ts +1 -1
- package/src/tools/skills/execute.ts +3 -9
- package/src/tools/skills/load.ts +3 -9
- package/src/tools/skills/skill-tool-factory.ts +1 -8
- package/src/tools/subagent/notify-parent.ts +3 -9
- package/src/tools/system/request-permission.ts +3 -9
- package/src/tools/terminal/safe-env.ts +3 -2
- package/src/tools/terminal/shell.ts +3 -9
- package/src/tools/tool-approval-handler.ts +19 -12
- package/src/tools/tool-defaults.ts +94 -0
- package/src/tools/types.ts +31 -98
- package/src/tools/ui-surface/definitions.ts +9 -23
- package/src/types/onboarding-context.ts +4 -0
- package/src/usage/pricing.ts +23 -0
- package/src/usage/types.ts +12 -0
- package/src/util/__tests__/favicon.test.ts +84 -0
- package/src/util/favicon.ts +40 -0
- package/src/util/logger.ts +16 -7
- package/src/util/platform.ts +7 -7
- package/src/util/sqlite3-runtime.ts +65 -0
- package/src/workspace/git-service.ts +75 -4
- package/src/workspace/migrations/086-revert-stale-gemini-mis-rewrites.ts +1 -0
- package/src/workspace/migrations/088-deprecate-background-conversation-override.ts +103 -0
- package/src/workspace/migrations/089-move-memory-tree-out-of-v3.ts +86 -0
- package/src/workspace/migrations/registry.ts +4 -0
- package/src/__tests__/compaction-strip-metadata-clear.test.ts +0 -206
- package/src/__tests__/message-complete-display-id.test.ts +0 -175
- package/src/config/bundled-skills/document/SKILL.md +0 -54
- package/src/config/bundled-skills/document/TOOLS.json +0 -106
- package/src/daemon/seed-files.ts +0 -18
- package/src/prompts/cache-boundary.ts +0 -8
- package/src/runtime/routes/interface-routes.ts +0 -43
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-create.ts +0 -0
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-delete.ts +0 -0
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-list.ts +0 -0
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-read.ts +0 -0
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-update.ts +0 -0
|
@@ -68,9 +68,6 @@ import { getLogger } from "../util/logger.js";
|
|
|
68
68
|
|
|
69
69
|
const log = getLogger("agent-wake");
|
|
70
70
|
|
|
71
|
-
/** Number of messages injected for the wake hint (user + assistant + user). */
|
|
72
|
-
const WAKE_HINT_MESSAGE_COUNT = 3;
|
|
73
|
-
|
|
74
71
|
/** Static preamble user message — no dynamic content, injection-safe. */
|
|
75
72
|
const WAKE_PREAMBLE =
|
|
76
73
|
"[system] The following assistant message comes from an external system.";
|
|
@@ -196,6 +193,51 @@ export interface WakeOptions {
|
|
|
196
193
|
* tune the model/profile and observability bucket independently.
|
|
197
194
|
*/
|
|
198
195
|
callSite?: LLMCallSite;
|
|
196
|
+
/**
|
|
197
|
+
* Role to use for the injected hint message. Defaults to `"assistant"` so
|
|
198
|
+
* the hint is sandwiched between two static user bookends — the canonical
|
|
199
|
+
* anti-injection pattern for hints that may carry text from an external
|
|
200
|
+
* source. Trusted internal callers (e.g. fork-based memory retrospectives)
|
|
201
|
+
* can pass `"user"` to inject a single user-role message containing the
|
|
202
|
+
* hint directly, which reads more naturally as an instruction from the
|
|
203
|
+
* user/system rather than a self-directed assistant note.
|
|
204
|
+
*/
|
|
205
|
+
hintRole?: "assistant" | "user";
|
|
206
|
+
/**
|
|
207
|
+
* Documented intent: this wake must not trigger auto-threshold compaction.
|
|
208
|
+
*
|
|
209
|
+
* Today this is automatically satisfied because the wake invokes
|
|
210
|
+
* `target.agentLoop.run()` directly, bypassing the daemon orchestrator
|
|
211
|
+
* (`conversation-agent-loop.ts`) where the compaction pipeline lives. The
|
|
212
|
+
* flag is recorded in the wake's structured log line so operators can
|
|
213
|
+
* verify the contract holds across refactors. If compaction is ever moved
|
|
214
|
+
* into `AgentLoop.run` or invoked from the wake path, callers that pass
|
|
215
|
+
* `true` here MUST be updated to suppress it; callers that pass `false`
|
|
216
|
+
* (or omit it) MUST tolerate compaction firing.
|
|
217
|
+
*
|
|
218
|
+
* Used by fork-based memory retrospectives: the wake operates on a
|
|
219
|
+
* freshly-forked conversation that may already be near (or past) the
|
|
220
|
+
* source's auto-threshold, but the goal is to operate on that exact
|
|
221
|
+
* context — running a compaction LLM call before the wake's own first
|
|
222
|
+
* call would waste tokens and defeat prompt-cache reuse.
|
|
223
|
+
*/
|
|
224
|
+
suppressAutoCompaction?: boolean;
|
|
225
|
+
/**
|
|
226
|
+
* Skip injection of the hint sandwich entirely. Used when the caller has
|
|
227
|
+
* already persisted the instruction as a real message in the conversation
|
|
228
|
+
* (e.g. fork-based memory retrospectives that append a user message to the
|
|
229
|
+
* forked conversation before waking). When `true`, `hint` is ignored.
|
|
230
|
+
*/
|
|
231
|
+
skipHintInjection?: boolean;
|
|
232
|
+
/**
|
|
233
|
+
* Skip injection of the "Conversation Woke" `ui_surface` card into the
|
|
234
|
+
* first assistant tail message and the corresponding live
|
|
235
|
+
* `onWakeProducedOutput` broadcast. Default false (existing behavior).
|
|
236
|
+
* Used by callers whose conversation context already makes it obvious
|
|
237
|
+
* that the agent's output came from a wake (e.g. fork-based memory
|
|
238
|
+
* retrospectives whose conversation title already says "(Retrospective)").
|
|
239
|
+
*/
|
|
240
|
+
suppressWakeSurface?: boolean;
|
|
199
241
|
}
|
|
200
242
|
|
|
201
243
|
/**
|
|
@@ -224,13 +266,18 @@ export interface WakeResult {
|
|
|
224
266
|
*/
|
|
225
267
|
export interface WakeDeps {
|
|
226
268
|
/**
|
|
227
|
-
* Resolve the wake target for a
|
|
269
|
+
* Resolve the wake target for a wake invocation.
|
|
228
270
|
* Returns `null` if the conversation doesn't exist, `"archived"` if it
|
|
229
271
|
* exists but is archived, or a `WakeTarget` to proceed with the wake.
|
|
272
|
+
*
|
|
273
|
+
* Receives the full {@link WakeOptions} so the default resolver can
|
|
274
|
+
* thread `trustContext` into `getOrCreateConversation`. Without that
|
|
275
|
+
* threading, the conversation hydrates with `trustContext === undefined`
|
|
276
|
+
* and `loadFromDb` fail-closes to `trustClass: "unknown"`, which filters
|
|
277
|
+
* out every guardian-provenance message — fatal for fork-based memory
|
|
278
|
+
* retrospectives.
|
|
230
279
|
*/
|
|
231
|
-
resolveTarget: (
|
|
232
|
-
conversationId: string,
|
|
233
|
-
) => Promise<WakeTarget | null | "archived">;
|
|
280
|
+
resolveTarget: (opts: WakeOptions) => Promise<WakeTarget | null | "archived">;
|
|
234
281
|
/** Timestamp source (for deterministic tests). */
|
|
235
282
|
now?: () => number;
|
|
236
283
|
}
|
|
@@ -242,8 +289,9 @@ export interface WakeDeps {
|
|
|
242
289
|
// `getOrCreateConversation`, and `conversationToWakeTarget`.
|
|
243
290
|
|
|
244
291
|
async function defaultResolveTarget(
|
|
245
|
-
|
|
292
|
+
opts: WakeOptions,
|
|
246
293
|
): Promise<WakeTarget | null | "archived"> {
|
|
294
|
+
const { conversationId } = opts;
|
|
247
295
|
// Lazy-import daemon modules to avoid pulling heavyweight transitive
|
|
248
296
|
// deps (conversation store → config/loader → provider catalogs) at
|
|
249
297
|
// module-evaluation time. Callers that only import agent-wake for
|
|
@@ -264,7 +312,15 @@ async function defaultResolveTarget(
|
|
|
264
312
|
);
|
|
265
313
|
return "archived";
|
|
266
314
|
}
|
|
267
|
-
|
|
315
|
+
// Thread trustContext through to getOrCreateConversation so the
|
|
316
|
+
// hydration path applies setTrustContext + ensureActorScopedHistory
|
|
317
|
+
// (conversation-store.ts:281-289) BEFORE the agent loop's per-turn
|
|
318
|
+
// snapshot reads. Without this, fork-based memory retrospectives see
|
|
319
|
+
// an empty history because loadFromDb ran with trustClass="unknown"
|
|
320
|
+
// and filtered out every guardian-provenance message.
|
|
321
|
+
const conversation = await getOrCreateConversation(conversationId, {
|
|
322
|
+
trustContext: opts.trustContext,
|
|
323
|
+
});
|
|
268
324
|
return conversationToWakeTarget(conversation);
|
|
269
325
|
} catch (err) {
|
|
270
326
|
log.warn(
|
|
@@ -376,6 +432,7 @@ function buildWakeTurnContext(
|
|
|
376
432
|
*/
|
|
377
433
|
function inspectWakeOutput(
|
|
378
434
|
baselineLength: number,
|
|
435
|
+
hintMessageCount: number,
|
|
379
436
|
updatedHistory: Message[],
|
|
380
437
|
): {
|
|
381
438
|
tailMessages: Message[];
|
|
@@ -383,10 +440,10 @@ function inspectWakeOutput(
|
|
|
383
440
|
toolUseNames: string[];
|
|
384
441
|
} {
|
|
385
442
|
// The agent loop appends messages onto the history it was given. We
|
|
386
|
-
// injected
|
|
387
|
-
//
|
|
388
|
-
// the run.
|
|
389
|
-
const firstAssistantIndex = baselineLength +
|
|
443
|
+
// injected `hintMessageCount` hint messages (0, 1, or 3 depending on
|
|
444
|
+
// hint mode), so anything at index >= baselineLength + hintMessageCount
|
|
445
|
+
// came from the run.
|
|
446
|
+
const firstAssistantIndex = baselineLength + hintMessageCount;
|
|
390
447
|
if (updatedHistory.length <= firstAssistantIndex) {
|
|
391
448
|
return { tailMessages: [], hasVisibleText: false, toolUseNames: [] };
|
|
392
449
|
}
|
|
@@ -436,7 +493,7 @@ export async function wakeAgentForOpportunity(
|
|
|
436
493
|
const startedAt = nowFn();
|
|
437
494
|
|
|
438
495
|
return runSingleFlight(conversationId, async () => {
|
|
439
|
-
const resolved = await resolveTarget(
|
|
496
|
+
const resolved = await resolveTarget(opts);
|
|
440
497
|
if (resolved === "archived") {
|
|
441
498
|
log.info(
|
|
442
499
|
{ conversationId, source },
|
|
@@ -505,28 +562,45 @@ export async function wakeAgentForOpportunity(
|
|
|
505
562
|
// tail-slice math would skip every message.
|
|
506
563
|
const baselineLength = baseline.length;
|
|
507
564
|
const wakeTurnContext = buildWakeTurnContext(opts, diskPressureDecision);
|
|
508
|
-
|
|
509
|
-
//
|
|
510
|
-
//
|
|
511
|
-
//
|
|
512
|
-
//
|
|
513
|
-
//
|
|
514
|
-
//
|
|
515
|
-
//
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
565
|
+
// Build the hint injection. Three modes:
|
|
566
|
+
// - `skipHintInjection`: caller has already persisted an instruction
|
|
567
|
+
// message into the conversation history (typical for fork-based
|
|
568
|
+
// memory retrospectives that append a user message before waking).
|
|
569
|
+
// - `hintRole === "user"`: single user-role message containing the
|
|
570
|
+
// hint directly. Used by trusted internal callers where the hint
|
|
571
|
+
// reads naturally as an instruction.
|
|
572
|
+
// - default (`hintRole === "assistant"`): sandwich the hint as an
|
|
573
|
+
// assistant message between two hardcoded user bookends. The
|
|
574
|
+
// assistant role defangs prompt injection (LLMs don't follow
|
|
575
|
+
// instructions in their own prior output) and the trailing user
|
|
576
|
+
// message satisfies providers that reject assistant prefill.
|
|
577
|
+
const hintRole = opts.hintRole ?? "assistant";
|
|
578
|
+
const wakeMessages: Message[] = opts.skipHintInjection
|
|
579
|
+
? []
|
|
580
|
+
: hintRole === "user"
|
|
581
|
+
? [
|
|
582
|
+
{
|
|
583
|
+
role: "user",
|
|
584
|
+
content: [{ type: "text", text: hint }],
|
|
585
|
+
},
|
|
586
|
+
]
|
|
587
|
+
: [
|
|
588
|
+
{
|
|
589
|
+
role: "user",
|
|
590
|
+
content: [{ type: "text", text: WAKE_PREAMBLE }],
|
|
591
|
+
},
|
|
592
|
+
{
|
|
593
|
+
role: "assistant",
|
|
594
|
+
content: [
|
|
595
|
+
{ type: "text", text: `[opportunity:${source}] ${hint}` },
|
|
596
|
+
],
|
|
597
|
+
},
|
|
598
|
+
{
|
|
599
|
+
role: "user",
|
|
600
|
+
content: [{ type: "text", text: WAKE_POSTAMBLE }],
|
|
601
|
+
},
|
|
602
|
+
];
|
|
603
|
+
const wakeHintMessageCount = wakeMessages.length;
|
|
530
604
|
const runInput: Message[] = [...baseline, ...wakeMessages];
|
|
531
605
|
|
|
532
606
|
// Event handling runs in two modes. While `mode === "buffering"`,
|
|
@@ -566,6 +640,7 @@ export async function wakeAgentForOpportunity(
|
|
|
566
640
|
JSON.stringify(record.rawResponse),
|
|
567
641
|
undefined,
|
|
568
642
|
record.provider,
|
|
643
|
+
"mainAgent",
|
|
569
644
|
);
|
|
570
645
|
} catch (err) {
|
|
571
646
|
log.warn(
|
|
@@ -663,26 +738,28 @@ export async function wakeAgentForOpportunity(
|
|
|
663
738
|
const goLive = (currentHistory: Message[]): void => {
|
|
664
739
|
if (mode === "live") return;
|
|
665
740
|
if (!surfaceInjected) {
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
firstAssistant.content
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
data: {
|
|
741
|
+
if (!opts.suppressWakeSurface) {
|
|
742
|
+
const tailStart = baselineLength + wakeHintMessageCount;
|
|
743
|
+
const tail = currentHistory.slice(tailStart);
|
|
744
|
+
const firstAssistant = tail.find((m) => m.role === "assistant");
|
|
745
|
+
if (firstAssistant && Array.isArray(firstAssistant.content)) {
|
|
746
|
+
firstAssistant.content.unshift({
|
|
747
|
+
type: "ui_surface",
|
|
748
|
+
surfaceId: wakeSurfaceId,
|
|
749
|
+
surfaceType: "card",
|
|
676
750
|
title: "Conversation Woke",
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
751
|
+
data: {
|
|
752
|
+
title: "Conversation Woke",
|
|
753
|
+
body: hint,
|
|
754
|
+
metadata: [{ label: "Source", value: source }],
|
|
755
|
+
},
|
|
756
|
+
display: "inline",
|
|
757
|
+
} as never);
|
|
758
|
+
}
|
|
682
759
|
}
|
|
683
760
|
surfaceInjected = true;
|
|
684
761
|
}
|
|
685
|
-
if (target.onWakeProducedOutput) {
|
|
762
|
+
if (!opts.suppressWakeSurface && target.onWakeProducedOutput) {
|
|
686
763
|
try {
|
|
687
764
|
target.onWakeProducedOutput(source, hint, wakeSurfaceId);
|
|
688
765
|
} catch (err) {
|
|
@@ -721,8 +798,7 @@ export async function wakeAgentForOpportunity(
|
|
|
721
798
|
const flushPendingTail = async (
|
|
722
799
|
currentHistory: Message[],
|
|
723
800
|
): Promise<void> => {
|
|
724
|
-
const start =
|
|
725
|
-
baselineLength + WAKE_HINT_MESSAGE_COUNT + persistedTailIndex;
|
|
801
|
+
const start = baselineLength + wakeHintMessageCount + persistedTailIndex;
|
|
726
802
|
if (start >= currentHistory.length) return;
|
|
727
803
|
const newMessages = currentHistory.slice(start);
|
|
728
804
|
for (const msg of newMessages) {
|
|
@@ -825,7 +901,11 @@ export async function wakeAgentForOpportunity(
|
|
|
825
901
|
tailMessages,
|
|
826
902
|
hasVisibleText,
|
|
827
903
|
toolUseNames: names,
|
|
828
|
-
} = inspectWakeOutput(
|
|
904
|
+
} = inspectWakeOutput(
|
|
905
|
+
baselineLength,
|
|
906
|
+
wakeHintMessageCount,
|
|
907
|
+
updatedHistory,
|
|
908
|
+
);
|
|
829
909
|
toolUseNames = names;
|
|
830
910
|
producedToolCalls = names.length > 0;
|
|
831
911
|
const producedOutput = producedToolCalls || hasVisibleText;
|
|
@@ -904,9 +984,19 @@ export async function wakeAgentForOpportunity(
|
|
|
904
984
|
}
|
|
905
985
|
|
|
906
986
|
const durationMs = nowFn() - startedAt;
|
|
987
|
+
const suppressAutoCompaction = opts.suppressAutoCompaction === true;
|
|
988
|
+
const suppressWakeSurface = opts.suppressWakeSurface === true;
|
|
907
989
|
if (runError) {
|
|
908
990
|
log.error(
|
|
909
|
-
{
|
|
991
|
+
{
|
|
992
|
+
conversationId,
|
|
993
|
+
source,
|
|
994
|
+
durationMs,
|
|
995
|
+
suppressAutoCompaction,
|
|
996
|
+
suppressWakeSurface,
|
|
997
|
+
hintRole,
|
|
998
|
+
err: runError,
|
|
999
|
+
},
|
|
910
1000
|
"agent-wake: agent loop threw; treating as no-op",
|
|
911
1001
|
);
|
|
912
1002
|
} else if (tailMessageCount === 0) {
|
|
@@ -915,6 +1005,9 @@ export async function wakeAgentForOpportunity(
|
|
|
915
1005
|
source,
|
|
916
1006
|
conversationId,
|
|
917
1007
|
durationMs,
|
|
1008
|
+
suppressAutoCompaction,
|
|
1009
|
+
suppressWakeSurface,
|
|
1010
|
+
hintRole,
|
|
918
1011
|
producedToolCalls: false,
|
|
919
1012
|
toolNamesCalled: [],
|
|
920
1013
|
},
|
|
@@ -926,6 +1019,9 @@ export async function wakeAgentForOpportunity(
|
|
|
926
1019
|
source,
|
|
927
1020
|
conversationId,
|
|
928
1021
|
durationMs,
|
|
1022
|
+
suppressAutoCompaction,
|
|
1023
|
+
suppressWakeSurface,
|
|
1024
|
+
hintRole,
|
|
929
1025
|
producedToolCalls,
|
|
930
1026
|
toolNamesCalled: toolUseNames,
|
|
931
1027
|
tailMessageCount,
|
|
@@ -247,6 +247,10 @@ export class AssistantEventHub {
|
|
|
247
247
|
* Publish an event to all matching subscribers.
|
|
248
248
|
*
|
|
249
249
|
* Matching rules:
|
|
250
|
+
* - if `excludeClientId` is set, the subscriber with that clientId is
|
|
251
|
+
* skipped regardless of every other rule (self-echo suppression — the
|
|
252
|
+
* client that originated the mutation does not receive its own
|
|
253
|
+
* invalidation back through the hub).
|
|
250
254
|
* - if `targetClientId` is set, deliver only to the subscriber with that
|
|
251
255
|
* clientId, bypassing the conversation-id filter entirely (the web-origin
|
|
252
256
|
* event's conversationId differs from the macOS client's subscribed
|
|
@@ -255,6 +259,11 @@ export class AssistantEventHub {
|
|
|
255
259
|
* `event.conversationId` must equal it
|
|
256
260
|
* - if `targetCapability` is set, only subscribers whose capabilities include
|
|
257
261
|
* it receive the event; untargeted events go to all
|
|
262
|
+
* - if `targetInterfaceId` is set, only client subscribers whose
|
|
263
|
+
* `interfaceId` matches receive the event; process subscribers and
|
|
264
|
+
* non-matching clients are skipped. Used to narrow legacy
|
|
265
|
+
* broadcasts (e.g. `conversation_list_invalidated`) to a specific
|
|
266
|
+
* client surface during a migration window.
|
|
258
267
|
*
|
|
259
268
|
* Fanout is isolated: a throwing or rejecting subscriber does not abort
|
|
260
269
|
* delivery to remaining subscribers.
|
|
@@ -264,6 +273,15 @@ export class AssistantEventHub {
|
|
|
264
273
|
options?: {
|
|
265
274
|
targetCapability?: HostProxyCapability;
|
|
266
275
|
targetClientId?: string;
|
|
276
|
+
targetInterfaceId?: InterfaceId;
|
|
277
|
+
/**
|
|
278
|
+
* Skip the subscriber with this `clientId`. Used for self-echo
|
|
279
|
+
* suppression on `sync_changed`: the route handler echoes the
|
|
280
|
+
* originating tab's `X-Vellum-Client-Id` back on the event, and the
|
|
281
|
+
* hub uses it here to avoid re-delivering the invalidation to the
|
|
282
|
+
* tab that already mutated its own optimistic state.
|
|
283
|
+
*/
|
|
284
|
+
excludeClientId?: string;
|
|
267
285
|
},
|
|
268
286
|
): Promise<void> {
|
|
269
287
|
if (event.conversationId) {
|
|
@@ -276,12 +294,33 @@ export class AssistantEventHub {
|
|
|
276
294
|
|
|
277
295
|
const targetCapability = options?.targetCapability;
|
|
278
296
|
const targetClientId = options?.targetClientId;
|
|
297
|
+
const targetInterfaceId = options?.targetInterfaceId;
|
|
298
|
+
const excludeClientId = options?.excludeClientId;
|
|
279
299
|
const snapshot = Array.from(this.subscribers);
|
|
280
300
|
const errors: unknown[] = [];
|
|
281
301
|
|
|
282
302
|
for (const entry of snapshot) {
|
|
283
303
|
if (!entry.active) continue;
|
|
284
304
|
|
|
305
|
+
// Self-echo suppression: the originating client never receives the
|
|
306
|
+
// event back. Checked before every other rule so it composes with
|
|
307
|
+
// both targeted and untargeted broadcasts.
|
|
308
|
+
if (
|
|
309
|
+
excludeClientId != null &&
|
|
310
|
+
entry.type === "client" &&
|
|
311
|
+
entry.clientId === excludeClientId
|
|
312
|
+
) {
|
|
313
|
+
continue;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// Interface targeting: skip any subscriber that is not a client of
|
|
317
|
+
// the requested interface. Composes with `targetClientId` and
|
|
318
|
+
// `targetCapability` below.
|
|
319
|
+
if (targetInterfaceId != null) {
|
|
320
|
+
if (entry.type !== "client" || entry.interfaceId !== targetInterfaceId)
|
|
321
|
+
continue;
|
|
322
|
+
}
|
|
323
|
+
|
|
285
324
|
if (targetClientId != null) {
|
|
286
325
|
// Targeted: bypass conversation filter, deliver only to the named client.
|
|
287
326
|
if (entry.type !== "client" || entry.clientId !== targetClientId)
|
|
@@ -519,10 +558,11 @@ let _hubChain = Promise.resolve();
|
|
|
519
558
|
export function broadcastMessage(
|
|
520
559
|
msg: ServerMessage,
|
|
521
560
|
conversationId?: string,
|
|
522
|
-
options?: { targetClientId?: string },
|
|
561
|
+
options?: { targetClientId?: string; targetInterfaceId?: InterfaceId },
|
|
523
562
|
): void {
|
|
524
563
|
const resolvedConversationId = conversationId ?? extractConversationId(msg);
|
|
525
564
|
const targetClientId = options?.targetClientId;
|
|
565
|
+
const targetInterfaceId = options?.targetInterfaceId;
|
|
526
566
|
|
|
527
567
|
// Confirmation-request side effects: canonical guardian request creation.
|
|
528
568
|
// The home-feed `activity.failed` notification side-effect lives in the
|
|
@@ -539,16 +579,45 @@ export function broadcastMessage(
|
|
|
539
579
|
: resolvedConversationId;
|
|
540
580
|
const event = buildAssistantEvent(msg, scopedConversationId);
|
|
541
581
|
const targetCapability = capabilityForMessageType(msg.type);
|
|
582
|
+
// Self-echo suppression: a `sync_changed` carrying an `originClientId`
|
|
583
|
+
// means a specific client just mutated the resource. The hub must not
|
|
584
|
+
// re-deliver the invalidation to that client — it already updated its
|
|
585
|
+
// optimistic state locally and a redundant invalidation would clobber it
|
|
586
|
+
// with a flash of stale-then-fresh data. Assistant-internal emits (agent
|
|
587
|
+
// loop, FS watcher, cron) leave `originClientId` unset and the event
|
|
588
|
+
// fans out to every subscriber as before.
|
|
589
|
+
const excludeClientId =
|
|
590
|
+
msg.type === "sync_changed" &&
|
|
591
|
+
typeof msg.originClientId === "string" &&
|
|
592
|
+
msg.originClientId.length > 0
|
|
593
|
+
? msg.originClientId
|
|
594
|
+
: undefined;
|
|
542
595
|
const publishOptions =
|
|
543
|
-
targetCapability != null ||
|
|
544
|
-
|
|
596
|
+
targetCapability != null ||
|
|
597
|
+
targetClientId != null ||
|
|
598
|
+
targetInterfaceId != null ||
|
|
599
|
+
excludeClientId != null
|
|
600
|
+
? {
|
|
601
|
+
targetCapability,
|
|
602
|
+
targetClientId,
|
|
603
|
+
targetInterfaceId,
|
|
604
|
+
excludeClientId,
|
|
605
|
+
}
|
|
545
606
|
: undefined;
|
|
546
607
|
_hubChain = _hubChain
|
|
547
608
|
.then(() => assistantEventHub.publish(event, publishOptions))
|
|
548
609
|
.then(() => {
|
|
549
|
-
// When a conversation title changes, also
|
|
550
|
-
// `conversation_list_invalidated` so
|
|
551
|
-
//
|
|
610
|
+
// When a conversation title changes, also publish a
|
|
611
|
+
// `conversation_list_invalidated` so the macOS sidebar refreshes
|
|
612
|
+
// its row ordering for the renamed conversation. Web consumes the
|
|
613
|
+
// paired `sync_changed` with `conversation:<id>:metadata` tag
|
|
614
|
+
// emitted by `publishConversationTitleChanged` and patches the
|
|
615
|
+
// single row in place, so the broadcast is scoped to macOS only.
|
|
616
|
+
//
|
|
617
|
+
// TODO(electron-cutover): remove this emission once macOS migrates
|
|
618
|
+
// to the Electron client and consumes `sync_changed` directly. At
|
|
619
|
+
// that point `conversation_list_invalidated` has no remaining
|
|
620
|
+
// consumers and the message type can be retired.
|
|
552
621
|
if (msg.type === "conversation_title_updated") {
|
|
553
622
|
return assistantEventHub
|
|
554
623
|
.publish(
|
|
@@ -556,6 +625,7 @@ export function broadcastMessage(
|
|
|
556
625
|
type: "conversation_list_invalidated",
|
|
557
626
|
reason: "renamed",
|
|
558
627
|
}),
|
|
628
|
+
{ targetInterfaceId: "macos" },
|
|
559
629
|
)
|
|
560
630
|
.catch((err: unknown) => {
|
|
561
631
|
log.warn(
|
|
@@ -153,6 +153,7 @@ const ACTOR_ENDPOINTS: Array<{ endpoint: string; scopes: Scope[] }> = [
|
|
|
153
153
|
{ endpoint: "conversations/undo", scopes: ["chat.write"] },
|
|
154
154
|
{ endpoint: "conversations/regenerate", scopes: ["chat.write"] },
|
|
155
155
|
{ endpoint: "conversations/attention", scopes: ["chat.read"] },
|
|
156
|
+
{ endpoint: "conversations/slack-channel/resolve", scopes: ["chat.read"] },
|
|
156
157
|
{ endpoint: "conversations/seen", scopes: ["chat.write"] },
|
|
157
158
|
{ endpoint: "conversations/unread", scopes: ["chat.write"] },
|
|
158
159
|
{ endpoint: "conversations/import", scopes: ["chat.write"] },
|
|
@@ -416,6 +417,7 @@ const ACTOR_ENDPOINTS: Array<{ endpoint: string; scopes: Scope[] }> = [
|
|
|
416
417
|
|
|
417
418
|
// LLM call site catalog
|
|
418
419
|
{ endpoint: "config/llm/call-sites:GET", scopes: ["settings.read"] },
|
|
420
|
+
{ endpoint: "config/llm/profiles:GET", scopes: ["settings.read"] },
|
|
419
421
|
|
|
420
422
|
// Conversation management
|
|
421
423
|
{ endpoint: "conversations:DELETE", scopes: ["chat.write"] },
|
|
@@ -439,6 +441,7 @@ const ACTOR_ENDPOINTS: Array<{ endpoint: string; scopes: Scope[] }> = [
|
|
|
439
441
|
// Message content
|
|
440
442
|
{ endpoint: "messages/content", scopes: ["chat.read"] },
|
|
441
443
|
{ endpoint: "messages/llm-context", scopes: ["chat.read"] },
|
|
444
|
+
{ endpoint: "conversations/llm-context", scopes: ["chat.read"] },
|
|
442
445
|
{ endpoint: "llm-request-logs/payload", scopes: ["chat.read"] },
|
|
443
446
|
{ endpoint: "messages/tts", scopes: ["chat.read"] },
|
|
444
447
|
{ endpoint: "tts/synthesize", scopes: ["chat.read"] },
|
|
@@ -451,15 +454,17 @@ const ACTOR_ENDPOINTS: Array<{ endpoint: string; scopes: Scope[] }> = [
|
|
|
451
454
|
{ endpoint: "bookmarks:POST", scopes: ["chat.write"] },
|
|
452
455
|
{ endpoint: "bookmarks/by-message:DELETE", scopes: ["chat.write"] },
|
|
453
456
|
|
|
454
|
-
// Interfaces
|
|
455
|
-
{ endpoint: "interfaces", scopes: ["settings.read"] },
|
|
456
|
-
|
|
457
457
|
// Skills
|
|
458
458
|
{ endpoint: "skills:GET", scopes: ["settings.read"] },
|
|
459
459
|
{ endpoint: "skills:POST", scopes: ["settings.write"] },
|
|
460
460
|
{ endpoint: "skills:DELETE", scopes: ["settings.write"] },
|
|
461
461
|
{ endpoint: "skills:PATCH", scopes: ["settings.write"] },
|
|
462
462
|
|
|
463
|
+
// Plugins (read-only for now — install / uninstall stay CLI-side)
|
|
464
|
+
{ endpoint: "plugins:GET", scopes: ["settings.read"] },
|
|
465
|
+
{ endpoint: "plugins/search:GET", scopes: ["settings.read"] },
|
|
466
|
+
{ endpoint: "plugins:DELETE", scopes: ["settings.write"] },
|
|
467
|
+
|
|
463
468
|
// Memory items
|
|
464
469
|
{ endpoint: "memory-items:GET", scopes: ["settings.read"] },
|
|
465
470
|
{ endpoint: "memory-items:POST", scopes: ["settings.write"] },
|
|
@@ -471,6 +476,20 @@ const ACTOR_ENDPOINTS: Array<{ endpoint: string; scopes: Scope[] }> = [
|
|
|
471
476
|
{ endpoint: "memory/v2/list-concept-pages:POST", scopes: ["settings.read"] },
|
|
472
477
|
{ endpoint: "memory/v2/reembed-skills:POST", scopes: ["settings.write"] },
|
|
473
478
|
{ endpoint: "memory/v2/concept-frequency:POST", scopes: ["settings.read"] },
|
|
479
|
+
{ endpoint: "memory/v2/ema-scores:POST", scopes: ["settings.read"] },
|
|
480
|
+
{ endpoint: "memory/v2/simulate-router:POST", scopes: ["settings.read"] },
|
|
481
|
+
{
|
|
482
|
+
endpoint: "memory/v2/compare-retrievers:POST",
|
|
483
|
+
scopes: ["settings.read"],
|
|
484
|
+
},
|
|
485
|
+
{
|
|
486
|
+
endpoint: "memory/v2/router-prompt-template:GET",
|
|
487
|
+
scopes: ["settings.read"],
|
|
488
|
+
},
|
|
489
|
+
{ endpoint: "memory/v2/now-text:GET", scopes: ["settings.read"] },
|
|
490
|
+
{ endpoint: "memory/v3/validate:POST", scopes: ["settings.read"] },
|
|
491
|
+
{ endpoint: "memory/v3/tree:POST", scopes: ["settings.read"] },
|
|
492
|
+
{ endpoint: "memory/v3/simulate:POST", scopes: ["settings.read"] },
|
|
474
493
|
|
|
475
494
|
// Trust rule listing
|
|
476
495
|
{ endpoint: "trust-rules/manage:GET", scopes: ["settings.read"] },
|
|
@@ -665,6 +684,12 @@ registerPolicy("channels/inbound", {
|
|
|
665
684
|
allowedPrincipalTypes: ["svc_gateway"],
|
|
666
685
|
});
|
|
667
686
|
|
|
687
|
+
// Background wake control-plane calls from the platform.
|
|
688
|
+
registerPolicy("background-wake", {
|
|
689
|
+
requiredScopes: ["internal.write"],
|
|
690
|
+
allowedPrincipalTypes: ["svc_gateway"],
|
|
691
|
+
});
|
|
692
|
+
|
|
668
693
|
// Internal forwarding endpoints: gateway-only
|
|
669
694
|
const INTERNAL_ENDPOINTS = [
|
|
670
695
|
"internal/twilio/voice-webhook",
|
|
@@ -887,6 +912,12 @@ registerPolicy("browser/execute", {
|
|
|
887
912
|
allowedPrincipalTypes: ["local"],
|
|
888
913
|
});
|
|
889
914
|
|
|
915
|
+
// Browser tabs operations (list/select/new/close): local-only (CLI / IPC callers)
|
|
916
|
+
registerPolicy("browser/tabs", {
|
|
917
|
+
requiredScopes: ["settings.write"],
|
|
918
|
+
allowedPrincipalTypes: ["local"],
|
|
919
|
+
});
|
|
920
|
+
|
|
890
921
|
// Background tools: local-only (CLI / IPC callers)
|
|
891
922
|
registerPolicy("background-tools", {
|
|
892
923
|
requiredScopes: ["settings.read"],
|
|
@@ -922,6 +953,11 @@ registerPolicy("domain/status", {
|
|
|
922
953
|
allowedPrincipalTypes: ["local"],
|
|
923
954
|
});
|
|
924
955
|
|
|
956
|
+
registerPolicy("domain/verification-status", {
|
|
957
|
+
requiredScopes: ["settings.read"],
|
|
958
|
+
allowedPrincipalTypes: ["local"],
|
|
959
|
+
});
|
|
960
|
+
|
|
925
961
|
// Email management (IPC-local)
|
|
926
962
|
registerPolicy("email/register", {
|
|
927
963
|
requiredScopes: ["settings.write"],
|
|
@@ -992,6 +1028,10 @@ registerPolicy("conversations/cli/export", {
|
|
|
992
1028
|
requiredScopes: ["settings.read"],
|
|
993
1029
|
allowedPrincipalTypes: ["local"],
|
|
994
1030
|
});
|
|
1031
|
+
registerPolicy("conversations/cli/slack/detach", {
|
|
1032
|
+
requiredScopes: ["settings.write"],
|
|
1033
|
+
allowedPrincipalTypes: ["local"],
|
|
1034
|
+
});
|
|
995
1035
|
// `conversations/cli/clear` wipes every conversation + message + vector
|
|
996
1036
|
// collection. Elevated to settings.write and locked to local callers,
|
|
997
1037
|
// mirroring the `conversations/clear-all` and `conversations/wipe` gates.
|
|
@@ -24,6 +24,11 @@ import type { TrustContext } from "../daemon/trust-context.js";
|
|
|
24
24
|
import { bootstrapConversation } from "../memory/conversation-bootstrap.js";
|
|
25
25
|
import { addMessage } from "../memory/conversation-crud.js";
|
|
26
26
|
import type { TitleOrigin } from "../memory/conversation-title-service.js";
|
|
27
|
+
import {
|
|
28
|
+
commitDeferredConversation,
|
|
29
|
+
discardDeferredConversation,
|
|
30
|
+
registerDeferredConversation,
|
|
31
|
+
} from "../notifications/deferred-emit.js";
|
|
27
32
|
import { emitNotificationSignal } from "../notifications/emit-signal.js";
|
|
28
33
|
import type { AttentionHints } from "../notifications/signal.js";
|
|
29
34
|
import { getLogger } from "../util/logger.js";
|
|
@@ -121,6 +126,11 @@ export interface RunBackgroundJobOptions {
|
|
|
121
126
|
* the `assistant` role and cannot override the action prompt.
|
|
122
127
|
*/
|
|
123
128
|
assistantSandwich?: { preamble: string; content: string; postamble: string };
|
|
129
|
+
/**
|
|
130
|
+
* Buffer in-band `notifications send` calls and only flush them after the
|
|
131
|
+
* run completes successfully. See `notifications/deferred-emit.ts`.
|
|
132
|
+
*/
|
|
133
|
+
deferNotifications?: boolean;
|
|
124
134
|
}
|
|
125
135
|
|
|
126
136
|
export interface RunBackgroundJobResult {
|
|
@@ -205,6 +215,10 @@ export async function runBackgroundJob(
|
|
|
205
215
|
...(opts.scheduleJobId ? { scheduleJobId: opts.scheduleJobId } : {}),
|
|
206
216
|
});
|
|
207
217
|
|
|
218
|
+
if (opts.deferNotifications) {
|
|
219
|
+
registerDeferredConversation(conversation.id);
|
|
220
|
+
}
|
|
221
|
+
|
|
208
222
|
// Fire the sidebar-creation callback synchronously after bootstrap so
|
|
209
223
|
// connected clients (macOS sidebar, etc.) see the conversation appear
|
|
210
224
|
// immediately rather than after `processMessage` returns. Wrapped so a
|
|
@@ -273,6 +287,14 @@ export async function runBackgroundJob(
|
|
|
273
287
|
});
|
|
274
288
|
|
|
275
289
|
await Promise.race([work, timeout]);
|
|
290
|
+
// Symmetric with the `work.catch` above: once `work` has won the race,
|
|
291
|
+
// the orphan timeout promise can still reject during the await below
|
|
292
|
+
// (commitDeferredConversation). Swallow so it doesn't surface as an
|
|
293
|
+
// unhandled rejection that Bun can use to terminate the process.
|
|
294
|
+
timeout.catch(() => {});
|
|
295
|
+
if (opts.deferNotifications) {
|
|
296
|
+
await commitDeferredConversation(conversation.id);
|
|
297
|
+
}
|
|
276
298
|
return { conversationId: conversation.id, ok: true };
|
|
277
299
|
} catch (err) {
|
|
278
300
|
const errorKind = classifyError(err);
|
|
@@ -281,6 +303,10 @@ export async function runBackgroundJob(
|
|
|
281
303
|
// so the structured failure result still flows to the caller.
|
|
282
304
|
const conversationId = conversation?.id ?? "";
|
|
283
305
|
|
|
306
|
+
if (opts.deferNotifications && conversationId) {
|
|
307
|
+
discardDeferredConversation(conversationId);
|
|
308
|
+
}
|
|
309
|
+
|
|
284
310
|
log.error(
|
|
285
311
|
{
|
|
286
312
|
err: error.message,
|
|
@@ -40,9 +40,6 @@ export interface RunBtwSidechainParams {
|
|
|
40
40
|
signal?: AbortSignal;
|
|
41
41
|
timeoutMs?: number;
|
|
42
42
|
onEvent?: (event: ProviderEvent) => void;
|
|
43
|
-
userPersona?: string | null;
|
|
44
|
-
channelPersona?: string | null;
|
|
45
|
-
userSlug?: string | null;
|
|
46
43
|
}
|
|
47
44
|
|
|
48
45
|
export interface RunBtwSidechainResult {
|
|
@@ -79,9 +76,6 @@ export async function runBtwSidechain(
|
|
|
79
76
|
: buildSystemPrompt({
|
|
80
77
|
excludeBootstrap: true,
|
|
81
78
|
excludeCustomPrefix: true,
|
|
82
|
-
userPersona: params.userPersona,
|
|
83
|
-
channelPersona: params.channelPersona,
|
|
84
|
-
userSlug: params.userSlug,
|
|
85
79
|
}));
|
|
86
80
|
|
|
87
81
|
const { signal: timeoutSignal, cleanup } = createTimeout(
|