@vellumai/assistant 0.9.0 → 0.10.0-staging.2

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 (572) hide show
  1. package/ARCHITECTURE.md +18 -34
  2. package/bun.lock +7 -8
  3. package/docs/activation-funnel-telemetry.md +28 -22
  4. package/docs/architecture/security.md +29 -28
  5. package/docs/stt-provider-onboarding.md +3 -5
  6. package/docs/workflows-testing.md +13 -44
  7. package/docs/workflows.md +3 -5
  8. package/node_modules/@vellumai/ces-client/src/__tests__/ces-client.test.ts +47 -0
  9. package/node_modules/@vellumai/ces-client/src/rpc-client.ts +28 -5
  10. package/node_modules/@vellumai/environments/src/seeds.ts +2 -5
  11. package/node_modules/@vellumai/gateway-client/src/admission-policy-contract.ts +97 -0
  12. package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +10 -0
  13. package/node_modules/@vellumai/gateway-client/src/index.ts +32 -6
  14. package/node_modules/@vellumai/gateway-client/src/outbound-contract.ts +119 -0
  15. package/node_modules/@vellumai/gateway-client/src/types.ts +15 -84
  16. package/openapi.yaml +976 -63
  17. package/package.json +2 -1
  18. package/scripts/sync-llm-catalog.ts +6 -15
  19. package/scripts/sync-web-search-catalog.ts +3 -11
  20. package/src/__tests__/access-request-card-view.test.ts +98 -0
  21. package/src/__tests__/access-request-seed-content-blocks.test.ts +2 -4
  22. package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +72 -32
  23. package/src/__tests__/agent-loop-compaction-strip.test.ts +241 -0
  24. package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +16 -13
  25. package/src/__tests__/agent-loop-output-hooks.test.ts +69 -0
  26. package/src/__tests__/agent-loop-override-profile.test.ts +25 -0
  27. package/src/__tests__/always-loaded-tools-guard.test.ts +2 -3
  28. package/src/__tests__/app-compiler.test.ts +15 -1
  29. package/src/__tests__/app-dir-path-guard.test.ts +0 -1
  30. package/src/__tests__/assistant-feature-flag-guard.test.ts +1 -4
  31. package/src/__tests__/assistant-feature-flag-guardrails.test.ts +0 -2
  32. package/src/__tests__/auth-fallback-events-store.test.ts +6 -14
  33. package/src/__tests__/avatar-identity-sync.test.ts +2 -27
  34. package/src/__tests__/btw-routes.test.ts +6 -8
  35. package/src/__tests__/call-pointer-messages.test.ts +28 -0
  36. package/src/__tests__/cancel-clears-processing.test.ts +89 -0
  37. package/src/__tests__/channel-approval-routes.test.ts +0 -4
  38. package/src/__tests__/channel-inbound-disk-pressure.test.ts +5 -15
  39. package/src/__tests__/checker.test.ts +0 -3
  40. package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +3 -4
  41. package/src/__tests__/compactor-image-manifest-trust.test.ts +21 -1
  42. package/src/__tests__/compactor-summary-call-truncation.test.ts +223 -0
  43. package/src/__tests__/config-loader-backfill.test.ts +268 -27
  44. package/src/__tests__/config-schema.test.ts +35 -0
  45. package/src/__tests__/config-watcher.test.ts +0 -18
  46. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +2 -2
  47. package/src/__tests__/contact-store-user-file.test.ts +0 -6
  48. package/src/__tests__/contacts-tools.test.ts +29 -0
  49. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +22 -0
  50. package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -0
  51. package/src/__tests__/conversation-agent-loop.test.ts +58 -0
  52. package/src/__tests__/conversation-attention-telegram.test.ts +0 -1
  53. package/src/__tests__/conversation-lifecycle.test.ts +7 -9
  54. package/src/__tests__/conversation-load-history-repair.test.ts +101 -0
  55. package/src/__tests__/conversation-routes-guardian-reply.test.ts +15 -12
  56. package/src/__tests__/conversation-surfaces-activation-emit.test.ts +6 -3
  57. package/src/__tests__/conversation-title-service.test.ts +62 -0
  58. package/src/__tests__/credential-broker.test.ts +449 -1
  59. package/src/__tests__/credential-execution-shell-lockdown.test.ts +18 -11
  60. package/src/__tests__/credential-execution-tools.test.ts +0 -1
  61. package/src/__tests__/credential-prompt-route.test.ts +4 -4
  62. package/src/__tests__/credential-routes.test.ts +360 -0
  63. package/src/__tests__/credential-security-invariants.test.ts +4 -13
  64. package/src/__tests__/disk-pressure-policy.test.ts +12 -0
  65. package/src/__tests__/disk-usage.test.ts +65 -0
  66. package/src/__tests__/dynamic-page-surface.test.ts +152 -1
  67. package/src/__tests__/fixtures/credential-security-fixtures.ts +2 -33
  68. package/src/__tests__/gateway-flag-listener.test.ts +110 -1
  69. package/src/__tests__/gateway-only-guard.test.ts +3 -7
  70. package/src/__tests__/guardian-binding-drift-heal.test.ts +1 -1
  71. package/src/__tests__/guardian-card-withdrawal.test.ts +403 -0
  72. package/src/__tests__/guardian-decision-primitive-canonical.test.ts +5 -3
  73. package/src/__tests__/guardian-grant-minting.test.ts +3 -35
  74. package/src/__tests__/guardian-routing-invariants.test.ts +64 -26
  75. package/src/__tests__/guardian-routing-state.test.ts +0 -1
  76. package/src/__tests__/headless-browser-mode.test.ts +10 -0
  77. package/src/__tests__/headless-browser-navigate.test.ts +8 -3
  78. package/src/__tests__/helpers/create-guardian-binding.ts +0 -1
  79. package/src/__tests__/host-browser-proxy.test.ts +87 -0
  80. package/src/__tests__/identity-routes.test.ts +0 -189
  81. package/src/__tests__/inbound-invite-redemption.test.ts +4 -4
  82. package/src/__tests__/injector-v3-suppression.test.ts +27 -20
  83. package/src/__tests__/internal-telemetry-routes.test.ts +6 -14
  84. package/src/__tests__/invite-redemption-service.test.ts +4 -7
  85. package/src/__tests__/llm-callsite-catalog.test.ts +5 -6
  86. package/src/__tests__/llm-catalog-parity.test.ts +30 -23
  87. package/src/__tests__/llm-resolver.test.ts +70 -24
  88. package/src/__tests__/llm-schema.test.ts +1 -0
  89. package/src/__tests__/managed-profile-guard.test.ts +163 -4
  90. package/src/__tests__/mcp-health-check.test.ts +6 -7
  91. package/src/__tests__/media-stream-server-integration.test.ts +317 -13
  92. package/src/__tests__/oauth-provider-seed-logos.test.ts +4 -6
  93. package/src/__tests__/onboarding-persona-write.test.ts +1 -1
  94. package/src/__tests__/path-policy.test.ts +34 -0
  95. package/src/__tests__/persona-resolver.test.ts +49 -14
  96. package/src/__tests__/plugin-api-model-profiles.test.ts +178 -0
  97. package/src/__tests__/plugin-api-provider.test.ts +24 -0
  98. package/src/__tests__/plugin-tool-contribution.test.ts +6 -3
  99. package/src/__tests__/post-compaction-reinjection-idempotency.test.ts +214 -0
  100. package/src/__tests__/provider-send-message-override-profile.test.ts +76 -0
  101. package/src/__tests__/reaction-persistence.test.ts +150 -29
  102. package/src/__tests__/registry.test.ts +2 -7
  103. package/src/__tests__/relay-server.test.ts +285 -0
  104. package/src/__tests__/runtime-attachment-metadata.test.ts +0 -1
  105. package/src/__tests__/schedule-routes-workflow-validation.test.ts +1 -10
  106. package/src/__tests__/schedule-routes.test.ts +0 -30
  107. package/src/__tests__/schedule-tools.test.ts +2 -18
  108. package/src/__tests__/scheduler-reuse-conversation.test.ts +8 -5
  109. package/src/__tests__/skill-execute-input.test.ts +51 -1
  110. package/src/__tests__/skill-runtime-path.test.ts +2 -3
  111. package/src/__tests__/skills.test.ts +51 -0
  112. package/src/__tests__/slack-notification-approval-card.test.ts +176 -0
  113. package/src/__tests__/slack-reaction-canonical-approval.test.ts +285 -0
  114. package/src/__tests__/subagent-tools.test.ts +266 -0
  115. package/src/__tests__/surface-completion-nudge-hook.test.ts +367 -0
  116. package/src/__tests__/task-progress-nudge-hook.test.ts +1 -1
  117. package/src/__tests__/title-generate-hook.test.ts +100 -3
  118. package/src/__tests__/token-estimator-accuracy.benchmark.test.ts +1 -29
  119. package/src/__tests__/token-manager.test.ts +519 -0
  120. package/src/__tests__/tool-approval-seed-content-blocks.test.ts +1 -1
  121. package/src/__tests__/tool-audit-listener.test.ts +7 -7
  122. package/src/__tests__/tool-executor-lifecycle-events.test.ts +6 -3
  123. package/src/__tests__/tool-executor.test.ts +0 -79
  124. package/src/__tests__/trusted-contact-approval-notifier.test.ts +4 -2
  125. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +220 -3
  126. package/src/__tests__/trusted-contact-multichannel.test.ts +3 -3
  127. package/src/__tests__/trusted-contact-verification.test.ts +8 -10
  128. package/src/__tests__/twilio-routes.test.ts +81 -1
  129. package/src/__tests__/voice-invite-redemption.test.ts +2 -3
  130. package/src/__tests__/weak-open-model.test.ts +30 -0
  131. package/src/__tests__/web-search-catalog-parity.test.ts +6 -25
  132. package/src/__tests__/workspace-greetings.test.ts +152 -0
  133. package/src/__tests__/workspace-migration-105-enable-memory-v3-live-for-new-workspaces.test.ts +149 -0
  134. package/src/__tests__/workspace-migration-108-drop-balanced-economy-profile.test.ts +285 -0
  135. package/src/__tests__/workspace-migration-add-send-diagnostics.test.ts +1 -1
  136. package/src/__tests__/workspace-migration-drop-collect-usage-data.test.ts +118 -0
  137. package/src/__tests__/workspace-migration-drop-send-diagnostics.test.ts +118 -0
  138. package/src/a2a/__tests__/e2e-a2a-channel.test.ts +0 -4
  139. package/src/agent/loop.ts +49 -29
  140. package/src/api/README.md +6 -6
  141. package/src/api/events/tool-result.ts +6 -0
  142. package/src/api/events/workflow-completed.ts +53 -0
  143. package/src/api/events/workflow-leaf-finished.ts +38 -0
  144. package/src/api/events/workflow-leaf-started.ts +35 -0
  145. package/src/api/events/workflow-progress.ts +32 -0
  146. package/src/api/events/workflow-started.ts +31 -0
  147. package/src/api/index.ts +40 -0
  148. package/src/api/responses/conversation-message.ts +28 -4
  149. package/src/api/responses/home.ts +26 -4
  150. package/src/api/responses/workflow-journal.ts +53 -0
  151. package/src/approvals/guardian-card-withdrawal.ts +145 -0
  152. package/src/approvals/guardian-decision-primitive.ts +26 -3
  153. package/src/approvals/guardian-request-resolvers.ts +183 -80
  154. package/src/calls/__tests__/channel-admission-reader.test.ts +132 -0
  155. package/src/calls/__tests__/relay-setup-router.test.ts +350 -0
  156. package/src/calls/call-pointer-messages.ts +10 -4
  157. package/src/calls/channel-admission-reader.ts +104 -0
  158. package/src/calls/guardian-dispatch.ts +17 -45
  159. package/src/calls/media-stream-server.ts +84 -2
  160. package/src/calls/relay-access-wait.ts +1 -1
  161. package/src/calls/relay-server.ts +66 -0
  162. package/src/calls/relay-setup-router.ts +82 -1
  163. package/src/calls/twilio-routes.ts +17 -8
  164. package/src/calls/voice-session-bridge.ts +2 -2
  165. package/src/cli/commands/clients.ts +3 -0
  166. package/src/cli/commands/{__tests__ → memory/__tests__}/memory-v2-compare-render.test.ts +1 -1
  167. package/src/cli/commands/{__tests__ → memory/__tests__}/memory-v2.test.ts +8 -7
  168. package/src/cli/commands/{__tests__ → memory/__tests__}/memory-v3.test.ts +5 -4
  169. package/src/cli/commands/memory/index.ts +30 -0
  170. package/src/cli/commands/{memory-v2-compare-render.ts → memory/memory-v2-compare-render.ts} +1 -1
  171. package/src/cli/commands/{memory-v2.ts → memory/memory-v2.ts} +6 -15
  172. package/src/cli/commands/{memory-v3.ts → memory/memory-v3.ts} +97 -11
  173. package/src/cli/commands/oauth/status.test.ts +36 -0
  174. package/src/cli/commands/oauth/status.ts +23 -3
  175. package/src/cli/commands/plugins.ts +197 -4
  176. package/src/cli/lib/__tests__/diff-plugin.test.ts +443 -0
  177. package/src/cli/lib/__tests__/inspect-plugin.test.ts +54 -0
  178. package/src/cli/lib/__tests__/merge-plugin-tree.test.ts +443 -0
  179. package/src/cli/lib/__tests__/plugin-surfaces.test.ts +111 -0
  180. package/src/cli/lib/__tests__/upgrade-plugin.test.ts +295 -2
  181. package/src/cli/lib/diff-plugin.ts +346 -0
  182. package/src/cli/lib/inspect-plugin.ts +12 -1
  183. package/src/cli/lib/install-from-github.ts +105 -17
  184. package/src/cli/lib/merge-plugin-tree.ts +328 -0
  185. package/src/cli/lib/plugin-fingerprint.ts +14 -0
  186. package/src/cli/lib/plugin-surfaces.ts +104 -0
  187. package/src/cli/lib/upgrade-plugin.ts +298 -10
  188. package/src/cli/program.ts +2 -6
  189. package/src/config/__tests__/sync-gated-profiles.test.ts +368 -0
  190. package/src/config/assistant-feature-flags.ts +22 -7
  191. package/src/config/bundled-skills/contacts/tools/contact-search.ts +0 -1
  192. package/src/config/bundled-skills/messaging/SKILL.md +6 -4
  193. package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +9 -8
  194. package/src/config/bundled-skills/subagent/SKILL.md +4 -0
  195. package/src/config/bundled-skills/subagent/TOOLS.json +4 -0
  196. package/src/config/bundled-skills/workflows/SKILL.md +14 -8
  197. package/src/config/bundled-tool-registry.ts +2 -7
  198. package/src/config/call-site-defaults.ts +15 -2
  199. package/src/config/feature-flag-registry.json +46 -31
  200. package/src/config/inference-profile-validation.ts +26 -0
  201. package/src/config/llm-resolver.ts +3 -0
  202. package/src/config/loader.ts +4 -0
  203. package/src/config/memory-v3-gate.ts +11 -0
  204. package/src/config/profile-order.ts +28 -0
  205. package/src/config/schema.ts +8 -6
  206. package/src/config/schemas/__tests__/memory-v3.test.ts +1 -0
  207. package/src/config/schemas/call-site-catalog.ts +7 -0
  208. package/src/config/schemas/channels.ts +11 -0
  209. package/src/config/schemas/elevenlabs.ts +0 -1
  210. package/src/config/schemas/llm.ts +31 -0
  211. package/src/config/schemas/memory-lifecycle.ts +3 -7
  212. package/src/config/schemas/memory-v3.ts +6 -0
  213. package/src/config/schemas/platform.ts +0 -8
  214. package/src/config/schemas/services.ts +18 -0
  215. package/src/config/seed-inference-profiles.ts +109 -44
  216. package/src/config/skills.ts +21 -0
  217. package/src/config/sync-gated-profiles.ts +220 -0
  218. package/src/contacts/contact-store.ts +89 -106
  219. package/src/contacts/contacts-write.ts +5 -22
  220. package/src/contacts/types.ts +0 -1
  221. package/src/context/compactor.ts +88 -54
  222. package/src/context/strip-injections.ts +58 -10
  223. package/src/context/token-estimator.ts +1 -1
  224. package/src/credential-execution/process-manager.ts +55 -14
  225. package/src/credential-execution/prompted-credential.ts +2 -3
  226. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +3 -2
  227. package/src/daemon/config-watcher.ts +0 -4
  228. package/src/daemon/conversation-agent-loop-handlers.ts +2 -0
  229. package/src/daemon/conversation-agent-loop.ts +114 -22
  230. package/src/daemon/conversation-history.ts +1 -1
  231. package/src/daemon/conversation-lifecycle.ts +3 -5
  232. package/src/daemon/conversation-process.ts +13 -5
  233. package/src/daemon/conversation-runtime-assembly.ts +13 -15
  234. package/src/daemon/conversation-slash.ts +2 -23
  235. package/src/daemon/conversation-surfaces.ts +26 -0
  236. package/src/daemon/conversation-tool-setup.ts +27 -14
  237. package/src/daemon/conversation.ts +66 -14
  238. package/src/daemon/disk-pressure-policy.ts +5 -3
  239. package/src/daemon/handlers/__tests__/config-a2a-complete.test.ts +0 -1
  240. package/src/daemon/handlers/__tests__/config-a2a-redeem.test.ts +0 -1
  241. package/src/daemon/handlers/config-a2a.ts +0 -2
  242. package/src/daemon/handlers/config-channels.ts +15 -16
  243. package/src/daemon/handlers/config-slack-channel.ts +22 -3
  244. package/src/daemon/handlers/conversations.ts +107 -0
  245. package/src/daemon/host-browser-proxy.ts +41 -0
  246. package/src/daemon/lifecycle.ts +55 -27
  247. package/src/daemon/message-provenance.ts +2 -0
  248. package/src/daemon/message-types/contacts.ts +0 -1
  249. package/src/daemon/message-types/conversations.ts +3 -3
  250. package/src/daemon/message-types/sync.ts +0 -1
  251. package/src/daemon/message-types/web-activity.ts +7 -1
  252. package/src/daemon/message-types/workflows.ts +83 -1
  253. package/src/daemon/orphan-reaper.test.ts +0 -19
  254. package/src/daemon/orphan-reaper.ts +2 -24
  255. package/src/daemon/server.ts +0 -10
  256. package/src/daemon/tool-setup-types.ts +4 -0
  257. package/src/daemon/trust-context.ts +1 -1
  258. package/src/events/tool-audit-listener.ts +2 -2
  259. package/src/home/feed-source-enrichment.test.ts +151 -0
  260. package/src/home/feed-source-enrichment.ts +176 -0
  261. package/src/home/relationship-state.ts +2 -4
  262. package/src/instrument.ts +18 -6
  263. package/src/ipc/__tests__/binary-result-ipc.test.ts +81 -0
  264. package/src/ipc/__tests__/clients-list-ipc.test.ts +20 -0
  265. package/src/ipc/assistant-server.ts +37 -4
  266. package/src/ipc/gateway-flag-listener.ts +18 -2
  267. package/src/memory/__tests__/auto-analysis-enqueue.test.ts +5 -16
  268. package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +7 -11
  269. package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +37 -7
  270. package/src/memory/__tests__/memory-retrospective-job.test.ts +229 -401
  271. package/src/memory/__tests__/onboarding-events-store.test.ts +7 -7
  272. package/src/memory/auth-fallback-events-store.ts +2 -2
  273. package/src/memory/auto-analysis-enqueue.ts +3 -5
  274. package/src/memory/bookmark-crud.ts +1 -2
  275. package/src/memory/canonical-guardian-store.ts +39 -1
  276. package/src/memory/conversation-crud.ts +9 -4
  277. package/src/memory/conversation-key-store.ts +17 -2
  278. package/src/memory/conversation-title-service.ts +64 -7
  279. package/src/memory/db-init.ts +17 -17
  280. package/src/memory/embedding-backend.ts +38 -1
  281. package/src/memory/embedding-billing-breaker.ts +96 -0
  282. package/src/memory/jobs-store.ts +25 -13
  283. package/src/memory/jobs-worker.ts +54 -1
  284. package/src/memory/lifecycle-events-store.ts +2 -2
  285. package/src/memory/memory-retrospective-constants.ts +4 -4
  286. package/src/memory/memory-retrospective-enqueue.ts +31 -6
  287. package/src/memory/memory-retrospective-job.ts +28 -227
  288. package/src/memory/migrations/129-contact-channels-access-fields.ts +18 -9
  289. package/src/memory/migrations/131-drop-legacy-member-guardian-tables.ts +14 -2
  290. package/src/memory/migrations/289-contact-channels-unique-ext-user.ts +10 -0
  291. package/src/memory/migrations/291-contact-channels-renormalize-addresses.ts +72 -0
  292. package/src/memory/migrations/292-schedule-default-no-reuse-conversation.test.ts +67 -0
  293. package/src/memory/migrations/292-schedule-default-no-reuse-conversation.ts +25 -0
  294. package/src/memory/migrations/293-workflow-journal-leaf-tokens.ts +32 -0
  295. package/src/memory/migrations/294-drop-external-user-id.ts +31 -0
  296. package/src/memory/migrations/295-drop-approval-prompt-ts-tracker.ts +20 -0
  297. package/src/memory/migrations/296-rewrite-balanced-economy-profile-pins.test.ts +110 -0
  298. package/src/memory/migrations/296-rewrite-balanced-economy-profile-pins.ts +68 -0
  299. package/src/memory/migrations/__tests__/131-drop-legacy-member-guardian-tables.test.ts +154 -0
  300. package/src/memory/migrations/__tests__/289-contact-channels-unique-ext-user.test.ts +31 -0
  301. package/src/memory/migrations/__tests__/291-contact-channels-renormalize-addresses.test.ts +341 -0
  302. package/src/memory/migrations/__tests__/run-migrations.test.ts +52 -0
  303. package/src/memory/migrations/index.ts +6 -0
  304. package/src/memory/migrations/run-migrations.ts +41 -0
  305. package/src/memory/migrations/validate-migration-state.ts +1 -1
  306. package/src/memory/onboarding-events-store.ts +3 -3
  307. package/src/memory/schema/contacts.ts +0 -5
  308. package/src/memory/skill-loaded-events-store.test.ts +7 -15
  309. package/src/memory/skill-loaded-events-store.ts +2 -2
  310. package/src/memory/tool-executed-events-store.test.ts +7 -7
  311. package/src/memory/turn-trace-store.test.ts +736 -0
  312. package/src/memory/turn-trace-store.ts +364 -0
  313. package/src/memory/v2/__tests__/consolidation-job.test.ts +8 -0
  314. package/src/memory/v2/__tests__/skill-content.test.ts +30 -0
  315. package/src/memory/v2/consolidation-job.ts +2 -2
  316. package/src/memory/v2/skill-content.ts +25 -7
  317. package/src/memory/v2/skill-store.ts +7 -1
  318. package/src/memory/v3-eval/__tests__/eval-packets.test.ts +248 -0
  319. package/src/memory/v3-eval/eval-packets.ts +546 -0
  320. package/src/messaging/providers/slack/adapter.ts +1 -1
  321. package/src/messaging/providers/slack/api.ts +31 -0
  322. package/src/messaging/providers/slack/send.test.ts +114 -2
  323. package/src/messaging/providers/slack/send.ts +30 -7
  324. package/src/messaging/providers/slack/withdraw.test.ts +200 -0
  325. package/src/messaging/providers/slack/withdraw.ts +161 -0
  326. package/src/notifications/AGENTS.md +2 -0
  327. package/src/notifications/access-request-copy.ts +72 -59
  328. package/src/notifications/adapters/shared.ts +29 -0
  329. package/src/notifications/adapters/slack.ts +58 -103
  330. package/src/notifications/adapters/telegram.ts +2 -20
  331. package/src/notifications/approval-card-data.ts +333 -0
  332. package/src/notifications/broadcaster.ts +16 -3
  333. package/src/notifications/canonical-delivery-recorder.ts +139 -0
  334. package/src/notifications/copy-composer.ts +3 -3
  335. package/src/notifications/decision-engine.ts +4 -2
  336. package/src/notifications/destination-resolver.ts +4 -6
  337. package/src/notifications/guardian-question-mode.ts +10 -0
  338. package/src/notifications/home-feed-side-effect.ts +7 -16
  339. package/src/notifications/notification-utils.ts +19 -20
  340. package/src/notifications/signal.ts +79 -43
  341. package/src/notifications/types.ts +98 -121
  342. package/src/oauth/AGENTS.md +5 -24
  343. package/src/permissions/checker.test.ts +51 -0
  344. package/src/permissions/checker.ts +185 -26
  345. package/src/permissions/ipc-risk-types.ts +24 -0
  346. package/src/permissions/question-prompter.test.ts +27 -0
  347. package/src/permissions/question-prompter.ts +4 -0
  348. package/src/platform/client.test.ts +119 -0
  349. package/src/platform/client.ts +66 -0
  350. package/src/platform/consent-cache.test.ts +267 -0
  351. package/src/platform/consent-cache.ts +174 -0
  352. package/src/plugin-api/constants.ts +1 -1
  353. package/src/plugin-api/index.ts +33 -1
  354. package/src/plugin-api/model-profiles.ts +33 -0
  355. package/src/plugin-api/types.ts +50 -2
  356. package/src/plugins/defaults/advisor/__tests__/advisor-gate.test.ts +56 -0
  357. package/src/plugins/defaults/advisor/__tests__/advisor-state-store.test.ts +43 -0
  358. package/src/plugins/defaults/advisor/__tests__/agent-loop-integration.test.ts +137 -0
  359. package/src/plugins/defaults/advisor/__tests__/consult.test.ts +153 -0
  360. package/src/plugins/defaults/advisor/__tests__/hooks.test.ts +138 -0
  361. package/src/plugins/defaults/advisor/__tests__/transcript.test.ts +147 -0
  362. package/src/plugins/defaults/advisor/advisor-gate.ts +29 -0
  363. package/src/plugins/defaults/advisor/advisor-state-store.ts +94 -0
  364. package/src/plugins/defaults/advisor/config.ts +21 -0
  365. package/src/plugins/defaults/advisor/consult.ts +93 -0
  366. package/src/plugins/defaults/advisor/hooks/post-model-call.ts +34 -0
  367. package/src/plugins/defaults/advisor/hooks/pre-model-call.ts +30 -0
  368. package/src/plugins/defaults/advisor/hooks/user-prompt-submit.ts +19 -0
  369. package/src/plugins/defaults/advisor/package.json +14 -0
  370. package/src/plugins/defaults/advisor/steering.ts +67 -0
  371. package/src/plugins/defaults/advisor/tools/advisor.ts +65 -0
  372. package/src/plugins/defaults/advisor/transcript.ts +76 -0
  373. package/src/plugins/defaults/index.ts +60 -0
  374. package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +22 -9
  375. package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit.ts +2 -2
  376. package/src/plugins/defaults/memory-retrieval/tail-reinjection-strip.ts +64 -0
  377. package/src/plugins/defaults/memory-retrieval/unified-turn-context.ts +29 -21
  378. package/src/plugins/defaults/memory-v3-shadow/__tests__/carry-integration.test.ts +1 -0
  379. package/src/plugins/defaults/memory-v3-shadow/__tests__/injection.test.ts +1 -0
  380. package/src/plugins/defaults/memory-v3-shadow/__tests__/maintain-job.test.ts +129 -9
  381. package/src/plugins/defaults/memory-v3-shadow/__tests__/orchestrate.test.ts +31 -4
  382. package/src/plugins/defaults/memory-v3-shadow/__tests__/selection-log-store.test.ts +77 -2
  383. package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +1 -0
  384. package/src/plugins/defaults/memory-v3-shadow/injector.ts +7 -10
  385. package/src/plugins/defaults/memory-v3-shadow/maintain-job.ts +144 -11
  386. package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +32 -20
  387. package/src/plugins/defaults/memory-v3-shadow/selection-log-store.ts +56 -3
  388. package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +23 -2
  389. package/src/plugins/defaults/surface-completion-nudge/hooks/post-model-call.ts +276 -0
  390. package/src/plugins/defaults/surface-completion-nudge/hooks/stop.ts +22 -0
  391. package/src/plugins/defaults/surface-completion-nudge/nudge-state-store.ts +46 -0
  392. package/src/plugins/defaults/surface-completion-nudge/package.json +14 -0
  393. package/src/plugins/defaults/task-progress-nudge/hooks/post-tool-use.ts +3 -13
  394. package/src/plugins/defaults/title-generate/hooks/stop.ts +56 -21
  395. package/src/prompts/persona-resolver.ts +14 -4
  396. package/src/prompts/templates/system-sections.ts +7 -2
  397. package/src/providers/__tests__/provider-env-vars.test.ts +6 -0
  398. package/src/providers/__tests__/provider-secret-catalog.test.ts +1 -0
  399. package/src/providers/__tests__/retry-callsite.test.ts +176 -0
  400. package/src/providers/atlascloud/client.ts +85 -0
  401. package/src/providers/fetch-provider-catalog.ts +85 -0
  402. package/src/providers/inference/adapter-factory.ts +3 -0
  403. package/src/providers/model-catalog.ts +58 -0
  404. package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +33 -0
  405. package/src/providers/openai/chat-completions-provider.ts +7 -0
  406. package/src/providers/openai/responses-provider.ts +10 -0
  407. package/src/providers/provider-send-message.ts +11 -3
  408. package/src/providers/retry.ts +53 -12
  409. package/src/providers/search-provider-catalog.ts +10 -0
  410. package/src/providers/weak-open-model.ts +22 -0
  411. package/src/runtime/AGENTS.md +0 -1
  412. package/src/runtime/__tests__/agent-wake.test.ts +181 -0
  413. package/src/runtime/__tests__/client-health.test.ts +44 -0
  414. package/src/runtime/access-request-helper.ts +21 -53
  415. package/src/runtime/actor-trust-resolver.ts +59 -63
  416. package/src/runtime/agent-wake.ts +52 -0
  417. package/src/runtime/assistant-event-hub.ts +18 -4
  418. package/src/runtime/auth/__tests__/route-policy.test.ts +12 -0
  419. package/src/runtime/auth/require-bound-guardian.ts +1 -4
  420. package/src/runtime/btw-sidechain.ts +3 -6
  421. package/src/runtime/capabilities.test.ts +120 -0
  422. package/src/runtime/capabilities.ts +197 -0
  423. package/src/runtime/channel-approval-types.ts +22 -45
  424. package/src/runtime/channel-invite-transports/telegram.ts +4 -4
  425. package/src/runtime/channel-retry-sweep.ts +1 -0
  426. package/src/runtime/channel-verification-service.ts +3 -3
  427. package/src/runtime/client-health.ts +26 -0
  428. package/src/runtime/confirmation-request-guardian-bridge.ts +38 -29
  429. package/src/runtime/effective-capabilities.test.ts +128 -0
  430. package/src/runtime/effective-capabilities.ts +84 -0
  431. package/src/runtime/guardian-reply-router.ts +106 -21
  432. package/src/runtime/invite-redemption-service.ts +9 -25
  433. package/src/runtime/migrations/__tests__/vbundle-builder-fd-leak.test.ts +123 -0
  434. package/src/runtime/migrations/vbundle-builder.ts +49 -20
  435. package/src/runtime/pending-interactions.ts +15 -0
  436. package/src/runtime/routes/__tests__/client-routes.test.ts +13 -0
  437. package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +67 -0
  438. package/src/runtime/routes/__tests__/plugins-routes.test.ts +240 -1
  439. package/src/runtime/routes/app-routes.ts +1 -1
  440. package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +2 -2
  441. package/src/runtime/routes/assets/vellum-design-system.css +1959 -0
  442. package/src/runtime/routes/browser-tabs-routes.ts +9 -0
  443. package/src/runtime/routes/btw-routes.ts +1 -27
  444. package/src/runtime/routes/canonical-guardian-expiry-sweep.ts +17 -8
  445. package/src/runtime/routes/client-routes.ts +10 -0
  446. package/src/runtime/routes/contact-routes.ts +31 -8
  447. package/src/runtime/routes/conversation-compaction-routes.ts +1 -1
  448. package/src/runtime/routes/conversation-management-routes.ts +80 -1
  449. package/src/runtime/routes/conversation-query-routes.ts +68 -22
  450. package/src/runtime/routes/conversation-routes.ts +39 -14
  451. package/src/runtime/routes/credential-routes.ts +40 -16
  452. package/src/runtime/routes/empty-state-greeting-cache.ts +1 -2
  453. package/src/runtime/routes/events-routes.ts +1 -3
  454. package/src/runtime/routes/guardian-approval-interception.ts +14 -73
  455. package/src/runtime/routes/guardian-approval-prompt.ts +22 -4
  456. package/src/runtime/routes/home-feed-routes.ts +8 -3
  457. package/src/runtime/routes/identity-routes.ts +1 -296
  458. package/src/runtime/routes/inbound-message-handler.ts +214 -228
  459. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +89 -7
  460. package/src/runtime/routes/inbound-stages/admission-policy.test.ts +154 -0
  461. package/src/runtime/routes/inbound-stages/admission-policy.ts +140 -0
  462. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +3 -3
  463. package/src/runtime/routes/inbound-stages/background-dispatch.ts +11 -6
  464. package/src/runtime/routes/inbound-stages/escalation-intercept.ts +1 -2
  465. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +1 -2
  466. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +7 -7
  467. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +47 -28
  468. package/src/runtime/routes/inbound-stages/reaction-intercept.ts +358 -0
  469. package/src/runtime/routes/index.ts +2 -0
  470. package/src/runtime/routes/integrations/slack/__tests__/channel.test.ts +8 -0
  471. package/src/runtime/routes/integrations/slack/channel.ts +36 -0
  472. package/src/runtime/routes/internal-telemetry-routes.ts +1 -1
  473. package/src/runtime/routes/mcp-auth-routes.ts +233 -41
  474. package/src/runtime/routes/memory-eval-routes.ts +87 -0
  475. package/src/runtime/routes/notification-routes.ts +122 -133
  476. package/src/runtime/routes/platform-routes.ts +2 -2
  477. package/src/runtime/routes/plugins-routes.ts +202 -3
  478. package/src/runtime/routes/schedule-routes.ts +0 -22
  479. package/src/runtime/routes/secret-routes.ts +10 -0
  480. package/src/runtime/routes/surface-action-routes.ts +2 -1
  481. package/src/runtime/routes/tool-call-question-enrichment.test.ts +146 -0
  482. package/src/runtime/routes/tool-call-question-enrichment.ts +66 -0
  483. package/src/runtime/routes/workflow-routes.test.ts +229 -44
  484. package/src/runtime/routes/workflow-routes.ts +131 -29
  485. package/src/runtime/routes/workspace-greetings.ts +55 -0
  486. package/src/runtime/sync/resource-sync-events.ts +1 -11
  487. package/src/runtime/tool-grant-request-helper.ts +18 -16
  488. package/src/runtime/trust-context-resolver.ts +8 -5
  489. package/src/schedule/inference-profile.ts +2 -14
  490. package/src/schedule/schedule-store.ts +1 -1
  491. package/src/schedule/scheduler-types.ts +5 -1
  492. package/src/security/__tests__/provider-key-env-fallback.test.ts +6 -0
  493. package/src/security/secret-patterns.ts +3 -0
  494. package/src/subagent/manager.ts +17 -4
  495. package/src/subagent/types.ts +6 -0
  496. package/src/telemetry/trace-collection-policy.test.ts +28 -0
  497. package/src/telemetry/trace-collection-policy.ts +30 -0
  498. package/src/telemetry/types.ts +89 -0
  499. package/src/telemetry/usage-telemetry-reporter.test.ts +586 -36
  500. package/src/telemetry/usage-telemetry-reporter.ts +148 -41
  501. package/src/tools/AGENTS.md +3 -3
  502. package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +31 -0
  503. package/src/tools/browser/browser-execution.ts +30 -19
  504. package/src/tools/document/document-tool.ts +2 -3
  505. package/src/tools/executor.ts +5 -3
  506. package/src/tools/host-terminal/host-shell.ts +5 -4
  507. package/src/tools/memory/register.ts +2 -2
  508. package/src/tools/network/__tests__/web-fetch-firecrawl.test.ts +360 -0
  509. package/src/tools/network/__tests__/web-search.test.ts +143 -0
  510. package/src/tools/network/web-fetch.ts +372 -1
  511. package/src/tools/network/web-search-error.ts +1 -1
  512. package/src/tools/network/web-search.ts +213 -10
  513. package/src/tools/permission-checker.ts +4 -3
  514. package/src/tools/registry.ts +20 -0
  515. package/src/tools/schedule/create.ts +7 -12
  516. package/src/tools/schedule/update.ts +4 -11
  517. package/src/tools/shared/filesystem/path-policy.ts +39 -13
  518. package/src/tools/side-effects.ts +2 -17
  519. package/src/tools/skills/execute.ts +33 -0
  520. package/src/tools/subagent/spawn.ts +61 -12
  521. package/src/tools/terminal/shell.ts +10 -4
  522. package/src/tools/tool-approval-handler.ts +18 -13
  523. package/src/tools/tool-manifest.ts +0 -2
  524. package/src/tools/types.ts +9 -0
  525. package/src/tools/ui-surface/definitions.ts +64 -3
  526. package/src/tools/verification-control-plane-policy.ts +3 -1
  527. package/src/tools/workflows/run-workflow.test.ts +8 -18
  528. package/src/tools/workflows/run-workflow.ts +1 -0
  529. package/src/util/disk-usage.ts +78 -23
  530. package/src/util/platform.ts +10 -3
  531. package/src/watcher/telemetry.ts +2 -2
  532. package/src/workflows/capabilities.ts +2 -3
  533. package/src/workflows/engine.test.ts +175 -1
  534. package/src/workflows/engine.ts +82 -0
  535. package/src/workflows/journal-store.test.ts +70 -0
  536. package/src/workflows/journal-store.ts +18 -3
  537. package/src/workflows/run-manager.test.ts +171 -28
  538. package/src/workflows/run-manager.ts +66 -24
  539. package/src/workspace/migrations/105-enable-memory-v3-live-for-new-workspaces.ts +63 -0
  540. package/src/workspace/migrations/106-drop-collect-usage-data.ts +47 -0
  541. package/src/workspace/migrations/107-drop-send-diagnostics.ts +47 -0
  542. package/src/workspace/migrations/108-drop-balanced-economy-profile.ts +129 -0
  543. package/src/workspace/migrations/registry.ts +8 -0
  544. package/src/__tests__/app-control-no-global-cgevent.test.ts +0 -98
  545. package/src/__tests__/credential-security-e2e.test.ts +0 -362
  546. package/src/__tests__/credential-vault-unit.test.ts +0 -1528
  547. package/src/__tests__/credential-vault.test.ts +0 -1706
  548. package/src/__tests__/identity-intro-cache.test.ts +0 -315
  549. package/src/__tests__/secret-onetime-send.test.ts +0 -182
  550. package/src/cli/commands/__tests__/task.test.ts +0 -914
  551. package/src/cli/commands/task.ts +0 -771
  552. package/src/config/bundled-skills/personal-page/SKILL.md +0 -57
  553. package/src/config/bundled-skills/personal-page/TOOLS.json +0 -27
  554. package/src/config/bundled-skills/personal-page/tools/app-refresh.ts +0 -17
  555. package/src/config/preloaded-apps/personal-page/src/components/About.tsx +0 -22
  556. package/src/config/preloaded-apps/personal-page/src/components/App.tsx +0 -16
  557. package/src/config/preloaded-apps/personal-page/src/components/Features.tsx +0 -77
  558. package/src/config/preloaded-apps/personal-page/src/components/Hero.tsx +0 -57
  559. package/src/config/preloaded-apps/personal-page/src/components/Pending.tsx +0 -28
  560. package/src/config/preloaded-apps/personal-page/src/components/animations.tsx +0 -234
  561. package/src/config/preloaded-apps/personal-page/src/components/icons.tsx +0 -48
  562. package/src/config/preloaded-apps/personal-page/src/components/media.ts +0 -16
  563. package/src/config/preloaded-apps/personal-page/src/index.html +0 -20
  564. package/src/config/preloaded-apps/personal-page/src/main.tsx +0 -7
  565. package/src/config/preloaded-apps/personal-page/src/profile-data.ts +0 -82
  566. package/src/config/preloaded-apps/personal-page/src/styles.css +0 -759
  567. package/src/memory/__tests__/preloaded-apps.test.ts +0 -85
  568. package/src/memory/preloaded-apps.ts +0 -116
  569. package/src/notifications/tool-approval-copy.ts +0 -142
  570. package/src/runtime/routes/approval-prompt-ts-tracker.ts +0 -78
  571. package/src/runtime/routes/identity-intro-cache.ts +0 -172
  572. package/src/tools/credentials/vault.ts +0 -712
@@ -1,85 +0,0 @@
1
- import {
2
- existsSync,
3
- mkdirSync,
4
- readFileSync,
5
- rmSync,
6
- writeFileSync,
7
- } from "node:fs";
8
- import { join } from "node:path";
9
- import { afterEach, beforeEach, describe, expect, test } from "bun:test";
10
-
11
- import { setOverridesForTesting } from "../../__tests__/feature-flag-test-helpers.js";
12
- import type { AssistantConfig } from "../../config/schema.js";
13
- import { getAppsDir } from "../app-store.js";
14
- import {
15
- ACTIVATION_FLOW_FLAG,
16
- PERSONAL_PAGE_APP_ID,
17
- PERSONAL_PAGE_ARM,
18
- seedPreloadedApps,
19
- } from "../preloaded-apps.js";
20
-
21
- // The flag resolver reads the override cache and registry; the config
22
- // argument is part of the signature but not consulted for resolution.
23
- const config = {} as AssistantConfig;
24
-
25
- function definitionPath(): string {
26
- return join(getAppsDir(), `${PERSONAL_PAGE_APP_ID}.json`);
27
- }
28
-
29
- function appDir(): string {
30
- return join(getAppsDir(), PERSONAL_PAGE_APP_ID);
31
- }
32
-
33
- beforeEach(() => {
34
- setOverridesForTesting({});
35
- });
36
-
37
- afterEach(() => {
38
- setOverridesForTesting({});
39
- rmSync(definitionPath(), { force: true });
40
- rmSync(appDir(), { recursive: true, force: true });
41
- });
42
-
43
- describe("seedPreloadedApps gating", () => {
44
- test("does not seed on the control arm", async () => {
45
- setOverridesForTesting({ [ACTIVATION_FLOW_FLAG]: "control" });
46
- await seedPreloadedApps(config);
47
- expect(existsSync(definitionPath())).toBe(false);
48
- expect(existsSync(appDir())).toBe(false);
49
- });
50
-
51
- test("does not seed on other treatment arms", async () => {
52
- setOverridesForTesting({ [ACTIVATION_FLOW_FLAG]: "variant-a" });
53
- await seedPreloadedApps(config);
54
- expect(existsSync(definitionPath())).toBe(false);
55
- });
56
-
57
- test("does not seed when the flag resolves to the registry default", async () => {
58
- // No override → declared default "control".
59
- await seedPreloadedApps(config);
60
- expect(existsSync(definitionPath())).toBe(false);
61
- });
62
-
63
- test("leaves an already-seeded, compiled app untouched", async () => {
64
- setOverridesForTesting({ [ACTIVATION_FLOW_FLAG]: PERSONAL_PAGE_ARM });
65
-
66
- const sentinelDefinition = JSON.stringify({
67
- id: PERSONAL_PAGE_APP_ID,
68
- userEdited: true,
69
- });
70
- mkdirSync(join(appDir(), "dist"), { recursive: true });
71
- writeFileSync(definitionPath(), sentinelDefinition, "utf-8");
72
- writeFileSync(
73
- join(appDir(), "dist", "index.html"),
74
- "<!-- compiled -->",
75
- "utf-8",
76
- );
77
-
78
- await seedPreloadedApps(config);
79
-
80
- // Seeding must not re-copy the template or rewrite the definition once
81
- // the app exists — its content is considered user-owned.
82
- expect(readFileSync(definitionPath(), "utf-8")).toBe(sentinelDefinition);
83
- expect(existsSync(join(appDir(), "src"))).toBe(false);
84
- });
85
- });
@@ -1,116 +0,0 @@
1
- /**
2
- * Seeds preloaded apps into the workspace apps directory at daemon startup.
3
- *
4
- * A preloaded app ships as plain source files under
5
- * `src/config/preloaded-apps/<dirName>/` and is copied into
6
- * `data/apps/<dirName>/` with a fixed, well-known app id, then compiled.
7
- * The assistant later populates it by overwriting designated content files
8
- * (e.g. the personal page's `src/profile-data.ts`) and calling app_refresh —
9
- * it never authors the layout itself.
10
- *
11
- * Seeding is idempotent and deliberately conservative: once the definition
12
- * JSON exists the app is considered user-owned (its content may have been
13
- * populated) and the template is never re-copied. A missing `dist/` triggers
14
- * a recompile only.
15
- *
16
- * Seeding is gated on the activation-flow experiment: only assistants in the
17
- * personal-page treatment arm get the app. The gate is evaluated once per
18
- * daemon startup — an assistant moved into the arm later picks it up on its
19
- * next restart, and an already-seeded app is never removed when the
20
- * assistant leaves the arm (it is user-owned by then).
21
- */
22
-
23
- import { cpSync, existsSync, writeFileSync } from "node:fs";
24
- import { join } from "node:path";
25
-
26
- import { compileApp } from "../bundler/app-compiler.js";
27
- import {
28
- getAssistantFeatureFlagValue,
29
- initFeatureFlagOverrides,
30
- } from "../config/assistant-feature-flags.js";
31
- import type { AssistantConfig } from "../config/schema.js";
32
- import { resolveBundledDir } from "../util/bundled-asset.js";
33
- import { getLogger } from "../util/logger.js";
34
- import { getAppsDir } from "./app-store.js";
35
-
36
- const log = getLogger("preloaded-apps");
37
-
38
- /** Well-known id (and dirName) of the personal landing page app. */
39
- export const PERSONAL_PAGE_APP_ID = "personal-page";
40
-
41
- /** Multivariate activation-flow experiment flag (scope "both"). */
42
- export const ACTIVATION_FLOW_FLAG = "experiment-activation-flow-2026-06-03";
43
-
44
- /** Arm of the activation-flow experiment that gets the preseeded page. */
45
- export const PERSONAL_PAGE_ARM = "personal-page";
46
-
47
- export async function seedPreloadedApps(
48
- config: AssistantConfig,
49
- ): Promise<void> {
50
- // The lifecycle hook fires this early in startup, possibly before the
51
- // gateway override fetch has completed. Await it here (no-op when already
52
- // cached; bounded retries otherwise) so the arm read below sees the
53
- // platform-assigned value rather than the registry default.
54
- await initFeatureFlagOverrides();
55
-
56
- const arm = getAssistantFeatureFlagValue(ACTIVATION_FLOW_FLAG, config);
57
- if (arm !== PERSONAL_PAGE_ARM) return;
58
-
59
- await seedPersonalPageApp();
60
- }
61
-
62
- async function seedPersonalPageApp(): Promise<void> {
63
- const appsDir = getAppsDir();
64
- const definitionPath = join(appsDir, `${PERSONAL_PAGE_APP_ID}.json`);
65
- const appDir = join(appsDir, PERSONAL_PAGE_APP_ID);
66
- const alreadySeeded = existsSync(definitionPath);
67
-
68
- if (alreadySeeded && existsSync(join(appDir, "dist", "index.html"))) {
69
- return;
70
- }
71
-
72
- if (!alreadySeeded) {
73
- const templateDir = resolveBundledDir(
74
- import.meta.dirname ?? __dirname,
75
- "../config/preloaded-apps/personal-page",
76
- "preloaded-apps/personal-page",
77
- );
78
- if (!existsSync(join(templateDir, "src"))) {
79
- log.warn(
80
- { templateDir },
81
- "Personal page template not found — skipping preloaded app seeding",
82
- );
83
- return;
84
- }
85
-
86
- cpSync(join(templateDir, "src"), join(appDir, "src"), { recursive: true });
87
- // Multifile (formatVersion 2) apps keep an empty root index.html; the
88
- // real entrypoint is src/index.html compiled into dist/. Matches the
89
- // on-disk shape produced by createApp().
90
- writeFileSync(join(appDir, "index.html"), "", "utf-8");
91
-
92
- const now = Date.now();
93
- const definition = {
94
- id: PERSONAL_PAGE_APP_ID,
95
- name: "Your Page",
96
- description:
97
- "A personal landing page the assistant fills in with what it learns about you.",
98
- icon: "✨",
99
- schemaJson: "{}",
100
- createdAt: now,
101
- updatedAt: now,
102
- formatVersion: 2,
103
- dirName: PERSONAL_PAGE_APP_ID,
104
- };
105
- writeFileSync(definitionPath, JSON.stringify(definition, null, 2), "utf-8");
106
- log.info({ appDir }, "Seeded personal page app");
107
- }
108
-
109
- const result = await compileApp(appDir);
110
- if (!result.ok) {
111
- log.warn(
112
- { errors: result.errors },
113
- "Personal page app failed to compile after seeding",
114
- );
115
- }
116
- }
@@ -1,142 +0,0 @@
1
- /**
2
- * Deterministic helpers for building guardian-facing tool-approval copy.
3
- *
4
- * Produces Surface card seed content blocks for `tool_approval`,
5
- * `tool_grant_request`, and voice/call `pending_question` (with `toolName`)
6
- * guardian questions, enabling Approve/Reject buttons in the Vellum in-app
7
- * channel (web/macOS/iOS).
8
- */
9
-
10
- import { buildApprovalCardBlocks } from "./approval-card-builder.js";
11
- import {
12
- buildGuardianRequestCodeInstruction,
13
- type GuardianQuestionPayload,
14
- type LenientToolApprovalPayload,
15
- LenientToolApprovalPayloadSchema,
16
- parseGuardianQuestionPayload,
17
- resolveGuardianInstructionModeFromFields,
18
- resolveGuardianInstructionModeFromPayload,
19
- } from "./guardian-question-mode.js";
20
- import { nonEmpty, sanitizeIdentityField } from "./notification-utils.js";
21
-
22
- // ── Approval detection ──────────────────────────────────────────────────────
23
-
24
- /**
25
- * Determine whether a typed guardian.question payload represents a tool
26
- * approval (as opposed to a free-text answer). Uses the canonical mode
27
- * resolver in `guardian-question-mode.ts` — the single source of truth
28
- * for the requestKind → instructionMode mapping.
29
- */
30
- function isToolApprovalPayload(payload: GuardianQuestionPayload): boolean {
31
- const { mode } = resolveGuardianInstructionModeFromPayload(payload);
32
- return mode === "approval" && payload.requestKind !== "access_request";
33
- }
34
-
35
- /**
36
- * Lenient approval detection for partially-constructed payloads that don't
37
- * satisfy the strict discriminated union schema.
38
- */
39
- function isLenientToolApproval(payload: LenientToolApprovalPayload): boolean {
40
- const modeResolution = resolveGuardianInstructionModeFromFields(
41
- payload.requestKind,
42
- payload.toolName,
43
- );
44
- if (!modeResolution) return false;
45
- return (
46
- modeResolution.mode === "approval" &&
47
- payload.requestKind !== "access_request"
48
- );
49
- }
50
-
51
- // ── Seed content blocks (Surface-based rendering) ───────────────────────────
52
-
53
- /**
54
- * Build structured content blocks for a tool approval/grant notification seed
55
- * message. Returns `null` when the payload does not represent a tool approval.
56
- *
57
- * Accepts both strict `GuardianQuestionPayload` (Zod-validated) and raw
58
- * `Record<string, unknown>` payloads. For raw payloads, attempts strict
59
- * parsing first, then falls back to lenient field extraction so cards
60
- * still render when optional fields are absent.
61
- */
62
- export function buildToolApprovalSeedContentBlocks(
63
- payload: GuardianQuestionPayload,
64
- ): unknown[] | null;
65
- export function buildToolApprovalSeedContentBlocks(
66
- payload: Record<string, unknown>,
67
- ): unknown[] | null;
68
- export function buildToolApprovalSeedContentBlocks(
69
- payload: GuardianQuestionPayload | Record<string, unknown>,
70
- ): unknown[] | null {
71
- // Try strict Zod parsing first (full discriminated union).
72
- const strict = parseGuardianQuestionPayload(
73
- payload as Record<string, unknown>,
74
- );
75
- if (strict) {
76
- if (!isToolApprovalPayload(strict)) return null;
77
- return buildCardFromFields(strict);
78
- }
79
-
80
- // Fall back to lenient parsing — requires only `requestKind`.
81
- const lenient = LenientToolApprovalPayloadSchema.safeParse(payload);
82
- if (!lenient.success) return null;
83
- if (!isLenientToolApproval(lenient.data)) return null;
84
- return buildCardFromFields(lenient.data);
85
- }
86
-
87
- // ── Card construction (shared between strict and lenient paths) ─────────────
88
-
89
- function buildCardFromFields(
90
- p: GuardianQuestionPayload | LenientToolApprovalPayload,
91
- ): unknown[] {
92
- const toolName =
93
- ("toolName" in p ? nonEmpty(p.toolName) : undefined) ?? "unknown tool";
94
- const rawRequester = nonEmpty(p.requesterIdentifier);
95
- const requester = rawRequester
96
- ? sanitizeIdentityField(rawRequester)
97
- : "Someone";
98
-
99
- const isGrant = p.requestKind === "tool_grant_request";
100
-
101
- const metadata: Array<{ label: string; value: string }> = [];
102
- metadata.push({ label: "Tool", value: toolName });
103
- const sourceChannel = nonEmpty(p.sourceChannel);
104
- if (sourceChannel) {
105
- metadata.push({ label: "Source", value: sourceChannel });
106
- }
107
-
108
- const body = p.questionText
109
- ? `> ${p.questionText}`
110
- : "No additional context available.";
111
-
112
- // Fallback text with request-code instructions for older clients.
113
- const baseFallback =
114
- p.questionText ?? `${requester} is requesting approval to use ${toolName}`;
115
- let fallbackText = baseFallback;
116
- const requestCode = nonEmpty(p.requestCode);
117
- if (requestCode) {
118
- const modeResolution = resolveGuardianInstructionModeFromFields(
119
- p.requestKind,
120
- "toolName" in p ? (p.toolName ?? undefined) : undefined,
121
- );
122
- const mode = modeResolution?.mode ?? "approval";
123
- const instruction = buildGuardianRequestCodeInstruction(
124
- requestCode.trim().toUpperCase(),
125
- mode,
126
- );
127
- fallbackText = `${baseFallback}\n\n${instruction}`;
128
- }
129
-
130
- return buildApprovalCardBlocks({
131
- surfaceIdPrefix: "tool-approval",
132
- cardTitle: isGrant ? "Tool Grant Request" : "Tool Approval",
133
- requesterName: requester,
134
- subtitle: isGrant
135
- ? "Requesting permission to use this tool"
136
- : "Requesting approval to run this tool",
137
- body,
138
- metadata,
139
- requestId: nonEmpty(p.requestId),
140
- fallbackText,
141
- });
142
- }
@@ -1,78 +0,0 @@
1
- /**
2
- * Persistent tracker for approval prompt message timestamps.
3
- *
4
- * Scopes guardian reaction approvals so only reactions on a known approval
5
- * prompt can resolve a pending request. Without this, a stray 👍/✅ on any
6
- * message in the guardian chat could approve a pending request (since
7
- * reactions are now admitted from any subscribed channel, not just tracked
8
- * bot threads).
9
- *
10
- * Entries are stored in the `approval_prompt_ts_tracker` table (created by
11
- * `createApprovalPromptTsTrackerTable`) so that a daemon restart between
12
- * prompt delivery and guardian reaction does not silently invalidate
13
- * reactions that are still within the 30-minute guardian approval TTL.
14
- * Entries expire after `APPROVAL_PROMPT_TS_TTL_MS` (guardian approval TTL
15
- * plus grace).
16
- */
17
- import { getSqlite } from "../../memory/db-connection.js";
18
- import { getLogger } from "../../util/logger.js";
19
-
20
- const log = getLogger("runtime-http");
21
-
22
- const APPROVAL_PROMPT_TS_TTL_MS = 35 * 60 * 1000;
23
-
24
- // Swallow errors: callers run this inside their delivery try/catch, so a
25
- // tracker throw would be misread as a delivery failure and trigger
26
- // fallback/retry, double-posting the guardian prompt.
27
- export function trackApprovalPromptTs(
28
- channel: string,
29
- chatId: string,
30
- ts: string,
31
- ): void {
32
- try {
33
- const now = Date.now();
34
- const expiresAt = now + APPROVAL_PROMPT_TS_TTL_MS;
35
- const db = getSqlite();
36
- db.run(
37
- /*sql*/ `DELETE FROM approval_prompt_ts_tracker WHERE expires_at <= ?`,
38
- [now],
39
- );
40
- db.run(
41
- /*sql*/ `INSERT OR REPLACE INTO approval_prompt_ts_tracker (channel, chat_id, ts, expires_at) VALUES (?, ?, ?, ?)`,
42
- [channel, chatId, ts, expiresAt],
43
- );
44
- } catch (err) {
45
- log.error(
46
- { err, channel, chatId, ts },
47
- "Failed to persist approval prompt ts tracker entry; continuing without tracking",
48
- );
49
- }
50
- }
51
-
52
- export function isTrackedApprovalPromptTs(
53
- channel: string,
54
- chatId: string,
55
- ts: string,
56
- ): boolean {
57
- const now = Date.now();
58
- const db = getSqlite();
59
- const row = db
60
- .query(
61
- /*sql*/ `SELECT expires_at FROM approval_prompt_ts_tracker WHERE channel = ? AND chat_id = ? AND ts = ?`,
62
- )
63
- .get(channel, chatId, ts) as { expires_at: number } | null;
64
- if (!row) return false;
65
- if (row.expires_at <= now) {
66
- db.run(
67
- /*sql*/ `DELETE FROM approval_prompt_ts_tracker WHERE channel = ? AND chat_id = ? AND ts = ?`,
68
- [channel, chatId, ts],
69
- );
70
- return false;
71
- }
72
- return true;
73
- }
74
-
75
- /** @internal Test-only — clear all tracked entries. */
76
- export function _clearApprovalPromptTsTrackerForTesting(): void {
77
- getSqlite().run(/*sql*/ `DELETE FROM approval_prompt_ts_tracker`);
78
- }
@@ -1,172 +0,0 @@
1
- /**
2
- * Caching layer for identity greetings.
3
- *
4
- * Greetings are sourced from (in priority order):
5
- * 1. A `## Greetings` section in SOUL.md (user-defined bullet list)
6
- * 2. A cached greetings array (populated by the empty-state greeting callsite)
7
- * 3. A generic fallback when generation is unavailable
8
- *
9
- * Cache invalidation is intentionally TTL-only. User-authored SOUL.md
10
- * greetings are read before cache, so manual overrides still take priority
11
- * without coupling cache validity to prompt-file edits.
12
- *
13
- * Storage uses the existing `memory_checkpoints` table (simple key-value store).
14
- */
15
-
16
- import { existsSync, readFileSync } from "node:fs";
17
-
18
- import {
19
- getMemoryCheckpoint,
20
- setMemoryCheckpoint,
21
- } from "../../memory/checkpoints.js";
22
- import { getWorkspacePromptPath } from "../../util/platform.js";
23
-
24
- // ---------------------------------------------------------------------------
25
- // Constants
26
- // ---------------------------------------------------------------------------
27
-
28
- const CACHE_TTL_MS = 4 * 60 * 60 * 1000; // 4 hours
29
-
30
- const CHECKPOINT_KEY_GREETINGS = "identity:intro:greetings";
31
- const CHECKPOINT_KEY_TIMESTAMP = "identity:intro:cached_at";
32
-
33
- // ---------------------------------------------------------------------------
34
- // Helpers
35
- // ---------------------------------------------------------------------------
36
-
37
- /** Read a workspace prompt file, returning empty string if missing. */
38
- function readWorkspaceFile(name: string): string {
39
- try {
40
- const path = getWorkspacePromptPath(name);
41
- if (!existsSync(path)) return "";
42
- return readFileSync(path, "utf-8");
43
- } catch {
44
- return "";
45
- }
46
- }
47
-
48
- function parseIdentityIntroSection(content: string): string | null {
49
- let inSection = false;
50
-
51
- for (const line of content.split("\n")) {
52
- const trimmed = line.trim();
53
- if (/^#+\s/.test(trimmed)) {
54
- inSection = trimmed.toLowerCase().includes("identity intro");
55
- continue;
56
- }
57
- if (inSection && trimmed.length > 0) {
58
- return trimmed;
59
- }
60
- }
61
-
62
- return null;
63
- }
64
-
65
- /**
66
- * Read the explicit `## Identity Intro` section from workspace prompt files.
67
- *
68
- * BOOTSTRAP.md instructs the assistant to write this section in IDENTITY.md.
69
- * SOUL.md remains a fallback for older workspaces that stored the intro there.
70
- */
71
- export function readWorkspaceIdentityIntro(): string | null {
72
- return (
73
- parseIdentityIntroSection(readWorkspaceFile("IDENTITY.md")) ??
74
- parseIdentityIntroSection(readWorkspaceFile("SOUL.md"))
75
- );
76
- }
77
-
78
- /**
79
- * Parse the `## Greetings` section from SOUL.md. Returns bullet items as an
80
- * array of strings, or `null` if the section is missing or empty.
81
- */
82
- export function parseGreetingsSection(content: string): string[] | null {
83
- let inSection = false;
84
- let sectionLevel: number | null = null;
85
- const greetings: string[] = [];
86
-
87
- for (const line of content.split("\n")) {
88
- const trimmed = line.trim();
89
- const heading = /^(#{1,6})\s+(.+?)\s*#*$/.exec(trimmed);
90
- if (heading) {
91
- const level = heading[1]!.length;
92
- const title = heading[2]!.trim();
93
- if (inSection) {
94
- if (sectionLevel !== null && level <= sectionLevel) break;
95
- continue;
96
- }
97
- if (level === 2 && /^greetings$/i.test(title)) {
98
- inSection = true;
99
- sectionLevel = level;
100
- }
101
- continue;
102
- }
103
- if (!inSection) continue;
104
- const bullet = /^(?:[-*+]\s+|\d+[.)]\s+)(.+)$/.exec(trimmed);
105
- const greeting = bullet?.[1]?.trim();
106
- if (greeting) {
107
- greetings.push(greeting);
108
- }
109
- }
110
-
111
- return greetings.length > 0 ? greetings : null;
112
- }
113
-
114
- /**
115
- * Read user-defined greetings from the `## Greetings` section of SOUL.md.
116
- */
117
- export function readWorkspaceGreetings(): string[] | null {
118
- const soulContent = readWorkspaceFile("SOUL.md");
119
- if (!soulContent) return null;
120
- return parseGreetingsSection(soulContent);
121
- }
122
-
123
- // ---------------------------------------------------------------------------
124
- // Public API
125
- // ---------------------------------------------------------------------------
126
-
127
- export interface CachedIntro {
128
- greetings: string[];
129
- }
130
-
131
- /**
132
- * Retrieve the cached greetings array if it exists and is within the TTL
133
- * window.
134
- *
135
- * Returns `null` when the cache is missing or expired.
136
- */
137
- export function getCachedIntro(): CachedIntro | null {
138
- try {
139
- const raw = getMemoryCheckpoint(CHECKPOINT_KEY_GREETINGS);
140
- const timestampStr = getMemoryCheckpoint(CHECKPOINT_KEY_TIMESTAMP);
141
-
142
- if (!raw || !timestampStr) return null;
143
-
144
- // TTL check
145
- const cachedAt = Number(timestampStr);
146
- if (isNaN(cachedAt) || Date.now() - cachedAt > CACHE_TTL_MS) return null;
147
-
148
- // Parse stored value — handles both JSON array and legacy single string
149
- let greetings: string[];
150
- try {
151
- const parsed = JSON.parse(raw);
152
- greetings = Array.isArray(parsed) ? parsed : [raw];
153
- } catch {
154
- greetings = [raw];
155
- }
156
-
157
- return { greetings };
158
- } catch {
159
- return null;
160
- }
161
- }
162
-
163
- /** Store a greetings array in the cache along with the current timestamp. */
164
- export function setCachedIntro(greetings: string[]): void {
165
- try {
166
- const now = String(Date.now());
167
- setMemoryCheckpoint(CHECKPOINT_KEY_GREETINGS, JSON.stringify(greetings));
168
- setMemoryCheckpoint(CHECKPOINT_KEY_TIMESTAMP, now);
169
- } catch {
170
- // Cache write failure is non-fatal — next request will regenerate.
171
- }
172
- }