@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
|
@@ -60,7 +60,7 @@ export function buildMemoryRollup(scopeId: string): string {
|
|
|
60
60
|
and(
|
|
61
61
|
sql`${memoryGraphNodes.fidelity} != 'gone'`,
|
|
62
62
|
eq(memoryGraphNodes.scopeId, scopeId),
|
|
63
|
-
)
|
|
63
|
+
),
|
|
64
64
|
)
|
|
65
65
|
.orderBy(desc(memoryGraphNodes.significance))
|
|
66
66
|
.limit(60)
|
|
@@ -111,19 +111,21 @@ function buildNewItemsDiff(scopeId: string): string {
|
|
|
111
111
|
WHERE fidelity != 'gone' AND scope_id = ? AND created > ?
|
|
112
112
|
ORDER BY created DESC LIMIT 20`,
|
|
113
113
|
scopeId,
|
|
114
|
-
lastGenAt
|
|
114
|
+
lastGenAt,
|
|
115
115
|
);
|
|
116
116
|
|
|
117
117
|
if (newItems.length === 0) return "";
|
|
118
118
|
|
|
119
119
|
return (
|
|
120
120
|
"## New since last generation\n" +
|
|
121
|
-
newItems
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
121
|
+
newItems
|
|
122
|
+
.map((i) => {
|
|
123
|
+
const nl = i.content.indexOf("\n");
|
|
124
|
+
const subject = nl >= 0 ? i.content.slice(0, nl) : i.content;
|
|
125
|
+
const statement = nl >= 0 ? i.content.slice(nl + 1) : i.content;
|
|
126
|
+
return `- (${i.kind}) ${subject}: ${statement}`;
|
|
127
|
+
})
|
|
128
|
+
.join("\n")
|
|
127
129
|
);
|
|
128
130
|
}
|
|
129
131
|
|
|
@@ -162,7 +164,8 @@ export const CONVERSATION_STARTER_CATEGORIES = [
|
|
|
162
164
|
"integration",
|
|
163
165
|
] as const;
|
|
164
166
|
|
|
165
|
-
export type ConversationStarterCategory =
|
|
167
|
+
export type ConversationStarterCategory =
|
|
168
|
+
(typeof CONVERSATION_STARTER_CATEGORIES)[number];
|
|
166
169
|
|
|
167
170
|
interface GeneratedStarter {
|
|
168
171
|
label: string;
|
|
@@ -171,7 +174,7 @@ interface GeneratedStarter {
|
|
|
171
174
|
}
|
|
172
175
|
|
|
173
176
|
async function generateStarters(scopeId: string): Promise<GeneratedStarter[]> {
|
|
174
|
-
const provider = await getConfiguredProvider();
|
|
177
|
+
const provider = await getConfiguredProvider("conversationStarters");
|
|
175
178
|
if (!provider) {
|
|
176
179
|
log.info("No configured provider for conversation starters generation");
|
|
177
180
|
return [];
|
|
@@ -288,7 +291,7 @@ Bad → Good (incomplete phrase → complete):
|
|
|
288
291
|
const response = await provider.sendMessage(
|
|
289
292
|
[
|
|
290
293
|
userMessage(
|
|
291
|
-
"Generate personalized conversation starters based on my context."
|
|
294
|
+
"Generate personalized conversation starters based on my context.",
|
|
292
295
|
),
|
|
293
296
|
],
|
|
294
297
|
[
|
|
@@ -330,7 +333,7 @@ Bad → Good (incomplete phrase → complete):
|
|
|
330
333
|
systemPrompt,
|
|
331
334
|
{
|
|
332
335
|
config: {
|
|
333
|
-
|
|
336
|
+
callSite: "conversationStarters" as const,
|
|
334
337
|
max_tokens: 2048,
|
|
335
338
|
tool_choice: {
|
|
336
339
|
type: "tool" as const,
|
|
@@ -338,14 +341,14 @@ Bad → Good (incomplete phrase → complete):
|
|
|
338
341
|
},
|
|
339
342
|
},
|
|
340
343
|
signal,
|
|
341
|
-
}
|
|
344
|
+
},
|
|
342
345
|
);
|
|
343
346
|
cleanup();
|
|
344
347
|
|
|
345
348
|
const toolBlock = extractToolUse(response);
|
|
346
349
|
if (!toolBlock) {
|
|
347
350
|
log.warn(
|
|
348
|
-
"No tool_use block in conversation starters generation response"
|
|
351
|
+
"No tool_use block in conversation starters generation response",
|
|
349
352
|
);
|
|
350
353
|
return [];
|
|
351
354
|
}
|
|
@@ -363,7 +366,7 @@ Bad → Good (incomplete phrase → complete):
|
|
|
363
366
|
s.label.length > 0 &&
|
|
364
367
|
s.label.length <= 40 &&
|
|
365
368
|
typeof s.prompt === "string" &&
|
|
366
|
-
s.prompt.length > 0
|
|
369
|
+
s.prompt.length > 0,
|
|
367
370
|
)
|
|
368
371
|
.slice(0, 4)
|
|
369
372
|
.map((s) => ({
|
|
@@ -372,7 +375,7 @@ Bad → Good (incomplete phrase → complete):
|
|
|
372
375
|
category:
|
|
373
376
|
typeof s.category === "string" &&
|
|
374
377
|
(CONVERSATION_STARTER_CATEGORIES as readonly string[]).includes(
|
|
375
|
-
s.category
|
|
378
|
+
s.category,
|
|
376
379
|
)
|
|
377
380
|
? s.category
|
|
378
381
|
: "productivity",
|
|
@@ -386,7 +389,7 @@ Bad → Good (incomplete phrase → complete):
|
|
|
386
389
|
// ── Job handler ───────────────────────────────────────────────────
|
|
387
390
|
|
|
388
391
|
export async function generateConversationStartersJob(
|
|
389
|
-
job: MemoryJob
|
|
392
|
+
job: MemoryJob,
|
|
390
393
|
): Promise<void> {
|
|
391
394
|
const scopeId = asString(job.payload.scopeId) ?? "default";
|
|
392
395
|
|
|
@@ -419,7 +422,7 @@ export async function generateConversationStartersJob(
|
|
|
419
422
|
and(
|
|
420
423
|
sql`${memoryGraphNodes.fidelity} != 'gone'`,
|
|
421
424
|
eq(memoryGraphNodes.scopeId, scopeId),
|
|
422
|
-
)
|
|
425
|
+
),
|
|
423
426
|
)
|
|
424
427
|
.groupBy(memoryGraphNodes.type)
|
|
425
428
|
.all();
|
|
@@ -453,7 +456,7 @@ export async function generateConversationStartersJob(
|
|
|
453
456
|
// Count active items for checkpoint
|
|
454
457
|
const countRow = rawGet<{ c: number }>(
|
|
455
458
|
`SELECT COUNT(*) AS c FROM memory_graph_nodes WHERE fidelity != 'gone' AND scope_id = ?`,
|
|
456
|
-
scopeId
|
|
459
|
+
scopeId,
|
|
457
460
|
);
|
|
458
461
|
const totalActive = countRow?.c ?? 0;
|
|
459
462
|
|
|
@@ -474,6 +477,6 @@ export async function generateConversationStartersJob(
|
|
|
474
477
|
|
|
475
478
|
log.info(
|
|
476
479
|
{ scopeId, batch: nextBatch, count: starters.length },
|
|
477
|
-
"Generated conversation starters"
|
|
480
|
+
"Generated conversation starters",
|
|
478
481
|
);
|
|
479
482
|
}
|
|
@@ -161,7 +161,7 @@ async function summarizeWithLLM(
|
|
|
161
161
|
return buildFallbackSummary(existingSummary, newContent, label);
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
-
const provider = await getConfiguredProvider();
|
|
164
|
+
const provider = await getConfiguredProvider("conversationSummarization");
|
|
165
165
|
if (!provider) {
|
|
166
166
|
log.debug(
|
|
167
167
|
{ label },
|
|
@@ -189,7 +189,7 @@ async function summarizeWithLLM(
|
|
|
189
189
|
systemPrompt,
|
|
190
190
|
{
|
|
191
191
|
config: {
|
|
192
|
-
|
|
192
|
+
callSite: "conversationSummarization" as const,
|
|
193
193
|
max_tokens: SUMMARY_MAX_TOKENS,
|
|
194
194
|
},
|
|
195
195
|
signal,
|
package/src/memory/job-utils.ts
CHANGED
|
@@ -147,7 +147,13 @@ export function truncate(text: string, max: number): string {
|
|
|
147
147
|
|
|
148
148
|
export async function embedAndUpsert(
|
|
149
149
|
config: AssistantConfig,
|
|
150
|
-
targetType:
|
|
150
|
+
targetType:
|
|
151
|
+
| "segment"
|
|
152
|
+
| "item"
|
|
153
|
+
| "summary"
|
|
154
|
+
| "media"
|
|
155
|
+
| "graph_node"
|
|
156
|
+
| "pkb_file",
|
|
151
157
|
targetId: string,
|
|
152
158
|
input: EmbeddingInput,
|
|
153
159
|
extraPayload?: Record<string, unknown>,
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { beforeAll, beforeEach, describe, expect, mock, test } from "bun:test";
|
|
2
|
+
|
|
3
|
+
mock.module("../../util/logger.js", () => ({
|
|
4
|
+
getLogger: () =>
|
|
5
|
+
new Proxy({} as Record<string, unknown>, {
|
|
6
|
+
get: () => () => {},
|
|
7
|
+
}),
|
|
8
|
+
}));
|
|
9
|
+
|
|
10
|
+
// Track calls to indexPkbFile so we can assert the handler forwards payload
|
|
11
|
+
// fields correctly.
|
|
12
|
+
const indexPkbFileCalls: Array<{
|
|
13
|
+
pkbRoot: string;
|
|
14
|
+
absPath: string;
|
|
15
|
+
memoryScopeId: string;
|
|
16
|
+
}> = [];
|
|
17
|
+
|
|
18
|
+
mock.module("../pkb/pkb-index.js", () => ({
|
|
19
|
+
indexPkbFile: async (
|
|
20
|
+
pkbRoot: string,
|
|
21
|
+
absPath: string,
|
|
22
|
+
memoryScopeId: string,
|
|
23
|
+
) => {
|
|
24
|
+
indexPkbFileCalls.push({ pkbRoot, absPath, memoryScopeId });
|
|
25
|
+
},
|
|
26
|
+
}));
|
|
27
|
+
|
|
28
|
+
mock.module("../../config/loader.js", () => ({
|
|
29
|
+
loadConfig: () => ({}),
|
|
30
|
+
getConfig: () => ({}),
|
|
31
|
+
invalidateConfigCache: () => {},
|
|
32
|
+
}));
|
|
33
|
+
|
|
34
|
+
import { DEFAULT_CONFIG } from "../../config/defaults.js";
|
|
35
|
+
import type { AssistantConfig } from "../../config/types.js";
|
|
36
|
+
import { getDb, initializeDb } from "../db.js";
|
|
37
|
+
import {
|
|
38
|
+
claimMemoryJobs,
|
|
39
|
+
type MemoryJob,
|
|
40
|
+
type MemoryJobType,
|
|
41
|
+
} from "../jobs-store.js";
|
|
42
|
+
import { memoryJobs } from "../schema.js";
|
|
43
|
+
import { embedPkbFileJob, enqueuePkbIndexJob } from "./embed-pkb-file.js";
|
|
44
|
+
|
|
45
|
+
const TEST_CONFIG: AssistantConfig = DEFAULT_CONFIG;
|
|
46
|
+
|
|
47
|
+
function makeJob(payload: Record<string, unknown>): MemoryJob {
|
|
48
|
+
return {
|
|
49
|
+
id: "job-1",
|
|
50
|
+
type: "embed_pkb_file",
|
|
51
|
+
payload,
|
|
52
|
+
status: "running",
|
|
53
|
+
attempts: 0,
|
|
54
|
+
deferrals: 0,
|
|
55
|
+
runAfter: 0,
|
|
56
|
+
lastError: null,
|
|
57
|
+
startedAt: Date.now(),
|
|
58
|
+
createdAt: Date.now(),
|
|
59
|
+
updatedAt: Date.now(),
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
describe("embedPkbFileJob", () => {
|
|
64
|
+
beforeAll(() => {
|
|
65
|
+
initializeDb();
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
beforeEach(() => {
|
|
69
|
+
indexPkbFileCalls.length = 0;
|
|
70
|
+
const db = getDb();
|
|
71
|
+
db.delete(memoryJobs).run();
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
test("calls indexPkbFile with payload fields", async () => {
|
|
75
|
+
await embedPkbFileJob(
|
|
76
|
+
makeJob({
|
|
77
|
+
pkbRoot: "/pkb/root",
|
|
78
|
+
absPath: "/pkb/root/note.md",
|
|
79
|
+
memoryScopeId: "scope-123",
|
|
80
|
+
}),
|
|
81
|
+
TEST_CONFIG,
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
expect(indexPkbFileCalls).toHaveLength(1);
|
|
85
|
+
expect(indexPkbFileCalls[0]).toEqual({
|
|
86
|
+
pkbRoot: "/pkb/root",
|
|
87
|
+
absPath: "/pkb/root/note.md",
|
|
88
|
+
memoryScopeId: "scope-123",
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
test("skips when pkbRoot is missing", async () => {
|
|
93
|
+
await embedPkbFileJob(
|
|
94
|
+
makeJob({ absPath: "/pkb/root/note.md", memoryScopeId: "scope-123" }),
|
|
95
|
+
TEST_CONFIG,
|
|
96
|
+
);
|
|
97
|
+
expect(indexPkbFileCalls).toHaveLength(0);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
test("skips when absPath is missing", async () => {
|
|
101
|
+
await embedPkbFileJob(
|
|
102
|
+
makeJob({ pkbRoot: "/pkb/root", memoryScopeId: "scope-123" }),
|
|
103
|
+
TEST_CONFIG,
|
|
104
|
+
);
|
|
105
|
+
expect(indexPkbFileCalls).toHaveLength(0);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
test("skips when memoryScopeId is missing", async () => {
|
|
109
|
+
await embedPkbFileJob(
|
|
110
|
+
makeJob({ pkbRoot: "/pkb/root", absPath: "/pkb/root/note.md" }),
|
|
111
|
+
TEST_CONFIG,
|
|
112
|
+
);
|
|
113
|
+
expect(indexPkbFileCalls).toHaveLength(0);
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
describe("enqueuePkbIndexJob", () => {
|
|
118
|
+
beforeAll(() => {
|
|
119
|
+
initializeDb();
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
beforeEach(() => {
|
|
123
|
+
indexPkbFileCalls.length = 0;
|
|
124
|
+
const db = getDb();
|
|
125
|
+
db.delete(memoryJobs).run();
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
test("enqueues a pending embed_pkb_file job with payload", () => {
|
|
129
|
+
const id = enqueuePkbIndexJob({
|
|
130
|
+
pkbRoot: "/pkb/root",
|
|
131
|
+
absPath: "/pkb/root/note.md",
|
|
132
|
+
memoryScopeId: "scope-abc",
|
|
133
|
+
});
|
|
134
|
+
expect(id).toBeTruthy();
|
|
135
|
+
|
|
136
|
+
const claimed = claimMemoryJobs(10);
|
|
137
|
+
expect(claimed).toHaveLength(1);
|
|
138
|
+
const [job] = claimed;
|
|
139
|
+
const expectedType: MemoryJobType = "embed_pkb_file";
|
|
140
|
+
expect(job.type).toBe(expectedType);
|
|
141
|
+
expect(job.payload).toEqual({
|
|
142
|
+
pkbRoot: "/pkb/root",
|
|
143
|
+
absPath: "/pkb/root/note.md",
|
|
144
|
+
memoryScopeId: "scope-abc",
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
test("round-trip: enqueued job dispatched to handler invokes indexPkbFile", async () => {
|
|
149
|
+
enqueuePkbIndexJob({
|
|
150
|
+
pkbRoot: "/pkb/root",
|
|
151
|
+
absPath: "/pkb/root/note.md",
|
|
152
|
+
memoryScopeId: "scope-rt",
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
const claimed = claimMemoryJobs(10);
|
|
156
|
+
expect(claimed).toHaveLength(1);
|
|
157
|
+
const [job] = claimed;
|
|
158
|
+
expect(job.type).toBe("embed_pkb_file");
|
|
159
|
+
|
|
160
|
+
await embedPkbFileJob(job, TEST_CONFIG);
|
|
161
|
+
expect(indexPkbFileCalls).toHaveLength(1);
|
|
162
|
+
expect(indexPkbFileCalls[0]).toEqual({
|
|
163
|
+
pkbRoot: "/pkb/root",
|
|
164
|
+
absPath: "/pkb/root/note.md",
|
|
165
|
+
memoryScopeId: "scope-rt",
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { AssistantConfig } from "../../config/types.js";
|
|
2
|
+
import { asString } from "../job-utils.js";
|
|
3
|
+
import { enqueueMemoryJob, type MemoryJob } from "../jobs-store.js";
|
|
4
|
+
import { indexPkbFile } from "../pkb/pkb-index.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Input shape for the `embed_pkb_file` background job.
|
|
8
|
+
*/
|
|
9
|
+
export interface EmbedPkbFileJobInput {
|
|
10
|
+
pkbRoot: string;
|
|
11
|
+
absPath: string;
|
|
12
|
+
memoryScopeId: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Job handler: read a PKB markdown file, chunk it, and upsert each chunk to
|
|
17
|
+
* Qdrant via the shared embedding pipeline. Thin wrapper around
|
|
18
|
+
* {@link indexPkbFile} so write hooks and startup reconciliation can
|
|
19
|
+
* fire-and-forget into the async job queue.
|
|
20
|
+
*/
|
|
21
|
+
export async function embedPkbFileJob(
|
|
22
|
+
job: MemoryJob,
|
|
23
|
+
_config: AssistantConfig,
|
|
24
|
+
): Promise<void> {
|
|
25
|
+
const pkbRoot = asString(job.payload.pkbRoot);
|
|
26
|
+
const absPath = asString(job.payload.absPath);
|
|
27
|
+
const memoryScopeId = asString(job.payload.memoryScopeId);
|
|
28
|
+
if (!pkbRoot || !absPath || !memoryScopeId) return;
|
|
29
|
+
|
|
30
|
+
try {
|
|
31
|
+
await indexPkbFile(pkbRoot, absPath, memoryScopeId);
|
|
32
|
+
} catch (error) {
|
|
33
|
+
if (
|
|
34
|
+
error !== null &&
|
|
35
|
+
typeof error === "object" &&
|
|
36
|
+
"code" in error &&
|
|
37
|
+
(error as { code?: unknown }).code === "ENOENT"
|
|
38
|
+
) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
throw error;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Enqueue an `embed_pkb_file` job (async, fire-and-forget).
|
|
47
|
+
*/
|
|
48
|
+
export function enqueuePkbIndexJob(input: EmbedPkbFileJobInput): string {
|
|
49
|
+
return enqueueMemoryJob("embed_pkb_file", {
|
|
50
|
+
pkbRoot: input.pkbRoot,
|
|
51
|
+
absPath: input.absPath,
|
|
52
|
+
memoryScopeId: input.memoryScopeId,
|
|
53
|
+
});
|
|
54
|
+
}
|
package/src/memory/jobs-store.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { and, asc, eq, inArray, lte, notInArray, sql } from "drizzle-orm";
|
|
1
|
+
import { and, asc, eq, inArray, lte, notInArray, or, sql } from "drizzle-orm";
|
|
2
2
|
import { v4 as uuid } from "uuid";
|
|
3
3
|
|
|
4
4
|
import { getLogger } from "../util/logger.js";
|
|
@@ -27,6 +27,7 @@ export type MemoryJobType =
|
|
|
27
27
|
| "embed_attachment"
|
|
28
28
|
| "generate_conversation_starters"
|
|
29
29
|
| "embed_graph_node"
|
|
30
|
+
| "embed_pkb_file"
|
|
30
31
|
| "graph_extract"
|
|
31
32
|
| "graph_decay"
|
|
32
33
|
| "graph_consolidate"
|
|
@@ -41,6 +42,7 @@ const EMBED_JOB_TYPES: MemoryJobType[] = [
|
|
|
41
42
|
"embed_media",
|
|
42
43
|
"embed_attachment",
|
|
43
44
|
"embed_graph_node",
|
|
45
|
+
"embed_pkb_file",
|
|
44
46
|
"graph_trigger_embed",
|
|
45
47
|
];
|
|
46
48
|
|
|
@@ -165,6 +167,10 @@ export function upsertAutoAnalysisJob(
|
|
|
165
167
|
: never,
|
|
166
168
|
): void {
|
|
167
169
|
const db = dbOverride ?? getDb();
|
|
170
|
+
// Match rows with the same triggerGroup OR legacy rows without triggerGroup
|
|
171
|
+
// (from older builds that used upsertDebouncedJob before triggerGroup was
|
|
172
|
+
// introduced). Without the IS NULL fallback, the next enqueue would insert
|
|
173
|
+
// a duplicate pending row for the same conversation.
|
|
168
174
|
const existing = db
|
|
169
175
|
.select()
|
|
170
176
|
.from(memoryJobs)
|
|
@@ -173,18 +179,53 @@ export function upsertAutoAnalysisJob(
|
|
|
173
179
|
eq(memoryJobs.type, "conversation_analyze"),
|
|
174
180
|
eq(memoryJobs.status, "pending"),
|
|
175
181
|
sql`json_extract(${memoryJobs.payload}, '$.conversationId') = ${payload.conversationId}`,
|
|
176
|
-
|
|
182
|
+
or(
|
|
183
|
+
sql`json_extract(${memoryJobs.payload}, '$.triggerGroup') = ${payload.triggerGroup}`,
|
|
184
|
+
sql`json_extract(${memoryJobs.payload}, '$.triggerGroup') IS NULL`,
|
|
185
|
+
),
|
|
177
186
|
),
|
|
178
187
|
)
|
|
179
188
|
.get();
|
|
180
189
|
if (existing) {
|
|
190
|
+
// Merge triggerGroup into legacy rows so subsequent lookups use the new key.
|
|
191
|
+
const existingPayload = JSON.parse(existing.payload) as Record<
|
|
192
|
+
string,
|
|
193
|
+
unknown
|
|
194
|
+
>;
|
|
195
|
+
const needsPayloadUpdate = !existingPayload.triggerGroup;
|
|
181
196
|
db.update(memoryJobs)
|
|
182
|
-
.set({
|
|
197
|
+
.set({
|
|
198
|
+
runAfter,
|
|
199
|
+
updatedAt: Date.now(),
|
|
200
|
+
...(needsPayloadUpdate
|
|
201
|
+
? {
|
|
202
|
+
payload: JSON.stringify({ ...existingPayload, ...payload }),
|
|
203
|
+
}
|
|
204
|
+
: {}),
|
|
205
|
+
})
|
|
183
206
|
.where(eq(memoryJobs.id, existing.id))
|
|
184
207
|
.run();
|
|
185
208
|
} else {
|
|
186
209
|
enqueueMemoryJob("conversation_analyze", payload, runAfter, dbOverride);
|
|
187
210
|
}
|
|
211
|
+
|
|
212
|
+
// When an immediate trigger fires (batch/compaction), cancel any pending
|
|
213
|
+
// debounced row for the same conversation — the immediate analysis covers
|
|
214
|
+
// those messages, making the debounced pass redundant. Without this, both
|
|
215
|
+
// rows fire independently and double the LLM cost per batch crossing.
|
|
216
|
+
if (payload.triggerGroup === "immediate") {
|
|
217
|
+
db.update(memoryJobs)
|
|
218
|
+
.set({ status: "completed", updatedAt: Date.now() })
|
|
219
|
+
.where(
|
|
220
|
+
and(
|
|
221
|
+
eq(memoryJobs.type, "conversation_analyze"),
|
|
222
|
+
eq(memoryJobs.status, "pending"),
|
|
223
|
+
sql`json_extract(${memoryJobs.payload}, '$.conversationId') = ${payload.conversationId}`,
|
|
224
|
+
sql`json_extract(${memoryJobs.payload}, '$.triggerGroup') = 'debounced'`,
|
|
225
|
+
),
|
|
226
|
+
)
|
|
227
|
+
.run();
|
|
228
|
+
}
|
|
188
229
|
}
|
|
189
230
|
|
|
190
231
|
/**
|
|
@@ -44,6 +44,7 @@ import {
|
|
|
44
44
|
RETRY_MAX_ATTEMPTS,
|
|
45
45
|
retryDelayForAttempt,
|
|
46
46
|
} from "./job-utils.js";
|
|
47
|
+
import { embedPkbFileJob } from "./jobs/embed-pkb-file.js";
|
|
47
48
|
import {
|
|
48
49
|
claimMemoryJobs,
|
|
49
50
|
completeMemoryJob,
|
|
@@ -420,6 +421,9 @@ async function processJob(
|
|
|
420
421
|
case "embed_graph_node":
|
|
421
422
|
await embedGraphNodeJob(job, config);
|
|
422
423
|
return;
|
|
424
|
+
case "embed_pkb_file":
|
|
425
|
+
await embedPkbFileJob(job, config);
|
|
426
|
+
return;
|
|
423
427
|
case "graph_trigger_embed":
|
|
424
428
|
await embedGraphTriggerJob(job, config);
|
|
425
429
|
return;
|
|
@@ -196,7 +196,7 @@ export function migrateBackfillUsageCacheAccounting(database: DrizzleDb): void {
|
|
|
196
196
|
const requestLogsByConversation = buildRequestLogMap(requestLogRows);
|
|
197
197
|
const requestOffsets = new Map<string, number>();
|
|
198
198
|
const previousUsageEventCreatedAt = new Map<string, number>();
|
|
199
|
-
const pricingOverrides = getConfig().pricingOverrides;
|
|
199
|
+
const pricingOverrides = getConfig().llm.pricingOverrides;
|
|
200
200
|
|
|
201
201
|
let scannedAnthropicRows = 0;
|
|
202
202
|
let updatedRows = 0;
|
|
@@ -63,8 +63,8 @@ export function isAutoIncrementedUserFile(
|
|
|
63
63
|
* Multiple contact rows may represent the same principal (one per channel:
|
|
64
64
|
* desktop, phone, Slack, etc.). When a new row was created for a second
|
|
65
65
|
* channel, `generateUserFileSlug(displayName)` auto-incremented to avoid a
|
|
66
|
-
* filename collision (e.g. `
|
|
67
|
-
* `
|
|
66
|
+
* filename collision (e.g. `alice.md` → `alice-2.md`), even though no
|
|
67
|
+
* `alice-2.md` file ever existed on disk. The persona resolver then silently
|
|
68
68
|
* fell back to `users/default.md` for that channel's messages — and the same
|
|
69
69
|
* slug is used for the journal directory, so the user lost per-principal
|
|
70
70
|
* continuity on every non-primary channel.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { isPlaceholderSentinelText } from "../../providers/anthropic/client.js";
|
|
2
|
+
import type { DrizzleDb } from "../db-connection.js";
|
|
3
|
+
import { getSqliteFrom } from "../db-connection.js";
|
|
4
|
+
import { withCrashRecovery } from "./validate-migration-state.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Strip Anthropic provider placeholder sentinel text blocks from persisted
|
|
8
|
+
* assistant messages.
|
|
9
|
+
*
|
|
10
|
+
* PLACEHOLDER_EMPTY_TURN and PLACEHOLDER_BLOCKS_OMITTED are injected into
|
|
11
|
+
* outbound Anthropic request bodies to preserve role alternation when an
|
|
12
|
+
* assistant turn would otherwise be empty. They are never supposed to be
|
|
13
|
+
* persisted, but a leak path caused them to be stored in the messages table
|
|
14
|
+
* where they render in chat bubbles as bold "PLACEHOLDER[...]" (markdown
|
|
15
|
+
* interprets the double-underscore surround as bold).
|
|
16
|
+
*
|
|
17
|
+
* This migration walks every assistant message, parses its content blocks,
|
|
18
|
+
* and drops text blocks whose text matches either sentinel (with or without
|
|
19
|
+
* the null-byte prefix, to cover rows that round-tripped through tools that
|
|
20
|
+
* stripped null bytes). If stripping leaves the message empty, stores [].
|
|
21
|
+
*
|
|
22
|
+
* Idempotent — safe to re-run.
|
|
23
|
+
*/
|
|
24
|
+
export function migrateStripPlaceholderSentinelsFromMessages(
|
|
25
|
+
database: DrizzleDb,
|
|
26
|
+
): void {
|
|
27
|
+
withCrashRecovery(
|
|
28
|
+
database,
|
|
29
|
+
"migration_strip_placeholder_sentinels_from_messages_v1",
|
|
30
|
+
() => {
|
|
31
|
+
const raw = getSqliteFrom(database);
|
|
32
|
+
|
|
33
|
+
const BATCH_SIZE = 100;
|
|
34
|
+
let lastRowid = 0;
|
|
35
|
+
|
|
36
|
+
for (;;) {
|
|
37
|
+
const rows = raw
|
|
38
|
+
.query(
|
|
39
|
+
`SELECT rowid, id, content FROM messages
|
|
40
|
+
WHERE role = 'assistant'
|
|
41
|
+
AND content LIKE '%__PLACEHOLDER__%'
|
|
42
|
+
AND rowid > ?
|
|
43
|
+
ORDER BY rowid
|
|
44
|
+
LIMIT ?`,
|
|
45
|
+
)
|
|
46
|
+
.all(lastRowid, BATCH_SIZE) as Array<{
|
|
47
|
+
rowid: number;
|
|
48
|
+
id: string;
|
|
49
|
+
content: string;
|
|
50
|
+
}>;
|
|
51
|
+
|
|
52
|
+
if (rows.length === 0) break;
|
|
53
|
+
|
|
54
|
+
for (const row of rows) {
|
|
55
|
+
lastRowid = row.rowid;
|
|
56
|
+
|
|
57
|
+
let blocks: Array<Record<string, unknown>>;
|
|
58
|
+
try {
|
|
59
|
+
const parsed = JSON.parse(row.content);
|
|
60
|
+
if (!Array.isArray(parsed)) continue;
|
|
61
|
+
blocks = parsed;
|
|
62
|
+
} catch {
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const stripped = blocks.filter((b) => {
|
|
67
|
+
if (typeof b !== "object" || b === null) return false;
|
|
68
|
+
if (b.type !== "text") return true;
|
|
69
|
+
const text = typeof b.text === "string" ? b.text : "";
|
|
70
|
+
return !isPlaceholderSentinelText(text);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
if (stripped.length === blocks.length) continue;
|
|
74
|
+
|
|
75
|
+
raw
|
|
76
|
+
.query(`UPDATE messages SET content = ? WHERE id = ?`)
|
|
77
|
+
.run(JSON.stringify(stripped), row.id);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
);
|
|
82
|
+
}
|
|
@@ -166,6 +166,7 @@ export {
|
|
|
166
166
|
migrateNormalizeUserFileByPrincipal,
|
|
167
167
|
} from "./220-normalize-user-file-by-principal.js";
|
|
168
168
|
export { migrateConversationsArchivedAt } from "./221-conversations-archived-at.js";
|
|
169
|
+
export { migrateStripPlaceholderSentinelsFromMessages } from "./222-strip-placeholder-sentinels-from-messages.js";
|
|
169
170
|
export {
|
|
170
171
|
MIGRATION_REGISTRY,
|
|
171
172
|
type MigrationRegistryEntry,
|