@vellumai/assistant 0.7.1 → 0.7.3

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 (739) hide show
  1. package/ARCHITECTURE.md +48 -50
  2. package/Dockerfile +1 -0
  3. package/README.md +1 -2
  4. package/__tests__/permissions/gateway-threshold-reader.test.ts +9 -3
  5. package/bun.lock +26 -26
  6. package/docs/architecture/memory.md +5 -2
  7. package/docs/architecture/security.md +20 -0
  8. package/docs/plugins.md +7 -9
  9. package/knip.json +1 -0
  10. package/node_modules/@vellumai/gateway-client/src/index.ts +1 -0
  11. package/node_modules/@vellumai/gateway-client/src/ipc-client.ts +52 -5
  12. package/node_modules/@vellumai/gateway-client/src/types.ts +11 -0
  13. package/node_modules/@vellumai/service-contracts/package.json +2 -0
  14. package/node_modules/@vellumai/service-contracts/src/__tests__/contracts.test.ts +4 -0
  15. package/node_modules/@vellumai/service-contracts/src/__tests__/ingress.test.ts +107 -0
  16. package/node_modules/@vellumai/service-contracts/src/index.ts +5 -1
  17. package/node_modules/@vellumai/service-contracts/src/ingress.ts +24 -0
  18. package/node_modules/@vellumai/service-contracts/src/twilio-ingress.ts +84 -0
  19. package/node_modules/@vellumai/slack-text/src/index.test.ts +18 -35
  20. package/node_modules/@vellumai/slack-text/src/index.ts +2 -48
  21. package/node_modules/@vellumai/twilio-client/bun.lock +24 -0
  22. package/node_modules/@vellumai/twilio-client/package.json +18 -0
  23. package/node_modules/@vellumai/twilio-client/src/__tests__/twilio-client.test.ts +128 -0
  24. package/node_modules/@vellumai/twilio-client/src/index.ts +179 -0
  25. package/node_modules/@vellumai/twilio-client/tsconfig.json +20 -0
  26. package/openapi.yaml +1020 -40
  27. package/package.json +6 -3
  28. package/src/__tests__/app-builder-tool-scripts.test.ts +3 -3
  29. package/src/__tests__/app-bundler.test.ts +170 -1
  30. package/src/__tests__/app-control-flow.test.ts +384 -0
  31. package/src/__tests__/app-control-no-global-cgevent.test.ts +98 -0
  32. package/src/__tests__/app-control-tool-schemas.test.ts +621 -0
  33. package/src/__tests__/app-executors.test.ts +30 -43
  34. package/src/__tests__/approval-routes-http.test.ts +23 -6
  35. package/src/__tests__/assistant-event-hub-machine-name.test.ts +146 -0
  36. package/src/__tests__/assistant-event-hub-targeted.test.ts +257 -0
  37. package/src/__tests__/assistant-event-hub.test.ts +157 -2
  38. package/src/__tests__/assistant-feature-flags-integration.test.ts +29 -7
  39. package/src/__tests__/auto-analysis-end-to-end.test.ts +62 -1
  40. package/src/__tests__/background-shell-host-bash.test.ts +14 -15
  41. package/src/__tests__/background-workers-disk-pressure.test.ts +268 -0
  42. package/src/__tests__/bootstrap-turn-cleanup.test.ts +44 -0
  43. package/src/__tests__/btw-routes.test.ts +13 -4
  44. package/src/__tests__/call-controller.test.ts +49 -1
  45. package/src/__tests__/call-conversation-messages.test.ts +8 -2
  46. package/src/__tests__/call-domain.test.ts +0 -2
  47. package/src/__tests__/call-routes-http.test.ts +0 -2
  48. package/src/__tests__/channel-inbound-disk-pressure.test.ts +537 -0
  49. package/src/__tests__/channel-readiness-service.test.ts +62 -2
  50. package/src/__tests__/checker.test.ts +3 -4
  51. package/src/__tests__/config-loader-backfill.test.ts +461 -147
  52. package/src/__tests__/config-loader-platform-defaults.test.ts +196 -0
  53. package/src/__tests__/config-schema-cmd.test.ts +0 -1
  54. package/src/__tests__/config-schema.test.ts +1 -0
  55. package/src/__tests__/config-set-platform-guard.test.ts +48 -4
  56. package/src/__tests__/config-watcher-cleanup-throttle.test.ts +20 -11
  57. package/src/__tests__/config-watcher.test.ts +142 -71
  58. package/src/__tests__/context-search-agent-runner.test.ts +61 -3
  59. package/src/__tests__/context-search-conversations-source.test.ts +0 -24
  60. package/src/__tests__/context-search-fanout.test.ts +0 -1
  61. package/src/__tests__/context-search-memory-source.test.ts +3 -7
  62. package/src/__tests__/context-search-memory-v2-source.test.ts +0 -2
  63. package/src/__tests__/context-search-pkb-source.test.ts +0 -1
  64. package/src/__tests__/context-search-workspace-source.test.ts +0 -1
  65. package/src/__tests__/conversation-abort-tool-results.test.ts +6 -0
  66. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +223 -0
  67. package/src/__tests__/conversation-agent-loop.test.ts +454 -5
  68. package/src/__tests__/conversation-app-control-instantiation.test.ts +392 -0
  69. package/src/__tests__/conversation-app-control-lifecycle.test.ts +237 -0
  70. package/src/__tests__/conversation-error.test.ts +150 -3
  71. package/src/__tests__/conversation-init.benchmark.test.ts +0 -2
  72. package/src/__tests__/conversation-lifecycle.test.ts +36 -0
  73. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +283 -0
  74. package/src/__tests__/conversation-process-callsite.test.ts +43 -0
  75. package/src/__tests__/conversation-provider-retry-repair.test.ts +6 -0
  76. package/src/__tests__/conversation-routes-disk-view.test.ts +6 -0
  77. package/src/__tests__/conversation-routes-guardian-reply.test.ts +120 -72
  78. package/src/__tests__/conversation-routes-slash-commands.test.ts +1 -0
  79. package/src/__tests__/conversation-runtime-assembly.test.ts +65 -0
  80. package/src/__tests__/conversation-slash-commands.test.ts +0 -4
  81. package/src/__tests__/conversation-slash-unknown.test.ts +6 -0
  82. package/src/__tests__/conversation-speed-override.test.ts +0 -3
  83. package/src/__tests__/conversation-store.test.ts +0 -18
  84. package/src/__tests__/conversation-surfaces-action-delivery.test.ts +202 -0
  85. package/src/__tests__/conversation-surfaces-app-control.test.ts +328 -0
  86. package/src/__tests__/conversation-surfaces-data-persist.test.ts +404 -0
  87. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +2 -5
  88. package/src/__tests__/conversation-workspace-injection.test.ts +6 -0
  89. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +6 -0
  90. package/src/__tests__/credential-execution-feature-gates.test.ts +5 -12
  91. package/src/__tests__/credential-execution-managed-contract.test.ts +3 -131
  92. package/src/__tests__/credentials-cli.test.ts +12 -12
  93. package/src/__tests__/cu-unified-flow.test.ts +351 -23
  94. package/src/__tests__/daemon-credential-client.test.ts +101 -19
  95. package/src/__tests__/date-context.test.ts +164 -2
  96. package/src/__tests__/db-schedule-syntax-migration.test.ts +2 -0
  97. package/src/__tests__/disk-pressure-guard.test.ts +262 -0
  98. package/src/__tests__/disk-pressure-lifecycle.test.ts +168 -0
  99. package/src/__tests__/disk-pressure-policy.test.ts +241 -0
  100. package/src/__tests__/disk-pressure-routes.test.ts +379 -0
  101. package/src/__tests__/disk-pressure-tools.test.ts +277 -0
  102. package/src/__tests__/disk-usage.test.ts +150 -0
  103. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +0 -1
  104. package/src/__tests__/events-client-registration.test.ts +52 -0
  105. package/src/__tests__/events-dev-bypass-actor.test.ts +162 -0
  106. package/src/__tests__/file-write-tool.test.ts +4 -10
  107. package/src/__tests__/filing-service.test.ts +3 -4
  108. package/src/__tests__/gateway-only-enforcement.test.ts +0 -1
  109. package/src/__tests__/guardian-verification-voice-binding.test.ts +0 -2
  110. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +0 -2
  111. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +0 -1
  112. package/src/__tests__/heartbeat-disk-pressure.test.ts +183 -0
  113. package/src/__tests__/heartbeat-service.test.ts +968 -2
  114. package/src/__tests__/helpers/call-route-handler.ts +7 -1
  115. package/src/__tests__/host-app-control-proxy.test.ts +772 -0
  116. package/src/__tests__/host-app-control-routes.test.ts +263 -0
  117. package/src/__tests__/host-bash-proxy.test.ts +439 -47
  118. package/src/__tests__/host-bash-routes.test.ts +459 -0
  119. package/src/__tests__/host-browser-proxy.test.ts +24 -22
  120. package/src/__tests__/host-browser-routes.test.ts +39 -13
  121. package/src/__tests__/host-cu-proxy.test.ts +248 -52
  122. package/src/__tests__/host-cu-routes-targeted.test.ts +429 -0
  123. package/src/__tests__/host-file-edit-tool.test.ts +47 -1
  124. package/src/__tests__/host-file-proxy-targeted.test.ts +378 -0
  125. package/src/__tests__/host-file-proxy.test.ts +301 -45
  126. package/src/__tests__/host-file-read-tool.test.ts +17 -0
  127. package/src/__tests__/host-file-routes-targeted.test.ts +420 -0
  128. package/src/__tests__/host-file-write-tool.test.ts +42 -1
  129. package/src/__tests__/host-proxy-base.test.ts +312 -0
  130. package/src/__tests__/host-shell-tool.test.ts +22 -4
  131. package/src/__tests__/host-transfer-proxy-targeted.test.ts +932 -0
  132. package/src/__tests__/host-transfer-proxy.test.ts +121 -22
  133. package/src/__tests__/host-transfer-routes-targeted.test.ts +662 -0
  134. package/src/__tests__/http-user-message-parity.test.ts +108 -1
  135. package/src/__tests__/identity-intro-cache.test.ts +29 -0
  136. package/src/__tests__/identity-routes.test.ts +103 -1
  137. package/src/__tests__/init-feature-flag-overrides.test.ts +26 -3
  138. package/src/__tests__/injector-chain.test.ts +18 -6
  139. package/src/__tests__/injector-disk-pressure.test.ts +224 -0
  140. package/src/__tests__/inline-command-runner.test.ts +0 -1
  141. package/src/__tests__/inline-skill-load-permissions.test.ts +5 -11
  142. package/src/__tests__/integration-status.test.ts +85 -5
  143. package/src/__tests__/intent-routing.test.ts +0 -1
  144. package/src/__tests__/jobs-store-qdrant-breaker.test.ts +95 -5
  145. package/src/__tests__/lifecycle-memory-v2-seed.test.ts +17 -0
  146. package/src/__tests__/managed-profile-guard.test.ts +18 -0
  147. package/src/__tests__/managed-skill-lifecycle.test.ts +0 -1
  148. package/src/__tests__/mcp-abort-signal.test.ts +130 -0
  149. package/src/__tests__/mcp-auth-routes.test.ts +197 -0
  150. package/src/__tests__/mcp-cli.test.ts +338 -2
  151. package/src/__tests__/memory-admin-recall.test.ts +3 -11
  152. package/src/__tests__/memory-jobs-worker-lanes.test.ts +188 -0
  153. package/src/__tests__/memory-retrieval-pipeline.test.ts +22 -1
  154. package/src/__tests__/migration-import-commit-http.test.ts +108 -2
  155. package/src/__tests__/mock-gateway-ipc.ts +1 -0
  156. package/src/__tests__/normalize-onboarding.test.ts +180 -0
  157. package/src/__tests__/oauth-cli.test.ts +0 -2
  158. package/src/__tests__/oauth-connect-routes.test.ts +316 -0
  159. package/src/__tests__/oauth-provider-seed-logos.test.ts +24 -2
  160. package/src/__tests__/oauth2-gateway-transport.test.ts +0 -1
  161. package/src/__tests__/onboarding-persona-write.test.ts +308 -0
  162. package/src/__tests__/openai-provider.test.ts +45 -8
  163. package/src/__tests__/persist-onboarding-artifacts.test.ts +44 -64
  164. package/src/__tests__/persistence-secret-redaction.test.ts +299 -0
  165. package/src/__tests__/platform-bash-auto-approve.test.ts +5 -9
  166. package/src/__tests__/platform-callback-registration.test.ts +21 -4
  167. package/src/__tests__/platform.test.ts +2 -1
  168. package/src/__tests__/playbook-execution.test.ts +0 -43
  169. package/src/__tests__/plugin-tool-contribution.test.ts +47 -0
  170. package/src/__tests__/prechat-onboarding-contract.test.ts +214 -25
  171. package/src/__tests__/process-message-background-slack.test.ts +2 -0
  172. package/src/__tests__/provider-commit-message-generator.test.ts +0 -1
  173. package/src/__tests__/provider-tool-name.test.ts +23 -0
  174. package/src/__tests__/public-ingress-urls.test.ts +97 -0
  175. package/src/__tests__/relay-server.test.ts +15 -4
  176. package/src/__tests__/require-fresh-approval.test.ts +0 -1
  177. package/src/__tests__/retry-backoff.test.ts +87 -0
  178. package/src/__tests__/runtime-events-sse.test.ts +2 -2
  179. package/src/__tests__/sanitize-config-for-transfer.test.ts +24 -2
  180. package/src/__tests__/schedule-retry.test.ts +715 -0
  181. package/src/__tests__/scheduler-disk-pressure.test.ts +148 -0
  182. package/src/__tests__/script-proxy-mitm-handler.test.ts +1 -1
  183. package/src/__tests__/secret-ingress-http.test.ts +1 -1
  184. package/src/__tests__/send-endpoint-busy.test.ts +3 -0
  185. package/src/__tests__/shell-tool-proxy-mode.test.ts +0 -1
  186. package/src/__tests__/skill-feature-flags.test.ts +43 -41
  187. package/src/__tests__/skill-load-feature-flag.test.ts +13 -14
  188. package/src/__tests__/skill-load-inline-command.test.ts +0 -51
  189. package/src/__tests__/skill-load-inline-includes.test.ts +0 -43
  190. package/src/__tests__/skill-projection.benchmark.test.ts +0 -1
  191. package/src/__tests__/skill-script-runner-sandbox.test.ts +0 -1
  192. package/src/__tests__/slack-channel-config.test.ts +9 -14
  193. package/src/__tests__/suggestion-routes.test.ts +46 -0
  194. package/src/__tests__/system-prompt-ask-mode.test.ts +0 -1
  195. package/src/__tests__/system-prompt.test.ts +0 -1
  196. package/src/__tests__/telegram-config.test.ts +0 -1
  197. package/src/__tests__/test-preload.ts +8 -0
  198. package/src/__tests__/tool-approval-handler.test.ts +3 -4
  199. package/src/__tests__/tool-audit-listener.test.ts +48 -0
  200. package/src/__tests__/tool-execute-pipeline.test.ts +0 -1
  201. package/src/__tests__/tool-execution-abort-cleanup.test.ts +0 -1
  202. package/src/__tests__/tool-executor-lifecycle-events.test.ts +0 -1
  203. package/src/__tests__/tool-executor.test.ts +0 -1
  204. package/src/__tests__/twilio-config.test.ts +3 -16
  205. package/src/__tests__/twilio-routes.test.ts +3 -5
  206. package/src/__tests__/twilio-validation.test.ts +93 -0
  207. package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +1 -4
  208. package/src/__tests__/verification-control-plane-policy.test.ts +2 -4
  209. package/src/__tests__/voice-ingress-preflight.test.ts +19 -0
  210. package/src/__tests__/workspace-migration-006-services-config.test.ts +3 -2
  211. package/src/__tests__/workspace-migration-065-bump-stale-heartbeat-interval.test.ts +122 -0
  212. package/src/__tests__/workspace-migration-066-seed-heartbeat-callsite-cost-default.test.ts +285 -0
  213. package/src/__tests__/workspace-migration-068-release-notes-local-timezone.test.ts +90 -0
  214. package/src/__tests__/workspace-migration-backfill-installation-id.test.ts +1 -5
  215. package/src/__tests__/workspace-migration-down-functions.test.ts +8 -8
  216. package/src/__tests__/workspace-migration-safe-storage-limits-release.test.ts +90 -0
  217. package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +10 -6
  218. package/src/approvals/guardian-decision-primitive.ts +13 -0
  219. package/src/approvals/guardian-request-resolvers.ts +16 -17
  220. package/src/backup/__tests__/paths.test.ts +0 -22
  221. package/src/backup/__tests__/restore.test.ts +51 -151
  222. package/src/backup/paths.ts +2 -18
  223. package/src/backup/restore.ts +107 -231
  224. package/src/backup/snapshot-lock.ts +2 -27
  225. package/src/bundler/app-bundler.ts +51 -3
  226. package/src/bundler/compiler-tools.ts +3 -2
  227. package/src/calls/call-conversation-messages.ts +46 -10
  228. package/src/calls/relay-server.ts +4 -44
  229. package/src/calls/twilio-config.ts +2 -17
  230. package/src/calls/twilio-rest.ts +33 -105
  231. package/src/calls/twilio-routes.ts +11 -12
  232. package/src/channels/types.ts +8 -7
  233. package/src/cli/commands/__tests__/backup.test.ts +6 -277
  234. package/src/cli/commands/__tests__/gateway.test.ts +288 -0
  235. package/src/cli/commands/__tests__/memory-v2.test.ts +4 -0
  236. package/src/cli/commands/__tests__/webhooks.test.ts +0 -5
  237. package/src/cli/commands/backup.ts +6 -331
  238. package/src/cli/commands/bash.ts +35 -108
  239. package/src/cli/commands/clients.ts +36 -37
  240. package/src/cli/commands/contacts.ts +137 -25
  241. package/src/cli/commands/conversations.ts +2 -5
  242. package/src/cli/commands/credentials.ts +71 -7
  243. package/src/cli/commands/domain.ts +66 -15
  244. package/src/cli/commands/gateway.ts +183 -0
  245. package/src/cli/commands/keys.ts +9 -6
  246. package/src/cli/commands/mcp.ts +116 -156
  247. package/src/cli/commands/memory-v2.ts +303 -7
  248. package/src/cli/commands/oauth/__tests__/connect.test.ts +437 -1
  249. package/src/cli/commands/oauth/connect.ts +127 -1
  250. package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +0 -4
  251. package/src/cli/commands/platform/__tests__/connect.test.ts +7 -3
  252. package/src/cli/commands/platform/__tests__/disconnect.test.ts +7 -3
  253. package/src/cli/commands/platform/__tests__/status.test.ts +116 -21
  254. package/src/cli/commands/platform/disconnect.ts +5 -4
  255. package/src/cli/commands/platform/index.ts +16 -25
  256. package/src/cli/commands/status.ts +57 -0
  257. package/src/cli/lib/daemon-credential-client.ts +110 -28
  258. package/src/cli/program.ts +6 -2
  259. package/src/config/assistant-feature-flags.ts +79 -12
  260. package/src/config/bundled-skills/acp/SKILL.md +6 -0
  261. package/src/config/bundled-skills/acp/TOOLS.json +1 -22
  262. package/src/config/bundled-skills/app-builder/SKILL.md +14 -109
  263. package/src/config/bundled-skills/app-builder/TOOLS.json +1 -28
  264. package/src/config/bundled-skills/app-builder/tools/app-create.ts +1 -10
  265. package/src/config/bundled-skills/app-control/SKILL.md +75 -0
  266. package/src/config/bundled-skills/app-control/TOOLS.json +299 -0
  267. package/src/config/bundled-skills/app-control/tools/app-control-click.ts +12 -0
  268. package/src/config/bundled-skills/app-control/tools/app-control-combo.ts +12 -0
  269. package/src/config/bundled-skills/app-control/tools/app-control-drag.ts +12 -0
  270. package/src/config/bundled-skills/app-control/tools/app-control-observe.ts +12 -0
  271. package/src/config/bundled-skills/app-control/tools/app-control-press.ts +12 -0
  272. package/src/config/bundled-skills/app-control/tools/app-control-sequence.ts +12 -0
  273. package/src/config/bundled-skills/app-control/tools/app-control-start.ts +12 -0
  274. package/src/config/bundled-skills/app-control/tools/app-control-stop.ts +12 -0
  275. package/src/config/bundled-skills/app-control/tools/app-control-type.ts +12 -0
  276. package/src/config/bundled-skills/computer-use/SKILL.md +6 -0
  277. package/src/config/bundled-skills/computer-use/TOOLS.json +67 -43
  278. package/src/config/bundled-skills/contacts/TOOLS.json +0 -16
  279. package/src/config/bundled-skills/document/TOOLS.json +0 -8
  280. package/src/config/bundled-skills/followups/TOOLS.json +0 -12
  281. package/src/config/bundled-skills/image-studio/SKILL.md +4 -0
  282. package/src/config/bundled-skills/image-studio/TOOLS.json +0 -4
  283. package/src/config/bundled-skills/media-processing/TOOLS.json +0 -24
  284. package/src/config/bundled-skills/messaging/TOOLS.json +0 -40
  285. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +4 -3
  286. package/src/config/bundled-skills/phone-calls/TOOLS.json +0 -12
  287. package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +25 -4
  288. package/src/config/bundled-skills/playbooks/TOOLS.json +0 -16
  289. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +2 -2
  290. package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +2 -2
  291. package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +2 -2
  292. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +2 -2
  293. package/src/config/bundled-skills/schedule/TOOLS.json +14 -14
  294. package/src/config/bundled-skills/sequences/TOOLS.json +0 -36
  295. package/src/config/bundled-skills/settings/SKILL.md +4 -0
  296. package/src/config/bundled-skills/settings/TOOLS.json +0 -12
  297. package/src/config/bundled-skills/skill-management/SKILL.md +6 -0
  298. package/src/config/bundled-skills/skill-management/TOOLS.json +0 -8
  299. package/src/config/bundled-skills/subagent/SKILL.md +6 -2
  300. package/src/config/bundled-skills/subagent/TOOLS.json +0 -20
  301. package/src/config/bundled-skills/transcribe/SKILL.md +4 -0
  302. package/src/config/bundled-skills/transcribe/TOOLS.json +0 -4
  303. package/src/config/bundled-tool-registry.ts +21 -0
  304. package/src/config/env-registry.ts +0 -2
  305. package/src/config/env.ts +19 -20
  306. package/src/config/feature-flag-registry.json +47 -135
  307. package/src/config/loader.ts +197 -104
  308. package/src/config/sanitize-for-transfer.ts +2 -0
  309. package/src/config/schemas/__tests__/memory-lifecycle.test.ts +80 -0
  310. package/src/config/schemas/__tests__/memory-v2.test.ts +17 -9
  311. package/src/config/schemas/call-site-catalog.ts +14 -0
  312. package/src/config/schemas/calls.ts +0 -9
  313. package/src/config/schemas/channels.ts +0 -5
  314. package/src/config/schemas/heartbeat.ts +64 -1
  315. package/src/config/schemas/ingress.ts +10 -6
  316. package/src/config/schemas/llm.ts +7 -10
  317. package/src/config/schemas/memory-lifecycle.ts +90 -24
  318. package/src/config/schemas/memory-v2.ts +121 -13
  319. package/src/config/schemas/platform.ts +49 -3
  320. package/src/config/schemas/services.ts +29 -15
  321. package/src/config/schemas/skills.ts +0 -6
  322. package/src/config/seed-inference-profiles.ts +230 -33
  323. package/src/contacts/contact-store.ts +0 -55
  324. package/src/contacts/contacts-write.ts +0 -27
  325. package/src/context/window-manager.ts +1 -2
  326. package/src/credential-execution/feature-gates.ts +10 -10
  327. package/src/credential-execution/process-manager.ts +12 -41
  328. package/src/daemon/__tests__/conversation-tool-setup.test.ts +187 -5
  329. package/src/daemon/assistant-attachments.ts +4 -4
  330. package/src/daemon/bootstrap-turn-cleanup.ts +45 -0
  331. package/src/daemon/config-watcher.ts +89 -60
  332. package/src/daemon/conversation-agent-loop-handlers.ts +27 -3
  333. package/src/daemon/conversation-agent-loop.ts +202 -61
  334. package/src/daemon/conversation-error.ts +87 -15
  335. package/src/daemon/conversation-lifecycle.ts +9 -4
  336. package/src/daemon/conversation-process.ts +24 -11
  337. package/src/daemon/conversation-runtime-assembly.ts +28 -2
  338. package/src/daemon/conversation-store.ts +2 -2
  339. package/src/daemon/conversation-surfaces.ts +305 -4
  340. package/src/daemon/conversation-tool-setup.ts +66 -62
  341. package/src/daemon/conversation.ts +38 -24
  342. package/src/daemon/date-context.ts +71 -22
  343. package/src/daemon/disk-pressure-background-gate.ts +73 -0
  344. package/src/daemon/disk-pressure-guard.ts +343 -0
  345. package/src/daemon/disk-pressure-policy.ts +163 -0
  346. package/src/daemon/doordash-steps.ts +1 -1
  347. package/src/daemon/handlers/shared.ts +4 -2
  348. package/src/daemon/handlers/skills.ts +3 -4
  349. package/src/daemon/host-app-control-proxy.ts +389 -0
  350. package/src/daemon/host-bash-proxy.ts +117 -82
  351. package/src/daemon/host-browser-proxy.ts +67 -82
  352. package/src/daemon/host-cu-proxy.ts +127 -86
  353. package/src/daemon/host-file-proxy.ts +129 -69
  354. package/src/daemon/host-proxy-base.ts +294 -0
  355. package/src/daemon/host-proxy-preactivation.ts +82 -0
  356. package/src/daemon/host-transfer-proxy.ts +338 -129
  357. package/src/daemon/lifecycle.ts +194 -145
  358. package/src/daemon/meet-host-supervisor.ts +4 -4
  359. package/src/daemon/meet-manifest-loader.ts +0 -1
  360. package/src/daemon/memory-v2-startup.ts +14 -4
  361. package/src/daemon/message-protocol.ts +6 -8
  362. package/src/daemon/message-types/contacts.ts +23 -1
  363. package/src/daemon/message-types/conversations.ts +15 -8
  364. package/src/daemon/message-types/disk-pressure.ts +9 -0
  365. package/src/daemon/message-types/host-app-control.ts +150 -0
  366. package/src/daemon/message-types/host-bash.ts +4 -0
  367. package/src/daemon/message-types/host-cu.ts +2 -0
  368. package/src/daemon/message-types/host-file.ts +4 -0
  369. package/src/daemon/message-types/host-transfer.ts +3 -0
  370. package/src/daemon/message-types/messages.ts +3 -0
  371. package/src/daemon/message-types/schedules.ts +8 -3
  372. package/src/daemon/message-types/skills.ts +2 -2
  373. package/src/daemon/process-message.ts +18 -1
  374. package/src/daemon/profiler-run-store.ts +5 -5
  375. package/src/daemon/shutdown-handlers.ts +0 -3
  376. package/src/daemon/tool-setup-types.ts +51 -0
  377. package/src/daemon/tool-side-effects.ts +1 -1
  378. package/src/documents/document-store.ts +85 -0
  379. package/src/events/tool-audit-listener.ts +2 -1
  380. package/src/filing/filing-service.ts +30 -5
  381. package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +24 -23
  382. package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +252 -0
  383. package/src/heartbeat/heartbeat-run-store.ts +249 -0
  384. package/src/heartbeat/heartbeat-service.ts +459 -54
  385. package/src/home/__tests__/post-connect-feed.test.ts +99 -0
  386. package/src/home/__tests__/relationship-state-writer.test.ts +11 -9
  387. package/src/home/__tests__/suggested-prompts.test.ts +89 -0
  388. package/src/home/feed-scheduler.ts +18 -0
  389. package/src/home/post-connect-feed.ts +68 -0
  390. package/src/home/relationship-state-writer.ts +17 -92
  391. package/src/home/suggested-prompts.ts +46 -10
  392. package/src/inbound/platform-callback-registration.ts +8 -15
  393. package/src/inbound/public-ingress-urls.ts +32 -34
  394. package/src/ipc/__tests__/clients-list-ipc.test.ts +169 -0
  395. package/src/ipc/__tests__/route-error-envelope.test.ts +80 -0
  396. package/src/ipc/assistant-server.ts +70 -3
  397. package/src/ipc/cli-client.ts +32 -1
  398. package/src/ipc/gateway-client.ts +37 -3
  399. package/src/live-voice/live-voice-archive.ts +4 -4
  400. package/src/live-voice/live-voice-metrics.ts +10 -10
  401. package/src/live-voice/protocol.ts +5 -7
  402. package/src/mcp/__tests__/mcp-auth-orchestrator.test.ts +304 -0
  403. package/src/mcp/mcp-auth-orchestrator.ts +213 -0
  404. package/src/mcp/mcp-auth-state.ts +133 -0
  405. package/src/mcp/mcp-oauth-provider.ts +19 -0
  406. package/src/media/image-service.ts +1 -7
  407. package/src/memory/__tests__/fixtures/memory-v2-activation-fixtures.ts +21 -13
  408. package/src/memory/__tests__/jobs-store-job-classes.test.ts +24 -0
  409. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +52 -22
  410. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +0 -6
  411. package/src/memory/__tests__/memory-v2-concept-frequency.test.ts +272 -0
  412. package/src/memory/__tests__/qdrant-client-sentinel.test.ts +49 -0
  413. package/src/memory/__tests__/sparse-tokenize.test.ts +66 -0
  414. package/src/memory/admin.ts +5 -9
  415. package/src/memory/anisotropy.test.ts +247 -0
  416. package/src/memory/anisotropy.ts +443 -0
  417. package/src/memory/auto-analysis-constants.ts +17 -0
  418. package/src/memory/auto-analysis-guard.ts +5 -15
  419. package/src/memory/canonical-guardian-store.ts +7 -7
  420. package/src/memory/context-search/__tests__/agent-runner-redaction.test.ts +122 -0
  421. package/src/memory/context-search/agent-protocol.ts +6 -6
  422. package/src/memory/context-search/agent-runner.ts +51 -9
  423. package/src/memory/context-search/sources/conversations.ts +2 -11
  424. package/src/memory/context-search/sources/memory-v2.ts +22 -9
  425. package/src/memory/context-search/sources/memory.ts +0 -1
  426. package/src/memory/context-search/types.ts +0 -1
  427. package/src/memory/conversation-crud.ts +5 -13
  428. package/src/memory/conversation-key-store.ts +2 -15
  429. package/src/memory/db-init.ts +6 -0
  430. package/src/memory/embedding-backend.ts +9 -21
  431. package/src/memory/embedding-runtime-manager.ts +119 -5
  432. package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +81 -25
  433. package/src/memory/graph/conversation-graph-memory.ts +43 -78
  434. package/src/memory/graph/extraction.ts +1 -3
  435. package/src/memory/graph/graph-search.test.ts +10 -67
  436. package/src/memory/graph/graph-search.ts +9 -20
  437. package/src/memory/graph/retriever.test.ts +6 -0
  438. package/src/memory/graph/retriever.ts +34 -10
  439. package/src/memory/graph/tools.ts +1 -1
  440. package/src/memory/indexer.ts +54 -45
  441. package/src/memory/job-handlers/backfill.ts +2 -11
  442. package/src/memory/job-handlers/cleanup.ts +43 -0
  443. package/src/memory/job-handlers/embedding.ts +6 -8
  444. package/src/memory/job-handlers/summarization.ts +2 -7
  445. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +8 -2
  446. package/src/memory/jobs/embed-concept-page.ts +28 -2
  447. package/src/memory/jobs/embed-pkb-file.test.ts +2 -2
  448. package/src/memory/jobs-store.ts +114 -22
  449. package/src/memory/jobs-worker.ts +193 -106
  450. package/src/memory/memory-v2-activation-log-store.ts +33 -15
  451. package/src/memory/memory-v2-concept-frequency.ts +169 -0
  452. package/src/memory/migrations/237-heartbeat-runs.ts +45 -0
  453. package/src/memory/migrations/238-schedule-retry-policy.ts +20 -0
  454. package/src/memory/migrations/239-trace-events-created-at-index.ts +18 -0
  455. package/src/memory/migrations/index.ts +6 -0
  456. package/src/memory/migrations/registry.ts +8 -0
  457. package/src/memory/pkb/pkb-search.test.ts +6 -0
  458. package/src/memory/pkb/pkb-search.ts +7 -0
  459. package/src/memory/qdrant-client.ts +49 -32
  460. package/src/memory/rerank-local.ts +374 -0
  461. package/src/memory/schema/infrastructure.ts +15 -0
  462. package/src/memory/search/semantic.ts +13 -67
  463. package/src/memory/sparse-tokenize.ts +49 -0
  464. package/src/memory/trace-event-store.ts +1 -17
  465. package/src/memory/v2/__tests__/activation.test.ts +387 -344
  466. package/src/memory/v2/__tests__/consolidation-job.test.ts +40 -8
  467. package/src/memory/v2/__tests__/injection.test.ts +181 -169
  468. package/src/memory/v2/__tests__/prompts-consolidation.test.ts +61 -2
  469. package/src/memory/v2/__tests__/qdrant.test.ts +16 -0
  470. package/src/memory/v2/__tests__/reranker.test.ts +338 -0
  471. package/src/memory/v2/__tests__/sim.test.ts +154 -188
  472. package/src/memory/v2/__tests__/skill-store.test.ts +71 -65
  473. package/src/memory/v2/__tests__/sparse-bm25.test.ts +292 -0
  474. package/src/memory/v2/__tests__/static-context.test.ts +76 -2
  475. package/src/memory/v2/activation.ts +213 -239
  476. package/src/memory/v2/consolidation-job.ts +65 -17
  477. package/src/memory/v2/constants.ts +7 -0
  478. package/src/memory/v2/injection.ts +123 -103
  479. package/src/memory/v2/prompts/consolidation.ts +348 -92
  480. package/src/memory/v2/qdrant.ts +198 -1
  481. package/src/memory/v2/reranker.ts +177 -0
  482. package/src/memory/v2/sim.ts +113 -77
  483. package/src/memory/v2/skill-content.ts +4 -3
  484. package/src/memory/v2/skill-store.ts +91 -53
  485. package/src/memory/v2/sparse-bm25.ts +245 -0
  486. package/src/memory/v2/static-context.ts +28 -5
  487. package/src/memory/v2/types.ts +10 -10
  488. package/src/messaging/providers/gmail/types.ts +0 -49
  489. package/src/messaging/providers/slack/adapter.ts +1 -31
  490. package/src/messaging/providers/slack/types.ts +0 -32
  491. package/src/notifications/README.md +10 -10
  492. package/src/notifications/broadcaster.ts +1 -1
  493. package/src/notifications/copy-composer.ts +13 -0
  494. package/src/notifications/guardian-question-mode.ts +5 -5
  495. package/src/notifications/signal.ts +4 -0
  496. package/src/oauth/AGENTS.md +3 -1
  497. package/src/oauth/__tests__/oauth-connect-state.test.ts +137 -0
  498. package/src/oauth/connect-orchestrator.ts +6 -0
  499. package/src/oauth/connection-resolver.test.ts +66 -1
  500. package/src/oauth/connection-resolver.ts +55 -1
  501. package/src/oauth/credential-token-resolver.ts +1 -3
  502. package/src/oauth/manual-token-connection.ts +0 -4
  503. package/src/oauth/oauth-connect-state.ts +77 -0
  504. package/src/oauth/seed-providers.ts +58 -1
  505. package/src/outbound-proxy/index.ts +1 -37
  506. package/src/outbound-proxy/logging.ts +1 -1
  507. package/src/outbound-proxy/policy.ts +6 -5
  508. package/src/outbound-proxy/router.ts +2 -1
  509. package/src/permissions/approval-policy.test.ts +6 -275
  510. package/src/permissions/approval-policy.ts +0 -51
  511. package/src/permissions/checker.test.ts +0 -1
  512. package/src/permissions/checker.ts +3 -17
  513. package/src/permissions/gateway-threshold-reader.ts +2 -0
  514. package/src/permissions/prompter.ts +34 -1
  515. package/src/permissions/secret-prompter.ts +6 -2
  516. package/src/plugins/defaults/injectors.ts +35 -2
  517. package/src/plugins/defaults/memory-retrieval.ts +5 -6
  518. package/src/plugins/types.ts +7 -0
  519. package/src/proactive-artifact/aux-message-injector.ts +74 -0
  520. package/src/proactive-artifact/decision.test.ts +226 -0
  521. package/src/proactive-artifact/decision.ts +165 -0
  522. package/src/proactive-artifact/index.ts +7 -0
  523. package/src/proactive-artifact/job.test.ts +867 -0
  524. package/src/proactive-artifact/job.ts +352 -0
  525. package/src/proactive-artifact/message-copy.ts +41 -0
  526. package/src/proactive-artifact/trigger-state.test.ts +277 -0
  527. package/src/proactive-artifact/trigger-state.ts +119 -0
  528. package/src/prompts/bootstrap-cleanup.ts +27 -0
  529. package/src/prompts/normalize-onboarding.ts +80 -0
  530. package/src/prompts/persona-resolver.ts +101 -9
  531. package/src/prompts/system-prompt.ts +23 -24
  532. package/src/prompts/templates/BOOTSTRAP.md +13 -5
  533. package/src/prompts/templates/SOUL.md +13 -1
  534. package/src/providers/__tests__/retry-callsite.test.ts +222 -1
  535. package/src/providers/model-intents.ts +7 -0
  536. package/src/providers/openrouter/client.ts +8 -0
  537. package/src/providers/retry.ts +50 -0
  538. package/src/providers/speech-to-text/provider-catalog.ts +7 -8
  539. package/src/providers/types.ts +1 -0
  540. package/src/runtime/__tests__/agent-wake.test.ts +456 -3
  541. package/src/runtime/agent-wake.ts +238 -100
  542. package/src/runtime/assistant-event-hub.ts +151 -99
  543. package/src/runtime/auth/__tests__/middleware.test.ts +11 -56
  544. package/src/runtime/auth/__tests__/route-policy.test.ts +64 -0
  545. package/src/runtime/auth/middleware.ts +0 -96
  546. package/src/runtime/auth/route-policy.ts +32 -0
  547. package/src/runtime/auth/same-actor.ts +216 -0
  548. package/src/runtime/btw-sidechain.ts +2 -3
  549. package/src/runtime/channel-invite-transport.ts +2 -48
  550. package/src/runtime/channel-invite-transports/email.ts +1 -1
  551. package/src/runtime/channel-invite-transports/slack.ts +1 -1
  552. package/src/runtime/channel-invite-transports/telegram.ts +1 -1
  553. package/src/runtime/channel-invite-transports/voice.ts +1 -1
  554. package/src/runtime/channel-invite-transports/whatsapp.ts +1 -1
  555. package/src/runtime/channel-invite-types.ts +54 -0
  556. package/src/runtime/channel-readiness-service.ts +32 -13
  557. package/src/runtime/channel-retry-sweep.ts +65 -1
  558. package/src/runtime/guardian-reply-router.ts +10 -0
  559. package/src/runtime/http-server.ts +3 -329
  560. package/src/runtime/http-types.ts +0 -5
  561. package/src/runtime/local-actor-identity.ts +52 -11
  562. package/src/runtime/migrations/__tests__/vbundle-import-parity.test.ts +413 -0
  563. package/src/runtime/migrations/__tests__/vbundle-import-policy.test.ts +260 -0
  564. package/src/runtime/migrations/__tests__/vbundle-import-version-compat.test.ts +189 -0
  565. package/src/runtime/migrations/__tests__/vbundle-streaming-importer.test.ts +153 -1
  566. package/src/runtime/migrations/__tests__/vbundle-symlink-importer.test.ts +451 -0
  567. package/src/runtime/migrations/__tests__/vbundle-symlink-streaming-importer.test.ts +0 -0
  568. package/src/runtime/migrations/__tests__/vbundle-symlink-streaming.test.ts +515 -0
  569. package/src/runtime/migrations/__tests__/vbundle-symlink-tar.test.ts +437 -0
  570. package/src/runtime/migrations/__tests__/vbundle-symlink-walker.test.ts +319 -0
  571. package/src/runtime/migrations/__tests__/vbundle-validator-v1-schema.test.ts +51 -1
  572. package/src/runtime/migrations/migration-transport.ts +7 -7
  573. package/src/runtime/migrations/vbundle-builder.ts +327 -60
  574. package/src/runtime/migrations/vbundle-import-analyzer.ts +4 -4
  575. package/src/runtime/migrations/vbundle-import-policy.ts +172 -0
  576. package/src/runtime/migrations/vbundle-importer.ts +245 -68
  577. package/src/runtime/migrations/vbundle-streaming-importer.ts +326 -35
  578. package/src/runtime/migrations/vbundle-streaming-validator.ts +157 -4
  579. package/src/runtime/migrations/vbundle-tar-stream.ts +15 -6
  580. package/src/runtime/migrations/vbundle-validator.ts +114 -0
  581. package/src/runtime/pending-interactions.ts +43 -9
  582. package/src/runtime/routes/__tests__/backup-routes.test.ts +22 -150
  583. package/src/runtime/routes/__tests__/client-routes.test.ts +155 -0
  584. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +98 -5
  585. package/src/runtime/routes/__tests__/gateway-log-routes.test.ts +242 -0
  586. package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +112 -0
  587. package/src/runtime/routes/approval-interception-types.ts +13 -0
  588. package/src/runtime/routes/approval-strategies/guardian-text-engine-strategy.ts +1 -1
  589. package/src/runtime/routes/backup-routes.ts +15 -38
  590. package/src/runtime/routes/btw-routes.ts +14 -37
  591. package/src/runtime/routes/client-routes.ts +21 -2
  592. package/src/runtime/routes/contact-prompt-routes.ts +183 -0
  593. package/src/runtime/routes/contact-routes.ts +0 -25
  594. package/src/runtime/routes/conversation-query-routes.ts +36 -1
  595. package/src/runtime/routes/conversation-routes.ts +65 -39
  596. package/src/runtime/routes/debug-bash-routes.ts +163 -0
  597. package/src/runtime/routes/disk-pressure-routes.ts +121 -0
  598. package/src/runtime/routes/document-pdf-renderer.ts +169 -0
  599. package/src/runtime/routes/documents-routes.ts +32 -75
  600. package/src/runtime/routes/errors.ts +19 -4
  601. package/src/runtime/routes/events-routes.ts +38 -0
  602. package/src/runtime/routes/gateway-log-routes.ts +79 -0
  603. package/src/runtime/routes/guardian-approval-interception.ts +2 -8
  604. package/src/runtime/routes/heartbeat-routes.ts +103 -38
  605. package/src/runtime/routes/host-app-control-routes.ts +134 -0
  606. package/src/runtime/routes/host-bash-routes.ts +56 -6
  607. package/src/runtime/routes/host-browser-routes.ts +108 -13
  608. package/src/runtime/routes/host-cu-routes.ts +66 -9
  609. package/src/runtime/routes/host-file-routes.ts +54 -5
  610. package/src/runtime/routes/host-transfer-routes.ts +122 -19
  611. package/src/runtime/routes/http-adapter.ts +1 -0
  612. package/src/runtime/routes/identity-intro-cache.ts +30 -0
  613. package/src/runtime/routes/identity-routes.ts +21 -180
  614. package/src/runtime/routes/inbound-message-handler.ts +78 -21
  615. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +0 -7
  616. package/src/runtime/routes/inbound-stages/edit-intercept.ts +0 -8
  617. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +3 -0
  618. package/src/runtime/routes/inbound-stages/transcribe-audio.test.ts +0 -20
  619. package/src/runtime/routes/inbound-stages/transcribe-audio.ts +5 -13
  620. package/src/runtime/routes/index.ts +14 -0
  621. package/src/runtime/routes/mcp-auth-routes.ts +132 -0
  622. package/src/runtime/routes/memory-item-routes.test.ts +41 -15
  623. package/src/runtime/routes/memory-item-routes.ts +10 -12
  624. package/src/runtime/routes/memory-v2-routes.ts +474 -1
  625. package/src/runtime/routes/migration-routes.ts +96 -0
  626. package/src/runtime/routes/oauth-connect-routes.ts +153 -0
  627. package/src/runtime/routes/schedule-routes.ts +7 -0
  628. package/src/runtime/verification-outbound-actions.ts +4 -4
  629. package/src/runtime/verification-templates.ts +4 -7
  630. package/src/schedule/integration-status.ts +66 -2
  631. package/src/schedule/recurrence-engine.ts +4 -1
  632. package/src/schedule/retry-backoff.ts +18 -0
  633. package/src/schedule/retry-policy.ts +82 -0
  634. package/src/schedule/run-script.ts +37 -5
  635. package/src/schedule/schedule-recovery.ts +64 -0
  636. package/src/schedule/schedule-store.ts +106 -2
  637. package/src/schedule/scheduler-types.ts +25 -0
  638. package/src/schedule/scheduler.ts +83 -39
  639. package/src/security/encrypted-store.ts +2 -0
  640. package/src/security/oauth-callback-registry.ts +8 -0
  641. package/src/security/secure-keys.ts +55 -0
  642. package/src/sequence/analytics.ts +5 -5
  643. package/src/sequence/engine.ts +1 -1
  644. package/src/skills/catalog-files.ts +2 -8
  645. package/src/skills/include-graph.ts +5 -5
  646. package/src/skills/remote-skill-policy.ts +10 -16
  647. package/src/skills/skill-file-provider.ts +1 -1
  648. package/src/skills/skill-file-types.ts +13 -0
  649. package/src/skills/skillssh-audit-types.ts +28 -0
  650. package/src/skills/skillssh-registry.ts +8 -21
  651. package/src/subagent/index.ts +1 -7
  652. package/src/subagent/manager.ts +1 -15
  653. package/src/tasks/task-runner.ts +0 -1
  654. package/src/tasks/task-store.ts +0 -3
  655. package/src/telemetry/types.ts +2 -0
  656. package/src/telemetry/usage-telemetry-reporter.test.ts +21 -0
  657. package/src/telemetry/usage-telemetry-reporter.ts +1 -0
  658. package/src/tools/app-control/skill-proxy-bridge.ts +28 -0
  659. package/src/tools/apps/executors.ts +56 -69
  660. package/src/tools/background-tool-registry.ts +17 -3
  661. package/src/tools/browser/__tests__/browser-status.test.ts +21 -18
  662. package/src/tools/browser/browser-execution.ts +2 -2
  663. package/src/tools/browser/cdp-client/__tests__/factory.test.ts +55 -4
  664. package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +12 -6
  665. package/src/tools/browser/cdp-client/factory.ts +23 -24
  666. package/src/tools/browser/cdp-client/index.ts +1 -14
  667. package/src/tools/computer-use/definitions.ts +42 -20
  668. package/src/tools/executor.ts +2 -0
  669. package/src/tools/host-filesystem/edit.test.ts +151 -0
  670. package/src/tools/host-filesystem/edit.ts +68 -0
  671. package/src/tools/host-filesystem/read.test.ts +129 -0
  672. package/src/tools/host-filesystem/read.ts +68 -0
  673. package/src/tools/host-filesystem/transfer.test.ts +127 -2
  674. package/src/tools/host-filesystem/transfer.ts +78 -3
  675. package/src/tools/host-filesystem/write.test.ts +134 -0
  676. package/src/tools/host-filesystem/write.ts +68 -0
  677. package/src/tools/host-terminal/host-shell.ts +66 -1
  678. package/src/tools/mcp/mcp-tool-factory.ts +2 -1
  679. package/src/tools/memory/register.test.ts +12 -9
  680. package/src/tools/memory/register.ts +1 -2
  681. package/src/tools/provider-tool-name.ts +28 -0
  682. package/src/tools/registry.ts +30 -9
  683. package/src/tools/schedule/create.ts +6 -0
  684. package/src/tools/schedule/list.ts +2 -0
  685. package/src/tools/schedule/update.ts +10 -0
  686. package/src/tools/shared/filesystem/file-ops-service.ts +2 -0
  687. package/src/tools/shared/filesystem/path-policy.ts +25 -1
  688. package/src/tools/skills/load.ts +0 -32
  689. package/src/tools/terminal/shell.ts +9 -1
  690. package/src/tools/tool-approval-handler.ts +32 -11
  691. package/src/tools/types.ts +28 -2
  692. package/src/tts/provider-catalog.ts +3 -5
  693. package/src/usage/pricing.ts +1 -1
  694. package/src/util/disk-usage.ts +138 -0
  695. package/src/util/platform.ts +21 -11
  696. package/src/util/process-liveness.ts +26 -0
  697. package/src/workspace/hatched-date.ts +86 -0
  698. package/src/workspace/heartbeat-service.ts +19 -0
  699. package/src/workspace/migrations/003-seed-device-id.ts +1 -1
  700. package/src/workspace/migrations/006-services-config.ts +8 -5
  701. package/src/workspace/migrations/016-extract-feature-flags-to-protected.ts +3 -9
  702. package/src/workspace/migrations/021-move-signals-to-workspace.ts +4 -10
  703. package/src/workspace/migrations/022-move-hooks-to-workspace.ts +4 -10
  704. package/src/workspace/migrations/023-move-config-files-to-workspace.ts +4 -11
  705. package/src/workspace/migrations/024-move-runtime-files-to-workspace.ts +3 -10
  706. package/src/workspace/migrations/040-seed-latency-callsite-defaults.ts +3 -2
  707. package/src/workspace/migrations/050-seed-main-agent-opus-callsite.ts +2 -1
  708. package/src/workspace/migrations/059-move-pid-to-workspace.ts +3 -8
  709. package/src/workspace/migrations/061-move-backup-key-to-workspace.ts +3 -8
  710. package/src/workspace/migrations/065-bump-stale-heartbeat-interval.ts +60 -0
  711. package/src/workspace/migrations/066-seed-heartbeat-callsite-cost-default.ts +146 -0
  712. package/src/workspace/migrations/067-release-notes-safe-storage-limits.ts +72 -0
  713. package/src/workspace/migrations/068-release-notes-local-timezone.ts +65 -0
  714. package/src/workspace/migrations/AGENTS.md +1 -1
  715. package/src/workspace/migrations/migrate-to-workspace-volume.ts +4 -10
  716. package/src/workspace/migrations/registry.ts +8 -0
  717. package/src/workspace/migrations/utils.ts +21 -0
  718. package/src/__tests__/conversation-tool-setup-memory-scope.test.ts +0 -167
  719. package/src/__tests__/host-browser-e2e-cloud.test.ts +0 -443
  720. package/src/__tests__/host-browser-e2e-self-hosted-capability.test.ts +0 -226
  721. package/src/__tests__/host-browser-ws-events-e2e.test.ts +0 -427
  722. package/src/__tests__/twilio-rest.test.ts +0 -34
  723. package/src/backup/__tests__/backup-key.test.ts +0 -152
  724. package/src/backup/__tests__/backup-worker.test.ts +0 -782
  725. package/src/backup/__tests__/offsite-writer.test.ts +0 -641
  726. package/src/backup/__tests__/stream-crypt.test.ts +0 -228
  727. package/src/backup/backup-key.ts +0 -137
  728. package/src/backup/backup-worker.ts +0 -472
  729. package/src/backup/offsite-writer.ts +0 -222
  730. package/src/backup/stream-crypt.ts +0 -263
  731. package/src/daemon/message-types/pairing.ts +0 -58
  732. package/src/memory/v2/__tests__/skill-qdrant.test.ts +0 -657
  733. package/src/memory/v2/skill-qdrant.ts +0 -395
  734. package/src/outbound-proxy/config.ts +0 -20
  735. package/src/outbound-proxy/health.ts +0 -18
  736. package/src/outbound-proxy/types.ts +0 -150
  737. package/src/runtime/capability-tokens.ts +0 -190
  738. package/src/signals/bash.ts +0 -198
  739. package/src/signals/mcp-reload.ts +0 -18
@@ -1,4 +1,11 @@
1
- import { describe, expect, it } from "bun:test";
1
+ import { beforeEach, describe, expect, it, mock } from "bun:test";
2
+
3
+ let providerRoutingSources: Record<string, "user-key" | "managed-proxy"> = {};
4
+
5
+ mock.module("../providers/registry.js", () => ({
6
+ getProviderRoutingSource: (provider: string) =>
7
+ providerRoutingSources[provider],
8
+ }));
2
9
 
3
10
  import type { ErrorContext } from "../daemon/conversation-error.js";
4
11
  import {
@@ -63,6 +70,10 @@ describe("isUserCancellation", () => {
63
70
  describe("classifyConversationError", () => {
64
71
  const baseCtx: ErrorContext = { phase: "agent_loop" };
65
72
 
73
+ beforeEach(() => {
74
+ providerRoutingSources = {};
75
+ });
76
+
66
77
  describe("network errors", () => {
67
78
  const cases = [
68
79
  "ECONNREFUSED",
@@ -105,6 +116,52 @@ describe("classifyConversationError", () => {
105
116
  expect(result.errorCategory).toBe("rate_limit");
106
117
  });
107
118
  }
119
+
120
+ it("classifies managed-proxy daily quota responses as MANAGED_USAGE_LIMIT", () => {
121
+ const err = new ProviderError(
122
+ 'Anthropic API error (429): 429 {"code":"daily_quota_exceeded","detail":"You\'ve reached your usage limit for today. You\'ve made 1000 requests, but your current plan allows 1000 per day.","provider":"anthropic"}',
123
+ "anthropic",
124
+ 429,
125
+ );
126
+
127
+ const result = classifyConversationError(err, baseCtx);
128
+
129
+ expect(result.code).toBe("MANAGED_USAGE_LIMIT");
130
+ expect(result.retryable).toBe(true);
131
+ expect(result.userMessage).toContain("Vellum managed inference");
132
+ expect(result.userMessage).toContain("not an AI provider outage");
133
+ expect(result.errorCategory).toBe("managed_usage_limit");
134
+ });
135
+
136
+ it("classifies managed-proxy routed 429s as MANAGED_USAGE_LIMIT", () => {
137
+ providerRoutingSources.anthropic = "managed-proxy";
138
+ const err = new ProviderError(
139
+ "Anthropic API error (429): Too many requests",
140
+ "anthropic",
141
+ 429,
142
+ );
143
+
144
+ const result = classifyConversationError(err, baseCtx);
145
+
146
+ expect(result.code).toBe("MANAGED_USAGE_LIMIT");
147
+ expect(result.userMessage).toContain("Vellum managed inference");
148
+ expect(result.errorCategory).toBe("managed_usage_limit");
149
+ });
150
+
151
+ it("keeps provider copy for direct provider 429s", () => {
152
+ providerRoutingSources.anthropic = "user-key";
153
+ const err = new ProviderError(
154
+ "Anthropic API error (429): Too many requests",
155
+ "anthropic",
156
+ 429,
157
+ );
158
+
159
+ const result = classifyConversationError(err, baseCtx);
160
+
161
+ expect(result.code).toBe("PROVIDER_RATE_LIMIT");
162
+ expect(result.userMessage).toContain("AI provider");
163
+ expect(result.errorCategory).toBe("rate_limit");
164
+ });
108
165
  });
109
166
 
110
167
  describe("provider overloaded errors", () => {
@@ -509,11 +566,11 @@ describe("classifyConversationError", () => {
509
566
  expect(result.errorCategory).toBe("provider_not_configured");
510
567
  });
511
568
 
512
- it("classifies ProviderError with 402 as credits_exhausted (non-retryable)", () => {
569
+ it("classifies direct ProviderError with 402 as provider_billing (non-retryable)", () => {
513
570
  const err = new ProviderError("Payment Required", "anthropic", 402);
514
571
  const result = classifyConversationError(err, baseCtx);
515
572
  expect(result.code).toBe("PROVIDER_BILLING");
516
- expect(result.errorCategory).toBe("credits_exhausted");
573
+ expect(result.errorCategory).toBe("provider_billing");
517
574
  expect(result.retryable).toBe(false);
518
575
  });
519
576
 
@@ -560,6 +617,96 @@ describe("classifyConversationError", () => {
560
617
  });
561
618
  });
562
619
 
620
+ describe("OpenRouter billing classification", () => {
621
+ it("keeps managed-proxy OpenRouter 402 responses as credits_exhausted", () => {
622
+ providerRoutingSources.openrouter = "managed-proxy";
623
+ const err = new ProviderError(
624
+ "OpenRouter API error (402): Payment Required",
625
+ "openrouter",
626
+ 402,
627
+ );
628
+
629
+ const result = classifyConversationError(err, baseCtx);
630
+
631
+ expect(result.code).toBe("PROVIDER_BILLING");
632
+ expect(result.errorCategory).toBe("credits_exhausted");
633
+ expect(result.retryable).toBe(false);
634
+ expect(result.userMessage).toContain("Add funds");
635
+ expect(result.userMessage).toContain("assistant");
636
+ });
637
+
638
+ it("classifies direct Anthropic, OpenAI, and OpenRouter 402 responses as provider_billing", () => {
639
+ providerRoutingSources.anthropic = "user-key";
640
+ providerRoutingSources.openai = "user-key";
641
+ providerRoutingSources.openrouter = "user-key";
642
+
643
+ for (const provider of ["anthropic", "openai", "openrouter"]) {
644
+ const err = new ProviderError(
645
+ `${provider} API error (402): Payment Required`,
646
+ provider,
647
+ 402,
648
+ );
649
+
650
+ const result = classifyConversationError(err, baseCtx);
651
+
652
+ expect(result.code).toBe("PROVIDER_BILLING");
653
+ expect(result.errorCategory).toBe("provider_billing");
654
+ expect(result.retryable).toBe(false);
655
+ expect(result.userMessage).toContain("provider");
656
+ expect(result.userMessage).toContain("Settings");
657
+ }
658
+ });
659
+
660
+ it("classifies OpenRouter 400 credit-limit messages as provider_billing", () => {
661
+ const cases = [
662
+ "OpenRouter API error (400): This request requires more credits",
663
+ "OpenRouter API error (400): You can only afford 1000 tokens",
664
+ ];
665
+
666
+ for (const message of cases) {
667
+ const err = new ProviderError(message, "openrouter", 400);
668
+
669
+ const result = classifyConversationError(err, baseCtx);
670
+
671
+ expect(result.code).toBe("PROVIDER_BILLING");
672
+ expect(result.errorCategory).toBe("provider_billing");
673
+ expect(result.retryable).toBe(false);
674
+ }
675
+ });
676
+
677
+ it("classifies managed-proxy OpenRouter insufficient_balance bodies as credits_exhausted", () => {
678
+ providerRoutingSources.openrouter = "managed-proxy";
679
+ const err = new ProviderError(
680
+ 'OpenRouter API error (402): {"code":"insufficient_balance","detail":"Managed balance exhausted"}',
681
+ "openrouter",
682
+ 402,
683
+ );
684
+
685
+ const result = classifyConversationError(err, baseCtx);
686
+
687
+ expect(result.code).toBe("PROVIDER_BILLING");
688
+ expect(result.errorCategory).toBe("credits_exhausted");
689
+ expect(result.retryable).toBe(false);
690
+ });
691
+
692
+ it("classifies direct OpenRouter insufficient_balance bodies as provider_billing", () => {
693
+ providerRoutingSources.openrouter = "user-key";
694
+ const err = new ProviderError(
695
+ 'OpenRouter API error (402): {"code":"insufficient_balance","detail":"Provider account balance exhausted"}',
696
+ "openrouter",
697
+ 402,
698
+ );
699
+
700
+ const result = classifyConversationError(err, baseCtx);
701
+
702
+ expect(result.code).toBe("PROVIDER_BILLING");
703
+ expect(result.errorCategory).toBe("provider_billing");
704
+ expect(result.retryable).toBe(false);
705
+ expect(result.userMessage).toContain("provider");
706
+ expect(result.userMessage).toContain("Settings");
707
+ });
708
+ });
709
+
563
710
  describe("debug detail truncation", () => {
564
711
  it("truncates debugDetails longer than 4000 chars", () => {
565
712
  const longMsg = "x".repeat(5000);
@@ -140,14 +140,12 @@ mock.module("../config/loader.js", () => ({
140
140
  getConfig: () => mockConfig,
141
141
  getConfigReadOnly: () => mockConfig,
142
142
  loadConfig: () => mockConfig,
143
- saveConfig: () => {},
144
143
  invalidateConfigCache: () => {},
145
144
  loadRawConfig: () => ({}),
146
145
  saveRawConfig: () => {},
147
146
  getNestedValue: () => undefined,
148
147
  setNestedValue: () => {},
149
148
  applyNestedDefaults: (c: unknown) => c,
150
- deepMergeMissing: () => {},
151
149
  deepMergeOverwrite: () => {},
152
150
  mergeDefaultWorkspaceConfig: () => {},
153
151
  }));
@@ -308,6 +308,42 @@ describe("loadFromDb metadata injection rehydration", () => {
308
308
  expect(messages[2].content).toEqual([{ type: "text", text: "Second" }]);
309
309
  });
310
310
 
311
+ test("historical wrapped memoryInjectedBlock rehydrates singly-wrapped", async () => {
312
+ // Historical v2 rows persisted `injectedBlockText` already wrapped in
313
+ // `<memory>...</memory>`. After unifying v2's storage with v1's
314
+ // unwrapped contract, the rehydrate path must defensively strip any
315
+ // pre-existing wrapper so old rows don't render double-wrapped.
316
+ mockConversation = defaultConv();
317
+ mockDbMessages = [
318
+ {
319
+ id: "m1",
320
+ role: "user",
321
+ content: JSON.stringify([{ type: "text", text: "Hi" }]),
322
+ metadata: JSON.stringify({
323
+ memoryInjectedBlock: "<memory>\nremember: alice\n</memory>",
324
+ }),
325
+ },
326
+ {
327
+ id: "m2",
328
+ role: "assistant",
329
+ content: JSON.stringify([{ type: "text", text: "Hello" }]),
330
+ },
331
+ ];
332
+
333
+ const conversation = makeConversation();
334
+ await conversation.loadFromDb();
335
+ const messages = conversation.getMessages();
336
+
337
+ expect(messages).toHaveLength(2);
338
+ const firstBlock = messages[0].content[0];
339
+ expect(firstBlock).toEqual({
340
+ type: "text",
341
+ text: "<memory>\nremember: alice\n</memory>",
342
+ });
343
+ if (firstBlock.type !== "text") throw new Error("unexpected block type");
344
+ expect(firstBlock.text.match(/<memory>/g)?.length).toBe(1);
345
+ });
346
+
311
347
  test("malformed metadata is tolerated: load does not throw, content unchanged", async () => {
312
348
  mockConversation = defaultConv();
313
349
  mockDbMessages = [
@@ -0,0 +1,283 @@
1
+ /**
2
+ * Verifies that the queue-drain paths in `conversation-process.ts` re-add
3
+ * the `app-control` skill to the conversation's preactivated set when the
4
+ * dequeued message's `userMessageInterface` supports the `host_app_control`
5
+ * proxy capability.
6
+ *
7
+ * Both `drainSingleMessage` (single-message path) and `drainBatch`
8
+ * (batched path) reset `preactivatedSkillIds = undefined` at the top of
9
+ * each drain. Without an explicit re-add, queued messages 2+ would lose
10
+ * the `app-control` skill — its tools wouldn't be projected to the LLM —
11
+ * even though the `HostAppControlProxy` is still attached to the
12
+ * conversation. This mirrors the existing parallel re-add for
13
+ * `computer-use` and uses the same `supportsHostProxy(_, "host_app_control")`
14
+ * gate that `prepareConversationForMessage` and the `conversation-routes`
15
+ * instantiation block use at first-message time.
16
+ */
17
+
18
+ import { describe, expect, mock, test } from "bun:test";
19
+
20
+ // ---------------------------------------------------------------------------
21
+ // Module mocks for downstream side effects (DB writes, slash resolution,
22
+ // notification preference extraction). The drain paths must be allowed to
23
+ // reach the preactivation block; they must not be allowed to touch a real DB.
24
+ // ---------------------------------------------------------------------------
25
+
26
+ mock.module("../util/logger.js", () => ({
27
+ getLogger: () =>
28
+ new Proxy({} as Record<string, unknown>, { get: () => () => {} }),
29
+ }));
30
+
31
+ mock.module("../memory/conversation-crud.js", () => ({
32
+ setConversationOriginChannelIfUnset: () => {},
33
+ setConversationOriginInterfaceIfUnset: () => {},
34
+ provenanceFromTrustContext: () => ({
35
+ source: "user",
36
+ trustContext: undefined,
37
+ }),
38
+ addMessage: () => ({ id: "msg-mock" }),
39
+ }));
40
+
41
+ mock.module("../memory/canonical-guardian-store.js", () => ({
42
+ listPendingRequestsByConversationScope: () => [],
43
+ }));
44
+
45
+ mock.module("../memory/trace-event-store.js", () => ({
46
+ persistTraceEvent: () => {},
47
+ getMaxSequence: () => 0,
48
+ }));
49
+
50
+ mock.module("../notifications/preference-extractor.js", () => ({
51
+ extractPreferences: async () => ({ detected: false, preferences: [] }),
52
+ }));
53
+
54
+ mock.module("../notifications/preferences-store.js", () => ({
55
+ createPreference: () => {},
56
+ }));
57
+
58
+ mock.module("../agent/attachments.ts", () => ({
59
+ enrichMessageWithSourcePaths: <T>(msg: T) => msg,
60
+ }));
61
+
62
+ // Stub the batched-drain helper so the test doesn't fall through to real
63
+ // SQLite paths after the preactivation block has already run. The drain
64
+ // chain doesn't recurse here because our stubbed `runAgentLoop` is a no-op.
65
+ mock.module("../daemon/conversation-messaging.js", () => ({
66
+ persistQueuedMessageBody: async () => "user-msg-id",
67
+ }));
68
+
69
+ // ---------------------------------------------------------------------------
70
+ // Imports under test (after mocks)
71
+ // ---------------------------------------------------------------------------
72
+
73
+ import type { TurnInterfaceContext } from "../channels/types.js";
74
+ import type { ProcessConversationContext } from "../daemon/conversation-process.js";
75
+ import { drainQueue } from "../daemon/conversation-process.js";
76
+ import {
77
+ MessageQueue,
78
+ type QueuedMessage,
79
+ } from "../daemon/conversation-queue-manager.js";
80
+ import { TraceEmitter } from "../daemon/trace-emitter.js";
81
+
82
+ // ---------------------------------------------------------------------------
83
+ // Fake context — captures preactivation calls, satisfies the bare minimum
84
+ // of `ProcessConversationContext`. `runAgentLoop` resolves immediately so
85
+ // the drain-chain does not recurse forever.
86
+ // ---------------------------------------------------------------------------
87
+
88
+ interface FakeRecord {
89
+ preactivatedSkillIdCalls: string[];
90
+ }
91
+
92
+ function makeFakeContext(opts: {
93
+ queue: MessageQueue;
94
+ turnInterfaceContext?: TurnInterfaceContext;
95
+ }): ProcessConversationContext & FakeRecord {
96
+ const calls: string[] = [];
97
+ let preactivatedSkillIds: string[] | undefined = undefined;
98
+ const ctx = {
99
+ conversationId: "conv-app-control-preactivation",
100
+ messages: [],
101
+ processing: false,
102
+ abortController: null,
103
+ queue: opts.queue,
104
+ traceEmitter: new TraceEmitter("conv-app-control-preactivation", () => {}),
105
+ surfaceActionRequestIds: new Set<string>(),
106
+ usageStats: { inputTokens: 0, outputTokens: 0, estimatedCost: 0 },
107
+ get preactivatedSkillIds(): string[] | undefined {
108
+ return preactivatedSkillIds;
109
+ },
110
+ set preactivatedSkillIds(value: string[] | undefined) {
111
+ preactivatedSkillIds = value;
112
+ },
113
+ preactivatedSkillIdCalls: calls,
114
+ addPreactivatedSkillId(id: string) {
115
+ calls.push(id);
116
+ if (!preactivatedSkillIds) {
117
+ preactivatedSkillIds = [id];
118
+ } else if (!preactivatedSkillIds.includes(id)) {
119
+ preactivatedSkillIds.push(id);
120
+ }
121
+ },
122
+ async ensureActorScopedHistory() {},
123
+ async persistUserMessage() {
124
+ return "user-msg-id";
125
+ },
126
+ async runAgentLoop() {
127
+ // No-op: the drain path's finally block would normally call drainQueue
128
+ // recursively. We intentionally do not chain another drain here so the
129
+ // test asserts on what the FIRST dequeue produced.
130
+ },
131
+ getTurnChannelContext: () => null,
132
+ setTurnChannelContext() {},
133
+ getTurnInterfaceContext: () => opts.turnInterfaceContext ?? null,
134
+ setTurnInterfaceContext() {},
135
+ emitActivityState() {},
136
+ async forceCompact() {
137
+ return {
138
+ compacted: false,
139
+ reason: "no-op",
140
+ estimatedInputTokens: 0,
141
+ previousEstimatedInputTokens: 0,
142
+ maxInputTokens: 100000,
143
+ compactedMessages: 0,
144
+ } as never;
145
+ },
146
+ setTransportHints() {},
147
+ applyHostEnvFromTransport() {},
148
+ } as unknown as ProcessConversationContext & FakeRecord;
149
+ return ctx;
150
+ }
151
+
152
+ function makeQueuedMessage(opts: {
153
+ requestId: string;
154
+ content?: string;
155
+ turnInterfaceContext?: TurnInterfaceContext;
156
+ }): QueuedMessage {
157
+ return {
158
+ content: opts.content ?? "follow up",
159
+ attachments: [],
160
+ requestId: opts.requestId,
161
+ onEvent: () => {},
162
+ metadata: {},
163
+ sentAt: Date.now(),
164
+ turnInterfaceContext: opts.turnInterfaceContext,
165
+ };
166
+ }
167
+
168
+ // ---------------------------------------------------------------------------
169
+ // Tests
170
+ // ---------------------------------------------------------------------------
171
+
172
+ describe("drainQueue preactivation re-add for host-proxy interfaces", () => {
173
+ test("drainSingleMessage re-adds 'app-control' for macOS-sourced queued message", async () => {
174
+ const queue = new MessageQueue();
175
+ const ifCtx: TurnInterfaceContext = {
176
+ userMessageInterface: "macos",
177
+ assistantMessageInterface: "macos",
178
+ };
179
+ queue.push(
180
+ makeQueuedMessage({ requestId: "req-2", turnInterfaceContext: ifCtx }),
181
+ );
182
+ const ctx = makeFakeContext({ queue, turnInterfaceContext: ifCtx });
183
+
184
+ await drainQueue(ctx);
185
+
186
+ // Both CU and app-control must be re-preactivated for queued macOS turns.
187
+ expect(ctx.preactivatedSkillIdCalls).toContain("computer-use");
188
+ expect(ctx.preactivatedSkillIdCalls).toContain("app-control");
189
+ expect(ctx.preactivatedSkillIds).toContain("app-control");
190
+ });
191
+
192
+ test("drainSingleMessage does not re-add 'app-control' for chrome-extension (host_app_control unsupported)", async () => {
193
+ const queue = new MessageQueue();
194
+ // chrome-extension supports host_browser but NOT host_app_control. The
195
+ // CU re-add (no-arg form) also returns false for chrome-extension, so
196
+ // neither skill should be re-preactivated.
197
+ const ifCtx: TurnInterfaceContext = {
198
+ userMessageInterface: "chrome-extension",
199
+ assistantMessageInterface: "chrome-extension",
200
+ };
201
+ queue.push(
202
+ makeQueuedMessage({ requestId: "req-2", turnInterfaceContext: ifCtx }),
203
+ );
204
+ const ctx = makeFakeContext({ queue, turnInterfaceContext: ifCtx });
205
+
206
+ await drainQueue(ctx);
207
+
208
+ expect(ctx.preactivatedSkillIdCalls).not.toContain("computer-use");
209
+ expect(ctx.preactivatedSkillIdCalls).not.toContain("app-control");
210
+ });
211
+
212
+ test("drainSingleMessage does not re-add 'app-control' for non-host-proxy interface (slack)", async () => {
213
+ const queue = new MessageQueue();
214
+ const ifCtx: TurnInterfaceContext = {
215
+ userMessageInterface: "slack",
216
+ assistantMessageInterface: "slack",
217
+ };
218
+ queue.push(
219
+ makeQueuedMessage({ requestId: "req-2", turnInterfaceContext: ifCtx }),
220
+ );
221
+ const ctx = makeFakeContext({ queue, turnInterfaceContext: ifCtx });
222
+
223
+ await drainQueue(ctx);
224
+
225
+ expect(ctx.preactivatedSkillIdCalls).not.toContain("computer-use");
226
+ expect(ctx.preactivatedSkillIdCalls).not.toContain("app-control");
227
+ });
228
+
229
+ test("drainBatch re-adds 'app-control' for macOS-sourced batched queue", async () => {
230
+ const queue = new MessageQueue();
231
+ const ifCtx: TurnInterfaceContext = {
232
+ userMessageInterface: "macos",
233
+ assistantMessageInterface: "macos",
234
+ };
235
+ // Two passthrough siblings with matching interface — buildPassthroughBatch
236
+ // groups them into a batch, exercising drainBatch.
237
+ queue.push(
238
+ makeQueuedMessage({
239
+ requestId: "req-2",
240
+ content: "msg-2",
241
+ turnInterfaceContext: ifCtx,
242
+ }),
243
+ );
244
+ queue.push(
245
+ makeQueuedMessage({
246
+ requestId: "req-3",
247
+ content: "msg-3",
248
+ turnInterfaceContext: ifCtx,
249
+ }),
250
+ );
251
+ const ctx = makeFakeContext({ queue, turnInterfaceContext: ifCtx });
252
+
253
+ await drainQueue(ctx);
254
+
255
+ // Batched path mirrors the single-message preactivation block.
256
+ expect(ctx.preactivatedSkillIdCalls).toContain("computer-use");
257
+ expect(ctx.preactivatedSkillIdCalls).toContain("app-control");
258
+ expect(ctx.preactivatedSkillIds).toContain("app-control");
259
+ });
260
+
261
+ test("drainSingleMessage skips 'app-control' re-add when isInteractive=false", async () => {
262
+ const queue = new MessageQueue();
263
+ const ifCtx: TurnInterfaceContext = {
264
+ userMessageInterface: "macos",
265
+ assistantMessageInterface: "macos",
266
+ };
267
+ const qm = makeQueuedMessage({
268
+ requestId: "req-2",
269
+ turnInterfaceContext: ifCtx,
270
+ });
271
+ qm.isInteractive = false;
272
+ queue.push(qm);
273
+ const ctx = makeFakeContext({ queue, turnInterfaceContext: ifCtx });
274
+
275
+ await drainQueue(ctx);
276
+
277
+ // Both branches share the outer `isInteractive !== false` gate, so
278
+ // app-control follows CU's behavior and is skipped for non-interactive
279
+ // turns even on macOS.
280
+ expect(ctx.preactivatedSkillIdCalls).not.toContain("computer-use");
281
+ expect(ctx.preactivatedSkillIdCalls).not.toContain("app-control");
282
+ });
283
+ });
@@ -12,8 +12,14 @@
12
12
  */
13
13
  import { describe, expect, mock, test } from "bun:test";
14
14
 
15
+ import { _setOverridesForTesting } from "../config/assistant-feature-flags.js";
15
16
  import type { Message, ProviderResponse } from "../providers/types.js";
16
17
 
18
+ // This test exercises v1 conversation routing. The `memory-v2-enabled` flag
19
+ // (registry default `true`) flips memory routing to v2 — disable it here so
20
+ // the v1 paths under test stay active.
21
+ _setOverridesForTesting({ "memory-v2-enabled": false });
22
+
17
23
  // Use an object wrapper so TypeScript doesn't narrow the captured type to
18
24
  // `undefined` based on the initial assignment in the test setup.
19
25
  const captured: {
@@ -382,4 +388,41 @@ describe("processMessage callSite threading", () => {
382
388
  expect(captured.resolvedMaxTokens).toBe(1234);
383
389
  expect(captured.resolvedHasMaxTokens).toBe(true);
384
390
  });
391
+
392
+ test("applies clientTimezone in the create and reuse transport metadata path", async () => {
393
+ mockConversation = {
394
+ id: "conv-store-client-timezone",
395
+ contextSummary: null,
396
+ contextCompactedMessageCount: 0,
397
+ totalInputTokens: 0,
398
+ totalOutputTokens: 0,
399
+ totalEstimatedCost: 0,
400
+ };
401
+ mockDbMessages = [];
402
+ clearCaptured();
403
+ clearAllActiveConversations();
404
+
405
+ const conversation = await getOrCreateConversation(
406
+ "conv-store-client-timezone",
407
+ {
408
+ transport: {
409
+ channelId: "vellum",
410
+ interfaceId: "macos",
411
+ clientTimezone: "america/new_york",
412
+ },
413
+ },
414
+ );
415
+
416
+ expect(conversation.clientTimezone).toBe("America/New_York");
417
+
418
+ await getOrCreateConversation("conv-store-client-timezone", {
419
+ transport: {
420
+ channelId: "vellum",
421
+ interfaceId: "ios",
422
+ clientTimezone: "europe/london",
423
+ },
424
+ });
425
+
426
+ expect(conversation.clientTimezone).toBe("Europe/London");
427
+ });
385
428
  });
@@ -1,11 +1,17 @@
1
1
  import { beforeEach, describe, expect, mock, test } from "bun:test";
2
2
 
3
3
  import type { AgentEvent } from "../agent/loop.js";
4
+ import { _setOverridesForTesting } from "../config/assistant-feature-flags.js";
4
5
  import type { UserMessageAttachment } from "../daemon/message-protocol.js";
5
6
  import { resetPluginRegistryAndRegisterDefaults } from "../plugins/defaults/index.js";
6
7
  import type { Message, ProviderResponse } from "../providers/types.js";
7
8
  import { ProviderError } from "../util/errors.js";
8
9
 
10
+ // This test exercises v1 conversation routing. The `memory-v2-enabled` flag
11
+ // (registry default `true`) flips memory routing to v2 — disable it here so
12
+ // the v1 paths under test stay active.
13
+ _setOverridesForTesting({ "memory-v2-enabled": false });
14
+
9
15
  mock.module("../util/logger.js", () => ({
10
16
  getLogger: () =>
11
17
  new Proxy({} as Record<string, unknown>, { get: () => () => {} }),
@@ -207,6 +207,12 @@ function createFakeConversation(conversationId: string): Conversation {
207
207
  setHostCuProxy(this: { hostCuProxy: unknown }, proxy: unknown) {
208
208
  this.hostCuProxy = proxy;
209
209
  },
210
+ setHostAppControlProxy(
211
+ this: { hostAppControlProxy: unknown },
212
+ proxy: unknown,
213
+ ) {
214
+ this.hostAppControlProxy = proxy;
215
+ },
210
216
  restoreBrowserProxyAvailability: () => {},
211
217
  addPreactivatedSkillId: () => {},
212
218
  hasAnyPendingConfirmation: () => false,