@vellumai/assistant 0.7.0 → 0.7.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 (666) hide show
  1. package/ARCHITECTURE.md +6 -7
  2. package/Dockerfile +1 -0
  3. package/README.md +2 -2
  4. package/__tests__/permissions/gateway-threshold-reader.test.ts +79 -139
  5. package/bun.lock +3 -0
  6. package/docs/architecture/security.md +18 -16
  7. package/knip.json +1 -0
  8. package/node_modules/@vellumai/skill-host-contracts/__tests__/client.test.ts +1 -5
  9. package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +0 -5
  10. package/node_modules/@vellumai/skill-host-contracts/src/client.ts +10 -16
  11. package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +1 -9
  12. package/node_modules/@vellumai/skill-host-contracts/src/tool-types.ts +12 -12
  13. package/node_modules/@vellumai/slack-text/bun.lock +24 -0
  14. package/node_modules/@vellumai/slack-text/package.json +18 -0
  15. package/node_modules/@vellumai/slack-text/src/index.test.ts +153 -0
  16. package/node_modules/@vellumai/slack-text/src/index.ts +235 -0
  17. package/node_modules/@vellumai/slack-text/tsconfig.json +20 -0
  18. package/openapi.yaml +294 -107
  19. package/package.json +4 -2
  20. package/scripts/generate-openapi.ts +16 -111
  21. package/src/__tests__/agent-wake-override-profile.test.ts +23 -1
  22. package/src/__tests__/anthropic-provider.test.ts +56 -13
  23. package/src/__tests__/app-conversation-ids-backfill.test.ts +278 -0
  24. package/src/__tests__/app-conversation-ids.test.ts +151 -0
  25. package/src/__tests__/approval-cascade.test.ts +0 -15
  26. package/src/__tests__/approval-routes-http.test.ts +6 -17
  27. package/src/__tests__/assistant-event-hub.test.ts +126 -77
  28. package/src/__tests__/assistant-event.test.ts +0 -5
  29. package/src/__tests__/assistant-events-sse-hardening.test.ts +37 -15
  30. package/src/__tests__/assistant-feature-flags-integration.test.ts +0 -29
  31. package/src/__tests__/background-shell-host-bash.test.ts +34 -43
  32. package/src/__tests__/call-controller.test.ts +1 -1
  33. package/src/__tests__/call-site-routing-provider.test.ts +193 -0
  34. package/src/__tests__/channel-approval-routes.test.ts +10 -296
  35. package/src/__tests__/channel-approvals.test.ts +25 -17
  36. package/src/__tests__/channel-guardian.test.ts +100 -146
  37. package/src/__tests__/checker.test.ts +20 -34
  38. package/src/__tests__/compact-event-conversation-id-guard.test.ts +50 -0
  39. package/src/__tests__/compaction-events.test.ts +2 -0
  40. package/src/__tests__/config-schema.test.ts +6 -48
  41. package/src/__tests__/config-watcher.test.ts +12 -0
  42. package/src/__tests__/connection-policy.test.ts +1 -52
  43. package/src/__tests__/contacts-write.test.ts +2 -64
  44. package/src/__tests__/context-image-dimensions.test.ts +1 -1
  45. package/src/__tests__/context-search-memory-source.test.ts +120 -1
  46. package/src/__tests__/context-search-memory-v2-source.test.ts +383 -0
  47. package/src/__tests__/context-search-pkb-source.test.ts +49 -0
  48. package/src/__tests__/context-search-workspace-source.test.ts +9 -22
  49. package/src/__tests__/context-window-manager.test.ts +46 -0
  50. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +2 -0
  51. package/src/__tests__/conversation-agent-loop-overflow.test.ts +102 -29
  52. package/src/__tests__/conversation-agent-loop.test.ts +980 -13
  53. package/src/__tests__/conversation-analysis-routes.test.ts +12 -10
  54. package/src/__tests__/conversation-attention-telegram.test.ts +11 -3
  55. package/src/__tests__/conversation-confirmation-signals.test.ts +0 -291
  56. package/src/__tests__/conversation-history-web-search.test.ts +4 -3
  57. package/src/__tests__/conversation-inference-profile-route.test.ts +12 -23
  58. package/src/__tests__/conversation-lifecycle.test.ts +4 -4
  59. package/src/__tests__/conversation-process-callsite.test.ts +79 -2
  60. package/src/__tests__/conversation-queue.test.ts +3 -8
  61. package/src/__tests__/conversation-routes-disk-view.test.ts +1 -161
  62. package/src/__tests__/conversation-routes-guardian-reply.test.ts +0 -32
  63. package/src/__tests__/conversation-routes-slash-commands.test.ts +75 -66
  64. package/src/__tests__/conversation-runtime-assembly.test.ts +257 -3
  65. package/src/__tests__/conversation-slash-commands.test.ts +24 -4
  66. package/src/__tests__/conversation-slash-queue.test.ts +2 -0
  67. package/src/__tests__/conversation-speed-override.test.ts +0 -3
  68. package/src/__tests__/conversation-starter-routes.test.ts +79 -2
  69. package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +12 -5
  70. package/src/__tests__/conversation-surfaces-standalone.test.ts +18 -14
  71. package/src/__tests__/conversation-surfaces-state-update.test.ts +3 -2
  72. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +8 -46
  73. package/src/__tests__/conversation-usage.test.ts +253 -3
  74. package/src/__tests__/credential-execution-shell-lockdown.test.ts +0 -39
  75. package/src/__tests__/credential-health-service.test.ts +68 -0
  76. package/src/__tests__/credential-security-e2e.test.ts +4 -3
  77. package/src/__tests__/credential-security-invariants.test.ts +1 -5
  78. package/src/__tests__/credential-token-resolver.test.ts +180 -0
  79. package/src/__tests__/cu-unified-flow.test.ts +33 -16
  80. package/src/__tests__/daemon-assistant-events.test.ts +34 -21
  81. package/src/__tests__/daemon-credential-client.test.ts +4 -1
  82. package/src/__tests__/db-connection-isolation.test.ts +125 -0
  83. package/src/__tests__/db-migration-rollback.test.ts +101 -0
  84. package/src/__tests__/db-slack-compaction-watermark-migration.test.ts +169 -0
  85. package/src/__tests__/deterministic-verification-control-plane.test.ts +7 -80
  86. package/src/__tests__/document-conversations.test.ts +332 -0
  87. package/src/__tests__/embedding-managed-proxy-selection.test.ts +2 -2
  88. package/src/__tests__/emit-event-signal.test.ts +4 -6
  89. package/src/__tests__/events-client-registration.test.ts +193 -49
  90. package/src/__tests__/filing-service.test.ts +58 -7
  91. package/src/__tests__/first-greeting.test.ts +156 -150
  92. package/src/__tests__/fixtures/mock-chrome-extension.ts +108 -66
  93. package/src/__tests__/get-skill-detail-audit.test.ts +3 -8
  94. package/src/__tests__/guardian-binding-drift-heal.test.ts +1 -1
  95. package/src/__tests__/guardian-dispatch.test.ts +1 -1
  96. package/src/__tests__/guardian-grant-minting.test.ts +7 -2
  97. package/src/__tests__/guardian-routing-invariants.test.ts +7 -2
  98. package/src/__tests__/guardian-routing-state.test.ts +1 -1
  99. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +32 -11
  100. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +2 -83
  101. package/src/__tests__/headless-browser-mode.test.ts +4 -9
  102. package/src/__tests__/headless-browser-navigate.test.ts +21 -20
  103. package/src/__tests__/heartbeat-service.test.ts +289 -7
  104. package/src/__tests__/helpers/channel-test-adapter.ts +2 -2
  105. package/src/__tests__/helpers/create-guardian-binding.ts +91 -0
  106. package/src/__tests__/host-bash-proxy.test.ts +46 -122
  107. package/src/__tests__/host-browser-e2e-cloud.test.ts +36 -497
  108. package/src/__tests__/host-browser-e2e-self-hosted-capability.test.ts +26 -96
  109. package/src/__tests__/host-browser-proxy.test.ts +111 -185
  110. package/src/__tests__/host-browser-routes.test.ts +45 -75
  111. package/src/__tests__/host-browser-ws-events-e2e.test.ts +26 -30
  112. package/src/__tests__/host-cu-proxy.test.ts +56 -111
  113. package/src/__tests__/host-file-proxy.test.ts +44 -98
  114. package/src/__tests__/host-file-read-tool.test.ts +42 -21
  115. package/src/__tests__/host-shell-tool.test.ts +33 -68
  116. package/src/__tests__/host-transfer-pending-interactions.test.ts +2 -18
  117. package/src/__tests__/host-transfer-proxy.test.ts +43 -53
  118. package/src/__tests__/http-user-message-parity.test.ts +0 -6
  119. package/src/__tests__/inbound-slack-persistence.test.ts +31 -0
  120. package/src/__tests__/injector-chain.test.ts +10 -5
  121. package/src/__tests__/injector-pkb-v2-silenced.test.ts +124 -0
  122. package/src/__tests__/inline-command-runner.test.ts +0 -66
  123. package/src/__tests__/inline-skill-load-permissions.test.ts +0 -2
  124. package/src/__tests__/install-skill-routing.test.ts +1 -13
  125. package/src/__tests__/llm-callsite-catalog.test.ts +34 -0
  126. package/src/__tests__/llm-catalog-parity.test.ts +90 -0
  127. package/src/__tests__/llm-context-resolution.test.ts +180 -0
  128. package/src/__tests__/llm-resolver.test.ts +80 -12
  129. package/src/__tests__/llm-usage-store.test.ts +269 -4
  130. package/src/__tests__/log-export-routes.test.ts +89 -0
  131. package/src/__tests__/managed-profile-guard.test.ts +225 -0
  132. package/src/__tests__/managed-skill-lifecycle.test.ts +0 -10
  133. package/src/__tests__/manual-token-reconciliation.test.ts +334 -0
  134. package/src/__tests__/memory-v2-static-injector.test.ts +95 -0
  135. package/src/__tests__/migration-cross-version-compatibility.test.ts +197 -291
  136. package/src/__tests__/migration-export-http.test.ts +33 -26
  137. package/src/__tests__/migration-export-streaming.test.ts +18 -10
  138. package/src/__tests__/migration-export-to-gcs.test.ts +49 -9
  139. package/src/__tests__/migration-import-commit-http.test.ts +66 -21
  140. package/src/__tests__/migration-import-from-gcs.test.ts +50 -9
  141. package/src/__tests__/migration-import-from-url.test.ts +20 -6
  142. package/src/__tests__/migration-import-preflight-http.test.ts +95 -95
  143. package/src/__tests__/migration-parity-persistence.test.ts +62 -25
  144. package/src/__tests__/migration-transport.test.ts +115 -23
  145. package/src/__tests__/migration-validate-http.test.ts +105 -80
  146. package/src/__tests__/migration-wizard.test.ts +133 -27
  147. package/src/__tests__/non-member-access-request.test.ts +1 -1
  148. package/src/__tests__/notification-guardian-path.test.ts +1 -1
  149. package/src/__tests__/oauth-store.test.ts +19 -0
  150. package/src/__tests__/platform-bash-auto-approve.test.ts +21 -12
  151. package/src/__tests__/prechat-onboarding-contract.test.ts +31 -7
  152. package/src/__tests__/pricing.test.ts +68 -4
  153. package/src/__tests__/process-message-background-slack.test.ts +331 -0
  154. package/src/__tests__/provider-managed-proxy-integration.test.ts +153 -17
  155. package/src/__tests__/provider-send-message-override-profile.test.ts +50 -0
  156. package/src/__tests__/provider-usage-tracking.test.ts +208 -0
  157. package/src/__tests__/reaction-persistence.test.ts +9 -6
  158. package/src/__tests__/rebind-secrets-screen.test.ts +53 -16
  159. package/src/__tests__/recording-handler.test.ts +64 -81
  160. package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +4 -3
  161. package/src/__tests__/relay-server.test.ts +18 -13
  162. package/src/__tests__/require-fresh-approval.test.ts +13 -22
  163. package/src/__tests__/runtime-attachment-metadata.test.ts +1 -1
  164. package/src/__tests__/runtime-events-sse-parity.test.ts +3 -4
  165. package/src/__tests__/runtime-events-sse.test.ts +3 -12
  166. package/src/__tests__/search-skills-unified.test.ts +9 -15
  167. package/src/__tests__/secret-ingress-cli.test.ts +2 -5
  168. package/src/__tests__/secret-ingress-http.test.ts +0 -4
  169. package/src/__tests__/secret-onetime-send.test.ts +4 -2
  170. package/src/__tests__/secret-prompt-log-hygiene.test.ts +24 -7
  171. package/src/__tests__/secret-prompter-channel-fallback.test.ts +42 -47
  172. package/src/__tests__/secret-response-routing.test.ts +29 -15
  173. package/src/__tests__/secret-routes-managed-proxy.test.ts +5 -1
  174. package/src/__tests__/secret-scanner.test.ts +2 -545
  175. package/src/__tests__/send-endpoint-busy.test.ts +9 -24
  176. package/src/__tests__/settings-routes.test.ts +1 -1
  177. package/src/__tests__/shell-credential-ref.test.ts +0 -8
  178. package/src/__tests__/shell-tool-proxy-mode.test.ts +0 -56
  179. package/src/__tests__/skill-script-runner-sandbox.test.ts +0 -11
  180. package/src/__tests__/skill-tool-factory.test.ts +97 -0
  181. package/src/__tests__/skills-file-content-endpoint.test.ts +9 -30
  182. package/src/__tests__/skills-files-catalog-fallback.test.ts +11 -17
  183. package/src/__tests__/slack-inbound-verification.test.ts +1 -62
  184. package/src/__tests__/subagent-fork-notifications.test.ts +57 -47
  185. package/src/__tests__/subagent-manager-notify.test.ts +70 -70
  186. package/src/__tests__/subagent-notify-parent.test.ts +80 -83
  187. package/src/__tests__/system-prompt.test.ts +115 -13
  188. package/src/__tests__/terminal-tools.test.ts +0 -89
  189. package/src/__tests__/thread-backfill.test.ts +945 -31
  190. package/src/__tests__/tool-domain-event-publisher.test.ts +0 -36
  191. package/src/__tests__/tool-execute-pipeline.test.ts +0 -6
  192. package/src/__tests__/tool-execution-abort-cleanup.test.ts +0 -16
  193. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +9 -19
  194. package/src/__tests__/tool-executor-lifecycle-events.test.ts +4 -7
  195. package/src/__tests__/tool-executor.test.ts +12 -19
  196. package/src/__tests__/tool-metrics-listener.test.ts +0 -35
  197. package/src/__tests__/tool-side-effects-slack-dm.test.ts +1 -0
  198. package/src/__tests__/tool-trace-listener.test.ts +0 -17
  199. package/src/__tests__/transfer-progress-screen.test.ts +63 -26
  200. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +2 -149
  201. package/src/__tests__/trusted-contact-multichannel.test.ts +2 -4
  202. package/src/__tests__/trusted-contact-verification.test.ts +1 -1
  203. package/src/__tests__/tts-catalog-parity.test.ts +16 -5
  204. package/src/__tests__/usage-attribution.test.ts +247 -0
  205. package/src/__tests__/usage-cli.test.ts +143 -0
  206. package/src/__tests__/usage-grouped-buckets.test.ts +155 -0
  207. package/src/__tests__/usage-routes.test.ts +150 -0
  208. package/src/__tests__/validation-results-screen.test.ts +39 -16
  209. package/src/__tests__/vbundle-pax-and-symlink.test.ts +12 -3
  210. package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +49 -137
  211. package/src/__tests__/verification-control-plane-policy.test.ts +4 -7
  212. package/src/__tests__/voice-session-bridge.test.ts +5 -5
  213. package/src/__tests__/workspace-migration-062-drop-memory-v2-edges-json.test.ts +103 -0
  214. package/src/__tests__/workspace-migration-063-release-notes-dynamic-model-context.test.ts +77 -0
  215. package/src/__tests__/workspace-migration-064-unwind-main-agent-opus-seed.test.ts +225 -0
  216. package/src/__tests__/workspace-migration-memory-v2-init.test.ts +8 -30
  217. package/src/acp/index.ts +0 -15
  218. package/src/acp/session-manager.ts +37 -34
  219. package/src/agent/loop.ts +16 -1
  220. package/src/approvals/AGENTS.md +4 -0
  221. package/src/approvals/__tests__/guardian-feed-event.test.ts +10 -3
  222. package/src/approvals/guardian-request-resolvers.ts +10 -2
  223. package/src/backup/__tests__/backup-worker.test.ts +36 -8
  224. package/src/backup/__tests__/paths.test.ts +2 -2
  225. package/src/backup/__tests__/restore.test.ts +45 -28
  226. package/src/backup/backup-worker.ts +36 -2
  227. package/src/backup/paths.ts +9 -6
  228. package/src/browser-session/events.ts +0 -9
  229. package/src/calls/call-store.ts +1 -34
  230. package/src/calls/guardian-question-copy.ts +0 -108
  231. package/src/calls/relay-server.ts +0 -24
  232. package/src/calls/twilio-rest.ts +0 -38
  233. package/src/calls/twilio-routes.ts +1 -1
  234. package/src/calls/voice-session-bridge.ts +7 -38
  235. package/src/channels/types.ts +1 -36
  236. package/src/cli/commands/__tests__/cache.test.ts +152 -5
  237. package/src/cli/commands/__tests__/memory-v2.test.ts +14 -28
  238. package/src/cli/commands/__tests__/trust.test.ts +21 -387
  239. package/src/cli/commands/backup.ts +4 -4
  240. package/src/cli/commands/cache-fs.ts +8 -0
  241. package/src/cli/commands/cache.ts +153 -82
  242. package/src/cli/commands/clients.ts +63 -5
  243. package/src/cli/commands/completions.ts +3 -3
  244. package/src/cli/commands/contacts.ts +231 -76
  245. package/src/cli/commands/keys.ts +4 -1
  246. package/src/cli/commands/memory-v2.ts +24 -52
  247. package/src/cli/commands/oauth/shared.ts +2 -29
  248. package/src/cli/commands/pending.ts +102 -0
  249. package/src/cli/commands/skills.ts +77 -35
  250. package/src/cli/commands/trust.ts +70 -430
  251. package/src/cli/commands/usage.ts +25 -16
  252. package/src/cli/lib/daemon-credential-client.ts +14 -0
  253. package/src/cli/program.ts +2 -0
  254. package/src/cli.ts +0 -21
  255. package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
  256. package/src/config/bundled-skills/messaging/TOOLS.json +14 -4
  257. package/src/config/env-registry.ts +12 -2
  258. package/src/config/env.ts +3 -14
  259. package/src/config/feature-flag-registry.json +30 -30
  260. package/src/config/llm-callsite-catalog.ts +12 -0
  261. package/src/config/llm-context-resolution.ts +80 -0
  262. package/src/config/llm-resolver.ts +58 -22
  263. package/src/config/loader.ts +3 -3
  264. package/src/config/schema.ts +2 -158
  265. package/src/config/schemas/__tests__/memory-v2.test.ts +1 -0
  266. package/src/config/schemas/call-site-catalog.ts +271 -0
  267. package/src/config/schemas/calls.ts +5 -5
  268. package/src/config/schemas/inference.ts +1 -1
  269. package/src/config/schemas/ingress.ts +1 -1
  270. package/src/config/schemas/llm.ts +31 -3
  271. package/src/config/schemas/memory-retrieval.ts +2 -2
  272. package/src/config/schemas/memory-v2.ts +9 -0
  273. package/src/config/schemas/security.ts +1 -42
  274. package/src/config/schemas/services.ts +6 -6
  275. package/src/config/schemas/skills.ts +5 -5
  276. package/src/config/schemas/tts.ts +1 -1
  277. package/src/config/seed-inference-profiles.ts +117 -0
  278. package/src/config/skills.ts +0 -90
  279. package/src/config/types.ts +3 -6
  280. package/src/contacts/contact-store.ts +0 -17
  281. package/src/contacts/contacts-write.ts +1 -105
  282. package/src/context/window-manager.ts +44 -5
  283. package/src/credential-execution/process-manager.ts +34 -10
  284. package/src/credential-health/credential-health-service.ts +21 -16
  285. package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +75 -82
  286. package/src/daemon/__tests__/daemon-skill-host.test.ts +2 -9
  287. package/src/daemon/connection-policy.ts +1 -26
  288. package/src/daemon/conversation-agent-loop-handlers.ts +53 -4
  289. package/src/daemon/conversation-agent-loop.ts +277 -36
  290. package/src/daemon/conversation-history.ts +8 -8
  291. package/src/daemon/conversation-launch.ts +20 -135
  292. package/src/daemon/conversation-lifecycle.ts +1 -1
  293. package/src/daemon/conversation-messaging.ts +1 -0
  294. package/src/daemon/conversation-process.ts +83 -163
  295. package/src/daemon/conversation-runtime-assembly.ts +219 -76
  296. package/src/daemon/conversation-slash.ts +47 -5
  297. package/src/daemon/conversation-store.ts +7 -31
  298. package/src/daemon/conversation-surfaces.ts +22 -28
  299. package/src/daemon/conversation-tool-setup.ts +3 -33
  300. package/src/daemon/conversation-usage.ts +36 -0
  301. package/src/daemon/conversation.ts +117 -233
  302. package/src/daemon/daemon-control.ts +3 -71
  303. package/src/daemon/daemon-skill-host.ts +8 -11
  304. package/src/daemon/dictation-profile-store.ts +2 -26
  305. package/src/daemon/first-greeting.ts +44 -156
  306. package/src/daemon/handlers/config-channels.ts +12 -12
  307. package/src/daemon/handlers/config-ingress.ts +4 -165
  308. package/src/daemon/handlers/config-model.ts +1 -1
  309. package/src/daemon/handlers/config-voice.ts +0 -42
  310. package/src/daemon/handlers/conversations.ts +11 -190
  311. package/src/daemon/handlers/recording.ts +26 -158
  312. package/src/daemon/handlers/shared.ts +23 -71
  313. package/src/daemon/handlers/skills.ts +42 -93
  314. package/src/daemon/host-bash-proxy.ts +67 -45
  315. package/src/daemon/host-browser-proxy.ts +65 -27
  316. package/src/daemon/host-cu-proxy.ts +40 -39
  317. package/src/daemon/host-file-proxy.ts +58 -37
  318. package/src/daemon/host-transfer-proxy.ts +84 -46
  319. package/src/daemon/lifecycle.ts +49 -15
  320. package/src/daemon/message-types/conversations.ts +7 -0
  321. package/src/daemon/message-types/host-bash.ts +1 -0
  322. package/src/daemon/message-types/host-cu.ts +1 -0
  323. package/src/daemon/message-types/host-file.ts +1 -0
  324. package/src/daemon/message-types/host-transfer.ts +1 -0
  325. package/src/daemon/message-types/messages.ts +10 -9
  326. package/src/daemon/message-types/workspace.ts +1 -1
  327. package/src/daemon/process-message.ts +102 -239
  328. package/src/daemon/server.ts +13 -462
  329. package/src/daemon/shutdown-handlers.ts +2 -2
  330. package/src/daemon/tool-side-effects.ts +125 -107
  331. package/src/daemon/trust-context.ts +13 -0
  332. package/src/daemon/wake-target-adapter.ts +4 -9
  333. package/src/events/domain-events.ts +0 -8
  334. package/src/events/tool-audit-listener.ts +3 -1
  335. package/src/events/tool-domain-event-publisher.ts +0 -10
  336. package/src/events/tool-metrics-listener.ts +0 -17
  337. package/src/events/tool-trace-listener.ts +0 -14
  338. package/src/filing/filing-service.ts +13 -1
  339. package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +6 -2
  340. package/src/heartbeat/heartbeat-service.ts +23 -5
  341. package/src/home/__tests__/feed-writer.test.ts +0 -4
  342. package/src/home/__tests__/relationship-state-writer.test.ts +30 -0
  343. package/src/home/feed-writer.ts +1 -2
  344. package/src/home/relationship-state-writer.ts +16 -3
  345. package/src/ipc/__tests__/browser-ipc.test.ts +2 -12
  346. package/src/ipc/__tests__/skill-server-bidirectional.test.ts +0 -1
  347. package/src/ipc/assistant-server.ts +3 -10
  348. package/src/ipc/routes/__tests__/memory-v2-backfill.test.ts +39 -20
  349. package/src/ipc/routes/route-adapter.ts +1 -1
  350. package/src/ipc/routes/trust-rules.test.ts +0 -95
  351. package/src/ipc/skill-ipc-types.ts +41 -0
  352. package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +13 -27
  353. package/src/ipc/skill-routes/__tests__/identity.test.ts +4 -23
  354. package/src/ipc/skill-routes/events.ts +12 -23
  355. package/src/ipc/skill-routes/identity.ts +4 -17
  356. package/src/ipc/skill-routes/index.ts +1 -1
  357. package/src/ipc/skill-server.ts +6 -39
  358. package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +0 -8
  359. package/src/live-voice/protocol.ts +4 -13
  360. package/src/mcp/manager.ts +0 -5
  361. package/src/memory/__tests__/fixtures/memory-v2-activation-fixtures.ts +55 -0
  362. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +127 -0
  363. package/src/memory/app-git-service.ts +0 -32
  364. package/src/memory/app-store.ts +154 -0
  365. package/src/memory/attachments-store.ts +6 -0
  366. package/src/memory/context-search/sources/memory-v2.ts +578 -0
  367. package/src/memory/context-search/sources/memory.ts +5 -0
  368. package/src/memory/context-search/sources/pkb.ts +10 -1
  369. package/src/memory/context-search/sources/workspace.ts +3 -2
  370. package/src/memory/conversation-crud.ts +29 -4
  371. package/src/memory/conversation-disk-view.ts +1 -5
  372. package/src/memory/conversation-starter-checkpoints.ts +63 -0
  373. package/src/memory/db-connection.ts +62 -0
  374. package/src/memory/db-init.ts +14 -0
  375. package/src/memory/embedding-backend.ts +3 -21
  376. package/src/memory/embedding-gemini.ts +0 -2
  377. package/src/memory/embedding-local.ts +6 -6
  378. package/src/memory/embedding-ollama.ts +6 -6
  379. package/src/memory/embedding-openai.ts +6 -6
  380. package/src/memory/embedding-types.ts +21 -0
  381. package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +3 -7
  382. package/src/memory/graph/conversation-graph-memory.ts +35 -13
  383. package/src/memory/graph/injection.test.ts +2 -2
  384. package/src/memory/graph/injection.ts +1 -1
  385. package/src/memory/guardian-action-store.ts +0 -83
  386. package/src/memory/guardian-approvals.ts +0 -48
  387. package/src/memory/indexer.ts +1 -15
  388. package/src/memory/job-handlers/conversation-starters.ts +36 -53
  389. package/src/memory/job-utils.ts +0 -6
  390. package/src/memory/jobs-store.ts +0 -1
  391. package/src/memory/jobs-worker.ts +2 -16
  392. package/src/memory/llm-request-log-store.ts +0 -41
  393. package/src/memory/llm-usage-store.ts +129 -43
  394. package/src/memory/memory-v2-activation-log-store.ts +115 -0
  395. package/src/memory/migrations/233-document-conversations.ts +54 -0
  396. package/src/memory/migrations/234-memory-v2-activation-logs.ts +55 -0
  397. package/src/memory/migrations/235-llm-usage-attribution.ts +31 -0
  398. package/src/memory/migrations/235-slack-compaction-watermark.ts +44 -0
  399. package/src/memory/migrations/236-tool-invocations-matched-rule-id.ts +26 -0
  400. package/src/memory/migrations/__tests__/234-memory-v2-activation-logs.test.ts +182 -0
  401. package/src/memory/migrations/index.ts +14 -0
  402. package/src/memory/migrations/registry.ts +24 -0
  403. package/src/memory/raw-query.ts +2 -68
  404. package/src/memory/schema/conversations.ts +7 -0
  405. package/src/memory/schema/infrastructure.ts +25 -0
  406. package/src/memory/search/semantic.ts +5 -16
  407. package/src/memory/tool-usage-store.ts +2 -0
  408. package/src/memory/usage-buckets.ts +40 -1
  409. package/src/memory/usage-grouped-buckets.ts +127 -0
  410. package/src/memory/v2/__tests__/activation.test.ts +289 -90
  411. package/src/memory/v2/__tests__/backfill-jobs.test.ts +2 -129
  412. package/src/memory/v2/__tests__/consolidation-job.test.ts +28 -11
  413. package/src/memory/v2/__tests__/edge-index.test.ts +278 -0
  414. package/src/memory/v2/__tests__/injection.test.ts +384 -15
  415. package/src/memory/v2/__tests__/migration.test.ts +64 -36
  416. package/src/memory/v2/__tests__/page-store.test.ts +191 -8
  417. package/src/memory/v2/__tests__/prompts-consolidation.test.ts +181 -0
  418. package/src/memory/v2/__tests__/skill-store.test.ts +115 -3
  419. package/src/memory/v2/__tests__/static-context.test.ts +153 -0
  420. package/src/memory/v2/activation.ts +168 -97
  421. package/src/memory/v2/backfill-jobs.ts +15 -100
  422. package/src/memory/v2/consolidation-job.ts +14 -12
  423. package/src/memory/v2/edge-index.ts +191 -0
  424. package/src/memory/v2/injection.ts +182 -58
  425. package/src/memory/v2/migration.ts +57 -64
  426. package/src/memory/v2/now-text.ts +2 -3
  427. package/src/memory/v2/page-store.ts +168 -31
  428. package/src/memory/v2/prompts/consolidation.ts +118 -42
  429. package/src/memory/v2/prompts/sweep.ts +3 -3
  430. package/src/memory/v2/skill-store.ts +55 -7
  431. package/src/memory/v2/static-context.ts +62 -0
  432. package/src/memory/v2/types.ts +10 -20
  433. package/src/memory/validation.ts +0 -11
  434. package/src/messaging/draft-store.ts +0 -6
  435. package/src/messaging/provider-types.ts +8 -0
  436. package/src/messaging/provider.ts +7 -0
  437. package/src/messaging/providers/gmail/client.ts +1 -121
  438. package/src/messaging/providers/outlook/client.ts +0 -73
  439. package/src/messaging/providers/slack/__tests__/adapter-mention-rendering.test.ts +226 -0
  440. package/src/messaging/providers/slack/adapter.ts +122 -21
  441. package/src/messaging/providers/slack/backfill.test.ts +95 -6
  442. package/src/messaging/providers/slack/backfill.ts +89 -11
  443. package/src/messaging/providers/slack/client.ts +10 -124
  444. package/src/messaging/providers/slack/message-metadata.ts +12 -2
  445. package/src/messaging/providers/slack/render-transcript.test.ts +56 -0
  446. package/src/messaging/providers/slack/render-transcript.ts +126 -25
  447. package/src/messaging/providers/slack/types.ts +1 -0
  448. package/src/oauth/connection-resolver.test.ts +8 -0
  449. package/src/oauth/connection-resolver.ts +8 -16
  450. package/src/oauth/credential-token-resolver.ts +97 -0
  451. package/src/oauth/manual-token-connection.ts +30 -34
  452. package/src/oauth/oauth-store.ts +6 -4
  453. package/src/outbound-proxy/certs.ts +0 -7
  454. package/src/outbound-proxy/config.ts +0 -74
  455. package/src/outbound-proxy/health.ts +0 -44
  456. package/src/outbound-proxy/index.ts +0 -22
  457. package/src/permissions/approval-provenance.test.ts +184 -0
  458. package/src/permissions/approval-provenance.ts +70 -0
  459. package/src/permissions/checker.ts +4 -1
  460. package/src/permissions/gateway-threshold-reader.ts +4 -1
  461. package/src/permissions/prompter.ts +9 -2
  462. package/src/permissions/secret-prompter.ts +21 -48
  463. package/src/permissions/types.ts +33 -0
  464. package/src/permissions/workspace-policy.ts +0 -5
  465. package/src/platform/sync-identity.ts +0 -8
  466. package/src/plugins/defaults/injectors.ts +69 -2
  467. package/src/plugins/defaults/overflow-reduce.ts +3 -2
  468. package/src/plugins/types.ts +8 -0
  469. package/src/prompts/system-prompt.ts +34 -70
  470. package/src/prompts/templates/BOOTSTRAP.md +52 -6
  471. package/src/prompts/update-bulletin-job.ts +2 -0
  472. package/src/providers/__tests__/retry-callsite.test.ts +138 -1
  473. package/src/providers/anthropic/client.ts +72 -33
  474. package/src/providers/call-site-routing.ts +42 -3
  475. package/src/providers/gemini/client.ts +18 -2
  476. package/src/providers/managed-proxy/context.ts +0 -5
  477. package/src/providers/model-catalog.ts +105 -19
  478. package/src/providers/openai/chat-completions-provider.ts +6 -0
  479. package/src/providers/openai/responses-provider.ts +7 -1
  480. package/src/providers/provider-send-message.ts +45 -2
  481. package/src/providers/ratelimit.ts +7 -2
  482. package/src/providers/registry.ts +14 -9
  483. package/src/providers/retry.ts +96 -8
  484. package/src/providers/types.ts +13 -0
  485. package/src/providers/usage-tracking.ts +96 -0
  486. package/src/runtime/AGENTS.md +10 -6
  487. package/src/runtime/__tests__/agent-wake.test.ts +89 -0
  488. package/src/runtime/agent-wake.ts +39 -2
  489. package/src/runtime/assistant-event-hub.ts +541 -45
  490. package/src/runtime/assistant-event.ts +1 -6
  491. package/src/runtime/auth/context.ts +0 -9
  492. package/src/runtime/auth/middleware.ts +1 -1
  493. package/src/runtime/auth/route-policy.ts +11 -9
  494. package/src/runtime/auth/token-service.ts +0 -11
  495. package/src/runtime/channel-approvals.ts +6 -2
  496. package/src/runtime/channel-verification-service.ts +3 -5
  497. package/src/runtime/http-errors.ts +0 -34
  498. package/src/runtime/http-router.ts +6 -3
  499. package/src/runtime/http-server.ts +22 -82
  500. package/src/runtime/http-types.ts +5 -0
  501. package/src/runtime/interactive-ui.ts +0 -1
  502. package/src/runtime/middleware/auth.ts +0 -20
  503. package/src/runtime/migrations/__tests__/v1-test-helpers.ts +112 -0
  504. package/src/runtime/migrations/__tests__/vbundle-builder-credentials.test.ts +11 -4
  505. package/src/runtime/migrations/__tests__/vbundle-builder-v1-shape.test.ts +253 -0
  506. package/src/runtime/migrations/__tests__/vbundle-import-credentials.test.ts +19 -6
  507. package/src/runtime/migrations/__tests__/vbundle-legacy-user-md.test.ts +71 -27
  508. package/src/runtime/migrations/__tests__/vbundle-metadata-merge-integration.test.ts +41 -2
  509. package/src/runtime/migrations/__tests__/vbundle-streaming-importer.test.ts +143 -79
  510. package/src/runtime/migrations/__tests__/vbundle-streaming-validator.test.ts +143 -23
  511. package/src/runtime/migrations/__tests__/vbundle-tar-stream.test.ts +2 -2
  512. package/src/runtime/migrations/__tests__/vbundle-validator-v1-schema.test.ts +371 -0
  513. package/src/runtime/migrations/migration-transport.ts +46 -13
  514. package/src/runtime/migrations/migration-wizard.ts +2 -2
  515. package/src/runtime/migrations/origin-mode.ts +40 -0
  516. package/src/runtime/migrations/vbundle-builder.ts +133 -79
  517. package/src/runtime/migrations/vbundle-import-analyzer.ts +9 -7
  518. package/src/runtime/migrations/vbundle-importer.ts +7 -7
  519. package/src/runtime/migrations/vbundle-metadata-merge.ts +1 -1
  520. package/src/runtime/migrations/vbundle-streaming-importer.ts +3 -3
  521. package/src/runtime/migrations/vbundle-streaming-validator.ts +48 -26
  522. package/src/runtime/migrations/vbundle-validator.ts +214 -41
  523. package/src/runtime/pending-interactions.ts +13 -4
  524. package/src/runtime/routes/__tests__/acp-routes.test.ts +0 -1
  525. package/src/runtime/routes/__tests__/backup-routes.test.ts +28 -19
  526. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +235 -0
  527. package/src/runtime/routes/__tests__/llm-call-sites-routes.test.ts +58 -0
  528. package/src/runtime/routes/__tests__/migration-export-secrets-redacted.test.ts +54 -0
  529. package/src/runtime/routes/__tests__/migration-import-credential-filter.test.ts +19 -6
  530. package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +7 -7
  531. package/src/runtime/routes/acp-routes.test.ts +0 -3
  532. package/src/runtime/routes/acp-routes.ts +3 -7
  533. package/src/runtime/routes/app-management-routes.ts +18 -9
  534. package/src/runtime/routes/approval-routes.ts +55 -14
  535. package/src/runtime/routes/avatar-routes.ts +3 -5
  536. package/src/runtime/routes/browser-routes.ts +1 -15
  537. package/src/runtime/routes/channel-guardian-routes.ts +1 -5
  538. package/src/runtime/routes/channel-readiness-routes.ts +3 -7
  539. package/src/runtime/routes/channel-route-shared.ts +2 -28
  540. package/src/runtime/routes/client-routes.ts +45 -12
  541. package/src/runtime/routes/consolidation-routes.ts +115 -0
  542. package/src/runtime/routes/conversation-list-routes.ts +12 -29
  543. package/src/runtime/routes/conversation-management-routes.ts +14 -51
  544. package/src/runtime/routes/conversation-query-routes.ts +120 -8
  545. package/src/runtime/routes/conversation-routes.ts +44 -528
  546. package/src/runtime/routes/conversation-starter-routes.ts +19 -40
  547. package/src/runtime/routes/documents-routes.ts +53 -18
  548. package/src/runtime/routes/events-routes.ts +59 -91
  549. package/src/runtime/routes/filing-routes.ts +18 -1
  550. package/src/runtime/routes/guardian-action-routes.ts +4 -9
  551. package/src/runtime/routes/host-bash-routes.ts +3 -2
  552. package/src/runtime/routes/host-browser-routes.ts +9 -33
  553. package/src/runtime/routes/host-cu-routes.ts +6 -1
  554. package/src/runtime/routes/host-file-routes.ts +3 -2
  555. package/src/runtime/routes/host-transfer-routes.ts +11 -15
  556. package/src/runtime/routes/identity-routes.ts +78 -6
  557. package/src/runtime/routes/inbound-message-handler.ts +580 -137
  558. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +2 -88
  559. package/src/runtime/routes/inbound-stages/background-dispatch.ts +3 -0
  560. package/src/runtime/routes/index.ts +4 -0
  561. package/src/runtime/routes/integrations/slack/channel.ts +0 -24
  562. package/src/runtime/routes/llm-call-sites-routes.ts +22 -0
  563. package/src/runtime/routes/memory-v2-routes.ts +10 -15
  564. package/src/runtime/routes/migration-routes.ts +188 -31
  565. package/src/runtime/routes/playground/guard.ts +1 -1
  566. package/src/runtime/routes/playground/index.ts +0 -2
  567. package/src/runtime/routes/recording-routes.ts +4 -24
  568. package/src/runtime/routes/rename-conversation-routes.ts +2 -6
  569. package/src/runtime/routes/schedule-routes.ts +3 -6
  570. package/src/runtime/routes/secret-routes.ts +87 -18
  571. package/src/runtime/routes/settings-routes.ts +29 -28
  572. package/src/runtime/routes/skills-routes.ts +12 -31
  573. package/src/runtime/routes/suggest-trust-rule-routes.ts +32 -1
  574. package/src/runtime/routes/task-routes.ts +6 -6
  575. package/src/runtime/routes/trust-rules-routes.ts +3 -94
  576. package/src/runtime/routes/types.ts +4 -4
  577. package/src/runtime/routes/upgrade-broadcast-routes.ts +3 -10
  578. package/src/runtime/routes/usage-routes.ts +87 -10
  579. package/src/runtime/routes/user-routes.ts +17 -31
  580. package/src/runtime/routes/work-items-routes.ts +1 -4
  581. package/src/runtime/services/__tests__/analyze-conversation.test.ts +2 -2
  582. package/src/runtime/services/analyze-conversation.ts +7 -17
  583. package/src/runtime/services/conversation-serializer.ts +2 -4
  584. package/src/runtime/verification-outbound-actions.ts +1 -1
  585. package/src/runtime/verification-rate-limiter.ts +1 -1
  586. package/src/schedule/schedule-store.ts +0 -16
  587. package/src/security/secret-scanner.ts +14 -547
  588. package/src/security/secure-keys.ts +31 -11
  589. package/src/security/token-manager.ts +7 -3
  590. package/src/signals/cancel.ts +16 -25
  591. package/src/signals/conversation-undo.ts +2 -27
  592. package/src/signals/emit-event.ts +1 -2
  593. package/src/signals/user-message.ts +108 -22
  594. package/src/skills/catalog-install.ts +1 -0
  595. package/src/skills/clawhub.ts +2 -2
  596. package/src/skills/inline-command-runner.ts +1 -7
  597. package/src/subagent/manager.ts +67 -84
  598. package/src/tasks/task-store.ts +1 -28
  599. package/src/telemetry/types.ts +6 -0
  600. package/src/telemetry/usage-telemetry-reporter.test.ts +38 -15
  601. package/src/telemetry/usage-telemetry-reporter.ts +3 -5
  602. package/src/tools/acp/spawn.test.ts +1 -2
  603. package/src/tools/acp/steer.test.ts +1 -2
  604. package/src/tools/browser/__tests__/browser-status.test.ts +44 -127
  605. package/src/tools/browser/browser-execution.ts +31 -147
  606. package/src/tools/browser/cdp-client/__tests__/factory.test.ts +92 -68
  607. package/src/tools/browser/cdp-client/factory.ts +48 -76
  608. package/src/tools/browser/cdp-client/index.ts +1 -14
  609. package/src/tools/executor.ts +44 -31
  610. package/src/tools/host-filesystem/edit.ts +3 -2
  611. package/src/tools/host-filesystem/read.ts +3 -2
  612. package/src/tools/host-filesystem/transfer.test.ts +45 -42
  613. package/src/tools/host-filesystem/transfer.ts +4 -3
  614. package/src/tools/host-filesystem/write.ts +3 -2
  615. package/src/tools/host-terminal/host-shell.ts +4 -3
  616. package/src/tools/network/script-proxy/index.ts +1 -10
  617. package/src/tools/permission-checker.ts +66 -1
  618. package/src/tools/skills/sandbox-runner.ts +1 -6
  619. package/src/tools/skills/skill-tool-factory.ts +32 -0
  620. package/src/tools/terminal/safe-env.ts +1 -0
  621. package/src/tools/terminal/shell.ts +2 -78
  622. package/src/tools/types.ts +12 -39
  623. package/src/tts/__tests__/provider-catalog.test.ts +2 -2
  624. package/src/tts/provider-catalog.ts +1 -1
  625. package/src/usage/actors.ts +2 -1
  626. package/src/usage/attribution.ts +185 -0
  627. package/src/usage/pricing.ts +166 -0
  628. package/src/usage/types.ts +14 -0
  629. package/src/util/json.ts +13 -0
  630. package/src/util/logger.ts +3 -3
  631. package/src/util/pricing.ts +50 -3
  632. package/src/work-items/work-item-runner.ts +15 -42
  633. package/src/workspace/migrations/050-seed-main-agent-opus-callsite.ts +4 -3
  634. package/src/workspace/migrations/052-seed-default-inference-profiles.ts +3 -3
  635. package/src/workspace/migrations/060-memory-v2-init.ts +2 -18
  636. package/src/workspace/migrations/061-move-backup-key-to-workspace.ts +59 -0
  637. package/src/workspace/migrations/062-drop-memory-v2-edges-json.ts +27 -0
  638. package/src/workspace/migrations/063-release-notes-dynamic-model-context.ts +70 -0
  639. package/src/workspace/migrations/064-unwind-main-agent-opus-seed.ts +64 -0
  640. package/src/workspace/migrations/registry.ts +8 -0
  641. package/src/workspace/provider-commit-message-generator.ts +3 -3
  642. package/src/__tests__/sandbox-diagnostics.test.ts +0 -138
  643. package/src/__tests__/sandbox-host-parity.test.ts +0 -1024
  644. package/src/__tests__/secret-detection-handler.test.ts +0 -67
  645. package/src/__tests__/secret-scanner-executor.test.ts +0 -450
  646. package/src/__tests__/tcc-sandbox-deny.test.ts +0 -198
  647. package/src/__tests__/terminal-sandbox.test.ts +0 -374
  648. package/src/__tests__/tool-notification-listener.test.ts +0 -65
  649. package/src/context/__tests__/microcompact.test.ts +0 -805
  650. package/src/context/microcompact.ts +0 -443
  651. package/src/daemon/handlers/slack-channel-oauth-install.ts +0 -197
  652. package/src/events/tool-notification-listener.ts +0 -17
  653. package/src/ipc/routes/__tests__/memory-v2-validate.test.ts +0 -219
  654. package/src/memory/v2/__tests__/edges.test.ts +0 -435
  655. package/src/memory/v2/edges.ts +0 -217
  656. package/src/prompts/__tests__/system-prompt-memory-v2.test.ts +0 -197
  657. package/src/runtime/__tests__/chrome-extension-registry.test.ts +0 -518
  658. package/src/runtime/__tests__/client-registry.test.ts +0 -271
  659. package/src/runtime/chrome-extension-registry.ts +0 -368
  660. package/src/runtime/client-registry.ts +0 -254
  661. package/src/runtime/routes/inbound-stages/verification-intercept.ts +0 -329
  662. package/src/tools/secret-detection-handler.ts +0 -269
  663. package/src/tools/terminal/backends/native.ts +0 -327
  664. package/src/tools/terminal/backends/types.ts +0 -37
  665. package/src/tools/terminal/sandbox-diagnostics.ts +0 -87
  666. package/src/tools/terminal/sandbox.ts +0 -40
package/ARCHITECTURE.md CHANGED
@@ -1606,11 +1606,11 @@ graph TB
1606
1606
  Auto-approve thresholds are **gateway-owned** — they live in the gateway's SQLite database and are read by the assistant via IPC (`get_global_thresholds`, `get_conversation_threshold`). Users control thresholds via the **Settings UI** (Permissions & Privacy tab) or the **per-conversation risk tolerance picker**. When the gateway is unreachable, the assistant defaults to `"none"` (Strict) — fail-closed with no local fallback.
1607
1607
 
1608
1608
  | `autoApproveUpTo` | Low-risk tools | Medium-risk tools | High-risk tools |
1609
- | ------------------ | -------------- | ----------------- | --------------- |
1610
- | `"none"` | Prompted | Prompted | Prompted |
1611
- | `"low"` (default) | Auto-allowed | Prompted | Prompted |
1612
- | `"medium"` | Auto-allowed | Auto-allowed | Prompted |
1613
- | `"high"` | Auto-allowed | Auto-allowed | Auto-allowed |
1609
+ | ----------------- | -------------- | ----------------- | --------------- |
1610
+ | `"none"` | Prompted | Prompted | Prompted |
1611
+ | `"low"` (default) | Auto-allowed | Prompted | Prompted |
1612
+ | `"medium"` | Auto-allowed | Auto-allowed | Prompted |
1613
+ | `"high"` | Auto-allowed | Auto-allowed | Auto-allowed |
1614
1614
 
1615
1615
  When set to `"none"`, every tool invocation requires explicit approval. Explicit deny and ask rules always take precedence over the threshold.
1616
1616
 
@@ -1867,7 +1867,6 @@ Events emitted during a conversation lifecycle:
1867
1867
  | `tool_permission_decided` | ToolTraceListener | Permission granted or denied (carries `decision`) |
1868
1868
  | `tool_finished` | ToolTraceListener | Tool execution completed (carries `durationMs`) |
1869
1869
  | `tool_failed` | ToolTraceListener | Tool execution failed (carries `durationMs`) |
1870
- | `secret_detected` | ToolTraceListener | Secret found in tool output |
1871
1870
  | `generation_handoff` | Conversation | Yielding to next queued message |
1872
1871
  | `message_complete` | Conversation | Full request processing finished |
1873
1872
  | `generation_cancelled` | Conversation | User cancelled the generation |
@@ -1876,7 +1875,7 @@ Events emitted during a conversation lifecycle:
1876
1875
  ### Architecture
1877
1876
 
1878
1877
  - **TraceEmitter** (daemon, per-conversation): Constructed with a `conversationId` and a `sendToClient` callback. Maintains a monotonic sequence counter for stable ordering. Truncates summaries to 200 chars and attribute values to 500 chars. Each call to `emit()` sends a `trace_event` SSE event to connected clients.
1879
- - **ToolTraceListener** (daemon): Subscribes to the conversation's `EventBus` via `onAny()` and translates tool domain events (`tool.execution.started`, `tool.execution.finished`, `tool.execution.failed`, `tool.permission.requested`, `tool.permission.decided`, `tool.secret.detected`) into trace events through the `TraceEmitter`.
1878
+ - **ToolTraceListener** (daemon): Subscribes to the conversation's `EventBus` via `onAny()` and translates tool domain events (`tool.execution.started`, `tool.execution.finished`, `tool.execution.failed`, `tool.permission.requested`, `tool.permission.decided`) into trace events through the `TraceEmitter`.
1880
1879
  - **DaemonClient** (Swift, shared): Decodes `trace_event` SSE events into `TraceEventMessage` structs and invokes the `onTraceEvent` callback.
1881
1880
  - **TraceStore** (Swift, macOS): `@MainActor ObservableObject` that ingests `TraceEventMessage` structs. Deduplicates by `eventId`, maintains stable sort order (sequence, then timestampMs, then insertion order), groups events by conversation and requestId, and enforces a retention cap of 5,000 events per conversation. Each request group is classified with a terminal status: `completed` (via `message_complete`), `cancelled` (via `generation_cancelled`), `handedOff` (via `generation_handoff`), `error` (via `request_error` or any event with `status == "error"`), or `active` (no terminal event yet).
1882
1881
  - **DebugPanel** (Swift, macOS): SwiftUI view that observes `TraceStore`. Displays a metrics strip (request count, LLM calls, total tokens, average latency, tool failures) and a `TraceTimelineView` showing events grouped by requestId with color-coded status indicators. The timeline auto-scrolls to new events while the user is at the bottom; scrolling up pauses auto-scroll and shows a "Jump to bottom" button that resumes it.
package/Dockerfile CHANGED
@@ -23,6 +23,7 @@ COPY packages/credential-storage ./packages/credential-storage
23
23
  COPY packages/egress-proxy ./packages/egress-proxy
24
24
  COPY packages/gateway-client ./packages/gateway-client
25
25
  COPY packages/skill-host-contracts ./packages/skill-host-contracts
26
+ COPY packages/slack-text ./packages/slack-text
26
27
 
27
28
  # Install deps for shared packages that have their own file: dependencies.
28
29
  # Without this, bun's module resolution at runtime walks up from e.g.
package/README.md CHANGED
@@ -85,7 +85,7 @@ bun run src/index.ts # interactive CLI session
85
85
  | `assistant conversations list\|new\|export\|clear` | Manage conversations |
86
86
  | `assistant config set\|get\|list` | Manage configuration |
87
87
  | `assistant keys set\|list\|delete` | Manage API keys in secure storage |
88
- | `assistant trust list\|add\|update\|remove` | Manage trust rules |
88
+ | `assistant trust list\|add\|update\|remove` | Manage trust rules |
89
89
 
90
90
  ## Project Structure
91
91
 
@@ -189,7 +189,7 @@ Internal forwarding routes (`/v1/internal/twilio/*`) are unaffected — these ac
189
189
  The `/channels/inbound` endpoint requires a JWT with the `svc_gateway` principal type and `ingress.write` scope to prove the request originated from the gateway. This ensures channel messages can only arrive via the gateway (which performs webhook-level verification) and not via direct HTTP calls that bypass signature checks.
190
190
 
191
191
  - **JWT-based enforcement:** The route policy in `route-policy.ts` restricts `/channels/inbound` to the `svc_gateway` principal type with `ingress.write` scope. Actor and local principals are rejected with 403.
192
- - **Dev bypass:** When `DISABLE_HTTP_AUTH` + `VELLUM_UNSAFE_AUTH_BYPASS=1` are set, JWT verification is skipped and a synthetic dev context is used.
192
+ - **Auth bypass:** When `DISABLE_HTTP_AUTH=true` is set (platform-managed deployments), JWT verification is skipped and a synthetic context is used.
193
193
 
194
194
  ## Twilio Setup Primitive
195
195
 
@@ -2,35 +2,32 @@ import { afterEach, describe, expect, mock, test } from "bun:test";
2
2
 
3
3
  // ── Mocks ────────────────────────────────────────────────────────────────────
4
4
 
5
- let mockFeatureFlagEnabled = true;
6
-
7
5
  mock.module("../../src/config/assistant-feature-flags.js", () => ({
8
- isAssistantFeatureFlagEnabled: (_key: string, _config: unknown) =>
9
- mockFeatureFlagEnabled,
6
+ isAssistantFeatureFlagEnabled: () => true,
10
7
  }));
11
8
 
12
9
  mock.module("../../src/config/loader.js", () => ({
13
10
  getConfig: () => ({}),
14
11
  }));
15
12
 
16
- // Track gatewayGet calls for assertion
17
- const gatewayGetCalls: string[] = [];
18
- let gatewayGetHandler: (path: string) => unknown = () => ({});
19
-
20
- mock.module("../../src/runtime/gateway-internal-client.js", () => ({
21
- GatewayRequestError: class GatewayRequestError extends Error {
22
- statusCode: number;
23
- gatewayError: string | undefined;
24
- constructor(message: string, statusCode: number, gatewayError?: string) {
25
- super(message);
26
- this.name = "GatewayRequestError";
27
- this.statusCode = statusCode;
28
- this.gatewayError = gatewayError;
29
- }
30
- },
31
- gatewayGet: async <T>(path: string): Promise<T> => {
32
- gatewayGetCalls.push(path);
33
- return gatewayGetHandler(path) as T;
13
+ // Track ipcCall invocations for assertion
14
+ const ipcCallLog: string[] = [];
15
+
16
+ // Handler receives (method, params) and returns the IPC response value.
17
+ // Return `undefined` to simulate a transport failure.
18
+ // Return `null` for get_conversation_threshold to indicate "no override".
19
+ type IpcHandler = (method: string, params?: Record<string, unknown>) => unknown;
20
+ let ipcHandler: IpcHandler = () => undefined;
21
+
22
+ mock.module("../../src/ipc/gateway-client.js", () => ({
23
+ ipcCall: async (method: string, params?: Record<string, unknown>) => {
24
+ // Normalise to a readable key for assertions
25
+ const key =
26
+ method === "get_conversation_threshold" && params?.conversationId
27
+ ? `/v1/permissions/thresholds/conversations/${params.conversationId}`
28
+ : "/v1/permissions/thresholds";
29
+ ipcCallLog.push(key);
30
+ return ipcHandler(method, params);
34
31
  },
35
32
  }));
36
33
 
@@ -48,42 +45,41 @@ import {
48
45
  _clearGlobalCacheForTesting,
49
46
  getAutoApproveThreshold,
50
47
  } from "../../src/permissions/gateway-threshold-reader.js";
51
- // Import GatewayRequestError from the mock so we can throw instances of it
52
- const { GatewayRequestError } =
53
- await import("../../src/runtime/gateway-internal-client.js");
54
48
 
55
49
  // ── Helpers ──────────────────────────────────────────────────────────────────
56
50
 
57
51
  function resetMocks(): void {
58
- mockFeatureFlagEnabled = true;
59
- gatewayGetCalls.length = 0;
60
- gatewayGetHandler = () => ({});
52
+ ipcCallLog.length = 0;
53
+ ipcHandler = () => undefined;
61
54
  _clearGlobalCacheForTesting();
62
55
  }
63
56
 
64
57
  afterEach(resetMocks);
65
58
 
59
+ // Convenience: set up a handler that returns the given global thresholds and,
60
+ // optionally, a per-conversation override threshold string.
61
+ function withGlobals(
62
+ globals: { interactive: string; autonomous: string },
63
+ conversationOverride?: { conversationId: string; threshold: string },
64
+ ): void {
65
+ ipcHandler = (method, params) => {
66
+ if (method === "get_global_thresholds") return globals;
67
+ if (method === "get_conversation_threshold") {
68
+ const id = params?.conversationId;
69
+ if (conversationOverride && id === conversationOverride.conversationId) {
70
+ return { threshold: conversationOverride.threshold };
71
+ }
72
+ return null; // no override
73
+ }
74
+ return undefined;
75
+ };
76
+ }
77
+
66
78
  // ── Tests ────────────────────────────────────────────────────────────────────
67
79
 
68
80
  describe("getAutoApproveThreshold", () => {
69
- test("returns undefined when feature flag is off", async () => {
70
- mockFeatureFlagEnabled = false;
71
- const result = await getAutoApproveThreshold("conv-123", "conversation");
72
- expect(result).toBeUndefined();
73
- // Should not make any gateway calls
74
- expect(gatewayGetCalls).toHaveLength(0);
75
- });
76
-
77
81
  test("returns global defaults when gateway returns them", async () => {
78
- gatewayGetHandler = (path: string) => {
79
- if (path === "/v1/permissions/thresholds") {
80
- return {
81
- interactive: "medium",
82
- autonomous: "low",
83
- };
84
- }
85
- return {};
86
- };
82
+ withGlobals({ interactive: "medium", autonomous: "low" });
87
83
 
88
84
  // conversation maps to interactive
89
85
  expect(await getAutoApproveThreshold(undefined, "conversation")).toBe(
@@ -102,105 +98,73 @@ describe("getAutoApproveThreshold", () => {
102
98
  });
103
99
 
104
100
  test("returns conversation override when it exists", async () => {
105
- gatewayGetHandler = (path: string) => {
106
- if (path === "/v1/permissions/thresholds/conversations/conv-xyz") {
107
- return { threshold: "medium" };
108
- }
109
- if (path === "/v1/permissions/thresholds") {
110
- return {
111
- interactive: "low",
112
- autonomous: "none",
113
- };
114
- }
115
- return {};
116
- };
101
+ withGlobals(
102
+ { interactive: "low", autonomous: "none" },
103
+ { conversationId: "conv-xyz", threshold: "medium" },
104
+ );
117
105
 
118
106
  const result = await getAutoApproveThreshold("conv-xyz", "conversation");
119
107
  expect(result).toBe("medium");
120
108
  // Should have called the conversation endpoint, not the global one
121
- expect(gatewayGetCalls).toEqual([
109
+ expect(ipcCallLog).toEqual([
122
110
  "/v1/permissions/thresholds/conversations/conv-xyz",
123
111
  ]);
124
112
  });
125
113
 
126
- test("falls back to global when conversation override returns 404", async () => {
127
- gatewayGetHandler = (path: string) => {
128
- if (path.startsWith("/v1/permissions/thresholds/conversations/")) {
129
- throw new GatewayRequestError("Not found", 404, "Not found");
130
- }
131
- if (path === "/v1/permissions/thresholds") {
132
- return {
133
- interactive: "low",
134
- autonomous: "none",
135
- };
136
- }
137
- return {};
138
- };
114
+ test("falls back to global when conversation override returns null (no override)", async () => {
115
+ withGlobals({ interactive: "low", autonomous: "none" });
116
+ // ipcHandler returns null for get_conversation_threshold (no row)
139
117
 
140
118
  const result = await getAutoApproveThreshold("conv-123", "conversation");
141
119
  expect(result).toBe("low");
142
- // Should have called both endpoints
143
- expect(gatewayGetCalls).toEqual([
120
+ // Called conversation endpoint first, then global
121
+ expect(ipcCallLog).toEqual([
144
122
  "/v1/permissions/thresholds/conversations/conv-123",
145
123
  "/v1/permissions/thresholds",
146
124
  ]);
147
125
  });
148
126
 
149
- test("falls back to hardcoded defaults on gateway error", async () => {
150
- gatewayGetHandler = () => {
127
+ test("falls back to global when conversation ipc returns undefined (transport failure)", async () => {
128
+ ipcHandler = (method) => {
129
+ if (method === "get_conversation_threshold") return undefined; // transport failure
130
+ if (method === "get_global_thresholds")
131
+ return { interactive: "low", autonomous: "none" };
132
+ return undefined;
133
+ };
134
+
135
+ const result = await getAutoApproveThreshold("conv-123", "conversation");
136
+ expect(result).toBe("low");
137
+ });
138
+
139
+ test("falls back to 'none' (Strict) for all contexts on global gateway failure", async () => {
140
+ // When the gateway IPC is unreachable, the reader defaults to "none" for
141
+ // all contexts — defense-in-depth ensures no tools are silently
142
+ // auto-approved when the gateway is down.
143
+ ipcHandler = () => {
151
144
  throw new Error("Connection refused");
152
145
  };
153
146
 
154
- // conversation → "low"
155
147
  expect(await getAutoApproveThreshold(undefined, "conversation")).toBe(
156
- "low",
148
+ "none",
157
149
  );
158
150
 
159
151
  _clearGlobalCacheForTesting();
160
152
 
161
- // background "none" (maps to autonomous, which defaults to "none")
162
- expect(await getAutoApproveThreshold(undefined, "background")).toBe(
163
- "none",
164
- );
153
+ expect(await getAutoApproveThreshold(undefined, "background")).toBe("none");
165
154
 
166
155
  _clearGlobalCacheForTesting();
167
156
 
168
- // headless → "none"
169
157
  expect(await getAutoApproveThreshold(undefined, "headless")).toBe("none");
170
158
  });
171
159
 
172
- test("falls back to hardcoded defaults on non-404 conversation error", async () => {
173
- gatewayGetHandler = (path: string) => {
174
- if (path.startsWith("/v1/permissions/thresholds/conversations/")) {
175
- throw new GatewayRequestError("Internal error", 500, "Server error");
176
- }
177
- // Should not reach global endpoint
178
- return {
179
- interactive: "medium",
180
- autonomous: "medium",
181
- };
182
- };
183
-
184
- const result = await getAutoApproveThreshold("conv-123", "conversation");
185
- // Should fall back to hardcoded default for conversation, not global endpoint
186
- expect(result).toBe("low");
187
- // Should have only called the conversation endpoint
188
- expect(gatewayGetCalls).toEqual([
189
- "/v1/permissions/thresholds/conversations/conv-123",
190
- ]);
191
- });
192
-
193
160
  test("caching: second call within 30s does not re-fetch global", async () => {
194
161
  let fetchCount = 0;
195
- gatewayGetHandler = (path: string) => {
196
- if (path === "/v1/permissions/thresholds") {
162
+ ipcHandler = (method) => {
163
+ if (method === "get_global_thresholds") {
197
164
  fetchCount++;
198
- return {
199
- interactive: "medium",
200
- autonomous: "low",
201
- };
165
+ return { interactive: "medium", autonomous: "low" };
202
166
  }
203
- return {};
167
+ return null;
204
168
  };
205
169
 
206
170
  // First call — should fetch
@@ -226,15 +190,7 @@ describe("getAutoApproveThreshold", () => {
226
190
  });
227
191
 
228
192
  test("defaults executionContext to conversation when omitted", async () => {
229
- gatewayGetHandler = (path: string) => {
230
- if (path === "/v1/permissions/thresholds") {
231
- return {
232
- interactive: "medium",
233
- autonomous: "low",
234
- };
235
- }
236
- return {};
237
- };
193
+ withGlobals({ interactive: "medium", autonomous: "low" });
238
194
 
239
195
  // executionContext omitted — should default to "conversation" → interactive
240
196
  const result = await getAutoApproveThreshold(undefined, undefined);
@@ -242,36 +198,20 @@ describe("getAutoApproveThreshold", () => {
242
198
  });
243
199
 
244
200
  test("skips conversation override when no conversationId", async () => {
245
- gatewayGetHandler = (path: string) => {
246
- if (path === "/v1/permissions/thresholds") {
247
- return {
248
- interactive: "low",
249
- autonomous: "none",
250
- };
251
- }
252
- return {};
253
- };
201
+ withGlobals({ interactive: "low", autonomous: "none" });
254
202
 
255
203
  const result = await getAutoApproveThreshold(undefined, "conversation");
256
204
  expect(result).toBe("low");
257
205
  // Should only call global endpoint, not conversation
258
- expect(gatewayGetCalls).toEqual(["/v1/permissions/thresholds"]);
206
+ expect(ipcCallLog).toEqual(["/v1/permissions/thresholds"]);
259
207
  });
260
208
 
261
209
  test("skips conversation override for non-conversation contexts", async () => {
262
- gatewayGetHandler = (path: string) => {
263
- if (path === "/v1/permissions/thresholds") {
264
- return {
265
- interactive: "low",
266
- autonomous: "medium",
267
- };
268
- }
269
- return {};
270
- };
210
+ withGlobals({ interactive: "low", autonomous: "medium" });
271
211
 
272
212
  // Even with a conversationId, background context should not check conversation override
273
213
  const result = await getAutoApproveThreshold("conv-123", "background");
274
214
  expect(result).toBe("medium");
275
- expect(gatewayGetCalls).toEqual(["/v1/permissions/thresholds"]);
215
+ expect(ipcCallLog).toEqual(["/v1/permissions/thresholds"]);
276
216
  });
277
217
  });
package/bun.lock CHANGED
@@ -20,6 +20,7 @@
20
20
  "@vellumai/gateway-client": "file:../packages/gateway-client",
21
21
  "@vellumai/service-contracts": "file:../packages/service-contracts",
22
22
  "@vellumai/skill-host-contracts": "file:../packages/skill-host-contracts",
23
+ "@vellumai/slack-text": "file:../packages/slack-text",
23
24
  "archiver": "7.0.1",
24
25
  "commander": "13.1.0",
25
26
  "croner": "10.0.1",
@@ -422,6 +423,8 @@
422
423
 
423
424
  "@vellumai/skill-host-contracts": ["@vellumai/skill-host-contracts@file:../packages/skill-host-contracts", { "devDependencies": { "@types/bun": "1.3.10", "typescript": "5.9.3" } }],
424
425
 
426
+ "@vellumai/slack-text": ["@vellumai/slack-text@file:../packages/slack-text", { "devDependencies": { "@types/bun": "1.3.10", "typescript": "5.9.3" } }],
427
+
425
428
  "@vue/compiler-core": ["@vue/compiler-core@3.5.33", "", { "dependencies": { "@babel/parser": "^7.29.2", "@vue/shared": "3.5.33", "entities": "^7.0.1", "estree-walker": "^2.0.2", "source-map-js": "^1.2.1" } }, "sha512-3PZLQwFw4Za3TC8t0FvTy3wI16Kt+pmwcgNZca4Pj9iWL2E72a/gZlpBtAJvEdDMdCxdG/qq0C7PN0bsJuv0Rw=="],
426
429
 
427
430
  "@vue/compiler-dom": ["@vue/compiler-dom@3.5.33", "", { "dependencies": { "@vue/compiler-core": "3.5.33", "@vue/shared": "3.5.33" } }, "sha512-PXq0yrfCLzzL07rbXO4awtXY1Z06LG2eu6Adg3RJFa/j3Cii217XxxLXG22N330gw7GmALCY0Z8RgXEviwgpjA=="],
@@ -39,11 +39,11 @@ graph TB
39
39
  Auto-approve thresholds are **gateway-owned** — they live in the gateway's SQLite database and are read by the assistant via IPC (`get_global_thresholds`, `get_conversation_threshold`). Users control thresholds via the **Settings UI** (Permissions & Privacy tab) or the **per-conversation risk tolerance picker**. When the gateway is unreachable, the assistant defaults to `"none"` (Strict) — fail-closed with no local fallback.
40
40
 
41
41
  | `autoApproveUpTo` | Low-risk tools | Medium-risk tools | High-risk tools |
42
- | ------------------ | -------------- | ----------------- | --------------- |
43
- | `"none"` | Prompted | Prompted | Prompted |
44
- | `"low"` (default) | Auto-allowed | Prompted | Prompted |
45
- | `"medium"` | Auto-allowed | Auto-allowed | Prompted |
46
- | `"high"` | Auto-allowed | Auto-allowed | Auto-allowed |
42
+ | ----------------- | -------------- | ----------------- | --------------- |
43
+ | `"none"` | Prompted | Prompted | Prompted |
44
+ | `"low"` (default) | Auto-allowed | Prompted | Prompted |
45
+ | `"medium"` | Auto-allowed | Auto-allowed | Prompted |
46
+ | `"high"` | Auto-allowed | Auto-allowed | Auto-allowed |
47
47
 
48
48
  When set to `"none"`, every tool invocation requires explicit approval. Explicit deny and ask rules always take precedence over the threshold.
49
49
 
@@ -262,20 +262,22 @@ The `allowOneTimeSend` config gate (default: `false`) enables a secondary "Send
262
262
  | ------------------- | ---------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
263
263
  | Secret values | CES credential store or encrypted file store | Encrypted credential values keyed as `credential/{service}/{field}`. Stored via CES RPC (primary), CES HTTP (containerized), or encrypted file store (fallback). |
264
264
  | Credential metadata | `~/.vellum/workspace/data/credentials/metadata.json` | Service, field, label, policy (allowedTools, allowedDomains), timestamps |
265
- | Config | `~/.vellum/workspace/config.*` | `secretDetection` settings: enabled, action, entropyThreshold, allowOneTimeSend |
265
+ | Config | `~/.vellum/workspace/config.*` | `secretDetection` settings: enabled, blockIngress, allowOneTimeSend |
266
266
 
267
267
  ### Key Files
268
268
 
269
- | File | Role |
270
- | ---------------------------------------------------- | --------------------------------------------------------------------- |
271
- | `assistant/src/tools/credentials/vault.ts` | `credential_store` tool — store, list, delete, prompt actions |
272
- | `assistant/src/security/secure-keys.ts` | Async secure key CRUD via CES and encrypted file store |
273
- | `assistant/src/tools/credentials/metadata-store.ts` | JSON file metadata CRUD for credential records |
274
- | `assistant/src/tools/credentials/broker.ts` | Brokered credential access with policy enforcement and transient send |
275
- | `assistant/src/tools/credentials/policy-validate.ts` | Policy input validation (allowedTools, allowedDomains) |
276
- | `assistant/src/permissions/secret-prompter.ts` | HTTP secret_request/secret_response flow |
277
- | `assistant/src/security/secret-scanner.ts` | Regex + entropy-based secret detection |
278
- | `clients/macos/.../SecretPromptManager.swift` | Floating panel UI for secure credential entry |
269
+ | File | Role |
270
+ | ---------------------------------------------------- | ---------------------------------------------------------------------------------- |
271
+ | `assistant/src/tools/credentials/vault.ts` | `credential_store` tool — store, list, delete, prompt actions |
272
+ | `assistant/src/security/secure-keys.ts` | Async secure key CRUD via CES and encrypted file store |
273
+ | `assistant/src/tools/credentials/metadata-store.ts` | JSON file metadata CRUD for credential records |
274
+ | `assistant/src/tools/credentials/broker.ts` | Brokered credential access with policy enforcement and transient send |
275
+ | `assistant/src/tools/credentials/policy-validate.ts` | Policy input validation (allowedTools, allowedDomains) |
276
+ | `assistant/src/permissions/secret-prompter.ts` | HTTP secret_request/secret_response flow |
277
+ | `assistant/src/security/secret-scanner.ts` | Prefix + shape-based secret regex detection (used by display-time `redactSecrets`) |
278
+ | `assistant/src/security/secret-ingress.ts` | Prefix-only ingress check on user messages |
279
+ | `assistant/src/util/log-redact.ts` | Pino log serializers — prefix-based redaction for logs |
280
+ | `clients/macos/.../SecretPromptManager.swift` | Floating panel UI for secure credential entry |
279
281
 
280
282
  ---
281
283
 
package/knip.json CHANGED
@@ -12,6 +12,7 @@
12
12
  "@vellumai/egress-proxy",
13
13
  "@vellumai/gateway-client",
14
14
  "@vellumai/service-contracts",
15
+ "@vellumai/slack-text",
15
16
  "@resvg/resvg-js-darwin-arm64",
16
17
  "@resvg/resvg-js-darwin-x64",
17
18
  "@vellumai/skill-host-contracts",
@@ -259,7 +259,6 @@ beforeEach(async () => {
259
259
  server = new StubServer(socketPath);
260
260
  // Standard identity/platform/log stubs every test relies on for
261
261
  // `connect()` to succeed.
262
- server.register("host.identity.getInternalAssistantId", () => "self");
263
262
  server.register(
264
263
  "host.identity.getAssistantName",
265
264
  () => "Example Assistant",
@@ -298,7 +297,6 @@ async function openClient(
298
297
  describe("SkillHostClient: bootstrap + sync accessors", () => {
299
298
  test("connect populates identity/platform caches", async () => {
300
299
  client = await openClient();
301
- expect(client.identity.internalAssistantId).toBe("self");
302
300
  expect(client.identity.getAssistantName()).toBe("Example Assistant");
303
301
  expect(client.platform.workspaceDir()).toBe("/tmp/workspace");
304
302
  expect(client.platform.vellumRoot()).toBe("/tmp/vellum");
@@ -310,7 +308,6 @@ describe("SkillHostClient: bootstrap + sync accessors", () => {
310
308
  socketPath,
311
309
  skillId: "test-skill",
312
310
  });
313
- expect(() => client!.identity.internalAssistantId).toThrow(/not connected/);
314
311
  expect(() => client!.platform.workspaceDir()).toThrow(/not connected/);
315
312
  });
316
313
 
@@ -880,11 +877,10 @@ describe("SkillHostClient: connect() retry semantics", () => {
880
877
  client = new SkillHostClient({ socketPath, skillId: "test-skill" });
881
878
  await expect(client.connect()).rejects.toThrow(/boom/);
882
879
  // Sync accessors should still throw — the cache wasn't populated.
883
- expect(() => client!.identity.internalAssistantId).toThrow(/not connected/);
880
+ expect(() => client!.platform.workspaceDir()).toThrow(/not connected/);
884
881
  // Second connect() must retry prefetch instead of short-circuiting on
885
882
  // the still-alive socket.
886
883
  await client.connect();
887
- expect(client.identity.internalAssistantId).toBe("self");
888
884
  expect(client.identity.getAssistantName()).toBe("Recovered Assistant");
889
885
  expect(nameCalls).toBe(2);
890
886
  });
@@ -28,8 +28,6 @@ import { randomUUID } from "node:crypto";
28
28
  export interface AssistantEvent<TMessage = unknown> {
29
29
  /** Globally unique event identifier (UUID). */
30
30
  id: string;
31
- /** The assistant this event belongs to. */
32
- assistantId: string;
33
31
  /** Resolved conversation id when available. */
34
32
  conversationId?: string;
35
33
  /** ISO-8601 timestamp of when the event was emitted. */
@@ -43,18 +41,15 @@ export interface AssistantEvent<TMessage = unknown> {
43
41
  /**
44
42
  * Construct an `AssistantEvent` envelope around a message payload.
45
43
  *
46
- * @param assistantId The logical assistant identifier (e.g. from the daemon or HTTP route).
47
44
  * @param message The outbound message payload.
48
45
  * @param conversationId Optional conversation id -- pass when known.
49
46
  */
50
47
  export function buildAssistantEvent<TMessage>(
51
- assistantId: string,
52
48
  message: TMessage,
53
49
  conversationId?: string,
54
50
  ): AssistantEvent<TMessage> {
55
51
  return {
56
52
  id: randomUUID(),
57
- assistantId,
58
53
  conversationId,
59
54
  emittedAt: new Date().toISOString(),
60
55
  message,
@@ -64,7 +64,7 @@
64
64
  * ### Sync-method bootstrap
65
65
  *
66
66
  * The `SkillHost` contract exposes a number of synchronous accessors
67
- * (`identity.internalAssistantId`, `platform.workspaceDir()`,
67
+ * (`identity.getAssistantName()`, `platform.workspaceDir()`,
68
68
  * `platform.runtimeMode()`, etc.) that naturally cannot round-trip an async
69
69
  * IPC call on every invocation. `connect()` prefetches the stable subset of
70
70
  * these values once, caches them locally, and every subsequent sync accessor
@@ -311,8 +311,8 @@ export class SkillHostClient implements SkillHost {
311
311
  >();
312
312
 
313
313
  // Prefetched sync state — populated by `connect()`.
314
- private cachedInternalAssistantId: string | null = null;
315
314
  private cachedAssistantName: string | undefined = undefined;
315
+ private cachedPrefetchDone = false;
316
316
  private cachedWorkspaceDir: string | null = null;
317
317
  private cachedVellumRoot: string | null = null;
318
318
  private cachedRuntimeMode: DaemonRuntimeMode | null = null;
@@ -383,7 +383,7 @@ export class SkillHostClient implements SkillHost {
383
383
  // the caches are still null and sync accessors would throw — fall
384
384
  // through and re-run prefetch over the existing socket.
385
385
  const socketAlive = !!this.socket && !this.socket.destroyed;
386
- const prefetchDone = this.cachedInternalAssistantId !== null;
386
+ const prefetchDone = this.cachedPrefetchDone;
387
387
  if (socketAlive && prefetchDone) return;
388
388
 
389
389
  const ensureSocket = socketAlive ? Promise.resolve() : this.doConnect();
@@ -774,15 +774,14 @@ export class SkillHostClient implements SkillHost {
774
774
  // ── Internal: bootstrap cache ───────────────────────────────────────────
775
775
 
776
776
  private async prefetchSyncState(): Promise<void> {
777
- const [assistantId, workspaceDir, vellumRootValue, runtimeMode, name] =
777
+ const [workspaceDir, vellumRootValue, runtimeMode, name] =
778
778
  await Promise.all([
779
- this.call<string>("host.identity.getInternalAssistantId"),
780
779
  this.call<string>("host.platform.workspaceDir"),
781
780
  this.call<string>("host.platform.vellumRoot"),
782
781
  this.call<DaemonRuntimeMode>("host.platform.runtimeMode"),
783
782
  this.call<string | null>("host.identity.getAssistantName"),
784
783
  ]);
785
- this.cachedInternalAssistantId = assistantId;
784
+ this.cachedPrefetchDone = true;
786
785
  this.cachedWorkspaceDir = workspaceDir;
787
786
  this.cachedVellumRoot = vellumRootValue;
788
787
  this.cachedRuntimeMode = runtimeMode;
@@ -844,13 +843,9 @@ export class SkillHostClient implements SkillHost {
844
843
  const self = this;
845
844
  return {
846
845
  getAssistantName: () => {
847
- if (self.cachedInternalAssistantId === null) throw notConnected();
846
+ if (!self.cachedPrefetchDone) throw notConnected();
848
847
  return self.cachedAssistantName;
849
848
  },
850
- get internalAssistantId(): string {
851
- if (self.cachedInternalAssistantId === null) throw notConnected();
852
- return self.cachedInternalAssistantId;
853
- },
854
849
  };
855
850
  }
856
851
 
@@ -1000,13 +995,12 @@ export class SkillHostClient implements SkillHost {
1000
995
  // `buildEvent` is typed as sync on the contract (the daemon
1001
996
  // allocates a uuid + timestamp and returns the envelope). A sync
1002
997
  // round-trip isn't possible, so the client produces an envelope
1003
- // locally using the cached assistant id and the standard uuid /
1004
- // timestamp sources. This matches the observable shape of the
1005
- // daemon's `buildAssistantEvent` without the round-trip.
1006
- if (this.cachedInternalAssistantId === null) throw notConnected();
998
+ // locally using the standard uuid / timestamp sources. This matches
999
+ // the observable shape of the daemon's `buildAssistantEvent` without
1000
+ // the round-trip.
1001
+ if (!this.cachedPrefetchDone) throw notConnected();
1007
1002
  return {
1008
1003
  id: randomUUID(),
1009
- assistantId: this.cachedInternalAssistantId,
1010
1004
  conversationId,
1011
1005
  emittedAt: new Date().toISOString(),
1012
1006
  message,
@@ -94,12 +94,6 @@ export interface IdentityFacet {
94
94
  * `undefined` when no name has been set.
95
95
  */
96
96
  getAssistantName(): string | undefined;
97
- /**
98
- * The daemon's internal assistant id (`DAEMON_INTERNAL_ASSISTANT_ID`).
99
- * Skills use this as the `assistantId` field on events they publish and
100
- * as the subject of memory writes.
101
- */
102
- readonly internalAssistantId: string;
103
97
  }
104
98
 
105
99
  // ---------------------------------------------------------------------------
@@ -228,9 +222,7 @@ export interface MemoryFacet {
228
222
 
229
223
  /** Subscription filter mirroring `AssistantEventFilter` from the daemon's hub. */
230
224
  export interface Filter {
231
- /** Only deliver events for this assistant. */
232
- assistantId: string;
233
- /** When set, further restrict to this conversation. */
225
+ /** When set, restrict delivery to this conversation. */
234
226
  conversationId?: string;
235
227
  }
236
228