@vellumai/assistant 0.8.10 → 0.8.11-staging.1

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 (400) hide show
  1. package/bun.lock +62 -1
  2. package/docs/workspace-tools.md +196 -0
  3. package/examples/plugins/echo/README.md +3 -3
  4. package/knip.json +1 -0
  5. package/openapi.yaml +460 -128
  6. package/package.json +2 -1
  7. package/scripts/build-plugin-api.ts +299 -0
  8. package/src/__tests__/agent-loop-callsite-precedence.test.ts +7 -0
  9. package/src/__tests__/agent-loop-compaction-events.test.ts +197 -0
  10. package/src/__tests__/agent-loop-exit-reason.test.ts +93 -96
  11. package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +2 -0
  12. package/src/__tests__/agent-loop-output-hooks.test.ts +274 -1
  13. package/src/__tests__/agent-loop-override-profile.test.ts +3 -0
  14. package/src/__tests__/agent-loop-provider-error-recording.test.ts +4 -0
  15. package/src/__tests__/agent-loop-thinking.test.ts +4 -0
  16. package/src/__tests__/agent-loop.test.ts +578 -5
  17. package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +0 -1
  18. package/src/__tests__/approval-cascade.test.ts +1 -0
  19. package/src/__tests__/background-workers-disk-pressure.test.ts +0 -2
  20. package/src/__tests__/btw-routes.test.ts +0 -1
  21. package/src/__tests__/build-persisted-content.test.ts +75 -1
  22. package/src/__tests__/catalog-install-normalize.test.ts +141 -0
  23. package/src/__tests__/ces-startup-timeout.test.ts +60 -0
  24. package/src/__tests__/compaction-events.test.ts +1 -0
  25. package/src/__tests__/config-managed-gemini-defaults.test.ts +2 -46
  26. package/src/__tests__/context-overflow-reducer.test.ts +264 -124
  27. package/src/__tests__/context-window-manager-overflow-rung.test.ts +351 -0
  28. package/src/__tests__/conversation-abort-tool-results.test.ts +1 -1
  29. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +13 -5
  30. package/src/__tests__/conversation-agent-loop-overflow.test.ts +284 -455
  31. package/src/__tests__/conversation-agent-loop.test.ts +131 -551
  32. package/src/__tests__/conversation-app-control-instantiation.test.ts +13 -0
  33. package/src/__tests__/conversation-confirmation-signals.test.ts +1 -0
  34. package/src/__tests__/conversation-fork-crud.test.ts +259 -0
  35. package/src/__tests__/conversation-history-web-search.test.ts +1 -1
  36. package/src/__tests__/conversation-lifecycle.test.ts +257 -1
  37. package/src/__tests__/conversation-process-callsite.test.ts +1 -0
  38. package/src/__tests__/conversation-provider-retry-repair.test.ts +38 -377
  39. package/src/__tests__/conversation-queue.test.ts +1 -39
  40. package/src/__tests__/conversation-runtime-assembly.test.ts +119 -8
  41. package/src/__tests__/conversation-skill-tools.test.ts +491 -5
  42. package/src/__tests__/conversation-slash-queue.test.ts +1 -1
  43. package/src/__tests__/conversation-slash-unknown.test.ts +1 -0
  44. package/src/__tests__/conversation-speed-override.test.ts +1 -0
  45. package/src/__tests__/conversation-store.test.ts +74 -0
  46. package/src/__tests__/conversation-surfaces-app-control.test.ts +4 -1
  47. package/src/__tests__/conversation-tool-setup-attribution.test.ts +323 -0
  48. package/src/__tests__/conversation-tool-setup-tools-disabled.test.ts +34 -0
  49. package/src/__tests__/conversation-workspace-cache-state.test.ts +1 -0
  50. package/src/__tests__/conversation-workspace-injection.test.ts +1 -1
  51. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +1 -0
  52. package/src/__tests__/corrected-target.test.ts +93 -0
  53. package/src/__tests__/credential-execution-feature-gates.test.ts +3 -5
  54. package/src/__tests__/credential-execution-tools.test.ts +23 -11
  55. package/src/__tests__/credential-security-invariants.test.ts +6 -1
  56. package/src/__tests__/db-schedule-syntax-migration.test.ts +80 -0
  57. package/src/__tests__/device-id.test.ts +70 -1
  58. package/src/__tests__/embedding-managed-proxy-selection.test.ts +6 -40
  59. package/src/__tests__/empty-response-hook.test.ts +242 -66
  60. package/src/__tests__/external-plugin-loader.test.ts +0 -31
  61. package/src/__tests__/get-skill-detail-audit.test.ts +43 -1
  62. package/src/__tests__/guardian-routing-invariants.test.ts +91 -0
  63. package/src/__tests__/history-repair-hook.test.ts +228 -3
  64. package/src/__tests__/host-app-control-proxy.test.ts +45 -0
  65. package/src/__tests__/host-browser-proxy.test.ts +254 -9
  66. package/src/__tests__/identity-routes.test.ts +1 -0
  67. package/src/__tests__/image-recovery-hook.test.ts +387 -0
  68. package/src/__tests__/injector-chain.test.ts +5 -4
  69. package/src/__tests__/injector-v3-suppression.test.ts +373 -47
  70. package/src/__tests__/intent-routing.test.ts +7 -0
  71. package/src/__tests__/memory-retrieval-hook.test.ts +117 -15
  72. package/src/__tests__/notification-decision-strategy.test.ts +3 -3
  73. package/src/__tests__/oauth-store.test.ts +0 -85
  74. package/src/__tests__/{context-overflow-policy.test.ts → overflow-policy.test.ts} +1 -1
  75. package/src/__tests__/parallel-tool.benchmark.test.ts +4 -0
  76. package/src/__tests__/persist-unsendable-image-downscale.test.ts +29 -9
  77. package/src/__tests__/persist-unsendable-image.test.ts +4 -4
  78. package/src/__tests__/persistence-secret-redaction.test.ts +78 -0
  79. package/src/__tests__/plugin-bootstrap.test.ts +82 -73
  80. package/src/__tests__/plugin-tool-contribution.test.ts +7 -4
  81. package/src/__tests__/plugin-types.test.ts +0 -8
  82. package/src/__tests__/provider-catalog-visibility.test.ts +1 -9
  83. package/src/__tests__/prune-old-conversations-job.test.ts +99 -0
  84. package/src/__tests__/registry.test.ts +240 -1
  85. package/src/__tests__/require-fresh-approval.test.ts +3 -0
  86. package/src/__tests__/schedule-routes.test.ts +116 -1
  87. package/src/__tests__/schedule-store.test.ts +28 -0
  88. package/src/__tests__/schedule-tools.test.ts +94 -1
  89. package/src/__tests__/server-history-render.test.ts +39 -0
  90. package/src/__tests__/skill-projection-feature-flag.test.ts +13 -0
  91. package/src/__tests__/skill-projection.benchmark.test.ts +25 -7
  92. package/src/__tests__/skills.test.ts +202 -0
  93. package/src/__tests__/slim-skill-category.test.ts +195 -0
  94. package/src/__tests__/strip-memory-injections.test.ts +33 -39
  95. package/src/__tests__/test-support/tool-invocation-seed.ts +79 -0
  96. package/src/__tests__/title-generate-hook.test.ts +9 -7
  97. package/src/__tests__/tool-audit-listener.test.ts +264 -1
  98. package/src/__tests__/tool-error-hook.test.ts +4 -3
  99. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +1 -0
  100. package/src/__tests__/tool-executor-lifecycle-events.test.ts +273 -0
  101. package/src/__tests__/tool-result-truncate-hook.test.ts +1 -0
  102. package/src/__tests__/tool-start-timestamp.test.ts +218 -0
  103. package/src/__tests__/tools-get-route.test.ts +202 -0
  104. package/src/__tests__/workspace-tool-loader.test.ts +319 -0
  105. package/src/__tests__/workspace-tools-watcher-flag.test.ts +70 -0
  106. package/src/agent/loop.ts +569 -319
  107. package/src/api/events/tool-result.ts +9 -0
  108. package/src/api/events/tool-use-start.ts +7 -0
  109. package/src/api/index.ts +10 -0
  110. package/src/api/responses/conversation-message.ts +135 -27
  111. package/src/api/responses/memory-v3-selection-log.ts +4 -4
  112. package/src/approvals/guardian-request-resolvers.ts +26 -0
  113. package/src/browser-session/backends/host-bridge.ts +29 -0
  114. package/src/browser-session/index.ts +1 -0
  115. package/src/browser-session/types.ts +5 -1
  116. package/src/cli/commands/__tests__/schedules.test.ts +62 -4
  117. package/src/cli/commands/__tests__/skills.test.ts +53 -0
  118. package/src/cli/commands/channel-verification-sessions.ts +6 -6
  119. package/src/cli/commands/inference-providers.ts +0 -8
  120. package/src/cli/commands/plugins.ts +2 -2
  121. package/src/cli/commands/schedules.ts +27 -4
  122. package/src/cli/commands/skills.ts +187 -146
  123. package/src/cli/commands/tools.ts +106 -0
  124. package/src/cli/lib/__tests__/install-from-github.test.ts +256 -328
  125. package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +6 -2
  126. package/src/cli/lib/__tests__/plugin-details.test.ts +10 -16
  127. package/src/cli/lib/__tests__/plugin-marketplace.test.ts +2 -2
  128. package/src/cli/lib/__tests__/search-plugins.test.ts +145 -240
  129. package/src/cli/lib/install-from-github.ts +187 -117
  130. package/src/cli/lib/plugin-catalog-cache.ts +9 -9
  131. package/src/cli/lib/plugin-details.ts +38 -68
  132. package/src/cli/lib/plugin-marketplace.ts +42 -14
  133. package/src/cli/lib/search-plugins.ts +29 -129
  134. package/src/cli/program.ts +2 -0
  135. package/src/config/bundled-skills/acp/SKILL.md +1 -0
  136. package/src/config/bundled-skills/app-builder/SKILL.md +1 -0
  137. package/src/config/bundled-skills/app-control/SKILL.md +1 -0
  138. package/src/config/bundled-skills/computer-use/SKILL.md +1 -0
  139. package/src/config/bundled-skills/contacts/SKILL.md +1 -0
  140. package/src/config/bundled-skills/document-editor/SKILL.md +1 -0
  141. package/src/config/bundled-skills/followups/SKILL.md +1 -0
  142. package/src/config/bundled-skills/image-studio/SKILL.md +1 -0
  143. package/src/config/bundled-skills/media-processing/SKILL.md +1 -0
  144. package/src/config/bundled-skills/messaging/SKILL.md +1 -0
  145. package/src/config/bundled-skills/phone-calls/SKILL.md +1 -0
  146. package/src/config/bundled-skills/playbooks/SKILL.md +1 -0
  147. package/src/config/bundled-skills/schedule/SKILL.md +1 -0
  148. package/src/config/bundled-skills/schedule/TOOLS.json +11 -3
  149. package/src/config/bundled-skills/sequences/SKILL.md +1 -0
  150. package/src/config/bundled-skills/settings/SKILL.md +1 -0
  151. package/src/config/bundled-skills/skill-management/SKILL.md +101 -1
  152. package/src/config/bundled-skills/subagent/SKILL.md +1 -0
  153. package/src/config/bundled-skills/transcribe/SKILL.md +1 -0
  154. package/src/config/env-registry.ts +23 -0
  155. package/src/config/feature-flag-registry.json +17 -81
  156. package/src/config/loader.ts +5 -22
  157. package/src/config/schema.ts +2 -0
  158. package/src/config/schemas/__tests__/compaction-logs.test.ts +56 -0
  159. package/src/config/schemas/__tests__/memory-v2.test.ts +0 -1
  160. package/src/config/schemas/__tests__/memory-v3.test.ts +61 -1
  161. package/src/config/schemas/compaction-logs.ts +79 -0
  162. package/src/config/schemas/memory-v2.ts +0 -8
  163. package/src/config/schemas/memory-v3.ts +104 -33
  164. package/src/config/seed-inference-profiles.ts +1 -1
  165. package/src/config/skills.ts +117 -47
  166. package/src/context/compactor.ts +11 -0
  167. package/src/context/strip-injections.ts +38 -4
  168. package/src/credential-execution/feature-gates.ts +0 -21
  169. package/src/credential-execution/startup-timeout.ts +32 -4
  170. package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +18 -0
  171. package/src/daemon/conversation-agent-loop-handlers.ts +140 -91
  172. package/src/daemon/conversation-agent-loop.ts +123 -658
  173. package/src/daemon/conversation-error.ts +6 -33
  174. package/src/daemon/conversation-lifecycle.ts +1 -1
  175. package/src/daemon/conversation-runtime-assembly.ts +183 -22
  176. package/src/daemon/conversation-skill-tools.ts +137 -8
  177. package/src/daemon/conversation-slash.ts +0 -14
  178. package/src/daemon/conversation-store.ts +2 -19
  179. package/src/daemon/conversation-tool-setup.ts +87 -1
  180. package/src/daemon/conversation.ts +119 -50
  181. package/src/daemon/external-plugins-bootstrap.ts +36 -95
  182. package/src/daemon/handlers/config-channels.ts +11 -2
  183. package/src/daemon/handlers/shared.ts +9 -1
  184. package/src/daemon/handlers/skills.ts +10 -4
  185. package/src/daemon/host-app-control-proxy.ts +72 -57
  186. package/src/daemon/host-browser-proxy.ts +117 -22
  187. package/src/daemon/lifecycle.ts +34 -5
  188. package/src/daemon/message-protocol.ts +0 -7
  189. package/src/daemon/message-types/schedules.ts +1 -0
  190. package/src/daemon/message-types/skills.ts +17 -0
  191. package/src/daemon/providers-setup.ts +3 -0
  192. package/src/daemon/server.ts +3 -3
  193. package/src/daemon/tool-setup-types.ts +9 -3
  194. package/src/daemon/trust-context.ts +23 -0
  195. package/src/daemon/workspace-tools-watcher.ts +324 -0
  196. package/src/events/tool-audit-listener.ts +78 -16
  197. package/src/events/tool-metrics-listener.ts +2 -5
  198. package/src/memory/__tests__/compaction-log-writer-clickhouse.test.ts +227 -0
  199. package/src/memory/__tests__/conversation-queries.test.ts +176 -0
  200. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +20 -32
  201. package/src/memory/compaction-log-writer-clickhouse.ts +418 -0
  202. package/src/memory/conversation-crud.ts +134 -3
  203. package/src/memory/conversation-queries.ts +64 -7
  204. package/src/memory/db-init.ts +14 -0
  205. package/src/memory/embedding-backend.test.ts +130 -1
  206. package/src/memory/embedding-backend.ts +79 -106
  207. package/src/memory/embedding-gemini.ts +5 -0
  208. package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +12 -0
  209. package/src/memory/graph/__tests__/handle-remember-v2.test.ts +19 -0
  210. package/src/memory/graph/conversation-graph-memory.ts +36 -25
  211. package/src/memory/graph/tool-handlers.ts +3 -0
  212. package/src/memory/job-handlers/cleanup.ts +3 -1
  213. package/src/memory/jobs-store.ts +0 -28
  214. package/src/memory/jobs-worker.ts +10 -22
  215. package/src/memory/memory-marker.ts +29 -0
  216. package/src/memory/memory-retrospective-startup-cleanup.ts +1 -1
  217. package/src/memory/migrations/268-add-memory-v3-selections.ts +6 -0
  218. package/src/memory/migrations/270-schedule-description.ts +36 -0
  219. package/src/memory/migrations/275-tool-invocations-add-skill-id.test.ts +81 -0
  220. package/src/memory/migrations/275-tool-invocations-add-skill-id.ts +20 -0
  221. package/src/memory/migrations/276-tool-invocations-created-at-id-index.test.ts +68 -0
  222. package/src/memory/migrations/276-tool-invocations-created-at-id-index.ts +20 -0
  223. package/src/memory/migrations/277-add-memory-v3-ever-injected.ts +29 -0
  224. package/src/memory/migrations/278-tool-invocations-telemetry-columns.test.ts +96 -0
  225. package/src/memory/migrations/278-tool-invocations-telemetry-columns.ts +39 -0
  226. package/src/memory/migrations/279-create-skill-loaded-events.test.ts +84 -0
  227. package/src/memory/migrations/279-create-skill-loaded-events.ts +26 -0
  228. package/src/memory/migrations/280-conversations-surfaced-at.test.ts +88 -0
  229. package/src/memory/migrations/280-conversations-surfaced-at.ts +24 -0
  230. package/src/memory/migrations/index.ts +10 -0
  231. package/src/memory/migrations/registry.ts +8 -0
  232. package/src/memory/schema/conversations.ts +16 -0
  233. package/src/memory/schema/infrastructure.ts +26 -0
  234. package/src/memory/skill-loaded-events-store.test.ts +160 -0
  235. package/src/memory/skill-loaded-events-store.ts +95 -0
  236. package/src/memory/tool-executed-events-store.test.ts +219 -0
  237. package/src/memory/tool-executed-events-store.ts +102 -0
  238. package/src/memory/tool-usage-store.ts +15 -3
  239. package/src/memory/v2/__tests__/consolidation-job.test.ts +117 -12
  240. package/src/memory/v2/__tests__/consolidation-prompt-flag-gating-guard.test.ts +189 -0
  241. package/src/memory/v2/__tests__/injected-block-slugs.test.ts +90 -0
  242. package/src/memory/v2/__tests__/page-store.test.ts +33 -0
  243. package/src/memory/v2/__tests__/prompts-consolidation.test.ts +88 -15
  244. package/src/memory/v2/activation-store.ts +50 -1
  245. package/src/memory/v2/consolidation-job.ts +113 -29
  246. package/src/memory/v2/injected-block-slugs.ts +79 -0
  247. package/src/memory/v2/injection.ts +6 -1
  248. package/src/memory/v2/prompts/consolidation.ts +414 -13
  249. package/src/memory/v2/router.ts +2 -28
  250. package/src/memory/v2/static-context.ts +1 -1
  251. package/src/memory/v2/types.ts +16 -0
  252. package/src/notifications/__tests__/copy-composer.test.ts +244 -0
  253. package/src/notifications/access-request-copy.ts +298 -0
  254. package/src/notifications/adapters/slack.ts +3 -3
  255. package/src/notifications/adapters/telegram.ts +2 -1
  256. package/src/notifications/copy-composer.ts +49 -267
  257. package/src/notifications/decision-engine.ts +16 -35
  258. package/src/notifications/home-feed-side-effect.ts +1 -6
  259. package/src/oauth/oauth-store.ts +0 -9
  260. package/src/permissions/checker.test.ts +83 -1
  261. package/src/permissions/checker.ts +25 -2
  262. package/src/permissions/gateway-threshold-reader.test.ts +182 -0
  263. package/src/permissions/gateway-threshold-reader.ts +80 -0
  264. package/src/platform/client.ts +1 -3
  265. package/src/platform/feature-gate.ts +3 -12
  266. package/src/plugin-api/constants.ts +4 -2
  267. package/src/plugin-api/index.ts +63 -11
  268. package/src/plugin-api/types.ts +236 -71
  269. package/src/plugins/defaults/compaction/compact.ts +66 -2
  270. package/src/plugins/defaults/compaction/context-overflow-reducer.ts +240 -32
  271. package/src/plugins/defaults/compaction/corrected-target.ts +53 -0
  272. package/src/{daemon/context-overflow-policy.ts → plugins/defaults/compaction/overflow-policy.ts} +1 -1
  273. package/src/plugins/defaults/compaction/window-manager.ts +303 -1
  274. package/src/plugins/defaults/empty-response/hooks/post-model-call.ts +173 -0
  275. package/src/plugins/defaults/empty-response/hooks/stop.ts +11 -115
  276. package/src/plugins/defaults/empty-response/nudge-state-store.ts +46 -0
  277. package/src/plugins/defaults/history-repair/hooks/post-model-call.ts +50 -0
  278. package/src/plugins/defaults/history-repair/hooks/stop.ts +22 -0
  279. package/src/plugins/defaults/history-repair/repair-state-store.ts +51 -0
  280. package/src/plugins/defaults/history-repair/terminal.ts +39 -2
  281. package/src/plugins/defaults/image-recovery/detect.ts +25 -0
  282. package/src/plugins/defaults/image-recovery/hooks/post-model-call.ts +73 -0
  283. package/src/plugins/defaults/image-recovery/hooks/stop.ts +22 -0
  284. package/src/plugins/defaults/image-recovery/image-recovery-state-store.ts +48 -0
  285. package/src/plugins/defaults/image-recovery/package.json +14 -0
  286. package/src/{daemon/persist-unsendable-image.ts → plugins/defaults/image-recovery/recover.ts} +67 -14
  287. package/src/plugins/defaults/index.ts +71 -5
  288. package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +76 -112
  289. package/src/plugins/defaults/memory-retrieval/hooks/{user-prompt-submit-temp.ts → user-prompt-submit.ts} +83 -74
  290. package/src/plugins/defaults/memory-retrieval/injector-chain.ts +14 -8
  291. package/src/plugins/defaults/memory-retrieval/injectors.ts +2 -18
  292. package/src/plugins/defaults/memory-retrieval/package.json +14 -0
  293. package/src/plugins/defaults/memory-v3-shadow/__tests__/carry-integration.test.ts +1157 -0
  294. package/src/plugins/defaults/memory-v3-shadow/__tests__/injection.test.ts +683 -0
  295. package/src/plugins/defaults/memory-v3-shadow/__tests__/live-integration.test.ts +161 -140
  296. package/src/plugins/defaults/memory-v3-shadow/__tests__/maintain-job.test.ts +160 -0
  297. package/src/plugins/defaults/memory-v3-shadow/__tests__/orchestrate.test.ts +335 -316
  298. package/src/plugins/defaults/memory-v3-shadow/__tests__/pool-select.test.ts +145 -53
  299. package/src/plugins/defaults/memory-v3-shadow/__tests__/render-injection.test.ts +38 -1
  300. package/src/plugins/defaults/memory-v3-shadow/__tests__/selection-log-store.test.ts +18 -8
  301. package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-integration.test.ts +112 -71
  302. package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +192 -51
  303. package/src/plugins/defaults/memory-v3-shadow/__tests__/types.test.ts +4 -16
  304. package/src/plugins/defaults/memory-v3-shadow/card.test.ts +173 -0
  305. package/src/plugins/defaults/memory-v3-shadow/card.ts +116 -0
  306. package/src/plugins/defaults/memory-v3-shadow/core-set.test.ts +104 -0
  307. package/src/plugins/defaults/memory-v3-shadow/core-set.ts +59 -0
  308. package/src/plugins/defaults/memory-v3-shadow/ever-injected-store.test.ts +305 -0
  309. package/src/plugins/defaults/memory-v3-shadow/ever-injected-store.ts +278 -0
  310. package/src/plugins/defaults/memory-v3-shadow/hot-set.test.ts +138 -0
  311. package/src/plugins/defaults/memory-v3-shadow/hot-set.ts +85 -0
  312. package/src/plugins/defaults/memory-v3-shadow/injector.ts +331 -24
  313. package/src/plugins/defaults/memory-v3-shadow/maintain-job.ts +119 -13
  314. package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +169 -114
  315. package/src/plugins/defaults/memory-v3-shadow/page-content.ts +47 -16
  316. package/src/plugins/defaults/memory-v3-shadow/pool-select.ts +144 -66
  317. package/src/plugins/defaults/memory-v3-shadow/prune.test.ts +758 -0
  318. package/src/plugins/defaults/memory-v3-shadow/prune.ts +471 -0
  319. package/src/plugins/defaults/memory-v3-shadow/render-injection.ts +68 -16
  320. package/src/plugins/defaults/memory-v3-shadow/selection-log-store.ts +19 -12
  321. package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +96 -43
  322. package/src/plugins/defaults/memory-v3-shadow/types.ts +34 -17
  323. package/src/plugins/defaults/title-generate/hooks/stop.ts +9 -11
  324. package/src/plugins/pipeline.ts +8 -5
  325. package/src/plugins/types.ts +5 -51
  326. package/src/providers/cache-control.ts +26 -0
  327. package/src/providers/inference/__tests__/base-url-route-validation.test.ts +1 -2
  328. package/src/providers/model-catalog.ts +13 -1
  329. package/src/providers/openai/__tests__/tool-choice-mapping.test.ts +147 -0
  330. package/src/providers/openai/chat-completions-provider.ts +46 -0
  331. package/src/providers/openai/responses-provider.ts +45 -0
  332. package/src/providers/registry.ts +0 -8
  333. package/src/runtime/__tests__/agent-wake.test.ts +0 -1
  334. package/src/runtime/agent-wake.ts +13 -0
  335. package/src/runtime/routes/__tests__/acp-routes.test.ts +151 -0
  336. package/src/runtime/routes/__tests__/consolidation-routes.test.ts +12 -50
  337. package/src/runtime/routes/__tests__/conversation-surface-routes.test.ts +322 -0
  338. package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +0 -62
  339. package/src/runtime/routes/__tests__/plugins-routes.test.ts +31 -11
  340. package/src/runtime/routes/acp-routes.test.ts +106 -0
  341. package/src/runtime/routes/acp-routes.ts +248 -2
  342. package/src/runtime/routes/browser-tabs-routes.ts +1 -1
  343. package/src/runtime/routes/channel-verification-routes.ts +14 -5
  344. package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +0 -14
  345. package/src/runtime/routes/consolidation-routes.ts +6 -82
  346. package/src/runtime/routes/conversation-list-routes.ts +6 -0
  347. package/src/runtime/routes/conversation-management-routes.ts +71 -0
  348. package/src/runtime/routes/identity-routes.ts +8 -0
  349. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +33 -34
  350. package/src/runtime/routes/inference-provider-connection-routes.ts +0 -45
  351. package/src/runtime/routes/plugins-routes.ts +34 -45
  352. package/src/runtime/routes/schedule-routes.ts +43 -5
  353. package/src/runtime/routes/settings-routes.ts +140 -15
  354. package/src/runtime/routes/skills-routes.ts +18 -6
  355. package/src/runtime/services/__tests__/conversation-serializer.test.ts +140 -0
  356. package/src/runtime/services/conversation-serializer.ts +38 -1
  357. package/src/runtime/verification-outbound-actions.ts +147 -2
  358. package/src/runtime/verification-templates.ts +29 -3
  359. package/src/schedule/schedule-store.ts +19 -0
  360. package/src/skills/catalog-install.ts +77 -13
  361. package/src/tasks/task-scheduler.ts +1 -0
  362. package/src/telemetry/types.ts +66 -1
  363. package/src/telemetry/usage-telemetry-reporter.test.ts +542 -13
  364. package/src/telemetry/usage-telemetry-reporter.ts +213 -20
  365. package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +49 -2
  366. package/src/tools/browser/__tests__/browser-status.test.ts +29 -5
  367. package/src/tools/browser/browser-execution.ts +27 -9
  368. package/src/tools/browser/cdp-client/__tests__/factory.test.ts +380 -4
  369. package/src/tools/browser/cdp-client/__tests__/host-bridge-cdp-client.test.ts +107 -0
  370. package/src/tools/browser/cdp-client/__tests__/types.test.ts +6 -1
  371. package/src/tools/browser/cdp-client/factory.ts +217 -17
  372. package/src/tools/browser/cdp-client/host-bridge-cdp-client.ts +67 -0
  373. package/src/tools/browser/cdp-client/types.ts +22 -2
  374. package/src/tools/credential-execution/make-authenticated-request.ts +2 -1
  375. package/src/tools/credential-execution/manage-secure-command-tool.ts +169 -164
  376. package/src/tools/credential-execution/run-authenticated-command.ts +2 -1
  377. package/src/tools/executor.ts +39 -7
  378. package/src/tools/registry.ts +387 -5
  379. package/src/tools/schedule/create.ts +16 -0
  380. package/src/tools/schedule/list.ts +12 -4
  381. package/src/tools/schedule/update.ts +12 -0
  382. package/src/tools/skills/load.ts +11 -6
  383. package/src/tools/terminal/safe-env.ts +2 -0
  384. package/src/tools/types.ts +65 -9
  385. package/src/tools/workspace-tools/loader.ts +673 -0
  386. package/src/usage/attribution.ts +28 -0
  387. package/src/util/device-id.ts +17 -3
  388. package/src/util/platform.ts +16 -0
  389. package/tsconfig.plugin-api.json +13 -0
  390. package/src/__tests__/plugin-external-api.test.ts +0 -68
  391. package/src/__tests__/plugin-skill-contribution.test.ts +0 -355
  392. package/src/daemon/message-types/browser.ts +0 -10
  393. package/src/notifications/__tests__/emit-signal-home-feed.test.ts +0 -187
  394. package/src/plugins/defaults/memory-v3-shadow/__tests__/fixtures/eval-turns.json +0 -36
  395. package/src/plugins/defaults/memory-v3-shadow/__tests__/fixtures/live-turns.json +0 -37
  396. package/src/plugins/defaults/memory-v3-shadow/__tests__/working-set-eviction.test.ts +0 -106
  397. package/src/plugins/defaults/memory-v3-shadow/__tests__/working-set-skeleton.test.ts +0 -44
  398. package/src/plugins/defaults/memory-v3-shadow/working-set.ts +0 -91
  399. package/src/plugins/external-api.ts +0 -114
  400. package/src/plugins/plugin-skill-contributions.ts +0 -292
@@ -24,6 +24,46 @@ export type HostBrowserInput = DistributiveOmit<
24
24
 
25
25
  const log = getLogger("host-browser-proxy");
26
26
 
27
+ /**
28
+ * Extension-only pseudo-CDP methods (Vellum.listTabs, Vellum.selectTab,
29
+ * Vellum.closeTab, Vellum.createTab, Vellum.findTab, Vellum.attach,
30
+ * Vellum.detach) are implemented solely by the Chrome extension's
31
+ * dispatcher via the chrome.tabs / chrome.debugger APIs. The macOS CDP
32
+ * bridge speaks raw CDP against localhost:9222 only and fails on every
33
+ * `Vellum.*` method, so routing them anywhere but the extension is a
34
+ * guaranteed failure. Prefix check rather than an allowlist so newly
35
+ * added pseudo-methods stay covered.
36
+ */
37
+ function isExtensionOnlyMethod(cdpMethod: string): boolean {
38
+ return cdpMethod.startsWith("Vellum.");
39
+ }
40
+
41
+ /**
42
+ * Structured isError result for pseudo-methods that cannot be served
43
+ * because no Chrome Extension client is connected (or the explicit
44
+ * target is a different transport). The `extension_required` code is
45
+ * deliberately NOT in ExtensionCdpClient's TRANSPORT_ERROR_CODES: it
46
+ * classifies as `cdp_error` so the factory does not fail over to a
47
+ * backend that cannot serve `Vellum.*` either, and the message is
48
+ * surfaced verbatim to the caller.
49
+ */
50
+ function extensionRequiredResult(
51
+ cdpMethod: string,
52
+ targetInterfaceId?: string,
53
+ ): ToolExecutionResult {
54
+ return {
55
+ content: JSON.stringify({
56
+ code: "extension_required",
57
+ message:
58
+ `${cdpMethod} requires the Chrome extension; ` +
59
+ (targetInterfaceId
60
+ ? `the targeted client (interface "${targetInterfaceId}") cannot handle it.`
61
+ : "no Chrome extension client is connected."),
62
+ }),
63
+ isError: true,
64
+ };
65
+ }
66
+
27
67
  /**
28
68
  * Pick the host_browser-capable client to dispatch to.
29
69
  *
@@ -32,24 +72,43 @@ const log = getLogger("host-browser-proxy");
32
72
  * in `request()` still runs on the returned client when
33
73
  * `sourceActorPrincipalId` is present.
34
74
  *
35
- * When `sourceActorPrincipalId` is supplied (and no explicit target),
36
- * candidate clients are filtered down to those owned by the same actor.
37
- * Returns `undefined` when no same-actor client is connected; the
38
- * caller surfaces this as the existing "no active extension connection"
39
- * rejection.
75
+ * Candidate ordering is method-aware and deterministic. Both the Chrome
76
+ * extension and the macOS desktop bridge register the `host_browser`
77
+ * capability, and both receive periodic heartbeats that update
78
+ * `lastActiveAt` — so pure recency ordering is a race between transports
79
+ * with very different capabilities:
40
80
  *
41
- * When neither is supplied (legacy callers without a resolved actor
42
- * identity), falls through to the most-recently-active host_browser
43
- * client so the registry singleton continues to work for single-client
44
- * setups.
81
+ * - `Vellum.*` pseudo-methods: candidates are restricted to
82
+ * chrome-extension clients (the only transport that implements them).
83
+ * - Raw CDP methods: chrome-extension clients are preferred over other
84
+ * host_browser clients (the macOS bridge), with `lastActiveAt`
85
+ * descending within each group — the natural order returned by
86
+ * `listClientsByCapability`. Callers that want the bridge despite a
87
+ * connected extension must pass `targetClientId` explicitly via the
88
+ * LLM-facing param added in #30066.
45
89
  *
46
- * Within each branch, ties are broken by `lastActiveAt` descending —
47
- * the natural order returned by `listClientsByCapability`. Callers that
48
- * need a specific transport (e.g. Chrome Extension's `chrome.debugger`
49
- * over the macOS CDP bridge) must pass `targetClientId` explicitly via
50
- * the LLM-facing param added in #30066.
90
+ * When `sourceActorPrincipalId` is supplied (and no explicit target),
91
+ * candidate clients are filtered down to those owned by the same actor.
92
+ * Returns `undefined` when no eligible client is connected.
93
+ */
94
+ /**
95
+ * Whether any of `clients` is dispatchable for the caller. Without an
96
+ * actor, any client counts (legacy single-user behavior); with one,
97
+ * only same-actor clients count — the strict match used by
98
+ * `resolveTargetClient`.
51
99
  */
100
+ function hasClientForActor(
101
+ clients: ReadonlyArray<{ actorPrincipalId?: string }>,
102
+ sourceActorPrincipalId?: string,
103
+ ): boolean {
104
+ if (sourceActorPrincipalId == null) return clients.length > 0;
105
+ return clients.some(
106
+ (c) => c.actorPrincipalId === sourceActorPrincipalId,
107
+ );
108
+ }
109
+
52
110
  function resolveTargetClient(
111
+ cdpMethod: string,
53
112
  sourceActorPrincipalId: string | undefined,
54
113
  targetClientId?: string,
55
114
  ) {
@@ -58,8 +117,12 @@ function resolveTargetClient(
58
117
  return clients.find((c) => c.clientId === targetClientId);
59
118
  }
60
119
 
61
- const candidates =
62
- assistantEventHub.listClientsByCapability("host_browser");
120
+ const all = assistantEventHub.listClientsByCapability("host_browser");
121
+ const extension = all.filter((c) => c.interfaceId === "chrome-extension");
122
+ const candidates = isExtensionOnlyMethod(cdpMethod)
123
+ ? extension
124
+ : [...extension, ...all.filter((c) => c.interfaceId !== "chrome-extension")];
125
+
63
126
  if (sourceActorPrincipalId == null) {
64
127
  return candidates[0];
65
128
  }
@@ -102,10 +165,16 @@ export class HostBrowserProxy {
102
165
  * Returns `true` when either the Chrome Extension or the macOS SSE
103
166
  * bridge is available — i.e. any transport can forward host-browser
104
167
  * requests.
168
+ *
169
+ * When `sourceActorPrincipalId` is supplied, only clients owned by
170
+ * that actor count — mirroring `resolveTargetClient`'s strict actor
171
+ * matching so availability checks never report a client the proxy
172
+ * would refuse to dispatch to.
105
173
  */
106
- isAvailable(): boolean {
107
- return (
108
- assistantEventHub.getMostRecentClientByCapability("host_browser") != null
174
+ isAvailable(sourceActorPrincipalId?: string): boolean {
175
+ return hasClientForActor(
176
+ assistantEventHub.listClientsByCapability("host_browser"),
177
+ sourceActorPrincipalId,
109
178
  );
110
179
  }
111
180
 
@@ -114,9 +183,17 @@ export class HostBrowserProxy {
114
183
  * Returns `false` when only the macOS SSE bridge is available.
115
184
  * Unlike {@link isAvailable}, this does not consider the macOS bridge
116
185
  * a valid extension transport.
186
+ *
187
+ * When `sourceActorPrincipalId` is supplied, only extension clients
188
+ * owned by that actor count. On a multi-actor cloud daemon, another
189
+ * actor's connected extension must not make this actor's
190
+ * conversations select extension-labelled transports.
117
191
  */
118
- hasExtensionClient(): boolean {
119
- return assistantEventHub.listClientsByInterface("chrome-extension").length > 0;
192
+ hasExtensionClient(sourceActorPrincipalId?: string): boolean {
193
+ return hasClientForActor(
194
+ assistantEventHub.listClientsByInterface("chrome-extension"),
195
+ sourceActorPrincipalId,
196
+ );
120
197
  }
121
198
 
122
199
  /**
@@ -155,7 +232,11 @@ export class HostBrowserProxy {
155
232
  // alongside the pending interaction registration. Same shape as
156
233
  // host-cu-proxy: the result-route same-actor check compares the
157
234
  // submitting client's actor against this captured value.
158
- const preferredClient = resolveTargetClient(sourceActorPrincipalId, targetClientId);
235
+ const preferredClient = resolveTargetClient(
236
+ input.cdpMethod,
237
+ sourceActorPrincipalId,
238
+ targetClientId,
239
+ );
159
240
 
160
241
  // Same-user enforcement: when the caller's actor is known, refuse to
161
242
  // dispatch to a client owned by a different actor. This covers the
@@ -175,6 +256,20 @@ export class HostBrowserProxy {
175
256
  if (rejection) return Promise.resolve(rejection);
176
257
  }
177
258
 
259
+ // Pseudo-methods can only be served by the Chrome extension. Fail fast
260
+ // (after the same-actor gate, which stays authoritative) instead of
261
+ // dispatching to a transport that is guaranteed to fail — the factory's
262
+ // pinned-extension gate is the first line of defense; this covers
263
+ // heartbeat races and bridge-routed auto-mode sends.
264
+ if (
265
+ isExtensionOnlyMethod(input.cdpMethod) &&
266
+ preferredClient?.interfaceId !== "chrome-extension"
267
+ ) {
268
+ return Promise.resolve(
269
+ extensionRequiredResult(input.cdpMethod, preferredClient?.interfaceId),
270
+ );
271
+ }
272
+
178
273
  const resolvedClientId = preferredClient?.clientId;
179
274
  const targetActorPrincipalId = preferredClient?.actorPrincipalId;
180
275
  const requestId = uuid();
@@ -31,6 +31,7 @@ import {
31
31
  import {
32
32
  awaitCesClientWithTimeout,
33
33
  DEFAULT_CES_STARTUP_TIMEOUT_MS,
34
+ injectCesClientWhenReady,
34
35
  } from "../credential-execution/startup-timeout.js";
35
36
  import { FilingService } from "../filing/filing-service.js";
36
37
  import { HeartbeatService } from "../heartbeat/heartbeat-service.js";
@@ -75,6 +76,7 @@ import { publishConversationListChanged } from "../runtime/sync/resource-sync-ev
75
76
  import { recoverStaleSchedules } from "../schedule/schedule-recovery.js";
76
77
  import { startScheduler } from "../schedule/scheduler.js";
77
78
  import {
79
+ getCesClient,
78
80
  onCesClientChanged,
79
81
  setCesClient,
80
82
  setCesReconnect,
@@ -633,21 +635,38 @@ export async function runDaemon(): Promise<void> {
633
635
  }
634
636
 
635
637
  // Privacy gating: Sentry crash/error reporting is gated by sendDiagnostics,
636
- // while the usage telemetry reporter is gated by collectUsageData. Both are
637
- // disabled in dev mode. Early-startup crashes before this point are still captured.
638
+ // while the usage telemetry reporter re-checks collectUsageData on every
639
+ // flush. Both are disabled in dev mode. Early-startup crashes before this
640
+ // point are still captured.
638
641
  const isDevMode = process.env.VELLUM_DEV === "1";
639
642
  const sendDiagnostics = !isDevMode && config.sendDiagnostics;
640
- const collectUsageData = !isDevMode && config.collectUsageData;
641
643
  if (!sendDiagnostics) {
642
644
  await closeSentry();
643
645
  }
644
646
 
647
+ // Construct and start the reporter even when usage collection is disabled:
648
+ // flush() re-checks collectUsageData each cycle and, when opted out, sends
649
+ // nothing but advances all watermarks (including the final flush in
650
+ // stop()). New opted-out tool_invocations rows are already unreportable by
651
+ // construction — the audit listener persists NULL telemetry columns for
652
+ // them, which the tool_executed projection filters out — so the opted-out
653
+ // flushes are defense in depth there (covering rows recorded under builds
654
+ // that predate that write-time gate) and remain the primary guard for the
655
+ // always-on tables without a write-time gate (llm_usage, turn events).
656
+ // Deliberately NOT gated on dbReady: getDb()
657
+ // can still work when initializeDb() failed mid-migration, in which case
658
+ // the audit listener keeps writing rows that the opt-out branch must keep
659
+ // covered. The reporter is degraded-mode safe — its constructor and
660
+ // flush() treat DB errors as non-fatal.
645
661
  let telemetryReporter: UsageTelemetryReporter | null = null;
646
- if (collectUsageData) {
662
+ if (!isDevMode) {
647
663
  telemetryReporter = new UsageTelemetryReporter();
648
664
  setUsageTelemetryReporter(telemetryReporter);
649
665
  telemetryReporter.start();
650
- log.info("Usage telemetry reporter started");
666
+ log.info(
667
+ { collectUsageData: config.collectUsageData },
668
+ "Usage telemetry reporter started",
669
+ );
651
670
  }
652
671
 
653
672
  // CES lifecycle — kick off early so CES handshake runs concurrently with
@@ -673,6 +692,16 @@ export async function runDaemon(): Promise<void> {
673
692
  });
674
693
  if (client) {
675
694
  setCesClient(client);
695
+ } else {
696
+ // The handshake lost the startup race, so provider init proceeds on
697
+ // the direct credential store. Still inject the CES client into the
698
+ // resolver once the handshake completes, so CES tools and the
699
+ // approval bridge route through CES rather than reporting it
700
+ // unavailable for the rest of the process.
701
+ injectCesClientWhenReady(cesResult.clientPromise, {
702
+ getCesClient,
703
+ setCesClient,
704
+ });
676
705
  }
677
706
  }
678
707
 
@@ -16,7 +16,6 @@
16
16
  export * from "./message-types/acp.js";
17
17
  export * from "./message-types/apps.js";
18
18
  export * from "./message-types/bookmarks.js";
19
- export * from "./message-types/browser.js";
20
19
  export * from "./message-types/computer-use.js";
21
20
  export * from "./message-types/contacts.js";
22
21
  export * from "./message-types/conversations.js";
@@ -57,10 +56,6 @@ import type {
57
56
  _AppsServerMessages,
58
57
  } from "./message-types/apps.js";
59
58
  import type { _BookmarksServerMessages } from "./message-types/bookmarks.js";
60
- import type {
61
- _BrowserClientMessages,
62
- _BrowserServerMessages,
63
- } from "./message-types/browser.js";
64
59
  import type {
65
60
  _ComputerUseClientMessages,
66
61
  _ComputerUseServerMessages,
@@ -167,7 +162,6 @@ export type ClientMessage =
167
162
  | _ComputerUseClientMessages
168
163
  | _ContactsClientMessages
169
164
  | _WorkItemsClientMessages
170
- | _BrowserClientMessages
171
165
  | _HostBrowserClientMessages
172
166
  | _SubagentsClientMessages
173
167
  | _DocumentsClientMessages
@@ -191,7 +185,6 @@ export type ServerMessage =
191
185
  | _ComputerUseServerMessages
192
186
  | _ContactsServerMessages
193
187
  | _WorkItemsServerMessages
194
- | _BrowserServerMessages
195
188
  | _SubagentsServerMessages
196
189
  | _DocumentsServerMessages
197
190
  | _DocumentCommentsServerMessages
@@ -80,6 +80,7 @@ export interface SchedulesListResponse {
80
80
  lastRunAt: number | null;
81
81
  lastStatus: string | null;
82
82
  description: string;
83
+ cadenceDescription: string;
83
84
  mode: string;
84
85
  status: string;
85
86
  routingIntent: string;
@@ -1,6 +1,7 @@
1
1
  // Skill management types.
2
2
 
3
3
  import type { PartnerAudit } from "../../skills/skillssh-audit-types.js";
4
+ import type { OwnerInfo } from "../../tools/types.js";
4
5
 
5
6
  // Re-export so consumers can access the audit types from this module.
6
7
  export type { PartnerAudit } from "../../skills/skillssh-audit-types.js";
@@ -91,6 +92,13 @@ interface SlimSkillBase {
91
92
  kind: "bundled" | "installed" | "catalog";
92
93
  status: "enabled" | "disabled" | "available";
93
94
  category: string;
95
+ /**
96
+ * Extension that ships this skill, reusing the tool registry's
97
+ * {@link OwnerInfo} model. Set for plugin-resident skills as
98
+ * `{ kind: "plugin", id: <plugin dir name> }` so clients can attribute
99
+ * them to the owning plugin instead of collapsing to their `kind`/`origin`.
100
+ */
101
+ owner?: OwnerInfo;
94
102
  }
95
103
 
96
104
  interface VellumSlimSkill extends SlimSkillBase {
@@ -167,6 +175,13 @@ interface SkillDetailBase {
167
175
 
168
176
  interface VellumSkillDetail extends SkillDetailBase {
169
177
  origin: "vellum";
178
+ /**
179
+ * Extension that ships this skill, reusing the tool registry's
180
+ * {@link OwnerInfo} model. Set for plugin-resident skills as
181
+ * `{ kind: "plugin", id: <plugin dir name> }` — plugin skills are mapped to
182
+ * the `vellum` origin, so this is where their attribution is preserved.
183
+ */
184
+ owner?: OwnerInfo;
170
185
  }
171
186
 
172
187
  interface ClawhubSkillDetail extends SkillDetailBase {
@@ -201,6 +216,8 @@ interface SkillsshSkillDetail extends SkillDetailBase {
201
216
 
202
217
  interface CustomSkillDetail extends SkillDetailBase {
203
218
  origin: "custom";
219
+ /** See {@link VellumSkillDetail.owner}. */
220
+ owner?: OwnerInfo;
204
221
  }
205
222
 
206
223
  export type SkillDetailResponse =
@@ -119,6 +119,9 @@ export async function initializeProvidersAndTools(
119
119
  }
120
120
 
121
121
  await initializeProviders(config);
122
+ // initializeTools() also loads workspace tool overrides from
123
+ // `<workspaceDir>/tools/` once core tools have settled, so they own
124
+ // their names before the MCP / plugin registrations below run.
122
125
  await initializeTools();
123
126
 
124
127
  // Start MCP servers and register their tools
@@ -43,7 +43,6 @@ import {
43
43
  import {
44
44
  getOrCreateConversation as getOrCreateActiveConversation,
45
45
  initConversationLifecycle,
46
- setCesClientPromise,
47
46
  } from "./conversation-store.js";
48
47
  import { refreshSurfacesForApp } from "./conversation-surfaces.js";
49
48
  import { parseIdentityFields } from "./handlers/identity.js";
@@ -51,6 +50,7 @@ import type { ConversationCreateOptions } from "./handlers/shared.js";
51
50
  import { setGlobalSkillIpcSender } from "./meet-host-supervisor.js";
52
51
  import { PluginSourceWatcher } from "./plugin-source-watcher.js";
53
52
  import { refreshSkillCapabilityMemories } from "./skill-memory-refresh.js";
53
+ import { WorkspaceToolsWatcher } from "./workspace-tools-watcher.js";
54
54
 
55
55
  const log = getLogger("server");
56
56
 
@@ -126,7 +126,6 @@ export class DaemonServer {
126
126
  }
127
127
  return client;
128
128
  });
129
- setCesClientPromise(this.cesClientPromise);
130
129
  }
131
130
  }
132
131
 
@@ -322,6 +321,7 @@ export class DaemonServer {
322
321
  this.appSourceWatcher.start((appId) => this.handleAppSourceChange(appId));
323
322
 
324
323
  this.pluginSourceWatcher.start();
324
+ WorkspaceToolsWatcher.getInstance().start();
325
325
 
326
326
  // Broadcast contacts_changed to all clients when any contact mutation occurs.
327
327
  this.unsubscribeContactChange = onContactChange(() => {
@@ -338,6 +338,7 @@ export class DaemonServer {
338
338
  this.configWatcher.stop();
339
339
  this.appSourceWatcher.stop();
340
340
  this.pluginSourceWatcher.stop();
341
+ WorkspaceToolsWatcher.getInstance().stop();
341
342
  this.cliIpc.stop();
342
343
  this.skillIpc.stop();
343
344
  if (this.unsubscribeContactChange) {
@@ -373,7 +374,6 @@ export class DaemonServer {
373
374
  if (this.cesClientPromise) {
374
375
  await this.cesClientPromise.catch(() => undefined);
375
376
  this.cesClientPromise = undefined;
376
- setCesClientPromise(undefined);
377
377
  }
378
378
  if (this.cesProcessManager) {
379
379
  this.cesProcessManager = undefined;
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import type { InterfaceId } from "../channels/types.js";
7
- import type { CesClient } from "../credential-execution/client.js";
7
+ import type { LLMCallSite } from "../config/schemas/llm.js";
8
8
  import type { SurfaceConversationContext } from "./conversation-surfaces.js";
9
9
  import type { TrustContext } from "./trust-context.js";
10
10
 
@@ -33,8 +33,6 @@ export interface ToolSetupContext extends SurfaceConversationContext {
33
33
  trustContext?: TrustContext;
34
34
  /** Voice/call session ID, if the conversation originates from a call. Propagated into ToolContext for scoped grant consumption. */
35
35
  callSessionId?: string;
36
- /** CES RPC client for credential execution operations. Injected when CES tools are enabled and the CES process is available. */
37
- cesClient?: CesClient;
38
36
  /** The interface ID of the connected client driving the current turn (e.g. "macos", "chrome-extension"). Propagated into ToolContext for browser backend selection. */
39
37
  readonly transportInterface?: InterfaceId;
40
38
 
@@ -49,6 +47,14 @@ export interface ToolSetupContext extends SurfaceConversationContext {
49
47
  * trust rules auto-executing side-effect tools in non-interactive contexts.
50
48
  */
51
49
  forcePromptSideEffects?: boolean;
50
+ /**
51
+ * The LLM call site driving the current turn, set by `runAgentLoopImpl`
52
+ * (`options.callSite ?? "mainAgent"`). Non-main turns (voice `callAgent`,
53
+ * `filingAgent`, …) resolve different provider/model/profile config, so
54
+ * tool telemetry attribution must use this rather than assuming
55
+ * `mainAgent`. Absent before the first turn starts.
56
+ */
57
+ currentCallSite?: LLMCallSite;
52
58
  /**
53
59
  * Per-turn snapshot of the resolved inference-profile override, set by
54
60
  * `runAgentLoopImpl`. Propagated into `ToolContext.overrideProfile` so
@@ -6,6 +6,7 @@
6
6
  */
7
7
  import type { ChannelId } from "../channels/types.js";
8
8
  import { isHttpAuthDisabled } from "../config/env.js";
9
+ import { shouldExposePersonalMemory } from "../memory/v2/static-context.js";
9
10
  import type { TrustClass } from "../runtime/actor-trust-resolver.js";
10
11
 
11
12
  export interface TrustContext {
@@ -81,3 +82,25 @@ export function resolveTrustClass(
81
82
  if (isHttpAuthDisabled()) return "guardian";
82
83
  return trustContext?.trustClass ?? "unknown";
83
84
  }
85
+
86
+ /**
87
+ * Whether personal-memory content may be surfaced for the actor described by
88
+ * `trustContext`: the gate admits guardian-class actors and internal/local
89
+ * flows (including turns with no trust context), and blocks remote untrusted
90
+ * actors — see {@link shouldExposePersonalMemory} for the rationale.
91
+ *
92
+ * This is THE personal-memory trust gate. Every surface that exposes private
93
+ * user content — the v2 dynamic/static `<memory>` layers, PKB context, NOW.md,
94
+ * memory-v3 cards/spotlight, and the `loadFromDb` rehydration of persisted
95
+ * memory blocks — must call this one helper so the exposure rule cannot drift
96
+ * between copies. It folds in {@link resolveTrustClass} so the dev-bypass
97
+ * (HTTP auth disabled → guardian) applies uniformly at every call site.
98
+ */
99
+ export function isPersonalMemoryAllowed(
100
+ trustContext: TrustContext | undefined,
101
+ ): boolean {
102
+ return shouldExposePersonalMemory({
103
+ sourceChannel: trustContext?.sourceChannel,
104
+ isTrustedActor: resolveTrustClass(trustContext) === "guardian",
105
+ });
106
+ }