@vellumai/assistant 0.8.4 → 0.8.6

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 (802) hide show
  1. package/AGENTS.md +33 -1
  2. package/ARCHITECTURE.md +3 -3
  3. package/bunfig.toml +6 -1
  4. package/docs/browser-use-architecture-phase2.md +1 -1
  5. package/docs/credential-execution-service.md +6 -6
  6. package/docs/plugins.md +4 -3
  7. package/knip.json +2 -1
  8. package/node_modules/@vellumai/skill-host-contracts/src/client.ts +12 -13
  9. package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +4 -1
  10. package/node_modules/@vellumai/skill-host-contracts/src/tool-types.ts +16 -14
  11. package/openapi.yaml +2748 -216
  12. package/package.json +1 -1
  13. package/src/__tests__/actor-token-service.test.ts +3 -2
  14. package/src/__tests__/agent-loop-exit-reason.test.ts +102 -9
  15. package/src/__tests__/agent-loop-override-profile.test.ts +2 -1
  16. package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +1 -0
  17. package/src/__tests__/agent-wake-override-profile.test.ts +1 -0
  18. package/src/__tests__/always-loaded-tools-guard.test.ts +2 -2
  19. package/src/__tests__/annotate-risk-options.test.ts +1 -0
  20. package/src/__tests__/anthropic-provider.test.ts +34 -37
  21. package/src/__tests__/approval-cascade.test.ts +1 -0
  22. package/src/__tests__/approval-routes-http.test.ts +9 -13
  23. package/src/__tests__/assert-not-live-db.ts +79 -0
  24. package/src/__tests__/assistant-event-hub-self-exclusion.test.ts +293 -0
  25. package/src/__tests__/assistant-feature-flags-integration.test.ts +12 -28
  26. package/src/__tests__/audit-log-rotation.test.ts +72 -18
  27. package/src/__tests__/auto-analysis-end-to-end.test.ts +6 -6
  28. package/src/__tests__/background-workers-disk-pressure.test.ts +8 -11
  29. package/src/__tests__/browser-skill-endstate.test.ts +3 -3
  30. package/src/__tests__/btw-routes.test.ts +5 -5
  31. package/src/__tests__/call-controller.test.ts +3 -3
  32. package/src/__tests__/cancel-resolves-conversation-key.test.ts +1 -1
  33. package/src/__tests__/channel-approval-routes.test.ts +3 -2
  34. package/src/__tests__/channel-guardian.test.ts +6 -5
  35. package/src/__tests__/channel-readiness-slack-remote.test.ts +175 -0
  36. package/src/__tests__/channel-reply-delivery.test.ts +35 -0
  37. package/src/__tests__/channel-retry-sweep.test.ts +320 -3
  38. package/src/__tests__/checker.test.ts +18 -27
  39. package/src/__tests__/compaction-events.test.ts +2 -0
  40. package/src/__tests__/compaction-trail-store.test.ts +264 -0
  41. package/src/__tests__/compactor-call-site-logging.test.ts +215 -0
  42. package/src/__tests__/compactor-preserved-tail-count.test.ts +1 -0
  43. package/src/__tests__/computer-use-skill-manifest-regression.test.ts +12 -16
  44. package/src/__tests__/computer-use-tools.test.ts +14 -18
  45. package/src/__tests__/config-loader-backfill.test.ts +13 -28
  46. package/src/__tests__/config-loader-corrupt.test.ts +5 -5
  47. package/src/__tests__/config-loader-platform-defaults.test.ts +93 -26
  48. package/src/__tests__/config-loader-quarantine-bulletin.test.ts +3 -3
  49. package/src/__tests__/config-managed-gemini-defaults.test.ts +3 -4
  50. package/src/__tests__/config-schema.test.ts +10 -10
  51. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -1
  52. package/src/__tests__/connection-model-compat.test.ts +83 -0
  53. package/src/__tests__/contacts-tools.test.ts +3 -2
  54. package/src/__tests__/context-token-estimator.test.ts +22 -0
  55. package/src/__tests__/conversation-abort-tool-results.test.ts +5 -0
  56. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +2 -1
  57. package/src/__tests__/conversation-agent-loop-handlers-max-tokens.test.ts +55 -0
  58. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +2 -1
  59. package/src/__tests__/conversation-agent-loop-overflow.test.ts +231 -2
  60. package/src/__tests__/conversation-agent-loop.test.ts +581 -54
  61. package/src/__tests__/conversation-analysis-routes.test.ts +1 -0
  62. package/src/__tests__/conversation-app-control-instantiation.test.ts +31 -24
  63. package/src/__tests__/conversation-app-control-lifecycle.test.ts +1 -0
  64. package/src/__tests__/conversation-attention-store.test.ts +101 -0
  65. package/src/__tests__/conversation-attention-telegram.test.ts +3 -2
  66. package/src/__tests__/conversation-clear-safety.test.ts +25 -25
  67. package/src/__tests__/conversation-confirmation-signals.test.ts +1 -0
  68. package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +1 -1
  69. package/src/__tests__/conversation-disk-view-integration.test.ts +2 -2
  70. package/src/__tests__/conversation-error.test.ts +61 -0
  71. package/src/__tests__/conversation-fork-crud.test.ts +239 -15
  72. package/src/__tests__/conversation-fork-route.test.ts +3 -2
  73. package/src/__tests__/conversation-history-web-search.test.ts +1 -0
  74. package/src/__tests__/conversation-inference-profile-list.test.ts +3 -2
  75. package/src/__tests__/conversation-inference-profile-route.test.ts +3 -2
  76. package/src/__tests__/conversation-lifecycle.test.ts +53 -11
  77. package/src/__tests__/conversation-list-source.test.ts +3 -2
  78. package/src/__tests__/conversation-load-history-repair.test.ts +2 -1
  79. package/src/__tests__/{conversation-load-cleaned-at.test.ts → conversation-load-history-stripped.test.ts} +14 -13
  80. package/src/__tests__/conversation-pairing.test.ts +53 -0
  81. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +26 -7
  82. package/src/__tests__/conversation-process-callsite.test.ts +1 -0
  83. package/src/__tests__/conversation-provider-retry-repair.test.ts +6 -0
  84. package/src/__tests__/conversation-queue.test.ts +333 -291
  85. package/src/__tests__/conversation-routes-disk-view.test.ts +112 -18
  86. package/src/__tests__/conversation-routes-guardian-reply.test.ts +33 -8
  87. package/src/__tests__/conversation-routes-slash-commands.test.ts +68 -2
  88. package/src/__tests__/conversation-runtime-assembly.test.ts +78 -0
  89. package/src/__tests__/conversation-skill-tools.test.ts +40 -147
  90. package/src/__tests__/conversation-slash-queue.test.ts +84 -32
  91. package/src/__tests__/conversation-slash-unknown.test.ts +5 -0
  92. package/src/__tests__/conversation-speed-override.test.ts +1 -0
  93. package/src/__tests__/conversation-store.test.ts +1 -1
  94. package/src/__tests__/conversation-surfaces-action-delivery.test.ts +46 -0
  95. package/src/__tests__/conversation-surfaces-data-persist.test.ts +1 -0
  96. package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +6 -3
  97. package/src/__tests__/conversation-surfaces-standalone.test.ts +6 -3
  98. package/src/__tests__/conversation-surfaces-state-update.test.ts +3 -3
  99. package/src/__tests__/conversation-surfaces-table-action.test.ts +7 -17
  100. package/src/__tests__/conversation-sync-tags.test.ts +218 -35
  101. package/src/__tests__/conversation-title-service.test.ts +1 -0
  102. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +30 -0
  103. package/src/__tests__/conversation-usage.test.ts +1 -0
  104. package/src/__tests__/conversation-workspace-cache-state.test.ts +2 -0
  105. package/src/__tests__/conversation-workspace-injection.test.ts +6 -1
  106. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +6 -1
  107. package/src/__tests__/credential-broker-browser-fill.test.ts +3 -3
  108. package/src/__tests__/credential-broker-server-use.test.ts +5 -5
  109. package/src/__tests__/credential-execution-client.test.ts +72 -1
  110. package/src/__tests__/credential-execution-feature-gates.test.ts +19 -19
  111. package/src/__tests__/credential-execution-tools.test.ts +6 -6
  112. package/src/__tests__/credential-health-service.test.ts +252 -3
  113. package/src/__tests__/credential-security-invariants.test.ts +6 -5
  114. package/src/__tests__/credential-vault-unit.test.ts +21 -21
  115. package/src/__tests__/credential-vault.test.ts +5 -5
  116. package/src/__tests__/cross-provider-web-search.test.ts +56 -2
  117. package/src/__tests__/db-connection-isolation.test.ts +7 -6
  118. package/src/__tests__/db-conversation-fork-lineage-migration.test.ts +8 -10
  119. package/src/__tests__/db-conversation-inference-profile-migration.test.ts +7 -10
  120. package/src/__tests__/db-llm-request-log-provider-migration.test.ts +9 -15
  121. package/src/__tests__/db-test-helpers.ts +58 -0
  122. package/src/__tests__/disk-pressure-guard.test.ts +58 -41
  123. package/src/__tests__/disk-pressure-lifecycle.test.ts +13 -10
  124. package/src/__tests__/disk-pressure-routes.test.ts +0 -33
  125. package/src/__tests__/disk-pressure-tools.test.ts +0 -4
  126. package/src/__tests__/dm-persistence.test.ts +26 -40
  127. package/src/__tests__/document-create-dedupe.test.ts +189 -0
  128. package/src/__tests__/document-find-replace.test.ts +3 -2
  129. package/src/__tests__/document-tool-security.test.ts +81 -2
  130. package/src/__tests__/dynamic-page-surface.test.ts +2 -2
  131. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +5 -4
  132. package/src/__tests__/email-html-renderer.test.ts +12 -0
  133. package/src/__tests__/encrypted-store-test-helpers.ts +56 -0
  134. package/src/__tests__/encrypted-store.test.ts +11 -9
  135. package/src/__tests__/feature-flag-test-helpers.ts +53 -0
  136. package/src/__tests__/filing-service.test.ts +1 -0
  137. package/src/__tests__/first-greeting.test.ts +62 -12
  138. package/src/__tests__/gateway-flag-listener.test.ts +236 -0
  139. package/src/__tests__/gemini-provider.test.ts +104 -0
  140. package/src/__tests__/guardian-action-sweep.test.ts +3 -2
  141. package/src/__tests__/guardian-dispatch.test.ts +0 -1
  142. package/src/__tests__/guardian-outbound-http.test.ts +10 -7
  143. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +48 -3
  144. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +2 -1
  145. package/src/__tests__/heartbeat-disk-pressure.test.ts +5 -0
  146. package/src/__tests__/heartbeat-service.test.ts +5 -0
  147. package/src/__tests__/helpers/mock-logger.ts +26 -0
  148. package/src/__tests__/host-bash-routes.test.ts +1 -0
  149. package/src/__tests__/host-cu-routes-targeted.test.ts +1 -0
  150. package/src/__tests__/host-file-routes-targeted.test.ts +1 -0
  151. package/src/__tests__/host-shell-tool.test.ts +6 -5
  152. package/src/__tests__/host-transfer-routes-targeted.test.ts +1 -0
  153. package/src/__tests__/http-conversation-lineage.test.ts +3 -2
  154. package/src/__tests__/http-user-message-parity.test.ts +29 -7
  155. package/src/__tests__/identity-intro-cache.test.ts +133 -22
  156. package/src/__tests__/inbound-slack-persistence.test.ts +44 -72
  157. package/src/__tests__/inference-profile-reaper.test.ts +3 -2
  158. package/src/__tests__/inference-profile-session-ipc.test.ts +3 -2
  159. package/src/__tests__/init-feature-flag-overrides.test.ts +5 -6
  160. package/src/__tests__/injector-disk-pressure.test.ts +3 -17
  161. package/src/__tests__/inline-skill-load-permissions.test.ts +4 -4
  162. package/src/__tests__/list-messages-hidden-metadata.test.ts +80 -0
  163. package/src/__tests__/list-messages-tool-merge.test.ts +70 -11
  164. package/src/__tests__/llm-context-normalization.test.ts +42 -0
  165. package/src/__tests__/llm-request-log-call-site.test.ts +136 -0
  166. package/src/__tests__/llm-request-log-source-clickhouse.test.ts +26 -0
  167. package/src/__tests__/llm-resolver.test.ts +408 -9
  168. package/src/__tests__/llm-schema.test.ts +1 -1
  169. package/src/__tests__/llm-usage-store.test.ts +66 -0
  170. package/src/__tests__/logger.test.ts +89 -0
  171. package/src/__tests__/manual-token-reconciliation.test.ts +76 -1
  172. package/src/__tests__/mcp-abort-signal.test.ts +16 -2
  173. package/src/__tests__/mcp-client-auth.test.ts +14 -0
  174. package/src/__tests__/media-generate-image.test.ts +31 -0
  175. package/src/__tests__/memory-v2-static-injector.test.ts +7 -7
  176. package/src/__tests__/messaging-send-tool.test.ts +1 -0
  177. package/src/__tests__/migration-import-from-url.test.ts +3 -3
  178. package/src/__tests__/mock-gateway-ipc.ts +18 -2
  179. package/src/__tests__/model-intents.test.ts +4 -6
  180. package/src/__tests__/native-web-search.test.ts +30 -2
  181. package/src/__tests__/notification-deep-link.test.ts +62 -0
  182. package/src/__tests__/notification-guardian-path.test.ts +0 -1
  183. package/src/__tests__/oauth-commands-routes.test.ts +37 -0
  184. package/src/__tests__/oauth-provider-visibility.test.ts +8 -8
  185. package/src/__tests__/oauth-store.test.ts +3 -2
  186. package/src/__tests__/onboarding-template-contract.test.ts +4 -3
  187. package/src/__tests__/openai-provider.test.ts +54 -9
  188. package/src/__tests__/openai-responses-provider.test.ts +176 -14
  189. package/src/__tests__/openrouter-provider-only.test.ts +27 -5
  190. package/src/__tests__/outbound-slack-persistence.test.ts +46 -1
  191. package/src/__tests__/pending-interactions-resolved-event.test.ts +0 -1
  192. package/src/__tests__/persistence-pipeline.test.ts +139 -1
  193. package/src/__tests__/persistence-secret-redaction.test.ts +83 -12
  194. package/src/__tests__/platform-bash-auto-approve.test.ts +2 -2
  195. package/src/__tests__/platform.test.ts +2 -2
  196. package/src/__tests__/plugin-api-tool-definition.test.ts +92 -0
  197. package/src/__tests__/plugin-bootstrap.test.ts +11 -13
  198. package/src/__tests__/plugin-tool-contribution.test.ts +50 -40
  199. package/src/__tests__/plugin-types.test.ts +3 -2
  200. package/src/__tests__/prechat-onboarding-contract.test.ts +131 -98
  201. package/src/__tests__/pricing.test.ts +12 -0
  202. package/src/__tests__/process-message-background-slack.test.ts +21 -16
  203. package/src/__tests__/process-message-display-content.test.ts +19 -22
  204. package/src/__tests__/provider-catalog-visibility.test.ts +9 -9
  205. package/src/__tests__/provider-platform-proxy-integration.test.ts +216 -4
  206. package/src/__tests__/provider-registry-ollama.test.ts +45 -22
  207. package/src/__tests__/prune-jobs-changes-parser.test.ts +61 -0
  208. package/src/__tests__/recording-handler.test.ts +1 -0
  209. package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +1 -0
  210. package/src/__tests__/registry.test.ts +84 -84
  211. package/src/__tests__/relay-server.test.ts +10 -10
  212. package/src/__tests__/require-fresh-approval.test.ts +2 -2
  213. package/src/__tests__/runtime-attachment-metadata.test.ts +3 -2
  214. package/src/__tests__/runtime-events-sse-bilingual.test.ts +154 -0
  215. package/src/__tests__/schedule-store.test.ts +16 -1
  216. package/src/__tests__/scheduler-reuse-conversation.test.ts +48 -3
  217. package/src/__tests__/secret-ingress-http.test.ts +5 -1
  218. package/src/__tests__/secure-keys.test.ts +3 -3
  219. package/src/__tests__/send-endpoint-busy.test.ts +81 -42
  220. package/src/__tests__/server-history-render.test.ts +4 -1
  221. package/src/__tests__/shell-tool-proxy-mode.test.ts +1 -1
  222. package/src/__tests__/skill-feature-flags-integration.test.ts +8 -10
  223. package/src/__tests__/skill-feature-flags.test.ts +16 -18
  224. package/src/__tests__/skill-load-feature-flag.test.ts +5 -5
  225. package/src/__tests__/skill-projection-feature-flag.test.ts +48 -37
  226. package/src/__tests__/skill-projection.benchmark.test.ts +7 -13
  227. package/src/__tests__/skill-tool-factory.test.ts +97 -96
  228. package/src/__tests__/slack-channel-config.test.ts +3 -3
  229. package/src/__tests__/subagent-call-site-routing.test.ts +11 -3
  230. package/src/__tests__/subagent-disposal.test.ts +27 -8
  231. package/src/__tests__/subagent-fork-notifications.test.ts +24 -9
  232. package/src/__tests__/subagent-fork-spawn.test.ts +13 -4
  233. package/src/__tests__/subagent-manager-notify.test.ts +20 -8
  234. package/src/__tests__/subagent-notify-parent.test.ts +6 -5
  235. package/src/__tests__/subagent-spawn-tool-fork.test.ts +58 -0
  236. package/src/__tests__/subagent-tools.test.ts +2 -1
  237. package/src/__tests__/suggestion-routes.test.ts +2 -0
  238. package/src/__tests__/sync-message-contract.test.ts +59 -0
  239. package/src/__tests__/system-prompt.test.ts +183 -131
  240. package/src/__tests__/terminal-tools.test.ts +1 -1
  241. package/src/__tests__/test-preload-verifier.ts +68 -0
  242. package/src/__tests__/test-preload.ts +32 -39
  243. package/src/__tests__/tool-approval-handler.test.ts +1 -5
  244. package/src/__tests__/tool-execute-pipeline.test.ts +2 -2
  245. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +2 -5
  246. package/src/__tests__/tool-executor-lifecycle-events.test.ts +35 -12
  247. package/src/__tests__/tool-executor.test.ts +64 -72
  248. package/src/__tests__/tool-grant-request-escalation.test.ts +1 -6
  249. package/src/__tests__/tool-preview-lifecycle.test.ts +1 -0
  250. package/src/__tests__/tool-result-metadata-plumbing.test.ts +1 -0
  251. package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
  252. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +1 -6
  253. package/src/__tests__/trusted-contact-multichannel.test.ts +0 -1
  254. package/src/__tests__/twilio-routes.test.ts +3 -2
  255. package/src/__tests__/ui-file-upload-surface.test.ts +2 -2
  256. package/src/__tests__/usage-routes.test.ts +3 -0
  257. package/src/__tests__/validate-input.test.ts +381 -0
  258. package/src/__tests__/verification-control-plane-policy.test.ts +3 -2
  259. package/src/__tests__/voice-scoped-grant-consumer.test.ts +2 -1
  260. package/src/__tests__/voice-session-bridge.test.ts +37 -28
  261. package/src/__tests__/workspace-git-service.test.ts +6 -5
  262. package/src/__tests__/workspace-migration-089-move-memory-tree-out-of-v3.test.ts +86 -0
  263. package/src/__tests__/workspace-migration-090-memory-router-cost-optimized-profile.test.ts +326 -0
  264. package/src/__tests__/workspace-migration-091-retighten-migration-onboarding-thread.test.ts +166 -0
  265. package/src/acp/__tests__/prepare-agent-env.test.ts +146 -0
  266. package/src/acp/prepare-agent-env.ts +78 -0
  267. package/src/acp/session-manager.ts +6 -7
  268. package/src/agent/loop.ts +88 -0
  269. package/src/api/README.md +127 -0
  270. package/src/api/constants/call-sites.ts +27 -0
  271. package/src/api/events/assistant-outbound-attachment.ts +51 -0
  272. package/src/api/events/assistant-text-delta.ts +32 -0
  273. package/src/api/events/assistant-turn-start.ts +33 -0
  274. package/src/api/events/document-comment-created.ts +48 -0
  275. package/src/api/events/document-comment-deleted.ts +24 -0
  276. package/src/api/events/document-comment-reopened.ts +25 -0
  277. package/src/api/events/document-comment-resolved.ts +27 -0
  278. package/src/api/events/generation-cancelled.ts +24 -0
  279. package/src/api/events/generation-handoff.ts +41 -0
  280. package/src/api/events/message-complete.ts +42 -0
  281. package/src/api/events/open-url.ts +30 -0
  282. package/src/api/events/relationship-state-updated.ts +25 -0
  283. package/src/api/events/tool-use-start.ts +32 -0
  284. package/src/api/index.ts +129 -0
  285. package/src/api/package.json +10 -0
  286. package/src/api/responses/llm-context-response.ts +39 -0
  287. package/src/api/responses/llm-request-log-entry.ts +93 -0
  288. package/src/api/responses/memory-recall-log.ts +65 -0
  289. package/src/api/responses/memory-v2-activation-log.ts +78 -0
  290. package/src/background-wake/background-wake-routes.test.ts +868 -0
  291. package/src/background-wake/platform-client.test.ts +308 -0
  292. package/src/background-wake/platform-client.ts +167 -0
  293. package/src/background-wake/publisher.ts +91 -0
  294. package/src/background-wake/runtime-registry.ts +24 -0
  295. package/src/background-wake/wake-intent-hooks.test.ts +282 -0
  296. package/src/calls/guardian-dispatch.ts +1 -0
  297. package/src/calls/voice-session-bridge.ts +4 -4
  298. package/src/cli/commands/__tests__/browser.test.ts +23 -5
  299. package/src/cli/commands/__tests__/conversations-slack.test.ts +16 -0
  300. package/src/cli/commands/__tests__/domain-register.test.ts +110 -0
  301. package/src/cli/commands/__tests__/domain-status.test.ts +33 -33
  302. package/src/cli/commands/__tests__/inference-send.test.ts +108 -5
  303. package/src/cli/commands/__tests__/memory-v2-compare-render.test.ts +98 -0
  304. package/src/cli/commands/__tests__/memory-v2.test.ts +1 -0
  305. package/src/cli/commands/__tests__/memory-v3-render.test.ts +340 -0
  306. package/src/cli/commands/__tests__/notifications.test.ts +184 -40
  307. package/src/cli/commands/browser.ts +247 -0
  308. package/src/cli/commands/channels/__tests__/channels.test.ts +143 -0
  309. package/src/cli/commands/channels/index.ts +229 -0
  310. package/src/cli/commands/domain.ts +91 -41
  311. package/src/cli/commands/inference.ts +93 -40
  312. package/src/cli/commands/memory-v2-compare-render.ts +115 -0
  313. package/src/cli/commands/memory-v2.ts +176 -1
  314. package/src/cli/commands/memory-v3-render.ts +491 -0
  315. package/src/cli/commands/memory-v3.ts +567 -0
  316. package/src/cli/commands/notifications.ts +365 -55
  317. package/src/cli/lib/open-browser.ts +7 -2
  318. package/src/cli/program.ts +4 -0
  319. package/src/config/assistant-feature-flags.ts +39 -46
  320. package/src/config/bundled-skills/document-editor/SKILL.md +16 -3
  321. package/src/config/bundled-skills/document-editor/TOOLS.json +18 -0
  322. package/src/config/bundled-skills/document-editor/tools/document-open.ts +12 -0
  323. package/src/config/bundled-skills/image-studio/SKILL.md +4 -0
  324. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +2 -2
  325. package/src/config/bundled-skills/media-processing/tools/ingest-media.ts +13 -8
  326. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +10 -3
  327. package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +16 -14
  328. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +7 -2
  329. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +7 -2
  330. package/src/config/bundled-skills/schedule/SKILL.md +1 -1
  331. package/src/config/bundled-skills/schedule/TOOLS.json +2 -2
  332. package/src/config/bundled-skills/settings/tools/open-system-settings.ts +1 -0
  333. package/src/config/bundled-tool-registry.ts +2 -0
  334. package/src/config/call-site-defaults.ts +8 -7
  335. package/src/config/feature-flag-cache.ts +86 -0
  336. package/src/config/feature-flag-registry.json +33 -17
  337. package/src/config/llm-context-resolution.ts +10 -1
  338. package/src/config/llm-resolver.ts +121 -15
  339. package/src/config/loader.ts +4 -5
  340. package/src/config/schemas/__tests__/memory-v2.test.ts +228 -1
  341. package/src/config/schemas/call-site-catalog.ts +21 -7
  342. package/src/config/schemas/heartbeat.ts +1 -1
  343. package/src/config/schemas/llm.ts +102 -2
  344. package/src/config/schemas/memory-v2.ts +272 -0
  345. package/src/config/schemas/memory.ts +2 -1
  346. package/src/config/schemas/services.ts +6 -2
  347. package/src/config/seed-inference-profiles.ts +36 -16
  348. package/src/context/compactor.ts +52 -0
  349. package/src/context/token-estimator.ts +10 -5
  350. package/src/conversations/__tests__/message-consolidation.test.ts +350 -0
  351. package/src/conversations/message-consolidation.ts +404 -0
  352. package/src/credential-execution/executable-discovery.ts +40 -0
  353. package/src/credential-execution/process-manager.ts +6 -2
  354. package/src/credential-health/credential-health-service.ts +125 -40
  355. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +3 -6
  356. package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +13 -15
  357. package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +2 -3
  358. package/src/daemon/__tests__/daemon-skill-host.test.ts +2 -0
  359. package/src/daemon/__tests__/meet-manifest-loader.test.ts +25 -12
  360. package/src/daemon/__tests__/native-web-search-metadata.test.ts +1 -0
  361. package/src/daemon/__tests__/switch-inference-profile-tool.test.ts +107 -0
  362. package/src/daemon/__tests__/web-search-status-text.test.ts +1 -0
  363. package/src/daemon/conversation-agent-loop-handlers.ts +390 -80
  364. package/src/daemon/conversation-agent-loop.ts +244 -90
  365. package/src/daemon/conversation-error.ts +64 -6
  366. package/src/daemon/conversation-lifecycle.ts +27 -22
  367. package/src/daemon/conversation-messaging.ts +84 -43
  368. package/src/daemon/conversation-process.ts +74 -37
  369. package/src/daemon/conversation-runtime-assembly.ts +38 -17
  370. package/src/daemon/conversation-skill-tools.ts +14 -30
  371. package/src/daemon/conversation-surfaces.ts +69 -34
  372. package/src/daemon/conversation-tool-setup.ts +77 -32
  373. package/src/daemon/conversation-usage.ts +2 -0
  374. package/src/daemon/conversation.ts +40 -75
  375. package/src/daemon/daemon-control.ts +1 -1
  376. package/src/daemon/daemon-skill-host.ts +9 -2
  377. package/src/daemon/disk-pressure-guard.ts +39 -29
  378. package/src/daemon/first-greeting.ts +31 -13
  379. package/src/daemon/handlers/config-model.test.ts +1 -0
  380. package/src/daemon/handlers/conversations.ts +11 -3
  381. package/src/daemon/handlers/shared.ts +6 -1
  382. package/src/daemon/host-browser-proxy.ts +5 -5
  383. package/src/daemon/host-cu-proxy.ts +4 -4
  384. package/src/daemon/host-file-proxy.ts +4 -4
  385. package/src/daemon/host-proxy-base.ts +4 -4
  386. package/src/daemon/host-transfer-proxy.ts +10 -10
  387. package/src/daemon/lifecycle.ts +29 -26
  388. package/src/daemon/mcp-reload-service.ts +1 -1
  389. package/src/daemon/meet-manifest-loader.ts +11 -24
  390. package/src/daemon/message-types/conversations.ts +22 -27
  391. package/src/daemon/message-types/document-comments.ts +8 -44
  392. package/src/daemon/message-types/home.ts +2 -14
  393. package/src/daemon/message-types/integrations.ts +2 -7
  394. package/src/daemon/message-types/messages.ts +25 -48
  395. package/src/daemon/message-types/subagents.ts +6 -0
  396. package/src/daemon/message-types/sync.ts +14 -0
  397. package/src/daemon/process-message.ts +9 -9
  398. package/src/daemon/providers-setup.ts +1 -1
  399. package/src/daemon/server.ts +16 -0
  400. package/src/daemon/shutdown-handlers.ts +24 -5
  401. package/src/daemon/switch-inference-profile-tool.ts +62 -0
  402. package/src/daemon/tool-setup-types.ts +7 -0
  403. package/src/daemon/wake-target-adapter.ts +10 -0
  404. package/src/documents/document-store.ts +38 -0
  405. package/src/export/__tests__/transcript-formatter.test.ts +1 -0
  406. package/src/heartbeat/__tests__/heartbeat-service.test.ts +30 -1
  407. package/src/heartbeat/heartbeat-service.ts +63 -0
  408. package/src/home/__tests__/feed-writer.test.ts +161 -0
  409. package/src/home/__tests__/post-connect-feed.test.ts +1 -0
  410. package/src/home/__tests__/suggested-prompts.test.ts +55 -59
  411. package/src/home/feed-writer.ts +146 -7
  412. package/src/home/home-greeting.ts +0 -9
  413. package/src/home/suggested-prompts.ts +27 -154
  414. package/src/ipc/__tests__/cli-ipc.test.ts +1 -0
  415. package/src/ipc/gateway-client.test.ts +4 -1
  416. package/src/ipc/gateway-flag-listener.ts +123 -0
  417. package/src/ipc/skill-routes/__tests__/memory.test.ts +1 -0
  418. package/src/ipc/skill-routes/__tests__/registries.test.ts +36 -7
  419. package/src/ipc/skill-routes/memory.ts +4 -3
  420. package/src/ipc/skill-routes/registries.ts +35 -40
  421. package/src/memory/__tests__/db-async-query.test.ts +165 -0
  422. package/src/memory/__tests__/db-maintenance.test.ts +115 -0
  423. package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +242 -0
  424. package/src/memory/__tests__/jobs-store-job-classes.test.ts +28 -1
  425. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +26 -5
  426. package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +1 -0
  427. package/src/memory/__tests__/memory-retrospective-job.test.ts +8 -0
  428. package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +1 -0
  429. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +31 -0
  430. package/src/memory/auto-analysis-enqueue.ts +5 -1
  431. package/src/memory/conversation-attention-store.ts +17 -3
  432. package/src/memory/conversation-crud.ts +423 -182
  433. package/src/memory/conversation-starters-cadence.ts +3 -1
  434. package/src/memory/conversation-title-service.ts +19 -3
  435. package/src/memory/db-async-query.ts +214 -0
  436. package/src/memory/db-connection.ts +29 -19
  437. package/src/memory/db-init.ts +14 -0
  438. package/src/memory/db-maintenance.ts +30 -21
  439. package/src/memory/db-singleton.ts +77 -0
  440. package/src/memory/delivery-channels.ts +82 -0
  441. package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +2 -4
  442. package/src/memory/graph/bootstrap.ts +8 -1
  443. package/src/memory/graph/capability-seed.ts +7 -3
  444. package/src/memory/graph/conversation-graph-memory.ts +100 -17
  445. package/src/memory/graph/extraction.ts +1 -5
  446. package/src/memory/graph/graph-search.ts +7 -1
  447. package/src/memory/graph/retriever.test.ts +3 -3
  448. package/src/memory/indexer.ts +28 -18
  449. package/src/memory/job-handlers/cleanup.ts +76 -18
  450. package/src/memory/job-handlers/conversation-starters.ts +1 -4
  451. package/src/memory/job-handlers/embedding.test.ts +3 -2
  452. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +5 -2
  453. package/src/memory/jobs/embed-pkb-file.ts +6 -1
  454. package/src/memory/jobs-store.ts +14 -0
  455. package/src/memory/jobs-worker.ts +66 -22
  456. package/src/memory/llm-request-log-source-clickhouse.ts +122 -2
  457. package/src/memory/llm-request-log-source-local.ts +31 -0
  458. package/src/memory/llm-request-log-source.ts +40 -2
  459. package/src/memory/llm-request-log-store.ts +228 -1
  460. package/src/memory/llm-usage-store.ts +24 -0
  461. package/src/memory/memory-retrospective-enqueue.ts +8 -1
  462. package/src/memory/memory-retrospective-job.ts +5 -0
  463. package/src/memory/memory-v2-activation-log-store.ts +110 -7
  464. package/src/memory/migrations/260-rename-cleaned-at.ts +44 -0
  465. package/src/memory/migrations/261-llm-usage-add-raw-usage.ts +36 -0
  466. package/src/memory/migrations/262-memory-v3-coactivation.ts +57 -0
  467. package/src/memory/migrations/263-memory-v3-auto-edges.ts +50 -0
  468. package/src/memory/migrations/264-llm-request-log-call-site.ts +29 -0
  469. package/src/memory/migrations/265-drop-provider-connection-status.ts +26 -0
  470. package/src/memory/migrations/266-messages-client-message-id.ts +43 -0
  471. package/src/memory/migrations/index.ts +19 -0
  472. package/src/memory/migrations/registry.ts +33 -0
  473. package/src/memory/schema/conversations.ts +10 -2
  474. package/src/memory/schema/inference.ts +0 -1
  475. package/src/memory/schema/infrastructure.ts +21 -0
  476. package/src/memory/tool-usage-store.ts +36 -8
  477. package/src/memory/v2/__tests__/backfill-jobs.test.ts +5 -2
  478. package/src/memory/v2/__tests__/consolidation-job.test.ts +1 -0
  479. package/src/memory/v2/__tests__/harness-compare.test.ts +186 -0
  480. package/src/memory/v2/__tests__/harness-metrics.test.ts +83 -0
  481. package/src/memory/v2/__tests__/harness-oracle.test.ts +257 -0
  482. package/src/memory/v2/__tests__/harness-replay-input.test.ts +230 -0
  483. package/src/memory/v2/__tests__/harness-runner.test.ts +135 -0
  484. package/src/memory/v2/__tests__/injection.test.ts +127 -98
  485. package/src/memory/v2/__tests__/qdrant.test.ts +36 -0
  486. package/src/memory/v2/__tests__/router.test.ts +171 -3
  487. package/src/memory/v2/__tests__/sweep-job.test.ts +6 -3
  488. package/src/memory/v2/harness/compare.ts +57 -0
  489. package/src/memory/v2/harness/metrics.ts +128 -0
  490. package/src/memory/v2/harness/oracle.ts +145 -0
  491. package/src/memory/v2/harness/replay-input.ts +240 -0
  492. package/src/memory/v2/harness/retriever.ts +74 -0
  493. package/src/memory/v2/harness/router-retriever.ts +43 -0
  494. package/src/memory/v2/harness/runner.ts +112 -0
  495. package/src/memory/v2/harness/trace.ts +64 -0
  496. package/src/memory/v2/injection.ts +21 -15
  497. package/src/memory/v2/prompts/router.ts +26 -1
  498. package/src/memory/v2/qdrant.ts +14 -2
  499. package/src/memory/v2/router.ts +171 -18
  500. package/src/memory/v3/__tests__/coactivation-store.test.ts +422 -0
  501. package/src/memory/v3/__tests__/consolidation-job.test.ts +466 -0
  502. package/src/memory/v3/__tests__/coretrieval-seed.test.ts +270 -0
  503. package/src/memory/v3/__tests__/edge-learning-job.test.ts +324 -0
  504. package/src/memory/v3/__tests__/edges.test.ts +706 -0
  505. package/src/memory/v3/__tests__/filter.test.ts +560 -0
  506. package/src/memory/v3/__tests__/gate.test.ts +637 -0
  507. package/src/memory/v3/__tests__/index-composition.test.ts +291 -0
  508. package/src/memory/v3/__tests__/loop.test.ts +775 -0
  509. package/src/memory/v3/__tests__/retriever.test.ts +226 -0
  510. package/src/memory/v3/__tests__/scouts.test.ts +489 -0
  511. package/src/memory/v3/__tests__/shadow-diff.test.ts +225 -0
  512. package/src/memory/v3/__tests__/shadow-middleware.test.ts +398 -0
  513. package/src/memory/v3/__tests__/system-prompts.test.ts +154 -0
  514. package/src/memory/v3/__tests__/traversal.test.ts +508 -0
  515. package/src/memory/v3/__tests__/tree-index.test.ts +280 -0
  516. package/src/memory/v3/__tests__/tree-store.test.ts +529 -0
  517. package/src/memory/v3/__tests__/tree-walk.test.ts +784 -0
  518. package/src/memory/v3/__tests__/validate.test.ts +277 -0
  519. package/src/memory/v3/auto-edges.ts +223 -0
  520. package/src/memory/v3/coactivation-store.ts +124 -0
  521. package/src/memory/v3/consolidation-job.ts +323 -0
  522. package/src/memory/v3/coretrieval-seed.ts +240 -0
  523. package/src/memory/v3/edge-learning-job.ts +160 -0
  524. package/src/memory/v3/edges.ts +286 -0
  525. package/src/memory/v3/filter.ts +286 -0
  526. package/src/memory/v3/gate.ts +349 -0
  527. package/src/memory/v3/index-composition.ts +126 -0
  528. package/src/memory/v3/llm-capture.ts +46 -0
  529. package/src/memory/v3/loop.ts +430 -0
  530. package/src/memory/v3/maintenance.ts +144 -0
  531. package/src/memory/v3/prompt-context.ts +33 -0
  532. package/src/memory/v3/prompts/consolidation.ts +458 -0
  533. package/src/memory/v3/prompts/system-prompts.ts +196 -0
  534. package/src/memory/v3/retriever.ts +33 -0
  535. package/src/memory/v3/scouts.ts +431 -0
  536. package/src/memory/v3/shadow-diff.ts +287 -0
  537. package/src/memory/v3/shadow-middleware.ts +347 -0
  538. package/src/memory/v3/traversal.ts +211 -0
  539. package/src/memory/v3/tree-index.ts +237 -0
  540. package/src/memory/v3/tree-store.ts +394 -0
  541. package/src/memory/v3/tree-walk.ts +356 -0
  542. package/src/memory/v3/types.ts +65 -0
  543. package/src/memory/v3/validate.ts +323 -0
  544. package/src/notifications/__tests__/emit-signal-home-feed.test.ts +1 -0
  545. package/src/notifications/__tests__/home-feed-side-effect.test.ts +1 -0
  546. package/src/notifications/adapters/macos.ts +18 -1
  547. package/src/notifications/adapters/platform.ts +1 -1
  548. package/src/notifications/adapters/slack.ts +45 -11
  549. package/src/notifications/broadcaster.ts +114 -63
  550. package/src/notifications/conversation-pairing.ts +23 -3
  551. package/src/notifications/decision-engine.ts +1 -4
  552. package/src/notifications/decisions-store.ts +32 -1
  553. package/src/notifications/deliveries-store.ts +45 -0
  554. package/src/notifications/edit-notification.ts +201 -0
  555. package/src/notifications/emit-signal.ts +40 -50
  556. package/src/notifications/signal.ts +10 -0
  557. package/src/notifications/types.ts +37 -0
  558. package/src/oauth/byo-connection.test.ts +67 -3
  559. package/src/oauth/byo-connection.ts +32 -5
  560. package/src/oauth/connect-orchestrator.ts +9 -0
  561. package/src/oauth/connection-resolver.test.ts +76 -0
  562. package/src/oauth/connection-resolver.ts +49 -10
  563. package/src/oauth/manual-token-connection.ts +51 -3
  564. package/src/oauth/seed-providers.ts +3 -0
  565. package/src/permissions/approval-policy.test.ts +19 -5
  566. package/src/permissions/approval-policy.ts +14 -3
  567. package/src/permissions/checker.ts +21 -8
  568. package/src/permissions/prompter.ts +3 -3
  569. package/src/permissions/question-prompter.ts +5 -2
  570. package/src/permissions/secret-prompter.ts +2 -2
  571. package/src/platform/client.test.ts +24 -1
  572. package/src/platform/client.ts +8 -0
  573. package/src/platform/feature-gate.ts +15 -0
  574. package/src/plugin-api/index.ts +4 -0
  575. package/src/plugin-api/types.ts +7 -33
  576. package/src/plugins/defaults/index.ts +6 -0
  577. package/src/plugins/defaults/injectors.ts +20 -19
  578. package/src/plugins/defaults/persistence.ts +25 -6
  579. package/src/plugins/external-plugin-loader.ts +5 -68
  580. package/src/plugins/types.ts +68 -29
  581. package/src/proactive-artifact/aux-message-injector.ts +17 -4
  582. package/src/proactive-artifact/job.test.ts +1 -0
  583. package/src/prompts/__tests__/system-prompt.test.ts +4 -4
  584. package/src/prompts/__tests__/task-progress-hint-section.test.ts +3 -9
  585. package/src/prompts/persona-resolver.ts +36 -21
  586. package/src/prompts/sections.ts +39 -7
  587. package/src/prompts/system-prompt.ts +84 -221
  588. package/src/prompts/template-detection.ts +10 -4
  589. package/src/prompts/templates/BOOTSTRAP.md +9 -13
  590. package/src/prompts/templates/IDENTITY.md +0 -2
  591. package/src/prompts/templates/system-sections.ts +230 -8
  592. package/src/providers/__tests__/connection-model-compat.test.ts +233 -0
  593. package/src/providers/__tests__/registry-native-web-search.test.ts +122 -0
  594. package/src/providers/__tests__/retry-callsite.test.ts +85 -5
  595. package/src/providers/anthropic/client.ts +32 -66
  596. package/src/providers/call-site-routing.ts +42 -6
  597. package/src/providers/connection-model-compat.ts +61 -0
  598. package/src/providers/connection-resolution.ts +47 -14
  599. package/src/providers/fireworks/client.ts +1 -0
  600. package/src/providers/gemini/client.ts +70 -6
  601. package/src/providers/inference/__tests__/adapter-factory-openai-compatible.test.ts +0 -2
  602. package/src/providers/inference/__tests__/base-url-security.test.ts +2 -3
  603. package/src/providers/inference/__tests__/{connections-status-label.test.ts → connections-label.test.ts} +12 -111
  604. package/src/providers/inference/adapter-factory.ts +3 -0
  605. package/src/providers/inference/auth.ts +0 -8
  606. package/src/providers/inference/connections.ts +3 -66
  607. package/src/providers/inference/resolve-auth.ts +2 -3
  608. package/src/providers/minimax/client.ts +106 -0
  609. package/src/providers/model-catalog.ts +78 -1
  610. package/src/providers/model-intents.ts +4 -4
  611. package/src/providers/openai/__tests__/api-error-detail.test.ts +120 -0
  612. package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +157 -5
  613. package/src/providers/openai/chat-completions-provider.ts +116 -15
  614. package/src/providers/openai/codex-models.ts +20 -0
  615. package/src/providers/openai/responses-provider.ts +87 -30
  616. package/src/providers/openrouter/client.ts +13 -8
  617. package/src/providers/provider-send-message.ts +20 -5
  618. package/src/providers/registry.ts +48 -8
  619. package/src/providers/retry.ts +50 -7
  620. package/src/providers/search-provider-catalog.ts +17 -9
  621. package/src/providers/thinking-config.ts +26 -1
  622. package/src/providers/types.ts +9 -0
  623. package/src/providers/usage-tracking.ts +2 -0
  624. package/src/runtime/AGENTS.md +2 -2
  625. package/src/runtime/__tests__/agent-wake.test.ts +1 -0
  626. package/src/runtime/__tests__/background-job-runner.test.ts +1 -0
  627. package/src/runtime/access-request-helper.ts +1 -0
  628. package/src/runtime/agent-wake.ts +1 -0
  629. package/src/runtime/assistant-event-hub.ts +76 -6
  630. package/src/runtime/auth/route-policy.ts +46 -0
  631. package/src/runtime/btw-sidechain.ts +0 -6
  632. package/src/runtime/channel-readiness-service.ts +68 -0
  633. package/src/runtime/channel-reply-delivery.ts +23 -0
  634. package/src/runtime/channel-retry-sweep.ts +47 -14
  635. package/src/runtime/confirmation-request-guardian-bridge.ts +1 -1
  636. package/src/runtime/http-types.ts +0 -2
  637. package/src/runtime/migrations/vbundle-builder.ts +12 -4
  638. package/src/runtime/pending-interactions.ts +0 -1
  639. package/src/runtime/routes/__tests__/bookmark-routes.test.ts +1 -0
  640. package/src/runtime/routes/__tests__/conversation-compaction-routes.test.ts +406 -0
  641. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +204 -0
  642. package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +1 -1
  643. package/src/runtime/routes/__tests__/home-feed-routes.test.ts +209 -1
  644. package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +13 -50
  645. package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +76 -9
  646. package/src/runtime/routes/__tests__/memory-v3-simulate-params.test.ts +35 -0
  647. package/src/runtime/routes/__tests__/plugins-routes.test.ts +512 -0
  648. package/src/runtime/routes/__tests__/slack-channel-routes.test.ts +3 -2
  649. package/src/runtime/routes/__tests__/surface-content-routes.test.ts +294 -0
  650. package/src/runtime/routes/__tests__/task-routes.test.ts +48 -3
  651. package/src/runtime/routes/acp-routes-list.test.ts +3 -0
  652. package/src/runtime/routes/acp-routes.test.ts +255 -6
  653. package/src/runtime/routes/acp-routes.ts +8 -1
  654. package/src/runtime/routes/app-management-routes.ts +111 -4
  655. package/src/runtime/routes/avatar-routes.ts +10 -10
  656. package/src/runtime/routes/background-wake-routes.ts +356 -0
  657. package/src/runtime/routes/browser-tabs-routes.ts +200 -0
  658. package/src/runtime/routes/btw-routes.ts +4 -10
  659. package/src/runtime/routes/conversation-analysis-routes.ts +6 -0
  660. package/src/runtime/routes/conversation-cli-routes.ts +1 -1
  661. package/src/runtime/routes/conversation-compaction-routes.ts +263 -0
  662. package/src/runtime/routes/conversation-list-routes.ts +159 -4
  663. package/src/runtime/routes/conversation-management-routes.ts +108 -26
  664. package/src/runtime/routes/conversation-query-routes.ts +200 -44
  665. package/src/runtime/routes/conversation-routes.ts +409 -521
  666. package/src/runtime/routes/conversation-starter-routes.ts +6 -3
  667. package/src/runtime/routes/conversations-import-routes.ts +19 -6
  668. package/src/runtime/routes/disk-pressure-routes.ts +1 -1
  669. package/src/runtime/routes/documents-routes.ts +10 -1
  670. package/src/runtime/routes/domain-routes.ts +60 -10
  671. package/src/runtime/routes/email-routes.ts +5 -2
  672. package/src/runtime/routes/events-routes.ts +54 -10
  673. package/src/runtime/routes/group-routes.ts +35 -8
  674. package/src/runtime/routes/home-feed-routes.ts +129 -0
  675. package/src/runtime/routes/host-browser-routes.ts +10 -2
  676. package/src/runtime/routes/host-cu-routes.ts +2 -2
  677. package/src/runtime/routes/identity-intro-cache.ts +61 -16
  678. package/src/runtime/routes/identity-routes.ts +30 -9
  679. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +96 -3
  680. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +530 -6
  681. package/src/runtime/routes/inbound-stages/background-dispatch.ts +57 -8
  682. package/src/runtime/routes/index.ts +10 -0
  683. package/src/runtime/routes/inference-profile-session-handler.ts +22 -12
  684. package/src/runtime/routes/inference-profile-session-routes.ts +7 -1
  685. package/src/runtime/routes/inference-provider-connection-routes.ts +5 -26
  686. package/src/runtime/routes/integrations/vercel.ts +15 -0
  687. package/src/runtime/routes/llm-call-sites-routes.ts +32 -5
  688. package/src/runtime/routes/llm-context-normalization.ts +7 -2
  689. package/src/runtime/routes/memory-item-routes.ts +8 -3
  690. package/src/runtime/routes/memory-v2-routes.ts +215 -5
  691. package/src/runtime/routes/memory-v3-routes.ts +474 -0
  692. package/src/runtime/routes/migration-routes.ts +32 -28
  693. package/src/runtime/routes/notification-routes.ts +63 -1
  694. package/src/runtime/routes/oauth-commands-routes.ts +6 -1
  695. package/src/runtime/routes/plugins-routes.ts +337 -0
  696. package/src/runtime/routes/rename-conversation-routes.ts +6 -2
  697. package/src/runtime/routes/secret-routes.ts +25 -5
  698. package/src/runtime/routes/settings-routes.ts +12 -11
  699. package/src/runtime/routes/slack-channel-routes.ts +5 -4
  700. package/src/runtime/routes/surface-action-routes.ts +1 -38
  701. package/src/runtime/routes/surface-content-routes.ts +12 -5
  702. package/src/runtime/routes/surface-conversation-resolver.ts +65 -0
  703. package/src/runtime/routes/wipe-conversation-routes.ts +3 -0
  704. package/src/runtime/routes/workspace-routes.ts +25 -10
  705. package/src/runtime/services/__tests__/analyze-conversation.test.ts +2 -0
  706. package/src/runtime/slack-dm-text-delivery.ts +177 -0
  707. package/src/runtime/sync/resource-sync-events.ts +106 -38
  708. package/src/runtime/sync/sync-publisher.test.ts +49 -0
  709. package/src/runtime/sync/sync-publisher.ts +2 -1
  710. package/src/runtime/tool-grant-request-helper.ts +1 -0
  711. package/src/runtime/verification-outbound-actions.ts +73 -1
  712. package/src/schedule/schedule-store.ts +8 -1
  713. package/src/schedule/scheduler.ts +111 -15
  714. package/src/security/__tests__/provider-key-env-fallback.test.ts +3 -3
  715. package/src/security/encrypted-store.ts +7 -16
  716. package/src/security/store-path-override.ts +61 -0
  717. package/src/signals/user-message.ts +5 -8
  718. package/src/skills/validate-input.ts +177 -0
  719. package/src/subagent/manager.ts +13 -13
  720. package/src/subagent/types.ts +6 -0
  721. package/src/tasks/tool-sanitizer.ts +2 -2
  722. package/src/telemetry/types.ts +12 -0
  723. package/src/telemetry/usage-telemetry-reporter.test.ts +48 -0
  724. package/src/telemetry/usage-telemetry-reporter.ts +1 -0
  725. package/src/tools/acp/spawn.test.ts +119 -0
  726. package/src/tools/acp/spawn.ts +15 -2
  727. package/src/tools/apps/definitions.ts +36 -28
  728. package/src/tools/ask-question/ask-question-tool.test.ts +3 -3
  729. package/src/tools/ask-question/ask-question-tool.ts +38 -45
  730. package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +2 -8
  731. package/src/tools/browser/__tests__/pinned-tabs.test.ts +70 -0
  732. package/src/tools/browser/browser-execution.ts +16 -3
  733. package/src/tools/browser/cdp-client/__tests__/browser-tabs-factory.test.ts +402 -0
  734. package/src/tools/browser/cdp-client/__tests__/types.test.ts +3 -0
  735. package/src/tools/browser/cdp-client/cdp-inspect-client.ts +12 -0
  736. package/src/tools/browser/cdp-client/extension-cdp-client.ts +27 -1
  737. package/src/tools/browser/cdp-client/factory.ts +100 -17
  738. package/src/tools/browser/cdp-client/local-cdp-client.ts +12 -0
  739. package/src/tools/browser/cdp-client/types.ts +65 -0
  740. package/src/tools/browser/pinned-tabs.ts +96 -40
  741. package/src/tools/computer-use/definitions.ts +282 -336
  742. package/src/tools/credential-execution/make-authenticated-request.ts +3 -9
  743. package/src/tools/credential-execution/manage-secure-command-tool.ts +3 -9
  744. package/src/tools/credential-execution/run-authenticated-command.ts +3 -9
  745. package/src/tools/credentials/vault.ts +3 -9
  746. package/src/tools/document/document-tool.ts +189 -7
  747. package/src/tools/execution-target.ts +18 -23
  748. package/src/tools/executor.ts +24 -56
  749. package/src/tools/filesystem/edit.ts +3 -9
  750. package/src/tools/filesystem/list.ts +3 -9
  751. package/src/tools/filesystem/read.ts +3 -9
  752. package/src/tools/filesystem/write.ts +3 -9
  753. package/src/tools/host-filesystem/edit.test.ts +1 -0
  754. package/src/tools/host-filesystem/edit.ts +3 -9
  755. package/src/tools/host-filesystem/read.test.ts +1 -0
  756. package/src/tools/host-filesystem/read.ts +3 -9
  757. package/src/tools/host-filesystem/transfer.test.ts +31 -6
  758. package/src/tools/host-filesystem/transfer.ts +3 -9
  759. package/src/tools/host-filesystem/write.test.ts +1 -0
  760. package/src/tools/host-filesystem/write.ts +3 -9
  761. package/src/tools/host-terminal/host-shell.ts +3 -9
  762. package/src/tools/mcp/mcp-tool-factory.ts +1 -10
  763. package/src/tools/memory/register.test.ts +1 -1
  764. package/src/tools/memory/register.ts +4 -9
  765. package/src/tools/network/__tests__/managed-search-proxy.test.ts +282 -0
  766. package/src/tools/network/__tests__/web-search.test.ts +211 -3
  767. package/src/tools/network/managed-search-proxy.ts +183 -0
  768. package/src/tools/network/web-fetch.ts +3 -9
  769. package/src/tools/network/web-search.ts +224 -76
  770. package/src/tools/policy-context.ts +3 -1
  771. package/src/tools/registry.ts +150 -123
  772. package/src/tools/schedule/create.ts +1 -1
  773. package/src/tools/schema-transforms.ts +1 -1
  774. package/src/tools/skills/execute.ts +3 -9
  775. package/src/tools/skills/load.ts +3 -9
  776. package/src/tools/skills/skill-tool-factory.ts +18 -44
  777. package/src/tools/subagent/notify-parent.ts +3 -9
  778. package/src/tools/subagent/spawn.ts +3 -0
  779. package/src/tools/system/request-permission.ts +3 -9
  780. package/src/tools/terminal/shell.ts +3 -9
  781. package/src/tools/tool-approval-handler.ts +10 -4
  782. package/src/tools/tool-defaults.ts +94 -0
  783. package/src/tools/tool-name-aliases.ts +72 -14
  784. package/src/tools/types.ts +32 -101
  785. package/src/tools/ui-surface/definitions.ts +104 -108
  786. package/src/types/onboarding-context.ts +6 -0
  787. package/src/usage/attribution.ts +32 -1
  788. package/src/usage/pricing.ts +23 -0
  789. package/src/usage/types.ts +12 -0
  790. package/src/util/browser.ts +7 -2
  791. package/src/util/logger.ts +16 -7
  792. package/src/util/platform.ts +7 -2
  793. package/src/util/sqlite3-runtime.ts +65 -0
  794. package/src/workspace/migrations/086-revert-stale-gemini-mis-rewrites.ts +1 -0
  795. package/src/workspace/migrations/089-move-memory-tree-out-of-v3.ts +86 -0
  796. package/src/workspace/migrations/090-memory-router-cost-optimized-profile.ts +109 -0
  797. package/src/workspace/migrations/091-retighten-migration-onboarding-thread.ts +41 -0
  798. package/src/workspace/migrations/registry.ts +6 -0
  799. package/src/__tests__/compaction-strip-metadata-clear.test.ts +0 -206
  800. package/src/__tests__/message-complete-display-id.test.ts +0 -175
  801. package/src/daemon/query-complexity-router.ts +0 -75
  802. package/src/prompts/cache-boundary.ts +0 -8
@@ -23,7 +23,7 @@ mock.module("../util/logger.js", () => ({
23
23
  }));
24
24
 
25
25
  // Mock config loader and feature flags to avoid filesystem reads on CI.
26
- // getConfig returns a minimal config; all feature flags default to enabled.
26
+ // The benchmark fixture treats every feature flag as enabled.
27
27
  mock.module("../config/loader.js", () => ({
28
28
  getConfig: () => ({}),
29
29
  loadConfig: () => ({}),
@@ -102,23 +102,16 @@ mock.module("../tools/skills/skill-tool-factory.js", () => ({
102
102
  entries: Array<{ name: string; description: string; input_schema: object }>,
103
103
  skillId: string,
104
104
  _skillDir: string,
105
- versionHash: string,
106
- bundled?: boolean,
105
+ _versionHash: string,
106
+ _bundled?: boolean,
107
107
  ) =>
108
108
  entries.map((e) => ({
109
109
  name: e.name,
110
110
  description: e.description,
111
111
  category: "skill",
112
112
  defaultRiskLevel: "low",
113
- origin: "skill" as const,
114
- ownerSkillId: skillId,
115
- ownerSkillVersionHash: versionHash,
116
- ownerSkillBundled: bundled,
117
- getDefinition: () => ({
118
- name: e.name,
119
- description: e.description,
120
- input_schema: e.input_schema,
121
- }),
113
+ owner: { kind: "skill" as const, id: skillId },
114
+ input_schema: e.input_schema,
122
115
  execute: async () => ({ content: "", isError: false }),
123
116
  })),
124
117
  }));
@@ -170,7 +163,8 @@ mock.module("../tools/registry.js", () => ({
170
163
  },
171
164
  unregisterSkillTools: (skillId: string) => {
172
165
  for (const [name, t] of benchmarkRegistry) {
173
- if ((t as { ownerSkillId?: string }).ownerSkillId === skillId)
166
+ const owner = (t as { owner?: { kind: string; id: string } }).owner;
167
+ if (owner?.kind === "skill" && owner.id === skillId)
174
168
  benchmarkRegistry.delete(name);
175
169
  }
176
170
  },
@@ -73,53 +73,23 @@ afterAll(async () => {
73
73
 
74
74
  describe("createSkillTool", () => {
75
75
  test("produces a tool with correct name, description, and category", () => {
76
- const tool = createSkillTool(
77
- makeEntry(),
78
- "my-skill",
79
- "/skills/my-skill",
80
- "v1:test",
81
- );
76
+ const tool = createSkillTool(makeEntry(), "/skills/my-skill", "v1:test");
82
77
 
83
78
  expect(tool.name).toBe("test_tool");
84
79
  expect(tool.description).toBe("A test tool");
85
80
  expect(tool.category).toBe("testing");
86
81
  });
87
82
 
88
- test("sets origin to skill and ownerSkillId", () => {
89
- const tool = createSkillTool(
90
- makeEntry(),
91
- "weather-skill",
92
- "/skills/weather",
93
- "v1:test",
94
- );
95
-
96
- expect(tool.origin).toBe("skill");
97
- expect(tool.ownerSkillId).toBe("weather-skill");
98
- });
99
-
100
- test("sets ownerSkillVersionHash from versionHash", () => {
101
- const hash = "v1:abc123def456";
102
- const tool = createSkillTool(
103
- makeEntry(),
104
- "my-skill",
105
- "/skills/my-skill",
106
- hash,
107
- );
108
-
109
- expect(tool.ownerSkillVersionHash).toBe(hash);
110
- });
83
+ // Removed "sets origin to skill" test the factory no longer stamps an
84
+ // origin/kind on the Tool. Ownership is recorded by `registerSkillTools`
85
+ // in the registry; see registry.test.ts.
111
86
 
112
87
  test.each([
113
88
  ["low", RiskLevel.Low],
114
89
  ["medium", RiskLevel.Medium],
115
90
  ["high", RiskLevel.High],
116
91
  ] as const)('maps risk "%s" to RiskLevel.%s', (risk, expected) => {
117
- const tool = createSkillTool(
118
- makeEntry({ risk }),
119
- "sk",
120
- "/skills/sk",
121
- "v1:test",
122
- );
92
+ const tool = createSkillTool(makeEntry({ risk }), "/skills/sk", "v1:test");
123
93
 
124
94
  expect(tool.defaultRiskLevel).toBe(expected);
125
95
  });
@@ -140,12 +110,11 @@ describe("createSkillTool", () => {
140
110
  description: "Scrape a URL",
141
111
  input_schema: schema,
142
112
  }),
143
- "scraper",
144
113
  "/skills/scraper",
145
114
  "v1:test",
146
115
  );
147
116
 
148
- const def = tool.getDefinition();
117
+ const def = tool;
149
118
 
150
119
  expect(def.name).toBe("web_scrape");
151
120
  expect(def.description).toBe("Scrape a URL");
@@ -160,7 +129,6 @@ describe("createSkillTool", () => {
160
129
  const hash = computeSkillVersionHash(tempDir);
161
130
  const tool = createSkillTool(
162
131
  makeEntry({ executor: "echo.ts" }),
163
- "my-skill",
164
132
  tempDir,
165
133
  hash,
166
134
  );
@@ -179,12 +147,13 @@ describe("createSkillTool", () => {
179
147
  const hash = computeSkillVersionHash(tempDir);
180
148
  const tool = createSkillTool(
181
149
  makeEntry({ executor: "nonexistent.ts" }),
182
- "my-skill",
183
150
  tempDir,
184
151
  hash,
185
152
  );
186
153
 
187
- const result = await tool.execute({}, makeContext());
154
+ // Provide valid input so we reach the executor (the default schema
155
+ // declares `query` as required).
156
+ const result = await tool.execute({ query: "x" }, makeContext());
188
157
 
189
158
  expect(result.isError).toBe(true);
190
159
  expect(result.content).toContain("Failed to load skill tool script");
@@ -205,7 +174,6 @@ describe("createSkillToolsFromManifest", () => {
205
174
 
206
175
  const tools = createSkillToolsFromManifest(
207
176
  entries,
208
- "multi-skill",
209
177
  "/skills/multi",
210
178
  "v1:test",
211
179
  );
@@ -219,54 +187,15 @@ describe("createSkillToolsFromManifest", () => {
219
187
  ]);
220
188
  });
221
189
 
222
- test("all created tools share the same skillId and origin", () => {
223
- const entries: SkillToolEntry[] = [
224
- makeEntry({ name: "alpha" }),
225
- makeEntry({ name: "beta" }),
226
- ];
227
-
228
- const tools = createSkillToolsFromManifest(
229
- entries,
230
- "shared-skill",
231
- "/skills/shared",
232
- "v1:test",
233
- );
234
-
235
- for (const tool of tools) {
236
- expect(tool.origin).toBe("skill");
237
- expect(tool.ownerSkillId).toBe("shared-skill");
238
- }
239
- });
190
+ // Removed "all created tools share the same origin" same reason as the
191
+ // single-tool case above: ownership is recorded by `registerSkillTools` in
192
+ // the registry, not stamped onto each Tool by the factory.
240
193
 
241
194
  test("returns an empty array when given no entries", () => {
242
- const tools = createSkillToolsFromManifest(
243
- [],
244
- "empty-skill",
245
- "/skills/empty",
246
- "v1:test",
247
- );
195
+ const tools = createSkillToolsFromManifest([], "/skills/empty", "v1:test");
248
196
 
249
197
  expect(tools).toEqual([]);
250
198
  });
251
-
252
- test("passes versionHash through to all created tools", () => {
253
- const hash = "v1:deadbeef";
254
- const entries: SkillToolEntry[] = [
255
- makeEntry({ name: "alpha" }),
256
- makeEntry({ name: "beta" }),
257
- ];
258
-
259
- const tools = createSkillToolsFromManifest(
260
- entries,
261
- "versioned-skill",
262
- "/skills/versioned",
263
- hash,
264
- );
265
-
266
- for (const tool of tools) {
267
- expect(tool.ownerSkillVersionHash).toBe(hash);
268
- }
269
- });
270
199
  });
271
200
 
272
201
  // ---------------------------------------------------------------------------
@@ -278,7 +207,6 @@ describe("createSkillTool — unknown parameter validation", () => {
278
207
  const hash = computeSkillVersionHash(tempDir);
279
208
  const tool = createSkillTool(
280
209
  makeEntry({ executor: "echo.ts" }),
281
- "my-skill",
282
210
  tempDir,
283
211
  hash,
284
212
  );
@@ -289,8 +217,9 @@ describe("createSkillTool — unknown parameter validation", () => {
289
217
  );
290
218
 
291
219
  expect(result.isError).toBe(true);
220
+ expect(result.content).toContain('Invalid input for tool "test_tool"');
292
221
  expect(result.content).toContain('Unknown parameter "unsubscribe"');
293
- expect(result.content).toContain("Supported parameters");
222
+ expect(result.content).toContain("Supported:");
294
223
  expect(result.content).toContain('"query"');
295
224
  });
296
225
 
@@ -298,7 +227,6 @@ describe("createSkillTool — unknown parameter validation", () => {
298
227
  const hash = computeSkillVersionHash(tempDir);
299
228
  const tool = createSkillTool(
300
229
  makeEntry({ executor: "echo.ts" }),
301
- "my-skill",
302
230
  tempDir,
303
231
  hash,
304
232
  );
@@ -309,16 +237,15 @@ describe("createSkillTool — unknown parameter validation", () => {
309
237
  );
310
238
 
311
239
  expect(result.isError).toBe(true);
312
- expect(result.content).toContain("Unknown parameters");
313
- expect(result.content).toContain('"foo"');
314
- expect(result.content).toContain('"bar"');
240
+ expect(result.content).toContain('Invalid input for tool "test_tool"');
241
+ expect(result.content).toContain('Unknown parameter "foo"');
242
+ expect(result.content).toContain('Unknown parameter "bar"');
315
243
  });
316
244
 
317
245
  test("allows input with only known parameters", async () => {
318
246
  const hash = computeSkillVersionHash(tempDir);
319
247
  const tool = createSkillTool(
320
248
  makeEntry({ executor: "echo.ts" }),
321
- "my-skill",
322
249
  tempDir,
323
250
  hash,
324
251
  );
@@ -338,7 +265,6 @@ describe("createSkillTool — unknown parameter validation", () => {
338
265
  properties: { query: { type: "string" } },
339
266
  },
340
267
  }),
341
- "my-skill",
342
268
  tempDir,
343
269
  hash,
344
270
  );
@@ -355,7 +281,6 @@ describe("createSkillTool — unknown parameter validation", () => {
355
281
  executor: "echo.ts",
356
282
  input_schema: { type: "object" },
357
283
  }),
358
- "my-skill",
359
284
  tempDir,
360
285
  hash,
361
286
  );
@@ -366,6 +291,85 @@ describe("createSkillTool — unknown parameter validation", () => {
366
291
  });
367
292
  });
368
293
 
294
+ // ---------------------------------------------------------------------------
295
+ // createSkillTool — required / type / enum validation
296
+ // ---------------------------------------------------------------------------
297
+
298
+ describe("createSkillTool — required/type/enum validation", () => {
299
+ test("rejects missing required field with self-correcting message", async () => {
300
+ const hash = computeSkillVersionHash(tempDir);
301
+ const tool = createSkillTool(
302
+ makeEntry({ executor: "echo.ts" }),
303
+ tempDir,
304
+ hash,
305
+ );
306
+
307
+ const result = await tool.execute({}, makeContext());
308
+
309
+ expect(result.isError).toBe(true);
310
+ expect(result.content).toContain('Invalid input for tool "test_tool"');
311
+ expect(result.content).toContain("query is required");
312
+ });
313
+
314
+ test("rejects wrong type with `must be a string` message", async () => {
315
+ const hash = computeSkillVersionHash(tempDir);
316
+ const tool = createSkillTool(
317
+ makeEntry({ executor: "echo.ts" }),
318
+ tempDir,
319
+ hash,
320
+ );
321
+
322
+ const result = await tool.execute({ query: 123 }, makeContext());
323
+
324
+ expect(result.isError).toBe(true);
325
+ expect(result.content).toContain('Invalid input for tool "test_tool"');
326
+ expect(result.content).toContain("query must be a string");
327
+ });
328
+
329
+ test("rejects enum violation with `must be one of` message", async () => {
330
+ const hash = computeSkillVersionHash(tempDir);
331
+ const tool = createSkillTool(
332
+ makeEntry({
333
+ executor: "echo.ts",
334
+ input_schema: {
335
+ type: "object",
336
+ properties: { mode: { type: "string", enum: ["a", "b"] } },
337
+ },
338
+ }),
339
+ tempDir,
340
+ hash,
341
+ );
342
+
343
+ const result = await tool.execute({ mode: "c" }, makeContext());
344
+
345
+ expect(result.isError).toBe(true);
346
+ expect(result.content).toContain('Invalid input for tool "test_tool"');
347
+ expect(result.content).toContain('mode must be one of "a", "b"');
348
+ });
349
+
350
+ test("passes valid input through to the executor unchanged", async () => {
351
+ const hash = computeSkillVersionHash(tempDir);
352
+ const tool = createSkillTool(
353
+ makeEntry({
354
+ executor: "echo.ts",
355
+ input_schema: {
356
+ type: "object",
357
+ properties: { mode: { type: "string", enum: ["a", "b"] } },
358
+ required: ["mode"],
359
+ },
360
+ }),
361
+ tempDir,
362
+ hash,
363
+ );
364
+
365
+ const result = await tool.execute({ mode: "a" }, makeContext());
366
+
367
+ expect(result.isError).toBe(false);
368
+ const parsed = JSON.parse(result.content);
369
+ expect(parsed.input).toEqual({ mode: "a" });
370
+ });
371
+ });
372
+
369
373
  // ---------------------------------------------------------------------------
370
374
  // createSkillTool — expectedSkillVersionHash plumbing
371
375
  // ---------------------------------------------------------------------------
@@ -376,7 +380,6 @@ describe("createSkillTool — version hash plumbing to runner", () => {
376
380
  const hash = computeSkillVersionHash(tempDir);
377
381
  const tool = createSkillTool(
378
382
  makeEntry({ executor: "echo.ts" }),
379
- "my-skill",
380
383
  tempDir,
381
384
  hash,
382
385
  );
@@ -389,7 +392,5 @@ describe("createSkillTool — version hash plumbing to runner", () => {
389
392
  const parsed = JSON.parse(result.content);
390
393
  expect(parsed.input).toEqual({ query: "test" });
391
394
  expect(parsed.workingDir).toBe("/my/project");
392
- // Confirm the tool still has the hash stored
393
- expect(tool.ownerSkillVersionHash).toBe(hash);
394
395
  });
395
396
  });
@@ -154,7 +154,6 @@ import {
154
154
  setSlackChannelConfig,
155
155
  } from "../daemon/handlers/config-slack-channel.js";
156
156
  import { credentialKey } from "../security/credential-key.js";
157
- import { _setStorePath } from "../security/encrypted-store.js";
158
157
  import * as secureKeys from "../security/secure-keys.js";
159
158
  import {
160
159
  _resetBackend,
@@ -167,11 +166,12 @@ import {
167
166
  listCredentialMetadata,
168
167
  upsertCredentialMetadata,
169
168
  } from "../tools/credentials/metadata-store.js";
169
+ import { setStorePathForTesting } from "./encrypted-store-test-helpers.js";
170
170
 
171
171
  afterAll(() => {
172
172
  globalThis.fetch = originalFetch;
173
173
  _setMetadataPath(null);
174
- _setStorePath(null);
174
+ setStorePathForTesting(null);
175
175
  _resetBackend();
176
176
  if (originalVellumDev === undefined) {
177
177
  delete process.env.VELLUM_DEV;
@@ -187,7 +187,7 @@ describe("Slack channel config handler", () => {
187
187
  globalThis.fetch = originalFetch;
188
188
  rmSync(secureStorePath, { force: true });
189
189
  rmSync(metadataPath, { force: true });
190
- _setStorePath(secureStorePath);
190
+ setStorePathForTesting(secureStorePath);
191
191
  _resetBackend();
192
192
  _setMetadataPath(metadataPath);
193
193
  });
@@ -87,7 +87,7 @@ class FakeConversation {
87
87
  return Promise.resolve();
88
88
  }
89
89
  persistUserMessage() {
90
- return "msg-id";
90
+ return { id: "msg-id", deduplicated: false };
91
91
  }
92
92
  runAgentLoop() {
93
93
  return Promise.resolve();
@@ -134,9 +134,17 @@ mock.module("../providers/registry.js", () => ({
134
134
  mock.module("../providers/inference/connections.js", () => ({
135
135
  getConnection: (_db: unknown, name: string) => {
136
136
  if (name === "anthropic-conn")
137
- return { name: "anthropic-conn", provider: "anthropic", auth: { type: "platform" } };
137
+ return {
138
+ name: "anthropic-conn",
139
+ provider: "anthropic",
140
+ auth: { type: "platform" },
141
+ };
138
142
  if (name === "openai-conn")
139
- return { name: "openai-conn", provider: "openai", auth: { type: "platform" } };
143
+ return {
144
+ name: "openai-conn",
145
+ provider: "openai",
146
+ auth: { type: "platform" },
147
+ };
140
148
  return null;
141
149
  },
142
150
  }));
@@ -14,7 +14,7 @@ interface FakeManagedSubagent {
14
14
  content: Array<{ type: string; text: string }>;
15
15
  }>;
16
16
  sendToClient: (msg: ServerMessage) => void;
17
- persistUserMessage?: (msg: string) => string;
17
+ persistUserMessage?: () => { id: string; deduplicated: boolean };
18
18
  runAgentLoop?: () => Promise<void>;
19
19
  enqueueMessage?: () => { rejected: boolean; queued: boolean };
20
20
  usageStats: {
@@ -64,7 +64,8 @@ function injectFakeSubagent(
64
64
  const internals = asInternals(manager);
65
65
 
66
66
  internals.subagents.set(subagentId, {
67
- conversation: conversation === undefined ? makeFakeConversation() : conversation,
67
+ conversation:
68
+ conversation === undefined ? makeFakeConversation() : conversation,
68
69
  state,
69
70
  parentSendToClient: parentSendToClient ?? (() => {}),
70
71
  });
@@ -104,7 +105,10 @@ describe("SubagentManager terminal disposal", () => {
104
105
  injectFakeSubagent(manager, subagentId, state);
105
106
 
106
107
  const managed = asInternals(manager).subagents.get(subagentId)!;
107
- managed.conversation!.persistUserMessage = () => "msg-1";
108
+ managed.conversation!.persistUserMessage = () => ({
109
+ id: "msg-1",
110
+ deduplicated: false,
111
+ });
108
112
  managed.conversation!.runAgentLoop = async () => {};
109
113
 
110
114
  await asInternals(manager).runSubagent(subagentId, "Do something");
@@ -127,7 +131,10 @@ describe("SubagentManager terminal disposal", () => {
127
131
  injectFakeSubagent(manager, subagentId, state);
128
132
 
129
133
  const managed = asInternals(manager).subagents.get(subagentId)!;
130
- managed.conversation!.persistUserMessage = () => "msg-1";
134
+ managed.conversation!.persistUserMessage = () => ({
135
+ id: "msg-1",
136
+ deduplicated: false,
137
+ });
131
138
  managed.conversation!.runAgentLoop = async () => {
132
139
  throw new Error("LLM error");
133
140
  };
@@ -148,7 +155,10 @@ describe("SubagentManager terminal disposal", () => {
148
155
  injectFakeSubagent(manager, subagentId, state);
149
156
 
150
157
  const managed = asInternals(manager).subagents.get(subagentId)!;
151
- managed.conversation!.persistUserMessage = () => "msg-1";
158
+ managed.conversation!.persistUserMessage = () => ({
159
+ id: "msg-1",
160
+ deduplicated: false,
161
+ });
152
162
  managed.conversation!.runAgentLoop = async () => {
153
163
  throw new Error("Conversation aborted");
154
164
  };
@@ -167,7 +177,10 @@ describe("SubagentManager terminal disposal", () => {
167
177
  injectFakeSubagent(manager, subagentId, state);
168
178
 
169
179
  const managed = asInternals(manager).subagents.get(subagentId)!;
170
- managed.conversation!.persistUserMessage = () => "msg-1";
180
+ managed.conversation!.persistUserMessage = () => ({
181
+ id: "msg-1",
182
+ deduplicated: false,
183
+ });
171
184
  managed.conversation!.runAgentLoop = async () => {};
172
185
 
173
186
  await asInternals(manager).runSubagent(subagentId, "Do something");
@@ -269,7 +282,10 @@ describe("SubagentManager terminal disposal", () => {
269
282
  outputTokens: 200,
270
283
  estimatedCost: 0.05,
271
284
  };
272
- managed.conversation!.persistUserMessage = () => "msg-1";
285
+ managed.conversation!.persistUserMessage = () => ({
286
+ id: "msg-1",
287
+ deduplicated: false,
288
+ });
273
289
  managed.conversation!.runAgentLoop = async () => {};
274
290
 
275
291
  await asInternals(manager).runSubagent(subagentId, "Do something");
@@ -291,7 +307,10 @@ describe("SubagentManager terminal disposal", () => {
291
307
  injectFakeSubagent(manager, subagentId, state);
292
308
 
293
309
  const managed = asInternals(manager).subagents.get(subagentId)!;
294
- managed.conversation!.persistUserMessage = () => "msg-1";
310
+ managed.conversation!.persistUserMessage = () => ({
311
+ id: "msg-1",
312
+ deduplicated: false,
313
+ });
295
314
  managed.conversation!.runAgentLoop = async () => {};
296
315
  // Simulate that a message was enqueued during the run.
297
316
  managed.hadEnqueuedMessages = true;
@@ -13,14 +13,14 @@ const capturedNotifications: {
13
13
 
14
14
  mock.module("../daemon/conversation-store.js", () => ({
15
15
  findConversation: (id: string) => ({
16
- enqueueMessage: (content: string) => {
16
+ enqueueMessage: (options: { content: string }) => {
17
17
  capturedNotifications.push({
18
18
  parentConversationId: id,
19
- message: content,
19
+ message: options.content,
20
20
  });
21
21
  return { queued: true };
22
22
  },
23
- persistUserMessage: async () => "mock-msg",
23
+ persistUserMessage: async () => ({ id: "mock-msg", deduplicated: false }),
24
24
  runAgentLoop: async () => {},
25
25
  }),
26
26
  addConversation: () => {},
@@ -46,7 +46,7 @@ interface FakeManagedSubagent {
46
46
  }>;
47
47
  sendToClient: (msg: ServerMessage) => void;
48
48
  loadFromDb?: () => Promise<void>;
49
- persistUserMessage?: (msg: string) => string;
49
+ persistUserMessage?: () => { id: string; deduplicated: boolean };
50
50
  runAgentLoop?: () => Promise<void>;
51
51
  usageStats: {
52
52
  inputTokens: number;
@@ -152,7 +152,10 @@ describe("Fork completion notifications", () => {
152
152
  injectFakeSubagent(manager, subagentId, state);
153
153
 
154
154
  const managed = asInternals(manager).subagents.get(subagentId)!;
155
- managed.conversation!.persistUserMessage = () => "msg-1";
155
+ managed.conversation!.persistUserMessage = () => ({
156
+ id: "msg-1",
157
+ deduplicated: false,
158
+ });
156
159
  managed.conversation!.runAgentLoop = async () => {};
157
160
 
158
161
  await asInternals(manager).runSubagent(subagentId, "Analyze data");
@@ -171,7 +174,10 @@ describe("Fork completion notifications", () => {
171
174
  injectFakeSubagent(manager, subagentId, state);
172
175
 
173
176
  const managed = asInternals(manager).subagents.get(subagentId)!;
174
- managed.conversation!.persistUserMessage = () => "msg-1";
177
+ managed.conversation!.persistUserMessage = () => ({
178
+ id: "msg-1",
179
+ deduplicated: false,
180
+ });
175
181
  managed.conversation!.runAgentLoop = async () => {};
176
182
 
177
183
  await asInternals(manager).runSubagent(subagentId, "Analyze data");
@@ -195,7 +201,10 @@ describe("Fork completion notifications", () => {
195
201
  injectFakeSubagent(manager, subagentId, state);
196
202
 
197
203
  const managed = asInternals(manager).subagents.get(subagentId)!;
198
- managed.conversation!.persistUserMessage = () => "msg-1";
204
+ managed.conversation!.persistUserMessage = () => ({
205
+ id: "msg-1",
206
+ deduplicated: false,
207
+ });
199
208
  managed.conversation!.runAgentLoop = async () => {
200
209
  throw new Error("Context too large");
201
210
  };
@@ -260,7 +269,10 @@ describe("Regular sub-agent notifications are unchanged", () => {
260
269
  injectFakeSubagent(manager, subagentId, state);
261
270
 
262
271
  const managed = asInternals(manager).subagents.get(subagentId)!;
263
- managed.conversation!.persistUserMessage = () => "msg-1";
272
+ managed.conversation!.persistUserMessage = () => ({
273
+ id: "msg-1",
274
+ deduplicated: false,
275
+ });
264
276
  managed.conversation!.runAgentLoop = async () => {};
265
277
 
266
278
  await asInternals(manager).runSubagent(subagentId, "Do something");
@@ -283,7 +295,10 @@ describe("Regular sub-agent notifications are unchanged", () => {
283
295
  injectFakeSubagent(manager, subagentId, state);
284
296
 
285
297
  const managed = asInternals(manager).subagents.get(subagentId)!;
286
- managed.conversation!.persistUserMessage = () => "msg-1";
298
+ managed.conversation!.persistUserMessage = () => ({
299
+ id: "msg-1",
300
+ deduplicated: false,
301
+ });
287
302
  managed.conversation!.runAgentLoop = async () => {
288
303
  throw new Error("Something went wrong");
289
304
  };
@@ -17,7 +17,7 @@ interface FakeManagedSubagent {
17
17
  dispose: () => void;
18
18
  messages: Message[];
19
19
  sendToClient: (msg: ServerMessage) => void;
20
- persistUserMessage?: (msg: string) => string;
20
+ persistUserMessage?: () => { id: string; deduplicated: boolean };
21
21
  runAgentLoop?: () => Promise<void>;
22
22
  enqueueMessage?: () => { rejected: boolean; queued: boolean };
23
23
  injectInheritedContext?: (messages: Message[]) => void;
@@ -127,7 +127,10 @@ describe("SubagentManager fork spawn", () => {
127
127
 
128
128
  const injectedMessages: Message[][] = [];
129
129
  const fakeConversation = makeFakeConversation();
130
- fakeConversation.persistUserMessage = () => "msg-1";
130
+ fakeConversation.persistUserMessage = () => ({
131
+ id: "msg-1",
132
+ deduplicated: false,
133
+ });
131
134
  fakeConversation.runAgentLoop = async () => {};
132
135
  fakeConversation.injectInheritedContext = (msgs: Message[]) => {
133
136
  injectedMessages.push(msgs);
@@ -197,7 +200,10 @@ describe("SubagentManager fork spawn", () => {
197
200
 
198
201
  let injectCalled = false;
199
202
  const fakeConversation = makeFakeConversation();
200
- fakeConversation.persistUserMessage = () => "msg-1";
203
+ fakeConversation.persistUserMessage = () => ({
204
+ id: "msg-1",
205
+ deduplicated: false,
206
+ });
201
207
  fakeConversation.runAgentLoop = async () => {};
202
208
  fakeConversation.injectInheritedContext = () => {
203
209
  injectCalled = true;
@@ -272,7 +278,10 @@ describe("SubagentManager fork spawn", () => {
272
278
  const subagentId = "sub-fork-role";
273
279
 
274
280
  const fakeConversation = makeFakeConversation();
275
- fakeConversation.persistUserMessage = () => "msg-1";
281
+ fakeConversation.persistUserMessage = () => ({
282
+ id: "msg-1",
283
+ deduplicated: false,
284
+ });
276
285
  fakeConversation.runAgentLoop = async () => {};
277
286
  fakeConversation.injectInheritedContext = () => {};
278
287
  fakeConversation.setSubagentAllowedTools = () => {};