@vellumai/assistant 0.5.15 → 0.6.0

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 (503) hide show
  1. package/ARCHITECTURE.md +3 -3
  2. package/Dockerfile +0 -3
  3. package/docs/architecture/integrations.md +15 -14
  4. package/knip.json +4 -1
  5. package/openapi.yaml +670 -122
  6. package/package.json +1 -1
  7. package/src/__tests__/actor-token-service.test.ts +68 -0
  8. package/src/__tests__/agent-loop.test.ts +0 -32
  9. package/src/__tests__/always-loaded-tools-guard.test.ts +2 -2
  10. package/src/__tests__/anthropic-provider.test.ts +57 -3
  11. package/src/__tests__/app-compiler.test.ts +120 -0
  12. package/src/__tests__/assistant-feature-flags-integration.test.ts +5 -377
  13. package/src/__tests__/call-conversation-messages.test.ts +2 -6
  14. package/src/__tests__/call-domain.test.ts +2 -6
  15. package/src/__tests__/call-pointer-messages.test.ts +2 -14
  16. package/src/__tests__/call-recovery.test.ts +2 -6
  17. package/src/__tests__/call-routes-http.test.ts +2 -6
  18. package/src/__tests__/call-store.test.ts +2 -6
  19. package/src/__tests__/cancel-resolves-conversation-key.test.ts +2 -6
  20. package/src/__tests__/canonical-guardian-store.test.ts +2 -6
  21. package/src/__tests__/ces-rpc-credential-backend.test.ts +4 -1
  22. package/src/__tests__/channel-delivery-store.test.ts +2 -6
  23. package/src/__tests__/channel-retry-sweep.test.ts +2 -6
  24. package/src/__tests__/checker.test.ts +84 -3
  25. package/src/__tests__/clawhub.test.ts +54 -24
  26. package/src/__tests__/cli-command-risk-guard.test.ts +108 -6
  27. package/src/__tests__/cli-memory.test.ts +377 -0
  28. package/src/__tests__/computer-use-skill-manifest-regression.test.ts +12 -2
  29. package/src/__tests__/config-schema.test.ts +1 -3
  30. package/src/__tests__/config-set-platform-guard.test.ts +302 -0
  31. package/src/__tests__/config-watcher-feature-flags.test.ts +211 -0
  32. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +2 -6
  33. package/src/__tests__/contacts-tools.test.ts +31 -0
  34. package/src/__tests__/context-overflow-reducer.test.ts +86 -0
  35. package/src/__tests__/context-token-estimator.test.ts +175 -10
  36. package/src/__tests__/conversation-agent-loop-overflow.test.ts +9 -0
  37. package/src/__tests__/conversation-agent-loop.test.ts +9 -0
  38. package/src/__tests__/conversation-attachments.test.ts +2 -6
  39. package/src/__tests__/conversation-attention-store.test.ts +2 -6
  40. package/src/__tests__/conversation-clear-safety.test.ts +2 -6
  41. package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +4 -10
  42. package/src/__tests__/conversation-disk-view-integration.test.ts +2 -6
  43. package/src/__tests__/conversation-disk-view.test.ts +2 -6
  44. package/src/__tests__/conversation-error.test.ts +33 -2
  45. package/src/__tests__/conversation-fork-crud.test.ts +2 -6
  46. package/src/__tests__/conversation-history-web-search.test.ts +5 -0
  47. package/src/__tests__/conversation-load-history-repair.test.ts +5 -1
  48. package/src/__tests__/conversation-media-retry.test.ts +91 -0
  49. package/src/__tests__/conversation-runtime-assembly.test.ts +7 -4
  50. package/src/__tests__/conversation-slash-commands.test.ts +2 -6
  51. package/src/__tests__/conversation-starter-routes.test.ts +20 -11
  52. package/src/__tests__/conversation-store.test.ts +2 -6
  53. package/src/__tests__/conversation-usage.test.ts +3 -6
  54. package/src/__tests__/conversation-wipe.test.ts +11 -408
  55. package/src/__tests__/credential-execution-feature-gates.test.ts +3 -3
  56. package/src/__tests__/credential-execution-shell-lockdown.test.ts +2 -2
  57. package/src/__tests__/credential-security-e2e.test.ts +6 -1
  58. package/src/__tests__/docker-signing-key-bootstrap.test.ts +7 -73
  59. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +6 -7
  60. package/src/__tests__/followup-tools.test.ts +2 -6
  61. package/src/__tests__/graph-extraction-event-date.test.ts +186 -0
  62. package/src/__tests__/guardian-action-conversation-turn.test.ts +2 -6
  63. package/src/__tests__/guardian-action-followup-executor.test.ts +2 -6
  64. package/src/__tests__/guardian-action-followup-store.test.ts +2 -6
  65. package/src/__tests__/guardian-action-grant-mint-consume.test.ts +2 -6
  66. package/src/__tests__/guardian-action-late-reply.test.ts +2 -6
  67. package/src/__tests__/guardian-action-store.test.ts +2 -6
  68. package/src/__tests__/guardian-binding-drift-heal.test.ts +2 -6
  69. package/src/__tests__/guardian-decision-primitive-canonical.test.ts +8 -8
  70. package/src/__tests__/guardian-dispatch.test.ts +2 -6
  71. package/src/__tests__/guardian-grant-minting.test.ts +2 -14
  72. package/src/__tests__/guardian-principal-id-roundtrip.test.ts +2 -6
  73. package/src/__tests__/guardian-routing-invariants.test.ts +343 -6
  74. package/src/__tests__/guardian-routing-state.test.ts +2 -6
  75. package/src/__tests__/guardian-verification-voice-binding.test.ts +2 -6
  76. package/src/__tests__/heartbeat-service.test.ts +1 -3
  77. package/src/__tests__/inbound-invite-redemption.test.ts +2 -6
  78. package/src/__tests__/injection-block.test.ts +154 -0
  79. package/src/__tests__/install-meta.test.ts +506 -0
  80. package/src/__tests__/install-skill-routing.test.ts +292 -0
  81. package/src/__tests__/intent-routing.test.ts +6 -18
  82. package/src/__tests__/invite-redemption-service.test.ts +2 -6
  83. package/src/__tests__/invite-routes-http.test.ts +2 -6
  84. package/src/__tests__/jobs-store-qdrant-breaker.test.ts +2 -14
  85. package/src/__tests__/list-messages-attachments.test.ts +2 -6
  86. package/src/__tests__/llm-context-route-provider.test.ts +2 -6
  87. package/src/__tests__/llm-request-log-turn-query.test.ts +2 -6
  88. package/src/__tests__/llm-usage-store.test.ts +2 -6
  89. package/src/__tests__/log-export-workspace.test.ts +4 -34
  90. package/src/__tests__/managed-skill-lifecycle.test.ts +7 -37
  91. package/src/__tests__/managed-store.test.ts +40 -21
  92. package/src/__tests__/memory-jobs-worker-backoff.test.ts +2 -8
  93. package/src/__tests__/memory-recall-log-store.test.ts +2 -6
  94. package/src/__tests__/memory-upsert-concurrency.test.ts +4 -112
  95. package/src/__tests__/messaging-send-tool.test.ts +6 -6
  96. package/src/__tests__/migration-cross-version-compatibility.test.ts +1 -29
  97. package/src/__tests__/migration-export-http.test.ts +3 -34
  98. package/src/__tests__/migration-import-commit-http.test.ts +1 -29
  99. package/src/__tests__/migration-import-preflight-http.test.ts +3 -34
  100. package/src/__tests__/no-domain-routing-in-prompt-guard.test.ts +2 -1
  101. package/src/__tests__/non-member-access-request.test.ts +2 -6
  102. package/src/__tests__/notification-guardian-path.test.ts +2 -6
  103. package/src/__tests__/oauth-apps-routes.test.ts +120 -10
  104. package/src/__tests__/oauth-cli.test.ts +364 -2
  105. package/src/__tests__/oauth-connect-orchestrator.test.ts +709 -0
  106. package/src/__tests__/oauth-provider-serializer.test.ts +2 -1
  107. package/src/__tests__/oauth-provider-visibility.test.ts +149 -0
  108. package/src/__tests__/oauth-providers-routes.test.ts +5 -2
  109. package/src/__tests__/oauth-store.test.ts +0 -5
  110. package/src/__tests__/oauth2-gateway-transport.test.ts +18 -3
  111. package/src/__tests__/outlook-attachments.test.ts +301 -0
  112. package/src/__tests__/outlook-automation-tools.test.ts +425 -0
  113. package/src/__tests__/outlook-categories.test.ts +212 -0
  114. package/src/__tests__/outlook-client-automation.test.ts +246 -0
  115. package/src/__tests__/outlook-compose-tools.test.ts +325 -0
  116. package/src/__tests__/outlook-declutter-tools.test.ts +585 -0
  117. package/src/__tests__/outlook-email-watcher.test.ts +322 -0
  118. package/src/__tests__/outlook-follow-up.test.ts +196 -0
  119. package/src/__tests__/outlook-messaging-provider.test.ts +1071 -0
  120. package/src/__tests__/outlook-trash.test.ts +77 -0
  121. package/src/__tests__/outlook-unsubscribe.test.ts +250 -0
  122. package/src/__tests__/path-policy.test.ts +2 -17
  123. package/src/__tests__/permission-types.test.ts +0 -1
  124. package/src/__tests__/platform-callback-registration.test.ts +7 -11
  125. package/src/__tests__/playbook-execution.test.ts +76 -80
  126. package/src/__tests__/playbook-tools.test.ts +5 -7
  127. package/src/__tests__/provider-commit-message-generator.test.ts +0 -1
  128. package/src/__tests__/provider-error-scenarios.test.ts +21 -2
  129. package/src/__tests__/qdrant-manager.test.ts +68 -21
  130. package/src/__tests__/rebuild-index-graph-nodes.test.ts +273 -0
  131. package/src/__tests__/registry.test.ts +2 -2
  132. package/src/__tests__/require-fresh-approval.test.ts +64 -3
  133. package/src/__tests__/runtime-events-sse-parity.test.ts +2 -6
  134. package/src/__tests__/runtime-events-sse.test.ts +2 -6
  135. package/src/__tests__/sandbox-diagnostics.test.ts +20 -29
  136. package/src/__tests__/scaffold-managed-skill-tool.test.ts +2 -10
  137. package/src/__tests__/schedule-store.test.ts +2 -6
  138. package/src/__tests__/schedule-tools.test.ts +2 -6
  139. package/src/__tests__/scheduler-recurrence.test.ts +1 -5
  140. package/src/__tests__/scoped-approval-grants.test.ts +2 -6
  141. package/src/__tests__/scoped-grant-security-matrix.test.ts +2 -6
  142. package/src/__tests__/search-skills-unified.test.ts +421 -0
  143. package/src/__tests__/secret-allowlist.test.ts +20 -35
  144. package/src/__tests__/secret-onetime-send.test.ts +2 -0
  145. package/src/__tests__/send-endpoint-busy.test.ts +2 -6
  146. package/src/__tests__/sequence-store.test.ts +2 -6
  147. package/src/__tests__/server-history-render.test.ts +2 -6
  148. package/src/__tests__/shell-credential-ref.test.ts +0 -5
  149. package/src/__tests__/skill-feature-flags-integration.test.ts +38 -31
  150. package/src/__tests__/skill-feature-flags.test.ts +6 -6
  151. package/src/__tests__/skill-load-feature-flag.test.ts +13 -54
  152. package/src/__tests__/skill-load-inline-command.test.ts +3 -65
  153. package/src/__tests__/skill-load-inline-includes.test.ts +3 -65
  154. package/src/__tests__/skill-load-tool.test.ts +3 -67
  155. package/src/__tests__/skill-memory.test.ts +480 -195
  156. package/src/__tests__/skills-uninstall.test.ts +2 -2
  157. package/src/__tests__/skills.test.ts +23 -50
  158. package/src/__tests__/slack-channel-config.test.ts +2 -21
  159. package/src/__tests__/slack-inbound-verification.test.ts +2 -6
  160. package/src/__tests__/starter-bundle.test.ts +2 -8
  161. package/src/__tests__/stt-hints.test.ts +7 -2
  162. package/src/__tests__/system-prompt.test.ts +25 -45
  163. package/src/__tests__/task-compiler.test.ts +2 -27
  164. package/src/__tests__/task-management-tools.test.ts +2 -27
  165. package/src/__tests__/task-memory-cleanup.test.ts +173 -250
  166. package/src/__tests__/task-runner.test.ts +2 -27
  167. package/src/__tests__/task-scheduler.test.ts +2 -27
  168. package/src/__tests__/terminal-tools.test.ts +1 -17
  169. package/src/__tests__/test-preload.ts +3 -0
  170. package/src/__tests__/token-estimator-accuracy.benchmark.test.ts +0 -79
  171. package/src/__tests__/tool-approval-handler.test.ts +4 -27
  172. package/src/__tests__/tool-execution-abort-cleanup.test.ts +2 -11
  173. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +1 -25
  174. package/src/__tests__/tool-executor-lifecycle-events.test.ts +0 -1
  175. package/src/__tests__/tool-executor.test.ts +0 -1
  176. package/src/__tests__/tool-grant-request-escalation.test.ts +4 -27
  177. package/src/__tests__/tool-preview-lifecycle.test.ts +0 -20
  178. package/src/__tests__/tool-side-effects-slack-dm.test.ts +276 -0
  179. package/src/__tests__/trust-store.test.ts +10 -42
  180. package/src/__tests__/trusted-contact-approval-notifier.test.ts +1 -30
  181. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +3 -27
  182. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +2 -28
  183. package/src/__tests__/trusted-contact-multichannel.test.ts +2 -28
  184. package/src/__tests__/trusted-contact-verification.test.ts +2 -28
  185. package/src/__tests__/turn-boundary-resolution.test.ts +2 -34
  186. package/src/__tests__/twilio-provider.test.ts +0 -16
  187. package/src/__tests__/twilio-routes-twiml.test.ts +7 -12
  188. package/src/__tests__/twilio-routes.test.ts +0 -24
  189. package/src/__tests__/update-bulletin.test.ts +17 -89
  190. package/src/__tests__/usage-cache-backfill-migration.test.ts +1 -26
  191. package/src/__tests__/usage-routes.test.ts +2 -27
  192. package/src/__tests__/user-reference.test.ts +1 -5
  193. package/src/__tests__/vbundle-pax-and-symlink.test.ts +4 -34
  194. package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +2 -53
  195. package/src/__tests__/verification-control-plane-policy.test.ts +0 -2
  196. package/src/__tests__/voice-invite-redemption.test.ts +2 -27
  197. package/src/__tests__/voice-scoped-grant-consumer.test.ts +2 -30
  198. package/src/__tests__/voice-session-bridge.test.ts +2 -27
  199. package/src/__tests__/volume-security-guard.test.ts +2 -0
  200. package/src/__tests__/workspace-lifecycle.test.ts +29 -1
  201. package/src/__tests__/workspace-migration-009-backfill-conversation-disk-view.test.ts +4 -29
  202. package/src/__tests__/workspace-migration-012-rename-conversation-disk-view-dirs.test.ts +2 -2
  203. package/src/__tests__/workspace-migration-013-repair-conversation-disk-view.test.ts +4 -29
  204. package/src/__tests__/workspace-migration-026-backfill-install-meta.test.ts +558 -0
  205. package/src/__tests__/workspace-migration-down-functions.test.ts +0 -6
  206. package/src/__tests__/workspace-policy.test.ts +1 -1
  207. package/src/acp/client-handler.ts +1 -2
  208. package/src/agent/attachments.ts +7 -2
  209. package/src/agent/image-optimize.ts +165 -0
  210. package/src/agent/loop.ts +1 -15
  211. package/src/bundler/app-compiler.ts +179 -2
  212. package/src/bundler/package-resolver.ts +3 -5
  213. package/src/cli/__tests__/notifications.test.ts +1 -24
  214. package/src/cli/cli-memory.ts +179 -0
  215. package/src/cli/commands/avatar.ts +3 -3
  216. package/src/cli/commands/config.ts +26 -13
  217. package/src/cli/commands/doctor.ts +2 -2
  218. package/src/cli/commands/memory.ts +41 -55
  219. package/src/cli/commands/oauth/__tests__/connect.test.ts +2 -2
  220. package/src/cli/commands/oauth/__tests__/disconnect.test.ts +2 -2
  221. package/src/cli/commands/oauth/__tests__/mode.test.ts +8 -1
  222. package/src/cli/commands/oauth/__tests__/providers-update.test.ts +1 -1
  223. package/src/cli/commands/oauth/__tests__/status.test.ts +2 -2
  224. package/src/cli/commands/oauth/connect.ts +26 -6
  225. package/src/cli/commands/oauth/mode.ts +7 -0
  226. package/src/cli/commands/oauth/providers.ts +49 -42
  227. package/src/cli/commands/oauth/shared.ts +39 -3
  228. package/src/cli/commands/platform/__tests__/connect.test.ts +3 -49
  229. package/src/cli/commands/platform/__tests__/disconnect.test.ts +3 -49
  230. package/src/cli/commands/platform/__tests__/status.test.ts +5 -55
  231. package/src/cli/commands/platform/index.ts +16 -16
  232. package/src/cli/commands/skills.ts +88 -16
  233. package/src/cli/commands/trust.ts +2 -2
  234. package/src/cli/lib/daemon-credential-client.ts +2 -3
  235. package/src/config/bundled-skills/acp/TOOLS.json +1 -1
  236. package/src/config/bundled-skills/computer-use/TOOLS.json +7 -7
  237. package/src/config/bundled-skills/contacts/SKILL.md +0 -1
  238. package/src/config/bundled-skills/contacts/TOOLS.json +0 -8
  239. package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +0 -4
  240. package/src/config/bundled-skills/gmail/SKILL.md +2 -10
  241. package/src/config/bundled-skills/google-calendar/SKILL.md +1 -9
  242. package/src/config/bundled-skills/messaging/SKILL.md +26 -19
  243. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +40 -33
  244. package/src/config/bundled-skills/outlook/SKILL.md +189 -0
  245. package/src/config/bundled-skills/outlook/TOOLS.json +530 -0
  246. package/src/config/bundled-skills/outlook/tools/outlook-attachments.ts +85 -0
  247. package/src/config/bundled-skills/outlook/tools/outlook-categories.ts +77 -0
  248. package/src/config/bundled-skills/outlook/tools/outlook-draft.ts +84 -0
  249. package/src/config/bundled-skills/outlook/tools/outlook-follow-up.ts +94 -0
  250. package/src/config/bundled-skills/outlook/tools/outlook-forward.ts +49 -0
  251. package/src/config/bundled-skills/outlook/tools/outlook-outreach-scan.ts +237 -0
  252. package/src/config/bundled-skills/outlook/tools/outlook-rules.ts +161 -0
  253. package/src/config/bundled-skills/outlook/tools/outlook-send-draft.ts +32 -0
  254. package/src/config/bundled-skills/outlook/tools/outlook-sender-digest.ts +272 -0
  255. package/src/config/bundled-skills/outlook/tools/outlook-trash.ts +29 -0
  256. package/src/config/bundled-skills/outlook/tools/outlook-unsubscribe.ts +129 -0
  257. package/src/config/bundled-skills/outlook/tools/outlook-vacation.ts +87 -0
  258. package/src/config/bundled-skills/outlook/tools/shared.ts +20 -0
  259. package/src/config/bundled-skills/outlook-calendar/SKILL.md +51 -0
  260. package/src/config/bundled-skills/outlook-calendar/TOOLS.json +221 -0
  261. package/src/config/bundled-skills/outlook-calendar/calendar-client.ts +252 -0
  262. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-check-availability.ts +53 -0
  263. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-create-event.ts +74 -0
  264. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-get-event.ts +18 -0
  265. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-list-events.ts +46 -0
  266. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-rsvp.ts +36 -0
  267. package/src/config/bundled-skills/outlook-calendar/tools/shared.ts +17 -0
  268. package/src/config/bundled-skills/outlook-calendar/types.ts +120 -0
  269. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +47 -40
  270. package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +16 -29
  271. package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +16 -18
  272. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +39 -47
  273. package/src/config/bundled-skills/settings/TOOLS.json +3 -3
  274. package/src/config/bundled-skills/slack/SKILL.md +1 -7
  275. package/src/config/bundled-tool-registry.ts +56 -4
  276. package/src/config/env-registry.ts +15 -8
  277. package/src/config/feature-flag-registry.json +29 -116
  278. package/src/config/loader.ts +4 -0
  279. package/src/config/schemas/platform.ts +8 -0
  280. package/src/config/schemas/security.ts +0 -6
  281. package/src/config/schemas/services.ts +8 -0
  282. package/src/config/schemas/timeouts.ts +1 -1
  283. package/src/config/skills.ts +18 -7
  284. package/src/context/token-estimator.ts +25 -18
  285. package/src/context/window-manager.ts +32 -9
  286. package/src/credential-execution/approval-bridge.ts +0 -1
  287. package/src/credential-execution/process-manager.ts +3 -1
  288. package/src/daemon/config-watcher.ts +51 -0
  289. package/src/daemon/context-overflow-reducer.ts +46 -2
  290. package/src/daemon/conversation-agent-loop-handlers.ts +123 -82
  291. package/src/daemon/conversation-agent-loop.ts +99 -63
  292. package/src/daemon/conversation-error.ts +31 -8
  293. package/src/daemon/conversation-lifecycle.ts +33 -0
  294. package/src/daemon/conversation-media-retry.ts +85 -7
  295. package/src/daemon/conversation-notifiers.ts +4 -1
  296. package/src/daemon/conversation-process.ts +1 -0
  297. package/src/daemon/conversation-runtime-assembly.ts +5 -0
  298. package/src/daemon/conversation-usage.ts +1 -0
  299. package/src/daemon/conversation.ts +41 -2
  300. package/src/daemon/daemon-control.ts +8 -2
  301. package/src/daemon/handlers/shared.ts +22 -12
  302. package/src/daemon/handlers/skills.ts +423 -201
  303. package/src/daemon/lifecycle.ts +52 -4
  304. package/src/daemon/main.ts +5 -1
  305. package/src/daemon/message-types/conversations.ts +5 -1
  306. package/src/daemon/message-types/messages.ts +3 -1
  307. package/src/daemon/message-types/skills.ts +97 -36
  308. package/src/daemon/providers-setup.ts +7 -0
  309. package/src/daemon/server.ts +35 -22
  310. package/src/daemon/tool-side-effects.ts +27 -5
  311. package/src/events/domain-events.ts +1 -2
  312. package/src/heartbeat/heartbeat-service.ts +1 -0
  313. package/src/hooks/cli.ts +2 -2
  314. package/src/hooks/runner.ts +15 -38
  315. package/src/inbound/platform-callback-registration.ts +14 -14
  316. package/src/memory/admin.ts +11 -45
  317. package/src/memory/conversation-bootstrap.ts +2 -0
  318. package/src/memory/conversation-crud.ts +242 -348
  319. package/src/memory/conversation-group-migration.ts +157 -0
  320. package/src/memory/conversation-queries.ts +4 -2
  321. package/src/memory/db-init.ts +39 -3
  322. package/src/memory/embed.ts +73 -0
  323. package/src/memory/embedding-backend.ts +8 -14
  324. package/src/memory/embedding-runtime-manager.ts +12 -114
  325. package/src/memory/fingerprint.ts +2 -2
  326. package/src/memory/graph/bootstrap.ts +512 -0
  327. package/src/memory/graph/capability-seed.ts +297 -0
  328. package/src/memory/graph/consolidation.ts +691 -0
  329. package/src/memory/graph/conversation-graph-memory.ts +630 -0
  330. package/src/memory/graph/decay.test.ts +208 -0
  331. package/src/memory/graph/decay.ts +195 -0
  332. package/src/memory/graph/extraction-job.ts +69 -0
  333. package/src/memory/graph/extraction.test.ts +936 -0
  334. package/src/memory/graph/extraction.ts +1254 -0
  335. package/src/memory/graph/graph-search.ts +266 -0
  336. package/src/memory/graph/image-ref-utils.ts +29 -0
  337. package/src/memory/graph/injection.test.ts +513 -0
  338. package/src/memory/graph/injection.ts +439 -0
  339. package/src/memory/graph/inspect.ts +534 -0
  340. package/src/memory/graph/narrative.ts +267 -0
  341. package/src/memory/graph/pattern-scan.ts +269 -0
  342. package/src/memory/graph/retriever.ts +1008 -0
  343. package/src/memory/graph/scoring.test.ts +548 -0
  344. package/src/memory/graph/scoring.ts +232 -0
  345. package/src/memory/graph/serendipity.ts +65 -0
  346. package/src/memory/graph/store.test.ts +1050 -0
  347. package/src/memory/graph/store.ts +699 -0
  348. package/src/memory/graph/tool-handlers.ts +426 -0
  349. package/src/memory/graph/tools.ts +141 -0
  350. package/src/memory/graph/triggers.test.ts +487 -0
  351. package/src/memory/graph/triggers.ts +223 -0
  352. package/src/memory/graph/types.ts +271 -0
  353. package/src/memory/group-crud.ts +191 -0
  354. package/src/memory/indexer.ts +37 -19
  355. package/src/memory/job-handlers/cleanup.ts +0 -53
  356. package/src/memory/job-handlers/conversation-starters.ts +91 -53
  357. package/src/memory/job-handlers/embedding.test.ts +3 -27
  358. package/src/memory/job-handlers/embedding.ts +5 -31
  359. package/src/memory/job-handlers/index-maintenance.ts +23 -11
  360. package/src/memory/job-handlers/summarization.ts +32 -17
  361. package/src/memory/job-utils.ts +1 -1
  362. package/src/memory/jobs-store.ts +50 -70
  363. package/src/memory/jobs-worker.ts +147 -112
  364. package/src/memory/llm-usage-store.ts +35 -2
  365. package/src/memory/message-content.ts +1 -0
  366. package/src/memory/migrations/201-oauth-providers-feature-flag.ts +11 -0
  367. package/src/memory/migrations/202-drop-callback-transport-column.ts +13 -0
  368. package/src/memory/migrations/202-memory-graph-tables.ts +130 -0
  369. package/src/memory/migrations/203-drop-memory-items-tables.ts +23 -0
  370. package/src/memory/migrations/204-rename-memory-graph-type-values.ts +46 -0
  371. package/src/memory/migrations/205-memory-graph-image-refs.ts +11 -0
  372. package/src/memory/migrations/index.ts +6 -0
  373. package/src/memory/migrations/registry.ts +8 -0
  374. package/src/memory/qdrant-client.ts +44 -17
  375. package/src/memory/qdrant-manager.ts +26 -5
  376. package/src/memory/schema/index.ts +1 -0
  377. package/src/memory/schema/memory-graph.ts +139 -0
  378. package/src/memory/schema/oauth.ts +1 -1
  379. package/src/memory/search/semantic.ts +47 -91
  380. package/src/memory/slack-thread-store.ts +17 -0
  381. package/src/memory/task-memory-cleanup.ts +28 -50
  382. package/src/messaging/providers/outlook/adapter.ts +200 -0
  383. package/src/messaging/providers/outlook/client.ts +610 -0
  384. package/src/messaging/providers/outlook/types.ts +201 -0
  385. package/src/notifications/adapters/macos.ts +1 -0
  386. package/src/notifications/adapters/slack.ts +1 -1
  387. package/src/notifications/copy-composer.ts +9 -0
  388. package/src/notifications/signal.ts +16 -0
  389. package/src/oauth/__tests__/identity-verifier.test.ts +1 -1
  390. package/src/oauth/connect-orchestrator.ts +10 -3
  391. package/src/oauth/oauth-store.ts +10 -11
  392. package/src/oauth/provider-serializer.ts +3 -0
  393. package/src/oauth/provider-visibility.ts +16 -0
  394. package/src/oauth/seed-providers.ts +50 -17
  395. package/src/permissions/checker.ts +62 -9
  396. package/src/permissions/defaults.ts +4 -4
  397. package/src/permissions/types.ts +2 -4
  398. package/src/permissions/workspace-policy.ts +1 -1
  399. package/src/playbooks/playbook-compiler.ts +19 -18
  400. package/src/playbooks/types.ts +4 -3
  401. package/src/prompts/system-prompt.ts +6 -93
  402. package/src/prompts/templates/UPDATES.md +6 -0
  403. package/src/providers/anthropic/client.ts +47 -19
  404. package/src/providers/gemini/client.ts +1 -1
  405. package/src/providers/openai/client.ts +1 -1
  406. package/src/providers/registry.ts +1 -1
  407. package/src/providers/retry.ts +19 -3
  408. package/src/runtime/actor-trust-resolver.ts +5 -1
  409. package/src/runtime/auth/__tests__/credential-service.test.ts +1 -27
  410. package/src/runtime/auth/__tests__/token-service.test.ts +1 -25
  411. package/src/runtime/auth/route-policy.ts +7 -4
  412. package/src/runtime/guardian-reply-router.ts +10 -2
  413. package/src/runtime/http-server.ts +23 -3
  414. package/src/runtime/middleware/auth.ts +20 -0
  415. package/src/runtime/routes/attachment-routes.test.ts +106 -0
  416. package/src/runtime/routes/attachment-routes.ts +106 -16
  417. package/src/runtime/routes/brain-graph-routes.ts +21 -22
  418. package/src/runtime/routes/btw-routes.ts +8 -0
  419. package/src/runtime/routes/conversation-management-routes.ts +2 -0
  420. package/src/runtime/routes/conversation-query-routes.ts +2 -58
  421. package/src/runtime/routes/conversation-starter-routes.ts +2 -2
  422. package/src/runtime/routes/debug-routes.ts +1 -1
  423. package/src/runtime/routes/global-search-routes.ts +21 -19
  424. package/src/runtime/routes/group-routes.ts +207 -0
  425. package/src/runtime/routes/guardian-action-routes.ts +21 -10
  426. package/src/runtime/routes/guardian-bootstrap-routes.ts +23 -19
  427. package/src/runtime/routes/inbound-message-handler.ts +19 -0
  428. package/src/runtime/routes/inbound-stages/background-dispatch.ts +43 -2
  429. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.test.ts +292 -0
  430. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +207 -0
  431. package/src/runtime/routes/memory-item-routes.test.ts +2 -31
  432. package/src/runtime/routes/memory-item-routes.ts +385 -341
  433. package/src/runtime/routes/oauth-apps.ts +18 -1
  434. package/src/runtime/routes/oauth-providers.ts +13 -1
  435. package/src/runtime/routes/schedule-routes.ts +2 -0
  436. package/src/runtime/routes/settings-routes.ts +1 -0
  437. package/src/runtime/routes/skills-routes.ts +103 -37
  438. package/src/runtime/routes/usage-routes.ts +19 -2
  439. package/src/runtime/routes/work-items-routes.test.ts +2 -27
  440. package/src/runtime/routes/workspace-routes.test.ts +3 -27
  441. package/src/schedule/scheduler.ts +8 -1
  442. package/src/security/oauth2.ts +1 -1
  443. package/src/security/secret-allowlist.ts +4 -4
  444. package/src/security/secure-keys.ts +4 -8
  445. package/src/shared/provider-env-vars.ts +19 -0
  446. package/src/skills/catalog-cache.ts +5 -0
  447. package/src/skills/catalog-install.ts +15 -14
  448. package/src/skills/clawhub.ts +134 -154
  449. package/src/skills/install-meta.ts +208 -0
  450. package/src/skills/managed-store.ts +27 -16
  451. package/src/skills/skill-memory.ts +210 -96
  452. package/src/skills/skillssh-registry.ts +19 -17
  453. package/src/tasks/task-runner.ts +3 -1
  454. package/src/telemetry/usage-telemetry-reporter.test.ts +3 -5
  455. package/src/tools/browser/runtime-check.ts +3 -1
  456. package/src/tools/memory/register.ts +63 -46
  457. package/src/tools/permission-checker.ts +7 -19
  458. package/src/tools/shared/filesystem/image-read.ts +22 -85
  459. package/src/tools/skills/skill-script-runner.ts +1 -1
  460. package/src/tools/terminal/safe-env.ts +1 -0
  461. package/src/tools/tool-manifest.ts +3 -3
  462. package/src/util/browser.ts +25 -10
  463. package/src/util/bun-runtime.ts +172 -0
  464. package/src/util/device-id.ts +3 -65
  465. package/src/watcher/providers/outlook-calendar.ts +343 -0
  466. package/src/watcher/providers/outlook.ts +198 -0
  467. package/src/workspace/git-service.ts +27 -6
  468. package/src/workspace/migrations/025-remove-oauth-app-setup-skills.ts +76 -0
  469. package/src/workspace/migrations/026-backfill-install-meta.ts +325 -0
  470. package/src/workspace/migrations/027-remove-orphaned-optimized-images-cache.ts +42 -0
  471. package/src/workspace/migrations/registry.ts +6 -0
  472. package/src/__tests__/context-memory-e2e.test.ts +0 -415
  473. package/src/__tests__/journal-context.test.ts +0 -268
  474. package/src/__tests__/memory-context-benchmark.benchmark.test.ts +0 -297
  475. package/src/__tests__/memory-lifecycle-e2e.test.ts +0 -459
  476. package/src/__tests__/memory-query-builder.test.ts +0 -59
  477. package/src/__tests__/memory-recall-quality.test.ts +0 -1046
  478. package/src/__tests__/memory-regressions.experimental.test.ts +0 -629
  479. package/src/__tests__/memory-regressions.test.ts +0 -3696
  480. package/src/__tests__/memory-retrieval.benchmark.test.ts +0 -295
  481. package/src/daemon/conversation-memory.ts +0 -207
  482. package/src/memory/conversation-starters-cadence.ts +0 -74
  483. package/src/memory/items-extractor.ts +0 -860
  484. package/src/memory/job-handlers/batch-extraction.ts +0 -741
  485. package/src/memory/job-handlers/extraction.ts +0 -40
  486. package/src/memory/job-handlers/journal-carry-forward.test.ts +0 -383
  487. package/src/memory/job-handlers/journal-carry-forward.ts +0 -255
  488. package/src/memory/journal-memory.ts +0 -224
  489. package/src/memory/query-builder.ts +0 -47
  490. package/src/memory/query-expansion.ts +0 -83
  491. package/src/memory/retriever.test.ts +0 -1590
  492. package/src/memory/retriever.ts +0 -1323
  493. package/src/memory/search/formatting.test.ts +0 -140
  494. package/src/memory/search/formatting.ts +0 -262
  495. package/src/memory/search/mmr.ts +0 -136
  496. package/src/memory/search/ranking.ts +0 -15
  497. package/src/memory/search/staleness.ts +0 -40
  498. package/src/memory/search/tier-classifier.ts +0 -18
  499. package/src/memory/search/types.ts +0 -121
  500. package/src/prompts/journal-context.ts +0 -156
  501. package/src/tools/memory/definitions.ts +0 -69
  502. package/src/tools/memory/handlers.test.ts +0 -590
  503. package/src/tools/memory/handlers.ts +0 -434
@@ -12,6 +12,7 @@ import {
12
12
  uninstallSkillLocally,
13
13
  } from "../../skills/catalog-install.js";
14
14
  import { filterByQuery } from "../../skills/catalog-search.js";
15
+ import { clawhubSearch } from "../../skills/clawhub.js";
15
16
  import type {
16
17
  AuditResponse,
17
18
  SkillsShSearchResult,
@@ -111,7 +112,9 @@ Examples:
111
112
 
112
113
  skills
113
114
  .command("search <query>")
114
- .description("Search the Vellum catalog and skills.sh community registry")
115
+ .description(
116
+ "Search the Vellum catalog, skills.sh, and clawhub community registries",
117
+ )
115
118
  .option("--limit <n>", "Maximum number of community results", "10")
116
119
  .option("--json", "Machine-readable JSON output")
117
120
  .addHelpText(
@@ -119,11 +122,11 @@ Examples:
119
122
  `
120
123
  Arguments:
121
124
  query Free-text search term matched against skill names, descriptions,
122
- and tags. Searches the Vellum catalog first, then the skills.sh
123
- community registry.
125
+ and tags. Searches the Vellum catalog, the skills.sh community
126
+ registry, and the clawhub registry.
124
127
 
125
- Displays results from both sources with clear labels. When a skill ID
126
- exists in both the Vellum catalog and the community registry, a conflict
128
+ Displays results from all sources with clear labels. When a skill ID
129
+ exists in both the Vellum catalog and a community registry, a conflict
127
130
  note is shown with guidance on which install command to use.
128
131
 
129
132
  Examples:
@@ -155,32 +158,64 @@ Examples:
155
158
  (s) => s.description,
156
159
  ]);
157
160
 
158
- // ── Community registry search (non-fatal on failure) ─────────
161
+ // ── Community registry searches (non-fatal on failure) ────────
162
+ // Run skills.sh and clawhub searches in parallel.
159
163
  let registryResults: SkillsShSearchResult[] = [];
160
164
  let registryError: string | undefined;
161
- try {
162
- registryResults = await searchSkillsRegistry(query, limit);
163
- } catch (err) {
164
- registryError = err instanceof Error ? err.message : String(err);
165
+ let clawhubResults: Awaited<
166
+ ReturnType<typeof clawhubSearch>
167
+ >["skills"] = [];
168
+ let clawhubError: string | undefined;
169
+
170
+ const [skillsShResult, clawhubResult] = await Promise.allSettled([
171
+ searchSkillsRegistry(query, limit),
172
+ clawhubSearch(query, { limit }),
173
+ ]);
174
+
175
+ if (skillsShResult.status === "fulfilled") {
176
+ registryResults = skillsShResult.value;
177
+ } else {
178
+ registryError =
179
+ skillsShResult.reason instanceof Error
180
+ ? skillsShResult.reason.message
181
+ : String(skillsShResult.reason);
182
+ }
183
+
184
+ if (clawhubResult.status === "fulfilled") {
185
+ clawhubResults = clawhubResult.value.skills;
186
+ } else {
187
+ clawhubError =
188
+ clawhubResult.reason instanceof Error
189
+ ? clawhubResult.reason.message
190
+ : String(clawhubResult.reason);
165
191
  }
166
192
 
167
193
  // ── Conflict detection ───────────────────────────────────────
168
194
  const catalogIds = new Set(catalogMatches.map((s) => s.id));
169
- const conflictIds = new Set(
170
- registryResults
195
+ const conflictIds = new Set([
196
+ ...registryResults
171
197
  .filter((r) => catalogIds.has(r.skillId))
172
198
  .map((r) => r.skillId),
173
- );
199
+ ...clawhubResults
200
+ .filter((r) => catalogIds.has(r.slug))
201
+ .map((r) => r.slug),
202
+ ]);
174
203
 
175
- if (catalogMatches.length === 0 && registryResults.length === 0) {
204
+ if (
205
+ catalogMatches.length === 0 &&
206
+ registryResults.length === 0 &&
207
+ clawhubResults.length === 0
208
+ ) {
176
209
  if (json) {
177
210
  console.log(
178
211
  JSON.stringify({
179
212
  ok: true,
180
213
  catalog: [],
181
214
  community: [],
215
+ clawhub: [],
182
216
  audits: {},
183
217
  ...(registryError ? { registryError } : {}),
218
+ ...(clawhubError ? { clawhubError } : {}),
184
219
  }),
185
220
  );
186
221
  } else {
@@ -188,6 +223,9 @@ Examples:
188
223
  if (registryError) {
189
224
  log.warn(`(skills.sh registry unavailable: ${registryError})`);
190
225
  }
226
+ if (clawhubError) {
227
+ log.warn(`(clawhub registry unavailable: ${clawhubError})`);
228
+ }
191
229
  }
192
230
  return;
193
231
  }
@@ -219,8 +257,10 @@ Examples:
219
257
  ok: true,
220
258
  catalog: catalogMatches,
221
259
  community: registryResults,
260
+ clawhub: clawhubResults,
222
261
  audits: allAudits,
223
262
  ...(registryError ? { registryError } : {}),
263
+ ...(clawhubError ? { clawhubError } : {}),
224
264
  }),
225
265
  );
226
266
  return;
@@ -280,6 +320,38 @@ Examples:
280
320
  } else if (registryError) {
281
321
  log.warn(`\n(skills.sh registry unavailable: ${registryError})`);
282
322
  }
323
+
324
+ // ── Display clawhub results ─────────────────────────────────
325
+ if (clawhubResults.length > 0) {
326
+ log.info(`Clawhub registry (${clawhubResults.length}):\n`);
327
+ for (const r of clawhubResults) {
328
+ const installed = isInstalled(r.slug);
329
+ const badge = installed ? " [installed]" : "";
330
+ log.info(` ${r.name}${badge}`);
331
+ if (r.name !== r.slug) {
332
+ log.info(` ID: ${r.slug}`);
333
+ }
334
+ if (r.author) {
335
+ log.info(` Author: ${r.author}`);
336
+ }
337
+ if (r.description) {
338
+ log.info(` Description: ${r.description}`);
339
+ }
340
+ if (r.stars > 0) {
341
+ log.info(` Stars: ${r.stars}`);
342
+ }
343
+ if (r.installs > 0) {
344
+ log.info(` Installs: ${r.installs}`);
345
+ }
346
+ log.info(` Install: npx clawhub install ${r.slug}`);
347
+ if (conflictIds.has(r.slug)) {
348
+ log.info(` NOTE: Conflicts with Vellum catalog skill`);
349
+ }
350
+ log.info("");
351
+ }
352
+ } else if (clawhubError) {
353
+ log.warn(`\n(clawhub registry unavailable: ${clawhubError})`);
354
+ }
283
355
  } catch (err) {
284
356
  const msg = err instanceof Error ? err.message : String(err);
285
357
  if (json) {
@@ -416,8 +488,8 @@ Arguments:
416
488
 
417
489
  Notes:
418
490
  Fetches the skill's SKILL.md and supporting files from the specified GitHub
419
- repository and installs them into the workspace skills directory. A
420
- version.json file is written with origin metadata for provenance tracking.
491
+ repository and installs them into the workspace skills directory. An
492
+ install-meta.json file is written with origin metadata for provenance tracking.
421
493
 
422
494
  Examples:
423
495
  $ assistant skills add vercel-labs/skills@find-skills
@@ -18,7 +18,7 @@ export function registerTrustCommand(program: Command): void {
18
18
  Trust rules are pattern-based decisions (allow/deny) for tool invocations.
19
19
  Each rule specifies a tool name, a command pattern matched with glob syntax,
20
20
  a scope, a decision (allow or deny), and a priority. Rules are stored in
21
- ~/.vellum/protected/trust.json and evaluated in priority order when the
21
+ the protected directory (trust.json) and evaluated in priority order when the
22
22
  assistant invokes a tool.
23
23
 
24
24
  Examples:
@@ -141,7 +141,7 @@ Examples:
141
141
  .addHelpText(
142
142
  "after",
143
143
  `
144
- Removes every trust rule from ~/.vellum/protected/trust.json. Prompts for
144
+ Removes every trust rule from the protected directory (trust.json). Prompts for
145
145
  confirmation before proceeding (y/N). This action is irreversible — all
146
146
  rules must be re-created manually after clearing.
147
147
 
@@ -7,7 +7,6 @@
7
7
  * (health check, JWT minting, HTTP call).
8
8
  */
9
9
 
10
- import providerEnvVarsRegistry from "../../../../meta/provider-env-vars.json" with { type: "json" };
11
10
  import { getRuntimeHttpHost, getRuntimeHttpPort } from "../../config/env.js";
12
11
  import { API_KEY_PROVIDERS } from "../../config/loader.js";
13
12
  import { healthCheckHost, isHttpHealthy } from "../../daemon/daemon-control.js";
@@ -25,13 +24,13 @@ import {
25
24
  getSecureKeyResultAsync,
26
25
  setSecureKeyAsync,
27
26
  } from "../../security/secure-keys.js";
27
+ import { PROVIDER_ENV_VAR_NAMES } from "../../shared/provider-env-vars.js";
28
28
  import { getLogger } from "../../util/logger.js";
29
29
 
30
30
  const log = getLogger("daemon-credential-client");
31
31
  const CREDENTIAL_KEY_PREFIX = "credential/";
32
32
 
33
- const PROVIDER_ENV_VARS: Record<string, string> =
34
- providerEnvVarsRegistry.providers;
33
+ const PROVIDER_ENV_VARS: Record<string, string> = PROVIDER_ENV_VAR_NAMES;
35
34
 
36
35
  // ---------------------------------------------------------------------------
37
36
  // Private daemon fetch helper
@@ -5,7 +5,7 @@
5
5
  "name": "acp_spawn",
6
6
  "description": "Spawn an external coding agent (e.g. Claude Code, Codex, Gemini CLI) via ACP to work on a task. The agent runs as a subprocess and streams results back. Use this when you want to delegate a coding task to an external agent that has its own tools, file editing, and terminal access. If ACP is not enabled, follow the setup instructions in SKILL.md to install claude-agent-acp and configure it. The command MUST be 'claude-agent-acp' - NEVER use 'claude', 'claude -p', or 'claude --acp'.",
7
7
  "category": "orchestration",
8
- "risk": "low",
8
+ "risk": "high",
9
9
  "input_schema": {
10
10
  "type": "object",
11
11
  "properties": {
@@ -23,7 +23,7 @@
23
23
  "name": "computer_use_click",
24
24
  "description": "Click an element on screen. Prefer element_id (from the accessibility tree) over x/y coordinates.",
25
25
  "category": "computer-use",
26
- "risk": "low",
26
+ "risk": "medium",
27
27
  "input_schema": {
28
28
  "type": "object",
29
29
  "properties": {
@@ -62,7 +62,7 @@
62
62
  "name": "computer_use_type_text",
63
63
  "description": "Type text at the current cursor position. First click a text field (by element_id) to focus it, then call this tool. If a field shows 'FOCUSED', skip the click.",
64
64
  "category": "computer-use",
65
- "risk": "low",
65
+ "risk": "medium",
66
66
  "input_schema": {
67
67
  "type": "object",
68
68
  "properties": {
@@ -88,7 +88,7 @@
88
88
  "name": "computer_use_key",
89
89
  "description": "Press a key or keyboard shortcut. Supported: enter, tab, escape, backspace, delete, up, down, left, right, space, cmd+a, cmd+c, cmd+v, cmd+z, cmd+tab, cmd+w, shift+tab, option+tab",
90
90
  "category": "computer-use",
91
- "risk": "low",
91
+ "risk": "medium",
92
92
  "input_schema": {
93
93
  "type": "object",
94
94
  "properties": {
@@ -114,7 +114,7 @@
114
114
  "name": "computer_use_scroll",
115
115
  "description": "Scroll within an element by its [ID], or at raw screen coordinates as fallback.",
116
116
  "category": "computer-use",
117
- "risk": "low",
117
+ "risk": "medium",
118
118
  "input_schema": {
119
119
  "type": "object",
120
120
  "properties": {
@@ -157,7 +157,7 @@
157
157
  "name": "computer_use_drag",
158
158
  "description": "Drag from one element or position to another. Use for moving files, resizing windows, rearranging items, or adjusting sliders.",
159
159
  "category": "computer-use",
160
- "risk": "low",
160
+ "risk": "medium",
161
161
  "input_schema": {
162
162
  "type": "object",
163
163
  "properties": {
@@ -229,7 +229,7 @@
229
229
  "name": "computer_use_open_app",
230
230
  "description": "Open or switch to a macOS application by name. Preferred over cmd+tab for switching apps - more reliable and explicit.",
231
231
  "category": "computer-use",
232
- "risk": "low",
232
+ "risk": "medium",
233
233
  "input_schema": {
234
234
  "type": "object",
235
235
  "properties": {
@@ -255,7 +255,7 @@
255
255
  "name": "computer_use_run_applescript",
256
256
  "description": "Run an AppleScript command. Prefer this over click/type when possible - it doesn't move the cursor or interrupt the user. Never use 'do shell script' inside AppleScript (blocked for security).",
257
257
  "category": "computer-use",
258
- "risk": "low",
258
+ "risk": "medium",
259
259
  "input_schema": {
260
260
  "type": "object",
261
261
  "properties": {
@@ -6,7 +6,6 @@ metadata:
6
6
  emoji: "👥"
7
7
  vellum:
8
8
  display-name: "Contacts"
9
- feature-flag: "contacts"
10
9
  ---
11
10
 
12
11
  Manage the user's contacts, relationship graph, access control (trusted contacts), and invite links. This skill covers contact CRUD with multi-channel tracking, controlling who can message the assistant through external channels (Telegram, phone), and creating/managing invite links that grant access.
@@ -47,14 +47,6 @@
47
47
  "is_primary": {
48
48
  "type": "boolean",
49
49
  "description": "Whether this is the primary channel for this type"
50
- },
51
- "external_user_id": {
52
- "type": "string",
53
- "description": "Platform-native user ID (e.g. Slack user ID like U12345). Used to cache user lookups."
54
- },
55
- "external_chat_id": {
56
- "type": "string",
57
- "description": "Platform-native chat/DM channel ID (e.g. Slack DM channel like D12345). Used to cache DM channel lookups."
58
50
  }
59
51
  },
60
52
  "required": ["type", "address"]
@@ -63,16 +63,12 @@ export async function executeContactUpsert(
63
63
  type: string;
64
64
  address: string;
65
65
  is_primary?: boolean;
66
- external_user_id?: string;
67
- external_chat_id?: string;
68
66
  }>
69
67
  | undefined;
70
68
  const channels = rawChannels?.map((ch) => ({
71
69
  type: ch.type,
72
70
  address: ch.address,
73
71
  isPrimary: ch.is_primary,
74
- externalUserId: ch.external_user_id,
75
- externalChatId: ch.external_chat_id,
76
72
  }));
77
73
 
78
74
  try {
@@ -28,22 +28,14 @@ Do not offer AgentMail as an option or mention it unless the user specifically a
28
28
  ### Gmail
29
29
 
30
30
  1. **Try connecting directly first.** Run `assistant oauth status google`. This will show whether or not the user had previously connected their google account. If so, they are ready to go.
31
- 2. **If no connections are found:** The user needs to either use Vellum's managed google integration or set up their own google oauth app.
32
- - Call `skill_load` with `skill: "vellum-oauth-integrations"` with `provider-key: google` throughout.
33
- - To use `your-own` mode, you will need to call `skill_load` with `skill: google-oauth-app-setup`. In this case:
34
- - Tell the user Gmail isn't connected yet and briefly explain what the setup involves, then use `ui_show` with `surface_type: "confirmation"` to ask for permission to start:
35
- - **message:** "Ready to set up Gmail?"
36
- - **detail:** "I'll open a few pages in your browser and walk you through setting up Google Cloud credentials - creating a project, enabling APIs, and connecting your account. Takes about 5 minutes.\n\n**Your emails stay under your control** — I only ever create drafts. Nothing gets sent without your explicit say-so."
37
- - **confirmLabel:** "Get Started"
38
- - **cancelLabel:** "Not Now"
39
- - If the user confirms, briefly acknowledge (e.g., "Setting up Gmail now...") and proceed with the setup guide. If they decline, acknowledge and let them know they can set it up later.
31
+ 2. **If no connections are found:** Call `skill_load` with `skill: "vellum-oauth-integrations"`. The skill will evaluate whether managed or your-own mode is appropriate and guide the user accordingly.
40
32
 
41
33
  ## Error Recovery
42
34
 
43
35
  When a Gmail tool fails with a token or authorization error:
44
36
 
45
37
  1. **Try to reconnect silently.** Call `assistant oauth ping google`. This often resolves expired tokens automatically.
46
- 2. **If reconnection fails, go straight to setup.** Don't present options, ask which route the user prefers, or explain what went wrong technically. Just tell the user briefly (e.g., "Gmail needs to be reconnected - let me set that up") and immediately follow the connection setup flow for Gmail (e.g., install and load **google-oauth-app-setup**). The user came to you to get something done, not to troubleshoot OAuth - make it seamless.
38
+ 2. **If reconnection fails, go straight to setup.** Don't present options, ask which route the user prefers, or explain what went wrong technically. Just tell the user briefly (e.g., "Gmail needs to be reconnected - let me set that up") and immediately load **vellum-oauth-integrations**. The user came to you to get something done, not to troubleshoot OAuth - make it seamless.
47
39
  3. **Never try alternative approaches.** Don't use bash, curl, browser automation, or any workaround. If the Gmail tools can't do it, the reconnection flow is the answer.
48
40
  4. **Never expose error details.** The user doesn't need to see error messages about tokens, OAuth, or API failures. Translate errors into plain language.
49
41
 
@@ -15,15 +15,7 @@ You are a Google Calendar assistant with full access to the user's calendar. Use
15
15
  Before using any Calendar tool, verify that Google Calendar is connected by attempting a lightweight call (e.g., `calendar_list_events` with a narrow date range). If the call fails with a token/authorization error:
16
16
 
17
17
  1. **Try connecting directly first.** Run `assistant oauth status google`. This will show whether or not the user had previously connected their google account. If so, they are ready to go.
18
- 2. **If no connections are found:** The user needs to either use Vellum's managed google integration or set up their own google oauth app.
19
- - Call `skill_load` with `skill: "vellum-oauth-integrations"` with `provider-key: google` throughout.
20
- - To use `your-own` mode, you will need to call `skill_load` with `skill: google-oauth-app-setup`. In this case:
21
- - Tell the user Google account isn't connected yet and briefly explain what the setup involves, then use `ui_show` with `surface_type: "confirmation"` to ask for permission to start:
22
- - **message:** "Ready to set up Google Calendar?"
23
- - **detail:** "I'll open a few pages in your browser and walk you through setting up Google Cloud credentials - creating a project, enabling APIs, and connecting your account. Takes about 5 minutes.\n\n**Your emails stay under your control** — I only ever create drafts. Nothing gets sent without your explicit say-so."
24
- - **confirmLabel:** "Get Started"
25
- - **cancelLabel:** "Not Now"
26
- - If the user confirms, briefly acknowledge (e.g., "Setting up Google Calendar now...") and proceed with the setup guide. If they decline, acknowledge and let them know they can set it up later.
18
+ 2. **If no connections are found:** Call `skill_load` with `skill: "vellum-oauth-integrations"`. The skill will evaluate whether managed or your-own mode is appropriate and guide the user accordingly.
27
19
 
28
20
  ## Capabilities
29
21
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: messaging
3
- description: Read, search, send, and manage messages across Gmail, Telegram, and other platforms
3
+ description: Read, search, send, and manage messages across Gmail, Outlook, Telegram, and other platforms
4
4
  compatibility: "Designed for Vellum personal assistants"
5
5
  metadata:
6
6
  emoji: "\U0001F4AC"
@@ -11,7 +11,7 @@ metadata:
11
11
  - "Handles credential flows -- do not improvise setup instructions"
12
12
  ---
13
13
 
14
- You are a unified messaging assistant with access to multiple platforms (Gmail, Telegram, and more). Use the messaging tools to help users read, search, organize, draft, and send messages across all connected platforms.
14
+ You are a unified messaging assistant with access to multiple platforms (Gmail, Outlook, Telegram, and more). Use the messaging tools to help users read, search, organize, draft, and send messages across all connected platforms.
15
15
 
16
16
  **Slack is not handled by this skill.** Slack messaging (send, read, search) is handled by the **slack** skill, which uses the Slack Web API directly via CLI. Do not use messaging tools with `platform: "slack"`.
17
17
 
@@ -19,13 +19,13 @@ You are a unified messaging assistant with access to multiple platforms (Gmail,
19
19
 
20
20
  When composing messages on behalf of your user to external recipients, refer to yourself as an "assistant" (not "AI assistant"). Use your user's name and pronouns from USER.md. Don't volunteer that you are an AI unless directly asked.
21
21
 
22
- For Gmail management (archive, label, triage, declutter), load the **gmail** skill. For email sequences, load the **sequences** skill.
22
+ For Email management (archive, label, triage, declutter), load the **gmail** or **outlook** skill. For email sequences, load the **sequences** skill.
23
23
 
24
24
  ## Email Routing Priority
25
25
 
26
- When the user mentions "email" - sending, reading, checking, decluttering, drafting, or anything else - **always default to the user's own email (Gmail)** unless they explicitly ask about the assistant's own email address (e.g., "set up your email", "send from your address", "check your inbox"). The vast majority of email requests are about the user's Gmail, not the assistant's AgentMail address.
26
+ When the user mentions "email" - sending, reading, checking, decluttering, drafting, or anything else - **always default to the user's own email** unless they explicitly ask about the assistant's own email address (e.g., "set up your email", "send from your address", "check your inbox"). The vast majority of email requests are about the user's Gmail or Outlook, not the assistant's AgentMail address.
27
27
 
28
- Do not offer AgentMail as an option or mention it unless the user specifically asks. If Gmail is not connected, guide them through Gmail setup - do not suggest AgentMail as an alternative.
28
+ Do not offer AgentMail as an option or mention it unless the user specifically asks. If Gmail and Outlookk are not connected, guide them through setup - do not suggest AgentMail as an alternative.
29
29
 
30
30
  ## Communication Style
31
31
 
@@ -44,28 +44,25 @@ Before using any messaging tool, verify that the platform is connected by callin
44
44
 
45
45
  ### Public Ingress (required for Telegram)
46
46
 
47
- Telegram setup requires webhook routing, but it does **not** always require ngrok. Before suggesting public ingress for Telegram, check managed callback availability with `assistant platform status --json`. If that reports `containerized: true` with a non-empty `assistantId` and `available: true`, use the platform callback route flow and do not prompt for ngrok. Only use the **public-ingress** skill for local assistants that genuinely need a public gateway URL. Slack uses Socket Mode and does not require public ingress. Gmail on the desktop app uses a loopback callback and does not require public ingress; the channel path (Path B in the google-oauth-app-setup skill) handles public ingress internally when needed.
47
+ Telegram setup requires webhook routing, but it does **not** always require ngrok. Before suggesting public ingress for Telegram, check managed callback availability with `assistant platform status --json`. If that reports `isPlatform: true` with a non-empty `assistantId` and `available: true`, use the platform callback route flow and do not prompt for ngrok. Only use the **public-ingress** skill for local assistants that genuinely need a public gateway URL. Slack uses Socket Mode and does not require public ingress. Gmail/Outlook on the desktop app uses a loopback callback and does not require public ingress; the channel path (Path B in the vellum-oauth-integrations skill) handles public ingress internally when needed.
48
48
 
49
49
  ### Email Connection Flow
50
50
 
51
51
  When the user asks to "connect my email", "set up email", "manage my email", or similar - and has not named a specific provider:
52
52
 
53
- 1. **Discover what's connected.** Call `messaging_auth_test` for `gmail` (and any other email-capable platforms). If one succeeds, tell the user it's already connected and proceed with their request.
53
+ 1. **Discover what's connected.** Call `messaging_auth_test` for `gmail`or `outlook` (and any other email-capable platforms). If one succeeds, tell the user it's already connected and proceed with their request.
54
54
  2. **If nothing is connected**, ask which provider they use - but keep it brief and conversational (e.g., "Which email do you use - Gmail, Outlook, etc.?"), not a numbered list of options with descriptions.
55
- 3. **Once the provider is known, act immediately.** Don't present setup options or explain OAuth. If it's Gmail, follow the Gmail section below. For any other provider, let the user know that only Gmail is fully supported right now, and offer to set up Gmail instead.
55
+ 3. **Once the provider is known, act immediately.** Don't present setup options or explain OAuth. If it's Gmail or Outlook, follow the sections below. For any other provider, let the user know that only Gmail and Outlook are fully supported right now, and offer to set up Gmail/Outlook instead.
56
56
 
57
57
  ### Gmail
58
58
 
59
59
  1. **Try connecting directly first.** Run `assistant oauth status google`. This will show whether or not the user had previously connected their google account. If so, they are ready to go.
60
- 2. **If no connections are found:** The user needs to either use Vellum's managed google integration or set up their own google oauth app.
61
- - Call `skill_load` with `skill: "vellum-oauth-integrations"` with `provider-key: google` throughout.
62
- - To use `your-own` mode, you will need to call `skill_load` with `skill: google-oauth-app-setup`. In this case:
63
- - Tell the user Gmail isn't connected yet and briefly explain what the setup involves, then use `ui_show` with `surface_type: "confirmation"` to ask for permission to start:
64
- - **message:** "Ready to set up Gmail?"
65
- - **detail:** "I'll open a few pages in your browser and walk you through setting up Google Cloud credentials - creating a project, enabling APIs, and connecting your account. Takes about 5 minutes."
66
- - **confirmLabel:** "Get Started"
67
- - **cancelLabel:** "Not Now"
68
- - If the user confirms, briefly acknowledge (e.g., "Setting up Gmail now...") and proceed with the setup guide. If they decline, acknowledge and let them know they can set it up later.
60
+ 2. **If no connections are found:** Call `skill_load` with `skill: "vellum-oauth-integrations"`. The skill will evaluate whether managed or your-own mode is appropriate and guide the user accordingly.
61
+
62
+ ### Outlook
63
+
64
+ 1. **Try connecting directly first.** Run `assistant oauth status outlook`. This will show whether the user has previously connected their Outlook account.
65
+ 2. **If no connections are found:** Call `skill_load` with `skill: "vellum-oauth-integrations"`. The skill will evaluate whether managed or your-own mode is appropriate and guide the user accordingly.
69
66
 
70
67
  ### Slack
71
68
 
@@ -96,7 +93,7 @@ The guardian-verify-setup skill handles the full outbound verification flow for
96
93
  When a messaging tool fails with a token or authorization error:
97
94
 
98
95
  1. **Try to reconnect silently.** Run `assistant oauth ping <provider>`. This often resolves expired tokens automatically.
99
- 2. **If reconnection fails, go straight to setup.** Don't present options, ask which route the user prefers, or explain what went wrong technically. Just tell the user briefly (e.g., "Gmail needs to be reconnected - let me set that up") and immediately follow the connection setup flow for that platform (e.g., install and load **google-oauth-app-setup** for Gmail). The user came to you to get something done, not to troubleshoot OAuth - make it seamless.
96
+ 2. **If reconnection fails, go straight to setup.** Don't present options, ask which route the user prefers, or explain what went wrong technically. Just tell the user briefly (e.g., "Gmail needs to be reconnected - let me set that up") and immediately load **vellum-oauth-integrations**. The user came to you to get something done, not to troubleshoot OAuth - make it seamless.
100
97
  3. **Never try alternative approaches.** Don't use bash, curl, browser automation, or any workaround. If the messaging tools can't do it, the reconnection flow is the answer.
101
98
  4. **Never expose error details.** The user doesn't need to see error messages about tokens, OAuth, or API failures. Translate errors into plain language.
102
99
 
@@ -109,7 +106,7 @@ When a messaging tool fails with a token or authorization error:
109
106
 
110
107
  ## Capabilities
111
108
 
112
- ### Universal (Gmail)
109
+ ### Gmail
113
110
 
114
111
  - **Auth Test**: Verify connection and show account info
115
112
  - **List Conversations**: Show inboxes, DMs with unread counts
@@ -118,6 +115,16 @@ When a messaging tool fails with a token or authorization error:
118
115
  - **Send / Reply**: Send a message or reply in a thread (via `thread_id`). High risk - requires user approval.
119
116
  - **Mark Read**: Mark conversation as read
120
117
 
118
+ ### Outlook
119
+
120
+ - **Auth Test**: Verify connection and show account info
121
+ - **List Conversations**: Show mail folders (Inbox, Sent, Drafts, etc.) with unread counts
122
+ - **Read Messages**: Read message history from a folder
123
+ - **Search**: Search messages using Microsoft Graph KQL syntax
124
+ - **Send / Reply**: Send a message or reply to a thread (high risk - requires user approval)
125
+ - **Mark Read**: Mark a message as read
126
+ - **Thread Replies**: View all messages in a conversation thread
127
+
121
128
  ### Telegram
122
129
 
123
130
  Telegram is supported as a messaging provider with limited capabilities compared to Gmail due to Bot API constraints:
@@ -1,10 +1,9 @@
1
- import { and, eq } from "drizzle-orm";
1
+ import { and, eq, sql } from "drizzle-orm";
2
2
  import { v4 as uuid } from "uuid";
3
3
 
4
4
  import { getDb } from "../../../../memory/db.js";
5
- import { computeMemoryFingerprint } from "../../../../memory/fingerprint.js";
6
5
  import { enqueueMemoryJob } from "../../../../memory/jobs-store.js";
7
- import { memoryItems } from "../../../../memory/schema.js";
6
+ import { memoryGraphNodes } from "../../../../memory/schema.js";
8
7
  import { clampUnitInterval } from "../../../../memory/validation.js";
9
8
  import { extractStylePatterns } from "../../../../messaging/style-analyzer.js";
10
9
  import type {
@@ -14,6 +13,12 @@ import type {
14
13
  import { truncate } from "../../../../util/truncate.js";
15
14
  import { err, getProviderConnection, ok, resolveProvider } from "./shared.js";
16
15
 
16
+ /** Map legacy caller kinds to valid MemoryType values. */
17
+ const KIND_TO_MEMORY_TYPE: Record<string, string> = {
18
+ style: "behavioral",
19
+ relationship: "semantic",
20
+ };
21
+
17
22
  function upsertMemoryItem(opts: {
18
23
  kind: string;
19
24
  subject: string;
@@ -23,58 +28,60 @@ function upsertMemoryItem(opts: {
23
28
  }): void {
24
29
  const db = getDb();
25
30
  const now = Date.now();
26
- const fingerprint = computeMemoryFingerprint(
27
- opts.scopeId,
28
- opts.kind,
29
- opts.subject,
30
- opts.statement,
31
- );
31
+ const content = `${opts.subject}\n${opts.statement}`;
32
32
 
33
33
  const existing = db
34
34
  .select()
35
- .from(memoryItems)
35
+ .from(memoryGraphNodes)
36
36
  .where(
37
37
  and(
38
- eq(memoryItems.fingerprint, fingerprint),
39
- eq(memoryItems.scopeId, opts.scopeId),
38
+ eq(memoryGraphNodes.content, content),
39
+ eq(memoryGraphNodes.scopeId, opts.scopeId),
40
+ sql`${memoryGraphNodes.fidelity} != 'gone'`,
40
41
  ),
41
42
  )
42
43
  .get();
43
44
 
44
45
  if (existing) {
45
- db.update(memoryItems)
46
+ db.update(memoryGraphNodes)
46
47
  .set({
47
- statement: opts.statement,
48
- status: "active",
49
- importance: clampUnitInterval(
50
- Math.max(existing.importance ?? 0, opts.importance),
48
+ content,
49
+ type: KIND_TO_MEMORY_TYPE[opts.kind] ?? opts.kind,
50
+ fidelity: "vivid",
51
+ significance: clampUnitInterval(
52
+ Math.max(existing.significance ?? 0, opts.importance),
51
53
  ),
52
- lastSeenAt: now,
53
- sourceType: existing.sourceType === "tool" ? "tool" : "extraction",
54
+ lastAccessed: now,
55
+ sourceType: existing.sourceType === "direct" ? "direct" : "inferred",
54
56
  })
55
- .where(eq(memoryItems.id, existing.id))
57
+ .where(eq(memoryGraphNodes.id, existing.id))
56
58
  .run();
57
- enqueueMemoryJob("embed_item", { itemId: existing.id });
59
+ enqueueMemoryJob("embed_graph_node", { nodeId: existing.id });
58
60
  } else {
59
61
  const id = uuid();
60
- db.insert(memoryItems)
62
+ db.insert(memoryGraphNodes)
61
63
  .values({
62
64
  id,
63
- kind: opts.kind,
64
- subject: opts.subject,
65
- statement: opts.statement,
66
- status: "active",
65
+ content,
66
+ type: KIND_TO_MEMORY_TYPE[opts.kind] ?? opts.kind,
67
+ created: now,
68
+ lastAccessed: now,
69
+ lastConsolidated: now,
70
+ emotionalCharge: '{"valence":0,"intensity":0.1,"decayCurve":"linear","decayRate":0.05,"originalIntensity":0.1}',
71
+ fidelity: "vivid",
67
72
  confidence: 0.8,
68
- importance: clampUnitInterval(opts.importance),
69
- fingerprint,
70
- sourceType: "extraction",
73
+ significance: clampUnitInterval(opts.importance),
74
+ stability: 14,
75
+ reinforcementCount: 0,
76
+ lastReinforced: now,
77
+ sourceConversations: "[]",
78
+ sourceType: "inferred",
79
+ narrativeRole: null,
80
+ partOfStory: null,
71
81
  scopeId: opts.scopeId,
72
- firstSeenAt: now,
73
- lastSeenAt: now,
74
- lastUsedAt: null,
75
82
  })
76
83
  .run();
77
- enqueueMemoryJob("embed_item", { itemId: id });
84
+ enqueueMemoryJob("embed_graph_node", { nodeId: id });
78
85
  }
79
86
  }
80
87