@vellumai/assistant 0.7.2 → 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 (347) hide show
  1. package/ARCHITECTURE.md +16 -1
  2. package/docs/architecture/memory.md +5 -2
  3. package/node_modules/@vellumai/gateway-client/src/ipc-client.ts +13 -4
  4. package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +0 -9
  5. package/node_modules/@vellumai/slack-text/src/index.test.ts +18 -35
  6. package/node_modules/@vellumai/slack-text/src/index.ts +2 -48
  7. package/openapi.yaml +449 -22
  8. package/package.json +1 -1
  9. package/src/__tests__/app-control-flow.test.ts +21 -11
  10. package/src/__tests__/assistant-event-hub.test.ts +48 -0
  11. package/src/__tests__/assistant-event.test.ts +0 -10
  12. package/src/__tests__/assistant-events-sse-hardening.test.ts +2 -7
  13. package/src/__tests__/assistant-feature-flags-integration.test.ts +18 -0
  14. package/src/__tests__/auto-analysis-end-to-end.test.ts +62 -1
  15. package/src/__tests__/background-workers-disk-pressure.test.ts +268 -0
  16. package/src/__tests__/call-conversation-messages.test.ts +8 -2
  17. package/src/__tests__/channel-inbound-disk-pressure.test.ts +537 -0
  18. package/src/__tests__/channel-readiness-service.test.ts +4 -2
  19. package/src/__tests__/config-loader-backfill.test.ts +379 -0
  20. package/src/__tests__/config-schema.test.ts +1 -0
  21. package/src/__tests__/config-watcher-cleanup-throttle.test.ts +18 -9
  22. package/src/__tests__/config-watcher.test.ts +140 -69
  23. package/src/__tests__/context-search-agent-runner.test.ts +61 -3
  24. package/src/__tests__/context-search-conversations-source.test.ts +0 -24
  25. package/src/__tests__/context-search-fanout.test.ts +0 -1
  26. package/src/__tests__/context-search-memory-source.test.ts +3 -7
  27. package/src/__tests__/context-search-memory-v2-source.test.ts +0 -2
  28. package/src/__tests__/context-search-pkb-source.test.ts +0 -1
  29. package/src/__tests__/context-search-workspace-source.test.ts +0 -1
  30. package/src/__tests__/conversation-abort-tool-results.test.ts +6 -0
  31. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +223 -0
  32. package/src/__tests__/conversation-agent-loop.test.ts +454 -5
  33. package/src/__tests__/conversation-error.test.ts +150 -3
  34. package/src/__tests__/conversation-process-callsite.test.ts +43 -0
  35. package/src/__tests__/conversation-provider-retry-repair.test.ts +6 -0
  36. package/src/__tests__/conversation-runtime-assembly.test.ts +65 -0
  37. package/src/__tests__/conversation-slash-unknown.test.ts +6 -0
  38. package/src/__tests__/conversation-speed-override.test.ts +0 -3
  39. package/src/__tests__/conversation-store.test.ts +0 -18
  40. package/src/__tests__/conversation-surfaces-app-control.test.ts +15 -4
  41. package/src/__tests__/conversation-surfaces-data-persist.test.ts +404 -0
  42. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +2 -5
  43. package/src/__tests__/conversation-workspace-injection.test.ts +6 -0
  44. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +6 -0
  45. package/src/__tests__/credentials-cli.test.ts +7 -0
  46. package/src/__tests__/cu-unified-flow.test.ts +176 -10
  47. package/src/__tests__/date-context.test.ts +164 -2
  48. package/src/__tests__/disk-pressure-guard.test.ts +262 -0
  49. package/src/__tests__/disk-pressure-lifecycle.test.ts +168 -0
  50. package/src/__tests__/disk-pressure-policy.test.ts +241 -0
  51. package/src/__tests__/disk-pressure-routes.test.ts +379 -0
  52. package/src/__tests__/disk-pressure-tools.test.ts +277 -0
  53. package/src/__tests__/disk-usage.test.ts +150 -0
  54. package/src/__tests__/events-client-registration.test.ts +52 -0
  55. package/src/__tests__/events-dev-bypass-actor.test.ts +162 -0
  56. package/src/__tests__/file-write-tool.test.ts +4 -10
  57. package/src/__tests__/filing-service.test.ts +3 -4
  58. package/src/__tests__/heartbeat-disk-pressure.test.ts +183 -0
  59. package/src/__tests__/heartbeat-service.test.ts +260 -11
  60. package/src/__tests__/host-app-control-proxy.test.ts +195 -25
  61. package/src/__tests__/host-bash-proxy.test.ts +227 -34
  62. package/src/__tests__/host-bash-routes.test.ts +178 -13
  63. package/src/__tests__/host-cu-proxy.test.ts +210 -3
  64. package/src/__tests__/host-cu-routes-targeted.test.ts +141 -12
  65. package/src/__tests__/host-file-proxy-targeted.test.ts +48 -9
  66. package/src/__tests__/host-file-proxy.test.ts +268 -6
  67. package/src/__tests__/host-file-routes-targeted.test.ts +175 -17
  68. package/src/__tests__/host-transfer-proxy-targeted.test.ts +408 -59
  69. package/src/__tests__/host-transfer-routes-targeted.test.ts +232 -17
  70. package/src/__tests__/http-user-message-parity.test.ts +107 -1
  71. package/src/__tests__/injector-chain.test.ts +18 -6
  72. package/src/__tests__/injector-disk-pressure.test.ts +224 -0
  73. package/src/__tests__/managed-profile-guard.test.ts +18 -0
  74. package/src/__tests__/mcp-abort-signal.test.ts +130 -0
  75. package/src/__tests__/memory-admin-recall.test.ts +3 -11
  76. package/src/__tests__/memory-retrieval-pipeline.test.ts +22 -1
  77. package/src/__tests__/normalize-onboarding.test.ts +180 -0
  78. package/src/__tests__/oauth-connect-routes.test.ts +316 -0
  79. package/src/__tests__/oauth-provider-seed-logos.test.ts +24 -2
  80. package/src/__tests__/onboarding-persona-write.test.ts +308 -0
  81. package/src/__tests__/openai-provider.test.ts +45 -8
  82. package/src/__tests__/persist-onboarding-artifacts.test.ts +44 -64
  83. package/src/__tests__/platform-callback-registration.test.ts +21 -4
  84. package/src/__tests__/platform.test.ts +2 -1
  85. package/src/__tests__/playbook-execution.test.ts +0 -43
  86. package/src/__tests__/plugin-tool-contribution.test.ts +47 -0
  87. package/src/__tests__/prechat-onboarding-contract.test.ts +214 -27
  88. package/src/__tests__/provider-tool-name.test.ts +23 -0
  89. package/src/__tests__/relay-server.test.ts +15 -4
  90. package/src/__tests__/runtime-events-sse.test.ts +4 -8
  91. package/src/__tests__/scheduler-disk-pressure.test.ts +148 -0
  92. package/src/__tests__/secret-ingress-http.test.ts +0 -1
  93. package/src/__tests__/suggestion-routes.test.ts +46 -0
  94. package/src/__tests__/twilio-validation.test.ts +2 -2
  95. package/src/__tests__/workspace-migration-065-bump-stale-heartbeat-interval.test.ts +122 -0
  96. package/src/__tests__/workspace-migration-066-seed-heartbeat-callsite-cost-default.test.ts +285 -0
  97. package/src/__tests__/workspace-migration-068-release-notes-local-timezone.test.ts +90 -0
  98. package/src/__tests__/workspace-migration-safe-storage-limits-release.test.ts +90 -0
  99. package/src/approvals/guardian-decision-primitive.ts +13 -0
  100. package/src/approvals/guardian-request-resolvers.ts +16 -17
  101. package/src/backup/snapshot-lock.ts +2 -27
  102. package/src/bundler/compiler-tools.ts +3 -2
  103. package/src/calls/call-conversation-messages.ts +46 -10
  104. package/src/cli/commands/__tests__/webhooks.test.ts +0 -4
  105. package/src/cli/commands/bash.ts +35 -108
  106. package/src/cli/commands/contacts.ts +64 -25
  107. package/src/cli/commands/credentials.ts +56 -0
  108. package/src/cli/commands/memory-v2.ts +7 -6
  109. package/src/cli/commands/oauth/__tests__/connect.test.ts +437 -1
  110. package/src/cli/commands/oauth/connect.ts +127 -1
  111. package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +0 -3
  112. package/src/cli/commands/platform/__tests__/connect.test.ts +7 -1
  113. package/src/cli/commands/platform/__tests__/disconnect.test.ts +7 -1
  114. package/src/cli/commands/platform/__tests__/status.test.ts +103 -6
  115. package/src/cli/commands/platform/index.ts +16 -7
  116. package/src/cli/commands/status.ts +57 -0
  117. package/src/cli/program.ts +4 -2
  118. package/src/config/assistant-feature-flags.ts +13 -3
  119. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +4 -3
  120. package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +13 -7
  121. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +2 -2
  122. package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +2 -2
  123. package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +2 -2
  124. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +2 -2
  125. package/src/config/env.ts +0 -8
  126. package/src/config/feature-flag-registry.json +27 -3
  127. package/src/config/loader.ts +127 -8
  128. package/src/config/schemas/__tests__/memory-v2.test.ts +10 -5
  129. package/src/config/schemas/call-site-catalog.ts +14 -0
  130. package/src/config/schemas/channels.ts +0 -5
  131. package/src/config/schemas/heartbeat.ts +1 -1
  132. package/src/config/schemas/llm.ts +2 -0
  133. package/src/config/schemas/memory-lifecycle.ts +13 -0
  134. package/src/config/schemas/memory-v2.ts +75 -11
  135. package/src/config/schemas/platform.ts +43 -3
  136. package/src/config/schemas/services.ts +28 -0
  137. package/src/config/seed-inference-profiles.ts +230 -33
  138. package/src/contacts/contact-store.ts +0 -25
  139. package/src/daemon/__tests__/conversation-tool-setup.test.ts +86 -25
  140. package/src/daemon/assistant-attachments.ts +4 -4
  141. package/src/daemon/config-watcher.ts +85 -57
  142. package/src/daemon/conversation-agent-loop-handlers.ts +6 -0
  143. package/src/daemon/conversation-agent-loop.ts +170 -33
  144. package/src/daemon/conversation-error.ts +87 -15
  145. package/src/daemon/conversation-lifecycle.ts +1 -3
  146. package/src/daemon/conversation-process.ts +8 -0
  147. package/src/daemon/conversation-runtime-assembly.ts +26 -0
  148. package/src/daemon/conversation-store.ts +2 -2
  149. package/src/daemon/conversation-surfaces.ts +195 -15
  150. package/src/daemon/conversation-tool-setup.ts +57 -14
  151. package/src/daemon/conversation.ts +17 -22
  152. package/src/daemon/date-context.ts +71 -22
  153. package/src/daemon/disk-pressure-background-gate.ts +73 -0
  154. package/src/daemon/disk-pressure-guard.ts +343 -0
  155. package/src/daemon/disk-pressure-policy.ts +163 -0
  156. package/src/daemon/handlers/shared.ts +0 -1
  157. package/src/daemon/handlers/skills.ts +3 -4
  158. package/src/daemon/host-app-control-proxy.ts +137 -41
  159. package/src/daemon/host-bash-proxy.ts +46 -21
  160. package/src/daemon/host-cu-proxy.ts +49 -3
  161. package/src/daemon/host-file-proxy.ts +43 -7
  162. package/src/daemon/host-transfer-proxy.ts +95 -4
  163. package/src/daemon/lifecycle.ts +79 -28
  164. package/src/daemon/meet-host-supervisor.ts +4 -4
  165. package/src/daemon/meet-manifest-loader.ts +0 -1
  166. package/src/daemon/memory-v2-startup.ts +14 -4
  167. package/src/daemon/message-protocol.ts +3 -0
  168. package/src/daemon/message-types/conversations.ts +4 -0
  169. package/src/daemon/message-types/disk-pressure.ts +9 -0
  170. package/src/daemon/message-types/messages.ts +3 -0
  171. package/src/daemon/profiler-run-store.ts +5 -5
  172. package/src/daemon/tool-setup-types.ts +2 -2
  173. package/src/documents/document-store.ts +85 -0
  174. package/src/filing/filing-service.ts +30 -5
  175. package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +9 -16
  176. package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +36 -0
  177. package/src/heartbeat/heartbeat-run-store.ts +13 -0
  178. package/src/heartbeat/heartbeat-service.ts +205 -31
  179. package/src/home/feed-scheduler.ts +18 -0
  180. package/src/inbound/platform-callback-registration.ts +8 -15
  181. package/src/ipc/__tests__/clients-list-ipc.test.ts +169 -0
  182. package/src/ipc/assistant-server.ts +56 -2
  183. package/src/ipc/gateway-client.ts +37 -3
  184. package/src/live-voice/live-voice-archive.ts +4 -4
  185. package/src/live-voice/protocol.ts +5 -7
  186. package/src/media/image-service.ts +1 -7
  187. package/src/memory/__tests__/fixtures/memory-v2-activation-fixtures.ts +21 -13
  188. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +52 -22
  189. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +0 -6
  190. package/src/memory/__tests__/memory-v2-concept-frequency.test.ts +272 -0
  191. package/src/memory/admin.ts +5 -9
  192. package/src/memory/context-search/agent-runner.ts +19 -2
  193. package/src/memory/context-search/sources/conversations.ts +2 -11
  194. package/src/memory/context-search/sources/memory-v2.ts +5 -4
  195. package/src/memory/context-search/sources/memory.ts +0 -1
  196. package/src/memory/context-search/types.ts +0 -1
  197. package/src/memory/conversation-crud.ts +4 -12
  198. package/src/memory/db-init.ts +2 -0
  199. package/src/memory/embedding-runtime-manager.ts +119 -5
  200. package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +32 -21
  201. package/src/memory/graph/conversation-graph-memory.ts +42 -54
  202. package/src/memory/graph/extraction.ts +1 -3
  203. package/src/memory/graph/graph-search.test.ts +10 -67
  204. package/src/memory/graph/graph-search.ts +1 -20
  205. package/src/memory/graph/retriever.test.ts +6 -0
  206. package/src/memory/graph/retriever.ts +6 -10
  207. package/src/memory/indexer.ts +54 -45
  208. package/src/memory/job-handlers/backfill.ts +2 -11
  209. package/src/memory/job-handlers/cleanup.ts +43 -0
  210. package/src/memory/job-handlers/embedding.ts +6 -8
  211. package/src/memory/job-handlers/summarization.ts +2 -7
  212. package/src/memory/jobs-store.ts +48 -0
  213. package/src/memory/jobs-worker.ts +81 -43
  214. package/src/memory/memory-v2-activation-log-store.ts +32 -14
  215. package/src/memory/memory-v2-concept-frequency.ts +169 -0
  216. package/src/memory/migrations/239-trace-events-created-at-index.ts +18 -0
  217. package/src/memory/migrations/index.ts +1 -0
  218. package/src/memory/pkb/pkb-search.test.ts +6 -0
  219. package/src/memory/qdrant-client.ts +0 -13
  220. package/src/memory/rerank-local.ts +374 -0
  221. package/src/memory/search/semantic.ts +6 -67
  222. package/src/memory/trace-event-store.ts +1 -17
  223. package/src/memory/v2/__tests__/activation.test.ts +311 -250
  224. package/src/memory/v2/__tests__/consolidation-job.test.ts +40 -8
  225. package/src/memory/v2/__tests__/injection.test.ts +157 -167
  226. package/src/memory/v2/__tests__/prompts-consolidation.test.ts +61 -2
  227. package/src/memory/v2/__tests__/qdrant.test.ts +16 -0
  228. package/src/memory/v2/__tests__/reranker.test.ts +338 -0
  229. package/src/memory/v2/__tests__/sim.test.ts +5 -199
  230. package/src/memory/v2/__tests__/skill-store.test.ts +71 -65
  231. package/src/memory/v2/__tests__/static-context.test.ts +76 -1
  232. package/src/memory/v2/activation.ts +149 -156
  233. package/src/memory/v2/consolidation-job.ts +62 -12
  234. package/src/memory/v2/injection.ts +47 -60
  235. package/src/memory/v2/prompts/consolidation.ts +36 -1
  236. package/src/memory/v2/qdrant.ts +99 -0
  237. package/src/memory/v2/reranker.ts +177 -0
  238. package/src/memory/v2/sim.ts +10 -84
  239. package/src/memory/v2/skill-content.ts +4 -3
  240. package/src/memory/v2/skill-store.ts +82 -59
  241. package/src/memory/v2/static-context.ts +22 -0
  242. package/src/memory/v2/types.ts +10 -10
  243. package/src/notifications/copy-composer.ts +13 -0
  244. package/src/notifications/signal.ts +4 -0
  245. package/src/oauth/AGENTS.md +3 -1
  246. package/src/oauth/__tests__/oauth-connect-state.test.ts +137 -0
  247. package/src/oauth/connect-orchestrator.ts +2 -0
  248. package/src/oauth/connection-resolver.test.ts +66 -1
  249. package/src/oauth/connection-resolver.ts +55 -1
  250. package/src/oauth/oauth-connect-state.ts +77 -0
  251. package/src/oauth/seed-providers.ts +58 -1
  252. package/src/plugins/defaults/injectors.ts +35 -2
  253. package/src/plugins/defaults/memory-retrieval.ts +5 -6
  254. package/src/plugins/types.ts +7 -0
  255. package/src/proactive-artifact/aux-message-injector.ts +74 -0
  256. package/src/proactive-artifact/decision.test.ts +226 -0
  257. package/src/proactive-artifact/decision.ts +165 -0
  258. package/src/proactive-artifact/index.ts +7 -0
  259. package/src/proactive-artifact/job.test.ts +867 -0
  260. package/src/proactive-artifact/job.ts +352 -0
  261. package/src/proactive-artifact/message-copy.ts +41 -0
  262. package/src/proactive-artifact/trigger-state.test.ts +277 -0
  263. package/src/proactive-artifact/trigger-state.ts +119 -0
  264. package/src/prompts/normalize-onboarding.ts +80 -0
  265. package/src/prompts/persona-resolver.ts +101 -9
  266. package/src/prompts/system-prompt.ts +21 -7
  267. package/src/prompts/templates/BOOTSTRAP.md +13 -5
  268. package/src/providers/__tests__/retry-callsite.test.ts +222 -1
  269. package/src/providers/model-intents.ts +7 -0
  270. package/src/providers/openrouter/client.ts +8 -0
  271. package/src/providers/retry.ts +50 -0
  272. package/src/providers/types.ts +1 -0
  273. package/src/runtime/__tests__/agent-wake.test.ts +456 -3
  274. package/src/runtime/agent-wake.ts +238 -100
  275. package/src/runtime/assistant-event-hub.ts +36 -6
  276. package/src/runtime/assistant-event.ts +0 -1
  277. package/src/runtime/auth/__tests__/route-policy.test.ts +64 -0
  278. package/src/runtime/auth/route-policy.ts +14 -1
  279. package/src/runtime/auth/same-actor.ts +216 -0
  280. package/src/runtime/channel-retry-sweep.ts +65 -1
  281. package/src/runtime/guardian-reply-router.ts +10 -0
  282. package/src/runtime/local-actor-identity.ts +52 -11
  283. package/src/runtime/pending-interactions.ts +8 -0
  284. package/src/runtime/routes/__tests__/client-routes.test.ts +155 -0
  285. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +0 -5
  286. package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +1 -1
  287. package/src/runtime/routes/client-routes.ts +20 -2
  288. package/src/runtime/routes/contact-routes.ts +0 -25
  289. package/src/runtime/routes/conversation-routes.ts +35 -26
  290. package/src/runtime/routes/debug-bash-routes.ts +163 -0
  291. package/src/runtime/routes/disk-pressure-routes.ts +121 -0
  292. package/src/runtime/routes/document-pdf-renderer.ts +6 -2
  293. package/src/runtime/routes/documents-routes.ts +2 -75
  294. package/src/runtime/routes/events-routes.ts +41 -9
  295. package/src/runtime/routes/host-bash-routes.ts +23 -3
  296. package/src/runtime/routes/host-cu-routes.ts +33 -6
  297. package/src/runtime/routes/host-file-routes.ts +32 -6
  298. package/src/runtime/routes/host-transfer-routes.ts +79 -16
  299. package/src/runtime/routes/identity-routes.ts +7 -138
  300. package/src/runtime/routes/inbound-message-handler.ts +77 -12
  301. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +3 -0
  302. package/src/runtime/routes/index.ts +6 -0
  303. package/src/runtime/routes/memory-item-routes.test.ts +41 -15
  304. package/src/runtime/routes/memory-v2-routes.ts +33 -0
  305. package/src/runtime/routes/oauth-connect-routes.ts +153 -0
  306. package/src/runtime/verification-outbound-actions.ts +4 -4
  307. package/src/schedule/run-script.ts +37 -5
  308. package/src/schedule/scheduler.ts +20 -1
  309. package/src/security/encrypted-store.ts +2 -0
  310. package/src/security/secure-keys.ts +55 -0
  311. package/src/skills/remote-skill-policy.ts +4 -10
  312. package/src/subagent/index.ts +1 -7
  313. package/src/subagent/manager.ts +1 -15
  314. package/src/tasks/task-runner.ts +0 -1
  315. package/src/tasks/task-store.ts +0 -3
  316. package/src/tools/background-tool-registry.ts +17 -3
  317. package/src/tools/host-filesystem/edit.test.ts +151 -0
  318. package/src/tools/host-filesystem/edit.ts +43 -1
  319. package/src/tools/host-filesystem/read.test.ts +129 -0
  320. package/src/tools/host-filesystem/read.ts +43 -1
  321. package/src/tools/host-filesystem/transfer.test.ts +127 -2
  322. package/src/tools/host-filesystem/transfer.ts +56 -11
  323. package/src/tools/host-filesystem/write.test.ts +134 -0
  324. package/src/tools/host-filesystem/write.ts +43 -1
  325. package/src/tools/host-terminal/host-shell.ts +13 -6
  326. package/src/tools/mcp/mcp-tool-factory.ts +2 -1
  327. package/src/tools/memory/register.test.ts +12 -9
  328. package/src/tools/memory/register.ts +1 -2
  329. package/src/tools/provider-tool-name.ts +28 -0
  330. package/src/tools/registry.ts +30 -9
  331. package/src/tools/terminal/shell.ts +9 -1
  332. package/src/tools/tool-approval-handler.ts +31 -6
  333. package/src/tools/types.ts +24 -2
  334. package/src/tts/provider-catalog.ts +3 -5
  335. package/src/util/disk-usage.ts +138 -0
  336. package/src/util/platform.ts +21 -11
  337. package/src/util/process-liveness.ts +26 -0
  338. package/src/workspace/heartbeat-service.ts +19 -0
  339. package/src/workspace/migrations/065-bump-stale-heartbeat-interval.ts +60 -0
  340. package/src/workspace/migrations/066-seed-heartbeat-callsite-cost-default.ts +146 -0
  341. package/src/workspace/migrations/067-release-notes-safe-storage-limits.ts +72 -0
  342. package/src/workspace/migrations/068-release-notes-local-timezone.ts +65 -0
  343. package/src/workspace/migrations/registry.ts +8 -0
  344. package/src/__tests__/conversation-tool-setup-memory-scope.test.ts +0 -167
  345. package/src/memory/v2/__tests__/skill-qdrant.test.ts +0 -657
  346. package/src/memory/v2/skill-qdrant.ts +0 -404
  347. package/src/signals/bash.ts +0 -198
@@ -30,12 +30,13 @@ import {
30
30
  ACTIVITY_SKIP_SET,
31
31
  injectActivityField,
32
32
  } from "../tools/schema-transforms.js";
33
- import type {
34
- ProxyApprovalCallback,
35
- ProxyApprovalRequest,
36
- ToolContext,
37
- ToolExecutionResult,
38
- ToolLifecycleEventHandler,
33
+ import {
34
+ isDiskPressureCleanupToolName,
35
+ type ProxyApprovalCallback,
36
+ type ProxyApprovalRequest,
37
+ type ToolContext,
38
+ type ToolExecutionResult,
39
+ type ToolLifecycleEventHandler,
39
40
  } from "../tools/types.js";
40
41
  import { allUiSurfaceTools } from "../tools/ui-surface/definitions.js";
41
42
  import { getLogger } from "../util/logger.js";
@@ -135,6 +136,7 @@ export function createToolExecutor(
135
136
  taskRunId: ctx.taskRunId,
136
137
  trustClass: resolveTrustClass(ctx.trustContext),
137
138
  executionChannel: ctx.trustContext?.sourceChannel,
139
+ sourceActorPrincipalId: ctx.trustContext?.guardianPrincipalId,
138
140
  callSessionId: ctx.callSessionId,
139
141
  triggeredBySurfaceAction:
140
142
  ctx.surfaceActionRequestIds?.has(ctx.currentRequestId ?? "") ?? false,
@@ -151,7 +153,7 @@ export function createToolExecutor(
151
153
  onOutput,
152
154
  signal: ctx.abortController?.signal,
153
155
  allowedToolNames: ctx.allowedToolNames,
154
- memoryScopeId: ctx.memoryPolicy.scopeId,
156
+ diskPressureCleanupModeActive: ctx.diskPressureCleanupModeActive,
155
157
  toolUseId,
156
158
  isPlatformHosted: getIsPlatform(),
157
159
  cesClient: ctx.cesClient,
@@ -305,6 +307,8 @@ export interface SkillProjectionContext {
305
307
  readonly hasNoClient?: boolean;
306
308
  /** When set, only tools in this set are included in the resolved tool list (subagent delegation). */
307
309
  subagentAllowedTools?: Set<string>;
310
+ /** True when the current turn is restricted to disk-pressure cleanup-safe tools. */
311
+ diskPressureCleanupModeActive?: boolean;
308
312
  /** True when this conversation belongs to a subagent spawned by SubagentManager. */
309
313
  readonly isSubagent?: boolean;
310
314
  /**
@@ -351,6 +355,29 @@ export const HOST_TOOL_TO_CAPABILITY = new Map<string, HostProxyCapability>([
351
355
  // Derived from HOST_TOOL_TO_CAPABILITY so the invariant "every host tool has
352
356
  // a capability mapping" is a structural fact — no runtime assertion needed.
353
357
  export const HOST_TOOL_NAMES = new Set(HOST_TOOL_TO_CAPABILITY.keys());
358
+ /**
359
+ * Capabilities eligible for cross-client exposure on non-host-proxy
360
+ * transports (e.g. web, ios routing to a connected macOS client).
361
+ * Adding a capability here exposes ALL tools that map to it (per
362
+ * HOST_TOOL_TO_CAPABILITY) on non-host-proxy transports — the daemon then
363
+ * routes the actual invocation to the connected capable client via the
364
+ * proxy's targetClientId path.
365
+ *
366
+ * Inclusions:
367
+ * - host_bash (Phase 1, PR #29322)
368
+ * - host_file (Phases 2 & 3, PRs #29398 + #29440)
369
+ *
370
+ * Exclusions:
371
+ * - host_browser: chrome-extension is its own executor; web turns don't
372
+ * have a CDP target model. Re-evaluate when host browser via macOS
373
+ * host proxy ships (PR #27489).
374
+ * - host_app_control, host_cu: not in HOST_TOOL_TO_CAPABILITY
375
+ * (skill-routed).
376
+ */
377
+ const CROSS_CLIENT_EXPOSED_CAPABILITIES = new Set<HostProxyCapability>([
378
+ "host_bash",
379
+ "host_file",
380
+ ]);
354
381
  const CLIENT_CAPABILITY_TOOL_NAMES = new Set(["app_open"]);
355
382
  const PLATFORM_TOOL_NAMES = new Set(["request_system_permission"]);
356
383
 
@@ -385,16 +412,22 @@ export function isToolActiveForContext(
385
412
  // Per-capability check is authoritative for structural support: if the
386
413
  // transport cannot service this capability, the tool is filtered out.
387
414
  if (transport && capability && !supportsHostProxy(transport, capability)) {
388
- // Cross-client exception: allow host_bash for non-host-proxy interfaces when
389
- // at least one capable client is connected via the event hub.
390
- // Only applies to host_bash (not host_file, host_cu, host_browser Phase 2).
391
- // Excludes chrome-extension (security boundary: extension only gets host_browser)
392
- // and hasNoClient turns (no interactive approval UI available).
415
+ // Cross-client exception: allow host tools whose capabilities have
416
+ // cross-client routing infrastructure (Phases 1–3) to be exposed for
417
+ // non-host-proxy transports (e.g. "web", "ios") when at least one
418
+ // capable client is connected via the event hub. Members of
419
+ // CROSS_CLIENT_EXPOSED_CAPABILITIES (host_bash, host_file) qualify;
420
+ // host_browser is intentionally excluded (chrome-extension is its
421
+ // own executor and web turns don't have a CDP target model).
422
+ // chrome-extension transport is excluded as a security boundary
423
+ // (extension only gets host_browser); hasNoClient turns are excluded
424
+ // (no interactive approval UI available).
393
425
  if (
394
- capability === "host_bash" &&
426
+ capability &&
427
+ CROSS_CLIENT_EXPOSED_CAPABILITIES.has(capability) &&
395
428
  transport !== "chrome-extension" &&
396
429
  !ctx.hasNoClient &&
397
- assistantEventHub.listClientsByCapability("host_bash").length > 0
430
+ assistantEventHub.listClientsByCapability(capability).length > 0
398
431
  ) {
399
432
  return true;
400
433
  }
@@ -516,6 +549,16 @@ export function createResolveToolsCallback(
516
549
  }
517
550
  turnAllowed.add(name);
518
551
  }
552
+ if (ctx.diskPressureCleanupModeActive === true) {
553
+ const cleanupDefs = allBaseDefs.filter((d) =>
554
+ isDiskPressureCleanupToolName(d.name),
555
+ );
556
+ ctx.allowedToolNames = new Set(
557
+ Array.from(turnAllowed).filter(isDiskPressureCleanupToolName),
558
+ );
559
+ return injectActivityField(cleanupDefs, ACTIVITY_SKIP_SET);
560
+ }
561
+
519
562
  ctx.allowedToolNames = turnAllowed;
520
563
  return injectActivityField(allBaseDefs, ACTIVITY_SKIP_SET);
521
564
  };
@@ -106,6 +106,7 @@ import {
106
106
  import type { SkillProjectionCache } from "./conversation-skill-tools.js";
107
107
  import {
108
108
  createSurfaceMutex,
109
+ flushPendingSurfaceDataPersists,
109
110
  handleSurfaceAction as handleSurfaceActionImpl,
110
111
  handleSurfaceUndo as handleSurfaceUndoImpl,
111
112
  type SurfaceActionResult,
@@ -117,6 +118,7 @@ import {
117
118
  createToolExecutor,
118
119
  } from "./conversation-tool-setup.js";
119
120
  import { refreshWorkspaceTopLevelContextIfNeeded as refreshWorkspaceImpl } from "./conversation-workspace.js";
121
+ import { canonicalizeTimeZone } from "./date-context.js";
120
122
  import type { HostAppControlProxy } from "./host-app-control-proxy.js";
121
123
  import { HostCuProxy } from "./host-cu-proxy.js";
122
124
  import type {
@@ -136,17 +138,6 @@ import { TraceEmitter } from "./trace-emitter.js";
136
138
 
137
139
  const log = getLogger("conversation");
138
140
 
139
- export interface ConversationMemoryPolicy {
140
- scopeId: string;
141
- includeDefaultFallback: boolean;
142
- }
143
-
144
- export const DEFAULT_MEMORY_POLICY: Readonly<ConversationMemoryPolicy> =
145
- Object.freeze({
146
- scopeId: "default",
147
- includeDefaultFallback: false,
148
- });
149
-
150
141
  export { findLastUndoableUserMessageIndex } from "./conversation-history.js";
151
142
  export type {
152
143
  QueueDrainReason,
@@ -170,6 +161,7 @@ export class Conversation {
170
161
  /** @internal */ eventBus = new EventBus<AssistantDomainEvents>();
171
162
  /** @internal */ workingDir: string;
172
163
  /** @internal */ allowedToolNames?: Set<string>;
164
+ /** @internal */ diskPressureCleanupModeActive?: boolean;
173
165
  /** @internal */ toolsDisabledDepth = 0;
174
166
  /** @internal */ preactivatedSkillIds?: string[];
175
167
  /** @internal */ subagentAllowedTools?: Set<string>;
@@ -318,12 +310,11 @@ export class Conversation {
318
310
  * @internal
319
311
  */
320
312
  hostUsername?: string;
313
+ /** @internal */ clientTimezone?: string;
321
314
  public readonly traceEmitter: TraceEmitter;
322
315
  /** @internal */ hasSystemPromptOverride: boolean;
323
- public memoryPolicy: ConversationMemoryPolicy;
324
316
  /** @internal */ readonly graphMemory: ConversationGraphMemory;
325
317
  /** @internal */ activeContextNodeIds?: string[];
326
- /** @internal */ memoryScopeId?: string;
327
318
  /** @internal */ streamThinking: boolean;
328
319
  /** @internal */ turnCount = 0;
329
320
  public lastAssistantAttachments: AssistantAttachmentDraft[] = [];
@@ -358,7 +349,6 @@ export class Conversation {
358
349
  maxTokens: number | undefined,
359
350
  sendToClient: (msg: ServerMessage) => void,
360
351
  workingDir: string,
361
- memoryPolicy?: ConversationMemoryPolicy,
362
352
  sharedCesClient?: CesClient,
363
353
  speedOverride?: Speed,
364
354
  cacheTtl?: "5m" | "1h",
@@ -369,13 +359,7 @@ export class Conversation {
369
359
  this.provider = provider;
370
360
  this.workingDir = workingDir;
371
361
  this.sendToClient = sendToClient;
372
- this.memoryPolicy = memoryPolicy
373
- ? { ...memoryPolicy }
374
- : { ...DEFAULT_MEMORY_POLICY };
375
- this.graphMemory = new ConversationGraphMemory(
376
- this.memoryPolicy.scopeId,
377
- conversationId,
378
- );
362
+ this.graphMemory = new ConversationGraphMemory(conversationId);
379
363
  this.traceEmitter = new TraceEmitter(conversationId, sendToClient);
380
364
  this.prompter = new PermissionPrompter(sendToClient);
381
365
  this.prompter.setOnStateChanged((requestId, state, source, toolUseId) => {
@@ -764,6 +748,11 @@ export class Conversation {
764
748
  clearTimeout(timer);
765
749
  }
766
750
  this.recentlyCompletedStandaloneSurfaces.clear();
751
+ // Flush any pending debounced surface-data persists for this
752
+ // conversation so updates that arrived inside the debounce window
753
+ // still land in the DB before teardown. Flushing also clears the
754
+ // pending entries, so no separate cancel call is needed.
755
+ flushPendingSurfaceDataPersists(this.conversationId);
767
756
  // Only dispose the per-conversation CU and app-control proxies.
768
757
  // Bash/File/Transfer are singletons — their lifecycle is managed by
769
758
  // static disposeInstance().
@@ -774,7 +763,6 @@ export class Conversation {
774
763
  // Do NOT close it here; the server manages the CES lifecycle.
775
764
  this.cesClient = undefined;
776
765
  this.activeContextNodeIds = this.graphMemory.tracker.getActiveNodeIds();
777
- this.memoryScopeId = this.memoryPolicy.scopeId;
778
766
  this.graphMemory.persistState();
779
767
  disposeConversation(this);
780
768
  }
@@ -1144,6 +1132,13 @@ export class Conversation {
1144
1132
  }
1145
1133
  }
1146
1134
 
1135
+ applyClientTimezoneFromTransport(
1136
+ transport: ConversationTransportMetadata,
1137
+ ): void {
1138
+ this.clientTimezone =
1139
+ canonicalizeTimeZone(transport.clientTimezone) ?? undefined;
1140
+ }
1141
+
1147
1142
  setAssistantId(assistantId: string | null): void {
1148
1143
  this.assistantId = assistantId ?? undefined;
1149
1144
  }
@@ -14,10 +14,31 @@ export interface TemporalContextOptions {
14
14
  hostTimeZone?: string;
15
15
  /** IANA timezone configured in user settings (if available). */
16
16
  configuredUserTimeZone?: string | null;
17
- /** IANA timezone inferred from user profile/memory (if available). */
17
+ /** IANA timezone reported by the active client for the current turn. */
18
+ clientTimezone?: string | null;
19
+ /** IANA timezone persisted from prior client environment detection. */
20
+ detectedTimezone?: string | null;
21
+ /** Profile timezone candidate accepted by legacy callers; not used for turn resolution. */
18
22
  userTimeZone?: string | null;
19
23
  }
20
24
 
25
+ export type TurnTimezoneSource =
26
+ | "timeZone"
27
+ | "configuredUserTimezone"
28
+ | "clientTimezone"
29
+ | "detectedTimezone"
30
+ | "hostTimezone"
31
+ | "utcFallback";
32
+
33
+ export interface TurnTimezoneContext {
34
+ configuredUserTimezone: string | null;
35
+ clientTimezone: string | null;
36
+ detectedTimezone: string | null;
37
+ hostTimezone: string | null;
38
+ effectiveTimezone: string;
39
+ source: TurnTimezoneSource;
40
+ }
41
+
21
42
  const WEEKDAY_LONG = [
22
43
  "Sunday",
23
44
  "Monday",
@@ -86,7 +107,12 @@ function canonicalizeUtcGmtOffsetToken(offsetToken: string): string | null {
86
107
  ).padStart(2, "0")}`;
87
108
  }
88
109
 
89
- function canonicalizeTimeZone(timeZone: string): string | null {
110
+ export function canonicalizeTimeZone(
111
+ timeZone: string | null | undefined,
112
+ ): string | null {
113
+ if (timeZone == null) {
114
+ return null;
115
+ }
90
116
  const trimmed = timeZone.trim();
91
117
  if (trimmed.length === 0) {
92
118
  return null;
@@ -121,6 +147,17 @@ function canonicalizeTimeZone(timeZone: string): string | null {
121
147
  }
122
148
  }
123
149
 
150
+ function firstResolvedTimezone(
151
+ candidates: Array<[TurnTimezoneSource, string | null]>,
152
+ ): { source: TurnTimezoneSource; timeZone: string } | null {
153
+ for (const [source, timeZone] of candidates) {
154
+ if (timeZone) {
155
+ return { source, timeZone };
156
+ }
157
+ }
158
+ return null;
159
+ }
160
+
124
161
  /**
125
162
  * Common timezone abbreviation → IANA identifier mapping.
126
163
  * Used as a fallback when `Intl.DateTimeFormat` does not recognize the abbreviation.
@@ -289,11 +326,41 @@ function formatLocalDate(date: Date, timeZone: string): string {
289
326
  ).padStart(2, "0")}`;
290
327
  }
291
328
 
329
+ export function resolveTurnTimezoneContext(
330
+ options: TemporalContextOptions = {},
331
+ ): TurnTimezoneContext {
332
+ const configuredUserTimezone = canonicalizeTimeZone(
333
+ options.configuredUserTimeZone,
334
+ );
335
+ const clientTimezone = canonicalizeTimeZone(options.clientTimezone);
336
+ const detectedTimezone = canonicalizeTimeZone(options.detectedTimezone);
337
+ const hostTimezone = canonicalizeTimeZone(
338
+ options.hostTimeZone ?? Intl.DateTimeFormat().resolvedOptions().timeZone,
339
+ );
340
+ const explicitTimezone = canonicalizeTimeZone(options.timeZone);
341
+ const selected = firstResolvedTimezone([
342
+ ["timeZone", explicitTimezone],
343
+ ["configuredUserTimezone", configuredUserTimezone],
344
+ ["clientTimezone", clientTimezone],
345
+ ["detectedTimezone", detectedTimezone],
346
+ ["hostTimezone", hostTimezone],
347
+ ]);
348
+
349
+ return {
350
+ configuredUserTimezone,
351
+ clientTimezone,
352
+ detectedTimezone,
353
+ hostTimezone,
354
+ effectiveTimezone: selected?.timeZone ?? "UTC",
355
+ source: selected?.source ?? "utcFallback",
356
+ };
357
+ }
358
+
292
359
  /**
293
360
  * Format time as HH:MM:SS with UTC offset and timezone name.
294
361
  *
295
362
  * Uses the timezone resolution cascade:
296
- * explicit override → configured user tz → profile user tz → host fallback.
363
+ * explicit override → configured user tz → client tz → detected tz → host fallback.
297
364
  *
298
365
  * Returns format: `2026-04-02 (Thursday) 01:52:33 -05:00 (America/Chicago)`
299
366
  */
@@ -301,24 +368,7 @@ export function formatTurnTimestamp(
301
368
  options: TemporalContextOptions = {},
302
369
  ): string {
303
370
  const now = new Date(options.nowMs ?? Date.now());
304
- const resolvedHostTimeZone =
305
- canonicalizeTimeZone(
306
- options.hostTimeZone ?? Intl.DateTimeFormat().resolvedOptions().timeZone,
307
- ) ?? "UTC";
308
- const resolvedConfiguredUserTimeZone = options.configuredUserTimeZone
309
- ? canonicalizeTimeZone(options.configuredUserTimeZone)
310
- : null;
311
- const resolvedUserTimeZone = options.userTimeZone
312
- ? canonicalizeTimeZone(options.userTimeZone)
313
- : null;
314
- const resolvedTimeZone = options.timeZone
315
- ? canonicalizeTimeZone(options.timeZone)
316
- : null;
317
- const timeZone =
318
- resolvedTimeZone ??
319
- resolvedConfiguredUserTimeZone ??
320
- resolvedUserTimeZone ??
321
- resolvedHostTimeZone;
371
+ const timeZone = resolveTurnTimezoneContext(options).effectiveTimezone;
322
372
 
323
373
  const dateStr = formatLocalDate(now, timeZone);
324
374
  const todayParts = localDateParts(now, timeZone);
@@ -341,4 +391,3 @@ export function formatTurnTimestamp(
341
391
 
342
392
  return `${dateStr} (${dayName}) ${hour}:${minute}:${second} ${offset} (${timeZone})`;
343
393
  }
344
-
@@ -0,0 +1,73 @@
1
+ import {
2
+ type DiskPressureBlockedCapability,
3
+ type DiskPressureStatus,
4
+ getDiskPressureStatus,
5
+ } from "./disk-pressure-guard.js";
6
+
7
+ export type DiskPressureBackgroundGateDecision =
8
+ | { action: "allow"; status: DiskPressureStatus }
9
+ | {
10
+ action: "skip";
11
+ reason: "disk_pressure";
12
+ status: DiskPressureStatus;
13
+ blockedCapability: DiskPressureBlockedCapability;
14
+ };
15
+
16
+ export const DISK_PRESSURE_BACKGROUND_LOG_THROTTLE_MS = 60_000;
17
+
18
+ const lastSkipLogAtByKey = new Map<string, number>();
19
+
20
+ export function checkDiskPressureBackgroundGate(
21
+ blockedCapability: DiskPressureBlockedCapability = "background-work",
22
+ ): DiskPressureBackgroundGateDecision {
23
+ const status = getDiskPressureStatus();
24
+ if (!status.enabled || !status.locked || status.overrideActive) {
25
+ return { action: "allow", status };
26
+ }
27
+ if (!status.effectivelyLocked) {
28
+ return { action: "allow", status };
29
+ }
30
+ return {
31
+ action: "skip",
32
+ reason: "disk_pressure",
33
+ status,
34
+ blockedCapability,
35
+ };
36
+ }
37
+
38
+ export function shouldLogDiskPressureBackgroundSkip(
39
+ key: string,
40
+ nowMs = Date.now(),
41
+ ): boolean {
42
+ const lastLoggedAt = lastSkipLogAtByKey.get(key) ?? 0;
43
+ if (nowMs - lastLoggedAt < DISK_PRESSURE_BACKGROUND_LOG_THROTTLE_MS) {
44
+ return false;
45
+ }
46
+ lastSkipLogAtByKey.set(key, nowMs);
47
+ return true;
48
+ }
49
+
50
+ export function diskPressureBackgroundSkipLogFields(
51
+ decision: Extract<DiskPressureBackgroundGateDecision, { action: "skip" }>,
52
+ ): {
53
+ reason: "disk_pressure";
54
+ thresholdPercent: number;
55
+ usagePercent: number | null;
56
+ blockedCapability: DiskPressureBlockedCapability;
57
+ lockId: string | null;
58
+ path: string | null;
59
+ } {
60
+ return {
61
+ reason: decision.reason,
62
+ thresholdPercent: decision.status.thresholdPercent,
63
+ usagePercent: decision.status.usagePercent,
64
+ blockedCapability: decision.blockedCapability,
65
+ lockId: decision.status.lockId,
66
+ path: decision.status.path,
67
+ };
68
+ }
69
+
70
+ /** @internal */
71
+ export function __resetDiskPressureBackgroundGateForTests(): void {
72
+ lastSkipLogAtByKey.clear();
73
+ }