@vellumai/assistant 0.8.4 → 0.8.6
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 +33 -1
- package/ARCHITECTURE.md +3 -3
- package/bunfig.toml +6 -1
- package/docs/browser-use-architecture-phase2.md +1 -1
- package/docs/credential-execution-service.md +6 -6
- package/docs/plugins.md +4 -3
- package/knip.json +2 -1
- package/node_modules/@vellumai/skill-host-contracts/src/client.ts +12 -13
- package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +4 -1
- package/node_modules/@vellumai/skill-host-contracts/src/tool-types.ts +16 -14
- package/openapi.yaml +2748 -216
- package/package.json +1 -1
- package/src/__tests__/actor-token-service.test.ts +3 -2
- package/src/__tests__/agent-loop-exit-reason.test.ts +102 -9
- package/src/__tests__/agent-loop-override-profile.test.ts +2 -1
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +1 -0
- package/src/__tests__/agent-wake-override-profile.test.ts +1 -0
- package/src/__tests__/always-loaded-tools-guard.test.ts +2 -2
- package/src/__tests__/annotate-risk-options.test.ts +1 -0
- package/src/__tests__/anthropic-provider.test.ts +34 -37
- package/src/__tests__/approval-cascade.test.ts +1 -0
- package/src/__tests__/approval-routes-http.test.ts +9 -13
- package/src/__tests__/assert-not-live-db.ts +79 -0
- package/src/__tests__/assistant-event-hub-self-exclusion.test.ts +293 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +12 -28
- package/src/__tests__/audit-log-rotation.test.ts +72 -18
- package/src/__tests__/auto-analysis-end-to-end.test.ts +6 -6
- package/src/__tests__/background-workers-disk-pressure.test.ts +8 -11
- package/src/__tests__/browser-skill-endstate.test.ts +3 -3
- package/src/__tests__/btw-routes.test.ts +5 -5
- package/src/__tests__/call-controller.test.ts +3 -3
- package/src/__tests__/cancel-resolves-conversation-key.test.ts +1 -1
- package/src/__tests__/channel-approval-routes.test.ts +3 -2
- package/src/__tests__/channel-guardian.test.ts +6 -5
- package/src/__tests__/channel-readiness-slack-remote.test.ts +175 -0
- package/src/__tests__/channel-reply-delivery.test.ts +35 -0
- package/src/__tests__/channel-retry-sweep.test.ts +320 -3
- package/src/__tests__/checker.test.ts +18 -27
- package/src/__tests__/compaction-events.test.ts +2 -0
- package/src/__tests__/compaction-trail-store.test.ts +264 -0
- package/src/__tests__/compactor-call-site-logging.test.ts +215 -0
- package/src/__tests__/compactor-preserved-tail-count.test.ts +1 -0
- package/src/__tests__/computer-use-skill-manifest-regression.test.ts +12 -16
- package/src/__tests__/computer-use-tools.test.ts +14 -18
- package/src/__tests__/config-loader-backfill.test.ts +13 -28
- package/src/__tests__/config-loader-corrupt.test.ts +5 -5
- package/src/__tests__/config-loader-platform-defaults.test.ts +93 -26
- package/src/__tests__/config-loader-quarantine-bulletin.test.ts +3 -3
- package/src/__tests__/config-managed-gemini-defaults.test.ts +3 -4
- package/src/__tests__/config-schema.test.ts +10 -10
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -1
- package/src/__tests__/connection-model-compat.test.ts +83 -0
- package/src/__tests__/contacts-tools.test.ts +3 -2
- package/src/__tests__/context-token-estimator.test.ts +22 -0
- package/src/__tests__/conversation-abort-tool-results.test.ts +5 -0
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +2 -1
- package/src/__tests__/conversation-agent-loop-handlers-max-tokens.test.ts +55 -0
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +2 -1
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +231 -2
- package/src/__tests__/conversation-agent-loop.test.ts +581 -54
- package/src/__tests__/conversation-analysis-routes.test.ts +1 -0
- package/src/__tests__/conversation-app-control-instantiation.test.ts +31 -24
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +1 -0
- package/src/__tests__/conversation-attention-store.test.ts +101 -0
- package/src/__tests__/conversation-attention-telegram.test.ts +3 -2
- package/src/__tests__/conversation-clear-safety.test.ts +25 -25
- package/src/__tests__/conversation-confirmation-signals.test.ts +1 -0
- 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 +61 -0
- package/src/__tests__/conversation-fork-crud.test.ts +239 -15
- package/src/__tests__/conversation-fork-route.test.ts +3 -2
- package/src/__tests__/conversation-history-web-search.test.ts +1 -0
- package/src/__tests__/conversation-inference-profile-list.test.ts +3 -2
- package/src/__tests__/conversation-inference-profile-route.test.ts +3 -2
- package/src/__tests__/conversation-lifecycle.test.ts +53 -11
- package/src/__tests__/conversation-list-source.test.ts +3 -2
- package/src/__tests__/conversation-load-history-repair.test.ts +2 -1
- package/src/__tests__/{conversation-load-cleaned-at.test.ts → conversation-load-history-stripped.test.ts} +14 -13
- package/src/__tests__/conversation-pairing.test.ts +53 -0
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +26 -7
- package/src/__tests__/conversation-process-callsite.test.ts +1 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +6 -0
- package/src/__tests__/conversation-queue.test.ts +333 -291
- package/src/__tests__/conversation-routes-disk-view.test.ts +112 -18
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +33 -8
- package/src/__tests__/conversation-routes-slash-commands.test.ts +68 -2
- package/src/__tests__/conversation-runtime-assembly.test.ts +78 -0
- package/src/__tests__/conversation-skill-tools.test.ts +40 -147
- package/src/__tests__/conversation-slash-queue.test.ts +84 -32
- package/src/__tests__/conversation-slash-unknown.test.ts +5 -0
- package/src/__tests__/conversation-speed-override.test.ts +1 -0
- package/src/__tests__/conversation-store.test.ts +1 -1
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +46 -0
- package/src/__tests__/conversation-surfaces-data-persist.test.ts +1 -0
- package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +6 -3
- package/src/__tests__/conversation-surfaces-standalone.test.ts +6 -3
- package/src/__tests__/conversation-surfaces-state-update.test.ts +3 -3
- package/src/__tests__/conversation-surfaces-table-action.test.ts +7 -17
- package/src/__tests__/conversation-sync-tags.test.ts +218 -35
- package/src/__tests__/conversation-title-service.test.ts +1 -0
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +30 -0
- package/src/__tests__/conversation-usage.test.ts +1 -0
- package/src/__tests__/conversation-workspace-cache-state.test.ts +2 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +6 -1
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +6 -1
- package/src/__tests__/credential-broker-browser-fill.test.ts +3 -3
- package/src/__tests__/credential-broker-server-use.test.ts +5 -5
- package/src/__tests__/credential-execution-client.test.ts +72 -1
- package/src/__tests__/credential-execution-feature-gates.test.ts +19 -19
- package/src/__tests__/credential-execution-tools.test.ts +6 -6
- package/src/__tests__/credential-health-service.test.ts +252 -3
- package/src/__tests__/credential-security-invariants.test.ts +6 -5
- package/src/__tests__/credential-vault-unit.test.ts +21 -21
- package/src/__tests__/credential-vault.test.ts +5 -5
- package/src/__tests__/cross-provider-web-search.test.ts +56 -2
- package/src/__tests__/db-connection-isolation.test.ts +7 -6
- package/src/__tests__/db-conversation-fork-lineage-migration.test.ts +8 -10
- package/src/__tests__/db-conversation-inference-profile-migration.test.ts +7 -10
- package/src/__tests__/db-llm-request-log-provider-migration.test.ts +9 -15
- package/src/__tests__/db-test-helpers.ts +58 -0
- package/src/__tests__/disk-pressure-guard.test.ts +58 -41
- package/src/__tests__/disk-pressure-lifecycle.test.ts +13 -10
- package/src/__tests__/disk-pressure-routes.test.ts +0 -33
- package/src/__tests__/disk-pressure-tools.test.ts +0 -4
- package/src/__tests__/dm-persistence.test.ts +26 -40
- package/src/__tests__/document-create-dedupe.test.ts +189 -0
- package/src/__tests__/document-find-replace.test.ts +3 -2
- package/src/__tests__/document-tool-security.test.ts +81 -2
- package/src/__tests__/dynamic-page-surface.test.ts +2 -2
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +5 -4
- package/src/__tests__/email-html-renderer.test.ts +12 -0
- package/src/__tests__/encrypted-store-test-helpers.ts +56 -0
- package/src/__tests__/encrypted-store.test.ts +11 -9
- package/src/__tests__/feature-flag-test-helpers.ts +53 -0
- package/src/__tests__/filing-service.test.ts +1 -0
- package/src/__tests__/first-greeting.test.ts +62 -12
- package/src/__tests__/gateway-flag-listener.test.ts +236 -0
- package/src/__tests__/gemini-provider.test.ts +104 -0
- package/src/__tests__/guardian-action-sweep.test.ts +3 -2
- package/src/__tests__/guardian-dispatch.test.ts +0 -1
- package/src/__tests__/guardian-outbound-http.test.ts +10 -7
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +48 -3
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +2 -1
- package/src/__tests__/heartbeat-disk-pressure.test.ts +5 -0
- package/src/__tests__/heartbeat-service.test.ts +5 -0
- package/src/__tests__/helpers/mock-logger.ts +26 -0
- package/src/__tests__/host-bash-routes.test.ts +1 -0
- package/src/__tests__/host-cu-routes-targeted.test.ts +1 -0
- package/src/__tests__/host-file-routes-targeted.test.ts +1 -0
- package/src/__tests__/host-shell-tool.test.ts +6 -5
- package/src/__tests__/host-transfer-routes-targeted.test.ts +1 -0
- package/src/__tests__/http-conversation-lineage.test.ts +3 -2
- package/src/__tests__/http-user-message-parity.test.ts +29 -7
- package/src/__tests__/identity-intro-cache.test.ts +133 -22
- package/src/__tests__/inbound-slack-persistence.test.ts +44 -72
- package/src/__tests__/inference-profile-reaper.test.ts +3 -2
- package/src/__tests__/inference-profile-session-ipc.test.ts +3 -2
- package/src/__tests__/init-feature-flag-overrides.test.ts +5 -6
- package/src/__tests__/injector-disk-pressure.test.ts +3 -17
- package/src/__tests__/inline-skill-load-permissions.test.ts +4 -4
- package/src/__tests__/list-messages-hidden-metadata.test.ts +80 -0
- package/src/__tests__/list-messages-tool-merge.test.ts +70 -11
- package/src/__tests__/llm-context-normalization.test.ts +42 -0
- 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 +408 -9
- package/src/__tests__/llm-schema.test.ts +1 -1
- package/src/__tests__/llm-usage-store.test.ts +66 -0
- package/src/__tests__/logger.test.ts +89 -0
- package/src/__tests__/manual-token-reconciliation.test.ts +76 -1
- package/src/__tests__/mcp-abort-signal.test.ts +16 -2
- package/src/__tests__/mcp-client-auth.test.ts +14 -0
- package/src/__tests__/media-generate-image.test.ts +31 -0
- package/src/__tests__/memory-v2-static-injector.test.ts +7 -7
- package/src/__tests__/messaging-send-tool.test.ts +1 -0
- package/src/__tests__/migration-import-from-url.test.ts +3 -3
- package/src/__tests__/mock-gateway-ipc.ts +18 -2
- package/src/__tests__/model-intents.test.ts +4 -6
- package/src/__tests__/native-web-search.test.ts +30 -2
- package/src/__tests__/notification-deep-link.test.ts +62 -0
- package/src/__tests__/notification-guardian-path.test.ts +0 -1
- package/src/__tests__/oauth-commands-routes.test.ts +37 -0
- package/src/__tests__/oauth-provider-visibility.test.ts +8 -8
- package/src/__tests__/oauth-store.test.ts +3 -2
- package/src/__tests__/onboarding-template-contract.test.ts +4 -3
- package/src/__tests__/openai-provider.test.ts +54 -9
- package/src/__tests__/openai-responses-provider.test.ts +176 -14
- package/src/__tests__/openrouter-provider-only.test.ts +27 -5
- package/src/__tests__/outbound-slack-persistence.test.ts +46 -1
- package/src/__tests__/pending-interactions-resolved-event.test.ts +0 -1
- package/src/__tests__/persistence-pipeline.test.ts +139 -1
- package/src/__tests__/persistence-secret-redaction.test.ts +83 -12
- package/src/__tests__/platform-bash-auto-approve.test.ts +2 -2
- package/src/__tests__/platform.test.ts +2 -2
- package/src/__tests__/plugin-api-tool-definition.test.ts +92 -0
- package/src/__tests__/plugin-bootstrap.test.ts +11 -13
- package/src/__tests__/plugin-tool-contribution.test.ts +50 -40
- 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 +21 -16
- package/src/__tests__/process-message-display-content.test.ts +19 -22
- package/src/__tests__/provider-catalog-visibility.test.ts +9 -9
- package/src/__tests__/provider-platform-proxy-integration.test.ts +216 -4
- package/src/__tests__/provider-registry-ollama.test.ts +45 -22
- package/src/__tests__/prune-jobs-changes-parser.test.ts +61 -0
- package/src/__tests__/recording-handler.test.ts +1 -0
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +1 -0
- package/src/__tests__/registry.test.ts +84 -84
- package/src/__tests__/relay-server.test.ts +10 -10
- package/src/__tests__/require-fresh-approval.test.ts +2 -2
- package/src/__tests__/runtime-attachment-metadata.test.ts +3 -2
- package/src/__tests__/runtime-events-sse-bilingual.test.ts +154 -0
- package/src/__tests__/schedule-store.test.ts +16 -1
- package/src/__tests__/scheduler-reuse-conversation.test.ts +48 -3
- package/src/__tests__/secret-ingress-http.test.ts +5 -1
- package/src/__tests__/secure-keys.test.ts +3 -3
- package/src/__tests__/send-endpoint-busy.test.ts +81 -42
- package/src/__tests__/server-history-render.test.ts +4 -1
- package/src/__tests__/shell-tool-proxy-mode.test.ts +1 -1
- package/src/__tests__/skill-feature-flags-integration.test.ts +8 -10
- package/src/__tests__/skill-feature-flags.test.ts +16 -18
- package/src/__tests__/skill-load-feature-flag.test.ts +5 -5
- package/src/__tests__/skill-projection-feature-flag.test.ts +48 -37
- package/src/__tests__/skill-projection.benchmark.test.ts +7 -13
- package/src/__tests__/skill-tool-factory.test.ts +97 -96
- package/src/__tests__/slack-channel-config.test.ts +3 -3
- package/src/__tests__/subagent-call-site-routing.test.ts +11 -3
- package/src/__tests__/subagent-disposal.test.ts +27 -8
- package/src/__tests__/subagent-fork-notifications.test.ts +24 -9
- package/src/__tests__/subagent-fork-spawn.test.ts +13 -4
- package/src/__tests__/subagent-manager-notify.test.ts +20 -8
- package/src/__tests__/subagent-notify-parent.test.ts +6 -5
- package/src/__tests__/subagent-spawn-tool-fork.test.ts +58 -0
- package/src/__tests__/subagent-tools.test.ts +2 -1
- package/src/__tests__/suggestion-routes.test.ts +2 -0
- package/src/__tests__/sync-message-contract.test.ts +59 -0
- package/src/__tests__/system-prompt.test.ts +183 -131
- package/src/__tests__/terminal-tools.test.ts +1 -1
- package/src/__tests__/test-preload-verifier.ts +68 -0
- package/src/__tests__/test-preload.ts +32 -39
- 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 +35 -12
- package/src/__tests__/tool-executor.test.ts +64 -72
- package/src/__tests__/tool-grant-request-escalation.test.ts +1 -6
- package/src/__tests__/tool-preview-lifecycle.test.ts +1 -0
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +1 -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 +3 -2
- package/src/__tests__/ui-file-upload-surface.test.ts +2 -2
- package/src/__tests__/usage-routes.test.ts +3 -0
- package/src/__tests__/validate-input.test.ts +381 -0
- package/src/__tests__/verification-control-plane-policy.test.ts +3 -2
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +2 -1
- package/src/__tests__/voice-session-bridge.test.ts +37 -28
- package/src/__tests__/workspace-git-service.test.ts +6 -5
- package/src/__tests__/workspace-migration-089-move-memory-tree-out-of-v3.test.ts +86 -0
- package/src/__tests__/workspace-migration-090-memory-router-cost-optimized-profile.test.ts +326 -0
- package/src/__tests__/workspace-migration-091-retighten-migration-onboarding-thread.test.ts +166 -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 +6 -7
- package/src/agent/loop.ts +88 -0
- package/src/api/README.md +127 -0
- package/src/api/constants/call-sites.ts +27 -0
- package/src/api/events/assistant-outbound-attachment.ts +51 -0
- package/src/api/events/assistant-text-delta.ts +32 -0
- package/src/api/events/assistant-turn-start.ts +33 -0
- package/src/api/events/document-comment-created.ts +48 -0
- package/src/api/events/document-comment-deleted.ts +24 -0
- package/src/api/events/document-comment-reopened.ts +25 -0
- package/src/api/events/document-comment-resolved.ts +27 -0
- package/src/api/events/generation-cancelled.ts +24 -0
- package/src/api/events/generation-handoff.ts +41 -0
- package/src/api/events/message-complete.ts +42 -0
- package/src/api/events/open-url.ts +30 -0
- package/src/api/events/relationship-state-updated.ts +25 -0
- package/src/api/events/tool-use-start.ts +32 -0
- package/src/api/index.ts +129 -0
- package/src/api/package.json +10 -0
- package/src/api/responses/llm-context-response.ts +39 -0
- package/src/api/responses/llm-request-log-entry.ts +93 -0
- package/src/api/responses/memory-recall-log.ts +65 -0
- package/src/api/responses/memory-v2-activation-log.ts +78 -0
- package/src/background-wake/background-wake-routes.test.ts +868 -0
- package/src/background-wake/platform-client.test.ts +308 -0
- package/src/background-wake/platform-client.ts +167 -0
- package/src/background-wake/publisher.ts +91 -0
- package/src/background-wake/runtime-registry.ts +24 -0
- package/src/background-wake/wake-intent-hooks.test.ts +282 -0
- package/src/calls/guardian-dispatch.ts +1 -0
- package/src/calls/voice-session-bridge.ts +4 -4
- package/src/cli/commands/__tests__/browser.test.ts +23 -5
- package/src/cli/commands/__tests__/conversations-slack.test.ts +16 -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 +1 -0
- package/src/cli/commands/__tests__/memory-v3-render.test.ts +340 -0
- package/src/cli/commands/__tests__/notifications.test.ts +184 -40
- package/src/cli/commands/browser.ts +247 -0
- package/src/cli/commands/channels/__tests__/channels.test.ts +143 -0
- package/src/cli/commands/channels/index.ts +229 -0
- package/src/cli/commands/domain.ts +91 -41
- 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 +176 -1
- package/src/cli/commands/memory-v3-render.ts +491 -0
- package/src/cli/commands/memory-v3.ts +567 -0
- package/src/cli/commands/notifications.ts +365 -55
- package/src/cli/lib/open-browser.ts +7 -2
- package/src/cli/program.ts +4 -0
- package/src/config/assistant-feature-flags.ts +39 -46
- package/src/config/bundled-skills/document-editor/SKILL.md +16 -3
- package/src/config/bundled-skills/document-editor/TOOLS.json +18 -0
- package/src/config/bundled-skills/document-editor/tools/document-open.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/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 +1 -1
- package/src/config/bundled-skills/schedule/TOOLS.json +2 -2
- package/src/config/bundled-skills/settings/tools/open-system-settings.ts +1 -0
- package/src/config/bundled-tool-registry.ts +2 -0
- package/src/config/call-site-defaults.ts +8 -7
- package/src/config/feature-flag-cache.ts +86 -0
- package/src/config/feature-flag-registry.json +33 -17
- package/src/config/llm-context-resolution.ts +10 -1
- package/src/config/llm-resolver.ts +121 -15
- package/src/config/loader.ts +4 -5
- package/src/config/schemas/__tests__/memory-v2.test.ts +228 -1
- package/src/config/schemas/call-site-catalog.ts +21 -7
- package/src/config/schemas/heartbeat.ts +1 -1
- package/src/config/schemas/llm.ts +102 -2
- package/src/config/schemas/memory-v2.ts +272 -0
- package/src/config/schemas/memory.ts +2 -1
- package/src/config/schemas/services.ts +6 -2
- package/src/config/seed-inference-profiles.ts +36 -16
- package/src/context/compactor.ts +52 -0
- package/src/context/token-estimator.ts +10 -5
- package/src/conversations/__tests__/message-consolidation.test.ts +350 -0
- package/src/conversations/message-consolidation.ts +404 -0
- package/src/credential-execution/executable-discovery.ts +40 -0
- package/src/credential-execution/process-manager.ts +6 -2
- package/src/credential-health/credential-health-service.ts +125 -40
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +3 -6
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +13 -15
- package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +2 -3
- package/src/daemon/__tests__/daemon-skill-host.test.ts +2 -0
- package/src/daemon/__tests__/meet-manifest-loader.test.ts +25 -12
- package/src/daemon/__tests__/native-web-search-metadata.test.ts +1 -0
- package/src/daemon/__tests__/switch-inference-profile-tool.test.ts +107 -0
- package/src/daemon/__tests__/web-search-status-text.test.ts +1 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +390 -80
- package/src/daemon/conversation-agent-loop.ts +244 -90
- package/src/daemon/conversation-error.ts +64 -6
- package/src/daemon/conversation-lifecycle.ts +27 -22
- package/src/daemon/conversation-messaging.ts +84 -43
- package/src/daemon/conversation-process.ts +74 -37
- package/src/daemon/conversation-runtime-assembly.ts +38 -17
- package/src/daemon/conversation-skill-tools.ts +14 -30
- package/src/daemon/conversation-surfaces.ts +69 -34
- package/src/daemon/conversation-tool-setup.ts +77 -32
- package/src/daemon/conversation-usage.ts +2 -0
- package/src/daemon/conversation.ts +40 -75
- package/src/daemon/daemon-control.ts +1 -1
- package/src/daemon/daemon-skill-host.ts +9 -2
- package/src/daemon/disk-pressure-guard.ts +39 -29
- package/src/daemon/first-greeting.ts +31 -13
- package/src/daemon/handlers/config-model.test.ts +1 -0
- package/src/daemon/handlers/conversations.ts +11 -3
- package/src/daemon/handlers/shared.ts +6 -1
- package/src/daemon/host-browser-proxy.ts +5 -5
- package/src/daemon/host-cu-proxy.ts +4 -4
- package/src/daemon/host-file-proxy.ts +4 -4
- package/src/daemon/host-proxy-base.ts +4 -4
- package/src/daemon/host-transfer-proxy.ts +10 -10
- package/src/daemon/lifecycle.ts +29 -26
- package/src/daemon/mcp-reload-service.ts +1 -1
- package/src/daemon/meet-manifest-loader.ts +11 -24
- package/src/daemon/message-types/conversations.ts +22 -27
- package/src/daemon/message-types/document-comments.ts +8 -44
- package/src/daemon/message-types/home.ts +2 -14
- package/src/daemon/message-types/integrations.ts +2 -7
- package/src/daemon/message-types/messages.ts +25 -48
- package/src/daemon/message-types/subagents.ts +6 -0
- package/src/daemon/message-types/sync.ts +14 -0
- package/src/daemon/process-message.ts +9 -9
- package/src/daemon/providers-setup.ts +1 -1
- package/src/daemon/server.ts +16 -0
- package/src/daemon/shutdown-handlers.ts +24 -5
- package/src/daemon/switch-inference-profile-tool.ts +62 -0
- package/src/daemon/tool-setup-types.ts +7 -0
- package/src/daemon/wake-target-adapter.ts +10 -0
- package/src/documents/document-store.ts +38 -0
- package/src/export/__tests__/transcript-formatter.test.ts +1 -0
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +30 -1
- package/src/heartbeat/heartbeat-service.ts +63 -0
- package/src/home/__tests__/feed-writer.test.ts +161 -0
- package/src/home/__tests__/post-connect-feed.test.ts +1 -0
- package/src/home/__tests__/suggested-prompts.test.ts +55 -59
- package/src/home/feed-writer.ts +146 -7
- package/src/home/home-greeting.ts +0 -9
- package/src/home/suggested-prompts.ts +27 -154
- package/src/ipc/__tests__/cli-ipc.test.ts +1 -0
- package/src/ipc/gateway-client.test.ts +4 -1
- package/src/ipc/gateway-flag-listener.ts +123 -0
- package/src/ipc/skill-routes/__tests__/memory.test.ts +1 -0
- package/src/ipc/skill-routes/__tests__/registries.test.ts +36 -7
- package/src/ipc/skill-routes/memory.ts +4 -3
- package/src/ipc/skill-routes/registries.ts +35 -40
- 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 +242 -0
- package/src/memory/__tests__/jobs-store-job-classes.test.ts +28 -1
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +26 -5
- package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +1 -0
- package/src/memory/__tests__/memory-retrospective-job.test.ts +8 -0
- package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +1 -0
- package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +31 -0
- package/src/memory/auto-analysis-enqueue.ts +5 -1
- package/src/memory/conversation-attention-store.ts +17 -3
- package/src/memory/conversation-crud.ts +423 -182
- 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-connection.ts +29 -19
- package/src/memory/db-init.ts +14 -0
- package/src/memory/db-maintenance.ts +30 -21
- package/src/memory/db-singleton.ts +77 -0
- package/src/memory/delivery-channels.ts +82 -0
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +2 -4
- 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/graph/retriever.test.ts +3 -3
- 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/job-handlers/embedding.test.ts +3 -2
- package/src/memory/jobs/__tests__/embed-concept-page.test.ts +5 -2
- package/src/memory/jobs/embed-pkb-file.ts +6 -1
- package/src/memory/jobs-store.ts +14 -0
- package/src/memory/jobs-worker.ts +66 -22
- package/src/memory/llm-request-log-source-clickhouse.ts +122 -2
- package/src/memory/llm-request-log-source-local.ts +31 -0
- package/src/memory/llm-request-log-source.ts +40 -2
- package/src/memory/llm-request-log-store.ts +228 -1
- package/src/memory/llm-usage-store.ts +24 -0
- package/src/memory/memory-retrospective-enqueue.ts +8 -1
- package/src/memory/memory-retrospective-job.ts +5 -0
- package/src/memory/memory-v2-activation-log-store.ts +110 -7
- 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/265-drop-provider-connection-status.ts +26 -0
- package/src/memory/migrations/266-messages-client-message-id.ts +43 -0
- package/src/memory/migrations/index.ts +19 -0
- package/src/memory/migrations/registry.ts +33 -0
- package/src/memory/schema/conversations.ts +10 -2
- package/src/memory/schema/inference.ts +0 -1
- package/src/memory/schema/infrastructure.ts +21 -0
- package/src/memory/tool-usage-store.ts +36 -8
- package/src/memory/v2/__tests__/backfill-jobs.test.ts +5 -2
- 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 +83 -0
- package/src/memory/v2/__tests__/harness-oracle.test.ts +257 -0
- package/src/memory/v2/__tests__/harness-replay-input.test.ts +230 -0
- package/src/memory/v2/__tests__/harness-runner.test.ts +135 -0
- package/src/memory/v2/__tests__/injection.test.ts +127 -98
- package/src/memory/v2/__tests__/qdrant.test.ts +36 -0
- package/src/memory/v2/__tests__/router.test.ts +171 -3
- package/src/memory/v2/__tests__/sweep-job.test.ts +6 -3
- package/src/memory/v2/harness/compare.ts +57 -0
- package/src/memory/v2/harness/metrics.ts +128 -0
- package/src/memory/v2/harness/oracle.ts +145 -0
- package/src/memory/v2/harness/replay-input.ts +240 -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 +112 -0
- package/src/memory/v2/harness/trace.ts +64 -0
- package/src/memory/v2/injection.ts +21 -15
- package/src/memory/v2/prompts/router.ts +26 -1
- package/src/memory/v2/qdrant.ts +14 -2
- package/src/memory/v2/router.ts +171 -18
- package/src/memory/v3/__tests__/coactivation-store.test.ts +422 -0
- package/src/memory/v3/__tests__/consolidation-job.test.ts +466 -0
- package/src/memory/v3/__tests__/coretrieval-seed.test.ts +270 -0
- package/src/memory/v3/__tests__/edge-learning-job.test.ts +324 -0
- package/src/memory/v3/__tests__/edges.test.ts +706 -0
- package/src/memory/v3/__tests__/filter.test.ts +560 -0
- package/src/memory/v3/__tests__/gate.test.ts +637 -0
- package/src/memory/v3/__tests__/index-composition.test.ts +291 -0
- package/src/memory/v3/__tests__/loop.test.ts +775 -0
- package/src/memory/v3/__tests__/retriever.test.ts +226 -0
- package/src/memory/v3/__tests__/scouts.test.ts +489 -0
- package/src/memory/v3/__tests__/shadow-diff.test.ts +225 -0
- package/src/memory/v3/__tests__/shadow-middleware.test.ts +398 -0
- package/src/memory/v3/__tests__/system-prompts.test.ts +154 -0
- package/src/memory/v3/__tests__/traversal.test.ts +508 -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 +784 -0
- package/src/memory/v3/__tests__/validate.test.ts +277 -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/coretrieval-seed.ts +240 -0
- package/src/memory/v3/edge-learning-job.ts +160 -0
- package/src/memory/v3/edges.ts +286 -0
- package/src/memory/v3/filter.ts +286 -0
- package/src/memory/v3/gate.ts +349 -0
- package/src/memory/v3/index-composition.ts +126 -0
- package/src/memory/v3/llm-capture.ts +46 -0
- package/src/memory/v3/loop.ts +430 -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 +431 -0
- package/src/memory/v3/shadow-diff.ts +287 -0
- package/src/memory/v3/shadow-middleware.ts +347 -0
- package/src/memory/v3/traversal.ts +211 -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 +356 -0
- package/src/memory/v3/types.ts +65 -0
- package/src/memory/v3/validate.ts +323 -0
- package/src/notifications/__tests__/emit-signal-home-feed.test.ts +1 -0
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +1 -0
- package/src/notifications/adapters/macos.ts +18 -1
- package/src/notifications/adapters/platform.ts +1 -1
- package/src/notifications/adapters/slack.ts +45 -11
- package/src/notifications/broadcaster.ts +114 -63
- package/src/notifications/conversation-pairing.ts +23 -3
- package/src/notifications/decision-engine.ts +1 -4
- package/src/notifications/decisions-store.ts +32 -1
- package/src/notifications/deliveries-store.ts +45 -0
- package/src/notifications/edit-notification.ts +201 -0
- package/src/notifications/emit-signal.ts +40 -50
- package/src/notifications/signal.ts +10 -0
- package/src/notifications/types.ts +37 -0
- package/src/oauth/byo-connection.test.ts +67 -3
- package/src/oauth/byo-connection.ts +32 -5
- package/src/oauth/connect-orchestrator.ts +9 -0
- package/src/oauth/connection-resolver.test.ts +76 -0
- package/src/oauth/connection-resolver.ts +49 -10
- package/src/oauth/manual-token-connection.ts +51 -3
- package/src/oauth/seed-providers.ts +3 -0
- package/src/permissions/approval-policy.test.ts +19 -5
- package/src/permissions/approval-policy.ts +14 -3
- package/src/permissions/checker.ts +21 -8
- package/src/permissions/prompter.ts +3 -3
- package/src/permissions/question-prompter.ts +5 -2
- package/src/permissions/secret-prompter.ts +2 -2
- package/src/platform/client.test.ts +24 -1
- package/src/platform/client.ts +8 -0
- package/src/platform/feature-gate.ts +15 -0
- 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 +20 -19
- package/src/plugins/defaults/persistence.ts +25 -6
- package/src/plugins/external-plugin-loader.ts +5 -68
- package/src/plugins/types.ts +68 -29
- package/src/proactive-artifact/aux-message-injector.ts +17 -4
- package/src/proactive-artifact/job.test.ts +1 -0
- package/src/prompts/__tests__/system-prompt.test.ts +4 -4
- package/src/prompts/__tests__/task-progress-hint-section.test.ts +3 -9
- package/src/prompts/persona-resolver.ts +36 -21
- package/src/prompts/sections.ts +39 -7
- package/src/prompts/system-prompt.ts +84 -221
- package/src/prompts/template-detection.ts +10 -4
- package/src/prompts/templates/BOOTSTRAP.md +9 -13
- package/src/prompts/templates/IDENTITY.md +0 -2
- package/src/prompts/templates/system-sections.ts +230 -8
- package/src/providers/__tests__/connection-model-compat.test.ts +233 -0
- package/src/providers/__tests__/registry-native-web-search.test.ts +122 -0
- package/src/providers/__tests__/retry-callsite.test.ts +85 -5
- package/src/providers/anthropic/client.ts +32 -66
- package/src/providers/call-site-routing.ts +42 -6
- package/src/providers/connection-model-compat.ts +61 -0
- package/src/providers/connection-resolution.ts +47 -14
- package/src/providers/fireworks/client.ts +1 -0
- package/src/providers/gemini/client.ts +70 -6
- package/src/providers/inference/__tests__/adapter-factory-openai-compatible.test.ts +0 -2
- package/src/providers/inference/__tests__/base-url-security.test.ts +2 -3
- package/src/providers/inference/__tests__/{connections-status-label.test.ts → connections-label.test.ts} +12 -111
- package/src/providers/inference/adapter-factory.ts +3 -0
- package/src/providers/inference/auth.ts +0 -8
- package/src/providers/inference/connections.ts +3 -66
- package/src/providers/inference/resolve-auth.ts +2 -3
- package/src/providers/minimax/client.ts +106 -0
- package/src/providers/model-catalog.ts +78 -1
- package/src/providers/model-intents.ts +4 -4
- package/src/providers/openai/__tests__/api-error-detail.test.ts +120 -0
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +157 -5
- package/src/providers/openai/chat-completions-provider.ts +116 -15
- package/src/providers/openai/codex-models.ts +20 -0
- package/src/providers/openai/responses-provider.ts +87 -30
- package/src/providers/openrouter/client.ts +13 -8
- package/src/providers/provider-send-message.ts +20 -5
- package/src/providers/registry.ts +48 -8
- package/src/providers/retry.ts +50 -7
- package/src/providers/search-provider-catalog.ts +17 -9
- package/src/providers/thinking-config.ts +26 -1
- package/src/providers/types.ts +9 -0
- package/src/providers/usage-tracking.ts +2 -0
- package/src/runtime/AGENTS.md +2 -2
- package/src/runtime/__tests__/agent-wake.test.ts +1 -0
- package/src/runtime/__tests__/background-job-runner.test.ts +1 -0
- package/src/runtime/access-request-helper.ts +1 -0
- package/src/runtime/agent-wake.ts +1 -0
- package/src/runtime/assistant-event-hub.ts +76 -6
- package/src/runtime/auth/route-policy.ts +46 -0
- package/src/runtime/btw-sidechain.ts +0 -6
- package/src/runtime/channel-readiness-service.ts +68 -0
- package/src/runtime/channel-reply-delivery.ts +23 -0
- package/src/runtime/channel-retry-sweep.ts +47 -14
- package/src/runtime/confirmation-request-guardian-bridge.ts +1 -1
- package/src/runtime/http-types.ts +0 -2
- package/src/runtime/migrations/vbundle-builder.ts +12 -4
- package/src/runtime/pending-interactions.ts +0 -1
- package/src/runtime/routes/__tests__/bookmark-routes.test.ts +1 -0
- package/src/runtime/routes/__tests__/conversation-compaction-routes.test.ts +406 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +204 -0
- package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/home-feed-routes.test.ts +209 -1
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +13 -50
- package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +76 -9
- package/src/runtime/routes/__tests__/memory-v3-simulate-params.test.ts +35 -0
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +512 -0
- package/src/runtime/routes/__tests__/slack-channel-routes.test.ts +3 -2
- package/src/runtime/routes/__tests__/surface-content-routes.test.ts +294 -0
- package/src/runtime/routes/__tests__/task-routes.test.ts +48 -3
- package/src/runtime/routes/acp-routes-list.test.ts +3 -0
- package/src/runtime/routes/acp-routes.test.ts +255 -6
- package/src/runtime/routes/acp-routes.ts +8 -1
- package/src/runtime/routes/app-management-routes.ts +111 -4
- package/src/runtime/routes/avatar-routes.ts +10 -10
- package/src/runtime/routes/background-wake-routes.ts +356 -0
- package/src/runtime/routes/browser-tabs-routes.ts +200 -0
- package/src/runtime/routes/btw-routes.ts +4 -10
- package/src/runtime/routes/conversation-analysis-routes.ts +6 -0
- package/src/runtime/routes/conversation-cli-routes.ts +1 -1
- package/src/runtime/routes/conversation-compaction-routes.ts +263 -0
- package/src/runtime/routes/conversation-list-routes.ts +159 -4
- package/src/runtime/routes/conversation-management-routes.ts +108 -26
- package/src/runtime/routes/conversation-query-routes.ts +200 -44
- package/src/runtime/routes/conversation-routes.ts +409 -521
- package/src/runtime/routes/conversation-starter-routes.ts +6 -3
- package/src/runtime/routes/conversations-import-routes.ts +19 -6
- package/src/runtime/routes/disk-pressure-routes.ts +1 -1
- package/src/runtime/routes/documents-routes.ts +10 -1
- 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 +35 -8
- package/src/runtime/routes/home-feed-routes.ts +129 -0
- package/src/runtime/routes/host-browser-routes.ts +10 -2
- package/src/runtime/routes/host-cu-routes.ts +2 -2
- package/src/runtime/routes/identity-intro-cache.ts +61 -16
- package/src/runtime/routes/identity-routes.ts +30 -9
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +96 -3
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +530 -6
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +57 -8
- package/src/runtime/routes/index.ts +10 -0
- 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 +5 -26
- package/src/runtime/routes/integrations/vercel.ts +15 -0
- package/src/runtime/routes/llm-call-sites-routes.ts +32 -5
- package/src/runtime/routes/llm-context-normalization.ts +7 -2
- package/src/runtime/routes/memory-item-routes.ts +8 -3
- package/src/runtime/routes/memory-v2-routes.ts +215 -5
- package/src/runtime/routes/memory-v3-routes.ts +474 -0
- package/src/runtime/routes/migration-routes.ts +32 -28
- package/src/runtime/routes/notification-routes.ts +63 -1
- package/src/runtime/routes/oauth-commands-routes.ts +6 -1
- package/src/runtime/routes/plugins-routes.ts +337 -0
- package/src/runtime/routes/rename-conversation-routes.ts +6 -2
- 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 +5 -4
- package/src/runtime/routes/surface-action-routes.ts +1 -38
- package/src/runtime/routes/surface-content-routes.ts +12 -5
- package/src/runtime/routes/surface-conversation-resolver.ts +65 -0
- package/src/runtime/routes/wipe-conversation-routes.ts +3 -0
- package/src/runtime/routes/workspace-routes.ts +25 -10
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +2 -0
- package/src/runtime/slack-dm-text-delivery.ts +177 -0
- 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/tool-grant-request-helper.ts +1 -0
- package/src/runtime/verification-outbound-actions.ts +73 -1
- package/src/schedule/schedule-store.ts +8 -1
- package/src/schedule/scheduler.ts +111 -15
- package/src/security/__tests__/provider-key-env-fallback.test.ts +3 -3
- package/src/security/encrypted-store.ts +7 -16
- package/src/security/store-path-override.ts +61 -0
- package/src/signals/user-message.ts +5 -8
- package/src/skills/validate-input.ts +177 -0
- package/src/subagent/manager.ts +13 -13
- package/src/subagent/types.ts +6 -0
- package/src/tasks/tool-sanitizer.ts +2 -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 +36 -28
- 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__/browser-execution-acquire.test.ts +2 -8
- package/src/tools/browser/__tests__/pinned-tabs.test.ts +70 -0
- package/src/tools/browser/browser-execution.ts +16 -3
- package/src/tools/browser/cdp-client/__tests__/browser-tabs-factory.test.ts +402 -0
- package/src/tools/browser/cdp-client/__tests__/types.test.ts +3 -0
- package/src/tools/browser/cdp-client/cdp-inspect-client.ts +12 -0
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +27 -1
- package/src/tools/browser/cdp-client/factory.ts +100 -17
- package/src/tools/browser/cdp-client/local-cdp-client.ts +12 -0
- package/src/tools/browser/cdp-client/types.ts +65 -0
- package/src/tools/browser/pinned-tabs.ts +96 -40
- package/src/tools/computer-use/definitions.ts +282 -336
- 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-tool.ts +189 -7
- package/src/tools/execution-target.ts +18 -23
- package/src/tools/executor.ts +24 -56
- 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.test.ts +1 -0
- package/src/tools/host-filesystem/edit.ts +3 -9
- package/src/tools/host-filesystem/read.test.ts +1 -0
- package/src/tools/host-filesystem/read.ts +3 -9
- package/src/tools/host-filesystem/transfer.test.ts +31 -6
- package/src/tools/host-filesystem/transfer.ts +3 -9
- package/src/tools/host-filesystem/write.test.ts +1 -0
- 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 -10
- package/src/tools/memory/register.test.ts +1 -1
- package/src/tools/memory/register.ts +4 -9
- package/src/tools/network/__tests__/managed-search-proxy.test.ts +282 -0
- package/src/tools/network/__tests__/web-search.test.ts +211 -3
- package/src/tools/network/managed-search-proxy.ts +183 -0
- package/src/tools/network/web-fetch.ts +3 -9
- package/src/tools/network/web-search.ts +224 -76
- package/src/tools/policy-context.ts +3 -1
- package/src/tools/registry.ts +150 -123
- package/src/tools/schedule/create.ts +1 -1
- 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 +18 -44
- package/src/tools/subagent/notify-parent.ts +3 -9
- package/src/tools/subagent/spawn.ts +3 -0
- package/src/tools/system/request-permission.ts +3 -9
- package/src/tools/terminal/shell.ts +3 -9
- package/src/tools/tool-approval-handler.ts +10 -4
- package/src/tools/tool-defaults.ts +94 -0
- package/src/tools/tool-name-aliases.ts +72 -14
- package/src/tools/types.ts +32 -101
- package/src/tools/ui-surface/definitions.ts +104 -108
- package/src/types/onboarding-context.ts +6 -0
- package/src/usage/attribution.ts +32 -1
- package/src/usage/pricing.ts +23 -0
- package/src/usage/types.ts +12 -0
- package/src/util/browser.ts +7 -2
- package/src/util/logger.ts +16 -7
- package/src/util/platform.ts +7 -2
- package/src/util/sqlite3-runtime.ts +65 -0
- package/src/workspace/migrations/086-revert-stale-gemini-mis-rewrites.ts +1 -0
- package/src/workspace/migrations/089-move-memory-tree-out-of-v3.ts +86 -0
- package/src/workspace/migrations/090-memory-router-cost-optimized-profile.ts +109 -0
- package/src/workspace/migrations/091-retighten-migration-onboarding-thread.ts +41 -0
- package/src/workspace/migrations/registry.ts +6 -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/daemon/query-complexity-router.ts +0 -75
- package/src/prompts/cache-boundary.ts +0 -8
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
getMessages,
|
|
17
17
|
type MessageRow,
|
|
18
18
|
} from "../memory/conversation-crud.js";
|
|
19
|
-
import { enqueueMemoryJob } from "../memory/jobs-store.js";
|
|
19
|
+
import { enqueueMemoryJob, isMemoryEnabled } from "../memory/jobs-store.js";
|
|
20
20
|
import { enqueueMemoryRetrospectiveIfEnabled } from "../memory/memory-retrospective-enqueue.js";
|
|
21
21
|
import { shouldExposePersonalMemory } from "../memory/v2/static-context.js";
|
|
22
22
|
import type { PermissionPrompter } from "../permissions/prompter.js";
|
|
@@ -189,17 +189,18 @@ export async function loadFromDb(ctx: LoadFromDbContext): Promise<void> {
|
|
|
189
189
|
ctx.contextCompactedAt = conv?.contextCompactedAt ?? null;
|
|
190
190
|
}
|
|
191
191
|
|
|
192
|
-
// `/clean`
|
|
193
|
-
//
|
|
194
|
-
//
|
|
195
|
-
|
|
192
|
+
// Every injection-strip event (`/clean` or compaction) updates
|
|
193
|
+
// `historyStrippedAt`. Messages older than this should skip metadata
|
|
194
|
+
// rehydration and have any injection prefixes still embedded in their
|
|
195
|
+
// content stripped, so the post-strip view survives reload and forks.
|
|
196
|
+
const historyStrippedAt = conv?.historyStrippedAt ?? null;
|
|
196
197
|
const slicedDbMessages = dbMessages.slice(ctx.contextCompactedMessageCount);
|
|
197
|
-
let
|
|
198
|
-
if (
|
|
198
|
+
let preStrippedCount = 0;
|
|
199
|
+
if (historyStrippedAt != null) {
|
|
199
200
|
const boundary = slicedDbMessages.findIndex(
|
|
200
|
-
(m) => m.createdAt >=
|
|
201
|
+
(m) => m.createdAt >= historyStrippedAt,
|
|
201
202
|
);
|
|
202
|
-
|
|
203
|
+
preStrippedCount = boundary === -1 ? slicedDbMessages.length : boundary;
|
|
203
204
|
}
|
|
204
205
|
|
|
205
206
|
// Mirror the injection-time gate (`shouldExposePersonalMemory` in
|
|
@@ -213,7 +214,7 @@ export async function loadFromDb(ctx: LoadFromDbContext): Promise<void> {
|
|
|
213
214
|
isTrustedActor: resolveTrustClass(ctx.trustContext) === "guardian",
|
|
214
215
|
});
|
|
215
216
|
const parsedMessages: Message[] = slicedDbMessages.map((m, index, arr) => {
|
|
216
|
-
const
|
|
217
|
+
const isPreStripped = index < preStrippedCount;
|
|
217
218
|
const role = m.role as "user" | "assistant";
|
|
218
219
|
let content: ContentBlock[];
|
|
219
220
|
try {
|
|
@@ -233,7 +234,7 @@ export async function loadFromDb(ctx: LoadFromDbContext): Promise<void> {
|
|
|
233
234
|
|
|
234
235
|
// Re-inject persisted injection blocks from metadata so it survives
|
|
235
236
|
// conversation reloads (eviction, restart, fork).
|
|
236
|
-
if (role === "user" && m.metadata && !
|
|
237
|
+
if (role === "user" && m.metadata && !isPreStripped) {
|
|
237
238
|
try {
|
|
238
239
|
const meta = JSON.parse(m.metadata);
|
|
239
240
|
const isTail = index === arr.length - 1;
|
|
@@ -244,9 +245,12 @@ export async function loadFromDb(ctx: LoadFromDbContext): Promise<void> {
|
|
|
244
245
|
// (pkb-context 30, pkb-reminder 35, memory-v2-static 38,
|
|
245
246
|
// now-md 40 — the v2 static block lands inside the memory
|
|
246
247
|
// prefix, so now-md splices *after* it):
|
|
247
|
-
// [<workspace>, <turn_context>, <memory
|
|
248
|
-
// <
|
|
248
|
+
// [<workspace>, <turn_context>, <memory>dynamic</memory>,
|
|
249
|
+
// <info>v2static</info>, <NOW.md>, <system_reminder>,
|
|
249
250
|
// <knowledge_base>, ...original]
|
|
251
|
+
// The v2 static block is replayed verbatim from stored metadata,
|
|
252
|
+
// so rows may carry either `<info>…</info>` or `<memory>…</memory>`
|
|
253
|
+
// depending on when they were persisted.
|
|
250
254
|
// Required so Anthropic's prefix cache keeps matching msg[0]
|
|
251
255
|
// across daemon restart and conversation eviction. The tail
|
|
252
256
|
// row only rehydrates `memoryInjectedBlock` — the next turn
|
|
@@ -273,11 +277,12 @@ export async function loadFromDb(ctx: LoadFromDbContext): Promise<void> {
|
|
|
273
277
|
}
|
|
274
278
|
|
|
275
279
|
// The v2 static memory block (essentials/threads/recent/buffer
|
|
276
|
-
// wrapped in `<memory>…</memory>`)
|
|
277
|
-
// Trust-gated to mirror
|
|
278
|
-
// time — untrusted-actor
|
|
279
|
-
//
|
|
280
|
-
//
|
|
280
|
+
// wrapped in either `<info>…</info>` or `<memory>…</memory>`)
|
|
281
|
+
// carries personal user memory. Trust-gated to mirror
|
|
282
|
+
// `shouldExposePersonalMemory` at injection time — untrusted-actor
|
|
283
|
+
// views must not read persisted personal memory back through
|
|
284
|
+
// metadata. Skipped on the tail row because the next turn
|
|
285
|
+
// re-injects fresh content on full-mode turns.
|
|
281
286
|
if (
|
|
282
287
|
!isTail &&
|
|
283
288
|
personalMemoryAllowed &&
|
|
@@ -336,13 +341,13 @@ export async function loadFromDb(ctx: LoadFromDbContext): Promise<void> {
|
|
|
336
341
|
// Strip pre-clean messages only; post-clean messages keep the fresh
|
|
337
342
|
// injections they were generated with.
|
|
338
343
|
const messagesBeforeRepair =
|
|
339
|
-
|
|
344
|
+
preStrippedCount === 0
|
|
340
345
|
? parsedMessages
|
|
341
346
|
: [
|
|
342
347
|
...stripInjectionsForCompaction(
|
|
343
|
-
parsedMessages.slice(0,
|
|
348
|
+
parsedMessages.slice(0, preStrippedCount),
|
|
344
349
|
),
|
|
345
|
-
...parsedMessages.slice(
|
|
350
|
+
...parsedMessages.slice(preStrippedCount),
|
|
346
351
|
];
|
|
347
352
|
|
|
348
353
|
const { messages: repairedMessages, stats } =
|
|
@@ -448,7 +453,7 @@ export function disposeConversation(ctx: DisposeContext): void {
|
|
|
448
453
|
} catch {
|
|
449
454
|
// Best-effort — fall through to legacy v1 enqueue
|
|
450
455
|
}
|
|
451
|
-
if (!v2Enabled) {
|
|
456
|
+
if (!v2Enabled && isMemoryEnabled()) {
|
|
452
457
|
try {
|
|
453
458
|
enqueueMemoryJob("graph_extract", {
|
|
454
459
|
conversationId: ctx.conversationId,
|
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
} from "../memory/attachments-store.js";
|
|
27
27
|
import {
|
|
28
28
|
addMessage,
|
|
29
|
+
extractImageSourcePaths,
|
|
29
30
|
getConversation,
|
|
30
31
|
provenanceFromTrustContext,
|
|
31
32
|
setConversationOriginChannelIfUnset,
|
|
@@ -284,22 +285,44 @@ export function buildSlackMetaForPersistence(params: {
|
|
|
284
285
|
return writeSlackMetadata(slackMeta);
|
|
285
286
|
}
|
|
286
287
|
|
|
288
|
+
// ── EnqueueMessageOptions ────────────────────────────────────────────
|
|
289
|
+
|
|
290
|
+
/** Options for `enqueueMessage`. Only `content` is required; everything
|
|
291
|
+
* else has a sensible default or is genuinely optional. */
|
|
292
|
+
export interface EnqueueMessageOptions {
|
|
293
|
+
content: string;
|
|
294
|
+
attachments?: UserMessageAttachment[];
|
|
295
|
+
onEvent?: (msg: ServerMessage) => void;
|
|
296
|
+
requestId?: string;
|
|
297
|
+
activeSurfaceId?: string;
|
|
298
|
+
currentPage?: string;
|
|
299
|
+
metadata?: Record<string, unknown>;
|
|
300
|
+
isInteractive?: boolean;
|
|
301
|
+
displayContent?: string;
|
|
302
|
+
transport?: ConversationTransportMetadata;
|
|
303
|
+
clientMessageId?: string;
|
|
304
|
+
}
|
|
305
|
+
|
|
287
306
|
// ── enqueueMessage ───────────────────────────────────────────────────
|
|
288
307
|
|
|
289
308
|
export function enqueueMessage(
|
|
290
309
|
ctx: MessagingConversationContext,
|
|
291
|
-
|
|
292
|
-
attachments: UserMessageAttachment[],
|
|
293
|
-
onEvent: (msg: ServerMessage) => void,
|
|
294
|
-
requestId: string,
|
|
295
|
-
activeSurfaceId?: string,
|
|
296
|
-
currentPage?: string,
|
|
297
|
-
metadata?: Record<string, unknown>,
|
|
298
|
-
options?: { isInteractive?: boolean },
|
|
299
|
-
displayContent?: string,
|
|
300
|
-
transport?: ConversationTransportMetadata,
|
|
301
|
-
clientMessageId?: string,
|
|
310
|
+
options: EnqueueMessageOptions,
|
|
302
311
|
): { queued: boolean; requestId: string; rejected?: boolean } {
|
|
312
|
+
const {
|
|
313
|
+
content,
|
|
314
|
+
attachments = [],
|
|
315
|
+
onEvent,
|
|
316
|
+
requestId = crypto.randomUUID(),
|
|
317
|
+
activeSurfaceId,
|
|
318
|
+
currentPage,
|
|
319
|
+
metadata,
|
|
320
|
+
isInteractive,
|
|
321
|
+
displayContent,
|
|
322
|
+
transport,
|
|
323
|
+
clientMessageId,
|
|
324
|
+
} = options;
|
|
325
|
+
|
|
303
326
|
if (!ctx.processing) {
|
|
304
327
|
return { queued: false, requestId };
|
|
305
328
|
}
|
|
@@ -316,20 +339,20 @@ export function enqueueMessage(
|
|
|
316
339
|
content,
|
|
317
340
|
attachments,
|
|
318
341
|
requestId,
|
|
319
|
-
onEvent,
|
|
342
|
+
onEvent: onEvent ?? (() => {}),
|
|
320
343
|
activeSurfaceId,
|
|
321
344
|
currentPage,
|
|
322
345
|
metadata,
|
|
323
346
|
turnChannelContext,
|
|
324
347
|
turnInterfaceContext,
|
|
325
|
-
isInteractive
|
|
348
|
+
isInteractive,
|
|
326
349
|
transport,
|
|
327
350
|
displayContent,
|
|
328
351
|
sentAt: Date.now(),
|
|
329
352
|
clientMessageId,
|
|
330
353
|
});
|
|
331
354
|
if (!accepted) {
|
|
332
|
-
onEvent({
|
|
355
|
+
onEvent?.({
|
|
333
356
|
type: "error",
|
|
334
357
|
conversationId: ctx.conversationId,
|
|
335
358
|
message:
|
|
@@ -341,16 +364,26 @@ export function enqueueMessage(
|
|
|
341
364
|
return { queued: true, requestId };
|
|
342
365
|
}
|
|
343
366
|
|
|
367
|
+
// ── PersistMessageOptions ────────────────────────────────────────────
|
|
368
|
+
|
|
369
|
+
/** Shared options for `persistUserMessage` and `persistQueuedMessageBody`. */
|
|
370
|
+
export interface PersistMessageOptions {
|
|
371
|
+
content: string;
|
|
372
|
+
attachments?: UserMessageAttachment[];
|
|
373
|
+
requestId?: string;
|
|
374
|
+
metadata?: Record<string, unknown>;
|
|
375
|
+
displayContent?: string;
|
|
376
|
+
clientMessageId?: string;
|
|
377
|
+
}
|
|
378
|
+
|
|
344
379
|
// ── persistUserMessage ───────────────────────────────────────────────
|
|
345
380
|
|
|
346
381
|
export async function persistUserMessage(
|
|
347
382
|
ctx: MessagingConversationContext,
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
displayContent?: string,
|
|
353
|
-
): Promise<string> {
|
|
383
|
+
options: PersistMessageOptions,
|
|
384
|
+
): Promise<{ id: string; deduplicated: boolean }> {
|
|
385
|
+
const { content, attachments = [] } = options;
|
|
386
|
+
|
|
354
387
|
if (ctx.processing) {
|
|
355
388
|
throw new Error("Conversation is already processing a message");
|
|
356
389
|
}
|
|
@@ -359,20 +392,23 @@ export async function persistUserMessage(
|
|
|
359
392
|
throw new Error("Message content or attachments are required");
|
|
360
393
|
}
|
|
361
394
|
|
|
362
|
-
const reqId = requestId ?? uuid();
|
|
395
|
+
const reqId = options.requestId ?? uuid();
|
|
363
396
|
ctx.currentRequestId = reqId;
|
|
364
397
|
ctx.processing = true;
|
|
365
398
|
ctx.abortController = new AbortController();
|
|
366
399
|
|
|
367
400
|
try {
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
content,
|
|
401
|
+
const result = await persistQueuedMessageBody(ctx, {
|
|
402
|
+
...options,
|
|
371
403
|
attachments,
|
|
372
|
-
reqId,
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
404
|
+
requestId: reqId,
|
|
405
|
+
});
|
|
406
|
+
if (result.deduplicated) {
|
|
407
|
+
ctx.processing = false;
|
|
408
|
+
ctx.abortController = null;
|
|
409
|
+
ctx.currentRequestId = undefined;
|
|
410
|
+
}
|
|
411
|
+
return result;
|
|
376
412
|
} catch (err) {
|
|
377
413
|
ctx.processing = false;
|
|
378
414
|
ctx.abortController = null;
|
|
@@ -394,12 +430,16 @@ export async function persistUserMessage(
|
|
|
394
430
|
*/
|
|
395
431
|
export async function persistQueuedMessageBody(
|
|
396
432
|
ctx: MessagingConversationContext,
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
433
|
+
options: PersistMessageOptions,
|
|
434
|
+
): Promise<{ id: string; deduplicated: boolean }> {
|
|
435
|
+
const {
|
|
436
|
+
content,
|
|
437
|
+
attachments = [],
|
|
438
|
+
requestId = uuid(),
|
|
439
|
+
metadata,
|
|
440
|
+
displayContent,
|
|
441
|
+
clientMessageId,
|
|
442
|
+
} = options;
|
|
403
443
|
const attachmentInputs = attachments.map((attachment) => ({
|
|
404
444
|
id: attachment.id,
|
|
405
445
|
filename: attachment.filename,
|
|
@@ -431,13 +471,7 @@ export async function persistQueuedMessageBody(
|
|
|
431
471
|
const turnIfCtx =
|
|
432
472
|
extractTurnInterfaceContext(metadata) ?? ctx.getTurnInterfaceContext();
|
|
433
473
|
const provenance = provenanceFromTrustContext(ctx.trustContext);
|
|
434
|
-
const imageSourcePaths
|
|
435
|
-
for (let i = 0; i < attachments.length; i++) {
|
|
436
|
-
const a = attachments[i];
|
|
437
|
-
if (a.filePath && a.mimeType.toLowerCase().startsWith("image/")) {
|
|
438
|
-
imageSourcePaths[`${i}:${a.filename}`] = a.filePath;
|
|
439
|
-
}
|
|
440
|
-
}
|
|
474
|
+
const imageSourcePaths = extractImageSourcePaths(attachments);
|
|
441
475
|
|
|
442
476
|
// Strip the transient `slackInbound` carrier key from the persisted
|
|
443
477
|
// metadata — it's an in-memory plumbing field, not a stored column value.
|
|
@@ -468,7 +502,7 @@ export async function persistQueuedMessageBody(
|
|
|
468
502
|
assistantMessageInterface: turnIfCtx.assistantMessageInterface,
|
|
469
503
|
}
|
|
470
504
|
: {}),
|
|
471
|
-
...(
|
|
505
|
+
...(imageSourcePaths ? { imageSourcePaths } : {}),
|
|
472
506
|
...(slackMeta ? { slackMeta } : {}),
|
|
473
507
|
};
|
|
474
508
|
|
|
@@ -486,8 +520,15 @@ export async function persistQueuedMessageBody(
|
|
|
486
520
|
"user",
|
|
487
521
|
contentToPersist,
|
|
488
522
|
mergedMetadata,
|
|
523
|
+
undefined,
|
|
524
|
+
clientMessageId,
|
|
489
525
|
);
|
|
490
526
|
|
|
527
|
+
if (persistedUserMessage.deduplicated) {
|
|
528
|
+
ctx.messages.pop();
|
|
529
|
+
return { id: persistedUserMessage.id, deduplicated: true };
|
|
530
|
+
}
|
|
531
|
+
|
|
491
532
|
if (turnCtx) {
|
|
492
533
|
setConversationOriginChannelIfUnset(
|
|
493
534
|
ctx.conversationId,
|
|
@@ -569,7 +610,7 @@ export async function persistQueuedMessageBody(
|
|
|
569
610
|
);
|
|
570
611
|
}
|
|
571
612
|
|
|
572
|
-
return persistedUserMessage.id;
|
|
613
|
+
return { id: persistedUserMessage.id, deduplicated: false };
|
|
573
614
|
} catch (err) {
|
|
574
615
|
ctx.messages.pop();
|
|
575
616
|
throw err;
|
|
@@ -34,6 +34,7 @@ import { routeGuardianReply } from "../runtime/guardian-reply-router.js";
|
|
|
34
34
|
import { publishConversationMessagesChanged } from "../runtime/sync/resource-sync-events.js";
|
|
35
35
|
import { getLogger } from "../util/logger.js";
|
|
36
36
|
import type { CleanResult } from "./conversation.js";
|
|
37
|
+
import type { PersistMessageOptions } from "./conversation-messaging.js";
|
|
37
38
|
import {
|
|
38
39
|
persistQueuedMessageBody,
|
|
39
40
|
serializePersistedUserMessageContent,
|
|
@@ -158,12 +159,8 @@ export interface ProcessConversationContext {
|
|
|
158
159
|
currentTurnChannelCapabilities?: ChannelCapabilities;
|
|
159
160
|
ensureActorScopedHistory(): Promise<void>;
|
|
160
161
|
persistUserMessage(
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
requestId?: string,
|
|
164
|
-
metadata?: Record<string, unknown>,
|
|
165
|
-
displayContent?: string,
|
|
166
|
-
): Promise<string>;
|
|
162
|
+
options: PersistMessageOptions,
|
|
163
|
+
): Promise<{ id: string; deduplicated: boolean }>;
|
|
167
164
|
runAgentLoop(
|
|
168
165
|
content: string,
|
|
169
166
|
userMessageId: string,
|
|
@@ -921,15 +918,16 @@ async function drainSingleMessage(
|
|
|
921
918
|
// succeeds, runAgentLoop is called and its finally block will drain
|
|
922
919
|
// the next message. If persistUserMessage fails, processMessage
|
|
923
920
|
// resolves early (no runAgentLoop call), so we must continue draining.
|
|
924
|
-
let
|
|
921
|
+
let persistResult: { id: string; deduplicated: boolean };
|
|
925
922
|
try {
|
|
926
|
-
|
|
927
|
-
resolvedContent,
|
|
928
|
-
next.attachments,
|
|
929
|
-
next.requestId,
|
|
930
|
-
{ ...next.metadata, sentAt: next.sentAt },
|
|
931
|
-
next.displayContent,
|
|
932
|
-
|
|
923
|
+
persistResult = await conversation.persistUserMessage({
|
|
924
|
+
content: resolvedContent,
|
|
925
|
+
attachments: next.attachments,
|
|
926
|
+
requestId: next.requestId,
|
|
927
|
+
metadata: { ...next.metadata, sentAt: next.sentAt },
|
|
928
|
+
displayContent: next.displayContent,
|
|
929
|
+
clientMessageId: next.clientMessageId,
|
|
930
|
+
});
|
|
933
931
|
} catch (err) {
|
|
934
932
|
const message = err instanceof Error ? err.message : String(err);
|
|
935
933
|
log.error(
|
|
@@ -961,6 +959,18 @@ async function drainSingleMessage(
|
|
|
961
959
|
return;
|
|
962
960
|
}
|
|
963
961
|
|
|
962
|
+
const userMessageId = persistResult.id;
|
|
963
|
+
|
|
964
|
+
if (persistResult.deduplicated) {
|
|
965
|
+
log.info(
|
|
966
|
+
{ conversationId: conversation.conversationId, userMessageId },
|
|
967
|
+
"Skipping agent loop for deduplicated queued message",
|
|
968
|
+
);
|
|
969
|
+
conversation.preactivatedSkillIds = undefined;
|
|
970
|
+
await drainQueue(conversation);
|
|
971
|
+
return;
|
|
972
|
+
}
|
|
973
|
+
|
|
964
974
|
// Broadcast the user message to all hub subscribers so passive devices
|
|
965
975
|
// see the user turn before the assistant reply starts streaming.
|
|
966
976
|
next.onEvent({
|
|
@@ -1217,24 +1227,43 @@ async function drainBatch(
|
|
|
1217
1227
|
const qmContent = qmSlash.content;
|
|
1218
1228
|
|
|
1219
1229
|
try {
|
|
1230
|
+
let batchPersistResult: { id: string; deduplicated: boolean };
|
|
1231
|
+
const persistOptions = {
|
|
1232
|
+
content: qmContent,
|
|
1233
|
+
attachments: qm.attachments,
|
|
1234
|
+
requestId: qm.requestId,
|
|
1235
|
+
metadata: { ...qm.metadata, sentAt: qm.sentAt },
|
|
1236
|
+
displayContent: qm.displayContent,
|
|
1237
|
+
clientMessageId: qm.clientMessageId,
|
|
1238
|
+
};
|
|
1220
1239
|
if (i === 0) {
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
qm.attachments,
|
|
1224
|
-
qm.requestId,
|
|
1225
|
-
{ ...qm.metadata, sentAt: qm.sentAt },
|
|
1226
|
-
qm.displayContent,
|
|
1227
|
-
);
|
|
1240
|
+
batchPersistResult =
|
|
1241
|
+
await conversation.persistUserMessage(persistOptions);
|
|
1228
1242
|
} else {
|
|
1229
|
-
|
|
1243
|
+
batchPersistResult = await persistQueuedMessageBody(
|
|
1230
1244
|
conversation,
|
|
1231
|
-
|
|
1232
|
-
qm.attachments,
|
|
1233
|
-
qm.requestId,
|
|
1234
|
-
{ ...qm.metadata, sentAt: qm.sentAt },
|
|
1235
|
-
qm.displayContent,
|
|
1245
|
+
persistOptions,
|
|
1236
1246
|
);
|
|
1237
1247
|
}
|
|
1248
|
+
if (batchPersistResult.deduplicated) {
|
|
1249
|
+
if (i === 0) {
|
|
1250
|
+
// Head was deduplicated — persistUserMessage cleared the
|
|
1251
|
+
// processing flag. Recursively drain remaining items so the
|
|
1252
|
+
// first non-duplicate becomes the new batch head and sets
|
|
1253
|
+
// processing via persistUserMessage.
|
|
1254
|
+
const remaining = batch.slice(1);
|
|
1255
|
+
if (remaining.length >= 2) {
|
|
1256
|
+
await drainBatch(conversation, remaining, reason);
|
|
1257
|
+
} else if (remaining.length === 1) {
|
|
1258
|
+
await drainSingleMessage(conversation, remaining[0], reason);
|
|
1259
|
+
} else {
|
|
1260
|
+
await drainQueue(conversation);
|
|
1261
|
+
}
|
|
1262
|
+
return;
|
|
1263
|
+
}
|
|
1264
|
+
continue;
|
|
1265
|
+
}
|
|
1266
|
+
lastUserMessageId = batchPersistResult.id;
|
|
1238
1267
|
} catch (err) {
|
|
1239
1268
|
const message = err instanceof Error ? err.message : String(err);
|
|
1240
1269
|
log.error(
|
|
@@ -1377,12 +1406,19 @@ async function drainBatch(
|
|
|
1377
1406
|
conversation.currentActiveSurfaceId = lastSuccessfulActiveSurfaceId;
|
|
1378
1407
|
conversation.currentPage = lastSuccessfulCurrentPage;
|
|
1379
1408
|
|
|
1380
|
-
// Broadcast agent-loop events only to
|
|
1381
|
-
//
|
|
1382
|
-
//
|
|
1383
|
-
//
|
|
1409
|
+
// Broadcast agent-loop events only to unique sinks whose persist succeeded.
|
|
1410
|
+
// Multiple web-queued messages share the same broadcastMessage callback; if
|
|
1411
|
+
// we call it once per queued message, every text delta is published N times
|
|
1412
|
+
// to the same SSE stream and the client renders duplicated text.
|
|
1413
|
+
//
|
|
1414
|
+
// Members whose persist failed already received an error event in the catch
|
|
1415
|
+
// block above; sending them the assistant's streaming response would surface
|
|
1416
|
+
// a reply for a user message that isn't in their DB.
|
|
1417
|
+
const successfulEventSinks = Array.from(
|
|
1418
|
+
new Set(successfulBatch.map((qm) => qm.onEvent)),
|
|
1419
|
+
);
|
|
1384
1420
|
const fanOutOnEvent = (msg: ServerMessage) => {
|
|
1385
|
-
for (const
|
|
1421
|
+
for (const onEvent of successfulEventSinks) onEvent(msg);
|
|
1386
1422
|
};
|
|
1387
1423
|
|
|
1388
1424
|
const drainLoopOptions: {
|
|
@@ -1857,15 +1893,14 @@ export async function processMessage(
|
|
|
1857
1893
|
}
|
|
1858
1894
|
}
|
|
1859
1895
|
|
|
1860
|
-
let
|
|
1896
|
+
let pmResult: { id: string; deduplicated: boolean };
|
|
1861
1897
|
try {
|
|
1862
|
-
|
|
1863
|
-
resolvedContent,
|
|
1898
|
+
pmResult = await conversation.persistUserMessage({
|
|
1899
|
+
content: resolvedContent,
|
|
1864
1900
|
attachments,
|
|
1865
1901
|
requestId,
|
|
1866
|
-
undefined,
|
|
1867
1902
|
displayContent,
|
|
1868
|
-
);
|
|
1903
|
+
});
|
|
1869
1904
|
publishConversationMessagesChanged(conversation.conversationId);
|
|
1870
1905
|
} catch (err) {
|
|
1871
1906
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -1879,6 +1914,8 @@ export async function processMessage(
|
|
|
1879
1914
|
return "";
|
|
1880
1915
|
}
|
|
1881
1916
|
|
|
1917
|
+
const userMessageId = pmResult.id;
|
|
1918
|
+
|
|
1882
1919
|
// Fire-and-forget: detect notification preferences in the user message
|
|
1883
1920
|
// and persist any that are found. Runs in the background so it doesn't
|
|
1884
1921
|
// block the main conversation flow.
|
|
@@ -997,23 +997,38 @@ export function buildUnifiedTurnContextBlock(
|
|
|
997
997
|
// ---------------------------------------------------------------------------
|
|
998
998
|
|
|
999
999
|
/**
|
|
1000
|
-
*
|
|
1001
|
-
*
|
|
1002
|
-
* the
|
|
1000
|
+
* A matcher for an injected text block. A plain string matches by prefix
|
|
1001
|
+
* (`startsWith`). A `{ prefix, suffix }` wrapper requires BOTH the opening
|
|
1002
|
+
* prefix and the closing suffix, so user-authored content that merely begins
|
|
1003
|
+
* with an injection-like opening tag (e.g. a message discussing `<info>`
|
|
1004
|
+
* markup) is not mistaken for an injected block and dropped. This mirrors
|
|
1005
|
+
* `countMemoryPrefixBlocks`, which only treats `<memory>…</memory>` /
|
|
1006
|
+
* `<info>…</info>` blocks as injected when the full wrapper is present.
|
|
1007
|
+
*/
|
|
1008
|
+
type InjectionMatcher = string | { prefix: string; suffix: string };
|
|
1009
|
+
|
|
1010
|
+
/**
|
|
1011
|
+
* Remove text blocks from user messages that match any of the given matchers.
|
|
1012
|
+
* If stripping removes all content blocks from a message, the message itself
|
|
1013
|
+
* is dropped.
|
|
1003
1014
|
*
|
|
1004
1015
|
* This is the shared primitive behind the individual strip* functions and
|
|
1005
1016
|
* the `stripInjectionsForCompaction` pipeline.
|
|
1006
1017
|
*/
|
|
1007
1018
|
function stripUserTextBlocksByPrefix(
|
|
1008
1019
|
messages: Message[],
|
|
1009
|
-
|
|
1020
|
+
matchers: InjectionMatcher[],
|
|
1010
1021
|
): Message[] {
|
|
1011
1022
|
return messages
|
|
1012
1023
|
.map((message) => {
|
|
1013
1024
|
if (message.role !== "user") return message;
|
|
1014
1025
|
const nextContent = message.content.filter((block) => {
|
|
1015
1026
|
if (block.type !== "text") return true;
|
|
1016
|
-
return !
|
|
1027
|
+
return !matchers.some((m) =>
|
|
1028
|
+
typeof m === "string"
|
|
1029
|
+
? block.text.startsWith(m)
|
|
1030
|
+
: block.text.startsWith(m.prefix) && block.text.endsWith(m.suffix),
|
|
1031
|
+
);
|
|
1017
1032
|
});
|
|
1018
1033
|
if (nextContent.length === message.content.length) return message;
|
|
1019
1034
|
if (nextContent.length === 0) return null;
|
|
@@ -1720,8 +1735,8 @@ export function loadSlackActiveThreadFocusBlock(
|
|
|
1720
1735
|
return assembleSlackActiveThreadFocusBlock(rows, capabilities);
|
|
1721
1736
|
}
|
|
1722
1737
|
|
|
1723
|
-
/**
|
|
1724
|
-
const RUNTIME_INJECTION_PREFIXES = [
|
|
1738
|
+
/** Matchers stripped by the pipeline (order doesn't matter — single pass). */
|
|
1739
|
+
const RUNTIME_INJECTION_PREFIXES: InjectionMatcher[] = [
|
|
1725
1740
|
"<channel_capabilities>",
|
|
1726
1741
|
"<channel_command_context>",
|
|
1727
1742
|
"<disk_pressure_warning>",
|
|
@@ -1734,15 +1749,21 @@ const RUNTIME_INJECTION_PREFIXES = [
|
|
|
1734
1749
|
"<background_turn>",
|
|
1735
1750
|
"<memory_context __injected>",
|
|
1736
1751
|
"<memory_context>", // backward-compat: strip legacy blocks from pre-__injected history
|
|
1737
|
-
// The static `memory-v2-static` block (
|
|
1738
|
-
//
|
|
1739
|
-
//
|
|
1740
|
-
//
|
|
1741
|
-
//
|
|
1742
|
-
//
|
|
1743
|
-
//
|
|
1744
|
-
//
|
|
1745
|
-
|
|
1752
|
+
// The static `memory-v2-static` block (`<info>\n…</info>`) and the
|
|
1753
|
+
// dynamic activation block (`<memory>\n…</memory>`, plus legacy
|
|
1754
|
+
// `<memory __injected>…`) are both stripped so each compaction
|
|
1755
|
+
// re-injects the freshest essentials/threads/recent/buffer view and
|
|
1756
|
+
// re-runs the activation pipeline, matching the `<knowledge_base>`
|
|
1757
|
+
// cadence. The activation pipeline dedupes via `everInjected`, and
|
|
1758
|
+
// compaction handles aggregate growth, so accumulation does not cause
|
|
1759
|
+
// unbounded context growth. Both wrappers may appear in persisted rows.
|
|
1760
|
+
//
|
|
1761
|
+
// These two use the full `{ prefix, suffix }` wrapper shape (not a bare
|
|
1762
|
+
// prefix) so that user-authored text merely starting with `<memory>\n` or
|
|
1763
|
+
// `<info>\n` is never silently dropped during compaction/`/clean`. This
|
|
1764
|
+
// matches the full-wrapper requirement in `countMemoryPrefixBlocks`.
|
|
1765
|
+
{ prefix: "<memory>\n", suffix: "\n</memory>" },
|
|
1766
|
+
{ prefix: "<info>\n", suffix: "\n</info>" },
|
|
1746
1767
|
"<voice_call_control>",
|
|
1747
1768
|
"<workspace_top_level>", // backward-compat: strip legacy workspace blocks
|
|
1748
1769
|
// NOTE: <workspace> is intentionally NOT stripped — workspace context
|
|
@@ -2037,7 +2058,7 @@ export interface RuntimeInjectionOptions {
|
|
|
2037
2058
|
/**
|
|
2038
2059
|
* Pre-rendered v2 static memory content (essentials/threads/recent/buffer
|
|
2039
2060
|
* concatenated, header-wrapped). When non-null on full-mode turns the
|
|
2040
|
-
* `memory-v2-static` injector wraps it in `<
|
|
2061
|
+
* `memory-v2-static` injector wraps it in `<info>` and splices it onto
|
|
2041
2062
|
* the user message; subsequent turns leave the prior block cached on its
|
|
2042
2063
|
* original user message.
|
|
2043
2064
|
*/
|