@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
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* list APIs.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import { and, eq, inArray, isNull } from "drizzle-orm";
|
|
10
|
+
import { and, eq, inArray, isNull, sql } from "drizzle-orm";
|
|
11
11
|
|
|
12
12
|
import { getDb } from "./db-connection.js";
|
|
13
13
|
import { externalConversationBindings } from "./schema.js";
|
|
@@ -16,6 +16,7 @@ export interface ExternalConversationBinding {
|
|
|
16
16
|
conversationId: string;
|
|
17
17
|
sourceChannel: string;
|
|
18
18
|
externalChatId: string;
|
|
19
|
+
externalChatName?: string | null;
|
|
19
20
|
externalThreadId?: string | null;
|
|
20
21
|
externalUserId?: string | null;
|
|
21
22
|
displayName?: string | null;
|
|
@@ -30,6 +31,7 @@ export interface UpsertBindingInput {
|
|
|
30
31
|
conversationId: string;
|
|
31
32
|
sourceChannel: string;
|
|
32
33
|
externalChatId: string;
|
|
34
|
+
externalChatName?: string | null;
|
|
33
35
|
externalThreadId?: string | null;
|
|
34
36
|
externalUserId?: string | null;
|
|
35
37
|
displayName?: string | null;
|
|
@@ -43,6 +45,13 @@ function normalizeExternalThreadId(
|
|
|
43
45
|
return trimmed ? trimmed : null;
|
|
44
46
|
}
|
|
45
47
|
|
|
48
|
+
function normalizeExternalChatName(
|
|
49
|
+
externalChatName?: string | null,
|
|
50
|
+
): string | null {
|
|
51
|
+
const trimmed = externalChatName?.trim();
|
|
52
|
+
return trimmed ? trimmed : null;
|
|
53
|
+
}
|
|
54
|
+
|
|
46
55
|
/**
|
|
47
56
|
* Insert or update an external conversation binding on conflict (conversationId).
|
|
48
57
|
* On conflict, updates channel metadata and timestamps.
|
|
@@ -51,6 +60,7 @@ export function upsertBinding(input: UpsertBindingInput): void {
|
|
|
51
60
|
const db = getDb();
|
|
52
61
|
const now = Date.now();
|
|
53
62
|
const externalThreadId = normalizeExternalThreadId(input.externalThreadId);
|
|
63
|
+
const externalChatName = normalizeExternalChatName(input.externalChatName);
|
|
54
64
|
|
|
55
65
|
// If a stale binding exists for this channel/chat/thread tuple under a
|
|
56
66
|
// different conversationId, remove it first so the unique index is not violated.
|
|
@@ -75,6 +85,7 @@ export function upsertBinding(input: UpsertBindingInput): void {
|
|
|
75
85
|
conversationId: input.conversationId,
|
|
76
86
|
sourceChannel: input.sourceChannel,
|
|
77
87
|
externalChatId: input.externalChatId,
|
|
88
|
+
externalChatName,
|
|
78
89
|
externalThreadId,
|
|
79
90
|
externalUserId: input.externalUserId ?? null,
|
|
80
91
|
displayName: input.displayName ?? null,
|
|
@@ -88,6 +99,9 @@ export function upsertBinding(input: UpsertBindingInput): void {
|
|
|
88
99
|
set: {
|
|
89
100
|
sourceChannel: input.sourceChannel,
|
|
90
101
|
externalChatId: input.externalChatId,
|
|
102
|
+
externalChatName:
|
|
103
|
+
externalChatName ??
|
|
104
|
+
sql`${externalConversationBindings.externalChatName}`,
|
|
91
105
|
externalThreadId,
|
|
92
106
|
externalUserId: input.externalUserId ?? null,
|
|
93
107
|
displayName: input.displayName ?? null,
|
|
@@ -158,6 +172,23 @@ export function upsertOutboundBinding(input: {
|
|
|
158
172
|
.run();
|
|
159
173
|
}
|
|
160
174
|
|
|
175
|
+
export function updateExternalChatName(
|
|
176
|
+
conversationId: string,
|
|
177
|
+
externalChatName: string,
|
|
178
|
+
): void {
|
|
179
|
+
const db = getDb();
|
|
180
|
+
const trimmedName = externalChatName.trim();
|
|
181
|
+
if (!trimmedName) return;
|
|
182
|
+
|
|
183
|
+
db.update(externalConversationBindings)
|
|
184
|
+
.set({
|
|
185
|
+
externalChatName: trimmedName,
|
|
186
|
+
updatedAt: Date.now(),
|
|
187
|
+
})
|
|
188
|
+
.where(eq(externalConversationBindings.conversationId, conversationId))
|
|
189
|
+
.run();
|
|
190
|
+
}
|
|
191
|
+
|
|
161
192
|
/**
|
|
162
193
|
* Look up an external binding by conversation ID.
|
|
163
194
|
*/
|
|
@@ -20,7 +20,11 @@ import { getLogger } from "../../util/logger.js";
|
|
|
20
20
|
import { getWorkspaceDir } from "../../util/platform.js";
|
|
21
21
|
import { getMemoryCheckpoint, setMemoryCheckpoint } from "../checkpoints.js";
|
|
22
22
|
import { getDb } from "../db-connection.js";
|
|
23
|
-
import {
|
|
23
|
+
import {
|
|
24
|
+
enqueueMemoryJob,
|
|
25
|
+
hasActiveJobOfType,
|
|
26
|
+
isMemoryEnabled,
|
|
27
|
+
} from "../jobs-store.js";
|
|
24
28
|
import { initQdrantClient, resolveQdrantUrl } from "../qdrant-client.js";
|
|
25
29
|
import { rawAll, rawGet, rawRun } from "../raw-query.js";
|
|
26
30
|
import { conversations, memoryGraphNodes, memorySegments } from "../schema.js";
|
|
@@ -342,6 +346,8 @@ export function maybeEnqueueGraphBootstrap(): void {
|
|
|
342
346
|
// Don't enqueue if already in progress
|
|
343
347
|
if (hasActiveJobOfType("graph_bootstrap")) return;
|
|
344
348
|
|
|
349
|
+
if (!isMemoryEnabled()) return;
|
|
350
|
+
|
|
345
351
|
log.info(
|
|
346
352
|
{ segmentCount, hasJournalFiles },
|
|
347
353
|
"Graph empty with historical data — enqueueing bootstrap",
|
|
@@ -392,6 +398,7 @@ const KIND_TO_PREFIX: Record<string, string> = {
|
|
|
392
398
|
*/
|
|
393
399
|
export function migrateToolCreatedItems(): void {
|
|
394
400
|
if (getMemoryCheckpoint(MIGRATE_ITEMS_CHECKPOINT)) return;
|
|
401
|
+
if (!isMemoryEnabled()) return;
|
|
395
402
|
|
|
396
403
|
const kinds = Object.keys(KIND_TO_PREFIX);
|
|
397
404
|
const placeholders = kinds.map(() => "?").join(", ");
|
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
} from "../../skills/skill-memory.js";
|
|
24
24
|
import { getLogger } from "../../util/logger.js";
|
|
25
25
|
import { getDb } from "../db-connection.js";
|
|
26
|
-
import { enqueueMemoryJob } from "../jobs-store.js";
|
|
26
|
+
import { enqueueMemoryJob, isMemoryEnabled } from "../jobs-store.js";
|
|
27
27
|
import { memoryGraphNodes } from "../schema.js";
|
|
28
28
|
import { createNode } from "./store.js";
|
|
29
29
|
|
|
@@ -268,7 +268,9 @@ function upsertCapabilityNode(sourceKey: string, content: string): void {
|
|
|
268
268
|
})
|
|
269
269
|
.where(eq(memoryGraphNodes.id, existing.id))
|
|
270
270
|
.run();
|
|
271
|
-
|
|
271
|
+
if (isMemoryEnabled()) {
|
|
272
|
+
enqueueMemoryJob("embed_graph_node", { nodeId: existing.id });
|
|
273
|
+
}
|
|
272
274
|
return;
|
|
273
275
|
}
|
|
274
276
|
|
|
@@ -301,7 +303,9 @@ function upsertCapabilityNode(sourceKey: string, content: string): void {
|
|
|
301
303
|
scopeId: "default",
|
|
302
304
|
});
|
|
303
305
|
|
|
304
|
-
|
|
306
|
+
if (isMemoryEnabled()) {
|
|
307
|
+
enqueueMemoryJob("embed_graph_node", { nodeId: node.id });
|
|
308
|
+
}
|
|
305
309
|
log.info({ sourceKey, nodeId: node.id }, "Created capability graph node");
|
|
306
310
|
}
|
|
307
311
|
|
|
@@ -35,6 +35,7 @@ import {
|
|
|
35
35
|
type InjectMemoryV2Mode,
|
|
36
36
|
} from "../v2/injection.js";
|
|
37
37
|
import { loadNowText } from "../v2/now-text.js";
|
|
38
|
+
import type { RouterTurnPair } from "../v2/router.js";
|
|
38
39
|
import {
|
|
39
40
|
loadGraphMemoryState,
|
|
40
41
|
saveGraphMemoryState,
|
|
@@ -440,8 +441,11 @@ export class ConversationGraphMemory {
|
|
|
440
441
|
messages,
|
|
441
442
|
config,
|
|
442
443
|
"context-load",
|
|
444
|
+
// Context-load runs before the messages array necessarily contains
|
|
445
|
+
// the just-arrived user turn (post-compaction restore, turn 1
|
|
446
|
+
// sketch), so override with the resolved user text rather than
|
|
447
|
+
// walking back through `messages`.
|
|
443
448
|
rawUserText ?? userQuery ?? "",
|
|
444
|
-
"",
|
|
445
449
|
signal,
|
|
446
450
|
);
|
|
447
451
|
|
|
@@ -605,8 +609,7 @@ export class ConversationGraphMemory {
|
|
|
605
609
|
messages,
|
|
606
610
|
config,
|
|
607
611
|
"per-turn",
|
|
608
|
-
|
|
609
|
-
assistantLast,
|
|
612
|
+
null,
|
|
610
613
|
signal,
|
|
611
614
|
);
|
|
612
615
|
if (v2.routed) {
|
|
@@ -762,8 +765,14 @@ export class ConversationGraphMemory {
|
|
|
762
765
|
messages: Message[],
|
|
763
766
|
config: AssistantConfig,
|
|
764
767
|
mode: InjectMemoryV2Mode,
|
|
765
|
-
|
|
766
|
-
|
|
768
|
+
/**
|
|
769
|
+
* Override for the just-arrived user message text. Used by
|
|
770
|
+
* `runContextLoad` where the conversation history may not yet contain
|
|
771
|
+
* the user message that triggered the load (e.g. turn 1 / post-
|
|
772
|
+
* compaction restoration). When provided, the extracted pairs array
|
|
773
|
+
* is replaced with `[{ assistantMessage: "", userMessage: override }]`.
|
|
774
|
+
*/
|
|
775
|
+
userMessageOverride: string | null,
|
|
767
776
|
signal: AbortSignal,
|
|
768
777
|
): Promise<{
|
|
769
778
|
routed: boolean;
|
|
@@ -776,13 +785,17 @@ export class ConversationGraphMemory {
|
|
|
776
785
|
|
|
777
786
|
const nowText = await loadNowText(getWorkspaceDir());
|
|
778
787
|
const currentTurn = this.tracker.getTurn();
|
|
788
|
+
const historicalPairs = config.memory.v2.router.historical_pairs;
|
|
789
|
+
const recentTurnPairs =
|
|
790
|
+
userMessageOverride !== null
|
|
791
|
+
? [{ assistantMessage: "", userMessage: userMessageOverride }]
|
|
792
|
+
: extractRecentTurnPairs(messages, historicalPairs);
|
|
779
793
|
|
|
780
794
|
const result = await injectMemoryV2Block({
|
|
781
795
|
database: getDb(),
|
|
782
796
|
conversationId: this.conversationId,
|
|
783
797
|
currentTurn,
|
|
784
|
-
|
|
785
|
-
assistantMessage,
|
|
798
|
+
recentTurnPairs,
|
|
786
799
|
nowText,
|
|
787
800
|
messageId: `${this.conversationId}:turn:${currentTurn}`,
|
|
788
801
|
mode,
|
|
@@ -808,16 +821,22 @@ export class ConversationGraphMemory {
|
|
|
808
821
|
|
|
809
822
|
/**
|
|
810
823
|
* Count the leading content blocks on a user message that were added by
|
|
811
|
-
* `injectMemoryBlock
|
|
812
|
-
* (opening `<memory_image>` text + image +
|
|
813
|
-
* followed by a `<memory>…</memory>` text
|
|
814
|
-
*
|
|
815
|
-
*
|
|
816
|
-
*
|
|
817
|
-
*
|
|
818
|
-
*
|
|
819
|
-
*
|
|
820
|
-
*
|
|
824
|
+
* `injectMemoryBlock` or the `memory-v2-static` injector. Memory-injected
|
|
825
|
+
* images use a 3-block pattern (opening `<memory_image>` text + image +
|
|
826
|
+
* closing `</memory_image>` text), followed by a `<memory>…</memory>` text
|
|
827
|
+
* block (legacy `<memory __injected>` is also accepted). The static
|
|
828
|
+
* memory-v2 block uses `<info>…</info>` and is also counted here so that
|
|
829
|
+
* `after-memory-prefix` splices for subsequent injectors (e.g. `now-md`)
|
|
830
|
+
* land after both the dynamic and static blocks.
|
|
831
|
+
*
|
|
832
|
+
* The bare `<memory>` and `<info>` forms are matched only when the block
|
|
833
|
+
* also ends with the corresponding closing tag, so user-authored content
|
|
834
|
+
* that happens to begin with `<memory>` or `<info>` (for example, a
|
|
835
|
+
* message discussing the XML-like markup) is not mistaken for an injected
|
|
836
|
+
* prefix and stripped on re-injection. A legacy 2-block image pattern (no
|
|
837
|
+
* closing tag) is also accepted for backward compatibility. The injection
|
|
838
|
+
* prefix is always contiguous at the start, so we stop at the first
|
|
839
|
+
* non-memory block.
|
|
821
840
|
*/
|
|
822
841
|
export function countMemoryPrefixBlocks(content: ContentBlock[]): number {
|
|
823
842
|
let firstNonMemory = 0;
|
|
@@ -829,6 +848,8 @@ export function countMemoryPrefixBlocks(content: ContentBlock[]): number {
|
|
|
829
848
|
block.type === "text" &&
|
|
830
849
|
((block.text.startsWith("<memory>\n") &&
|
|
831
850
|
block.text.endsWith("\n</memory>")) ||
|
|
851
|
+
(block.text.startsWith("<info>\n") &&
|
|
852
|
+
block.text.endsWith("\n</info>")) ||
|
|
832
853
|
block.text.startsWith("<memory __injected>\n"))
|
|
833
854
|
) {
|
|
834
855
|
firstNonMemory++;
|
|
@@ -991,3 +1012,65 @@ function readRawUserText(message: Message | undefined): string | null {
|
|
|
991
1012
|
if (texts.length === 0) return null;
|
|
992
1013
|
return texts.join(" ");
|
|
993
1014
|
}
|
|
1015
|
+
|
|
1016
|
+
/**
|
|
1017
|
+
* Walk back through the conversation history and collect the most recent
|
|
1018
|
+
* `K` `(assistant, user)` turn pairs for the router prompt. Each pair
|
|
1019
|
+
* represents the assistant's reply followed by the user message that
|
|
1020
|
+
* came after — the last pair's `userMessage` is the just-arrived turn
|
|
1021
|
+
* that triggered this call.
|
|
1022
|
+
*
|
|
1023
|
+
* Behavior at K=1 is bit-identical to the pre-knob signature: one pair
|
|
1024
|
+
* with the prior assistant reply + the just-arrived user message.
|
|
1025
|
+
*
|
|
1026
|
+
* Edge cases:
|
|
1027
|
+
* - If history has fewer than K full pairs available (e.g. early in a
|
|
1028
|
+
* conversation), returns however many pairs were found, oldest first.
|
|
1029
|
+
* The oldest pair may have `assistantMessage: ""` when there is a
|
|
1030
|
+
* user message with no preceding assistant reply — `runRouterBatch`
|
|
1031
|
+
* skips the `[assistant]:` line in that case.
|
|
1032
|
+
* - Non-text content (tool_use, tool_result, images) is collapsed by
|
|
1033
|
+
* joining all text blocks within a single message with spaces. This
|
|
1034
|
+
* matches the v1-style extraction the router has used since K=1.
|
|
1035
|
+
*/
|
|
1036
|
+
function extractRecentTurnPairs(
|
|
1037
|
+
messages: Message[],
|
|
1038
|
+
k: number,
|
|
1039
|
+
): RouterTurnPair[] {
|
|
1040
|
+
const messageText = (msg: Message): string =>
|
|
1041
|
+
msg.content
|
|
1042
|
+
.filter(
|
|
1043
|
+
(b): b is Extract<typeof b, { type: "text" }> => b.type === "text",
|
|
1044
|
+
)
|
|
1045
|
+
.map((b) => b.text)
|
|
1046
|
+
.join(" ");
|
|
1047
|
+
|
|
1048
|
+
const pairs: RouterTurnPair[] = [];
|
|
1049
|
+
let pendingUser: string | null = null;
|
|
1050
|
+
for (let i = messages.length - 1; i >= 0 && pairs.length < k; i--) {
|
|
1051
|
+
const msg = messages[i];
|
|
1052
|
+
if (msg.role === "user" && pendingUser === null) {
|
|
1053
|
+
pendingUser = messageText(msg);
|
|
1054
|
+
} else if (msg.role === "assistant" && pendingUser !== null) {
|
|
1055
|
+
pairs.unshift({
|
|
1056
|
+
assistantMessage: messageText(msg),
|
|
1057
|
+
userMessage: pendingUser,
|
|
1058
|
+
});
|
|
1059
|
+
pendingUser = null;
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
// Conversation start: a user message with no preceding assistant reply
|
|
1063
|
+
// still belongs in the prompt as the just-arrived turn. Emit it with an
|
|
1064
|
+
// empty `assistantMessage` so `runRouterBatch` renders only `[user]:`.
|
|
1065
|
+
if (pendingUser !== null && pairs.length < k) {
|
|
1066
|
+
pairs.unshift({ assistantMessage: "", userMessage: pendingUser });
|
|
1067
|
+
}
|
|
1068
|
+
// Defensive fallback: the router contract requires a non-empty array.
|
|
1069
|
+
// This only fires when `messages` has no user-text content at all
|
|
1070
|
+
// (currently impossible since the agent loop always appends a user
|
|
1071
|
+
// turn before invoking the v2 path, but cheap to keep correct).
|
|
1072
|
+
if (pairs.length === 0) {
|
|
1073
|
+
pairs.push({ assistantMessage: "", userMessage: "" });
|
|
1074
|
+
}
|
|
1075
|
+
return pairs;
|
|
1076
|
+
}
|
|
@@ -12,7 +12,6 @@ import { join } from "node:path";
|
|
|
12
12
|
import { and, asc, desc, eq, gt } from "drizzle-orm";
|
|
13
13
|
|
|
14
14
|
import type { AssistantConfig } from "../../config/types.js";
|
|
15
|
-
import { resolveGuardianPersona } from "../../prompts/persona-resolver.js";
|
|
16
15
|
import { buildCoreIdentityContext } from "../../prompts/system-prompt.js";
|
|
17
16
|
import {
|
|
18
17
|
extractToolUse,
|
|
@@ -1026,10 +1025,7 @@ export async function runGraphExtraction(
|
|
|
1026
1025
|
const candidateNodeIds = new Set(candidateNodes.map((n) => n.id));
|
|
1027
1026
|
|
|
1028
1027
|
// 4. Build prompt
|
|
1029
|
-
const
|
|
1030
|
-
const identityContext = buildCoreIdentityContext({
|
|
1031
|
-
userPersona: userPersona ?? undefined,
|
|
1032
|
-
});
|
|
1028
|
+
const identityContext = buildCoreIdentityContext();
|
|
1033
1029
|
|
|
1034
1030
|
const activeSet = opts?.activeContextNodeIds
|
|
1035
1031
|
? new Set(opts.activeContextNodeIds)
|
|
@@ -9,7 +9,11 @@ import { selectedBackendSupportsMultimodal } from "../embedding-backend.js";
|
|
|
9
9
|
import type { EmbeddingInput } from "../embedding-types.js";
|
|
10
10
|
import { embedAndUpsert } from "../job-utils.js";
|
|
11
11
|
import { asString } from "../job-utils.js";
|
|
12
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
enqueueMemoryJob,
|
|
14
|
+
isMemoryEnabled,
|
|
15
|
+
type MemoryJob,
|
|
16
|
+
} from "../jobs-store.js";
|
|
13
17
|
import { isQdrantBreakerOpen } from "../qdrant-circuit-breaker.js";
|
|
14
18
|
import { withQdrantBreaker } from "../qdrant-circuit-breaker.js";
|
|
15
19
|
import {
|
|
@@ -238,6 +242,7 @@ export async function embedGraphNodeJob(
|
|
|
238
242
|
* Enqueue an embedding job for a graph node (async, for live conversations).
|
|
239
243
|
*/
|
|
240
244
|
export function enqueueGraphNodeEmbed(nodeId: string): void {
|
|
245
|
+
if (!isMemoryEnabled()) return;
|
|
241
246
|
enqueueMemoryJob("embed_graph_node", { nodeId });
|
|
242
247
|
}
|
|
243
248
|
|
|
@@ -282,5 +287,6 @@ export async function embedGraphTriggerJob(
|
|
|
282
287
|
* Enqueue a trigger embedding job.
|
|
283
288
|
*/
|
|
284
289
|
export function enqueueGraphTriggerEmbed(triggerId: string): void {
|
|
290
|
+
if (!isMemoryEnabled()) return;
|
|
285
291
|
enqueueMemoryJob("graph_trigger_embed", { triggerId });
|
|
286
292
|
}
|
package/src/memory/indexer.ts
CHANGED
|
@@ -11,7 +11,11 @@ import { isAutoAnalysisConversation } from "./auto-analysis-guard.js";
|
|
|
11
11
|
import { getMemoryCheckpoint, setMemoryCheckpoint } from "./checkpoints.js";
|
|
12
12
|
import { getDb } from "./db-connection.js";
|
|
13
13
|
import { selectedBackendSupportsMultimodal } from "./embedding-backend.js";
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
enqueueMemoryJob,
|
|
16
|
+
isMemoryEnabled,
|
|
17
|
+
upsertDebouncedJob,
|
|
18
|
+
} from "./jobs-store.js";
|
|
15
19
|
import { isMemoryRetrospectiveConversation } from "./memory-retrospective-enqueue.js";
|
|
16
20
|
import { maybeEnqueueRetrospective } from "./memory-retrospective-trigger-check.js";
|
|
17
21
|
import {
|
|
@@ -139,20 +143,22 @@ export async function indexMessageNow(
|
|
|
139
143
|
|
|
140
144
|
if (existing?.contentHash === hash) {
|
|
141
145
|
skippedEmbedJobs++;
|
|
142
|
-
} else {
|
|
146
|
+
} else if (isMemoryEnabled()) {
|
|
143
147
|
enqueueMemoryJob("embed_segment", { segmentId }, Date.now(), tx);
|
|
144
148
|
}
|
|
145
149
|
}
|
|
146
150
|
|
|
147
151
|
// Enqueue embed_attachment jobs for image content blocks when the
|
|
148
152
|
// embedding provider supports multimodal (Gemini only).
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
153
|
+
if (isMemoryEnabled()) {
|
|
154
|
+
for (const block of mediaBlocks) {
|
|
155
|
+
enqueueMemoryJob(
|
|
156
|
+
"embed_attachment",
|
|
157
|
+
{ messageId: input.messageId, blockIndex: block.index },
|
|
158
|
+
Date.now(),
|
|
159
|
+
tx,
|
|
160
|
+
);
|
|
161
|
+
}
|
|
156
162
|
}
|
|
157
163
|
});
|
|
158
164
|
|
|
@@ -221,14 +227,16 @@ export async function indexMessageNow(
|
|
|
221
227
|
extractRunAfter = graphBatchFired
|
|
222
228
|
? Date.now()
|
|
223
229
|
: Date.now() + idleTimeoutMs;
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
230
|
+
if (isMemoryEnabled()) {
|
|
231
|
+
upsertDebouncedJob(
|
|
232
|
+
"graph_extract",
|
|
233
|
+
{
|
|
234
|
+
conversationId: input.conversationId,
|
|
235
|
+
scopeId: input.scopeId ?? "default",
|
|
236
|
+
},
|
|
237
|
+
extractRunAfter,
|
|
238
|
+
);
|
|
239
|
+
}
|
|
232
240
|
} else {
|
|
233
241
|
extractRunAfter = Date.now() + idleTimeoutMs;
|
|
234
242
|
}
|
|
@@ -309,7 +317,7 @@ export async function indexMessageNow(
|
|
|
309
317
|
// jobs-worker.ts. Debounced on the same idle timeout — no threshold
|
|
310
318
|
// trigger needed since summaries compress the whole conversation, not
|
|
311
319
|
// incremental batches.
|
|
312
|
-
if (v2Config == null) {
|
|
320
|
+
if (v2Config == null && isMemoryEnabled()) {
|
|
313
321
|
upsertDebouncedJob(
|
|
314
322
|
"build_conversation_summary",
|
|
315
323
|
{ conversationId: input.conversationId },
|
|
@@ -372,10 +380,12 @@ export async function indexMessageNow(
|
|
|
372
380
|
}
|
|
373
381
|
|
|
374
382
|
export function enqueueBackfillJob(force = false): string {
|
|
383
|
+
if (!isMemoryEnabled()) return "";
|
|
375
384
|
return enqueueMemoryJob("backfill", { force });
|
|
376
385
|
}
|
|
377
386
|
|
|
378
387
|
export function enqueueRebuildIndexJob(): string {
|
|
388
|
+
if (!isMemoryEnabled()) return "";
|
|
379
389
|
return enqueueMemoryJob("rebuild_index", {});
|
|
380
390
|
}
|
|
381
391
|
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { AssistantConfig } from "../../config/types.js";
|
|
2
2
|
import { getLogger } from "../../util/logger.js";
|
|
3
|
+
import { runAsyncSqlite } from "../db-async-query.js";
|
|
3
4
|
import { getDb } from "../db-connection.js";
|
|
4
5
|
import { enqueueMemoryJob, type MemoryJob } from "../jobs-store.js";
|
|
5
|
-
import { rawAll,
|
|
6
|
+
import { rawAll, rawRun } from "../raw-query.js";
|
|
6
7
|
|
|
7
8
|
const log = getLogger("memory-jobs-worker");
|
|
8
9
|
|
|
@@ -13,11 +14,18 @@ const PRUNE_LOG_BATCH_LIMIT = 1000;
|
|
|
13
14
|
* Delete LLM request/response logs older than the configured retention period.
|
|
14
15
|
* Processes in batches to avoid long DB locks and excessive WAL growth.
|
|
15
16
|
* Re-enqueues itself if more rows remain.
|
|
17
|
+
*
|
|
18
|
+
* The DELETE is dispatched through `runAsyncSqlite` so it runs in a
|
|
19
|
+
* sqlite3 subprocess (when available) and does not block the daemon's
|
|
20
|
+
* main event loop. The two bind parameters (`cutoffMs`, batch limit)
|
|
21
|
+
* are integers — they're inlined directly into the SQL after a
|
|
22
|
+
* `Math.floor` + `Number.isFinite` guard so there is no string
|
|
23
|
+
* interpolation surface.
|
|
16
24
|
*/
|
|
17
|
-
export function pruneOldLlmRequestLogsJob(
|
|
25
|
+
export async function pruneOldLlmRequestLogsJob(
|
|
18
26
|
job: MemoryJob,
|
|
19
27
|
config: AssistantConfig,
|
|
20
|
-
): void {
|
|
28
|
+
): Promise<void> {
|
|
21
29
|
const rawRetention = job.payload.retentionMs;
|
|
22
30
|
const retentionMs =
|
|
23
31
|
rawRetention === null
|
|
@@ -31,14 +39,29 @@ export function pruneOldLlmRequestLogsJob(
|
|
|
31
39
|
// null means "keep forever" — skip pruning entirely
|
|
32
40
|
if (retentionMs === null || retentionMs === undefined) return;
|
|
33
41
|
|
|
34
|
-
const cutoffMs = Date.now() - retentionMs;
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
42
|
+
const cutoffMs = Math.floor(Date.now() - retentionMs);
|
|
43
|
+
if (!Number.isFinite(cutoffMs)) return;
|
|
44
|
+
|
|
45
|
+
// Inline the cutoff and batch limit (both integers, both validated)
|
|
46
|
+
// and chain `SELECT changes()` so we can read the row count from the
|
|
47
|
+
// subprocess's stdout. The sqlite3 CLI prints `changes()` as a bare
|
|
48
|
+
// integer on its own line in default output mode; the in-process
|
|
49
|
+
// fallback backend in `db-async-query.ts` synthesizes the same shape
|
|
50
|
+
// by capturing `changes()` atomically after `exec()`. Both backends
|
|
51
|
+
// end up on the parser path below.
|
|
52
|
+
const result = await runAsyncSqlite(
|
|
53
|
+
`DELETE FROM llm_request_logs WHERE rowid IN (SELECT rowid FROM llm_request_logs WHERE created_at < ${cutoffMs} LIMIT ${PRUNE_LOG_BATCH_LIMIT});
|
|
54
|
+
SELECT changes();`,
|
|
40
55
|
);
|
|
41
|
-
|
|
56
|
+
if (!result.ok) {
|
|
57
|
+
log.warn(
|
|
58
|
+
{ error: result.error, backend: result.backend },
|
|
59
|
+
"pruneOldLlmRequestLogsJob: DELETE failed",
|
|
60
|
+
);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const deleted = parseDeletedCount(result.stdout);
|
|
42
65
|
|
|
43
66
|
if (deleted >= PRUNE_LOG_BATCH_LIMIT) {
|
|
44
67
|
enqueueMemoryJob("prune_old_llm_request_logs", { retentionMs });
|
|
@@ -58,11 +81,14 @@ export function pruneOldLlmRequestLogsJob(
|
|
|
58
81
|
* Delete trace events older than the configured retention period.
|
|
59
82
|
* Processes in batches to avoid long DB locks and excessive WAL growth.
|
|
60
83
|
* Re-enqueues itself if more rows remain.
|
|
84
|
+
*
|
|
85
|
+
* Same async dispatch + integer inlining shape as
|
|
86
|
+
* {@link pruneOldLlmRequestLogsJob}.
|
|
61
87
|
*/
|
|
62
|
-
export function pruneOldTraceEventsJob(
|
|
88
|
+
export async function pruneOldTraceEventsJob(
|
|
63
89
|
job: MemoryJob,
|
|
64
90
|
config: AssistantConfig,
|
|
65
|
-
): void {
|
|
91
|
+
): Promise<void> {
|
|
66
92
|
const rawRetention = job.payload.retentionDays;
|
|
67
93
|
const retentionDays =
|
|
68
94
|
typeof rawRetention === "number" &&
|
|
@@ -74,14 +100,22 @@ export function pruneOldTraceEventsJob(
|
|
|
74
100
|
// 0 means disabled
|
|
75
101
|
if (retentionDays === 0) return;
|
|
76
102
|
|
|
77
|
-
const cutoffMs = Date.now() - retentionDays * 86_400_000;
|
|
103
|
+
const cutoffMs = Math.floor(Date.now() - retentionDays * 86_400_000);
|
|
104
|
+
if (!Number.isFinite(cutoffMs)) return;
|
|
78
105
|
|
|
79
|
-
|
|
80
|
-
`DELETE FROM trace_events WHERE rowid IN (SELECT rowid FROM trace_events WHERE created_at <
|
|
81
|
-
|
|
82
|
-
PRUNE_LOG_BATCH_LIMIT,
|
|
106
|
+
const result = await runAsyncSqlite(
|
|
107
|
+
`DELETE FROM trace_events WHERE rowid IN (SELECT rowid FROM trace_events WHERE created_at < ${cutoffMs} LIMIT ${PRUNE_LOG_BATCH_LIMIT});
|
|
108
|
+
SELECT changes();`,
|
|
83
109
|
);
|
|
84
|
-
|
|
110
|
+
if (!result.ok) {
|
|
111
|
+
log.warn(
|
|
112
|
+
{ error: result.error, backend: result.backend },
|
|
113
|
+
"pruneOldTraceEventsJob: DELETE failed",
|
|
114
|
+
);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const deleted = parseDeletedCount(result.stdout);
|
|
85
119
|
|
|
86
120
|
if (deleted >= PRUNE_LOG_BATCH_LIMIT) {
|
|
87
121
|
enqueueMemoryJob("prune_old_trace_events", { retentionDays });
|
|
@@ -97,6 +131,30 @@ export function pruneOldTraceEventsJob(
|
|
|
97
131
|
);
|
|
98
132
|
}
|
|
99
133
|
|
|
134
|
+
/**
|
|
135
|
+
* Parse the `SELECT changes()` result emitted by the sqlite3 CLI after
|
|
136
|
+
* the prune DELETE. Returns 0 if stdout is missing or unparseable —
|
|
137
|
+
* callers treat that the same as "no rows deleted, do not re-enqueue".
|
|
138
|
+
*
|
|
139
|
+
* In the CLI's default output mode the value is a bare integer on its
|
|
140
|
+
* own line. We tolerate trailing whitespace/blank lines and pick the
|
|
141
|
+
* last numeric line so any incidental output (warnings, etc.) above it
|
|
142
|
+
* doesn't throw the parse off.
|
|
143
|
+
*/
|
|
144
|
+
export function _parseDeletedCount(stdout: string | undefined): number {
|
|
145
|
+
return parseDeletedCount(stdout);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function parseDeletedCount(stdout: string | undefined): number {
|
|
149
|
+
if (!stdout) return 0;
|
|
150
|
+
const lines = stdout.split(/\r?\n/).filter((s) => s.trim().length > 0);
|
|
151
|
+
for (let i = lines.length - 1; i >= 0; i--) {
|
|
152
|
+
const n = parseInt(lines[i].trim(), 10);
|
|
153
|
+
if (Number.isFinite(n) && n >= 0) return n;
|
|
154
|
+
}
|
|
155
|
+
return 0;
|
|
156
|
+
}
|
|
157
|
+
|
|
100
158
|
/**
|
|
101
159
|
* Delete conversations that have had no activity (updatedAt) for longer than
|
|
102
160
|
* the configured retention period. Processes in batches so a single job doesn't
|
|
@@ -9,7 +9,6 @@ import { and, desc, eq, sql } from "drizzle-orm";
|
|
|
9
9
|
import { v4 as uuid } from "uuid";
|
|
10
10
|
|
|
11
11
|
import { loadSkillCatalog } from "../../config/skills.js";
|
|
12
|
-
import { resolveGuardianPersona } from "../../prompts/persona-resolver.js";
|
|
13
12
|
import { buildCoreIdentityContext } from "../../prompts/system-prompt.js";
|
|
14
13
|
import {
|
|
15
14
|
createTimeout,
|
|
@@ -200,9 +199,7 @@ async function generateStarters(scopeId: string): Promise<GeneratedStarter[]> {
|
|
|
200
199
|
|
|
201
200
|
// Truncate identity context to prevent oversized prompts when SOUL.md /
|
|
202
201
|
// IDENTITY.md / users/<slug>.md are large.
|
|
203
|
-
const rawIdentityContext = buildCoreIdentityContext(
|
|
204
|
-
userPersona: resolveGuardianPersona(),
|
|
205
|
-
});
|
|
202
|
+
const rawIdentityContext = buildCoreIdentityContext();
|
|
206
203
|
const identityContext = rawIdentityContext
|
|
207
204
|
? truncate(rawIdentityContext, 2000, "\n…[truncated]")
|
|
208
205
|
: null;
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import type { AssistantConfig } from "../../config/types.js";
|
|
2
2
|
import { asString } from "../job-utils.js";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
enqueueMemoryJob,
|
|
5
|
+
isMemoryEnabled,
|
|
6
|
+
type MemoryJob,
|
|
7
|
+
} from "../jobs-store.js";
|
|
4
8
|
import { indexPkbFile } from "../pkb/pkb-index.js";
|
|
5
9
|
|
|
6
10
|
/**
|
|
@@ -46,6 +50,7 @@ export async function embedPkbFileJob(
|
|
|
46
50
|
* Enqueue an `embed_pkb_file` job (async, fire-and-forget).
|
|
47
51
|
*/
|
|
48
52
|
export function enqueuePkbIndexJob(input: EmbedPkbFileJobInput): string {
|
|
53
|
+
if (!isMemoryEnabled()) return "";
|
|
49
54
|
return enqueueMemoryJob("embed_pkb_file", {
|
|
50
55
|
pkbRoot: input.pkbRoot,
|
|
51
56
|
absPath: input.absPath,
|