@vellumai/assistant 0.8.3 → 0.8.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +2 -2
- package/docker-entrypoint.sh +0 -1
- package/docs/browser-use-architecture-phase2.md +1 -1
- package/knip.json +2 -1
- package/node_modules/@vellumai/gateway-client/src/types.ts +2 -0
- package/openapi.yaml +1492 -100
- package/package.json +1 -1
- package/src/__tests__/agent-loop-exit-reason.test.ts +4 -5
- package/src/__tests__/agent-loop-override-profile.test.ts +1 -1
- package/src/__tests__/agent-loop.test.ts +88 -3
- package/src/__tests__/anthropic-provider.test.ts +302 -33
- package/src/__tests__/approval-cascade.test.ts +1 -1
- package/src/__tests__/assistant-event-hub-self-exclusion.test.ts +293 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +3 -3
- package/src/__tests__/audit-log-rotation.test.ts +70 -16
- package/src/__tests__/background-workers-disk-pressure.test.ts +4 -3
- package/src/__tests__/btw-routes.test.ts +2 -3
- package/src/__tests__/call-controller.test.ts +0 -1
- package/src/__tests__/cancel-resolves-conversation-key.test.ts +1 -1
- package/src/__tests__/channel-delivery-store.test.ts +193 -0
- package/src/__tests__/channel-guardian.test.ts +3 -3
- package/src/__tests__/channel-reply-delivery.test.ts +284 -5
- package/src/__tests__/channel-retry-sweep.test.ts +274 -1
- package/src/__tests__/checker.test.ts +6 -15
- package/src/__tests__/compaction-events.test.ts +2 -1
- package/src/__tests__/compactor-call-site-logging.test.ts +214 -0
- package/src/__tests__/compactor-preserved-tail-count.test.ts +110 -0
- package/src/__tests__/computer-use-skill-manifest-regression.test.ts +5 -11
- package/src/__tests__/computer-use-tools.test.ts +2 -4
- package/src/__tests__/config-watcher.test.ts +1 -1
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -1
- package/src/__tests__/context-token-estimator.test.ts +91 -1
- package/src/__tests__/conversation-abort-tool-results.test.ts +1 -1
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +1 -1
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +55 -4
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +228 -8
- package/src/__tests__/conversation-agent-loop.test.ts +188 -129
- package/src/__tests__/conversation-app-control-instantiation.test.ts +2 -5
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +1 -1
- package/src/__tests__/conversation-clean-command.test.ts +137 -0
- package/src/__tests__/conversation-clear-safety.test.ts +25 -25
- package/src/__tests__/conversation-confirmation-signals.test.ts +1 -1
- package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +1 -1
- package/src/__tests__/conversation-disk-view-integration.test.ts +2 -2
- package/src/__tests__/conversation-error.test.ts +31 -0
- package/src/__tests__/conversation-fork-crud.test.ts +324 -0
- package/src/__tests__/conversation-lifecycle.test.ts +53 -12
- package/src/__tests__/conversation-load-history-repair.test.ts +1 -1
- package/src/__tests__/conversation-load-history-stripped.test.ts +279 -0
- package/src/__tests__/conversation-pairing.test.ts +2 -2
- package/src/__tests__/conversation-process-callsite.test.ts +1 -1
- package/src/__tests__/conversation-provider-retry-repair.test.ts +2 -1
- package/src/__tests__/conversation-queue.test.ts +1 -1
- package/src/__tests__/conversation-routes-disk-view.test.ts +109 -0
- package/src/__tests__/conversation-routes-slash-commands.test.ts +35 -0
- package/src/__tests__/conversation-runtime-assembly.test.ts +264 -81
- package/src/__tests__/conversation-seed-composer.test.ts +66 -4
- package/src/__tests__/conversation-skill-tools.test.ts +2 -5
- package/src/__tests__/conversation-slash-commands.test.ts +36 -8
- package/src/__tests__/conversation-slash-queue.test.ts +1 -1
- package/src/__tests__/conversation-slash-unknown.test.ts +1 -1
- package/src/__tests__/conversation-speed-override.test.ts +1 -1
- package/src/__tests__/conversation-store.test.ts +1 -1
- package/src/__tests__/conversation-surfaces-task-progress.test.ts +220 -0
- package/src/__tests__/conversation-sync-tags.test.ts +99 -32
- package/src/__tests__/conversation-workspace-cache-state.test.ts +2 -1
- package/src/__tests__/conversation-workspace-injection.test.ts +5 -1
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +5 -1
- package/src/__tests__/credential-execution-feature-gates.test.ts +9 -7
- package/src/__tests__/credential-execution-tools.test.ts +6 -6
- package/src/__tests__/credential-security-invariants.test.ts +7 -0
- package/src/__tests__/credential-vault-unit.test.ts +2 -2
- package/src/__tests__/cu-unified-flow.test.ts +10 -1
- package/src/__tests__/dm-backfill.test.ts +64 -0
- package/src/__tests__/dm-persistence.test.ts +33 -0
- package/src/__tests__/document-find-replace.test.ts +501 -0
- package/src/__tests__/dynamic-page-surface.test.ts +2 -2
- package/src/__tests__/email-html-renderer.test.ts +12 -0
- package/src/__tests__/first-greeting.test.ts +23 -2
- package/src/__tests__/gateway-flag-listener.test.ts +237 -0
- package/src/__tests__/gemini-provider.test.ts +78 -0
- package/src/__tests__/guardian-dispatch.test.ts +0 -1
- package/src/__tests__/guardian-outbound-http.test.ts +7 -5
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +1 -1
- package/src/__tests__/headless-browser-navigate.test.ts +172 -0
- package/src/__tests__/heartbeat-disk-pressure.test.ts +4 -0
- package/src/__tests__/heartbeat-service.test.ts +4 -0
- package/src/__tests__/host-bash-proxy.test.ts +6 -0
- package/src/__tests__/host-browser-proxy.test.ts +10 -0
- package/src/__tests__/host-cu-proxy.test.ts +8 -1
- package/src/__tests__/host-file-proxy.test.ts +8 -1
- package/src/__tests__/host-shell-tool.test.ts +1 -1
- package/src/__tests__/host-transfer-proxy.test.ts +8 -1
- package/src/__tests__/identity-routes.test.ts +57 -0
- package/src/__tests__/inbound-slack-persistence.test.ts +3 -0
- package/src/__tests__/init-feature-flag-overrides.test.ts +5 -6
- package/src/__tests__/injector-chain.test.ts +2 -0
- package/src/__tests__/injector-document-comments.test.ts +378 -0
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +4 -25
- package/src/__tests__/list-messages-attachments.test.ts +21 -17
- package/src/__tests__/list-messages-hidden-metadata.test.ts +217 -0
- package/src/__tests__/list-messages-page-latest.test.ts +130 -14
- package/src/__tests__/list-messages-tool-merge.test.ts +77 -17
- package/src/__tests__/llm-context-normalization.test.ts +0 -2
- package/src/__tests__/llm-request-log-call-site.test.ts +136 -0
- package/src/__tests__/llm-request-log-source-clickhouse.test.ts +26 -0
- package/src/__tests__/llm-resolver.test.ts +161 -9
- package/src/__tests__/llm-usage-store.test.ts +66 -0
- package/src/__tests__/log-export-routes.test.ts +99 -2
- package/src/__tests__/logger.test.ts +89 -0
- package/src/__tests__/mcp-abort-signal.test.ts +2 -2
- package/src/__tests__/media-generate-image.test.ts +31 -0
- package/src/__tests__/memory-v2-static-injector.test.ts +7 -7
- package/src/__tests__/message-queue-steer.test.ts +114 -0
- package/src/__tests__/model-intents.test.ts +2 -4
- package/src/__tests__/notification-guardian-path.test.ts +0 -1
- package/src/__tests__/onboarding-template-contract.test.ts +1 -1
- package/src/__tests__/openai-provider.test.ts +151 -0
- package/src/__tests__/openai-responses-provider.test.ts +118 -16
- package/src/__tests__/outbound-slack-persistence.test.ts +187 -20
- package/src/__tests__/pending-interactions-resolved-event.test.ts +189 -0
- package/src/__tests__/platform-bash-auto-approve.test.ts +2 -2
- package/src/__tests__/platform.test.ts +2 -5
- package/src/__tests__/plugin-api-tool-definition.test.ts +92 -0
- package/src/__tests__/plugin-bootstrap.test.ts +2 -2
- package/src/__tests__/plugin-source-watcher.test.ts +302 -0
- package/src/__tests__/plugin-tool-contribution.test.ts +13 -6
- package/src/__tests__/plugin-types.test.ts +3 -2
- package/src/__tests__/prechat-onboarding-contract.test.ts +131 -98
- package/src/__tests__/pricing.test.ts +12 -0
- package/src/__tests__/process-message-background-slack.test.ts +1 -51
- package/src/__tests__/process-message-display-content.test.ts +21 -16
- package/src/__tests__/prune-jobs-changes-parser.test.ts +61 -0
- package/src/__tests__/registry.test.ts +2 -8
- package/src/__tests__/require-fresh-approval.test.ts +2 -2
- package/src/__tests__/runtime-events-sse-bilingual.test.ts +154 -0
- package/src/__tests__/server-history-render.test.ts +83 -4
- package/src/__tests__/shell-tool-proxy-mode.test.ts +1 -1
- package/src/__tests__/skill-feature-flags.test.ts +2 -2
- package/src/__tests__/skill-projection-feature-flag.test.ts +4 -7
- package/src/__tests__/skill-projection.benchmark.test.ts +2 -6
- package/src/__tests__/skill-tool-factory.test.ts +1 -1
- package/src/__tests__/steer-tool-repair.test.ts +249 -0
- package/src/__tests__/subagent-notify-parent.test.ts +1 -1
- package/src/__tests__/suggestion-routes.test.ts +1 -0
- package/src/__tests__/sync-message-contract.test.ts +59 -0
- package/src/__tests__/system-prompt.test.ts +161 -124
- package/src/__tests__/terminal-tools.test.ts +12 -2
- package/src/__tests__/thinking-block-replay.test.ts +113 -0
- package/src/__tests__/thread-backfill.test.ts +370 -22
- package/src/__tests__/tool-approval-handler.test.ts +1 -5
- package/src/__tests__/tool-execute-pipeline.test.ts +2 -2
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +2 -5
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +15 -5
- package/src/__tests__/tool-executor.test.ts +89 -53
- package/src/__tests__/tool-grant-request-escalation.test.ts +1 -6
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +167 -0
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +1 -6
- package/src/__tests__/trusted-contact-multichannel.test.ts +0 -1
- package/src/__tests__/twilio-routes.test.ts +1 -1
- package/src/__tests__/ui-file-upload-surface.test.ts +2 -2
- package/src/__tests__/usage-routes.test.ts +3 -0
- package/src/__tests__/verification-control-plane-policy.test.ts +2 -2
- package/src/__tests__/web-fetch.test.ts +2 -2
- package/src/__tests__/workspace-git-service.test.ts +94 -10
- package/src/__tests__/workspace-migration-088-deprecate-background-conversation-override.test.ts +158 -0
- package/src/__tests__/workspace-migration-089-move-memory-tree-out-of-v3.test.ts +86 -0
- package/src/acp/__tests__/prepare-agent-env.test.ts +146 -0
- package/src/acp/prepare-agent-env.ts +78 -0
- package/src/acp/session-manager.ts +1 -1
- package/src/agent/attachments.ts +1 -0
- package/src/agent/loop.ts +65 -20
- package/src/api/README.md +5 -0
- package/src/api/index.ts +4 -0
- package/src/api/package.json +10 -0
- package/src/background-wake/background-wake-routes.test.ts +233 -0
- package/src/background-wake/next-wake.test.ts +289 -0
- package/src/background-wake/next-wake.ts +172 -0
- package/src/background-wake/runtime-registry.ts +24 -0
- package/src/browser/operations.ts +15 -0
- package/src/cli/commands/__tests__/browser.test.ts +23 -5
- package/src/cli/commands/__tests__/conversations-slack.test.ts +572 -0
- package/src/cli/commands/__tests__/domain-register.test.ts +110 -0
- package/src/cli/commands/__tests__/domain-status.test.ts +33 -33
- package/src/cli/commands/__tests__/inference-send.test.ts +108 -5
- package/src/cli/commands/__tests__/memory-v2-compare-render.test.ts +98 -0
- package/src/cli/commands/__tests__/memory-v2.test.ts +10 -12
- package/src/cli/commands/__tests__/memory-v3-render.test.ts +340 -0
- package/src/cli/commands/browser.ts +247 -0
- package/src/cli/commands/conversations.ts +128 -1
- package/src/cli/commands/domain.ts +91 -41
- package/src/cli/commands/inference-providers.ts +147 -1
- package/src/cli/commands/inference.ts +93 -40
- package/src/cli/commands/memory-v2-compare-render.ts +115 -0
- package/src/cli/commands/memory-v2.ts +483 -0
- package/src/cli/commands/memory-v3-render.ts +344 -0
- package/src/cli/commands/memory-v3.ts +316 -0
- package/src/cli/commands/notifications.ts +24 -2
- package/src/cli/program.ts +2 -0
- package/src/cli/utils/conversation-id.ts +17 -5
- package/src/config/assistant-feature-flags.ts +21 -9
- package/src/config/bundled-skills/app-builder/SKILL.md +2 -2
- package/src/config/bundled-skills/document-editor/SKILL.md +124 -0
- package/src/config/bundled-skills/document-editor/TOOLS.json +258 -0
- package/src/config/bundled-skills/document-editor/tools/comment-list.ts +12 -0
- package/src/config/bundled-skills/document-editor/tools/comment-reply.ts +12 -0
- package/src/config/bundled-skills/document-editor/tools/comment-resolve.ts +12 -0
- package/src/config/bundled-skills/document-editor/tools/document-find.ts +12 -0
- package/src/config/bundled-skills/document-editor/tools/document-open.ts +12 -0
- package/src/config/bundled-skills/document-editor/tools/document-replace-text.ts +12 -0
- package/src/config/bundled-skills/image-studio/SKILL.md +4 -0
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +2 -2
- package/src/config/bundled-skills/media-processing/SKILL.md +8 -0
- package/src/config/bundled-skills/media-processing/tools/ingest-media.ts +13 -8
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +10 -3
- package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +16 -14
- package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +7 -2
- package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +7 -2
- package/src/config/bundled-skills/schedule/SKILL.md +8 -0
- package/src/config/bundled-tool-registry.ts +24 -12
- package/src/config/call-site-defaults.ts +20 -0
- package/src/config/feature-flag-registry.json +115 -3
- package/src/config/llm-resolver.ts +16 -2
- package/src/config/schemas/__tests__/memory-v2.test.ts +217 -1
- package/src/config/schemas/call-site-catalog.ts +35 -0
- package/src/config/schemas/llm.ts +14 -0
- package/src/config/schemas/memory-v2.ts +294 -1
- package/src/config/schemas/memory.ts +2 -1
- package/src/context/compactor.ts +60 -1
- package/src/context/token-estimator.ts +47 -4
- package/src/context/window-manager.ts +25 -0
- package/src/conversations/__tests__/message-consolidation.test.ts +350 -0
- package/src/conversations/message-consolidation.ts +404 -0
- package/src/credential-health/credential-health-service.ts +34 -19
- package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +1 -1
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +66 -6
- package/src/daemon/__tests__/meet-manifest-loader.test.ts +1 -1
- package/src/daemon/__tests__/native-web-search-metadata.test.ts +357 -0
- package/src/daemon/__tests__/web-search-status-text.test.ts +287 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +155 -36
- package/src/daemon/conversation-agent-loop.ts +307 -88
- package/src/daemon/conversation-error.ts +31 -1
- package/src/daemon/conversation-lifecycle.ts +149 -118
- package/src/daemon/conversation-messaging.ts +3 -0
- package/src/daemon/conversation-process.ts +273 -0
- package/src/daemon/conversation-queue-manager.ts +14 -0
- package/src/daemon/conversation-runtime-assembly.ts +145 -84
- package/src/daemon/conversation-slash.ts +37 -5
- package/src/daemon/conversation-surfaces.ts +45 -2
- package/src/daemon/conversation-tool-setup.ts +70 -3
- package/src/daemon/conversation-usage.ts +2 -0
- package/src/daemon/conversation.ts +54 -32
- package/src/daemon/disk-pressure-guard.ts +14 -2
- package/src/daemon/first-greeting.ts +10 -0
- package/src/daemon/handlers/__tests__/config-a2a-accept.test.ts +498 -0
- package/src/daemon/handlers/config-a2a.ts +160 -0
- package/src/daemon/handlers/config-model.test.ts +2 -0
- package/src/daemon/handlers/conversations.ts +90 -3
- package/src/daemon/handlers/shared.ts +92 -29
- package/src/daemon/host-bash-proxy.ts +1 -1
- package/src/daemon/host-browser-proxy.ts +5 -5
- package/src/daemon/host-cu-proxy.ts +5 -5
- package/src/daemon/host-file-proxy.ts +5 -5
- package/src/daemon/host-proxy-base.ts +4 -4
- package/src/daemon/host-transfer-proxy.ts +11 -11
- package/src/daemon/lifecycle.ts +40 -23
- package/src/daemon/meet-manifest-loader.ts +1 -7
- package/src/daemon/message-protocol.ts +4 -0
- package/src/daemon/message-types/conversations.ts +14 -9
- package/src/daemon/message-types/document-comments.ts +50 -0
- package/src/daemon/message-types/home.ts +1 -13
- package/src/daemon/message-types/messages.ts +66 -7
- package/src/daemon/message-types/surfaces.ts +3 -1
- package/src/daemon/message-types/sync.ts +14 -0
- package/src/daemon/message-types/web-activity.ts +57 -0
- package/src/daemon/plugin-source-watcher.ts +135 -3
- package/src/daemon/process-message.ts +69 -12
- package/src/daemon/shutdown-handlers.ts +24 -5
- package/src/daemon/switch-inference-profile-tool.ts +52 -0
- package/src/daemon/tool-setup-types.ts +13 -0
- package/src/daemon/trust-context.ts +6 -0
- package/src/documents/document-comments-store.test.ts +338 -0
- package/src/documents/document-comments-store.ts +237 -0
- package/src/documents/document-store.ts +202 -0
- package/src/events/relationship-state-updated.ts +25 -0
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +1 -2
- package/src/heartbeat/heartbeat-service.ts +1 -0
- package/src/home/__tests__/suggested-prompts.test.ts +33 -2
- package/src/home/feed-types.ts +6 -1
- package/src/home/home-content-refresh.ts +52 -0
- package/src/home/home-greeting-cache.ts +69 -0
- package/src/home/home-greeting.ts +85 -0
- package/src/home/suggested-prompts.ts +168 -9
- package/src/ipc/gateway-flag-listener.ts +123 -0
- package/src/ipc/skill-routes/registries.ts +8 -12
- package/src/memory/__tests__/db-async-query.test.ts +165 -0
- package/src/memory/__tests__/db-maintenance.test.ts +115 -0
- package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +241 -0
- package/src/memory/__tests__/jobs-store-job-classes.test.ts +28 -1
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +135 -2
- package/src/memory/__tests__/memory-retrospective-job.test.ts +327 -6
- package/src/memory/auto-analysis-enqueue.ts +5 -1
- package/src/memory/conversation-crud.ts +191 -100
- package/src/memory/conversation-starters-cadence.ts +3 -1
- package/src/memory/conversation-title-service.ts +19 -3
- package/src/memory/db-async-query.ts +214 -0
- package/src/memory/db-init.ts +26 -0
- package/src/memory/db-maintenance.ts +30 -21
- package/src/memory/delivery-crud.ts +41 -0
- package/src/memory/delivery-status.ts +141 -15
- package/src/memory/external-conversation-store.ts +32 -1
- package/src/memory/graph/bootstrap.ts +8 -1
- package/src/memory/graph/capability-seed.ts +7 -3
- package/src/memory/graph/conversation-graph-memory.ts +100 -17
- package/src/memory/graph/extraction.ts +1 -5
- package/src/memory/graph/graph-search.ts +7 -1
- package/src/memory/indexer.ts +28 -18
- package/src/memory/job-handlers/cleanup.ts +76 -18
- package/src/memory/job-handlers/conversation-starters.ts +1 -4
- package/src/memory/jobs/embed-pkb-file.ts +6 -1
- package/src/memory/jobs-store.ts +14 -0
- package/src/memory/jobs-worker.ts +68 -15
- package/src/memory/llm-request-log-source-clickhouse.ts +42 -2
- package/src/memory/llm-request-log-source-local.ts +7 -0
- package/src/memory/llm-request-log-source.ts +9 -2
- package/src/memory/llm-request-log-store.ts +43 -1
- package/src/memory/llm-usage-store.ts +24 -0
- package/src/memory/memory-retrospective-constants.ts +28 -0
- package/src/memory/memory-retrospective-enqueue.ts +11 -3
- package/src/memory/memory-retrospective-job.ts +413 -18
- package/src/memory/memory-retrospective-startup-cleanup.ts +3 -3
- package/src/memory/memory-v2-activation-log-store.ts +41 -14
- package/src/memory/migrations/100-core-tables.ts +1 -0
- package/src/memory/migrations/109-external-conversation-bindings.ts +1 -0
- package/src/memory/migrations/253-conversation-last-notified-profile.ts +15 -0
- package/src/memory/migrations/253-document-comments.ts +47 -0
- package/src/memory/migrations/254-external-conversation-binding-chat-name.ts +43 -0
- package/src/memory/migrations/255-channel-inbound-delivery-attempts.ts +24 -0
- package/src/memory/migrations/256-memory-v2-injection-events.ts +113 -0
- package/src/memory/migrations/257-strip-base-url-non-openai-compatible.ts +22 -0
- package/src/memory/migrations/258-onboarding-events-prior-assistants.ts +13 -0
- package/src/memory/migrations/259-conversation-cleaned-at.ts +33 -0
- package/src/memory/migrations/260-rename-cleaned-at.ts +44 -0
- package/src/memory/migrations/261-llm-usage-add-raw-usage.ts +36 -0
- package/src/memory/migrations/262-memory-v3-coactivation.ts +57 -0
- package/src/memory/migrations/263-memory-v3-auto-edges.ts +50 -0
- package/src/memory/migrations/264-llm-request-log-call-site.ts +29 -0
- package/src/memory/migrations/index.ts +34 -0
- package/src/memory/migrations/registry.ts +58 -0
- package/src/memory/onboarding-events-store.ts +7 -0
- package/src/memory/schema/calls.ts +1 -0
- package/src/memory/schema/conversations.ts +3 -0
- package/src/memory/schema/infrastructure.ts +22 -0
- package/src/memory/tool-usage-store.ts +36 -8
- package/src/memory/v2/__tests__/consolidation-job.test.ts +1 -0
- package/src/memory/v2/__tests__/harness-compare.test.ts +186 -0
- package/src/memory/v2/__tests__/harness-metrics.test.ts +74 -0
- package/src/memory/v2/__tests__/harness-oracle.test.ts +257 -0
- package/src/memory/v2/__tests__/harness-replay-input.test.ts +225 -0
- package/src/memory/v2/__tests__/harness-runner.test.ts +109 -0
- package/src/memory/v2/__tests__/injection-events.test.ts +318 -0
- package/src/memory/v2/__tests__/injection.test.ts +158 -112
- package/src/memory/v2/__tests__/page-index.test.ts +365 -1
- package/src/memory/v2/__tests__/qdrant.test.ts +36 -0
- package/src/memory/v2/__tests__/router.test.ts +660 -4
- package/src/memory/v2/consolidation-job.ts +14 -0
- package/src/memory/v2/harness/compare.ts +57 -0
- package/src/memory/v2/harness/metrics.ts +124 -0
- package/src/memory/v2/harness/oracle.ts +145 -0
- package/src/memory/v2/harness/replay-input.ts +224 -0
- package/src/memory/v2/harness/retriever.ts +74 -0
- package/src/memory/v2/harness/router-retriever.ts +43 -0
- package/src/memory/v2/harness/runner.ts +106 -0
- package/src/memory/v2/harness/trace.ts +58 -0
- package/src/memory/v2/injection-events.ts +101 -0
- package/src/memory/v2/injection.ts +42 -25
- package/src/memory/v2/page-index.ts +209 -7
- package/src/memory/v2/page-store.ts +18 -0
- package/src/memory/v2/prompts/router.ts +26 -1
- package/src/memory/v2/qdrant.ts +14 -2
- package/src/memory/v2/router.ts +369 -62
- package/src/memory/v3/__tests__/coactivation-store.test.ts +422 -0
- package/src/memory/v3/__tests__/consolidation-job.test.ts +468 -0
- package/src/memory/v3/__tests__/edge-learning-job.test.ts +324 -0
- package/src/memory/v3/__tests__/edges.test.ts +563 -0
- package/src/memory/v3/__tests__/filter.test.ts +512 -0
- package/src/memory/v3/__tests__/gate.test.ts +574 -0
- package/src/memory/v3/__tests__/index-composition.test.ts +233 -0
- package/src/memory/v3/__tests__/loop.test.ts +530 -0
- package/src/memory/v3/__tests__/retriever.test.ts +226 -0
- package/src/memory/v3/__tests__/scouts.test.ts +440 -0
- package/src/memory/v3/__tests__/shadow-middleware.test.ts +312 -0
- package/src/memory/v3/__tests__/system-prompts.test.ts +154 -0
- package/src/memory/v3/__tests__/traversal.test.ts +469 -0
- package/src/memory/v3/__tests__/tree-index.test.ts +280 -0
- package/src/memory/v3/__tests__/tree-store.test.ts +529 -0
- package/src/memory/v3/__tests__/tree-walk.test.ts +707 -0
- package/src/memory/v3/__tests__/validate.test.ts +245 -0
- package/src/memory/v3/auto-edges.ts +223 -0
- package/src/memory/v3/coactivation-store.ts +124 -0
- package/src/memory/v3/consolidation-job.ts +323 -0
- package/src/memory/v3/edge-learning-job.ts +160 -0
- package/src/memory/v3/edges.ts +249 -0
- package/src/memory/v3/filter.ts +281 -0
- package/src/memory/v3/gate.ts +334 -0
- package/src/memory/v3/index-composition.ts +113 -0
- package/src/memory/v3/llm-capture.ts +46 -0
- package/src/memory/v3/loop.ts +382 -0
- package/src/memory/v3/maintenance.ts +144 -0
- package/src/memory/v3/prompt-context.ts +33 -0
- package/src/memory/v3/prompts/consolidation.ts +458 -0
- package/src/memory/v3/prompts/system-prompts.ts +196 -0
- package/src/memory/v3/retriever.ts +33 -0
- package/src/memory/v3/scouts.ts +420 -0
- package/src/memory/v3/shadow-middleware.ts +305 -0
- package/src/memory/v3/traversal.ts +206 -0
- package/src/memory/v3/tree-index.ts +237 -0
- package/src/memory/v3/tree-store.ts +394 -0
- package/src/memory/v3/tree-walk.ts +351 -0
- package/src/memory/v3/types.ts +65 -0
- package/src/memory/v3/validate.ts +300 -0
- package/src/messaging/providers/index.ts +7 -1
- package/src/messaging/providers/slack/__tests__/adapter-mention-rendering.test.ts +329 -3
- package/src/messaging/providers/slack/__tests__/adapter-token-routing.test.ts +34 -1
- package/src/messaging/providers/slack/adapter.ts +178 -25
- package/src/messaging/providers/slack/api.test.ts +54 -0
- package/src/messaging/providers/slack/api.ts +119 -3
- package/src/messaging/providers/slack/client.ts +12 -0
- package/src/messaging/providers/slack/deep-link.ts +20 -1
- package/src/messaging/providers/slack/message-metadata.test.ts +48 -0
- package/src/messaging/providers/slack/message-metadata.ts +156 -0
- package/src/messaging/providers/slack/render-transcript.test.ts +107 -75
- package/src/messaging/providers/slack/render-transcript.ts +176 -49
- package/src/messaging/providers/slack/send.test.ts +77 -0
- package/src/messaging/providers/slack/send.ts +8 -2
- package/src/messaging/providers/slack/types.ts +14 -0
- package/src/notifications/__tests__/emit-signal-home-feed.test.ts +4 -1
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +116 -54
- package/src/notifications/adapters/macos.ts +18 -1
- package/src/notifications/adapters/platform.ts +1 -1
- package/src/notifications/conversation-seed-composer.ts +14 -2
- package/src/notifications/decision-engine.ts +1 -4
- package/src/notifications/deferred-emit.ts +135 -0
- package/src/notifications/emit-signal.ts +38 -50
- package/src/notifications/home-feed-side-effect.ts +60 -30
- package/src/oauth/connect-orchestrator.ts +3 -0
- package/src/oauth/credential-token-resolver.ts +2 -0
- package/src/oauth/manual-token-connection.ts +19 -0
- package/src/oauth/oauth-store.ts +12 -0
- package/src/oauth/seed-providers.ts +22 -0
- package/src/permissions/prompter.ts +8 -5
- package/src/permissions/question-prompter.ts +5 -2
- package/src/permissions/secret-prompter.ts +6 -3
- package/src/plugin-api/index.ts +4 -0
- package/src/plugin-api/types.ts +7 -33
- package/src/plugins/defaults/index.ts +6 -0
- package/src/plugins/defaults/injectors.ts +100 -20
- package/src/plugins/external-plugin-loader.ts +5 -68
- package/src/plugins/types.ts +11 -16
- package/src/proactive-artifact/aux-message-injector.ts +17 -4
- package/src/prompts/__tests__/system-prompt.test.ts +46 -2
- package/src/prompts/__tests__/task-progress-hint-section.test.ts +3 -9
- package/src/prompts/normalize-onboarding.ts +40 -0
- package/src/prompts/persona-resolver.ts +36 -21
- package/src/prompts/sections.ts +69 -19
- package/src/prompts/system-prompt.ts +118 -216
- package/src/prompts/template-detection.ts +37 -0
- package/src/prompts/templates/BOOTSTRAP-CONTENT-AUTOMATION.md +141 -0
- package/src/prompts/templates/BOOTSTRAP.md +10 -2
- package/src/prompts/templates/VOICE.md +3 -0
- package/src/prompts/templates/system-sections.ts +281 -9
- package/src/providers/__tests__/connection-model-compat.test.ts +234 -0
- package/src/providers/__tests__/retry-callsite.test.ts +85 -5
- package/src/providers/anthropic/client.ts +159 -66
- package/src/providers/call-site-routing.ts +14 -2
- package/src/providers/connection-model-compat.ts +38 -0
- package/src/providers/connection-resolution.ts +16 -2
- package/src/providers/fireworks/client.ts +20 -2
- package/src/providers/gemini/client.ts +49 -6
- package/src/providers/inference/__tests__/base-url-route-validation.test.ts +342 -0
- package/src/providers/inference/__tests__/base-url-security.test.ts +189 -0
- package/src/providers/inference/__tests__/codex-token-refresh.test.ts +254 -0
- package/src/providers/inference/adapter-factory.ts +18 -1
- package/src/providers/inference/auth.ts +3 -3
- package/src/providers/inference/codex-token-refresh.ts +128 -0
- package/src/providers/inference/resolve-auth.ts +49 -6
- package/src/providers/minimax/client.ts +106 -0
- package/src/providers/model-catalog.ts +91 -1
- package/src/providers/model-intents.ts +1 -1
- package/src/providers/openai/chat-completions-provider.ts +63 -23
- package/src/providers/openai/codex-models.ts +18 -0
- package/src/providers/openai/responses-provider.ts +86 -23
- package/src/providers/openrouter/client.ts +5 -1
- package/src/providers/provider-send-message.ts +7 -1
- package/src/providers/retry.ts +34 -3
- package/src/providers/thinking-config.ts +26 -1
- package/src/providers/types.ts +25 -0
- package/src/providers/usage-tracking.ts +2 -0
- package/src/runtime/AGENTS.md +2 -2
- package/src/runtime/__tests__/agent-wake.test.ts +214 -0
- package/src/runtime/__tests__/background-job-runner.test.ts +128 -0
- package/src/runtime/agent-wake.ts +152 -56
- package/src/runtime/assistant-event-hub.ts +76 -6
- package/src/runtime/auth/route-policy.ts +43 -3
- package/src/runtime/background-job-runner.ts +26 -0
- package/src/runtime/btw-sidechain.ts +0 -6
- package/src/runtime/channel-reply-delivery.ts +182 -47
- package/src/runtime/channel-retry-sweep.ts +141 -16
- package/src/runtime/http-types.ts +7 -6
- package/src/runtime/migrations/vbundle-builder.ts +10 -3
- package/src/runtime/pending-interactions.ts +50 -8
- package/src/runtime/routes/__tests__/content-source-routes.test.ts +162 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +161 -1
- package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +14 -0
- package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +290 -0
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +512 -0
- package/src/runtime/routes/__tests__/sanity-routes.test.ts +280 -0
- package/src/runtime/routes/__tests__/slack-channel-routes.test.ts +266 -0
- package/src/runtime/routes/acp-routes.test.ts +255 -6
- package/src/runtime/routes/acp-routes.ts +8 -1
- package/src/runtime/routes/approval-routes.ts +4 -1
- package/src/runtime/routes/avatar-routes.ts +10 -10
- package/src/runtime/routes/background-wake-routes.ts +188 -0
- package/src/runtime/routes/browser-tabs-routes.ts +200 -0
- package/src/runtime/routes/btw-routes.ts +0 -6
- package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +246 -0
- package/src/runtime/routes/content-source-routes.ts +78 -0
- package/src/runtime/routes/conversation-cli-routes.ts +147 -2
- package/src/runtime/routes/conversation-list-routes.ts +12 -4
- package/src/runtime/routes/conversation-management-routes.ts +77 -20
- package/src/runtime/routes/conversation-query-routes.ts +196 -31
- package/src/runtime/routes/conversation-routes.ts +472 -425
- package/src/runtime/routes/conversation-starter-routes.ts +6 -3
- package/src/runtime/routes/disk-pressure-routes.ts +1 -1
- package/src/runtime/routes/document-comments-routes.ts +287 -0
- package/src/runtime/routes/documents-routes.ts +33 -0
- package/src/runtime/routes/domain-routes.ts +60 -10
- package/src/runtime/routes/email-routes.ts +5 -2
- package/src/runtime/routes/events-routes.ts +54 -10
- package/src/runtime/routes/group-routes.ts +24 -8
- package/src/runtime/routes/home-feed-routes.ts +6 -3
- package/src/runtime/routes/host-app-control-routes.ts +1 -1
- package/src/runtime/routes/host-browser-routes.ts +17 -2
- package/src/runtime/routes/host-cu-routes.ts +2 -2
- package/src/runtime/routes/identity-routes.ts +21 -0
- package/src/runtime/routes/inbound-message-handler.ts +288 -58
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +96 -3
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +365 -6
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +283 -82
- package/src/runtime/routes/index.ts +20 -4
- package/src/runtime/routes/inference-profile-session-handler.ts +22 -12
- package/src/runtime/routes/inference-profile-session-routes.ts +7 -1
- package/src/runtime/routes/inference-provider-connection-routes.ts +63 -7
- package/src/runtime/routes/integrations/a2a.ts +60 -1
- package/src/runtime/routes/llm-call-sites-routes.ts +32 -5
- package/src/runtime/routes/log-export-routes.ts +39 -0
- package/src/runtime/routes/memory-item-routes.ts +8 -3
- package/src/runtime/routes/memory-v2-routes.ts +427 -0
- package/src/runtime/routes/memory-v3-routes.ts +316 -0
- package/src/runtime/routes/migration-routes.ts +21 -24
- package/src/runtime/routes/notification-routes.ts +19 -2
- package/src/runtime/routes/plugins-routes.ts +337 -0
- package/src/runtime/routes/question-routes.ts +4 -1
- package/src/runtime/routes/rename-conversation-routes.ts +6 -2
- package/src/runtime/routes/sanity-routes.ts +159 -0
- package/src/runtime/routes/secret-routes.ts +25 -5
- package/src/runtime/routes/settings-routes.ts +12 -11
- package/src/runtime/routes/slack-channel-routes.ts +188 -0
- package/src/runtime/routes/workspace-routes.ts +25 -10
- package/src/runtime/services/conversation-serializer.ts +30 -4
- package/src/runtime/sync/resource-sync-events.ts +106 -38
- package/src/runtime/sync/sync-publisher.test.ts +49 -0
- package/src/runtime/sync/sync-publisher.ts +2 -1
- package/src/runtime/verification-outbound-actions.ts +73 -1
- package/src/schedule/integration-status.ts +3 -1
- package/src/security/__tests__/oauth2-device-code.test.ts +479 -0
- package/src/security/oauth2-device-code.ts +307 -0
- package/src/security/oauth2.ts +26 -9
- package/src/security/secure-keys.ts +5 -0
- package/src/skills/catalog-install.ts +6 -2
- package/src/telemetry/types.ts +12 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +48 -0
- package/src/telemetry/usage-telemetry-reporter.ts +1 -0
- package/src/tools/acp/spawn.test.ts +119 -0
- package/src/tools/acp/spawn.ts +15 -2
- package/src/tools/apps/definitions.ts +2 -8
- package/src/tools/ask-question/ask-question-tool.test.ts +3 -3
- package/src/tools/ask-question/ask-question-tool.ts +38 -45
- package/src/tools/browser/__tests__/pinned-tabs.test.ts +150 -0
- package/src/tools/browser/browser-execution.ts +106 -0
- package/src/tools/browser/cdp-client/__tests__/browser-tabs-factory.test.ts +402 -0
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +28 -0
- package/src/tools/browser/cdp-client/__tests__/types.test.ts +4 -0
- package/src/tools/browser/cdp-client/cdp-inspect-client.ts +22 -0
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +42 -2
- package/src/tools/browser/cdp-client/factory.ts +171 -4
- package/src/tools/browser/cdp-client/local-cdp-client.ts +21 -0
- package/src/tools/browser/cdp-client/types.ts +101 -0
- package/src/tools/browser/pinned-tabs.ts +146 -0
- package/src/tools/computer-use/definitions.ts +22 -78
- package/src/tools/credential-execution/make-authenticated-request.ts +3 -9
- package/src/tools/credential-execution/manage-secure-command-tool.ts +3 -9
- package/src/tools/credential-execution/run-authenticated-command.ts +3 -9
- package/src/tools/credentials/vault.ts +3 -9
- package/src/tools/document/document-comment-tool.test.ts +379 -0
- package/src/tools/document/document-comment-tool.ts +156 -0
- package/src/tools/document/document-tool.ts +187 -2
- package/src/tools/execution-target.ts +21 -23
- package/src/tools/executor.ts +6 -1
- package/src/tools/filesystem/edit.ts +3 -9
- package/src/tools/filesystem/list.ts +3 -9
- package/src/tools/filesystem/read.ts +3 -9
- package/src/tools/filesystem/write.ts +3 -9
- package/src/tools/host-filesystem/edit.ts +3 -9
- package/src/tools/host-filesystem/read.ts +3 -9
- package/src/tools/host-filesystem/transfer.ts +3 -9
- package/src/tools/host-filesystem/write.ts +3 -9
- package/src/tools/host-terminal/host-shell.ts +3 -9
- package/src/tools/mcp/mcp-tool-factory.ts +1 -8
- package/src/tools/memory/register.test.ts +1 -1
- package/src/tools/memory/register.ts +4 -9
- package/src/tools/network/__tests__/web-fetch-metadata.test.ts +229 -0
- package/src/tools/network/__tests__/web-search-metadata.test.ts +346 -0
- package/src/tools/network/domain-normalize.ts +17 -0
- package/src/tools/network/web-fetch.ts +216 -73
- package/src/tools/network/web-search.ts +216 -98
- package/src/tools/registry.ts +7 -23
- package/src/tools/schema-transforms.ts +1 -1
- package/src/tools/skills/execute.ts +3 -9
- package/src/tools/skills/load.ts +3 -9
- package/src/tools/skills/skill-tool-factory.ts +1 -8
- package/src/tools/subagent/notify-parent.ts +3 -9
- package/src/tools/system/request-permission.ts +3 -9
- package/src/tools/terminal/safe-env.ts +3 -2
- package/src/tools/terminal/shell.ts +3 -9
- package/src/tools/tool-approval-handler.ts +19 -12
- package/src/tools/tool-defaults.ts +94 -0
- package/src/tools/types.ts +31 -98
- package/src/tools/ui-surface/definitions.ts +9 -23
- package/src/types/onboarding-context.ts +4 -0
- package/src/usage/pricing.ts +23 -0
- package/src/usage/types.ts +12 -0
- package/src/util/__tests__/favicon.test.ts +84 -0
- package/src/util/favicon.ts +40 -0
- package/src/util/logger.ts +16 -7
- package/src/util/platform.ts +7 -7
- package/src/util/sqlite3-runtime.ts +65 -0
- package/src/workspace/git-service.ts +75 -4
- package/src/workspace/migrations/086-revert-stale-gemini-mis-rewrites.ts +1 -0
- package/src/workspace/migrations/088-deprecate-background-conversation-override.ts +103 -0
- package/src/workspace/migrations/089-move-memory-tree-out-of-v3.ts +86 -0
- package/src/workspace/migrations/registry.ts +4 -0
- package/src/__tests__/compaction-strip-metadata-clear.test.ts +0 -206
- package/src/__tests__/message-complete-display-id.test.ts +0 -175
- package/src/config/bundled-skills/document/SKILL.md +0 -54
- package/src/config/bundled-skills/document/TOOLS.json +0 -106
- package/src/daemon/seed-files.ts +0 -18
- package/src/prompts/cache-boundary.ts +0 -8
- package/src/runtime/routes/interface-routes.ts +0 -43
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-create.ts +0 -0
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-delete.ts +0 -0
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-list.ts +0 -0
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-read.ts +0 -0
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-update.ts +0 -0
|
@@ -27,8 +27,8 @@ mock.module("../config/env.js", () => ({
|
|
|
27
27
|
|
|
28
28
|
mock.module("../daemon/handlers/conversations.js", () => ({
|
|
29
29
|
cancelGeneration: () => true,
|
|
30
|
-
clearAllConversations: () => {
|
|
31
|
-
clearAll();
|
|
30
|
+
clearAllConversations: async () => {
|
|
31
|
+
await clearAll();
|
|
32
32
|
return 0;
|
|
33
33
|
},
|
|
34
34
|
switchConversation: async () => null,
|
|
@@ -129,26 +129,28 @@ describe("DELETE /v1/conversations — route handler", () => {
|
|
|
129
129
|
(r) => r.operationId === "clearAllConversations",
|
|
130
130
|
)!;
|
|
131
131
|
|
|
132
|
-
test("missing X-Confirm-Destructive header throws BadRequestError", () => {
|
|
133
|
-
expect(
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
132
|
+
test("missing X-Confirm-Destructive header throws BadRequestError", async () => {
|
|
133
|
+
await expect(
|
|
134
|
+
Promise.resolve().then(() =>
|
|
135
|
+
clearRoute.handler({
|
|
136
|
+
pathParams: {},
|
|
137
|
+
body: {},
|
|
138
|
+
headers: {},
|
|
139
|
+
}),
|
|
140
|
+
),
|
|
141
|
+
).rejects.toThrow(BadRequestError);
|
|
141
142
|
});
|
|
142
143
|
|
|
143
|
-
test("wrong X-Confirm-Destructive header value throws BadRequestError", () => {
|
|
144
|
-
expect(
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
144
|
+
test("wrong X-Confirm-Destructive header value throws BadRequestError", async () => {
|
|
145
|
+
await expect(
|
|
146
|
+
Promise.resolve().then(() =>
|
|
147
|
+
clearRoute.handler({
|
|
148
|
+
pathParams: {},
|
|
149
|
+
body: {},
|
|
150
|
+
headers: { "x-confirm-destructive": "wrong-value" },
|
|
151
|
+
}),
|
|
152
|
+
),
|
|
153
|
+
).rejects.toThrow(BadRequestError);
|
|
152
154
|
});
|
|
153
155
|
|
|
154
156
|
test("correct header clears data", async () => {
|
|
@@ -156,23 +158,21 @@ describe("DELETE /v1/conversations — route handler", () => {
|
|
|
156
158
|
await addMessage(conv.id, "user", "hello from safety test");
|
|
157
159
|
expect(getConversation(conv.id)).not.toBeNull();
|
|
158
160
|
|
|
159
|
-
const result = clearRoute.handler({
|
|
161
|
+
const result = await clearRoute.handler({
|
|
160
162
|
pathParams: {},
|
|
161
163
|
body: {},
|
|
162
164
|
headers: { "x-confirm-destructive": "clear-all-conversations" },
|
|
163
|
-
|
|
164
165
|
});
|
|
165
166
|
expect(result).toBeUndefined();
|
|
166
167
|
|
|
167
168
|
expect(getConversation(conv.id)).toBeNull();
|
|
168
169
|
});
|
|
169
170
|
|
|
170
|
-
test("lifecycle_events contains conversations_clear_all after successful clear", () => {
|
|
171
|
-
clearRoute.handler({
|
|
171
|
+
test("lifecycle_events contains conversations_clear_all after successful clear", async () => {
|
|
172
|
+
await clearRoute.handler({
|
|
172
173
|
pathParams: {},
|
|
173
174
|
body: {},
|
|
174
175
|
headers: { "x-confirm-destructive": "clear-all-conversations" },
|
|
175
|
-
|
|
176
176
|
});
|
|
177
177
|
|
|
178
178
|
const raw = (
|
|
@@ -51,7 +51,7 @@ mock.module("../memory/guardian-action-store.js", () => ({
|
|
|
51
51
|
|
|
52
52
|
mock.module("../providers/registry.js", () => ({
|
|
53
53
|
getProvider: () => ({ name: "mock-provider" }),
|
|
54
|
-
initializeProviders: () => {},
|
|
54
|
+
initializeProviders: async () => {},
|
|
55
55
|
}));
|
|
56
56
|
|
|
57
57
|
mock.module("../config/loader.js", () => ({
|
|
@@ -23,7 +23,7 @@ mock.module("../daemon/conversation-store.js", () => ({
|
|
|
23
23
|
|
|
24
24
|
mock.module("../daemon/handlers/conversations.js", () => ({
|
|
25
25
|
cancelGeneration: () => true,
|
|
26
|
-
clearAllConversations: () => 0,
|
|
26
|
+
clearAllConversations: async () => 0,
|
|
27
27
|
switchConversation: async () => null,
|
|
28
28
|
undoLastMessage: async () => null,
|
|
29
29
|
regenerateResponse: async () => null,
|
|
@@ -231,7 +231,7 @@ describe("clearAll → disk view", () => {
|
|
|
231
231
|
resetConversationsDir();
|
|
232
232
|
});
|
|
233
233
|
|
|
234
|
-
test("empties the conversations directory", () => {
|
|
234
|
+
test("empties the conversations directory", async () => {
|
|
235
235
|
// Create two conversations
|
|
236
236
|
createConversation("Conv A");
|
|
237
237
|
createConversation("Conv B");
|
|
@@ -241,7 +241,7 @@ describe("clearAll → disk view", () => {
|
|
|
241
241
|
expect(entries.length).toBe(2);
|
|
242
242
|
|
|
243
243
|
// Clear all
|
|
244
|
-
clearAll();
|
|
244
|
+
await clearAll();
|
|
245
245
|
|
|
246
246
|
// Conversations directory should exist but be empty
|
|
247
247
|
expect(existsSync(conversationsDir)).toBe(true);
|
|
@@ -9,6 +9,7 @@ mock.module("../providers/registry.js", () => ({
|
|
|
9
9
|
|
|
10
10
|
import type { ErrorContext } from "../daemon/conversation-error.js";
|
|
11
11
|
import {
|
|
12
|
+
budgetYieldUnrecoveredClassification,
|
|
12
13
|
buildConversationErrorMessage,
|
|
13
14
|
classifyConversationError,
|
|
14
15
|
isUserCancellation,
|
|
@@ -947,3 +948,33 @@ describe("buildConversationErrorMessage", () => {
|
|
|
947
948
|
expect(msg.code).toBe("PROVIDER_WEB_SEARCH");
|
|
948
949
|
});
|
|
949
950
|
});
|
|
951
|
+
|
|
952
|
+
describe("budgetYieldUnrecoveredClassification", () => {
|
|
953
|
+
it("returns the BUDGET_YIELD_UNRECOVERED code and retryable=true", () => {
|
|
954
|
+
const classified = budgetYieldUnrecoveredClassification();
|
|
955
|
+
expect(classified.code).toBe("BUDGET_YIELD_UNRECOVERED");
|
|
956
|
+
expect(classified.retryable).toBe(true);
|
|
957
|
+
expect(classified.errorCategory).toBe("budget_yield_unrecovered");
|
|
958
|
+
});
|
|
959
|
+
|
|
960
|
+
it("returns a user-facing message that explains the situation", () => {
|
|
961
|
+
const classified = budgetYieldUnrecoveredClassification();
|
|
962
|
+
// The message must communicate (a) compaction was attempted, (b) send
|
|
963
|
+
// another message to continue. Avoid asserting exact wording so copy
|
|
964
|
+
// tweaks don't trip the test, but lock down the two semantic anchors
|
|
965
|
+
// a downstream client could test against.
|
|
966
|
+
expect(classified.userMessage).toContain("compact");
|
|
967
|
+
expect(classified.userMessage).toContain("Send another message");
|
|
968
|
+
});
|
|
969
|
+
|
|
970
|
+
it("survives the buildConversationErrorMessage envelope unchanged", () => {
|
|
971
|
+
const classified = budgetYieldUnrecoveredClassification();
|
|
972
|
+
const envelope = buildConversationErrorMessage("conv-1", classified);
|
|
973
|
+
expect(envelope.type).toBe("conversation_error");
|
|
974
|
+
expect(envelope.conversationId).toBe("conv-1");
|
|
975
|
+
expect(envelope.code).toBe("BUDGET_YIELD_UNRECOVERED");
|
|
976
|
+
expect(envelope.retryable).toBe(true);
|
|
977
|
+
expect(envelope.errorCategory).toBe("budget_yield_unrecovered");
|
|
978
|
+
expect(envelope.userMessage).toBe(classified.userMessage);
|
|
979
|
+
});
|
|
980
|
+
});
|
|
@@ -49,6 +49,7 @@ import {
|
|
|
49
49
|
getRetrospectiveState,
|
|
50
50
|
upsertRetrospectiveState,
|
|
51
51
|
} from "../memory/memory-retrospective-state.js";
|
|
52
|
+
import { rawGet, rawRun } from "../memory/raw-query.js";
|
|
52
53
|
import {
|
|
53
54
|
activationState,
|
|
54
55
|
channelInboundEvents,
|
|
@@ -213,6 +214,115 @@ describe("forkConversation", () => {
|
|
|
213
214
|
]);
|
|
214
215
|
});
|
|
215
216
|
|
|
217
|
+
test("advances fork boundary through consecutive assistant rows after the requested message", async () => {
|
|
218
|
+
// When the read-path merges consecutive assistant DB rows into a single
|
|
219
|
+
// display row, the client only addresses the anchor id. Forking through
|
|
220
|
+
// the anchor must still include the merged tail rows that follow.
|
|
221
|
+
const source = createConversation("Multi-row turn thread");
|
|
222
|
+
await addMessage(source.id, "user", "Message 1", undefined, {
|
|
223
|
+
skipIndexing: true,
|
|
224
|
+
});
|
|
225
|
+
const anchor = await addMessage(
|
|
226
|
+
source.id,
|
|
227
|
+
"assistant",
|
|
228
|
+
"Assistant text segment",
|
|
229
|
+
undefined,
|
|
230
|
+
{ skipIndexing: true },
|
|
231
|
+
);
|
|
232
|
+
const toolRow = await addMessage(
|
|
233
|
+
source.id,
|
|
234
|
+
"assistant",
|
|
235
|
+
"Tool turn row",
|
|
236
|
+
undefined,
|
|
237
|
+
{ skipIndexing: true },
|
|
238
|
+
);
|
|
239
|
+
const tailRow = await addMessage(
|
|
240
|
+
source.id,
|
|
241
|
+
"assistant",
|
|
242
|
+
"Final assistant segment",
|
|
243
|
+
undefined,
|
|
244
|
+
{ skipIndexing: true },
|
|
245
|
+
);
|
|
246
|
+
await addMessage(source.id, "user", "Next user turn", undefined, {
|
|
247
|
+
skipIndexing: true,
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
const fork = forkConversation({
|
|
251
|
+
conversationId: source.id,
|
|
252
|
+
throughMessageId: anchor.id,
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
// Boundary advances past the entire consecutive-assistant cluster, so the
|
|
256
|
+
// full turn is preserved in the fork — not just the anchor row.
|
|
257
|
+
expect(getMessages(fork.id).map((message) => message.content)).toEqual([
|
|
258
|
+
"Message 1",
|
|
259
|
+
"Assistant text segment",
|
|
260
|
+
"Tool turn row",
|
|
261
|
+
"Final assistant segment",
|
|
262
|
+
]);
|
|
263
|
+
expect(fork.forkParentMessageId).toBe(tailRow.id);
|
|
264
|
+
expect(toolRow.id).not.toBe(anchor.id);
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
test("advances fork boundary across tool-result-only user rows between assistant rows", async () => {
|
|
268
|
+
// Read-path collapse folds tool-result-only user rows into the
|
|
269
|
+
// surrounding assistant turn (`mergeToolResultsIntoAssistantMessages`
|
|
270
|
+
// suppresses them). The client only sees a single display turn anchored
|
|
271
|
+
// at the first assistant row, so forking through the anchor must include
|
|
272
|
+
// both halves of the assistant turn plus the suppressed user row in
|
|
273
|
+
// between — otherwise the fork loses tool_use ↔ tool_result pairing
|
|
274
|
+
// and produces an invalid LLM history.
|
|
275
|
+
const source = createConversation("Tool-result gap thread");
|
|
276
|
+
await addMessage(source.id, "user", "Find the latest sales numbers", undefined, {
|
|
277
|
+
skipIndexing: true,
|
|
278
|
+
});
|
|
279
|
+
const anchor = await addMessage(
|
|
280
|
+
source.id,
|
|
281
|
+
"assistant",
|
|
282
|
+
JSON.stringify([
|
|
283
|
+
{ type: "text", text: "Looking up the data." },
|
|
284
|
+
{ type: "tool_use", id: "tool_1", name: "lookup", input: {} },
|
|
285
|
+
]),
|
|
286
|
+
undefined,
|
|
287
|
+
{ skipIndexing: true },
|
|
288
|
+
);
|
|
289
|
+
const toolResultUserRow = await addMessage(
|
|
290
|
+
source.id,
|
|
291
|
+
"user",
|
|
292
|
+
JSON.stringify([
|
|
293
|
+
{ type: "tool_result", tool_use_id: "tool_1", content: "data" },
|
|
294
|
+
]),
|
|
295
|
+
undefined,
|
|
296
|
+
{ skipIndexing: true },
|
|
297
|
+
);
|
|
298
|
+
const tailAssistantRow = await addMessage(
|
|
299
|
+
source.id,
|
|
300
|
+
"assistant",
|
|
301
|
+
"Here are the numbers.",
|
|
302
|
+
undefined,
|
|
303
|
+
{ skipIndexing: true },
|
|
304
|
+
);
|
|
305
|
+
await addMessage(source.id, "user", "Thanks", undefined, {
|
|
306
|
+
skipIndexing: true,
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
const fork = forkConversation({
|
|
310
|
+
conversationId: source.id,
|
|
311
|
+
throughMessageId: anchor.id,
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
// All three DB rows of the assistant display turn — including the
|
|
315
|
+
// suppressed tool-result user row in the middle — land in the fork.
|
|
316
|
+
const forkedContent = getMessages(fork.id).map((m) => m.content);
|
|
317
|
+
expect(forkedContent).toHaveLength(4);
|
|
318
|
+
expect(forkedContent[0]).toBe("Find the latest sales numbers");
|
|
319
|
+
expect(forkedContent[1]).toContain("tool_use");
|
|
320
|
+
expect(forkedContent[2]).toContain("tool_result");
|
|
321
|
+
expect(forkedContent[3]).toBe("Here are the numbers.");
|
|
322
|
+
expect(fork.forkParentMessageId).toBe(tailAssistantRow.id);
|
|
323
|
+
expect(toolResultUserRow.id).not.toBe(anchor.id);
|
|
324
|
+
});
|
|
325
|
+
|
|
216
326
|
test("preserves compacted context when forking from the visible window", async () => {
|
|
217
327
|
const source = createConversation("Compacted thread");
|
|
218
328
|
await addMessage(source.id, "user", "Message 1", undefined, {
|
|
@@ -296,6 +406,168 @@ describe("forkConversation", () => {
|
|
|
296
406
|
]);
|
|
297
407
|
});
|
|
298
408
|
|
|
409
|
+
test("inherits historyStrippedAt when forking past the clean event", async () => {
|
|
410
|
+
const source = createConversation("Clean thread");
|
|
411
|
+
await addMessage(source.id, "user", "Message 1", undefined, {
|
|
412
|
+
skipIndexing: true,
|
|
413
|
+
});
|
|
414
|
+
const preClean = await addMessage(
|
|
415
|
+
source.id,
|
|
416
|
+
"assistant",
|
|
417
|
+
"Message 2",
|
|
418
|
+
undefined,
|
|
419
|
+
{ skipIndexing: true },
|
|
420
|
+
);
|
|
421
|
+
|
|
422
|
+
const historyStrippedAt = preClean.createdAt + 1;
|
|
423
|
+
getDb()
|
|
424
|
+
.update(conversations)
|
|
425
|
+
.set({ historyStrippedAt })
|
|
426
|
+
.where(eq(conversations.id, source.id))
|
|
427
|
+
.run();
|
|
428
|
+
|
|
429
|
+
const postClean = await addMessage(
|
|
430
|
+
source.id,
|
|
431
|
+
"user",
|
|
432
|
+
"Message 3",
|
|
433
|
+
undefined,
|
|
434
|
+
{ skipIndexing: true },
|
|
435
|
+
);
|
|
436
|
+
expect(postClean.createdAt).toBeGreaterThanOrEqual(historyStrippedAt);
|
|
437
|
+
|
|
438
|
+
const fork = forkConversation({
|
|
439
|
+
conversationId: source.id,
|
|
440
|
+
throughMessageId: postClean.id,
|
|
441
|
+
});
|
|
442
|
+
|
|
443
|
+
expect(fork.historyStrippedAt).toBe(historyStrippedAt);
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
test("does not inherit historyStrippedAt when forking before the clean event", async () => {
|
|
447
|
+
const source = createConversation("Clean thread");
|
|
448
|
+
await addMessage(source.id, "user", "Message 1", undefined, {
|
|
449
|
+
skipIndexing: true,
|
|
450
|
+
});
|
|
451
|
+
const preClean = await addMessage(
|
|
452
|
+
source.id,
|
|
453
|
+
"assistant",
|
|
454
|
+
"Message 2",
|
|
455
|
+
undefined,
|
|
456
|
+
{ skipIndexing: true },
|
|
457
|
+
);
|
|
458
|
+
|
|
459
|
+
const historyStrippedAt = preClean.createdAt + 1;
|
|
460
|
+
getDb()
|
|
461
|
+
.update(conversations)
|
|
462
|
+
.set({ historyStrippedAt })
|
|
463
|
+
.where(eq(conversations.id, source.id))
|
|
464
|
+
.run();
|
|
465
|
+
|
|
466
|
+
await addMessage(source.id, "user", "Message 3", undefined, {
|
|
467
|
+
skipIndexing: true,
|
|
468
|
+
});
|
|
469
|
+
|
|
470
|
+
const fork = forkConversation({
|
|
471
|
+
conversationId: source.id,
|
|
472
|
+
throughMessageId: preClean.id,
|
|
473
|
+
});
|
|
474
|
+
|
|
475
|
+
expect(fork.historyStrippedAt).toBeNull();
|
|
476
|
+
});
|
|
477
|
+
|
|
478
|
+
test("inherits historyStrippedAt on a full-history fork", async () => {
|
|
479
|
+
const source = createConversation("Clean thread");
|
|
480
|
+
await addMessage(source.id, "user", "Message 1", undefined, {
|
|
481
|
+
skipIndexing: true,
|
|
482
|
+
});
|
|
483
|
+
const last = await addMessage(
|
|
484
|
+
source.id,
|
|
485
|
+
"assistant",
|
|
486
|
+
"Message 2",
|
|
487
|
+
undefined,
|
|
488
|
+
{ skipIndexing: true },
|
|
489
|
+
);
|
|
490
|
+
|
|
491
|
+
const historyStrippedAt = last.createdAt - 1;
|
|
492
|
+
getDb()
|
|
493
|
+
.update(conversations)
|
|
494
|
+
.set({ historyStrippedAt })
|
|
495
|
+
.where(eq(conversations.id, source.id))
|
|
496
|
+
.run();
|
|
497
|
+
|
|
498
|
+
const fork = forkConversation({ conversationId: source.id });
|
|
499
|
+
|
|
500
|
+
expect(fork.historyStrippedAt).toBe(historyStrippedAt);
|
|
501
|
+
});
|
|
502
|
+
|
|
503
|
+
test("leaves historyStrippedAt null when the source has no clean event", async () => {
|
|
504
|
+
const source = createConversation("Unclean thread");
|
|
505
|
+
await addMessage(source.id, "user", "Message 1", undefined, {
|
|
506
|
+
skipIndexing: true,
|
|
507
|
+
});
|
|
508
|
+
await addMessage(source.id, "assistant", "Message 2", undefined, {
|
|
509
|
+
skipIndexing: true,
|
|
510
|
+
});
|
|
511
|
+
|
|
512
|
+
const fork = forkConversation({ conversationId: source.id });
|
|
513
|
+
|
|
514
|
+
expect(fork.historyStrippedAt).toBeNull();
|
|
515
|
+
});
|
|
516
|
+
|
|
517
|
+
test("fork from a pre-compaction message preserves historical injection metadata", async () => {
|
|
518
|
+
const source = createConversation("Compacted thread");
|
|
519
|
+
const m1 = await addMessage(
|
|
520
|
+
source.id,
|
|
521
|
+
"user",
|
|
522
|
+
"Historical question",
|
|
523
|
+
{
|
|
524
|
+
pkbContextBlock: "<knowledge_base>\nstale\n</knowledge_base>",
|
|
525
|
+
nowScratchpadBlock:
|
|
526
|
+
"<NOW.md Always keep this up to date>\nstale\n</NOW.md>",
|
|
527
|
+
},
|
|
528
|
+
{ skipIndexing: true },
|
|
529
|
+
);
|
|
530
|
+
await addMessage(source.id, "assistant", "Reply 1", undefined, {
|
|
531
|
+
skipIndexing: true,
|
|
532
|
+
});
|
|
533
|
+
await addMessage(source.id, "user", "Tail turn", undefined, {
|
|
534
|
+
skipIndexing: true,
|
|
535
|
+
});
|
|
536
|
+
const compactedAt = Date.now();
|
|
537
|
+
getDb()
|
|
538
|
+
.update(conversations)
|
|
539
|
+
.set({
|
|
540
|
+
contextSummary: "summary",
|
|
541
|
+
contextCompactedMessageCount: 2,
|
|
542
|
+
contextCompactedAt: compactedAt,
|
|
543
|
+
historyStrippedAt: compactedAt,
|
|
544
|
+
})
|
|
545
|
+
.where(eq(conversations.id, source.id))
|
|
546
|
+
.run();
|
|
547
|
+
|
|
548
|
+
const fork = forkConversation({
|
|
549
|
+
conversationId: source.id,
|
|
550
|
+
throughMessageId: m1.id,
|
|
551
|
+
});
|
|
552
|
+
|
|
553
|
+
expect(fork.historyStrippedAt).toBeNull();
|
|
554
|
+
expect(fork.contextSummary).toBeNull();
|
|
555
|
+
expect(fork.contextCompactedMessageCount).toBe(0);
|
|
556
|
+
|
|
557
|
+
const forkedMessages = getMessages(fork.id);
|
|
558
|
+
expect(forkedMessages).toHaveLength(1);
|
|
559
|
+
const meta = parseMetadata(forkedMessages[0].metadata) as Record<
|
|
560
|
+
string,
|
|
561
|
+
unknown
|
|
562
|
+
>;
|
|
563
|
+
expect(meta.pkbContextBlock).toBe(
|
|
564
|
+
"<knowledge_base>\nstale\n</knowledge_base>",
|
|
565
|
+
);
|
|
566
|
+
expect(meta.nowScratchpadBlock).toBe(
|
|
567
|
+
"<NOW.md Always keep this up to date>\nstale\n</NOW.md>",
|
|
568
|
+
);
|
|
569
|
+
});
|
|
570
|
+
|
|
299
571
|
test("rejects forks when the source conversation has no persisted messages", () => {
|
|
300
572
|
const source = createConversation("Empty thread");
|
|
301
573
|
|
|
@@ -661,6 +933,58 @@ describe("forkConversation", () => {
|
|
|
661
933
|
expect(loadGraphMemoryState(fork.id)).toBeNull();
|
|
662
934
|
});
|
|
663
935
|
|
|
936
|
+
test("defaults conversationType to standard and inherits the parent's group", async () => {
|
|
937
|
+
const source = createConversation("Default inheritance thread");
|
|
938
|
+
await addMessage(source.id, "user", "first message", undefined, {
|
|
939
|
+
skipIndexing: true,
|
|
940
|
+
});
|
|
941
|
+
rawRun(
|
|
942
|
+
"UPDATE conversations SET group_id = ? WHERE id = ?",
|
|
943
|
+
"system:pinned",
|
|
944
|
+
source.id,
|
|
945
|
+
);
|
|
946
|
+
|
|
947
|
+
const fork = forkConversation({ conversationId: source.id });
|
|
948
|
+
const row = getDb()
|
|
949
|
+
.select()
|
|
950
|
+
.from(conversations)
|
|
951
|
+
.where(eq(conversations.id, fork.id))
|
|
952
|
+
.get();
|
|
953
|
+
const groupIdRow = rawGet<{ group_id: string | null }>(
|
|
954
|
+
"SELECT group_id FROM conversations WHERE id = ?",
|
|
955
|
+
fork.id,
|
|
956
|
+
);
|
|
957
|
+
|
|
958
|
+
expect(row?.conversationType).toBe("standard");
|
|
959
|
+
expect(groupIdRow?.group_id).toBe("system:pinned");
|
|
960
|
+
});
|
|
961
|
+
|
|
962
|
+
test("honors conversationType and groupId overrides on the fork", async () => {
|
|
963
|
+
const source = createConversation("Override thread");
|
|
964
|
+
await addMessage(source.id, "user", "first message", undefined, {
|
|
965
|
+
skipIndexing: true,
|
|
966
|
+
});
|
|
967
|
+
|
|
968
|
+
const fork = forkConversation({
|
|
969
|
+
conversationId: source.id,
|
|
970
|
+
conversationType: "background",
|
|
971
|
+
groupId: "system:background",
|
|
972
|
+
});
|
|
973
|
+
|
|
974
|
+
const row = getDb()
|
|
975
|
+
.select()
|
|
976
|
+
.from(conversations)
|
|
977
|
+
.where(eq(conversations.id, fork.id))
|
|
978
|
+
.get();
|
|
979
|
+
const groupIdRow = rawGet<{ group_id: string | null }>(
|
|
980
|
+
"SELECT group_id FROM conversations WHERE id = ?",
|
|
981
|
+
fork.id,
|
|
982
|
+
);
|
|
983
|
+
|
|
984
|
+
expect(row?.conversationType).toBe("background");
|
|
985
|
+
expect(groupIdRow?.group_id).toBe("system:background");
|
|
986
|
+
});
|
|
987
|
+
|
|
664
988
|
test("copies memory state when throughMessageId points at the last message", async () => {
|
|
665
989
|
const source = createConversation("Through-last thread");
|
|
666
990
|
const lastMessage = await addMessage(
|
|
@@ -8,7 +8,7 @@ mock.module("../util/logger.js", () => ({
|
|
|
8
8
|
|
|
9
9
|
mock.module("../providers/registry.js", () => ({
|
|
10
10
|
getProvider: () => ({ name: "mock-provider" }),
|
|
11
|
-
initializeProviders: () => {},
|
|
11
|
+
initializeProviders: async () => {},
|
|
12
12
|
}));
|
|
13
13
|
|
|
14
14
|
mock.module("../config/loader.js", () => ({
|
|
@@ -379,7 +379,7 @@ describe("loadFromDb metadata injection rehydration", () => {
|
|
|
379
379
|
metadata: JSON.stringify({
|
|
380
380
|
memoryInjectedBlock: "mem payload",
|
|
381
381
|
memoryV2StaticBlock:
|
|
382
|
-
"<
|
|
382
|
+
"<info>\n## Essentials\n\nAlice prefers VS Code.\n</info>",
|
|
383
383
|
pkbSystemReminderBlock:
|
|
384
384
|
"<system_reminder>\npkb payload\n</system_reminder>",
|
|
385
385
|
}),
|
|
@@ -406,7 +406,7 @@ describe("loadFromDb metadata injection rehydration", () => {
|
|
|
406
406
|
{ type: "text", text: "<memory>\nmem payload\n</memory>" },
|
|
407
407
|
{
|
|
408
408
|
type: "text",
|
|
409
|
-
text: "<
|
|
409
|
+
text: "<info>\n## Essentials\n\nAlice prefers VS Code.\n</info>",
|
|
410
410
|
},
|
|
411
411
|
{
|
|
412
412
|
type: "text",
|
|
@@ -416,6 +416,47 @@ describe("loadFromDb metadata injection rehydration", () => {
|
|
|
416
416
|
]);
|
|
417
417
|
});
|
|
418
418
|
|
|
419
|
+
test("legacy <memory>-wrapped memoryV2StaticBlock rehydrates verbatim", async () => {
|
|
420
|
+
// `meta.memoryV2StaticBlock` may carry either `<info>…</info>` or
|
|
421
|
+
// legacy `<memory>…</memory>` wrappers depending on when the row was
|
|
422
|
+
// persisted. The rehydrate path replays the stored text verbatim,
|
|
423
|
+
// so both wrappers must round-trip unchanged.
|
|
424
|
+
mockConversation = defaultConv();
|
|
425
|
+
mockDbMessages = [
|
|
426
|
+
{
|
|
427
|
+
id: "m1",
|
|
428
|
+
role: "user",
|
|
429
|
+
content: JSON.stringify([{ type: "text", text: "First turn" }]),
|
|
430
|
+
metadata: JSON.stringify({
|
|
431
|
+
memoryV2StaticBlock:
|
|
432
|
+
"<memory>\n## Essentials\n\nAlice prefers VS Code.\n</memory>",
|
|
433
|
+
}),
|
|
434
|
+
},
|
|
435
|
+
{
|
|
436
|
+
id: "m2",
|
|
437
|
+
role: "assistant",
|
|
438
|
+
content: JSON.stringify([{ type: "text", text: "Reply" }]),
|
|
439
|
+
},
|
|
440
|
+
{
|
|
441
|
+
id: "m3",
|
|
442
|
+
role: "user",
|
|
443
|
+
content: JSON.stringify([{ type: "text", text: "Tail turn" }]),
|
|
444
|
+
},
|
|
445
|
+
];
|
|
446
|
+
|
|
447
|
+
const conversation = makeConversation();
|
|
448
|
+
await conversation.loadFromDb();
|
|
449
|
+
const messages = conversation.getMessages();
|
|
450
|
+
|
|
451
|
+
expect(messages[0].content).toEqual([
|
|
452
|
+
{
|
|
453
|
+
type: "text",
|
|
454
|
+
text: "<memory>\n## Essentials\n\nAlice prefers VS Code.\n</memory>",
|
|
455
|
+
},
|
|
456
|
+
{ type: "text", text: "First turn" },
|
|
457
|
+
]);
|
|
458
|
+
});
|
|
459
|
+
|
|
419
460
|
test("tail user row skips memoryV2StaticBlock", async () => {
|
|
420
461
|
mockConversation = defaultConv();
|
|
421
462
|
mockDbMessages = [
|
|
@@ -434,7 +475,7 @@ describe("loadFromDb metadata injection rehydration", () => {
|
|
|
434
475
|
role: "user",
|
|
435
476
|
content: JSON.stringify([{ type: "text", text: "Tail" }]),
|
|
436
477
|
metadata: JSON.stringify({
|
|
437
|
-
memoryV2StaticBlock: "<
|
|
478
|
+
memoryV2StaticBlock: "<info>\n## Essentials\n\nleak\n</info>",
|
|
438
479
|
}),
|
|
439
480
|
},
|
|
440
481
|
];
|
|
@@ -471,7 +512,7 @@ describe("loadFromDb metadata injection rehydration", () => {
|
|
|
471
512
|
// survive the row-level filter for non-guardian views.
|
|
472
513
|
provenanceTrustClass: "trusted_contact",
|
|
473
514
|
memoryV2StaticBlock:
|
|
474
|
-
"<
|
|
515
|
+
"<info>\n## Essentials\n\nAlice prefers VS Code.\n</info>",
|
|
475
516
|
}),
|
|
476
517
|
},
|
|
477
518
|
{
|
|
@@ -500,7 +541,7 @@ describe("loadFromDb metadata injection rehydration", () => {
|
|
|
500
541
|
expect(messages[0].content).toEqual([
|
|
501
542
|
{
|
|
502
543
|
type: "text",
|
|
503
|
-
text: "<
|
|
544
|
+
text: "<info>\n## Essentials\n\nAlice prefers VS Code.\n</info>",
|
|
504
545
|
},
|
|
505
546
|
{ type: "text", text: "First" },
|
|
506
547
|
]);
|
|
@@ -510,7 +551,7 @@ describe("loadFromDb metadata injection rehydration", () => {
|
|
|
510
551
|
// Injection-time layout (per `applyRuntimeInjections` after-memory-
|
|
511
552
|
// prefix splicing in ascending injector order: pkb-context 30,
|
|
512
553
|
// pkb-reminder 35, memory-v2-static 38, now-md 40):
|
|
513
|
-
// [<memory
|
|
554
|
+
// [<memory>dynamic</memory>, <info>v2static</info>, <NOW.md>,
|
|
514
555
|
// <system_reminder>, <knowledge_base>, ...original]
|
|
515
556
|
// Rehydration must reproduce this exactly so Anthropic's prefix cache
|
|
516
557
|
// matches msg[0] across daemon restarts.
|
|
@@ -523,7 +564,7 @@ describe("loadFromDb metadata injection rehydration", () => {
|
|
|
523
564
|
metadata: JSON.stringify({
|
|
524
565
|
memoryInjectedBlock: "mem payload",
|
|
525
566
|
memoryV2StaticBlock:
|
|
526
|
-
"<
|
|
567
|
+
"<info>\n## Essentials\n\nAlice prefers VS Code.\n</info>",
|
|
527
568
|
nowScratchpadBlock: "<NOW.md>\nnow body\n</NOW.md>",
|
|
528
569
|
pkbSystemReminderBlock:
|
|
529
570
|
"<system_reminder>\npkb reminder body\n</system_reminder>",
|
|
@@ -551,7 +592,7 @@ describe("loadFromDb metadata injection rehydration", () => {
|
|
|
551
592
|
{ type: "text", text: "<memory>\nmem payload\n</memory>" },
|
|
552
593
|
{
|
|
553
594
|
type: "text",
|
|
554
|
-
text: "<
|
|
595
|
+
text: "<info>\n## Essentials\n\nAlice prefers VS Code.\n</info>",
|
|
555
596
|
},
|
|
556
597
|
{ type: "text", text: "<NOW.md>\nnow body\n</NOW.md>" },
|
|
557
598
|
{
|
|
@@ -575,7 +616,7 @@ describe("loadFromDb metadata injection rehydration", () => {
|
|
|
575
616
|
metadata: JSON.stringify({
|
|
576
617
|
provenanceTrustClass: "trusted_contact",
|
|
577
618
|
memoryV2StaticBlock:
|
|
578
|
-
"<
|
|
619
|
+
"<info>\n## Essentials\n\nprivate memory\n</info>",
|
|
579
620
|
}),
|
|
580
621
|
},
|
|
581
622
|
{
|
|
@@ -621,7 +662,7 @@ describe("loadFromDb metadata injection rehydration", () => {
|
|
|
621
662
|
metadata: JSON.stringify({
|
|
622
663
|
provenanceTrustClass: "trusted_contact",
|
|
623
664
|
memoryV2StaticBlock:
|
|
624
|
-
"<
|
|
665
|
+
"<info>\n## Essentials\n\nprivate memory\n</info>",
|
|
625
666
|
}),
|
|
626
667
|
},
|
|
627
668
|
{
|
|
@@ -649,7 +690,7 @@ describe("loadFromDb metadata injection rehydration", () => {
|
|
|
649
690
|
expect(conversation.getMessages()[0].content).toEqual([
|
|
650
691
|
{
|
|
651
692
|
type: "text",
|
|
652
|
-
text: "<
|
|
693
|
+
text: "<info>\n## Essentials\n\nprivate memory\n</info>",
|
|
653
694
|
},
|
|
654
695
|
{ type: "text", text: "First" },
|
|
655
696
|
]);
|
|
@@ -10,7 +10,7 @@ mock.module("../util/logger.js", () => ({
|
|
|
10
10
|
|
|
11
11
|
mock.module("../providers/registry.js", () => ({
|
|
12
12
|
getProvider: () => ({ name: "mock-provider" }),
|
|
13
|
-
initializeProviders: () => {},
|
|
13
|
+
initializeProviders: async () => {},
|
|
14
14
|
}));
|
|
15
15
|
|
|
16
16
|
mock.module("../config/loader.js", () => ({
|