@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.
Files changed (438) hide show
  1. package/ARCHITECTURE.md +2 -2
  2. package/docs/browser-use-architecture-phase2.md +1 -1
  3. package/knip.json +2 -1
  4. package/openapi.yaml +809 -11
  5. package/package.json +1 -1
  6. package/src/__tests__/anthropic-provider.test.ts +34 -37
  7. package/src/__tests__/assistant-event-hub-self-exclusion.test.ts +293 -0
  8. package/src/__tests__/assistant-feature-flags-integration.test.ts +3 -3
  9. package/src/__tests__/audit-log-rotation.test.ts +70 -16
  10. package/src/__tests__/background-workers-disk-pressure.test.ts +3 -3
  11. package/src/__tests__/btw-routes.test.ts +2 -3
  12. package/src/__tests__/call-controller.test.ts +0 -1
  13. package/src/__tests__/cancel-resolves-conversation-key.test.ts +1 -1
  14. package/src/__tests__/channel-guardian.test.ts +3 -3
  15. package/src/__tests__/checker.test.ts +6 -15
  16. package/src/__tests__/compaction-events.test.ts +1 -0
  17. package/src/__tests__/compactor-call-site-logging.test.ts +214 -0
  18. package/src/__tests__/computer-use-skill-manifest-regression.test.ts +5 -11
  19. package/src/__tests__/computer-use-tools.test.ts +2 -4
  20. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -1
  21. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +1 -1
  22. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +1 -1
  23. package/src/__tests__/conversation-agent-loop-overflow.test.ts +197 -2
  24. package/src/__tests__/conversation-agent-loop.test.ts +163 -122
  25. package/src/__tests__/conversation-app-control-instantiation.test.ts +2 -5
  26. package/src/__tests__/conversation-clear-safety.test.ts +25 -25
  27. package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +1 -1
  28. package/src/__tests__/conversation-disk-view-integration.test.ts +2 -2
  29. package/src/__tests__/conversation-error.test.ts +31 -0
  30. package/src/__tests__/conversation-fork-crud.test.ts +178 -15
  31. package/src/__tests__/conversation-lifecycle.test.ts +52 -11
  32. package/src/__tests__/{conversation-load-cleaned-at.test.ts → conversation-load-history-stripped.test.ts} +13 -13
  33. package/src/__tests__/conversation-provider-retry-repair.test.ts +1 -0
  34. package/src/__tests__/conversation-routes-disk-view.test.ts +109 -0
  35. package/src/__tests__/conversation-routes-slash-commands.test.ts +35 -0
  36. package/src/__tests__/conversation-skill-tools.test.ts +2 -5
  37. package/src/__tests__/conversation-store.test.ts +1 -1
  38. package/src/__tests__/conversation-sync-tags.test.ts +99 -32
  39. package/src/__tests__/conversation-workspace-cache-state.test.ts +1 -0
  40. package/src/__tests__/conversation-workspace-injection.test.ts +1 -1
  41. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +1 -1
  42. package/src/__tests__/credential-execution-feature-gates.test.ts +9 -7
  43. package/src/__tests__/credential-execution-tools.test.ts +6 -6
  44. package/src/__tests__/credential-security-invariants.test.ts +1 -0
  45. package/src/__tests__/credential-vault-unit.test.ts +2 -2
  46. package/src/__tests__/dynamic-page-surface.test.ts +2 -2
  47. package/src/__tests__/email-html-renderer.test.ts +12 -0
  48. package/src/__tests__/gateway-flag-listener.test.ts +237 -0
  49. package/src/__tests__/gemini-provider.test.ts +78 -0
  50. package/src/__tests__/guardian-dispatch.test.ts +0 -1
  51. package/src/__tests__/guardian-outbound-http.test.ts +7 -5
  52. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +1 -1
  53. package/src/__tests__/heartbeat-disk-pressure.test.ts +4 -0
  54. package/src/__tests__/heartbeat-service.test.ts +4 -0
  55. package/src/__tests__/host-shell-tool.test.ts +1 -1
  56. package/src/__tests__/init-feature-flag-overrides.test.ts +5 -6
  57. package/src/__tests__/list-messages-tool-merge.test.ts +70 -11
  58. package/src/__tests__/llm-request-log-call-site.test.ts +136 -0
  59. package/src/__tests__/llm-request-log-source-clickhouse.test.ts +26 -0
  60. package/src/__tests__/llm-resolver.test.ts +77 -9
  61. package/src/__tests__/llm-usage-store.test.ts +66 -0
  62. package/src/__tests__/logger.test.ts +89 -0
  63. package/src/__tests__/mcp-abort-signal.test.ts +2 -2
  64. package/src/__tests__/media-generate-image.test.ts +31 -0
  65. package/src/__tests__/memory-v2-static-injector.test.ts +7 -7
  66. package/src/__tests__/model-intents.test.ts +2 -4
  67. package/src/__tests__/notification-guardian-path.test.ts +0 -1
  68. package/src/__tests__/onboarding-template-contract.test.ts +1 -1
  69. package/src/__tests__/openai-provider.test.ts +46 -0
  70. package/src/__tests__/openai-responses-provider.test.ts +114 -12
  71. package/src/__tests__/pending-interactions-resolved-event.test.ts +0 -1
  72. package/src/__tests__/platform-bash-auto-approve.test.ts +2 -2
  73. package/src/__tests__/platform.test.ts +2 -2
  74. package/src/__tests__/plugin-api-tool-definition.test.ts +92 -0
  75. package/src/__tests__/plugin-bootstrap.test.ts +2 -2
  76. package/src/__tests__/plugin-tool-contribution.test.ts +13 -6
  77. package/src/__tests__/plugin-types.test.ts +3 -2
  78. package/src/__tests__/prechat-onboarding-contract.test.ts +131 -98
  79. package/src/__tests__/pricing.test.ts +12 -0
  80. package/src/__tests__/prune-jobs-changes-parser.test.ts +61 -0
  81. package/src/__tests__/registry.test.ts +2 -8
  82. package/src/__tests__/require-fresh-approval.test.ts +2 -2
  83. package/src/__tests__/runtime-events-sse-bilingual.test.ts +154 -0
  84. package/src/__tests__/shell-tool-proxy-mode.test.ts +1 -1
  85. package/src/__tests__/skill-feature-flags.test.ts +2 -2
  86. package/src/__tests__/skill-projection-feature-flag.test.ts +4 -7
  87. package/src/__tests__/skill-projection.benchmark.test.ts +2 -6
  88. package/src/__tests__/skill-tool-factory.test.ts +1 -1
  89. package/src/__tests__/subagent-notify-parent.test.ts +1 -1
  90. package/src/__tests__/suggestion-routes.test.ts +1 -0
  91. package/src/__tests__/sync-message-contract.test.ts +59 -0
  92. package/src/__tests__/system-prompt.test.ts +145 -131
  93. package/src/__tests__/terminal-tools.test.ts +1 -1
  94. package/src/__tests__/tool-approval-handler.test.ts +1 -5
  95. package/src/__tests__/tool-execute-pipeline.test.ts +2 -2
  96. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +2 -5
  97. package/src/__tests__/tool-executor-lifecycle-events.test.ts +15 -5
  98. package/src/__tests__/tool-executor.test.ts +9 -62
  99. package/src/__tests__/tool-grant-request-escalation.test.ts +1 -6
  100. package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
  101. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +1 -6
  102. package/src/__tests__/trusted-contact-multichannel.test.ts +0 -1
  103. package/src/__tests__/ui-file-upload-surface.test.ts +2 -2
  104. package/src/__tests__/usage-routes.test.ts +3 -0
  105. package/src/__tests__/verification-control-plane-policy.test.ts +2 -2
  106. package/src/__tests__/workspace-git-service.test.ts +6 -5
  107. package/src/__tests__/workspace-migration-089-move-memory-tree-out-of-v3.test.ts +86 -0
  108. package/src/acp/__tests__/prepare-agent-env.test.ts +146 -0
  109. package/src/acp/prepare-agent-env.ts +78 -0
  110. package/src/acp/session-manager.ts +1 -1
  111. package/src/agent/loop.ts +8 -0
  112. package/src/api/README.md +5 -0
  113. package/src/api/index.ts +4 -0
  114. package/src/api/package.json +10 -0
  115. package/src/background-wake/background-wake-routes.test.ts +233 -0
  116. package/src/background-wake/runtime-registry.ts +24 -0
  117. package/src/cli/commands/__tests__/browser.test.ts +23 -5
  118. package/src/cli/commands/__tests__/domain-register.test.ts +110 -0
  119. package/src/cli/commands/__tests__/domain-status.test.ts +33 -33
  120. package/src/cli/commands/__tests__/inference-send.test.ts +108 -5
  121. package/src/cli/commands/__tests__/memory-v2-compare-render.test.ts +98 -0
  122. package/src/cli/commands/__tests__/memory-v2.test.ts +1 -0
  123. package/src/cli/commands/__tests__/memory-v3-render.test.ts +340 -0
  124. package/src/cli/commands/browser.ts +247 -0
  125. package/src/cli/commands/domain.ts +91 -41
  126. package/src/cli/commands/inference.ts +93 -40
  127. package/src/cli/commands/memory-v2-compare-render.ts +115 -0
  128. package/src/cli/commands/memory-v2.ts +176 -1
  129. package/src/cli/commands/memory-v3-render.ts +344 -0
  130. package/src/cli/commands/memory-v3.ts +316 -0
  131. package/src/cli/program.ts +2 -0
  132. package/src/config/assistant-feature-flags.ts +21 -9
  133. package/src/config/bundled-skills/document-editor/SKILL.md +11 -2
  134. package/src/config/bundled-skills/document-editor/TOOLS.json +18 -0
  135. package/src/config/bundled-skills/document-editor/tools/document-open.ts +12 -0
  136. package/src/config/bundled-skills/image-studio/SKILL.md +4 -0
  137. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +2 -2
  138. package/src/config/bundled-skills/media-processing/tools/ingest-media.ts +13 -8
  139. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +10 -3
  140. package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +16 -14
  141. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +7 -2
  142. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +7 -2
  143. package/src/config/bundled-tool-registry.ts +2 -0
  144. package/src/config/call-site-defaults.ts +7 -6
  145. package/src/config/feature-flag-registry.json +16 -0
  146. package/src/config/schemas/__tests__/memory-v2.test.ts +213 -1
  147. package/src/config/schemas/call-site-catalog.ts +21 -7
  148. package/src/config/schemas/llm.ts +12 -1
  149. package/src/config/schemas/memory-v2.ts +246 -0
  150. package/src/config/schemas/memory.ts +2 -1
  151. package/src/context/compactor.ts +52 -0
  152. package/src/conversations/__tests__/message-consolidation.test.ts +350 -0
  153. package/src/conversations/message-consolidation.ts +404 -0
  154. package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +1 -1
  155. package/src/daemon/__tests__/meet-manifest-loader.test.ts +1 -1
  156. package/src/daemon/conversation-agent-loop-handlers.ts +2 -13
  157. package/src/daemon/conversation-agent-loop.ts +126 -76
  158. package/src/daemon/conversation-error.ts +31 -1
  159. package/src/daemon/conversation-lifecycle.ts +27 -22
  160. package/src/daemon/conversation-runtime-assembly.ts +10 -9
  161. package/src/daemon/conversation-tool-setup.ts +63 -3
  162. package/src/daemon/conversation-usage.ts +2 -0
  163. package/src/daemon/conversation.ts +14 -29
  164. package/src/daemon/disk-pressure-guard.ts +14 -2
  165. package/src/daemon/handlers/config-model.test.ts +1 -0
  166. package/src/daemon/handlers/conversations.ts +11 -3
  167. package/src/daemon/host-browser-proxy.ts +5 -5
  168. package/src/daemon/host-cu-proxy.ts +4 -4
  169. package/src/daemon/host-file-proxy.ts +4 -4
  170. package/src/daemon/host-proxy-base.ts +4 -4
  171. package/src/daemon/host-transfer-proxy.ts +10 -10
  172. package/src/daemon/lifecycle.ts +23 -20
  173. package/src/daemon/meet-manifest-loader.ts +1 -7
  174. package/src/daemon/message-types/conversations.ts +6 -9
  175. package/src/daemon/message-types/home.ts +1 -13
  176. package/src/daemon/message-types/messages.ts +6 -14
  177. package/src/daemon/message-types/sync.ts +14 -0
  178. package/src/daemon/shutdown-handlers.ts +24 -5
  179. package/src/daemon/switch-inference-profile-tool.ts +52 -0
  180. package/src/daemon/tool-setup-types.ts +13 -0
  181. package/src/events/relationship-state-updated.ts +25 -0
  182. package/src/heartbeat/__tests__/heartbeat-service.test.ts +1 -1
  183. package/src/home/home-greeting.ts +0 -9
  184. package/src/home/suggested-prompts.ts +0 -9
  185. package/src/ipc/gateway-flag-listener.ts +123 -0
  186. package/src/ipc/skill-routes/registries.ts +8 -12
  187. package/src/memory/__tests__/db-async-query.test.ts +165 -0
  188. package/src/memory/__tests__/db-maintenance.test.ts +115 -0
  189. package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +241 -0
  190. package/src/memory/__tests__/jobs-store-job-classes.test.ts +28 -1
  191. package/src/memory/__tests__/memory-retrospective-job.test.ts +7 -0
  192. package/src/memory/auto-analysis-enqueue.ts +5 -1
  193. package/src/memory/conversation-crud.ts +71 -70
  194. package/src/memory/conversation-starters-cadence.ts +3 -1
  195. package/src/memory/conversation-title-service.ts +19 -3
  196. package/src/memory/db-async-query.ts +214 -0
  197. package/src/memory/db-init.ts +10 -0
  198. package/src/memory/db-maintenance.ts +30 -21
  199. package/src/memory/graph/bootstrap.ts +8 -1
  200. package/src/memory/graph/capability-seed.ts +7 -3
  201. package/src/memory/graph/conversation-graph-memory.ts +100 -17
  202. package/src/memory/graph/extraction.ts +1 -5
  203. package/src/memory/graph/graph-search.ts +7 -1
  204. package/src/memory/indexer.ts +28 -18
  205. package/src/memory/job-handlers/cleanup.ts +76 -18
  206. package/src/memory/job-handlers/conversation-starters.ts +1 -4
  207. package/src/memory/jobs/embed-pkb-file.ts +6 -1
  208. package/src/memory/jobs-store.ts +14 -0
  209. package/src/memory/jobs-worker.ts +55 -22
  210. package/src/memory/llm-request-log-source-clickhouse.ts +42 -2
  211. package/src/memory/llm-request-log-source-local.ts +7 -0
  212. package/src/memory/llm-request-log-source.ts +9 -2
  213. package/src/memory/llm-request-log-store.ts +43 -1
  214. package/src/memory/llm-usage-store.ts +24 -0
  215. package/src/memory/memory-retrospective-enqueue.ts +8 -1
  216. package/src/memory/memory-retrospective-job.ts +5 -0
  217. package/src/memory/memory-v2-activation-log-store.ts +15 -6
  218. package/src/memory/migrations/260-rename-cleaned-at.ts +44 -0
  219. package/src/memory/migrations/261-llm-usage-add-raw-usage.ts +36 -0
  220. package/src/memory/migrations/262-memory-v3-coactivation.ts +57 -0
  221. package/src/memory/migrations/263-memory-v3-auto-edges.ts +50 -0
  222. package/src/memory/migrations/264-llm-request-log-call-site.ts +29 -0
  223. package/src/memory/migrations/index.ts +17 -0
  224. package/src/memory/migrations/registry.ts +33 -0
  225. package/src/memory/schema/conversations.ts +1 -1
  226. package/src/memory/schema/infrastructure.ts +21 -0
  227. package/src/memory/tool-usage-store.ts +36 -8
  228. package/src/memory/v2/__tests__/consolidation-job.test.ts +1 -0
  229. package/src/memory/v2/__tests__/harness-compare.test.ts +186 -0
  230. package/src/memory/v2/__tests__/harness-metrics.test.ts +74 -0
  231. package/src/memory/v2/__tests__/harness-oracle.test.ts +257 -0
  232. package/src/memory/v2/__tests__/harness-replay-input.test.ts +225 -0
  233. package/src/memory/v2/__tests__/harness-runner.test.ts +109 -0
  234. package/src/memory/v2/__tests__/injection.test.ts +127 -98
  235. package/src/memory/v2/__tests__/qdrant.test.ts +36 -0
  236. package/src/memory/v2/__tests__/router.test.ts +171 -3
  237. package/src/memory/v2/harness/compare.ts +57 -0
  238. package/src/memory/v2/harness/metrics.ts +124 -0
  239. package/src/memory/v2/harness/oracle.ts +145 -0
  240. package/src/memory/v2/harness/replay-input.ts +224 -0
  241. package/src/memory/v2/harness/retriever.ts +74 -0
  242. package/src/memory/v2/harness/router-retriever.ts +43 -0
  243. package/src/memory/v2/harness/runner.ts +106 -0
  244. package/src/memory/v2/harness/trace.ts +58 -0
  245. package/src/memory/v2/injection.ts +21 -15
  246. package/src/memory/v2/prompts/router.ts +26 -1
  247. package/src/memory/v2/qdrant.ts +14 -2
  248. package/src/memory/v2/router.ts +171 -18
  249. package/src/memory/v3/__tests__/coactivation-store.test.ts +422 -0
  250. package/src/memory/v3/__tests__/consolidation-job.test.ts +468 -0
  251. package/src/memory/v3/__tests__/edge-learning-job.test.ts +324 -0
  252. package/src/memory/v3/__tests__/edges.test.ts +563 -0
  253. package/src/memory/v3/__tests__/filter.test.ts +512 -0
  254. package/src/memory/v3/__tests__/gate.test.ts +574 -0
  255. package/src/memory/v3/__tests__/index-composition.test.ts +233 -0
  256. package/src/memory/v3/__tests__/loop.test.ts +530 -0
  257. package/src/memory/v3/__tests__/retriever.test.ts +226 -0
  258. package/src/memory/v3/__tests__/scouts.test.ts +440 -0
  259. package/src/memory/v3/__tests__/shadow-middleware.test.ts +312 -0
  260. package/src/memory/v3/__tests__/system-prompts.test.ts +154 -0
  261. package/src/memory/v3/__tests__/traversal.test.ts +469 -0
  262. package/src/memory/v3/__tests__/tree-index.test.ts +280 -0
  263. package/src/memory/v3/__tests__/tree-store.test.ts +529 -0
  264. package/src/memory/v3/__tests__/tree-walk.test.ts +707 -0
  265. package/src/memory/v3/__tests__/validate.test.ts +245 -0
  266. package/src/memory/v3/auto-edges.ts +223 -0
  267. package/src/memory/v3/coactivation-store.ts +124 -0
  268. package/src/memory/v3/consolidation-job.ts +323 -0
  269. package/src/memory/v3/edge-learning-job.ts +160 -0
  270. package/src/memory/v3/edges.ts +249 -0
  271. package/src/memory/v3/filter.ts +281 -0
  272. package/src/memory/v3/gate.ts +334 -0
  273. package/src/memory/v3/index-composition.ts +113 -0
  274. package/src/memory/v3/llm-capture.ts +46 -0
  275. package/src/memory/v3/loop.ts +382 -0
  276. package/src/memory/v3/maintenance.ts +144 -0
  277. package/src/memory/v3/prompt-context.ts +33 -0
  278. package/src/memory/v3/prompts/consolidation.ts +458 -0
  279. package/src/memory/v3/prompts/system-prompts.ts +196 -0
  280. package/src/memory/v3/retriever.ts +33 -0
  281. package/src/memory/v3/scouts.ts +420 -0
  282. package/src/memory/v3/shadow-middleware.ts +305 -0
  283. package/src/memory/v3/traversal.ts +206 -0
  284. package/src/memory/v3/tree-index.ts +237 -0
  285. package/src/memory/v3/tree-store.ts +394 -0
  286. package/src/memory/v3/tree-walk.ts +351 -0
  287. package/src/memory/v3/types.ts +65 -0
  288. package/src/memory/v3/validate.ts +300 -0
  289. package/src/notifications/adapters/macos.ts +18 -1
  290. package/src/notifications/adapters/platform.ts +1 -1
  291. package/src/notifications/decision-engine.ts +1 -4
  292. package/src/notifications/emit-signal.ts +29 -49
  293. package/src/permissions/prompter.ts +3 -3
  294. package/src/permissions/question-prompter.ts +5 -2
  295. package/src/permissions/secret-prompter.ts +2 -2
  296. package/src/plugin-api/index.ts +4 -0
  297. package/src/plugin-api/types.ts +7 -33
  298. package/src/plugins/defaults/index.ts +6 -0
  299. package/src/plugins/defaults/injectors.ts +18 -11
  300. package/src/plugins/external-plugin-loader.ts +5 -68
  301. package/src/plugins/types.ts +11 -16
  302. package/src/proactive-artifact/aux-message-injector.ts +17 -4
  303. package/src/prompts/__tests__/task-progress-hint-section.test.ts +3 -9
  304. package/src/prompts/persona-resolver.ts +36 -21
  305. package/src/prompts/sections.ts +39 -7
  306. package/src/prompts/system-prompt.ts +50 -185
  307. package/src/prompts/templates/BOOTSTRAP.md +2 -2
  308. package/src/prompts/templates/system-sections.ts +230 -8
  309. package/src/providers/__tests__/connection-model-compat.test.ts +234 -0
  310. package/src/providers/__tests__/retry-callsite.test.ts +85 -5
  311. package/src/providers/anthropic/client.ts +32 -66
  312. package/src/providers/call-site-routing.ts +14 -2
  313. package/src/providers/connection-model-compat.ts +38 -0
  314. package/src/providers/connection-resolution.ts +16 -2
  315. package/src/providers/gemini/client.ts +49 -6
  316. package/src/providers/inference/adapter-factory.ts +3 -0
  317. package/src/providers/minimax/client.ts +106 -0
  318. package/src/providers/model-catalog.ts +43 -0
  319. package/src/providers/model-intents.ts +1 -1
  320. package/src/providers/openai/chat-completions-provider.ts +6 -3
  321. package/src/providers/openai/codex-models.ts +18 -0
  322. package/src/providers/openai/responses-provider.ts +78 -21
  323. package/src/providers/provider-send-message.ts +7 -1
  324. package/src/providers/retry.ts +34 -3
  325. package/src/providers/thinking-config.ts +26 -1
  326. package/src/providers/usage-tracking.ts +2 -0
  327. package/src/runtime/AGENTS.md +2 -2
  328. package/src/runtime/agent-wake.ts +1 -0
  329. package/src/runtime/assistant-event-hub.ts +76 -6
  330. package/src/runtime/auth/route-policy.ts +36 -0
  331. package/src/runtime/btw-sidechain.ts +0 -6
  332. package/src/runtime/http-types.ts +0 -2
  333. package/src/runtime/migrations/vbundle-builder.ts +10 -3
  334. package/src/runtime/pending-interactions.ts +0 -1
  335. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +106 -0
  336. package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +25 -6
  337. package/src/runtime/routes/__tests__/plugins-routes.test.ts +512 -0
  338. package/src/runtime/routes/acp-routes.test.ts +255 -6
  339. package/src/runtime/routes/acp-routes.ts +8 -1
  340. package/src/runtime/routes/avatar-routes.ts +10 -10
  341. package/src/runtime/routes/background-wake-routes.ts +188 -0
  342. package/src/runtime/routes/browser-tabs-routes.ts +200 -0
  343. package/src/runtime/routes/btw-routes.ts +0 -6
  344. package/src/runtime/routes/conversation-cli-routes.ts +1 -1
  345. package/src/runtime/routes/conversation-list-routes.ts +12 -4
  346. package/src/runtime/routes/conversation-management-routes.ts +77 -20
  347. package/src/runtime/routes/conversation-query-routes.ts +142 -36
  348. package/src/runtime/routes/conversation-routes.ts +252 -410
  349. package/src/runtime/routes/conversation-starter-routes.ts +6 -3
  350. package/src/runtime/routes/disk-pressure-routes.ts +1 -1
  351. package/src/runtime/routes/domain-routes.ts +60 -10
  352. package/src/runtime/routes/email-routes.ts +5 -2
  353. package/src/runtime/routes/events-routes.ts +54 -10
  354. package/src/runtime/routes/group-routes.ts +24 -8
  355. package/src/runtime/routes/host-browser-routes.ts +10 -2
  356. package/src/runtime/routes/host-cu-routes.ts +2 -2
  357. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +96 -3
  358. package/src/runtime/routes/index.ts +8 -0
  359. package/src/runtime/routes/inference-profile-session-handler.ts +22 -12
  360. package/src/runtime/routes/inference-profile-session-routes.ts +7 -1
  361. package/src/runtime/routes/llm-call-sites-routes.ts +32 -5
  362. package/src/runtime/routes/memory-item-routes.ts +8 -3
  363. package/src/runtime/routes/memory-v2-routes.ts +215 -5
  364. package/src/runtime/routes/memory-v3-routes.ts +316 -0
  365. package/src/runtime/routes/migration-routes.ts +21 -24
  366. package/src/runtime/routes/plugins-routes.ts +337 -0
  367. package/src/runtime/routes/rename-conversation-routes.ts +6 -2
  368. package/src/runtime/routes/secret-routes.ts +25 -5
  369. package/src/runtime/routes/settings-routes.ts +12 -11
  370. package/src/runtime/routes/slack-channel-routes.ts +5 -4
  371. package/src/runtime/routes/workspace-routes.ts +25 -10
  372. package/src/runtime/sync/resource-sync-events.ts +106 -38
  373. package/src/runtime/sync/sync-publisher.test.ts +49 -0
  374. package/src/runtime/sync/sync-publisher.ts +2 -1
  375. package/src/runtime/verification-outbound-actions.ts +73 -1
  376. package/src/telemetry/types.ts +12 -0
  377. package/src/telemetry/usage-telemetry-reporter.test.ts +48 -0
  378. package/src/telemetry/usage-telemetry-reporter.ts +1 -0
  379. package/src/tools/acp/spawn.test.ts +119 -0
  380. package/src/tools/acp/spawn.ts +15 -2
  381. package/src/tools/apps/definitions.ts +2 -8
  382. package/src/tools/ask-question/ask-question-tool.test.ts +3 -3
  383. package/src/tools/ask-question/ask-question-tool.ts +38 -45
  384. package/src/tools/browser/__tests__/pinned-tabs.test.ts +70 -0
  385. package/src/tools/browser/browser-execution.ts +16 -3
  386. package/src/tools/browser/cdp-client/__tests__/browser-tabs-factory.test.ts +402 -0
  387. package/src/tools/browser/cdp-client/__tests__/types.test.ts +3 -0
  388. package/src/tools/browser/cdp-client/cdp-inspect-client.ts +12 -0
  389. package/src/tools/browser/cdp-client/extension-cdp-client.ts +27 -1
  390. package/src/tools/browser/cdp-client/factory.ts +100 -17
  391. package/src/tools/browser/cdp-client/local-cdp-client.ts +12 -0
  392. package/src/tools/browser/cdp-client/types.ts +65 -0
  393. package/src/tools/browser/pinned-tabs.ts +96 -40
  394. package/src/tools/computer-use/definitions.ts +22 -78
  395. package/src/tools/credential-execution/make-authenticated-request.ts +3 -9
  396. package/src/tools/credential-execution/manage-secure-command-tool.ts +3 -9
  397. package/src/tools/credential-execution/run-authenticated-command.ts +3 -9
  398. package/src/tools/credentials/vault.ts +3 -9
  399. package/src/tools/document/document-tool.ts +59 -0
  400. package/src/tools/execution-target.ts +21 -23
  401. package/src/tools/executor.ts +6 -1
  402. package/src/tools/filesystem/edit.ts +3 -9
  403. package/src/tools/filesystem/list.ts +3 -9
  404. package/src/tools/filesystem/read.ts +3 -9
  405. package/src/tools/filesystem/write.ts +3 -9
  406. package/src/tools/host-filesystem/edit.ts +3 -9
  407. package/src/tools/host-filesystem/read.ts +3 -9
  408. package/src/tools/host-filesystem/transfer.ts +3 -9
  409. package/src/tools/host-filesystem/write.ts +3 -9
  410. package/src/tools/host-terminal/host-shell.ts +3 -9
  411. package/src/tools/mcp/mcp-tool-factory.ts +1 -8
  412. package/src/tools/memory/register.test.ts +1 -1
  413. package/src/tools/memory/register.ts +4 -9
  414. package/src/tools/network/web-fetch.ts +3 -9
  415. package/src/tools/network/web-search.ts +25 -32
  416. package/src/tools/registry.ts +7 -23
  417. package/src/tools/schema-transforms.ts +1 -1
  418. package/src/tools/skills/execute.ts +3 -9
  419. package/src/tools/skills/load.ts +3 -9
  420. package/src/tools/skills/skill-tool-factory.ts +1 -8
  421. package/src/tools/subagent/notify-parent.ts +3 -9
  422. package/src/tools/system/request-permission.ts +3 -9
  423. package/src/tools/terminal/shell.ts +3 -9
  424. package/src/tools/tool-defaults.ts +94 -0
  425. package/src/tools/types.ts +27 -98
  426. package/src/tools/ui-surface/definitions.ts +6 -22
  427. package/src/usage/pricing.ts +23 -0
  428. package/src/usage/types.ts +12 -0
  429. package/src/util/logger.ts +16 -7
  430. package/src/util/platform.ts +7 -2
  431. package/src/util/sqlite3-runtime.ts +65 -0
  432. package/src/workspace/migrations/086-revert-stale-gemini-mis-rewrites.ts +1 -0
  433. package/src/workspace/migrations/089-move-memory-tree-out-of-v3.ts +86 -0
  434. package/src/workspace/migrations/registry.ts +2 -0
  435. package/src/__tests__/compaction-strip-metadata-clear.test.ts +0 -206
  436. package/src/__tests__/message-complete-display-id.test.ts +0 -175
  437. package/src/daemon/query-complexity-router.ts +0 -75
  438. 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
+ }
@@ -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. `true` (for undeclared keys)
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
- * only).
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`), which biases toward off for
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. `true` (for undeclared keys with no override)
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 default to enabled.
308
- return true;
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. If the document is there, call `document_read` with its `surface_id`. Done in one call.
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 `document_read` to retrieve the content.
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 { enqueueMemoryJob } from "../../../../memory/jobs-store.js";
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
- enqueueMemoryJob("media_processing", {
203
- mediaAssetId: asset.id,
204
- stage: "ingest",
205
- filePath,
206
- mimeType,
207
- mediaType,
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 { enqueueMemoryJob } from "../../../../memory/jobs-store.js";
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
- enqueueMemoryJob("embed_graph_node", { nodeId: existing.id });
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
- enqueueMemoryJob("embed_graph_node", { nodeId: id });
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 daemon logs (`vellum.log`) only contain caller-side transcripts and lifecycle events at the default log level, so they are **not sufficient** for full transcript reconstruction.
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 `vellum.log` by searching for recent session creation entries:
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" ~/.vellum/workspace/data/logs/vellum.log | tail -5
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 ~/.vellum/workspace/data/db/assistant.db \
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" ~/.vellum/workspace/data/logs/vellum.log | tail -1 | python3 -c "import sys,json; print(json.loads(sys.stdin.readline().strip())['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 ~/.vellum/workspace/data/db/assistant.db \
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) | `~/.vellum/workspace/data/logs/vellum.log` |
50
- | Full conversation database | `~/.vellum/workspace/data/db/assistant.db` |
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
- `vellum.log` at the default log level does **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.
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 { enqueueMemoryJob } from "../../../../memory/jobs-store.js";
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
- enqueueMemoryJob("embed_graph_node", { nodeId: node.id });
122
+ if (isMemoryEnabled()) {
123
+ enqueueMemoryJob("embed_graph_node", { nodeId: node.id });
124
+ }
120
125
 
121
126
  const autonomyLabel =
122
127
  autonomyLevel === "auto"