@vellumai/assistant 0.8.4 → 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/docs/browser-use-architecture-phase2.md +1 -1
- package/knip.json +2 -1
- package/openapi.yaml +809 -11
- package/package.json +1 -1
- package/src/__tests__/anthropic-provider.test.ts +34 -37
- 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 +3 -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-guardian.test.ts +3 -3
- package/src/__tests__/checker.test.ts +6 -15
- package/src/__tests__/compaction-events.test.ts +1 -0
- package/src/__tests__/compactor-call-site-logging.test.ts +214 -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__/confirmation-request-guardian-bridge.test.ts +0 -1
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +1 -1
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +1 -1
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +197 -2
- package/src/__tests__/conversation-agent-loop.test.ts +163 -122
- package/src/__tests__/conversation-app-control-instantiation.test.ts +2 -5
- package/src/__tests__/conversation-clear-safety.test.ts +25 -25
- 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 +178 -15
- package/src/__tests__/conversation-lifecycle.test.ts +52 -11
- package/src/__tests__/{conversation-load-cleaned-at.test.ts → conversation-load-history-stripped.test.ts} +13 -13
- package/src/__tests__/conversation-provider-retry-repair.test.ts +1 -0
- 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-skill-tools.test.ts +2 -5
- package/src/__tests__/conversation-store.test.ts +1 -1
- package/src/__tests__/conversation-sync-tags.test.ts +99 -32
- package/src/__tests__/conversation-workspace-cache-state.test.ts +1 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +1 -1
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +1 -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 +1 -0
- package/src/__tests__/credential-vault-unit.test.ts +2 -2
- package/src/__tests__/dynamic-page-surface.test.ts +2 -2
- package/src/__tests__/email-html-renderer.test.ts +12 -0
- 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__/heartbeat-disk-pressure.test.ts +4 -0
- package/src/__tests__/heartbeat-service.test.ts +4 -0
- package/src/__tests__/host-shell-tool.test.ts +1 -1
- package/src/__tests__/init-feature-flag-overrides.test.ts +5 -6
- package/src/__tests__/list-messages-tool-merge.test.ts +70 -11
- 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 +77 -9
- package/src/__tests__/llm-usage-store.test.ts +66 -0
- 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__/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 +46 -0
- package/src/__tests__/openai-responses-provider.test.ts +114 -12
- package/src/__tests__/pending-interactions-resolved-event.test.ts +0 -1
- package/src/__tests__/platform-bash-auto-approve.test.ts +2 -2
- package/src/__tests__/platform.test.ts +2 -2
- package/src/__tests__/plugin-api-tool-definition.test.ts +92 -0
- package/src/__tests__/plugin-bootstrap.test.ts +2 -2
- 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__/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__/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__/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 +145 -131
- package/src/__tests__/terminal-tools.test.ts +1 -1
- 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 +9 -62
- package/src/__tests__/tool-grant-request-escalation.test.ts +1 -6
- 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__/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__/workspace-git-service.test.ts +6 -5
- package/src/__tests__/workspace-migration-089-move-memory-tree-out-of-v3.test.ts +86 -0
- package/src/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/loop.ts +8 -0
- 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/runtime-registry.ts +24 -0
- package/src/cli/commands/__tests__/browser.test.ts +23 -5
- package/src/cli/commands/__tests__/domain-register.test.ts +110 -0
- package/src/cli/commands/__tests__/domain-status.test.ts +33 -33
- package/src/cli/commands/__tests__/inference-send.test.ts +108 -5
- package/src/cli/commands/__tests__/memory-v2-compare-render.test.ts +98 -0
- package/src/cli/commands/__tests__/memory-v2.test.ts +1 -0
- package/src/cli/commands/__tests__/memory-v3-render.test.ts +340 -0
- package/src/cli/commands/browser.ts +247 -0
- package/src/cli/commands/domain.ts +91 -41
- package/src/cli/commands/inference.ts +93 -40
- package/src/cli/commands/memory-v2-compare-render.ts +115 -0
- package/src/cli/commands/memory-v2.ts +176 -1
- package/src/cli/commands/memory-v3-render.ts +344 -0
- package/src/cli/commands/memory-v3.ts +316 -0
- package/src/cli/program.ts +2 -0
- package/src/config/assistant-feature-flags.ts +21 -9
- package/src/config/bundled-skills/document-editor/SKILL.md +11 -2
- package/src/config/bundled-skills/document-editor/TOOLS.json +18 -0
- package/src/config/bundled-skills/document-editor/tools/document-open.ts +12 -0
- package/src/config/bundled-skills/image-studio/SKILL.md +4 -0
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +2 -2
- package/src/config/bundled-skills/media-processing/tools/ingest-media.ts +13 -8
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +10 -3
- package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +16 -14
- package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +7 -2
- package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +7 -2
- package/src/config/bundled-tool-registry.ts +2 -0
- package/src/config/call-site-defaults.ts +7 -6
- package/src/config/feature-flag-registry.json +16 -0
- package/src/config/schemas/__tests__/memory-v2.test.ts +213 -1
- package/src/config/schemas/call-site-catalog.ts +21 -7
- package/src/config/schemas/llm.ts +12 -1
- package/src/config/schemas/memory-v2.ts +246 -0
- package/src/config/schemas/memory.ts +2 -1
- package/src/context/compactor.ts +52 -0
- package/src/conversations/__tests__/message-consolidation.test.ts +350 -0
- package/src/conversations/message-consolidation.ts +404 -0
- package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +1 -1
- package/src/daemon/__tests__/meet-manifest-loader.test.ts +1 -1
- package/src/daemon/conversation-agent-loop-handlers.ts +2 -13
- package/src/daemon/conversation-agent-loop.ts +126 -76
- package/src/daemon/conversation-error.ts +31 -1
- package/src/daemon/conversation-lifecycle.ts +27 -22
- package/src/daemon/conversation-runtime-assembly.ts +10 -9
- package/src/daemon/conversation-tool-setup.ts +63 -3
- package/src/daemon/conversation-usage.ts +2 -0
- package/src/daemon/conversation.ts +14 -29
- package/src/daemon/disk-pressure-guard.ts +14 -2
- package/src/daemon/handlers/config-model.test.ts +1 -0
- package/src/daemon/handlers/conversations.ts +11 -3
- package/src/daemon/host-browser-proxy.ts +5 -5
- package/src/daemon/host-cu-proxy.ts +4 -4
- package/src/daemon/host-file-proxy.ts +4 -4
- package/src/daemon/host-proxy-base.ts +4 -4
- package/src/daemon/host-transfer-proxy.ts +10 -10
- package/src/daemon/lifecycle.ts +23 -20
- package/src/daemon/meet-manifest-loader.ts +1 -7
- package/src/daemon/message-types/conversations.ts +6 -9
- package/src/daemon/message-types/home.ts +1 -13
- package/src/daemon/message-types/messages.ts +6 -14
- package/src/daemon/message-types/sync.ts +14 -0
- 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/events/relationship-state-updated.ts +25 -0
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +1 -1
- package/src/home/home-greeting.ts +0 -9
- package/src/home/suggested-prompts.ts +0 -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__/memory-retrospective-job.test.ts +7 -0
- package/src/memory/auto-analysis-enqueue.ts +5 -1
- package/src/memory/conversation-crud.ts +71 -70
- 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 +10 -0
- package/src/memory/db-maintenance.ts +30 -21
- 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 +55 -22
- 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-enqueue.ts +8 -1
- package/src/memory/memory-retrospective-job.ts +5 -0
- package/src/memory/memory-v2-activation-log-store.ts +15 -6
- 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 +17 -0
- package/src/memory/migrations/registry.ts +33 -0
- package/src/memory/schema/conversations.ts +1 -1
- package/src/memory/schema/infrastructure.ts +21 -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.test.ts +127 -98
- package/src/memory/v2/__tests__/qdrant.test.ts +36 -0
- package/src/memory/v2/__tests__/router.test.ts +171 -3
- package/src/memory/v2/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.ts +21 -15
- package/src/memory/v2/prompts/router.ts +26 -1
- package/src/memory/v2/qdrant.ts +14 -2
- package/src/memory/v2/router.ts +171 -18
- package/src/memory/v3/__tests__/coactivation-store.test.ts +422 -0
- package/src/memory/v3/__tests__/consolidation-job.test.ts +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/notifications/adapters/macos.ts +18 -1
- package/src/notifications/adapters/platform.ts +1 -1
- package/src/notifications/decision-engine.ts +1 -4
- package/src/notifications/emit-signal.ts +29 -49
- package/src/permissions/prompter.ts +3 -3
- package/src/permissions/question-prompter.ts +5 -2
- package/src/permissions/secret-prompter.ts +2 -2
- package/src/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 +18 -11
- 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__/task-progress-hint-section.test.ts +3 -9
- package/src/prompts/persona-resolver.ts +36 -21
- package/src/prompts/sections.ts +39 -7
- package/src/prompts/system-prompt.ts +50 -185
- package/src/prompts/templates/BOOTSTRAP.md +2 -2
- package/src/prompts/templates/system-sections.ts +230 -8
- 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 +32 -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/gemini/client.ts +49 -6
- package/src/providers/inference/adapter-factory.ts +3 -0
- package/src/providers/minimax/client.ts +106 -0
- package/src/providers/model-catalog.ts +43 -0
- package/src/providers/model-intents.ts +1 -1
- package/src/providers/openai/chat-completions-provider.ts +6 -3
- package/src/providers/openai/codex-models.ts +18 -0
- package/src/providers/openai/responses-provider.ts +78 -21
- 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/usage-tracking.ts +2 -0
- package/src/runtime/AGENTS.md +2 -2
- package/src/runtime/agent-wake.ts +1 -0
- package/src/runtime/assistant-event-hub.ts +76 -6
- package/src/runtime/auth/route-policy.ts +36 -0
- package/src/runtime/btw-sidechain.ts +0 -6
- package/src/runtime/http-types.ts +0 -2
- package/src/runtime/migrations/vbundle-builder.ts +10 -3
- package/src/runtime/pending-interactions.ts +0 -1
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +106 -0
- package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +25 -6
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +512 -0
- package/src/runtime/routes/acp-routes.test.ts +255 -6
- package/src/runtime/routes/acp-routes.ts +8 -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/conversation-cli-routes.ts +1 -1
- 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 +142 -36
- package/src/runtime/routes/conversation-routes.ts +252 -410
- package/src/runtime/routes/conversation-starter-routes.ts +6 -3
- package/src/runtime/routes/disk-pressure-routes.ts +1 -1
- package/src/runtime/routes/domain-routes.ts +60 -10
- package/src/runtime/routes/email-routes.ts +5 -2
- package/src/runtime/routes/events-routes.ts +54 -10
- package/src/runtime/routes/group-routes.ts +24 -8
- package/src/runtime/routes/host-browser-routes.ts +10 -2
- package/src/runtime/routes/host-cu-routes.ts +2 -2
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +96 -3
- package/src/runtime/routes/index.ts +8 -0
- package/src/runtime/routes/inference-profile-session-handler.ts +22 -12
- package/src/runtime/routes/inference-profile-session-routes.ts +7 -1
- package/src/runtime/routes/llm-call-sites-routes.ts +32 -5
- package/src/runtime/routes/memory-item-routes.ts +8 -3
- package/src/runtime/routes/memory-v2-routes.ts +215 -5
- package/src/runtime/routes/memory-v3-routes.ts +316 -0
- package/src/runtime/routes/migration-routes.ts +21 -24
- package/src/runtime/routes/plugins-routes.ts +337 -0
- package/src/runtime/routes/rename-conversation-routes.ts +6 -2
- package/src/runtime/routes/secret-routes.ts +25 -5
- package/src/runtime/routes/settings-routes.ts +12 -11
- package/src/runtime/routes/slack-channel-routes.ts +5 -4
- package/src/runtime/routes/workspace-routes.ts +25 -10
- 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/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 +70 -0
- package/src/tools/browser/browser-execution.ts +16 -3
- package/src/tools/browser/cdp-client/__tests__/browser-tabs-factory.test.ts +402 -0
- package/src/tools/browser/cdp-client/__tests__/types.test.ts +3 -0
- package/src/tools/browser/cdp-client/cdp-inspect-client.ts +12 -0
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +27 -1
- package/src/tools/browser/cdp-client/factory.ts +100 -17
- package/src/tools/browser/cdp-client/local-cdp-client.ts +12 -0
- package/src/tools/browser/cdp-client/types.ts +65 -0
- package/src/tools/browser/pinned-tabs.ts +96 -40
- package/src/tools/computer-use/definitions.ts +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-tool.ts +59 -0
- 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/web-fetch.ts +3 -9
- package/src/tools/network/web-search.ts +25 -32
- 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/shell.ts +3 -9
- package/src/tools/tool-defaults.ts +94 -0
- package/src/tools/types.ts +27 -98
- package/src/tools/ui-surface/definitions.ts +6 -22
- package/src/usage/pricing.ts +23 -0
- package/src/usage/types.ts +12 -0
- package/src/util/logger.ts +16 -7
- package/src/util/platform.ts +7 -2
- package/src/util/sqlite3-runtime.ts +65 -0
- package/src/workspace/migrations/086-revert-stale-gemini-mis-rewrites.ts +1 -0
- package/src/workspace/migrations/089-move-memory-tree-out-of-v3.ts +86 -0
- package/src/workspace/migrations/registry.ts +2 -0
- package/src/__tests__/compaction-strip-metadata-clear.test.ts +0 -206
- package/src/__tests__/message-complete-display-id.test.ts +0 -175
- package/src/daemon/query-complexity-router.ts +0 -75
- package/src/prompts/cache-boundary.ts +0 -8
|
@@ -247,6 +247,10 @@ export class AssistantEventHub {
|
|
|
247
247
|
* Publish an event to all matching subscribers.
|
|
248
248
|
*
|
|
249
249
|
* Matching rules:
|
|
250
|
+
* - if `excludeClientId` is set, the subscriber with that clientId is
|
|
251
|
+
* skipped regardless of every other rule (self-echo suppression — the
|
|
252
|
+
* client that originated the mutation does not receive its own
|
|
253
|
+
* invalidation back through the hub).
|
|
250
254
|
* - if `targetClientId` is set, deliver only to the subscriber with that
|
|
251
255
|
* clientId, bypassing the conversation-id filter entirely (the web-origin
|
|
252
256
|
* event's conversationId differs from the macOS client's subscribed
|
|
@@ -255,6 +259,11 @@ export class AssistantEventHub {
|
|
|
255
259
|
* `event.conversationId` must equal it
|
|
256
260
|
* - if `targetCapability` is set, only subscribers whose capabilities include
|
|
257
261
|
* it receive the event; untargeted events go to all
|
|
262
|
+
* - if `targetInterfaceId` is set, only client subscribers whose
|
|
263
|
+
* `interfaceId` matches receive the event; process subscribers and
|
|
264
|
+
* non-matching clients are skipped. Used to narrow legacy
|
|
265
|
+
* broadcasts (e.g. `conversation_list_invalidated`) to a specific
|
|
266
|
+
* client surface during a migration window.
|
|
258
267
|
*
|
|
259
268
|
* Fanout is isolated: a throwing or rejecting subscriber does not abort
|
|
260
269
|
* delivery to remaining subscribers.
|
|
@@ -264,6 +273,15 @@ export class AssistantEventHub {
|
|
|
264
273
|
options?: {
|
|
265
274
|
targetCapability?: HostProxyCapability;
|
|
266
275
|
targetClientId?: string;
|
|
276
|
+
targetInterfaceId?: InterfaceId;
|
|
277
|
+
/**
|
|
278
|
+
* Skip the subscriber with this `clientId`. Used for self-echo
|
|
279
|
+
* suppression on `sync_changed`: the route handler echoes the
|
|
280
|
+
* originating tab's `X-Vellum-Client-Id` back on the event, and the
|
|
281
|
+
* hub uses it here to avoid re-delivering the invalidation to the
|
|
282
|
+
* tab that already mutated its own optimistic state.
|
|
283
|
+
*/
|
|
284
|
+
excludeClientId?: string;
|
|
267
285
|
},
|
|
268
286
|
): Promise<void> {
|
|
269
287
|
if (event.conversationId) {
|
|
@@ -276,12 +294,33 @@ export class AssistantEventHub {
|
|
|
276
294
|
|
|
277
295
|
const targetCapability = options?.targetCapability;
|
|
278
296
|
const targetClientId = options?.targetClientId;
|
|
297
|
+
const targetInterfaceId = options?.targetInterfaceId;
|
|
298
|
+
const excludeClientId = options?.excludeClientId;
|
|
279
299
|
const snapshot = Array.from(this.subscribers);
|
|
280
300
|
const errors: unknown[] = [];
|
|
281
301
|
|
|
282
302
|
for (const entry of snapshot) {
|
|
283
303
|
if (!entry.active) continue;
|
|
284
304
|
|
|
305
|
+
// Self-echo suppression: the originating client never receives the
|
|
306
|
+
// event back. Checked before every other rule so it composes with
|
|
307
|
+
// both targeted and untargeted broadcasts.
|
|
308
|
+
if (
|
|
309
|
+
excludeClientId != null &&
|
|
310
|
+
entry.type === "client" &&
|
|
311
|
+
entry.clientId === excludeClientId
|
|
312
|
+
) {
|
|
313
|
+
continue;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// Interface targeting: skip any subscriber that is not a client of
|
|
317
|
+
// the requested interface. Composes with `targetClientId` and
|
|
318
|
+
// `targetCapability` below.
|
|
319
|
+
if (targetInterfaceId != null) {
|
|
320
|
+
if (entry.type !== "client" || entry.interfaceId !== targetInterfaceId)
|
|
321
|
+
continue;
|
|
322
|
+
}
|
|
323
|
+
|
|
285
324
|
if (targetClientId != null) {
|
|
286
325
|
// Targeted: bypass conversation filter, deliver only to the named client.
|
|
287
326
|
if (entry.type !== "client" || entry.clientId !== targetClientId)
|
|
@@ -519,10 +558,11 @@ let _hubChain = Promise.resolve();
|
|
|
519
558
|
export function broadcastMessage(
|
|
520
559
|
msg: ServerMessage,
|
|
521
560
|
conversationId?: string,
|
|
522
|
-
options?: { targetClientId?: string },
|
|
561
|
+
options?: { targetClientId?: string; targetInterfaceId?: InterfaceId },
|
|
523
562
|
): void {
|
|
524
563
|
const resolvedConversationId = conversationId ?? extractConversationId(msg);
|
|
525
564
|
const targetClientId = options?.targetClientId;
|
|
565
|
+
const targetInterfaceId = options?.targetInterfaceId;
|
|
526
566
|
|
|
527
567
|
// Confirmation-request side effects: canonical guardian request creation.
|
|
528
568
|
// The home-feed `activity.failed` notification side-effect lives in the
|
|
@@ -539,16 +579,45 @@ export function broadcastMessage(
|
|
|
539
579
|
: resolvedConversationId;
|
|
540
580
|
const event = buildAssistantEvent(msg, scopedConversationId);
|
|
541
581
|
const targetCapability = capabilityForMessageType(msg.type);
|
|
582
|
+
// Self-echo suppression: a `sync_changed` carrying an `originClientId`
|
|
583
|
+
// means a specific client just mutated the resource. The hub must not
|
|
584
|
+
// re-deliver the invalidation to that client — it already updated its
|
|
585
|
+
// optimistic state locally and a redundant invalidation would clobber it
|
|
586
|
+
// with a flash of stale-then-fresh data. Assistant-internal emits (agent
|
|
587
|
+
// loop, FS watcher, cron) leave `originClientId` unset and the event
|
|
588
|
+
// fans out to every subscriber as before.
|
|
589
|
+
const excludeClientId =
|
|
590
|
+
msg.type === "sync_changed" &&
|
|
591
|
+
typeof msg.originClientId === "string" &&
|
|
592
|
+
msg.originClientId.length > 0
|
|
593
|
+
? msg.originClientId
|
|
594
|
+
: undefined;
|
|
542
595
|
const publishOptions =
|
|
543
|
-
targetCapability != null ||
|
|
544
|
-
|
|
596
|
+
targetCapability != null ||
|
|
597
|
+
targetClientId != null ||
|
|
598
|
+
targetInterfaceId != null ||
|
|
599
|
+
excludeClientId != null
|
|
600
|
+
? {
|
|
601
|
+
targetCapability,
|
|
602
|
+
targetClientId,
|
|
603
|
+
targetInterfaceId,
|
|
604
|
+
excludeClientId,
|
|
605
|
+
}
|
|
545
606
|
: undefined;
|
|
546
607
|
_hubChain = _hubChain
|
|
547
608
|
.then(() => assistantEventHub.publish(event, publishOptions))
|
|
548
609
|
.then(() => {
|
|
549
|
-
// When a conversation title changes, also
|
|
550
|
-
// `conversation_list_invalidated` so
|
|
551
|
-
//
|
|
610
|
+
// When a conversation title changes, also publish a
|
|
611
|
+
// `conversation_list_invalidated` so the macOS sidebar refreshes
|
|
612
|
+
// its row ordering for the renamed conversation. Web consumes the
|
|
613
|
+
// paired `sync_changed` with `conversation:<id>:metadata` tag
|
|
614
|
+
// emitted by `publishConversationTitleChanged` and patches the
|
|
615
|
+
// single row in place, so the broadcast is scoped to macOS only.
|
|
616
|
+
//
|
|
617
|
+
// TODO(electron-cutover): remove this emission once macOS migrates
|
|
618
|
+
// to the Electron client and consumes `sync_changed` directly. At
|
|
619
|
+
// that point `conversation_list_invalidated` has no remaining
|
|
620
|
+
// consumers and the message type can be retired.
|
|
552
621
|
if (msg.type === "conversation_title_updated") {
|
|
553
622
|
return assistantEventHub
|
|
554
623
|
.publish(
|
|
@@ -556,6 +625,7 @@ export function broadcastMessage(
|
|
|
556
625
|
type: "conversation_list_invalidated",
|
|
557
626
|
reason: "renamed",
|
|
558
627
|
}),
|
|
628
|
+
{ targetInterfaceId: "macos" },
|
|
559
629
|
)
|
|
560
630
|
.catch((err: unknown) => {
|
|
561
631
|
log.warn(
|
|
@@ -417,6 +417,7 @@ const ACTOR_ENDPOINTS: Array<{ endpoint: string; scopes: Scope[] }> = [
|
|
|
417
417
|
|
|
418
418
|
// LLM call site catalog
|
|
419
419
|
{ endpoint: "config/llm/call-sites:GET", scopes: ["settings.read"] },
|
|
420
|
+
{ endpoint: "config/llm/profiles:GET", scopes: ["settings.read"] },
|
|
420
421
|
|
|
421
422
|
// Conversation management
|
|
422
423
|
{ endpoint: "conversations:DELETE", scopes: ["chat.write"] },
|
|
@@ -440,6 +441,7 @@ const ACTOR_ENDPOINTS: Array<{ endpoint: string; scopes: Scope[] }> = [
|
|
|
440
441
|
// Message content
|
|
441
442
|
{ endpoint: "messages/content", scopes: ["chat.read"] },
|
|
442
443
|
{ endpoint: "messages/llm-context", scopes: ["chat.read"] },
|
|
444
|
+
{ endpoint: "conversations/llm-context", scopes: ["chat.read"] },
|
|
443
445
|
{ endpoint: "llm-request-logs/payload", scopes: ["chat.read"] },
|
|
444
446
|
{ endpoint: "messages/tts", scopes: ["chat.read"] },
|
|
445
447
|
{ endpoint: "tts/synthesize", scopes: ["chat.read"] },
|
|
@@ -458,6 +460,11 @@ const ACTOR_ENDPOINTS: Array<{ endpoint: string; scopes: Scope[] }> = [
|
|
|
458
460
|
{ endpoint: "skills:DELETE", scopes: ["settings.write"] },
|
|
459
461
|
{ endpoint: "skills:PATCH", scopes: ["settings.write"] },
|
|
460
462
|
|
|
463
|
+
// Plugins (read-only for now — install / uninstall stay CLI-side)
|
|
464
|
+
{ endpoint: "plugins:GET", scopes: ["settings.read"] },
|
|
465
|
+
{ endpoint: "plugins/search:GET", scopes: ["settings.read"] },
|
|
466
|
+
{ endpoint: "plugins:DELETE", scopes: ["settings.write"] },
|
|
467
|
+
|
|
461
468
|
// Memory items
|
|
462
469
|
{ endpoint: "memory-items:GET", scopes: ["settings.read"] },
|
|
463
470
|
{ endpoint: "memory-items:POST", scopes: ["settings.write"] },
|
|
@@ -471,6 +478,18 @@ const ACTOR_ENDPOINTS: Array<{ endpoint: string; scopes: Scope[] }> = [
|
|
|
471
478
|
{ endpoint: "memory/v2/concept-frequency:POST", scopes: ["settings.read"] },
|
|
472
479
|
{ endpoint: "memory/v2/ema-scores:POST", scopes: ["settings.read"] },
|
|
473
480
|
{ endpoint: "memory/v2/simulate-router:POST", scopes: ["settings.read"] },
|
|
481
|
+
{
|
|
482
|
+
endpoint: "memory/v2/compare-retrievers:POST",
|
|
483
|
+
scopes: ["settings.read"],
|
|
484
|
+
},
|
|
485
|
+
{
|
|
486
|
+
endpoint: "memory/v2/router-prompt-template:GET",
|
|
487
|
+
scopes: ["settings.read"],
|
|
488
|
+
},
|
|
489
|
+
{ endpoint: "memory/v2/now-text:GET", scopes: ["settings.read"] },
|
|
490
|
+
{ endpoint: "memory/v3/validate:POST", scopes: ["settings.read"] },
|
|
491
|
+
{ endpoint: "memory/v3/tree:POST", scopes: ["settings.read"] },
|
|
492
|
+
{ endpoint: "memory/v3/simulate:POST", scopes: ["settings.read"] },
|
|
474
493
|
|
|
475
494
|
// Trust rule listing
|
|
476
495
|
{ endpoint: "trust-rules/manage:GET", scopes: ["settings.read"] },
|
|
@@ -665,6 +684,12 @@ registerPolicy("channels/inbound", {
|
|
|
665
684
|
allowedPrincipalTypes: ["svc_gateway"],
|
|
666
685
|
});
|
|
667
686
|
|
|
687
|
+
// Background wake control-plane calls from the platform.
|
|
688
|
+
registerPolicy("background-wake", {
|
|
689
|
+
requiredScopes: ["internal.write"],
|
|
690
|
+
allowedPrincipalTypes: ["svc_gateway"],
|
|
691
|
+
});
|
|
692
|
+
|
|
668
693
|
// Internal forwarding endpoints: gateway-only
|
|
669
694
|
const INTERNAL_ENDPOINTS = [
|
|
670
695
|
"internal/twilio/voice-webhook",
|
|
@@ -887,6 +912,12 @@ registerPolicy("browser/execute", {
|
|
|
887
912
|
allowedPrincipalTypes: ["local"],
|
|
888
913
|
});
|
|
889
914
|
|
|
915
|
+
// Browser tabs operations (list/select/new/close): local-only (CLI / IPC callers)
|
|
916
|
+
registerPolicy("browser/tabs", {
|
|
917
|
+
requiredScopes: ["settings.write"],
|
|
918
|
+
allowedPrincipalTypes: ["local"],
|
|
919
|
+
});
|
|
920
|
+
|
|
890
921
|
// Background tools: local-only (CLI / IPC callers)
|
|
891
922
|
registerPolicy("background-tools", {
|
|
892
923
|
requiredScopes: ["settings.read"],
|
|
@@ -922,6 +953,11 @@ registerPolicy("domain/status", {
|
|
|
922
953
|
allowedPrincipalTypes: ["local"],
|
|
923
954
|
});
|
|
924
955
|
|
|
956
|
+
registerPolicy("domain/verification-status", {
|
|
957
|
+
requiredScopes: ["settings.read"],
|
|
958
|
+
allowedPrincipalTypes: ["local"],
|
|
959
|
+
});
|
|
960
|
+
|
|
925
961
|
// Email management (IPC-local)
|
|
926
962
|
registerPolicy("email/register", {
|
|
927
963
|
requiredScopes: ["settings.write"],
|
|
@@ -40,9 +40,6 @@ export interface RunBtwSidechainParams {
|
|
|
40
40
|
signal?: AbortSignal;
|
|
41
41
|
timeoutMs?: number;
|
|
42
42
|
onEvent?: (event: ProviderEvent) => void;
|
|
43
|
-
userPersona?: string | null;
|
|
44
|
-
channelPersona?: string | null;
|
|
45
|
-
userSlug?: string | null;
|
|
46
43
|
}
|
|
47
44
|
|
|
48
45
|
export interface RunBtwSidechainResult {
|
|
@@ -79,9 +76,6 @@ export async function runBtwSidechain(
|
|
|
79
76
|
: buildSystemPrompt({
|
|
80
77
|
excludeBootstrap: true,
|
|
81
78
|
excludeCustomPrefix: true,
|
|
82
|
-
userPersona: params.userPersona,
|
|
83
|
-
channelPersona: params.channelPersona,
|
|
84
|
-
userSlug: params.userSlug,
|
|
85
79
|
}));
|
|
86
80
|
|
|
87
81
|
const { signal: timeoutSignal, cleanup } = createTimeout(
|
|
@@ -148,8 +148,6 @@ export interface RuntimeAttachmentMetadata {
|
|
|
148
148
|
|
|
149
149
|
export interface RuntimeMessagePayload {
|
|
150
150
|
id: string;
|
|
151
|
-
/** Concrete persisted assistant row id for row-scoped actions. */
|
|
152
|
-
daemonMessageId?: string;
|
|
153
151
|
role: string;
|
|
154
152
|
content: string;
|
|
155
153
|
timestamp: string;
|
|
@@ -681,8 +681,13 @@ export interface BuildExportVBundleOptions {
|
|
|
681
681
|
* flushed to the main .db file. Callers should pass a function that runs
|
|
682
682
|
* PRAGMA wal_checkpoint(TRUNCATE) on the live database connection.
|
|
683
683
|
* Called before the workspace walk so the DB file is up to date.
|
|
684
|
+
*
|
|
685
|
+
* May return a Promise — `streamExportVBundle` awaits the result so an
|
|
686
|
+
* async-dispatched checkpoint (e.g. via `runAsyncSqlite`) does not race
|
|
687
|
+
* with the file walk. The synchronous `buildExportVBundle` path does
|
|
688
|
+
* not await; pass a sync callback there.
|
|
684
689
|
*/
|
|
685
|
-
checkpoint?: () => void
|
|
690
|
+
checkpoint?: () => void | Promise<void>;
|
|
686
691
|
/** Optional credential entries to include in the archive under credentials/ prefix. */
|
|
687
692
|
credentials?: Array<{ account: string; value: string }>;
|
|
688
693
|
}
|
|
@@ -1120,9 +1125,11 @@ export async function streamExportVBundle(
|
|
|
1120
1125
|
credentials,
|
|
1121
1126
|
} = options;
|
|
1122
1127
|
|
|
1123
|
-
// Flush WAL to the main database file before reading
|
|
1128
|
+
// Flush WAL to the main database file before reading. Awaiting allows
|
|
1129
|
+
// the callback to dispatch the checkpoint via `runAsyncSqlite` so the
|
|
1130
|
+
// daemon event loop stays responsive while SQLite truncates the WAL.
|
|
1124
1131
|
if (checkpoint) {
|
|
1125
|
-
checkpoint();
|
|
1132
|
+
await checkpoint();
|
|
1126
1133
|
}
|
|
1127
1134
|
|
|
1128
1135
|
const allFileMetadata: FileMetadata[] = [];
|
|
@@ -66,6 +66,7 @@ import {
|
|
|
66
66
|
recordMemoryV2ActivationLog,
|
|
67
67
|
} from "../../../memory/memory-v2-activation-log-store.js";
|
|
68
68
|
import {
|
|
69
|
+
conversationKeys,
|
|
69
70
|
conversations,
|
|
70
71
|
llmRequestLogs,
|
|
71
72
|
memoryV2ActivationLogs,
|
|
@@ -89,6 +90,10 @@ const llmContextRoute = ROUTES.find(
|
|
|
89
90
|
(r) => r.method === "GET" && r.endpoint === "messages/:id/llm-context",
|
|
90
91
|
)!;
|
|
91
92
|
|
|
93
|
+
const conversationLlmContextRoute = ROUTES.find(
|
|
94
|
+
(r) => r.method === "GET" && r.endpoint === "conversations/llm-context",
|
|
95
|
+
)!;
|
|
96
|
+
|
|
92
97
|
const replaceProfileRoute = ROUTES.find(
|
|
93
98
|
(r) => r.operationId === "config_llm_profiles_replace",
|
|
94
99
|
)!;
|
|
@@ -97,11 +102,16 @@ function dispatchLlmContext(messageId: string) {
|
|
|
97
102
|
return llmContextRoute.handler({ pathParams: { id: messageId } });
|
|
98
103
|
}
|
|
99
104
|
|
|
105
|
+
function dispatchConversationLlmContext(queryParams: Record<string, string>) {
|
|
106
|
+
return conversationLlmContextRoute.handler({ queryParams });
|
|
107
|
+
}
|
|
108
|
+
|
|
100
109
|
function clearTables(): void {
|
|
101
110
|
const db = getDb();
|
|
102
111
|
db.delete(llmRequestLogs).run();
|
|
103
112
|
db.delete(memoryV2ActivationLogs).run();
|
|
104
113
|
db.delete(messages).run();
|
|
114
|
+
db.delete(conversationKeys).run();
|
|
105
115
|
db.delete(conversations).run();
|
|
106
116
|
}
|
|
107
117
|
|
|
@@ -165,6 +175,102 @@ function seedRequestLog(
|
|
|
165
175
|
.run();
|
|
166
176
|
}
|
|
167
177
|
|
|
178
|
+
function seedConversationKey(conversationKey: string, conversationId: string): void {
|
|
179
|
+
getDb()
|
|
180
|
+
.insert(conversationKeys)
|
|
181
|
+
.values({
|
|
182
|
+
id: `key-${conversationKey}`,
|
|
183
|
+
conversationKey,
|
|
184
|
+
conversationId,
|
|
185
|
+
createdAt: Date.now(),
|
|
186
|
+
})
|
|
187
|
+
.run();
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
describe("GET /v1/conversations/llm-context", () => {
|
|
191
|
+
beforeEach(() => {
|
|
192
|
+
clearTables();
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
test("returns all LLM calls for a resolved conversation key", async () => {
|
|
196
|
+
seedConversationAndMessage({
|
|
197
|
+
conversationId: "conv-1",
|
|
198
|
+
messageId: "msg-1",
|
|
199
|
+
source: "user",
|
|
200
|
+
conversationType: "standard",
|
|
201
|
+
totalEstimatedCost: 0.42,
|
|
202
|
+
});
|
|
203
|
+
getDb()
|
|
204
|
+
.insert(messages)
|
|
205
|
+
.values({
|
|
206
|
+
id: "msg-2",
|
|
207
|
+
conversationId: "conv-1",
|
|
208
|
+
role: "assistant",
|
|
209
|
+
content: "",
|
|
210
|
+
createdAt: Date.now() + 1,
|
|
211
|
+
metadata: null,
|
|
212
|
+
})
|
|
213
|
+
.run();
|
|
214
|
+
seedConversationAndMessage({
|
|
215
|
+
conversationId: "conv-other",
|
|
216
|
+
messageId: "msg-other",
|
|
217
|
+
source: "user",
|
|
218
|
+
conversationType: "standard",
|
|
219
|
+
});
|
|
220
|
+
seedConversationKey("conv-key", "conv-1");
|
|
221
|
+
seedRequestLog("msg-2", "log-b");
|
|
222
|
+
seedRequestLog("msg-1", "log-a");
|
|
223
|
+
getDb()
|
|
224
|
+
.insert(llmRequestLogs)
|
|
225
|
+
.values({
|
|
226
|
+
id: "log-other",
|
|
227
|
+
conversationId: "conv-other",
|
|
228
|
+
messageId: "msg-other",
|
|
229
|
+
provider: "openai",
|
|
230
|
+
requestPayload: JSON.stringify({ model: "gpt-4.1", messages: [] }),
|
|
231
|
+
responsePayload: JSON.stringify({
|
|
232
|
+
choices: [{ message: { content: "other" } }],
|
|
233
|
+
}),
|
|
234
|
+
createdAt: 1_700_000_000_001,
|
|
235
|
+
})
|
|
236
|
+
.run();
|
|
237
|
+
|
|
238
|
+
const body = (await dispatchConversationLlmContext({
|
|
239
|
+
conversationKey: "conv-key",
|
|
240
|
+
})) as {
|
|
241
|
+
conversationId: string;
|
|
242
|
+
conversationKey: string;
|
|
243
|
+
conversationKind: string;
|
|
244
|
+
conversationTotalEstimatedCostUsd: number | null;
|
|
245
|
+
logs: Array<{ id: string }>;
|
|
246
|
+
memoryRecall: null;
|
|
247
|
+
memoryV2Activation: null;
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
expect(body.conversationId).toBe("conv-1");
|
|
251
|
+
expect(body.conversationKey).toBe("conv-key");
|
|
252
|
+
expect(body.conversationKind).toBe("user");
|
|
253
|
+
expect(body.conversationTotalEstimatedCostUsd).toBe(0.42);
|
|
254
|
+
expect(body.logs.map((log) => log.id)).toEqual(["log-a", "log-b"]);
|
|
255
|
+
expect(body.memoryRecall).toBeNull();
|
|
256
|
+
expect(body.memoryV2Activation).toBeNull();
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
test("returns an empty inspector response for an unresolved conversation key", async () => {
|
|
260
|
+
const body = (await dispatchConversationLlmContext({
|
|
261
|
+
conversationKey: "missing-key",
|
|
262
|
+
})) as {
|
|
263
|
+
conversationId: string | null;
|
|
264
|
+
conversationKey: string;
|
|
265
|
+
logs: unknown[];
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
expect(body.conversationId).toBeNull();
|
|
269
|
+
expect(body.conversationKey).toBe("missing-key");
|
|
270
|
+
expect(body.logs).toEqual([]);
|
|
271
|
+
});
|
|
272
|
+
});
|
|
273
|
+
|
|
168
274
|
describe("GET /v1/messages/:id/llm-context — memoryV2Activation", () => {
|
|
169
275
|
beforeEach(() => {
|
|
170
276
|
clearTables();
|
|
@@ -210,7 +210,11 @@ describe("handleSimulateRouter", () => {
|
|
|
210
210
|
providerStub = makeProvider([3, 1]);
|
|
211
211
|
|
|
212
212
|
const result = await handleSimulateRouter({
|
|
213
|
-
body: {
|
|
213
|
+
body: {
|
|
214
|
+
recentTurnPairs: [
|
|
215
|
+
{ assistantMessage: "", userMessage: "what's relevant?" },
|
|
216
|
+
],
|
|
217
|
+
},
|
|
214
218
|
});
|
|
215
219
|
|
|
216
220
|
expect(result.failureReason).toBeNull();
|
|
@@ -228,7 +232,7 @@ describe("handleSimulateRouter", () => {
|
|
|
228
232
|
|
|
229
233
|
const result = await handleSimulateRouter({
|
|
230
234
|
body: {
|
|
231
|
-
|
|
235
|
+
recentTurnPairs: [{ assistantMessage: "", userMessage: "test" }],
|
|
232
236
|
configOverrides: {
|
|
233
237
|
tier1_size: 50,
|
|
234
238
|
batch_size: 25,
|
|
@@ -249,22 +253,37 @@ describe("handleSimulateRouter", () => {
|
|
|
249
253
|
providerStub = makeProvider([1, 2]);
|
|
250
254
|
|
|
251
255
|
await handleSimulateRouter({
|
|
252
|
-
body: {
|
|
256
|
+
body: {
|
|
257
|
+
recentTurnPairs: [
|
|
258
|
+
{ assistantMessage: "", userMessage: "should not record" },
|
|
259
|
+
],
|
|
260
|
+
},
|
|
253
261
|
});
|
|
254
262
|
|
|
255
263
|
expect(recordCalls).toEqual([]);
|
|
256
264
|
});
|
|
257
265
|
|
|
258
|
-
test("rejects an empty
|
|
266
|
+
test("rejects an empty last-pair userMessage at the schema layer", async () => {
|
|
259
267
|
await expect(
|
|
260
|
-
handleSimulateRouter({
|
|
268
|
+
handleSimulateRouter({
|
|
269
|
+
body: { recentTurnPairs: [{ assistantMessage: "", userMessage: "" }] },
|
|
270
|
+
}),
|
|
271
|
+
).rejects.toThrow();
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
test("rejects an empty recentTurnPairs array at the schema layer", async () => {
|
|
275
|
+
await expect(
|
|
276
|
+
handleSimulateRouter({ body: { recentTurnPairs: [] } }),
|
|
261
277
|
).rejects.toThrow();
|
|
262
278
|
});
|
|
263
279
|
|
|
264
280
|
test("rejects negative tier size at the schema layer", async () => {
|
|
265
281
|
await expect(
|
|
266
282
|
handleSimulateRouter({
|
|
267
|
-
body: {
|
|
283
|
+
body: {
|
|
284
|
+
recentTurnPairs: [{ assistantMessage: "", userMessage: "test" }],
|
|
285
|
+
configOverrides: { tier1_size: -5 },
|
|
286
|
+
},
|
|
268
287
|
}),
|
|
269
288
|
).rejects.toThrow();
|
|
270
289
|
});
|