@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
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `assistant memory v3` CLI subgroup.
|
|
3
|
+
*
|
|
4
|
+
* Operator-facing read-only inspection of the v3 memory tree — the DAG overlay
|
|
5
|
+
* the v2 → v3 data-migration hand-authors over the flat concept pages.
|
|
6
|
+
*
|
|
7
|
+
* Subcommands:
|
|
8
|
+
*
|
|
9
|
+
* - `validate` — print a structural health report (dangling refs, orphan
|
|
10
|
+
* pages, cycles, stale indexes, unknown edge targets). Exits non-zero when
|
|
11
|
+
* any defect is found so it is scriptable as a check.
|
|
12
|
+
* - `tree` — print the tree as an indented outline rooted at the tree root,
|
|
13
|
+
* marking shared-DAG re-entries.
|
|
14
|
+
* - `simulate` — dry-run the v3 retrieval loop against an ad-hoc query and
|
|
15
|
+
* print the per-pass descent trace plus the lane-grouped selection.
|
|
16
|
+
*
|
|
17
|
+
* All are read-only: they mutate nothing. `validate`/`tree` run no LLM;
|
|
18
|
+
* `simulate` invokes the loop (filter + gate LLM calls) but persists nothing.
|
|
19
|
+
* `--json` emits the raw daemon payload for any subcommand.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import { mkdirSync, writeFileSync } from "node:fs";
|
|
23
|
+
import { join } from "node:path";
|
|
24
|
+
|
|
25
|
+
import type { Command } from "commander";
|
|
26
|
+
|
|
27
|
+
import { cliIpcCall } from "../../ipc/cli-client.js";
|
|
28
|
+
import type {
|
|
29
|
+
MemoryV3SimulateResult,
|
|
30
|
+
MemoryV3TreeResult,
|
|
31
|
+
MemoryV3ValidateResult,
|
|
32
|
+
} from "../../runtime/routes/memory-v3-routes.js";
|
|
33
|
+
import { registerCommand } from "../lib/register-command.js";
|
|
34
|
+
import { log } from "../logger.js";
|
|
35
|
+
import {
|
|
36
|
+
renderLlmCalls,
|
|
37
|
+
renderSimulation,
|
|
38
|
+
renderTree,
|
|
39
|
+
renderValidationReport,
|
|
40
|
+
reportHasDefects,
|
|
41
|
+
} from "./memory-v3-render.js";
|
|
42
|
+
|
|
43
|
+
/** Valid lane names accepted by `--lanes` (matches memory.v3.lanes keys). */
|
|
44
|
+
const V3_LANE_NAMES = ["hot", "sparse", "dense", "tree", "edges"] as const;
|
|
45
|
+
|
|
46
|
+
export function registerMemoryV3Command(program: Command): void {
|
|
47
|
+
// Reuse an existing `memory` parent if a sibling registrar (e.g. v2)
|
|
48
|
+
// attached it first; otherwise create one. Keeps registration order between
|
|
49
|
+
// sibling memory registrars unconstrained.
|
|
50
|
+
const memory =
|
|
51
|
+
program.commands.find((c) => c.name() === "memory") ??
|
|
52
|
+
program
|
|
53
|
+
.command("memory")
|
|
54
|
+
.description("Manage the memory subsystem (concept-page model)");
|
|
55
|
+
|
|
56
|
+
registerCommand(memory, {
|
|
57
|
+
name: "v3",
|
|
58
|
+
transport: "ipc",
|
|
59
|
+
description: "Memory v3 subsystem operations (tree-DAG overlay)",
|
|
60
|
+
build: (v3) => {
|
|
61
|
+
v3.addHelpText(
|
|
62
|
+
"after",
|
|
63
|
+
`
|
|
64
|
+
The v3 memory subsystem layers a hand-authored DAG of tree nodes over the
|
|
65
|
+
flat v2 concept pages. Each node lives under /workspace/memory/tree/ and
|
|
66
|
+
its frontmatter 'children' list references sub-nodes (node:<id>) and leaf
|
|
67
|
+
concept pages (page:<slug>). The structure is authored by the v2 → v3
|
|
68
|
+
data-migration, so these subcommands are read-only inspection only — they
|
|
69
|
+
mutate nothing and run no LLM.
|
|
70
|
+
|
|
71
|
+
Examples:
|
|
72
|
+
$ assistant memory v3 validate
|
|
73
|
+
$ assistant memory v3 tree
|
|
74
|
+
$ assistant memory v3 tree --json | jq '.nodes | length'
|
|
75
|
+
$ assistant memory v3 simulate -q "what should we ship next"`,
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
// ── validate ──────────────────────────────────────────────────────────
|
|
79
|
+
|
|
80
|
+
v3.command("validate")
|
|
81
|
+
.description(
|
|
82
|
+
"Print a structural health report of the v3 tree (read-only)",
|
|
83
|
+
)
|
|
84
|
+
.option("--json", "Emit raw JSON instead of a formatted report")
|
|
85
|
+
.addHelpText(
|
|
86
|
+
"after",
|
|
87
|
+
`
|
|
88
|
+
Walks the hand-authored v3 tree DAG and reports:
|
|
89
|
+
- Dangling child refs (node:/page: targets that do not exist)
|
|
90
|
+
- Orphan pages (concept pages not reachable from the tree root)
|
|
91
|
+
- Cycles (back-edges in the node:/node: adjacency)
|
|
92
|
+
- Stale indexes (a node older than a child it composes)
|
|
93
|
+
- Unknown edge targets (page edges: pointing at a missing slug)
|
|
94
|
+
|
|
95
|
+
Read-only — mutates nothing. Exits non-zero if any defect is reported, so it
|
|
96
|
+
is usable as a pre-flight check while the v2 → v3 migration is in flight.
|
|
97
|
+
|
|
98
|
+
Examples:
|
|
99
|
+
$ assistant memory v3 validate
|
|
100
|
+
$ assistant memory v3 validate --json | jq '.orphanPageCount'`,
|
|
101
|
+
)
|
|
102
|
+
.action(async (opts: { json?: boolean }) => {
|
|
103
|
+
const result = await cliIpcCall<MemoryV3ValidateResult>(
|
|
104
|
+
"memory_v3_validate",
|
|
105
|
+
{ body: {} },
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
if (!result.ok) {
|
|
109
|
+
log.error(result.error ?? "Failed to validate memory v3 tree");
|
|
110
|
+
process.exitCode = 1;
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const report = result.result!;
|
|
115
|
+
|
|
116
|
+
if (opts.json === true) {
|
|
117
|
+
log.info(JSON.stringify(report, null, 2));
|
|
118
|
+
} else {
|
|
119
|
+
log.info(renderValidationReport(report));
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (reportHasDefects(report)) {
|
|
123
|
+
process.exitCode = 1;
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
// ── tree ──────────────────────────────────────────────────────────────
|
|
128
|
+
|
|
129
|
+
v3.command("tree")
|
|
130
|
+
.description(
|
|
131
|
+
"Print the v3 tree as an indented outline from the root (read-only)",
|
|
132
|
+
)
|
|
133
|
+
.option("--json", "Emit raw JSON instead of a formatted tree")
|
|
134
|
+
.addHelpText(
|
|
135
|
+
"after",
|
|
136
|
+
`
|
|
137
|
+
Descends the v3 tree depth-first from its root node, printing one line per
|
|
138
|
+
node:/page: ref with indentation by depth. A node reached more than once
|
|
139
|
+
(shared DAG sub-node or a cycle back-edge) is printed once with a re-entry
|
|
140
|
+
marker rather than re-expanded, so output is finite. Nodes that exist on disk
|
|
141
|
+
but are unreachable from the root are listed separately.
|
|
142
|
+
|
|
143
|
+
Read-only — mutates nothing.
|
|
144
|
+
|
|
145
|
+
Examples:
|
|
146
|
+
$ assistant memory v3 tree
|
|
147
|
+
$ assistant memory v3 tree --json | jq '.root'`,
|
|
148
|
+
)
|
|
149
|
+
.action(async (opts: { json?: boolean }) => {
|
|
150
|
+
const result = await cliIpcCall<MemoryV3TreeResult>(
|
|
151
|
+
"memory_v3_tree",
|
|
152
|
+
{
|
|
153
|
+
body: {},
|
|
154
|
+
},
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
if (!result.ok) {
|
|
158
|
+
log.error(result.error ?? "Failed to read memory v3 tree");
|
|
159
|
+
process.exitCode = 1;
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const view = result.result!;
|
|
164
|
+
|
|
165
|
+
if (opts.json === true) {
|
|
166
|
+
log.info(JSON.stringify(view, null, 2));
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
log.info(renderTree(view));
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
// ── simulate ────────────────────────────────────────────────────────────
|
|
174
|
+
|
|
175
|
+
v3.command("simulate")
|
|
176
|
+
.description(
|
|
177
|
+
"Dry-run the v3 retrieval loop against an ad-hoc query (read-only)",
|
|
178
|
+
)
|
|
179
|
+
.requiredOption(
|
|
180
|
+
"-q, --query <text>",
|
|
181
|
+
"User query to run a single synthetic retrieval turn against",
|
|
182
|
+
)
|
|
183
|
+
.option(
|
|
184
|
+
"--pass-cap <n>",
|
|
185
|
+
"Override memory.v3.passCap for this run (positive integer)",
|
|
186
|
+
)
|
|
187
|
+
.option(
|
|
188
|
+
"--lanes <list>",
|
|
189
|
+
`Restrict to a comma-separated allowlist of lanes (others off): ${V3_LANE_NAMES.join(", ")}`,
|
|
190
|
+
)
|
|
191
|
+
.option("--json", "Emit raw JSON instead of a formatted report")
|
|
192
|
+
.option(
|
|
193
|
+
"--show-llm",
|
|
194
|
+
"Print the full input + output of every v3 LLM call (filter / descender / gate)",
|
|
195
|
+
)
|
|
196
|
+
.option(
|
|
197
|
+
"--dump-llm <dir>",
|
|
198
|
+
"Write one JSON file per v3 LLM call into <dir> (full request + raw response)",
|
|
199
|
+
)
|
|
200
|
+
.addHelpText(
|
|
201
|
+
"after",
|
|
202
|
+
`
|
|
203
|
+
Runs the v3 multi-lane bounded-descent loop read-only against the live page
|
|
204
|
+
index + tree DAG, building a single synthetic turn from the query plus the live
|
|
205
|
+
NOW context. Prints the per-pass descent trace (scouts / tree levels / edge
|
|
206
|
+
expansions / gate verdict) and the final selection grouped by provenance lane.
|
|
207
|
+
|
|
208
|
+
The loop is invoked directly — it does NOT require memory.v3.enabled or
|
|
209
|
+
memory.v3.shadow, so you can probe v3 retrieval before the flags flip. Writes
|
|
210
|
+
nothing (co-activation persistence is forced off), but each pass still spends
|
|
211
|
+
the loop's dense-filter + gate LLM calls, so pass-cap is the cost knob.
|
|
212
|
+
|
|
213
|
+
Examples:
|
|
214
|
+
$ assistant memory v3 simulate -q "what should we ship next"
|
|
215
|
+
$ assistant memory v3 simulate -q "..." --lanes tree,edges
|
|
216
|
+
$ assistant memory v3 simulate -q "..." --pass-cap 1 --json | jq '.selectedSlugs'
|
|
217
|
+
$ assistant memory v3 simulate -q "..." --show-llm
|
|
218
|
+
$ assistant memory v3 simulate -q "..." --dump-llm /tmp/v3-calls`,
|
|
219
|
+
)
|
|
220
|
+
.action(
|
|
221
|
+
async (opts: {
|
|
222
|
+
query: string;
|
|
223
|
+
passCap?: string;
|
|
224
|
+
lanes?: string;
|
|
225
|
+
json?: boolean;
|
|
226
|
+
showLlm?: boolean;
|
|
227
|
+
dumpLlm?: string;
|
|
228
|
+
}) => {
|
|
229
|
+
let passCap: number | undefined;
|
|
230
|
+
if (opts.passCap !== undefined) {
|
|
231
|
+
const parsed = Number(opts.passCap);
|
|
232
|
+
if (!Number.isInteger(parsed) || parsed < 1) {
|
|
233
|
+
log.error(
|
|
234
|
+
`--pass-cap must be a positive integer (got "${opts.passCap}")`,
|
|
235
|
+
);
|
|
236
|
+
process.exitCode = 1;
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
passCap = parsed;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
let lanes: string[] | undefined;
|
|
243
|
+
if (opts.lanes !== undefined) {
|
|
244
|
+
const requested = opts.lanes
|
|
245
|
+
.split(",")
|
|
246
|
+
.map((s) => s.trim())
|
|
247
|
+
.filter((s) => s.length > 0);
|
|
248
|
+
const invalid = requested.filter(
|
|
249
|
+
(l) =>
|
|
250
|
+
!V3_LANE_NAMES.includes(l as (typeof V3_LANE_NAMES)[number]),
|
|
251
|
+
);
|
|
252
|
+
if (invalid.length > 0) {
|
|
253
|
+
log.error(
|
|
254
|
+
`--lanes contains unknown lane(s): ${invalid.join(", ")}. Valid: ${V3_LANE_NAMES.join(", ")}`,
|
|
255
|
+
);
|
|
256
|
+
process.exitCode = 1;
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
if (requested.length === 0) {
|
|
260
|
+
log.error("--lanes must list at least one lane");
|
|
261
|
+
process.exitCode = 1;
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
lanes = requested;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
const result = await cliIpcCall<MemoryV3SimulateResult>(
|
|
268
|
+
"memory_v3_simulate",
|
|
269
|
+
{
|
|
270
|
+
body: {
|
|
271
|
+
query: opts.query,
|
|
272
|
+
...(passCap !== undefined ? { passCap } : {}),
|
|
273
|
+
...(lanes !== undefined ? { lanes } : {}),
|
|
274
|
+
},
|
|
275
|
+
},
|
|
276
|
+
);
|
|
277
|
+
|
|
278
|
+
if (!result.ok) {
|
|
279
|
+
log.error(result.error ?? "Failed to simulate v3 retrieval");
|
|
280
|
+
process.exitCode = 1;
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
const payload = result.result!;
|
|
285
|
+
if (opts.json === true) {
|
|
286
|
+
log.info(JSON.stringify(payload, null, 2));
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
log.info(renderSimulation(payload));
|
|
290
|
+
|
|
291
|
+
log.info("");
|
|
292
|
+
log.info(
|
|
293
|
+
renderLlmCalls(payload.llmCalls, { full: opts.showLlm === true }),
|
|
294
|
+
);
|
|
295
|
+
|
|
296
|
+
if (opts.dumpLlm !== undefined) {
|
|
297
|
+
mkdirSync(opts.dumpLlm, { recursive: true });
|
|
298
|
+
for (const call of payload.llmCalls) {
|
|
299
|
+
const nodePart = call.node
|
|
300
|
+
? `-${call.node.replace(/\//g, "_")}`
|
|
301
|
+
: "";
|
|
302
|
+
const file = join(
|
|
303
|
+
opts.dumpLlm,
|
|
304
|
+
`pass${call.pass}-${call.lane}${nodePart}.json`,
|
|
305
|
+
);
|
|
306
|
+
writeFileSync(file, JSON.stringify(call, null, 2));
|
|
307
|
+
}
|
|
308
|
+
log.info(
|
|
309
|
+
`\nWrote ${payload.llmCalls.length} LLM-call file(s) to ${opts.dumpLlm}`,
|
|
310
|
+
);
|
|
311
|
+
}
|
|
312
|
+
},
|
|
313
|
+
);
|
|
314
|
+
},
|
|
315
|
+
});
|
|
316
|
+
}
|
package/src/cli/program.ts
CHANGED
|
@@ -34,6 +34,7 @@ import { registerInferenceCommand } from "./commands/inference.js";
|
|
|
34
34
|
import { registerKeysCommand } from "./commands/keys.js";
|
|
35
35
|
import { registerMcpCommand } from "./commands/mcp.js";
|
|
36
36
|
import { registerMemoryV2Command } from "./commands/memory-v2.js";
|
|
37
|
+
import { registerMemoryV3Command } from "./commands/memory-v3.js";
|
|
37
38
|
import { registerNotificationsCommand } from "./commands/notifications.js";
|
|
38
39
|
import { registerOAuthCommand } from "./commands/oauth/index.js";
|
|
39
40
|
import { registerPendingCommand } from "./commands/pending.js";
|
|
@@ -129,6 +130,7 @@ Examples:
|
|
|
129
130
|
registerKeysCommand(program);
|
|
130
131
|
registerMcpCommand(program);
|
|
131
132
|
registerMemoryV2Command(program);
|
|
133
|
+
registerMemoryV3Command(program);
|
|
132
134
|
registerNotificationsCommand(program);
|
|
133
135
|
registerOAuthCommand(program);
|
|
134
136
|
registerPendingCommand(program);
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* (in priority order):
|
|
8
8
|
* 1. Override values from the gateway IPC socket
|
|
9
9
|
* 2. defaults registry `defaultEnabled` (for declared keys)
|
|
10
|
-
* 3. `
|
|
10
|
+
* 3. `false` (for undeclared keys)
|
|
11
11
|
*
|
|
12
12
|
* Key format:
|
|
13
13
|
* Canonical: simple kebab-case string (e.g., "browser", "ces-tools")
|
|
@@ -172,8 +172,8 @@ const DEFAULT_INIT_RETRY_BACKOFFS_MS: readonly number[] = [
|
|
|
172
172
|
* Retries the gateway IPC fetch on empty/failed results — the gateway
|
|
173
173
|
* may not have bound its IPC socket yet when the daemon races ahead at
|
|
174
174
|
* startup. After exhausting retries, the cache is left unset so
|
|
175
|
-
* subsequent sync calls return an empty override map (registry defaults
|
|
176
|
-
*
|
|
175
|
+
* subsequent sync calls return an empty override map (registry defaults for
|
|
176
|
+
* declared flags, fail-closed for undeclared flags).
|
|
177
177
|
*
|
|
178
178
|
* Pass `retryBackoffsMs: []` to disable retries (used by unit tests that
|
|
179
179
|
* intentionally simulate an unreachable gateway and want immediate
|
|
@@ -229,12 +229,11 @@ export async function initFeatureFlagOverrides(options?: {
|
|
|
229
229
|
|
|
230
230
|
// Exhausted retries — leave cache unset so loadOverrides() returns an
|
|
231
231
|
// empty map on subsequent sync reads. Flag checks fall through to the
|
|
232
|
-
// registry default (`defaultEnabled`)
|
|
233
|
-
// newer assistant-scope flags.
|
|
232
|
+
// registry default (`defaultEnabled`) or the fail-closed undeclared default.
|
|
234
233
|
if (backoffs.length > 0) {
|
|
235
234
|
log.warn(
|
|
236
235
|
{ attempts: backoffs.length + 1 },
|
|
237
|
-
"Feature flag overrides empty after all retries; falling back to registry defaults",
|
|
236
|
+
"Feature flag overrides empty after all retries; falling back to registry defaults and fail-closed undeclared flags",
|
|
238
237
|
);
|
|
239
238
|
}
|
|
240
239
|
}
|
|
@@ -260,6 +259,19 @@ export function clearFeatureFlagOverridesCache(): void {
|
|
|
260
259
|
cachedOverridesFromGateway = false;
|
|
261
260
|
}
|
|
262
261
|
|
|
262
|
+
/**
|
|
263
|
+
* Re-fetch feature flag overrides from the gateway.
|
|
264
|
+
*
|
|
265
|
+
* Clears the cached overrides and re-runs the gateway IPC fetch without
|
|
266
|
+
* retries (the gateway is known to be up because it just pushed an event).
|
|
267
|
+
* Called by the gateway flag listener when a `feature_flags_changed` event
|
|
268
|
+
* arrives.
|
|
269
|
+
*/
|
|
270
|
+
export async function refreshOverridesFromGateway(): Promise<void> {
|
|
271
|
+
clearFeatureFlagOverridesCache();
|
|
272
|
+
await initFeatureFlagOverrides({ retryBackoffsMs: [] });
|
|
273
|
+
}
|
|
274
|
+
|
|
263
275
|
/**
|
|
264
276
|
* Directly inject override values into the module-level cache.
|
|
265
277
|
*
|
|
@@ -287,7 +299,7 @@ export function _setOverridesForTesting(
|
|
|
287
299
|
* values, which the gateway merges server-side: persisted > remote >
|
|
288
300
|
* registry)
|
|
289
301
|
* 2. Registry `defaultEnabled` (for declared assistant-scope keys)
|
|
290
|
-
* 3. `
|
|
302
|
+
* 3. `false` (for undeclared keys with no override)
|
|
291
303
|
*/
|
|
292
304
|
export function isAssistantFeatureFlagEnabled(
|
|
293
305
|
key: string,
|
|
@@ -304,6 +316,6 @@ export function isAssistantFeatureFlagEnabled(
|
|
|
304
316
|
// 2. For declared keys, use the registry default.
|
|
305
317
|
if (declared) return declared.defaultEnabled;
|
|
306
318
|
|
|
307
|
-
// 3. Undeclared keys with no override
|
|
308
|
-
return
|
|
319
|
+
// 3. Undeclared keys with no override fail closed.
|
|
320
|
+
return false;
|
|
309
321
|
}
|
|
@@ -16,6 +16,7 @@ Create and edit long-form documents using the built-in rich text editor. Documen
|
|
|
16
16
|
|
|
17
17
|
## Tools
|
|
18
18
|
|
|
19
|
+
- **document_open** - Opens an existing document in the editor panel by `surface_id`. Use this when a document exists but isn't visible in the editor — for example after the user switches devices, refreshes the page, or when the editor panel was closed. Fetches the document from storage and sends it to the client.
|
|
19
20
|
- **document_create** - Opens a new document editor with an optional title and initial Markdown content. Returns a `surface_id` for subsequent updates.
|
|
20
21
|
- **document_update** - Updates content in an open document editor by `surface_id`. Supports `replace` (overwrite) and `append` (add to end) modes.
|
|
21
22
|
- **document_read** - Reads the current content of a document by `surface_id` when it belongs to the current conversation, or when the current actor is the guardian/local user. Use to verify content before editing.
|
|
@@ -28,12 +29,14 @@ Create and edit long-form documents using the built-in rich text editor. Documen
|
|
|
28
29
|
|
|
29
30
|
When the user asks to see, open, or pull up a document:
|
|
30
31
|
|
|
31
|
-
1. Check the `<active_documents>` block in your context — it lists all documents in this conversation with their `surface_id` and title.
|
|
32
|
+
1. Check the `<active_documents>` block in your context — it lists all documents in this conversation with their `surface_id` and title.
|
|
32
33
|
2. If the document is NOT in `<active_documents>`, call `document_list` with a `query` matching the document title. For guardian/local users, this searches across previous conversations and sessions.
|
|
33
|
-
3. Once you have the `surface_id`, call `
|
|
34
|
+
3. Once you have the `surface_id`, call `document_open` to open the editor panel. This both surfaces the editor on the client and returns the document content. If the user only needs the text (not the editor), use `document_read` instead.
|
|
34
35
|
|
|
35
36
|
**Never** search the filesystem, conversation history, or archives to find a document. Always use `document_list` with a `query`.
|
|
36
37
|
|
|
38
|
+
**If the user says they can't see a document you know exists** (e.g. after switching from macOS to web, or after a page refresh), call `document_open` with the `surface_id` to re-surface the editor panel on their current client.
|
|
39
|
+
|
|
37
40
|
## Creating a new document
|
|
38
41
|
|
|
39
42
|
1. **Create the document**: Call `document_create` with a title (inferred from the request). Call the tool immediately, not after conversational preamble.
|
|
@@ -107,6 +110,12 @@ Users can leave inline comments on documents. Open comments are surfaced in a `<
|
|
|
107
110
|
3. Call `comment_resolve` on comments you have addressed.
|
|
108
111
|
4. If a comment is ambiguous, call `comment_reply` to ask for clarification instead of guessing.
|
|
109
112
|
|
|
113
|
+
## Anti-Patterns
|
|
114
|
+
|
|
115
|
+
- **Don't use `app_create` for blog posts, articles, or written content.** Use `document_create` — apps are for interactive content with state/data.
|
|
116
|
+
- **Don't output the full content in chat.** The content goes in the document editor, not in the chat response. Acknowledge what you're doing and stream to the editor.
|
|
117
|
+
- **Don't wait to generate everything before sending.** Stream content in chunks via `document_update` with `mode: "append"` so users see progress in real time.
|
|
118
|
+
|
|
110
119
|
## Usage Notes
|
|
111
120
|
|
|
112
121
|
- The `mode` parameter on `document_update` defaults to `append`.
|
|
@@ -1,6 +1,24 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 1,
|
|
3
3
|
"tools": [
|
|
4
|
+
{
|
|
5
|
+
"name": "document_open",
|
|
6
|
+
"description": "Open an existing document in the editor panel. Use this when the user asks to see or pull up a document that exists but isn't currently visible in the editor — for example after switching devices, refreshing, or when the editor panel was closed.",
|
|
7
|
+
"category": "document-editor",
|
|
8
|
+
"risk": "low",
|
|
9
|
+
"input_schema": {
|
|
10
|
+
"type": "object",
|
|
11
|
+
"properties": {
|
|
12
|
+
"surface_id": {
|
|
13
|
+
"type": "string",
|
|
14
|
+
"description": "The ID of the document to open"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"required": ["surface_id"]
|
|
18
|
+
},
|
|
19
|
+
"executor": "tools/document-open.ts",
|
|
20
|
+
"execution_target": "host"
|
|
21
|
+
},
|
|
4
22
|
{
|
|
5
23
|
"name": "document_create",
|
|
6
24
|
"description": "Create a new long-form document with a rich text editor. Use this when the user asks to write a blog post, article, or any long-form content. The editor opens in workspace mode with chat docked to the side.",
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { executeDocumentOpen } from "../../../../tools/document/document-tool.js";
|
|
2
|
+
import type {
|
|
3
|
+
ToolContext,
|
|
4
|
+
ToolExecutionResult,
|
|
5
|
+
} from "../../../../tools/types.js";
|
|
6
|
+
|
|
7
|
+
export async function run(
|
|
8
|
+
input: Record<string, unknown>,
|
|
9
|
+
context: ToolContext,
|
|
10
|
+
): Promise<ToolExecutionResult> {
|
|
11
|
+
return executeDocumentOpen(input, context);
|
|
12
|
+
}
|
|
@@ -37,3 +37,7 @@ You are an image generation assistant. When the user asks you to create or edit
|
|
|
37
37
|
- When editing images, clearly describe what changes you want made to the source image.
|
|
38
38
|
- Use the `variants` parameter (1-4) to generate multiple options and pick the best one.
|
|
39
39
|
- If no API key is configured for the selected model's provider (Gemini or OpenAI), the tool will return an error - ask the user to set one up.
|
|
40
|
+
|
|
41
|
+
## Error handling
|
|
42
|
+
|
|
43
|
+
When image generation fails, report the error to the user as-is. **Do not** attempt to fix the error by changing service configuration (e.g. switching between "managed" and "your-own" mode, or changing the provider/model). Service configuration changes should only be made at the user's explicit request via Settings.
|
|
@@ -30,7 +30,7 @@ export async function run(
|
|
|
30
30
|
});
|
|
31
31
|
if (!credentials) {
|
|
32
32
|
return {
|
|
33
|
-
content: errorHint ?? "Image generation is not configured.",
|
|
33
|
+
content: `${errorHint ?? "Image generation is not configured."}\n\nReport this error to the user. Do not change service configuration (mode, provider, or model) to try to fix it.`,
|
|
34
34
|
isError: true,
|
|
35
35
|
};
|
|
36
36
|
}
|
|
@@ -131,7 +131,7 @@ export async function run(
|
|
|
131
131
|
};
|
|
132
132
|
} catch (error) {
|
|
133
133
|
return {
|
|
134
|
-
content: mapImageGenError(provider, error),
|
|
134
|
+
content: `${mapImageGenError(provider, error)}\n\nReport this error to the user. Do not change service configuration (mode, provider, or model) to try to fix it.`,
|
|
135
135
|
isError: true,
|
|
136
136
|
};
|
|
137
137
|
}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { access } from "node:fs/promises";
|
|
2
2
|
import { basename, extname } from "node:path";
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
enqueueMemoryJob,
|
|
6
|
+
isMemoryEnabled,
|
|
7
|
+
} from "../../../../memory/jobs-store.js";
|
|
5
8
|
import {
|
|
6
9
|
computeFileHashStreaming,
|
|
7
10
|
createProcessingStage,
|
|
@@ -199,13 +202,15 @@ export async function run(
|
|
|
199
202
|
updateMediaAssetStatus(asset.id, "processing");
|
|
200
203
|
|
|
201
204
|
// Enqueue a processing job via the existing jobs framework
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
205
|
+
if (isMemoryEnabled()) {
|
|
206
|
+
enqueueMemoryJob("media_processing", {
|
|
207
|
+
mediaAssetId: asset.id,
|
|
208
|
+
stage: "ingest",
|
|
209
|
+
filePath,
|
|
210
|
+
mimeType,
|
|
211
|
+
mediaType,
|
|
212
|
+
});
|
|
213
|
+
}
|
|
209
214
|
|
|
210
215
|
context.onOutput?.(`Registered media asset: ${asset.id}\n`);
|
|
211
216
|
|
|
@@ -2,7 +2,10 @@ import { and, eq, sql } from "drizzle-orm";
|
|
|
2
2
|
import { v4 as uuid } from "uuid";
|
|
3
3
|
|
|
4
4
|
import { getDb } from "../../../../memory/db-connection.js";
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
enqueueMemoryJob,
|
|
7
|
+
isMemoryEnabled,
|
|
8
|
+
} from "../../../../memory/jobs-store.js";
|
|
6
9
|
import { memoryGraphNodes } from "../../../../memory/schema.js";
|
|
7
10
|
import { clampUnitInterval } from "../../../../memory/validation.js";
|
|
8
11
|
import { extractStylePatterns } from "../../../../messaging/style-analyzer.js";
|
|
@@ -56,7 +59,9 @@ function upsertMemoryItem(opts: {
|
|
|
56
59
|
})
|
|
57
60
|
.where(eq(memoryGraphNodes.id, existing.id))
|
|
58
61
|
.run();
|
|
59
|
-
|
|
62
|
+
if (isMemoryEnabled()) {
|
|
63
|
+
enqueueMemoryJob("embed_graph_node", { nodeId: existing.id });
|
|
64
|
+
}
|
|
60
65
|
} else {
|
|
61
66
|
const id = uuid();
|
|
62
67
|
db.insert(memoryGraphNodes)
|
|
@@ -82,7 +87,9 @@ function upsertMemoryItem(opts: {
|
|
|
82
87
|
scopeId: opts.scopeId,
|
|
83
88
|
})
|
|
84
89
|
.run();
|
|
85
|
-
|
|
90
|
+
if (isMemoryEnabled()) {
|
|
91
|
+
enqueueMemoryJob("embed_graph_node", { nodeId: id });
|
|
92
|
+
}
|
|
86
93
|
}
|
|
87
94
|
}
|
|
88
95
|
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
# Retrieving Past Call Transcripts
|
|
2
2
|
|
|
3
|
-
After a call ends, the full bidirectional transcript (caller speech, assistant responses, tool calls, and tool results) is stored in the SQLite database. The
|
|
3
|
+
After a call ends, the full bidirectional transcript (caller speech, assistant responses, tool calls, and tool results) is stored in the SQLite database. The assistant logs only contain caller-side transcripts and lifecycle events at the default log level, so they are **not sufficient** for full transcript reconstruction.
|
|
4
|
+
|
|
5
|
+
Logs rotate daily as `$VELLUM_WORKSPACE_DIR/data/logs/assistant-YYYY-MM-DD.log`. The commands below use today's UTC log file; if a call happened on a previous day, swap the date in or grep across `assistant-*.log`.
|
|
4
6
|
|
|
5
7
|
## Finding the conversation
|
|
6
8
|
|
|
7
|
-
1. **Get the call session ID and voice conversation ID** from
|
|
9
|
+
1. **Get the call session ID and voice conversation ID** from today's log by searching for recent session creation entries:
|
|
8
10
|
|
|
9
11
|
```bash
|
|
10
|
-
grep "voiceConversationId"
|
|
12
|
+
grep "voiceConversationId" "$VELLUM_WORKSPACE_DIR/data/logs/assistant-$(date -u +%Y-%m-%d).log" | tail -5
|
|
11
13
|
```
|
|
12
14
|
|
|
13
15
|
The `voiceConversationId` field in the `Created new inbound voice session` (or outbound equivalent) log line is the key you need.
|
|
@@ -15,7 +17,7 @@ The `voiceConversationId` field in the `Created new inbound voice session` (or o
|
|
|
15
17
|
2. **Query the messages table** in the SQLite database using the voice conversation ID:
|
|
16
18
|
|
|
17
19
|
```bash
|
|
18
|
-
sqlite3
|
|
20
|
+
sqlite3 "$VELLUM_WORKSPACE_DIR/data/db/assistant.db" \
|
|
19
21
|
"SELECT role, content FROM messages WHERE conversation_id = '<voiceConversationId>' ORDER BY created_at ASC;"
|
|
20
22
|
```
|
|
21
23
|
|
|
@@ -27,9 +29,9 @@ This returns all messages in chronological order with:
|
|
|
27
29
|
## Quick one-liner for the most recent call
|
|
28
30
|
|
|
29
31
|
```bash
|
|
30
|
-
CONV_ID=$(grep "voiceConversationId"
|
|
32
|
+
CONV_ID=$(grep -h "voiceConversationId" "$VELLUM_WORKSPACE_DIR"/data/logs/assistant-*.log | tail -1 | python3 -c "import sys,json; print(json.loads(sys.stdin.readline().strip())['voiceConversationId'])")
|
|
31
33
|
|
|
32
|
-
sqlite3
|
|
34
|
+
sqlite3 "$VELLUM_WORKSPACE_DIR/data/db/assistant.db" \
|
|
33
35
|
"SELECT role, content FROM messages WHERE conversation_id = '$CONV_ID' ORDER BY created_at ASC;"
|
|
34
36
|
```
|
|
35
37
|
|
|
@@ -44,14 +46,14 @@ sqlite3 ~/.vellum/workspace/data/db/assistant.db \
|
|
|
44
46
|
|
|
45
47
|
## Key paths
|
|
46
48
|
|
|
47
|
-
| Resource | Path
|
|
48
|
-
| --------------------------------------------- |
|
|
49
|
-
| Assistant logs (caller-side transcripts only) |
|
|
50
|
-
| Full conversation database |
|
|
51
|
-
| Messages table | `messages` (keyed by `conversation_id`)
|
|
52
|
-
| Call sessions table | `call_sessions`
|
|
53
|
-
| Call events table | `call_events`
|
|
49
|
+
| Resource | Path |
|
|
50
|
+
| --------------------------------------------- | ----------------------------------------------------- |
|
|
51
|
+
| Assistant logs (caller-side transcripts only) | `$VELLUM_WORKSPACE_DIR/data/logs/assistant-*.log` |
|
|
52
|
+
| Full conversation database | `$VELLUM_WORKSPACE_DIR/data/db/assistant.db` |
|
|
53
|
+
| Messages table | `messages` (keyed by `conversation_id`) |
|
|
54
|
+
| Call sessions table | `call_sessions` |
|
|
55
|
+
| Call events table | `call_events` |
|
|
54
56
|
|
|
55
57
|
## Important
|
|
56
58
|
|
|
57
|
-
|
|
59
|
+
Assistant log files at the default log level do **not** contain assistant responses, TTS text, or LLM completions for voice calls. Always use the `messages` table in `assistant.db` as the source of truth for complete call transcripts.
|
|
@@ -3,7 +3,10 @@ import { sql } from "drizzle-orm";
|
|
|
3
3
|
import { getDb } from "../../../../memory/db-connection.js";
|
|
4
4
|
import { createNode, updateNode } from "../../../../memory/graph/store.js";
|
|
5
5
|
import type { NewNode } from "../../../../memory/graph/types.js";
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
enqueueMemoryJob,
|
|
8
|
+
isMemoryEnabled,
|
|
9
|
+
} from "../../../../memory/jobs-store.js";
|
|
7
10
|
import { memoryGraphNodes } from "../../../../memory/schema.js";
|
|
8
11
|
import type {
|
|
9
12
|
Playbook,
|
|
@@ -116,7 +119,9 @@ export async function executePlaybookCreate(
|
|
|
116
119
|
sourceConversations: [`playbook:${node.id}`],
|
|
117
120
|
});
|
|
118
121
|
|
|
119
|
-
|
|
122
|
+
if (isMemoryEnabled()) {
|
|
123
|
+
enqueueMemoryJob("embed_graph_node", { nodeId: node.id });
|
|
124
|
+
}
|
|
120
125
|
|
|
121
126
|
const autonomyLabel =
|
|
122
127
|
autonomyLevel === "auto"
|