@vellumai/assistant 0.6.4 → 0.6.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/.prettierignore +5 -0
- package/ARCHITECTURE.md +32 -36
- package/Dockerfile +12 -0
- package/README.md +3 -4
- package/bun.lock +8 -3
- package/docs/architecture/integrations.md +1 -20
- package/docs/architecture/security.md +16 -16
- package/docs/error-handling.md +111 -0
- package/docs/skills.md +10 -10
- package/docs/stt-provider-onboarding.md +2 -1
- package/knip.json +9 -2
- package/node_modules/@vellumai/ces-contracts/package.json +2 -1
- package/node_modules/@vellumai/ces-contracts/src/__tests__/trust-rules.test.ts +471 -0
- package/node_modules/@vellumai/ces-contracts/src/trust-rules.ts +398 -4
- package/node_modules/@vellumai/credential-storage/bun.lock +2 -2
- package/node_modules/@vellumai/credential-storage/package.json +2 -2
- package/node_modules/@vellumai/credential-storage/src/oauth-runtime.ts +20 -2
- package/node_modules/@vellumai/egress-proxy/bun.lock +2 -2
- package/node_modules/@vellumai/egress-proxy/package.json +2 -2
- package/openapi.yaml +123 -11
- package/package.json +6 -3
- package/scripts/generate-openapi.ts +50 -11
- package/src/__tests__/agent-loop-callsite-precedence.test.ts +318 -0
- package/src/__tests__/agent-loop-sentry-hygiene.test.ts +137 -0
- package/src/__tests__/agent-loop.test.ts +112 -1
- package/src/__tests__/anthropic-error-formatting.test.ts +98 -0
- package/src/__tests__/anthropic-provider.test.ts +171 -2
- package/src/__tests__/approval-cascade.test.ts +31 -10
- package/src/__tests__/approval-routes-http.test.ts +134 -10
- package/src/__tests__/assistant-attachments.test.ts +44 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +29 -0
- package/src/__tests__/browser-fill-credential.test.ts +1 -1
- package/src/__tests__/browser-identifier-parity-guard.test.ts +53 -0
- package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +23 -33
- package/src/__tests__/browser-skill-endstate.test.ts +51 -182
- package/src/__tests__/btw-routes.test.ts +47 -1
- package/src/__tests__/call-controller.test.ts +1 -2
- package/src/__tests__/call-site-routing-provider.test.ts +214 -0
- package/src/__tests__/catalog-cache.test.ts +27 -4
- package/src/__tests__/channel-approval-routes.test.ts +4 -4
- package/src/__tests__/channel-reply-delivery.test.ts +300 -2
- package/src/__tests__/checker.test.ts +428 -501
- package/src/__tests__/cli-command-risk-guard.test.ts +30 -33
- package/src/__tests__/compaction-circuit-breaker.test.ts +336 -0
- package/src/__tests__/compaction.benchmark.test.ts +1 -1
- package/src/__tests__/config-analysis.test.ts +11 -28
- package/src/__tests__/config-loader-backfill.test.ts +174 -0
- package/src/__tests__/config-loader-corrupt.test.ts +183 -0
- package/src/__tests__/config-loader-quarantine-bulletin.test.ts +202 -0
- package/src/__tests__/config-schema-cmd.test.ts +11 -5
- package/src/__tests__/config-schema.test.ts +427 -114
- package/src/__tests__/config-watcher.test.ts +2 -2
- package/src/__tests__/contact-store-user-file.test.ts +72 -73
- package/src/__tests__/contacts-write.test.ts +4 -4
- package/src/__tests__/context-token-estimator.test.ts +191 -1
- package/src/__tests__/context-window-manager.test.ts +530 -2
- package/src/__tests__/conversation-abort-tool-results.test.ts +30 -16
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +61 -17
- package/src/__tests__/conversation-agent-loop.test.ts +412 -82
- package/src/__tests__/conversation-attachments.test.ts +1 -1
- package/src/__tests__/conversation-confirmation-signals.test.ts +30 -9
- package/src/__tests__/conversation-error.test.ts +37 -6
- package/src/__tests__/conversation-history-web-search.test.ts +6 -0
- package/src/__tests__/conversation-init.benchmark.test.ts +36 -0
- package/src/__tests__/conversation-lifecycle.test.ts +336 -0
- package/src/__tests__/conversation-load-history-repair.test.ts +27 -10
- package/src/__tests__/conversation-pre-run-repair.test.ts +30 -16
- package/src/__tests__/conversation-process-callsite.test.ts +306 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +30 -16
- package/src/__tests__/conversation-queue.test.ts +41 -26
- package/src/__tests__/conversation-routes-disk-view.test.ts +29 -1
- package/src/__tests__/conversation-routes-slash-commands.test.ts +31 -3
- package/src/__tests__/conversation-runtime-assembly.test.ts +2735 -55
- package/src/__tests__/conversation-runtime-workspace.test.ts +12 -12
- package/src/__tests__/conversation-skill-tools.test.ts +12 -146
- package/src/__tests__/conversation-slash-queue.test.ts +34 -19
- package/src/__tests__/conversation-slash-unknown.test.ts +30 -16
- package/src/__tests__/conversation-speed-override.test.ts +30 -11
- package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +1035 -0
- package/src/__tests__/conversation-surfaces-standalone.test.ts +630 -0
- package/src/__tests__/conversation-title-service.test.ts +2 -2
- package/src/__tests__/conversation-tool-setup-batch-authorized.test.ts +1 -1
- package/src/__tests__/conversation-unread-route.test.ts +2 -2
- package/src/__tests__/conversation-usage.test.ts +3 -1
- package/src/__tests__/conversation-workspace-cache-state.test.ts +31 -10
- package/src/__tests__/conversation-workspace-injection.test.ts +43 -15
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +44 -16
- package/src/__tests__/credential-broker-browser-fill.test.ts +110 -0
- package/src/__tests__/credential-security-invariants.test.ts +3 -0
- package/src/__tests__/credential-storage-oauth-compat.test.ts +18 -0
- package/src/__tests__/credential-storage-static-compat.test.ts +28 -0
- package/src/__tests__/credential-vault-unit.test.ts +135 -19
- package/src/__tests__/credentials-cli.test.ts +1 -9
- package/src/__tests__/cross-provider-web-search.test.ts +84 -0
- package/src/__tests__/daemon-server-persist-and-process-callsite.test.ts +92 -0
- package/src/__tests__/delete-propagation.test.ts +437 -0
- package/src/__tests__/dm-backfill.test.ts +417 -0
- package/src/__tests__/dm-persistence.test.ts +227 -0
- package/src/__tests__/edit-propagation.test.ts +280 -0
- package/src/__tests__/ephemeral-permissions.test.ts +93 -3
- package/src/__tests__/estimator-calibration-integration.test.ts +208 -0
- package/src/__tests__/estimator-calibration.test.ts +213 -0
- package/src/__tests__/extension-id-sync-guard.test.ts +26 -7
- package/src/__tests__/file-write-tool.test.ts +151 -1
- package/src/__tests__/filing-service.test.ts +255 -0
- package/src/__tests__/gemini-provider.test.ts +0 -3
- package/src/__tests__/guardian-grant-minting.test.ts +8 -0
- package/src/__tests__/headless-browser-interactions.test.ts +1 -1
- package/src/__tests__/heartbeat-service.test.ts +96 -15
- package/src/__tests__/host-shell-tool.test.ts +124 -18
- package/src/__tests__/http-user-message-parity.test.ts +29 -1
- package/src/__tests__/inbound-slack-persistence.test.ts +340 -0
- package/src/__tests__/intent-routing.test.ts +1 -40
- package/src/__tests__/llm-catalog-parity.test.ts +174 -0
- package/src/__tests__/llm-context-normalization.test.ts +121 -0
- package/src/__tests__/llm-resolver.test.ts +214 -0
- package/src/__tests__/llm-schema.test.ts +223 -0
- package/src/__tests__/managed-proxy-context.test.ts +6 -2
- package/src/__tests__/messaging-skill-split.test.ts +3 -34
- package/src/__tests__/migration-import-from-url.test.ts +684 -0
- package/src/__tests__/model-intents.test.ts +9 -83
- package/src/__tests__/notification-decision-fallback.test.ts +0 -10
- package/src/__tests__/notification-decision-identity.test.ts +0 -9
- package/src/__tests__/notification-decision-recipient-context.test.ts +0 -9
- package/src/__tests__/oauth-store.test.ts +10 -7
- package/src/__tests__/oauth2-gateway-transport.test.ts +8 -3
- package/src/__tests__/oauth2-refresh-retry.test.ts +279 -0
- package/src/__tests__/openai-provider.test.ts +7 -0
- package/src/__tests__/openai-responses-provider.test.ts +396 -0
- package/src/__tests__/openrouter-provider-only.test.ts +135 -0
- package/src/__tests__/outbound-slack-persistence.test.ts +293 -0
- package/src/__tests__/permission-checker-host-gate.test.ts +1 -1
- package/src/__tests__/permission-mode.test.ts +16 -0
- package/src/__tests__/permission-types.test.ts +0 -1
- package/src/__tests__/persona-resolver.test.ts +13 -13
- package/src/__tests__/pkb-autoinject.test.ts +37 -1
- package/src/__tests__/platform-bash-auto-approve.test.ts +1 -1
- package/src/__tests__/pricing.test.ts +50 -3
- package/src/__tests__/profiler-routes.test.ts +1 -1
- package/src/__tests__/provider-commit-message-generator.test.ts +14 -84
- package/src/__tests__/provider-env-vars-scope.test.ts +52 -0
- package/src/__tests__/provider-error-scenarios.test.ts +135 -6
- package/src/__tests__/provider-managed-proxy-integration.test.ts +42 -11
- package/src/__tests__/provider-registry-ollama.test.ts +1 -2
- package/src/__tests__/proxy-approval-callback.test.ts +0 -1
- package/src/__tests__/reaction-persistence.test.ts +560 -0
- package/src/__tests__/relay-server.test.ts +1 -1
- package/src/__tests__/require-fresh-approval.test.ts +1 -1
- package/src/__tests__/retry-openrouter-only-normalization.test.ts +136 -0
- package/src/__tests__/retry-thinking-tool-choice.test.ts +226 -0
- package/src/__tests__/risk-classifier-parity.test.ts +230 -0
- package/src/__tests__/sanitize-config-for-transfer.test.ts +78 -1
- package/src/__tests__/secret-ingress-http.test.ts +28 -0
- package/src/__tests__/secret-prompter-channel-fallback.test.ts +125 -0
- package/src/__tests__/secret-routes-managed-proxy.test.ts +2 -3
- package/src/__tests__/secret-scanner-executor.test.ts +1 -1
- package/src/__tests__/send-endpoint-busy.test.ts +29 -1
- package/src/__tests__/server-history-render.test.ts +31 -0
- package/src/__tests__/shell-parser-property.test.ts +13 -13
- package/src/__tests__/skill-cache-store.test.ts +182 -0
- package/src/__tests__/skills.test.ts +19 -33
- package/src/__tests__/slack-app-setup-skill-regression.test.ts +3 -1
- package/src/__tests__/slack-skill.test.ts +3 -8
- package/src/__tests__/starter-bundle.test.ts +35 -0
- package/src/__tests__/subagent-call-site-routing.test.ts +280 -0
- package/src/__tests__/suggestion-routes.test.ts +160 -3
- package/src/__tests__/system-prompt.test.ts +22 -35
- package/src/__tests__/task-runner.test.ts +3 -1
- package/src/__tests__/tcc-sandbox-deny.test.ts +198 -0
- package/src/__tests__/terminal-tools.test.ts +8 -0
- package/src/__tests__/test-support/browser-skill-harness.ts +2 -52
- package/src/__tests__/thread-backfill.test.ts +941 -0
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +2 -2
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +2 -2
- package/src/__tests__/tool-executor.test.ts +60 -94
- package/src/__tests__/trust-store.test.ts +442 -109
- package/src/__tests__/update-bulletin-job.test.ts +389 -0
- package/src/__tests__/usage-cache-backfill-migration.test.ts +3 -1
- package/src/__tests__/verification-control-plane-policy.test.ts +1 -22
- package/src/__tests__/voice-session-bridge.test.ts +39 -0
- package/src/__tests__/volume-security-guard.test.ts +3 -2
- package/src/__tests__/web-search-history.test.ts +337 -0
- package/src/__tests__/workspace-migration-039-drop-legacy-llm-keys.test.ts +343 -0
- package/src/__tests__/workspace-migration-043-release-notes-latex-rendering.test.ts +202 -0
- package/src/__tests__/workspace-migration-045-release-notes-meet-avatar.test.ts +210 -0
- package/src/__tests__/workspace-migration-drop-user-md.test.ts +11 -11
- package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +841 -0
- package/src/__tests__/workspace-policy.test.ts +1 -13
- package/src/acp/client-handler.ts +1 -2
- package/src/agent/loop.ts +209 -17
- package/src/avatar/resvg-lazy.test.ts +136 -0
- package/src/avatar/resvg-lazy.ts +82 -9
- package/src/avatar/traits-png-sync.ts +21 -1
- package/src/browser/__tests__/operations.test.ts +163 -0
- package/src/browser/identifiers.ts +51 -0
- package/src/browser/operations.ts +660 -0
- package/src/browser/types.ts +81 -0
- package/src/calls/guardian-question-copy.ts +2 -2
- package/src/calls/telephony-stt-routing.ts +1 -1
- package/src/calls/voice-session-bridge.ts +1 -0
- package/src/cli/AGENTS.md +1 -1
- package/src/cli/commands/__tests__/attachment.test.ts +438 -0
- package/src/cli/commands/__tests__/browser.test.ts +554 -0
- package/src/cli/commands/__tests__/cache.test.ts +623 -0
- package/src/cli/commands/__tests__/email-list.test.ts +6 -0
- package/src/cli/commands/__tests__/email-send.test.ts +93 -1
- package/src/cli/commands/__tests__/image-generation.test.ts +666 -0
- package/src/cli/commands/__tests__/inference-send.test.ts +451 -0
- package/src/cli/commands/__tests__/stt-transcribe.test.ts +454 -0
- package/src/cli/commands/__tests__/task.test.ts +913 -0
- package/src/cli/commands/__tests__/tts-synthesize.test.ts +594 -0
- package/src/cli/commands/__tests__/ui-confirm.test.ts +650 -0
- package/src/cli/commands/__tests__/ui.test.ts +1215 -0
- package/src/cli/commands/__tests__/watchers.test.ts +716 -0
- package/src/cli/commands/attachment.ts +182 -0
- package/src/cli/commands/browser.ts +350 -0
- package/src/cli/commands/cache.ts +341 -0
- package/src/cli/commands/completions.ts +0 -3
- package/src/cli/commands/config.ts +6 -6
- package/src/cli/commands/conversations-import.ts +347 -0
- package/src/cli/commands/conversations.ts +14 -1
- package/src/cli/commands/email.ts +234 -194
- package/src/cli/commands/image-generation.ts +300 -0
- package/src/cli/commands/inference.ts +200 -0
- package/src/cli/commands/memory.ts +127 -17
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +0 -1
- package/src/cli/commands/platform/__tests__/connect.test.ts +0 -1
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +0 -1
- package/src/cli/commands/platform/__tests__/status.test.ts +0 -1
- package/src/cli/commands/stt.ts +339 -0
- package/src/cli/commands/task.ts +795 -0
- package/src/cli/commands/trust.ts +50 -19
- package/src/cli/commands/tts.ts +273 -0
- package/src/cli/commands/ui.ts +670 -0
- package/src/cli/commands/watchers.ts +509 -0
- package/src/cli/lib/daemon-credential-client.ts +0 -19
- package/src/cli/program.ts +23 -4
- package/src/cli.ts +0 -37
- package/src/config/bundled-skills/conversations/tools/rename-conversation.ts +23 -1
- package/src/config/bundled-skills/media-processing/services/reduce.ts +1 -1
- package/src/config/bundled-skills/messaging/SKILL.md +2 -2
- package/src/config/bundled-skills/messaging/TOOLS.json +4 -0
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +8 -1
- package/src/config/bundled-skills/messaging/tools/messaging-read.ts +15 -1
- package/src/config/bundled-skills/messaging/tools/messaging-search.ts +21 -1
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +11 -12
- package/src/config/bundled-skills/phone-calls/references/CONFIG.md +9 -8
- package/src/config/bundled-skills/settings/TOOLS.json +3 -3
- package/src/config/bundled-tool-registry.ts +0 -175
- package/src/config/env.ts +7 -2
- package/src/config/feature-flag-registry.json +25 -9
- package/src/config/llm-resolver.ts +128 -0
- package/src/config/loader.ts +194 -10
- package/src/config/raw-config-utils.ts +30 -2
- package/src/config/sanitize-for-transfer.ts +35 -0
- package/src/config/schema.ts +30 -41
- package/src/config/schemas/analysis.ts +3 -22
- package/src/config/schemas/calls.ts +0 -4
- package/src/config/schemas/filing.ts +2 -7
- package/src/config/schemas/heartbeat.ts +0 -5
- package/src/config/schemas/inference.ts +3 -23
- package/src/config/schemas/llm.ts +318 -0
- package/src/config/schemas/memory-processing.ts +1 -9
- package/src/config/schemas/notifications.ts +4 -11
- package/src/config/schemas/platform.ts +3 -9
- package/src/config/schemas/security.ts +33 -0
- package/src/config/schemas/services.ts +9 -4
- package/src/config/schemas/stt.ts +1 -0
- package/src/config/schemas/tts.ts +53 -0
- package/src/config/schemas/updates.ts +1 -1
- package/src/config/schemas/workspace-git.ts +3 -40
- package/src/config/skills.ts +2 -2
- package/src/context/__tests__/compact-prompt.test.ts +45 -0
- package/src/context/__tests__/microcompact.test.ts +805 -0
- package/src/context/estimator-calibration.ts +136 -0
- package/src/context/microcompact.ts +443 -0
- package/src/context/prompts/compact.md +12 -0
- package/src/context/token-estimator.ts +61 -3
- package/src/context/window-manager.ts +229 -25
- package/src/credential-execution/approval-bridge.ts +0 -1
- package/src/credential-execution/executable-discovery.ts +19 -8
- package/src/credential-execution/process-manager.test.ts +109 -0
- package/src/credential-execution/process-manager.ts +65 -2
- package/src/daemon/approval-generators.ts +29 -4
- package/src/daemon/assistant-attachments.ts +24 -13
- package/src/daemon/classifier.ts +2 -2
- package/src/daemon/config-watcher.ts +0 -1
- package/src/daemon/context-overflow-reducer.ts +4 -1
- package/src/daemon/conversation-agent-loop-handlers.ts +79 -12
- package/src/daemon/conversation-agent-loop.ts +462 -80
- package/src/daemon/conversation-attachments.ts +2 -6
- package/src/daemon/conversation-error.ts +36 -1
- package/src/daemon/conversation-lifecycle.ts +30 -6
- package/src/daemon/conversation-messaging.ts +73 -4
- package/src/daemon/conversation-process.ts +10 -4
- package/src/daemon/conversation-queue-manager.ts +3 -0
- package/src/daemon/conversation-runtime-assembly.ts +760 -29
- package/src/daemon/conversation-slash.ts +2 -2
- package/src/daemon/conversation-surfaces.ts +389 -1
- package/src/daemon/conversation-tool-setup.ts +10 -5
- package/src/daemon/conversation-usage.ts +1 -1
- package/src/daemon/conversation.ts +118 -30
- package/src/daemon/external-skills-bootstrap.ts +41 -0
- package/src/daemon/guardian-action-generators.ts +34 -14
- package/src/daemon/handlers/config-model.test.ts +86 -0
- package/src/daemon/handlers/config-model.ts +54 -12
- package/src/daemon/handlers/conversations.ts +9 -2
- package/src/daemon/handlers/shared.ts +39 -11
- package/src/daemon/handlers/skills.ts +2 -2
- package/src/daemon/handlers/slack-channel-oauth-install.ts +197 -0
- package/src/daemon/lifecycle.ts +76 -14
- package/src/daemon/message-types/conversations.ts +14 -0
- package/src/daemon/message-types/messages.ts +9 -1
- package/src/daemon/message-types/trust.ts +0 -2
- package/src/daemon/parse-actual-tokens-from-error.test.ts +57 -1
- package/src/daemon/parse-actual-tokens-from-error.ts +66 -0
- package/src/daemon/pkb-context-tracker.test.ts +169 -0
- package/src/daemon/pkb-context-tracker.ts +125 -0
- package/src/daemon/pkb-reminder-builder.test.ts +70 -0
- package/src/daemon/pkb-reminder-builder.ts +31 -0
- package/src/daemon/providers-setup.ts +6 -0
- package/src/daemon/server.ts +117 -9
- package/src/daemon/tool-side-effects.ts +0 -9
- package/src/daemon/watch-handler.ts +4 -4
- package/src/daemon/web-search-history.ts +126 -0
- package/src/events/domain-events.ts +0 -1
- package/src/filing/filing-service.ts +9 -10
- package/src/heartbeat/heartbeat-service.ts +76 -28
- package/src/home/__tests__/feed-scheduler.test.ts +39 -11
- package/src/home/__tests__/rollup-producer.test.ts +44 -0
- package/src/home/assistant-feed-authoring.ts +4 -0
- package/src/home/emit-feed-event.ts +4 -0
- package/src/home/feed-scheduler.ts +20 -4
- package/src/home/feed-types.ts +56 -2
- package/src/home/relationship-state-writer.ts +2 -2
- package/src/home/rollup-producer.ts +34 -5
- package/src/home/suggested-prompts.ts +101 -0
- package/src/ipc/__tests__/attachment-ipc.test.ts +213 -0
- package/src/ipc/__tests__/browser-ipc.test.ts +339 -0
- package/src/ipc/__tests__/cache-ipc.test.ts +266 -0
- package/src/ipc/__tests__/socket-path.test.ts +73 -0
- package/src/ipc/__tests__/task-ipc.test.ts +577 -0
- package/src/ipc/__tests__/ui-request-route.test.ts +495 -0
- package/src/ipc/__tests__/watcher-ipc.test.ts +295 -0
- package/src/ipc/cli-client.ts +2 -1
- package/src/ipc/cli-server.ts +26 -8
- package/src/ipc/gateway-client.ts +4 -4
- package/src/ipc/routes/attachment.ts +114 -0
- package/src/ipc/routes/browser-context.ts +61 -0
- package/src/ipc/routes/browser.ts +96 -0
- package/src/ipc/routes/cache.ts +96 -0
- package/src/ipc/routes/index.ts +17 -1
- package/src/ipc/routes/task-queue.ts +226 -0
- package/src/ipc/routes/task.ts +173 -0
- package/src/ipc/routes/ui-request.ts +50 -0
- package/src/ipc/routes/watcher.ts +203 -0
- package/src/ipc/socket-path.ts +100 -0
- package/src/memory/__tests__/conversation-analyze-job.test.ts +9 -8
- package/src/memory/__tests__/conversation-group-migration.test.ts +99 -0
- package/src/memory/admin.ts +18 -0
- package/src/memory/conversation-analyze-job.ts +14 -13
- package/src/memory/conversation-attention-store.ts +13 -6
- package/src/memory/conversation-crud.ts +103 -3
- package/src/memory/conversation-group-migration.ts +38 -6
- package/src/memory/conversation-title-service.ts +7 -4
- package/src/memory/db-init.ts +2 -0
- package/src/memory/embedding-backend.ts +1 -1
- package/src/memory/graph/compaction.ts +299 -0
- package/src/memory/graph/consolidation.ts +4 -4
- package/src/memory/graph/conversation-graph-memory.ts +89 -29
- package/src/memory/graph/extraction.test.ts +272 -2
- package/src/memory/graph/extraction.ts +173 -51
- package/src/memory/graph/graph-search.test.ts +92 -0
- package/src/memory/graph/graph-search.ts +4 -1
- package/src/memory/graph/narrative.ts +2 -2
- package/src/memory/graph/pattern-scan.ts +2 -2
- package/src/memory/graph/retriever.test.ts +459 -0
- package/src/memory/graph/retriever.ts +230 -48
- package/src/memory/graph/store.ts +41 -0
- package/src/memory/graph/tool-handlers.ts +27 -0
- package/src/memory/graph/tools.ts +6 -1
- package/src/memory/indexer.ts +5 -5
- package/src/memory/job-handlers/conversation-starters.ts +23 -20
- package/src/memory/job-handlers/summarization.ts +2 -2
- package/src/memory/job-utils.ts +7 -1
- package/src/memory/jobs/embed-pkb-file.test.ts +168 -0
- package/src/memory/jobs/embed-pkb-file.ts +54 -0
- package/src/memory/jobs-store.ts +44 -3
- package/src/memory/jobs-worker.ts +4 -0
- package/src/memory/migrations/140-backfill-usage-cache-accounting.ts +1 -1
- package/src/memory/migrations/220-normalize-user-file-by-principal.ts +2 -2
- package/src/memory/migrations/222-strip-placeholder-sentinels-from-messages.ts +82 -0
- package/src/memory/migrations/index.ts +1 -0
- package/src/memory/pkb/pkb-index.test.ts +368 -0
- package/src/memory/pkb/pkb-index.ts +255 -0
- package/src/memory/pkb/pkb-reconcile.test.ts +251 -0
- package/src/memory/pkb/pkb-reconcile.ts +148 -0
- package/src/memory/pkb/pkb-search.test.ts +438 -0
- package/src/memory/pkb/pkb-search.ts +137 -0
- package/src/memory/pkb/types.ts +53 -0
- package/src/memory/qdrant-client.ts +122 -1
- package/src/memory/slack-thread-store.ts +37 -0
- package/src/messaging/providers/gmail/adapter.ts +6 -16
- package/src/messaging/providers/gmail/client.ts +22 -0
- package/src/messaging/providers/gmail/types.ts +7 -0
- package/src/messaging/providers/slack/adapter.ts +14 -2
- package/src/messaging/providers/slack/backfill.test.ts +257 -0
- package/src/messaging/providers/slack/backfill.ts +101 -0
- package/src/messaging/providers/slack/message-metadata.test.ts +316 -0
- package/src/messaging/providers/slack/message-metadata.ts +123 -0
- package/src/messaging/providers/slack/render-transcript.test.ts +1373 -0
- package/src/messaging/providers/slack/render-transcript.ts +443 -0
- package/src/messaging/style-analyzer.ts +5 -2
- package/src/notifications/README.md +9 -5
- package/src/notifications/decision-engine.ts +3 -9
- package/src/notifications/preference-extractor.ts +2 -6
- package/src/oauth/oauth-store.ts +1 -0
- package/src/oauth/platform-connection.test.ts +47 -0
- package/src/oauth/platform-connection.ts +15 -5
- package/src/oauth/seed-providers.ts +4 -2
- package/src/permissions/approval-policy.test.ts +948 -0
- package/src/permissions/approval-policy.ts +257 -0
- package/src/permissions/bash-risk-classifier.test.ts +1208 -0
- package/src/permissions/bash-risk-classifier.ts +707 -0
- package/src/permissions/checker.ts +217 -708
- package/src/permissions/command-registry.test.ts +535 -0
- package/src/permissions/command-registry.ts +825 -0
- package/src/permissions/defaults.ts +26 -78
- package/src/permissions/file-risk-classifier.test.ts +535 -0
- package/src/permissions/file-risk-classifier.ts +274 -0
- package/src/permissions/risk-types.ts +205 -0
- package/src/permissions/secret-prompter.ts +53 -2
- package/src/permissions/skill-risk-classifier.test.ts +311 -0
- package/src/permissions/skill-risk-classifier.ts +214 -0
- package/src/permissions/trust-client.ts +52 -25
- package/src/permissions/trust-store-interface.ts +1 -6
- package/src/permissions/trust-store.ts +161 -62
- package/src/permissions/types.ts +23 -14
- package/src/permissions/web-risk-classifier.test.ts +170 -0
- package/src/permissions/web-risk-classifier.ts +89 -0
- package/src/permissions/workspace-policy.ts +1 -16
- package/src/platform/client.ts +19 -1
- package/src/prompts/persona-resolver.ts +3 -3
- package/src/prompts/system-prompt.ts +19 -20
- package/src/prompts/templates/SOUL.md +2 -2
- package/src/prompts/update-bulletin-job.ts +190 -0
- package/src/providers/__tests__/context-overflow-error.test.ts +328 -0
- package/src/providers/__tests__/provider-env-vars.test.ts +102 -0
- package/src/providers/__tests__/retry-callsite.test.ts +424 -0
- package/src/providers/anthropic/client.ts +183 -14
- package/src/providers/call-site-routing.ts +71 -0
- package/src/providers/gemini/client.ts +65 -2
- package/src/providers/managed-proxy/constants.ts +2 -1
- package/src/providers/model-catalog.ts +501 -33
- package/src/providers/model-intents.ts +4 -4
- package/src/providers/openai/chat-completions-provider.ts +57 -1
- package/src/providers/openai/responses-provider.ts +86 -9
- package/src/providers/openrouter/client.ts +76 -9
- package/src/providers/provider-env-vars.ts +56 -0
- package/src/providers/provider-send-message.ts +22 -5
- package/src/providers/ratelimit.ts +4 -0
- package/src/providers/registry.ts +19 -8
- package/src/providers/retry.ts +174 -39
- package/src/providers/speech-to-text/__tests__/resolve.test.ts +55 -0
- package/src/providers/speech-to-text/google-gemini-live-stream.ts +4 -4
- package/src/providers/speech-to-text/provider-catalog.ts +17 -0
- package/src/providers/speech-to-text/resolve.ts +7 -0
- package/src/providers/speech-to-text/xai-realtime.test.ts +578 -0
- package/src/providers/speech-to-text/xai-realtime.ts +796 -0
- package/src/providers/speech-to-text/xai.test.ts +155 -0
- package/src/providers/speech-to-text/xai.ts +97 -0
- package/src/providers/types.ts +93 -3
- package/src/runtime/AGENTS.md +2 -2
- package/src/runtime/__tests__/agent-wake.test.ts +43 -2
- package/src/runtime/__tests__/interactive-ui.test.ts +673 -0
- package/src/runtime/agent-wake.ts +63 -22
- package/src/runtime/auth/route-policy.ts +4 -0
- package/src/runtime/btw-sidechain.ts +13 -3
- package/src/runtime/channel-reply-delivery.ts +106 -2
- package/src/runtime/decision-token.ts +116 -0
- package/src/runtime/gateway-client.ts +2 -2
- package/src/runtime/http-router.ts +32 -0
- package/src/runtime/http-server.ts +52 -1
- package/src/runtime/http-types.ts +23 -1
- package/src/runtime/interactive-ui.ts +362 -0
- package/src/runtime/invite-instruction-generator.ts +2 -2
- package/src/runtime/migrations/__tests__/gcs-signed-url.test.ts +176 -0
- package/src/runtime/migrations/__tests__/vbundle-metadata-merge-integration.test.ts +390 -0
- package/src/runtime/migrations/__tests__/vbundle-metadata-merge.test.ts +221 -0
- package/src/runtime/migrations/__tests__/vbundle-streaming-importer.test.ts +1540 -0
- package/src/runtime/migrations/__tests__/vbundle-streaming-validator.test.ts +453 -0
- package/src/runtime/migrations/__tests__/vbundle-tar-stream.test.ts +222 -0
- package/src/runtime/migrations/gcs-signed-url.ts +162 -0
- package/src/runtime/migrations/vbundle-importer.ts +154 -9
- package/src/runtime/migrations/vbundle-metadata-merge.ts +124 -0
- package/src/runtime/migrations/vbundle-streaming-importer.ts +2522 -0
- package/src/runtime/migrations/vbundle-streaming-validator.ts +244 -0
- package/src/runtime/migrations/vbundle-tar-stream.ts +217 -0
- package/src/runtime/migrations/vbundle-validator.ts +15 -6
- package/src/runtime/routes/__tests__/home-feed-routes.test.ts +111 -0
- package/src/runtime/routes/__tests__/migration-import-credential-filter.test.ts +114 -75
- package/src/runtime/routes/__tests__/migration-vellum-metadata-reconcile.test.ts +246 -0
- package/src/runtime/routes/approval-prompt-ts-tracker.ts +58 -0
- package/src/runtime/routes/approval-routes.ts +12 -17
- package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +9 -0
- package/src/runtime/routes/avatar-routes.ts +20 -4
- package/src/runtime/routes/btw-routes.ts +1 -4
- package/src/runtime/routes/conversation-management-routes.ts +20 -2
- package/src/runtime/routes/conversation-routes.ts +133 -27
- package/src/runtime/routes/debug-routes.ts +1 -1
- package/src/runtime/routes/diagnostics-routes.ts +6 -4
- package/src/runtime/routes/events-routes.ts +16 -0
- package/src/runtime/routes/guardian-approval-interception.ts +33 -3
- package/src/runtime/routes/guardian-approval-prompt.ts +13 -3
- package/src/runtime/routes/home-feed-routes.ts +120 -2
- package/src/runtime/routes/inbound-message-handler.ts +912 -2
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +113 -2
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +61 -3
- package/src/runtime/routes/inbound-stages/edit-intercept.ts +129 -6
- package/src/runtime/routes/integrations/slack/channel.ts +25 -3
- package/src/runtime/routes/llm-context-normalization.ts +23 -1
- package/src/runtime/routes/migration-routes.ts +720 -124
- package/src/runtime/routes/settings-routes.ts +4 -2
- package/src/runtime/routes/trust-rules-routes.ts +30 -14
- package/src/runtime/routes/work-items-routes.test.ts +1 -1
- package/src/runtime/routes/work-items-routes.ts +3 -2
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +25 -43
- package/src/runtime/services/analyze-conversation.ts +12 -16
- package/src/runtime/skill-route-registry.ts +28 -6
- package/src/schedule/scheduler.ts +8 -0
- package/src/security/__tests__/provider-key-env-fallback.test.ts +119 -0
- package/src/security/__tests__/untrusted-content.test.ts +109 -0
- package/src/security/oauth2.ts +98 -35
- package/src/security/secure-keys.ts +7 -8
- package/src/security/token-manager.ts +27 -13
- package/src/security/untrusted-content.ts +102 -0
- package/src/skills/catalog-cache.ts +26 -7
- package/src/skills/catalog-install.ts +31 -3
- package/src/skills/skill-cache-store.ts +97 -0
- package/src/stt/__tests__/daemon-batch-transcriber.test.ts +76 -0
- package/src/stt/daemon-batch-transcriber.ts +33 -0
- package/src/stt/stt-stream-session.ts +8 -1
- package/src/stt/types.ts +5 -1
- package/src/subagent/manager.ts +41 -13
- package/src/tasks/ephemeral-permissions.ts +9 -4
- package/src/telemetry/usage-telemetry-reporter.ts +27 -5
- package/src/tools/browser/__tests__/browser-status.test.ts +45 -2
- package/src/tools/browser/browser-execution.ts +65 -38
- package/src/tools/browser/cdp-client/cdp-inspect/discovery.ts +22 -0
- package/src/tools/credentials/tool-policy.ts +39 -5
- package/src/tools/credentials/vault.ts +9 -4
- package/src/tools/executor.ts +4 -0
- package/src/tools/filesystem/write.ts +52 -0
- package/src/tools/host-terminal/host-shell.ts +45 -5
- package/src/tools/memory/register.test.ts +185 -0
- package/src/tools/memory/register.ts +3 -1
- package/src/tools/network/web-fetch.ts +20 -10
- package/src/tools/network/web-search.ts +19 -4
- package/src/tools/permission-checker.ts +36 -15
- package/src/tools/policy-context.ts +25 -8
- package/src/tools/registry.ts +55 -3
- package/src/tools/side-effects.ts +0 -11
- package/src/tools/skills/execute.ts +2 -2
- package/src/tools/skills/sandbox-runner.ts +5 -2
- package/src/tools/terminal/backends/native.ts +51 -2
- package/src/tools/terminal/safe-env.ts +3 -2
- package/src/tools/terminal/shell.ts +1 -0
- package/src/tools/tool-manifest.ts +6 -21
- package/src/tools/types.ts +12 -3
- package/src/tools/verification-control-plane-policy.ts +1 -1
- package/src/tts/__tests__/provider-adapters.test.ts +240 -13
- package/src/tts/provider-catalog.ts +18 -0
- package/src/tts/providers/index.ts +2 -0
- package/src/tts/providers/xai-provider.ts +224 -0
- package/src/tts/types.ts +46 -0
- package/src/types/tar-stream.d.ts +66 -0
- package/src/util/json.ts +17 -0
- package/src/util/platform.ts +2 -2
- package/src/util/pricing.ts +15 -5
- package/src/watcher/engine.ts +1 -1
- package/src/watcher/providers/google-calendar.ts +134 -8
- package/src/watcher/providers/outlook-calendar.ts +42 -2
- package/src/workspace/git-service.ts +23 -4
- package/src/workspace/migrations/038-unify-llm-callsite-configs.ts +516 -0
- package/src/workspace/migrations/039-drop-legacy-llm-keys.ts +171 -0
- package/src/workspace/migrations/040-seed-latency-callsite-defaults.ts +154 -0
- package/src/workspace/migrations/041-backfill-google-gmail-settings-scope.ts +57 -0
- package/src/workspace/migrations/042-fix-backfill-google-gmail-settings-scope.ts +70 -0
- package/src/workspace/migrations/043-release-notes-latex-rendering.ts +75 -0
- package/src/workspace/migrations/044-bump-stale-provider-stream-timeout.ts +51 -0
- package/src/workspace/migrations/045-release-notes-meet-avatar.ts +130 -0
- package/src/workspace/migrations/AGENTS.md +1 -1
- package/src/workspace/migrations/registry.ts +16 -0
- package/src/workspace/provider-commit-message-generator.ts +19 -38
- package/src/__tests__/gmail-archive-fallback.test.ts +0 -193
- package/src/__tests__/gmail-archive-gate.test.ts +0 -246
- package/src/__tests__/gmail-preferences.test.ts +0 -117
- package/src/__tests__/outlook-attachments.test.ts +0 -301
- package/src/__tests__/outlook-automation-tools.test.ts +0 -425
- package/src/__tests__/outlook-categories.test.ts +0 -212
- package/src/__tests__/outlook-compose-tools.test.ts +0 -325
- package/src/__tests__/outlook-declutter-tools.test.ts +0 -585
- package/src/__tests__/outlook-follow-up.test.ts +0 -196
- package/src/__tests__/outlook-trash.test.ts +0 -77
- package/src/__tests__/outlook-unsubscribe.test.ts +0 -279
- package/src/__tests__/update-bulletin-format.test.ts +0 -181
- package/src/__tests__/update-bulletin-state.test.ts +0 -135
- package/src/__tests__/update-bulletin.test.ts +0 -478
- package/src/__tests__/update-template-contract.test.ts +0 -29
- package/src/cli/commands/doctor.ts +0 -341
- package/src/config/bundled-skills/browser/SKILL.md +0 -88
- package/src/config/bundled-skills/browser/TOOLS.json +0 -516
- package/src/config/bundled-skills/browser/tools/browser-attach.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-click.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-close.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-detach.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-extract.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-fill-credential.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-hover.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-navigate.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-press-key.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-screenshot.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-scroll.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-select-option.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-snapshot.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-status.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-type.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-wait-for-download.ts +0 -49
- package/src/config/bundled-skills/browser/tools/browser-wait-for.ts +0 -12
- package/src/config/bundled-skills/chatgpt-import/SKILL.md +0 -27
- package/src/config/bundled-skills/chatgpt-import/TOOLS.json +0 -27
- package/src/config/bundled-skills/chatgpt-import/tools/chatgpt-import.ts +0 -378
- package/src/config/bundled-skills/gmail/SKILL.md +0 -221
- package/src/config/bundled-skills/gmail/TOOLS.json +0 -588
- package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +0 -256
- package/src/config/bundled-skills/gmail/tools/gmail-attachments.ts +0 -112
- package/src/config/bundled-skills/gmail/tools/gmail-draft.ts +0 -44
- package/src/config/bundled-skills/gmail/tools/gmail-filters.ts +0 -81
- package/src/config/bundled-skills/gmail/tools/gmail-follow-up.ts +0 -108
- package/src/config/bundled-skills/gmail/tools/gmail-forward.ts +0 -146
- package/src/config/bundled-skills/gmail/tools/gmail-label.ts +0 -53
- package/src/config/bundled-skills/gmail/tools/gmail-outreach-scan.ts +0 -347
- package/src/config/bundled-skills/gmail/tools/gmail-preferences-tool.ts +0 -59
- package/src/config/bundled-skills/gmail/tools/gmail-preferences.ts +0 -82
- package/src/config/bundled-skills/gmail/tools/gmail-send-draft.ts +0 -26
- package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +0 -347
- package/src/config/bundled-skills/gmail/tools/gmail-trash.ts +0 -29
- package/src/config/bundled-skills/gmail/tools/gmail-unsubscribe.ts +0 -122
- package/src/config/bundled-skills/gmail/tools/gmail-vacation.ts +0 -67
- package/src/config/bundled-skills/gmail/tools/scan-result-store.ts +0 -100
- package/src/config/bundled-skills/gmail/tools/shared.ts +0 -47
- package/src/config/bundled-skills/google-calendar/SKILL.md +0 -51
- package/src/config/bundled-skills/google-calendar/TOOLS.json +0 -226
- package/src/config/bundled-skills/google-calendar/calendar-client.ts +0 -223
- package/src/config/bundled-skills/google-calendar/tools/calendar-check-availability.ts +0 -27
- package/src/config/bundled-skills/google-calendar/tools/calendar-create-event.ts +0 -48
- package/src/config/bundled-skills/google-calendar/tools/calendar-get-event.ts +0 -19
- package/src/config/bundled-skills/google-calendar/tools/calendar-list-events.ts +0 -36
- package/src/config/bundled-skills/google-calendar/tools/calendar-rsvp.ts +0 -58
- package/src/config/bundled-skills/google-calendar/tools/shared.ts +0 -17
- package/src/config/bundled-skills/google-calendar/types.ts +0 -97
- package/src/config/bundled-skills/outlook/SKILL.md +0 -196
- package/src/config/bundled-skills/outlook/TOOLS.json +0 -530
- package/src/config/bundled-skills/outlook/tools/outlook-attachments.ts +0 -85
- package/src/config/bundled-skills/outlook/tools/outlook-categories.ts +0 -77
- package/src/config/bundled-skills/outlook/tools/outlook-draft.ts +0 -84
- package/src/config/bundled-skills/outlook/tools/outlook-follow-up.ts +0 -94
- package/src/config/bundled-skills/outlook/tools/outlook-forward.ts +0 -49
- package/src/config/bundled-skills/outlook/tools/outlook-outreach-scan.ts +0 -237
- package/src/config/bundled-skills/outlook/tools/outlook-rules.ts +0 -161
- package/src/config/bundled-skills/outlook/tools/outlook-send-draft.ts +0 -32
- package/src/config/bundled-skills/outlook/tools/outlook-sender-digest.ts +0 -272
- package/src/config/bundled-skills/outlook/tools/outlook-trash.ts +0 -29
- package/src/config/bundled-skills/outlook/tools/outlook-unsubscribe.ts +0 -129
- package/src/config/bundled-skills/outlook/tools/outlook-vacation.ts +0 -87
- package/src/config/bundled-skills/outlook/tools/shared.ts +0 -20
- package/src/config/bundled-skills/outlook-calendar/SKILL.md +0 -51
- package/src/config/bundled-skills/outlook-calendar/TOOLS.json +0 -221
- package/src/config/bundled-skills/outlook-calendar/calendar-client.ts +0 -252
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-check-availability.ts +0 -53
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-create-event.ts +0 -74
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-get-event.ts +0 -18
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-list-events.ts +0 -46
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-rsvp.ts +0 -36
- package/src/config/bundled-skills/outlook-calendar/tools/shared.ts +0 -17
- package/src/config/bundled-skills/outlook-calendar/types.ts +0 -120
- package/src/config/bundled-skills/slack/SKILL.md +0 -108
- package/src/config/bundled-skills/tasks/SKILL.md +0 -37
- package/src/config/bundled-skills/tasks/TOOLS.json +0 -353
- package/src/config/bundled-skills/tasks/icon.svg +0 -34
- package/src/config/bundled-skills/tasks/tools/task-delete.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-list-add.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-list-remove.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-list-show.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-list-update.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-list.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-queue-run.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-run.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-save.ts +0 -12
- package/src/config/bundled-skills/watcher/SKILL.md +0 -31
- package/src/config/bundled-skills/watcher/TOOLS.json +0 -167
- package/src/config/bundled-skills/watcher/tools/watcher-create.ts +0 -12
- package/src/config/bundled-skills/watcher/tools/watcher-delete.ts +0 -12
- package/src/config/bundled-skills/watcher/tools/watcher-digest.ts +0 -12
- package/src/config/bundled-skills/watcher/tools/watcher-list.ts +0 -12
- package/src/config/bundled-skills/watcher/tools/watcher-update.ts +0 -12
- package/src/prompts/templates/UPDATES.md +0 -50
- package/src/prompts/update-bulletin-format.ts +0 -85
- package/src/prompts/update-bulletin-state.ts +0 -58
- package/src/prompts/update-bulletin-template-path.ts +0 -13
- package/src/prompts/update-bulletin.ts +0 -139
- package/src/shared/provider-env-vars.ts +0 -19
- package/src/tools/watcher/create.ts +0 -86
- package/src/tools/watcher/delete.ts +0 -36
- package/src/tools/watcher/digest.ts +0 -54
- package/src/tools/watcher/list.ts +0 -83
- package/src/tools/watcher/update.ts +0 -71
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
gte,
|
|
11
11
|
inArray,
|
|
12
12
|
isNull,
|
|
13
|
+
like,
|
|
13
14
|
lt,
|
|
14
15
|
lte,
|
|
15
16
|
sql,
|
|
@@ -23,6 +24,7 @@ import { CHANNEL_IDS, INTERFACE_IDS, isChannelId } from "../channels/types.js";
|
|
|
23
24
|
import { getConfig } from "../config/loader.js";
|
|
24
25
|
import type { TrustContext } from "../daemon/conversation-runtime-assembly.js";
|
|
25
26
|
import { UserError } from "../util/errors.js";
|
|
27
|
+
import { safeParseRecord } from "../util/json.js";
|
|
26
28
|
import { getLogger } from "../util/logger.js";
|
|
27
29
|
import { getConversationsDir } from "../util/platform.js";
|
|
28
30
|
import { createRowMapper } from "../util/row-mapper.js";
|
|
@@ -102,6 +104,9 @@ export const messageMetadataSchema = z
|
|
|
102
104
|
forkSourceMessageId: z.string().optional(),
|
|
103
105
|
/** Image source paths from desktop attachments, keyed by filename. */
|
|
104
106
|
imageSourcePaths: z.record(z.string(), z.string()).optional(),
|
|
107
|
+
memoryInjectedBlock: z.string().optional(),
|
|
108
|
+
turnContextBlock: z.string().optional(),
|
|
109
|
+
pkbSystemReminderBlock: z.string().optional(),
|
|
105
110
|
})
|
|
106
111
|
.passthrough();
|
|
107
112
|
|
|
@@ -420,9 +425,7 @@ export function findAnalysisConversationFor(
|
|
|
420
425
|
* not found. Tiny convenience used by the recursion guard in the
|
|
421
426
|
* auto-analyze loop.
|
|
422
427
|
*/
|
|
423
|
-
export function getConversationSource(
|
|
424
|
-
conversationId: string,
|
|
425
|
-
): string | null {
|
|
428
|
+
export function getConversationSource(conversationId: string): string | null {
|
|
426
429
|
const db = getDb();
|
|
427
430
|
const row = db
|
|
428
431
|
.select({ source: conversations.source })
|
|
@@ -1044,6 +1047,49 @@ export function getMessages(conversationId: string): MessageRow[] {
|
|
|
1044
1047
|
.map(parseMessage);
|
|
1045
1048
|
}
|
|
1046
1049
|
|
|
1050
|
+
/**
|
|
1051
|
+
* Count messages whose metadata JSON contains a `slackMeta` envelope, capped
|
|
1052
|
+
* at `limit`. Pushes the cap into SQL (`LIKE` + `LIMIT`) so warm Slack DM
|
|
1053
|
+
* conversations don't require a full-table scan + JSON parse on every
|
|
1054
|
+
* inbound message to confirm the cold-start threshold has been cleared.
|
|
1055
|
+
* Returns the number of matching rows up to `limit`; callers compare against
|
|
1056
|
+
* the cold-start threshold to decide whether to backfill.
|
|
1057
|
+
*/
|
|
1058
|
+
export function countMessagesWithSlackMeta(
|
|
1059
|
+
conversationId: string,
|
|
1060
|
+
limit: number,
|
|
1061
|
+
): number {
|
|
1062
|
+
const db = getDb();
|
|
1063
|
+
const rows = db
|
|
1064
|
+
.select({ one: sql`1` })
|
|
1065
|
+
.from(messages)
|
|
1066
|
+
.where(
|
|
1067
|
+
and(
|
|
1068
|
+
eq(messages.conversationId, conversationId),
|
|
1069
|
+
like(messages.metadata, '%"slackMeta"%'),
|
|
1070
|
+
),
|
|
1071
|
+
)
|
|
1072
|
+
.limit(limit)
|
|
1073
|
+
.all();
|
|
1074
|
+
return rows.length;
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1077
|
+
/**
|
|
1078
|
+
* Efficient existence check — returns true if the conversation has at least
|
|
1079
|
+
* one message row. Uses `LIMIT 1` + `select({ 1 })` to avoid loading and
|
|
1080
|
+
* parsing any message content.
|
|
1081
|
+
*/
|
|
1082
|
+
export function hasMessages(conversationId: string): boolean {
|
|
1083
|
+
const db = getDb();
|
|
1084
|
+
const row = db
|
|
1085
|
+
.select({ one: sql`1` })
|
|
1086
|
+
.from(messages)
|
|
1087
|
+
.where(eq(messages.conversationId, conversationId))
|
|
1088
|
+
.limit(1)
|
|
1089
|
+
.get();
|
|
1090
|
+
return row !== undefined;
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1047
1093
|
export interface PaginatedMessagesResult {
|
|
1048
1094
|
messages: MessageRow[];
|
|
1049
1095
|
hasMore: boolean;
|
|
@@ -1456,6 +1502,60 @@ export function updateMessageMetadata(
|
|
|
1456
1502
|
.run();
|
|
1457
1503
|
}
|
|
1458
1504
|
|
|
1505
|
+
/**
|
|
1506
|
+
* Bulk-remove the `pkbSystemReminderBlock` field from every user-message
|
|
1507
|
+
* metadata row in a conversation. Called from compaction-strip sites so
|
|
1508
|
+
* post-restart rehydration stays consistent with the in-memory state
|
|
1509
|
+
* produced by `stripInjectionsForCompaction` (which removes
|
|
1510
|
+
* `<system_reminder>` from live messages but cannot touch the DB).
|
|
1511
|
+
*/
|
|
1512
|
+
export function clearPkbSystemReminderMetadataForConversation(
|
|
1513
|
+
conversationId: string,
|
|
1514
|
+
): void {
|
|
1515
|
+
rawRun(
|
|
1516
|
+
`UPDATE messages
|
|
1517
|
+
SET metadata = json_remove(metadata, '$.pkbSystemReminderBlock')
|
|
1518
|
+
WHERE conversation_id = ?
|
|
1519
|
+
AND role = 'user'
|
|
1520
|
+
AND metadata IS NOT NULL
|
|
1521
|
+
AND json_extract(metadata, '$.pkbSystemReminderBlock') IS NOT NULL`,
|
|
1522
|
+
conversationId,
|
|
1523
|
+
);
|
|
1524
|
+
}
|
|
1525
|
+
|
|
1526
|
+
/**
|
|
1527
|
+
* Atomically update both `content` and (shallow-merged) `metadata` for a
|
|
1528
|
+
* message. Used by edit-propagation paths that need to update the message
|
|
1529
|
+
* body and stamp metadata (e.g. `slackMeta.editedAt`) in a single
|
|
1530
|
+
* transaction so a partial write cannot leak.
|
|
1531
|
+
*
|
|
1532
|
+
* `metadataUpdates` is shallow-merged into the existing top-level metadata
|
|
1533
|
+
* object. To merge into a nested sub-key (e.g. `slackMeta`), the caller
|
|
1534
|
+
* must compute the merged sub-value first and pass `{ slackMeta: merged }`.
|
|
1535
|
+
*/
|
|
1536
|
+
export function updateMessageContentAndMetadata(
|
|
1537
|
+
messageId: string,
|
|
1538
|
+
newContent: string,
|
|
1539
|
+
metadataUpdates: Record<string, unknown>,
|
|
1540
|
+
): void {
|
|
1541
|
+
const db = getDb();
|
|
1542
|
+
db.transaction((tx) => {
|
|
1543
|
+
const row = tx
|
|
1544
|
+
.select({ metadata: messages.metadata })
|
|
1545
|
+
.from(messages)
|
|
1546
|
+
.where(eq(messages.id, messageId))
|
|
1547
|
+
.get();
|
|
1548
|
+
const existing = row?.metadata ? safeParseRecord(row.metadata) : {};
|
|
1549
|
+
tx.update(messages)
|
|
1550
|
+
.set({
|
|
1551
|
+
content: newContent,
|
|
1552
|
+
metadata: JSON.stringify({ ...existing, ...metadataUpdates }),
|
|
1553
|
+
})
|
|
1554
|
+
.where(eq(messages.id, messageId))
|
|
1555
|
+
.run();
|
|
1556
|
+
});
|
|
1557
|
+
}
|
|
1558
|
+
|
|
1459
1559
|
/**
|
|
1460
1560
|
* Re-link all attachments from a set of source messages to a target message.
|
|
1461
1561
|
* Used during message consolidation so that attachments linked to deleted
|
|
@@ -58,10 +58,6 @@ export function ensureGroupMigration(): void {
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
// 3. Seed system groups.
|
|
61
|
-
//
|
|
62
|
-
// `system:reflections` is a legacy group kept for backward compatibility
|
|
63
|
-
// with existing installations. New auto-analysis conversations are assigned
|
|
64
|
-
// to `system:background`; the migration in step 6 moves existing ones.
|
|
65
61
|
const now = Math.floor(Date.now() / 1000);
|
|
66
62
|
rawExec(`
|
|
67
63
|
INSERT OR IGNORE INTO conversation_groups (id, name, sort_position, is_system_group, created_at, updated_at)
|
|
@@ -69,8 +65,7 @@ export function ensureGroupMigration(): void {
|
|
|
69
65
|
('system:pinned', 'Pinned', 0, TRUE, ${now}, ${now}),
|
|
70
66
|
('system:scheduled', 'Scheduled', 1, TRUE, ${now}, ${now}),
|
|
71
67
|
('system:background', 'Background', 2, TRUE, ${now}, ${now}),
|
|
72
|
-
('system:all', 'Recents', 3, TRUE, ${now}, ${now})
|
|
73
|
-
('system:reflections', 'Reflections', 100, TRUE, ${now}, ${now})
|
|
68
|
+
('system:all', 'Recents', 3, TRUE, ${now}, ${now})
|
|
74
69
|
`);
|
|
75
70
|
|
|
76
71
|
// One-time migration: move system:all to sortPosition 3 (from 999999).
|
|
@@ -245,5 +240,42 @@ export function ensureGroupMigration(): void {
|
|
|
245
240
|
}
|
|
246
241
|
}
|
|
247
242
|
|
|
243
|
+
// 7. One-time cleanup: delete the orphaned system:reflections group row.
|
|
244
|
+
//
|
|
245
|
+
// Reflections render as a sub-group under Background via the client's
|
|
246
|
+
// sub-group label provider; the standalone system:reflections group is no
|
|
247
|
+
// longer referenced by any conversation after step 6. Leaving the row in
|
|
248
|
+
// place causes the macOS sidebar to render an empty duplicate "Reflections"
|
|
249
|
+
// entry with a fallback folder icon alongside the Background sub-group.
|
|
250
|
+
const reflectionsGroupDeleted = rawGet<{ id: string }>(
|
|
251
|
+
"SELECT id FROM conversation_groups WHERE id = '_reflections_group_deleted_complete'",
|
|
252
|
+
);
|
|
253
|
+
|
|
254
|
+
if (!reflectionsGroupDeleted) {
|
|
255
|
+
try {
|
|
256
|
+
rawExec("BEGIN");
|
|
257
|
+
|
|
258
|
+
// Belt-and-suspenders: re-run the conversation move in case a straggler
|
|
259
|
+
// crept in between step 6's sentinel being set and this step shipping.
|
|
260
|
+
rawExec(`
|
|
261
|
+
UPDATE conversations SET group_id = 'system:background'
|
|
262
|
+
WHERE group_id = 'system:reflections'
|
|
263
|
+
`);
|
|
264
|
+
|
|
265
|
+
rawExec(`DELETE FROM conversation_groups WHERE id = 'system:reflections'`);
|
|
266
|
+
|
|
267
|
+
rawExec(`
|
|
268
|
+
INSERT OR IGNORE INTO conversation_groups (id, name, sort_position, is_system_group)
|
|
269
|
+
VALUES ('_reflections_group_deleted_complete', '_reflections_group_deleted_complete', -1, TRUE)
|
|
270
|
+
`);
|
|
271
|
+
|
|
272
|
+
rawExec("COMMIT");
|
|
273
|
+
} catch (err) {
|
|
274
|
+
rawExec("ROLLBACK");
|
|
275
|
+
log.error({ err }, "reflections-group deletion failed, rolled back");
|
|
276
|
+
throw err;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
248
280
|
migrated = true;
|
|
249
281
|
}
|
|
@@ -37,6 +37,7 @@ export type TitleOrigin =
|
|
|
37
37
|
| "filing"
|
|
38
38
|
| "local"
|
|
39
39
|
| "task_submit"
|
|
40
|
+
| "updates_bulletin"
|
|
40
41
|
| "misc";
|
|
41
42
|
|
|
42
43
|
export interface TitleContext {
|
|
@@ -118,7 +119,8 @@ export async function generateAndPersistConversationTitle(
|
|
|
118
119
|
return { title: conversation.title!, updated: false };
|
|
119
120
|
}
|
|
120
121
|
|
|
121
|
-
const provider =
|
|
122
|
+
const provider =
|
|
123
|
+
params.provider ?? (await getConfiguredProvider("conversationTitle"));
|
|
122
124
|
if (!provider) {
|
|
123
125
|
// No provider available — fall back to context-derived title or untitled
|
|
124
126
|
const fallback = deriveFallbackTitle(context) ?? UNTITLED_FALLBACK;
|
|
@@ -133,7 +135,7 @@ export async function generateAndPersistConversationTitle(
|
|
|
133
135
|
provider,
|
|
134
136
|
systemPrompt: buildTitleSystemPrompt(),
|
|
135
137
|
tools: [],
|
|
136
|
-
|
|
138
|
+
callSite: "conversationTitle",
|
|
137
139
|
signal,
|
|
138
140
|
timeoutMs: 10_000,
|
|
139
141
|
});
|
|
@@ -219,7 +221,8 @@ export async function regenerateConversationTitle(
|
|
|
219
221
|
return { title: conversation?.title ?? UNTITLED_FALLBACK, updated: false };
|
|
220
222
|
}
|
|
221
223
|
|
|
222
|
-
const provider =
|
|
224
|
+
const provider =
|
|
225
|
+
params.provider ?? (await getConfiguredProvider("conversationTitle"));
|
|
223
226
|
if (!provider) {
|
|
224
227
|
return { title: conversation.title ?? UNTITLED_FALLBACK, updated: false };
|
|
225
228
|
}
|
|
@@ -236,7 +239,7 @@ export async function regenerateConversationTitle(
|
|
|
236
239
|
provider,
|
|
237
240
|
systemPrompt: buildTitleSystemPrompt(),
|
|
238
241
|
tools: [],
|
|
239
|
-
|
|
242
|
+
callSite: "conversationTitle",
|
|
240
243
|
signal,
|
|
241
244
|
timeoutMs: 10_000,
|
|
242
245
|
});
|
package/src/memory/db-init.ts
CHANGED
|
@@ -146,6 +146,7 @@ import {
|
|
|
146
146
|
migrateSchemaIndexesAndColumns,
|
|
147
147
|
migrateScrubCorruptedImageAttachments,
|
|
148
148
|
migrateStripIntegrationPrefixFromProviderKeys,
|
|
149
|
+
migrateStripPlaceholderSentinelsFromMessages,
|
|
149
150
|
migrateStripThinkingFromConsolidated,
|
|
150
151
|
migrateUsageDashboardIndexes,
|
|
151
152
|
migrateUsageLlmCallCount,
|
|
@@ -370,6 +371,7 @@ export function initializeDb(): void {
|
|
|
370
371
|
migrateOAuthProvidersTokenExchangeBodyFormat,
|
|
371
372
|
migrateNormalizeUserFileByPrincipal,
|
|
372
373
|
migrateConversationsArchivedAt,
|
|
374
|
+
migrateStripPlaceholderSentinelsFromMessages,
|
|
373
375
|
];
|
|
374
376
|
|
|
375
377
|
// Run each migration step, catching and logging individual failures so one
|
|
@@ -795,7 +795,7 @@ export async function selectedBackendSupportsMultimodal(
|
|
|
795
795
|
|
|
796
796
|
async function isOllamaConfigured(config: AssistantConfig): Promise<boolean> {
|
|
797
797
|
return (
|
|
798
|
-
config.
|
|
798
|
+
config.llm.default.provider === "ollama" ||
|
|
799
799
|
Boolean(await getProviderKeyAsync("ollama")) ||
|
|
800
800
|
Boolean(getOllamaBaseUrlEnv())
|
|
801
801
|
);
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Memory Graph — One-off backfill to compact over-long node content
|
|
3
|
+
//
|
|
4
|
+
// Scans memory_graph_nodes for entries whose `content` exceeds a length
|
|
5
|
+
// threshold and rewrites them via an LLM call constrained to the same
|
|
6
|
+
// "1-3 sentences / ~300 chars" rule the extraction prompt now enforces.
|
|
7
|
+
// Preserves all other node fields (significance, emotionalCharge, edges,
|
|
8
|
+
// triggers, image_refs). Each rewrite is logged in memory_graph_node_edits
|
|
9
|
+
// with source="manual" so it is reversible and auditable.
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
|
|
12
|
+
import { and, sql } from "drizzle-orm";
|
|
13
|
+
|
|
14
|
+
import {
|
|
15
|
+
extractToolUse,
|
|
16
|
+
getConfiguredProvider,
|
|
17
|
+
userMessage,
|
|
18
|
+
} from "../../providers/provider-send-message.js";
|
|
19
|
+
import { BackendUnavailableError } from "../../util/errors.js";
|
|
20
|
+
import { getLogger } from "../../util/logger.js";
|
|
21
|
+
import { getDb } from "../db.js";
|
|
22
|
+
import { memoryGraphNodes } from "../schema.js";
|
|
23
|
+
import { recordNodeEdit, updateNode } from "./store.js";
|
|
24
|
+
|
|
25
|
+
const log = getLogger("graph-compaction");
|
|
26
|
+
|
|
27
|
+
const COMPACTION_TOOL_SCHEMA = {
|
|
28
|
+
name: "compact_memory",
|
|
29
|
+
description: "Rewrite a memory node's content to fit the length cap",
|
|
30
|
+
input_schema: {
|
|
31
|
+
type: "object" as const,
|
|
32
|
+
properties: {
|
|
33
|
+
compacted_content: {
|
|
34
|
+
type: "string" as const,
|
|
35
|
+
description:
|
|
36
|
+
"The rewritten content — 1-3 sentences, first-person, ~300 characters or fewer",
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
required: ["compacted_content"] as const,
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const COMPACTION_SYSTEM_PROMPT = `You are compacting an over-long memory node in an AI assistant's memory graph. The original content exceeds the extraction prompt's 1-3 sentence / ~300 character cap because it was written before the cap existed. Rewrite it to fit.
|
|
44
|
+
|
|
45
|
+
## Rules
|
|
46
|
+
|
|
47
|
+
**LENGTH: 1-3 sentences. Target ~300 characters. Hard cap ~400.** No exceptions.
|
|
48
|
+
|
|
49
|
+
**Preserve:**
|
|
50
|
+
- The core fact, event, or moment being remembered
|
|
51
|
+
- First-person prose style if the original is first-person
|
|
52
|
+
- The essential emotional tone of the memory
|
|
53
|
+
|
|
54
|
+
**Drop:**
|
|
55
|
+
- Scene-setting and surrounding context
|
|
56
|
+
- Dialogue preservation (unless one short quote IS the memory)
|
|
57
|
+
- Narrative "what it meant" commentary
|
|
58
|
+
- Cataloging of every emotional nuance
|
|
59
|
+
- Image descriptions packed into prose (images live in image_refs, not content)
|
|
60
|
+
|
|
61
|
+
**Never:**
|
|
62
|
+
- Invent facts not present in the original
|
|
63
|
+
- Change the core subject or emotional valence
|
|
64
|
+
- Pad to hit a target length — shorter than 300 chars is fine if the essence is there
|
|
65
|
+
|
|
66
|
+
The node's \`emotionalCharge\` and \`significance\` fields (not shown) already carry the weight. Content stays lean.
|
|
67
|
+
|
|
68
|
+
Call the \`compact_memory\` tool with the rewritten content. No preamble.`;
|
|
69
|
+
|
|
70
|
+
export interface CompactionCandidate {
|
|
71
|
+
id: string;
|
|
72
|
+
beforeLen: number;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export interface CompactionProgress {
|
|
76
|
+
nodeId: string;
|
|
77
|
+
beforeLen: number;
|
|
78
|
+
afterLen: number;
|
|
79
|
+
action: "compacted" | "skipped" | "failed";
|
|
80
|
+
newContent?: string;
|
|
81
|
+
reason?: string;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export interface CompactionResult {
|
|
85
|
+
/** Nodes whose content exceeded the threshold (before --limit is applied). */
|
|
86
|
+
scanned: number;
|
|
87
|
+
/** Nodes actually processed (scanned ∩ limit). */
|
|
88
|
+
processed: number;
|
|
89
|
+
compacted: number;
|
|
90
|
+
skipped: number;
|
|
91
|
+
failures: number;
|
|
92
|
+
beforeChars: number;
|
|
93
|
+
afterChars: number;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export interface CompactionOptions {
|
|
97
|
+
/** Content length threshold — nodes above this get compacted. Default 400. */
|
|
98
|
+
threshold?: number;
|
|
99
|
+
/** If true, write changes. If false, only list candidates (no LLM calls). Default false. */
|
|
100
|
+
apply?: boolean;
|
|
101
|
+
/** Max nodes to process. Default: no limit. */
|
|
102
|
+
limit?: number;
|
|
103
|
+
/** Called for each node as it is processed in apply mode. */
|
|
104
|
+
onProgress?: (evt: CompactionProgress) => void;
|
|
105
|
+
/** Called once with the full candidate list (both preview and apply modes). */
|
|
106
|
+
onCandidates?: (candidates: CompactionCandidate[]) => void;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Find over-length nodes in the memory graph and (optionally) rewrite their
|
|
111
|
+
* content to fit the length cap. In preview mode (apply=false) no LLM calls
|
|
112
|
+
* are made — only the candidate list is returned.
|
|
113
|
+
*/
|
|
114
|
+
export async function compactLongMemories(
|
|
115
|
+
opts: CompactionOptions = {},
|
|
116
|
+
): Promise<CompactionResult> {
|
|
117
|
+
const threshold = opts.threshold ?? 400;
|
|
118
|
+
const apply = opts.apply ?? false;
|
|
119
|
+
|
|
120
|
+
const db = getDb();
|
|
121
|
+
const rows = db
|
|
122
|
+
.select({
|
|
123
|
+
id: memoryGraphNodes.id,
|
|
124
|
+
content: memoryGraphNodes.content,
|
|
125
|
+
})
|
|
126
|
+
.from(memoryGraphNodes)
|
|
127
|
+
.where(
|
|
128
|
+
and(
|
|
129
|
+
// Skip already-dead nodes — rewriting content on "gone" fidelity is wasted work
|
|
130
|
+
sql`${memoryGraphNodes.fidelity} != 'gone'`,
|
|
131
|
+
sql`LENGTH(${memoryGraphNodes.content}) > ${threshold}`,
|
|
132
|
+
),
|
|
133
|
+
)
|
|
134
|
+
.all();
|
|
135
|
+
|
|
136
|
+
const candidates = opts.limit != null ? rows.slice(0, opts.limit) : rows;
|
|
137
|
+
|
|
138
|
+
opts.onCandidates?.(
|
|
139
|
+
candidates.map((r) => ({ id: r.id, beforeLen: r.content.length })),
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
const result: CompactionResult = {
|
|
143
|
+
scanned: rows.length,
|
|
144
|
+
processed: candidates.length,
|
|
145
|
+
compacted: 0,
|
|
146
|
+
skipped: 0,
|
|
147
|
+
failures: 0,
|
|
148
|
+
beforeChars: candidates.reduce((sum, r) => sum + r.content.length, 0),
|
|
149
|
+
afterChars: 0,
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
if (!apply) {
|
|
153
|
+
// Preview mode: record beforeChars as afterChars (no rewrites attempted)
|
|
154
|
+
result.afterChars = result.beforeChars;
|
|
155
|
+
return result;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (candidates.length === 0) return result;
|
|
159
|
+
|
|
160
|
+
const provider = await getConfiguredProvider("memoryConsolidation");
|
|
161
|
+
if (!provider) {
|
|
162
|
+
throw new BackendUnavailableError(
|
|
163
|
+
"Provider unavailable for memory compaction",
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
for (const row of candidates) {
|
|
168
|
+
const beforeLen = row.content.length;
|
|
169
|
+
|
|
170
|
+
try {
|
|
171
|
+
const response = await provider.sendMessage(
|
|
172
|
+
[
|
|
173
|
+
userMessage(
|
|
174
|
+
`Original memory content (length: ${beforeLen} chars):\n\n${row.content}`,
|
|
175
|
+
),
|
|
176
|
+
],
|
|
177
|
+
[COMPACTION_TOOL_SCHEMA],
|
|
178
|
+
COMPACTION_SYSTEM_PROMPT,
|
|
179
|
+
{
|
|
180
|
+
config: {
|
|
181
|
+
callSite: "memoryConsolidation" as const,
|
|
182
|
+
tool_choice: {
|
|
183
|
+
type: "tool" as const,
|
|
184
|
+
name: "compact_memory",
|
|
185
|
+
},
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
);
|
|
189
|
+
|
|
190
|
+
const toolBlock = extractToolUse(response);
|
|
191
|
+
if (!toolBlock) {
|
|
192
|
+
result.failures += 1;
|
|
193
|
+
result.afterChars += beforeLen;
|
|
194
|
+
opts.onProgress?.({
|
|
195
|
+
nodeId: row.id,
|
|
196
|
+
beforeLen,
|
|
197
|
+
afterLen: beforeLen,
|
|
198
|
+
action: "failed",
|
|
199
|
+
reason: "no tool_use block in response",
|
|
200
|
+
});
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const input = toolBlock.input as { compacted_content?: string };
|
|
205
|
+
const newContent =
|
|
206
|
+
typeof input.compacted_content === "string"
|
|
207
|
+
? input.compacted_content.trim()
|
|
208
|
+
: "";
|
|
209
|
+
|
|
210
|
+
if (!newContent) {
|
|
211
|
+
result.failures += 1;
|
|
212
|
+
result.afterChars += beforeLen;
|
|
213
|
+
opts.onProgress?.({
|
|
214
|
+
nodeId: row.id,
|
|
215
|
+
beforeLen,
|
|
216
|
+
afterLen: beforeLen,
|
|
217
|
+
action: "failed",
|
|
218
|
+
reason: "empty compacted_content",
|
|
219
|
+
});
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// If the model didn't actually shrink it, skip — never overwrite with
|
|
224
|
+
// something equivalent or longer. Preserves the original when the LLM
|
|
225
|
+
// fails to compress.
|
|
226
|
+
if (newContent.length >= beforeLen) {
|
|
227
|
+
result.skipped += 1;
|
|
228
|
+
result.afterChars += beforeLen;
|
|
229
|
+
opts.onProgress?.({
|
|
230
|
+
nodeId: row.id,
|
|
231
|
+
beforeLen,
|
|
232
|
+
afterLen: newContent.length,
|
|
233
|
+
action: "skipped",
|
|
234
|
+
reason: "rewrite was not shorter than original",
|
|
235
|
+
newContent,
|
|
236
|
+
});
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// Reject rewrites that are shorter than the original but still exceed
|
|
241
|
+
// the threshold cap — the whole point of the compaction is to land
|
|
242
|
+
// under the cap, not merely to reduce length.
|
|
243
|
+
if (newContent.length > threshold) {
|
|
244
|
+
result.skipped += 1;
|
|
245
|
+
result.afterChars += beforeLen;
|
|
246
|
+
opts.onProgress?.({
|
|
247
|
+
nodeId: row.id,
|
|
248
|
+
beforeLen,
|
|
249
|
+
afterLen: newContent.length,
|
|
250
|
+
action: "skipped",
|
|
251
|
+
reason: `rewrite still exceeds threshold (${newContent.length} > ${threshold})`,
|
|
252
|
+
newContent,
|
|
253
|
+
});
|
|
254
|
+
continue;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// Wrap edit recording + node update in a transaction so they are
|
|
258
|
+
// atomic: if updateNode fails, the edit record is rolled back. Without
|
|
259
|
+
// this, a mid-operation throw leaves an orphaned audit row pointing at
|
|
260
|
+
// a change that never committed.
|
|
261
|
+
getDb().transaction(() => {
|
|
262
|
+
recordNodeEdit({
|
|
263
|
+
nodeId: row.id,
|
|
264
|
+
previousContent: row.content,
|
|
265
|
+
newContent,
|
|
266
|
+
source: "manual",
|
|
267
|
+
});
|
|
268
|
+
updateNode(row.id, {
|
|
269
|
+
content: newContent,
|
|
270
|
+
lastConsolidated: Date.now(),
|
|
271
|
+
});
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
result.compacted += 1;
|
|
275
|
+
result.afterChars += newContent.length;
|
|
276
|
+
opts.onProgress?.({
|
|
277
|
+
nodeId: row.id,
|
|
278
|
+
beforeLen,
|
|
279
|
+
afterLen: newContent.length,
|
|
280
|
+
action: "compacted",
|
|
281
|
+
newContent,
|
|
282
|
+
});
|
|
283
|
+
} catch (err) {
|
|
284
|
+
result.failures += 1;
|
|
285
|
+
result.afterChars += beforeLen;
|
|
286
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
287
|
+
log.warn({ nodeId: row.id, err: reason }, "Compaction failed for node");
|
|
288
|
+
opts.onProgress?.({
|
|
289
|
+
nodeId: row.id,
|
|
290
|
+
beforeLen,
|
|
291
|
+
afterLen: beforeLen,
|
|
292
|
+
action: "failed",
|
|
293
|
+
reason,
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
return result;
|
|
299
|
+
}
|
|
@@ -262,7 +262,7 @@ async function identifyDuplicateGroups(
|
|
|
262
262
|
): Promise<MemoryNode[][]> {
|
|
263
263
|
if (nodes.length < 2) return [];
|
|
264
264
|
|
|
265
|
-
const provider = await getConfiguredProvider();
|
|
265
|
+
const provider = await getConfiguredProvider("memoryConsolidation");
|
|
266
266
|
if (!provider) return [];
|
|
267
267
|
|
|
268
268
|
// Compact listing: ID + first 100 chars of content
|
|
@@ -282,7 +282,7 @@ async function identifyDuplicateGroups(
|
|
|
282
282
|
systemPrompt,
|
|
283
283
|
{
|
|
284
284
|
config: {
|
|
285
|
-
|
|
285
|
+
callSite: "memoryConsolidation" as const,
|
|
286
286
|
tool_choice: { type: "tool" as const, name: "report_duplicate_groups" },
|
|
287
287
|
},
|
|
288
288
|
},
|
|
@@ -428,7 +428,7 @@ async function consolidateChunk(
|
|
|
428
428
|
return true;
|
|
429
429
|
});
|
|
430
430
|
|
|
431
|
-
const provider = await getConfiguredProvider();
|
|
431
|
+
const provider = await getConfiguredProvider("memoryConsolidation");
|
|
432
432
|
if (!provider) {
|
|
433
433
|
throw new BackendUnavailableError("Provider unavailable for consolidation");
|
|
434
434
|
}
|
|
@@ -459,7 +459,7 @@ async function consolidateChunk(
|
|
|
459
459
|
systemPrompt,
|
|
460
460
|
{
|
|
461
461
|
config: {
|
|
462
|
-
|
|
462
|
+
callSite: "memoryConsolidation" as const,
|
|
463
463
|
tool_choice: { type: "tool" as const, name: "consolidate_diff" },
|
|
464
464
|
},
|
|
465
465
|
},
|