@vellumai/assistant 0.4.56 → 0.4.57

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 (450) hide show
  1. package/ARCHITECTURE.md +10 -10
  2. package/Dockerfile +3 -0
  3. package/README.md +11 -11
  4. package/docs/architecture/integrations.md +2 -2
  5. package/docs/architecture/memory.md +3 -4
  6. package/docs/credential-execution-service.md +13 -20
  7. package/node_modules/@vellumai/ces-contracts/src/error.ts +5 -4
  8. package/package.json +1 -1
  9. package/src/__tests__/actor-token-service.test.ts +7 -7
  10. package/src/__tests__/anthropic-provider.test.ts +172 -0
  11. package/src/__tests__/app-builder-tool-scripts.test.ts +15 -1
  12. package/src/__tests__/approval-cascade.test.ts +2 -2
  13. package/src/__tests__/approval-routes-http.test.ts +3 -4
  14. package/src/__tests__/asset-materialize-tool.test.ts +5 -5
  15. package/src/__tests__/asset-search-tool.test.ts +1 -1
  16. package/src/__tests__/assistant-attachments.test.ts +5 -5
  17. package/src/__tests__/assistant-events-sse-hardening.test.ts +1 -1
  18. package/src/__tests__/assistant-feature-flags-integration.test.ts +50 -38
  19. package/src/__tests__/attachments-store.test.ts +2 -2
  20. package/src/__tests__/avatar-e2e.test.ts +5 -3
  21. package/src/__tests__/browser-skill-endstate.test.ts +0 -1
  22. package/src/__tests__/call-routes-http.test.ts +2 -2
  23. package/src/__tests__/callback-handoff-copy.test.ts +1 -1
  24. package/src/__tests__/cancel-resolves-conversation-key.test.ts +158 -0
  25. package/src/__tests__/channel-readiness-routes.test.ts +0 -1
  26. package/src/__tests__/channel-readiness-service.test.ts +0 -1
  27. package/src/__tests__/checker.test.ts +31 -32
  28. package/src/__tests__/chrome-cdp.test.ts +47 -18
  29. package/src/__tests__/claude-code-skill-regression.test.ts +2 -2
  30. package/src/__tests__/config-schema-cmd.test.ts +2 -2
  31. package/src/__tests__/config-schema.test.ts +9 -18
  32. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +1 -1
  33. package/src/__tests__/conversation-abort-tool-results.test.ts +4 -4
  34. package/src/__tests__/conversation-agent-loop-overflow.test.ts +2 -2
  35. package/src/__tests__/conversation-agent-loop.test.ts +11 -4
  36. package/src/__tests__/conversation-attachments.test.ts +1 -1
  37. package/src/__tests__/conversation-confirmation-signals.test.ts +2 -2
  38. package/src/__tests__/conversation-error.test.ts +33 -0
  39. package/src/__tests__/conversation-init.benchmark.test.ts +0 -1
  40. package/src/__tests__/conversation-load-history-repair.test.ts +1 -1
  41. package/src/__tests__/conversation-pairing.test.ts +1 -1
  42. package/src/__tests__/conversation-pre-run-repair.test.ts +4 -4
  43. package/src/__tests__/conversation-provider-retry-repair.test.ts +4 -4
  44. package/src/__tests__/conversation-queue.test.ts +23 -14
  45. package/src/__tests__/conversation-routes-slash-commands.test.ts +3 -3
  46. package/src/__tests__/conversation-runtime-assembly.test.ts +185 -173
  47. package/src/__tests__/conversation-seed-composer.test.ts +1 -1
  48. package/src/__tests__/conversation-slash-queue.test.ts +4 -4
  49. package/src/__tests__/conversation-slash-unknown.test.ts +4 -4
  50. package/src/__tests__/conversation-starter-routes.test.ts +291 -0
  51. package/src/__tests__/conversation-wipe.test.ts +438 -0
  52. package/src/__tests__/conversation-workspace-cache-state.test.ts +2 -3
  53. package/src/__tests__/conversation-workspace-injection.test.ts +4 -5
  54. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +4 -5
  55. package/src/__tests__/credential-security-e2e.test.ts +20 -0
  56. package/src/__tests__/credential-security-invariants.test.ts +1 -0
  57. package/src/__tests__/credential-vault-unit.test.ts +227 -0
  58. package/src/__tests__/credentials-cli.test.ts +3 -0
  59. package/src/__tests__/date-context.test.ts +59 -377
  60. package/src/__tests__/drop-capability-card-state-migration.test.ts +169 -0
  61. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +11 -45
  62. package/src/__tests__/emit-signal-routing-intent.test.ts +3 -3
  63. package/src/__tests__/encrypted-store.test.ts +237 -15
  64. package/src/__tests__/ephemeral-permissions.test.ts +4 -5
  65. package/src/__tests__/event-bus.test.ts +3 -3
  66. package/src/__tests__/gateway-only-enforcement.test.ts +2 -2
  67. package/src/__tests__/gateway-only-guard.test.ts +1 -0
  68. package/src/__tests__/gemini-image-service.test.ts +4 -4
  69. package/src/__tests__/gemini-provider.test.ts +6 -9
  70. package/src/__tests__/guardian-binding-drift-heal.test.ts +128 -0
  71. package/src/__tests__/guardian-dispatch.test.ts +0 -1
  72. package/src/__tests__/host-shell-tool.test.ts +6 -6
  73. package/src/__tests__/http-user-message-parity.test.ts +2 -2
  74. package/src/__tests__/intent-routing.test.ts +51 -99
  75. package/src/__tests__/invite-routes-http.test.ts +5 -0
  76. package/src/__tests__/list-messages-attachments.test.ts +1 -1
  77. package/src/__tests__/managed-proxy-context.test.ts +2 -5
  78. package/src/__tests__/managed-skill-lifecycle.test.ts +8 -8
  79. package/src/__tests__/media-generate-image.test.ts +32 -15
  80. package/src/__tests__/media-reuse-story.e2e.test.ts +1 -1
  81. package/src/__tests__/memory-context-benchmark.benchmark.test.ts +1 -1
  82. package/src/__tests__/memory-lifecycle-e2e.test.ts +24 -18
  83. package/src/__tests__/memory-recall-quality.test.ts +4 -3
  84. package/src/__tests__/memory-regressions.test.ts +86 -90
  85. package/src/__tests__/migration-cross-version-compatibility.test.ts +32 -32
  86. package/src/__tests__/migration-export-http.test.ts +26 -27
  87. package/src/__tests__/migration-import-commit-http.test.ts +165 -37
  88. package/src/__tests__/migration-import-preflight-http.test.ts +81 -20
  89. package/src/__tests__/migration-validate-http.test.ts +16 -16
  90. package/src/__tests__/model-intents.test.ts +1 -1
  91. package/src/__tests__/no-domain-routing-in-prompt-guard.test.ts +1 -1
  92. package/src/__tests__/notification-broadcaster.test.ts +1 -1
  93. package/src/__tests__/notification-decision-fallback.test.ts +2 -2
  94. package/src/__tests__/notification-decision-identity.test.ts +8 -9
  95. package/src/__tests__/notification-decision-strategy.test.ts +1 -1
  96. package/src/__tests__/notification-deep-link.test.ts +1 -1
  97. package/src/__tests__/notification-guardian-path.test.ts +0 -1
  98. package/src/__tests__/notification-schedule-dedup.test.ts +7 -7
  99. package/src/__tests__/oauth-store.test.ts +1 -3
  100. package/src/__tests__/oauth2-gateway-transport.test.ts +6 -1
  101. package/src/__tests__/onboarding-template-contract.test.ts +23 -59
  102. package/src/__tests__/provider-error-scenarios.test.ts +154 -0
  103. package/src/__tests__/provider-fail-open-selection.test.ts +2 -2
  104. package/src/__tests__/provider-managed-proxy-integration.test.ts +8 -9
  105. package/src/__tests__/provider-registry-ollama.test.ts +5 -2
  106. package/src/__tests__/qdrant-manager.test.ts +7 -7
  107. package/src/__tests__/ratelimit.test.ts +0 -74
  108. package/src/__tests__/recording-handler.test.ts +0 -1
  109. package/src/__tests__/require-fresh-approval.test.ts +1 -1
  110. package/src/__tests__/runtime-attachment-metadata.test.ts +1 -1
  111. package/src/__tests__/runtime-events-sse-parity.test.ts +1 -1
  112. package/src/__tests__/runtime-events-sse.test.ts +1 -1
  113. package/src/__tests__/scheduler-recurrence.test.ts +46 -2
  114. package/src/__tests__/schema-transforms.test.ts +114 -54
  115. package/src/__tests__/secret-onetime-send.test.ts +20 -0
  116. package/src/__tests__/secret-routes-managed-proxy.test.ts +5 -2
  117. package/src/__tests__/secret-scanner-executor.test.ts +1 -2
  118. package/src/__tests__/send-endpoint-busy.test.ts +63 -4
  119. package/src/__tests__/send-notification-tool.test.ts +2 -2
  120. package/src/__tests__/shell-credential-ref.test.ts +0 -1
  121. package/src/__tests__/shell-tool-proxy-mode.test.ts +1 -2
  122. package/src/__tests__/skill-memory.test.ts +547 -0
  123. package/src/__tests__/skill-script-runner-sandbox.test.ts +1 -2
  124. package/src/__tests__/slack-app-setup-skill-regression.test.ts +37 -0
  125. package/src/__tests__/slack-channel-config.test.ts +109 -94
  126. package/src/__tests__/swarm-conversation-integration.test.ts +2 -2
  127. package/src/__tests__/swarm-recursion.test.ts +2 -2
  128. package/src/__tests__/swarm-tool.test.ts +2 -2
  129. package/src/__tests__/system-prompt.test.ts +19 -66
  130. package/src/__tests__/telegram-config.test.ts +121 -0
  131. package/src/__tests__/terminal-tools.test.ts +1 -1
  132. package/src/__tests__/tool-execution-abort-cleanup.test.ts +1 -2
  133. package/src/__tests__/tool-executor-lifecycle-events.test.ts +1 -1
  134. package/src/__tests__/tool-executor-shell-integration.test.ts +1 -1
  135. package/src/__tests__/tool-executor.test.ts +1 -1
  136. package/src/__tests__/trace-emitter.test.ts +8 -1
  137. package/src/__tests__/trust-store.test.ts +7 -8
  138. package/src/__tests__/twilio-routes.test.ts +1 -18
  139. package/src/__tests__/user-reference.test.ts +82 -2
  140. package/src/__tests__/vbundle-pax-and-symlink.test.ts +196 -0
  141. package/src/__tests__/verification-control-plane-policy.test.ts +1 -1
  142. package/src/approvals/guardian-request-resolvers.ts +3 -3
  143. package/src/avatar/ascii-renderer.ts +2 -2
  144. package/src/avatar/png-renderer.ts +2 -2
  145. package/src/avatar/resvg-lazy.ts +21 -0
  146. package/src/calls/guardian-dispatch.ts +1 -1
  147. package/src/calls/relay-access-wait.ts +2 -2
  148. package/src/calls/twilio-rest.ts +0 -248
  149. package/src/cli/AGENTS.md +5 -8
  150. package/src/cli/__tests__/notifications.test.ts +5 -5
  151. package/src/cli/commands/avatar.ts +64 -2
  152. package/src/cli/commands/conversations.ts +131 -1
  153. package/src/cli/commands/credentials.ts +2 -0
  154. package/src/cli/commands/notifications.ts +3 -3
  155. package/src/cli.ts +10 -0
  156. package/src/config/bundled-skills/acp/SKILL.md +5 -5
  157. package/src/config/bundled-skills/acp/TOOLS.json +6 -6
  158. package/src/config/bundled-skills/app-builder/SKILL.md +42 -42
  159. package/src/config/bundled-skills/app-builder/TOOLS.json +10 -10
  160. package/src/config/bundled-skills/browser/SKILL.md +15 -15
  161. package/src/config/bundled-skills/browser/TOOLS.json +14 -14
  162. package/src/config/bundled-skills/chatgpt-import/SKILL.md +2 -2
  163. package/src/config/bundled-skills/chatgpt-import/TOOLS.json +1 -1
  164. package/src/config/bundled-skills/chatgpt-import/tools/chatgpt-import.ts +1 -1
  165. package/src/config/bundled-skills/claude-code/SKILL.md +5 -5
  166. package/src/config/bundled-skills/computer-use/SKILL.md +2 -2
  167. package/src/config/bundled-skills/computer-use/TOOLS.json +15 -15
  168. package/src/config/bundled-skills/contacts/SKILL.md +3 -3
  169. package/src/config/bundled-skills/contacts/TOOLS.json +4 -4
  170. package/src/config/bundled-skills/document/SKILL.md +4 -4
  171. package/src/config/bundled-skills/document/TOOLS.json +2 -2
  172. package/src/config/bundled-skills/followups/TOOLS.json +3 -3
  173. package/src/config/bundled-skills/gmail/SKILL.md +32 -32
  174. package/src/config/bundled-skills/gmail/TOOLS.json +16 -16
  175. package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +1 -1
  176. package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +1 -1
  177. package/src/config/bundled-skills/google-calendar/SKILL.md +1 -1
  178. package/src/config/bundled-skills/google-calendar/TOOLS.json +5 -5
  179. package/src/config/bundled-skills/google-calendar/types.ts +1 -1
  180. package/src/config/bundled-skills/heartbeat/SKILL.md +43 -0
  181. package/src/config/bundled-skills/image-studio/SKILL.md +3 -3
  182. package/src/config/bundled-skills/image-studio/TOOLS.json +2 -3
  183. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +16 -12
  184. package/src/config/bundled-skills/media-processing/SKILL.md +40 -40
  185. package/src/config/bundled-skills/media-processing/TOOLS.json +8 -8
  186. package/src/config/bundled-skills/media-processing/__tests__/concurrency-pool.test.ts +2 -2
  187. package/src/config/bundled-skills/media-processing/__tests__/preprocess.test.ts +1 -1
  188. package/src/config/bundled-skills/media-processing/services/gemini-map.ts +5 -5
  189. package/src/config/bundled-skills/media-processing/services/gemini-video.ts +2 -2
  190. package/src/config/bundled-skills/media-processing/services/preprocess.ts +2 -2
  191. package/src/config/bundled-skills/media-processing/services/processing-pipeline.ts +2 -2
  192. package/src/config/bundled-skills/media-processing/services/reduce.ts +3 -3
  193. package/src/config/bundled-skills/media-processing/tools/generate-clip.ts +2 -2
  194. package/src/config/bundled-skills/media-processing/tools/query-media-events.ts +1 -1
  195. package/src/config/bundled-skills/messaging/SKILL.md +29 -25
  196. package/src/config/bundled-skills/messaging/TOOLS.json +11 -11
  197. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +1 -1
  198. package/src/config/bundled-skills/messaging/tools/shared.ts +1 -1
  199. package/src/config/bundled-skills/notifications/SKILL.md +3 -3
  200. package/src/config/bundled-skills/notifications/TOOLS.json +2 -2
  201. package/src/config/bundled-skills/notifications/tools/send-notification.ts +3 -3
  202. package/src/config/bundled-skills/orchestration/SKILL.md +1 -1
  203. package/src/config/bundled-skills/orchestration/TOOLS.json +1 -1
  204. package/src/config/bundled-skills/phone-calls/SKILL.md +18 -14
  205. package/src/config/bundled-skills/phone-calls/TOOLS.json +3 -3
  206. package/src/config/bundled-skills/phone-calls/references/CONFIG.md +2 -2
  207. package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +2 -2
  208. package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +1 -1
  209. package/src/config/bundled-skills/playbooks/TOOLS.json +4 -4
  210. package/src/config/bundled-skills/schedule/SKILL.md +26 -26
  211. package/src/config/bundled-skills/schedule/TOOLS.json +5 -5
  212. package/src/config/bundled-skills/screen-watch/SKILL.md +3 -3
  213. package/src/config/bundled-skills/screen-watch/TOOLS.json +1 -1
  214. package/src/config/bundled-skills/sequences/SKILL.md +2 -2
  215. package/src/config/bundled-skills/sequences/TOOLS.json +10 -10
  216. package/src/config/bundled-skills/sequences/tools/sequence-analytics.ts +2 -2
  217. package/src/config/bundled-skills/sequences/tools/sequence-enroll.ts +2 -2
  218. package/src/config/bundled-skills/sequences/tools/sequence-enrollment-list.ts +1 -1
  219. package/src/config/bundled-skills/sequences/tools/sequence-get.ts +1 -1
  220. package/src/config/bundled-skills/sequences/tools/sequence-import.ts +3 -3
  221. package/src/config/bundled-skills/sequences/tools/sequence-list.ts +1 -1
  222. package/src/config/bundled-skills/sequences/tools/sequence-update.ts +1 -1
  223. package/src/config/bundled-skills/settings/TOOLS.json +3 -3
  224. package/src/config/bundled-skills/settings/tools/open-system-settings.ts +1 -1
  225. package/src/config/bundled-skills/skill-management/TOOLS.json +5 -5
  226. package/src/config/bundled-skills/skills-catalog/SKILL.md +84 -0
  227. package/src/config/bundled-skills/slack/SKILL.md +2 -2
  228. package/src/config/bundled-skills/slack/TOOLS.json +8 -8
  229. package/src/config/bundled-skills/slack/tools/slack-scan-digest.ts +3 -3
  230. package/src/config/bundled-skills/subagent/TOOLS.json +5 -5
  231. package/src/config/bundled-skills/tasks/SKILL.md +1 -1
  232. package/src/config/bundled-skills/tasks/TOOLS.json +9 -9
  233. package/src/config/bundled-skills/transcribe/SKILL.md +5 -5
  234. package/src/config/bundled-skills/transcribe/TOOLS.json +1 -1
  235. package/src/config/bundled-skills/transcribe/tools/transcribe-media.ts +10 -10
  236. package/src/config/bundled-skills/watcher/SKILL.md +4 -4
  237. package/src/config/bundled-skills/watcher/TOOLS.json +5 -5
  238. package/src/config/feature-flag-registry.json +33 -17
  239. package/src/config/schemas/sandbox.ts +1 -1
  240. package/src/config/schemas/services.ts +13 -3
  241. package/src/config/schemas/timeouts.ts +0 -10
  242. package/src/contacts/contact-store.ts +63 -0
  243. package/src/contacts/contacts-write.ts +1 -1
  244. package/src/daemon/assistant-attachments.ts +2 -2
  245. package/src/daemon/conversation-agent-loop-handlers.ts +2 -2
  246. package/src/daemon/conversation-agent-loop.ts +7 -30
  247. package/src/daemon/conversation-error.ts +24 -0
  248. package/src/daemon/conversation-memory.ts +8 -7
  249. package/src/daemon/conversation-runtime-assembly.ts +139 -274
  250. package/src/daemon/conversation-slash.ts +7 -26
  251. package/src/daemon/conversation-surfaces.ts +14 -0
  252. package/src/daemon/conversation-tool-setup.ts +9 -8
  253. package/src/daemon/conversation.ts +2 -0
  254. package/src/daemon/daemon-control.ts +1 -1
  255. package/src/daemon/date-context.ts +10 -83
  256. package/src/daemon/handlers/config-channels.ts +12 -2
  257. package/src/daemon/handlers/config-slack-channel.ts +7 -1
  258. package/src/daemon/handlers/config-telegram.ts +6 -1
  259. package/src/daemon/handlers/conversations.ts +2 -2
  260. package/src/daemon/handlers/skills.ts +4 -0
  261. package/src/daemon/lifecycle.ts +28 -4
  262. package/src/daemon/providers-setup.ts +1 -1
  263. package/src/daemon/server.ts +1 -5
  264. package/src/daemon/shutdown-handlers.ts +9 -3
  265. package/src/daemon/tool-side-effects.ts +40 -0
  266. package/src/daemon/trace-emitter.ts +25 -2
  267. package/src/events/domain-events.ts +1 -1
  268. package/src/events/tool-permission-telemetry-listener.ts +46 -0
  269. package/src/inbound/platform-callback-registration.ts +0 -18
  270. package/src/media/app-icon-generator.ts +15 -8
  271. package/src/media/avatar-router.ts +15 -8
  272. package/src/media/gemini-image-service.ts +125 -21
  273. package/src/memory/attachments-store.ts +3 -3
  274. package/src/memory/channel-verification-sessions.ts +6 -6
  275. package/src/memory/conversation-crud.ts +196 -1
  276. package/src/memory/{thread-starters-cadence.ts → conversation-starters-cadence.ts} +9 -42
  277. package/src/memory/conversation-title-service.ts +2 -3
  278. package/src/memory/db-init.ts +25 -1
  279. package/src/memory/invite-store.ts +4 -4
  280. package/src/memory/items-extractor.ts +4 -4
  281. package/src/memory/job-handlers/{thread-starters.ts → conversation-starters.ts} +123 -38
  282. package/src/memory/jobs-store.ts +3 -2
  283. package/src/memory/jobs-worker.ts +7 -5
  284. package/src/memory/lifecycle-events-store.ts +63 -0
  285. package/src/memory/migrations/172-rename-created-by-session-id.ts +27 -0
  286. package/src/memory/migrations/173-rename-source-session-id.ts +16 -0
  287. package/src/memory/migrations/174-rename-thread-starters-table.ts +52 -0
  288. package/src/memory/migrations/175-create-lifecycle-events.ts +15 -0
  289. package/src/memory/migrations/176-drop-capability-card-state.ts +36 -0
  290. package/src/memory/migrations/177-create-trace-events-table.ts +40 -0
  291. package/src/memory/migrations/index.ts +6 -0
  292. package/src/memory/migrations/registry.ts +13 -0
  293. package/src/memory/retriever.test.ts +223 -96
  294. package/src/memory/retriever.ts +115 -138
  295. package/src/memory/schema/calls.ts +1 -1
  296. package/src/memory/schema/contacts.ts +1 -1
  297. package/src/memory/schema/infrastructure.ts +29 -0
  298. package/src/memory/schema/memory-core.ts +7 -17
  299. package/src/memory/schema/notifications.ts +1 -1
  300. package/src/memory/search/formatting.ts +23 -6
  301. package/src/memory/search/lexical.ts +2 -0
  302. package/src/memory/search/semantic.ts +2 -0
  303. package/src/memory/search/staleness.ts +1 -0
  304. package/src/memory/search/types.ts +4 -0
  305. package/src/memory/task-memory-cleanup.ts +96 -6
  306. package/src/memory/trace-event-store.ts +148 -0
  307. package/src/notifications/README.md +1 -1
  308. package/src/notifications/decision-engine.ts +2 -2
  309. package/src/notifications/emit-signal.ts +4 -4
  310. package/src/notifications/events-store.ts +4 -4
  311. package/src/notifications/signal.ts +1 -1
  312. package/src/oauth/manual-token-connection.ts +49 -25
  313. package/src/permissions/checker.ts +6 -5
  314. package/src/permissions/defaults.ts +4 -4
  315. package/src/prompts/__tests__/build-cli-reference-section.test.ts +9 -90
  316. package/src/prompts/cache-boundary.ts +8 -0
  317. package/src/prompts/system-prompt.ts +105 -634
  318. package/src/prompts/templates/BOOTSTRAP.md +166 -33
  319. package/src/prompts/templates/IDENTITY.md +8 -23
  320. package/src/prompts/templates/SOUL.md +20 -41
  321. package/src/prompts/templates/USER.md +3 -19
  322. package/src/prompts/user-reference.ts +14 -16
  323. package/src/providers/anthropic/client.ts +46 -2
  324. package/src/providers/gemini/client.ts +6 -9
  325. package/src/providers/managed-proxy/constants.ts +1 -7
  326. package/src/providers/managed-proxy/context.ts +0 -1
  327. package/src/providers/model-intents.ts +5 -5
  328. package/src/providers/openai/client.ts +10 -1
  329. package/src/providers/openrouter/client.ts +1 -0
  330. package/src/providers/ratelimit.ts +0 -35
  331. package/src/providers/registry.ts +3 -5
  332. package/src/providers/retry.ts +18 -1
  333. package/src/runtime/access-request-helper.ts +1 -1
  334. package/src/runtime/auth/route-policy.ts +7 -0
  335. package/src/runtime/channel-verification-service.ts +1 -1
  336. package/src/runtime/confirmation-request-guardian-bridge.ts +1 -1
  337. package/src/runtime/guardian-vellum-migration.ts +63 -1
  338. package/src/runtime/http-server.ts +8 -4
  339. package/src/runtime/migrations/vbundle-builder.ts +212 -32
  340. package/src/runtime/migrations/vbundle-import-analyzer.ts +74 -8
  341. package/src/runtime/migrations/vbundle-importer.ts +66 -1
  342. package/src/runtime/migrations/vbundle-validator.ts +17 -3
  343. package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +4 -4
  344. package/src/runtime/routes/attachment-routes.ts +2 -2
  345. package/src/runtime/routes/btw-routes.ts +9 -0
  346. package/src/runtime/routes/channel-verification-routes.ts +19 -2
  347. package/src/runtime/routes/conversation-management-routes.ts +55 -1
  348. package/src/runtime/routes/conversation-query-routes.ts +1 -1
  349. package/src/runtime/routes/conversation-routes.ts +49 -5
  350. package/src/runtime/routes/conversation-starter-routes.ts +207 -0
  351. package/src/runtime/routes/guardian-bootstrap-routes.ts +13 -9
  352. package/src/runtime/routes/inbound-stages/escalation-intercept.ts +1 -1
  353. package/src/runtime/routes/inbound-stages/verification-intercept.ts +1 -1
  354. package/src/runtime/routes/migration-routes.ts +25 -13
  355. package/src/runtime/routes/secret-routes.ts +18 -0
  356. package/src/runtime/routes/settings-routes.ts +8 -8
  357. package/src/runtime/routes/telemetry-routes.ts +53 -0
  358. package/src/runtime/routes/trace-event-routes.ts +62 -0
  359. package/src/runtime/tool-grant-request-helper.ts +1 -1
  360. package/src/runtime/verification-outbound-actions.ts +47 -31
  361. package/src/security/encrypted-store.ts +263 -78
  362. package/src/skills/catalog-install.ts +10 -0
  363. package/src/skills/managed-store.ts +2 -0
  364. package/src/skills/skill-memory.ts +220 -0
  365. package/src/subagent/manager.ts +1 -4
  366. package/src/telemetry/types.ts +10 -1
  367. package/src/telemetry/usage-telemetry-reporter.test.ts +1 -1
  368. package/src/telemetry/usage-telemetry-reporter.ts +51 -4
  369. package/src/tools/AGENTS.md +11 -11
  370. package/src/tools/acp/spawn.ts +1 -1
  371. package/src/tools/apps/executors.ts +8 -8
  372. package/src/tools/apps/registry.ts +1 -1
  373. package/src/tools/assets/materialize.ts +6 -6
  374. package/src/tools/assets/search.ts +10 -10
  375. package/src/tools/browser/__tests__/auth-cache.test.ts +2 -2
  376. package/src/tools/browser/__tests__/auth-detector.test.ts +4 -4
  377. package/src/tools/browser/auth-detector.ts +6 -6
  378. package/src/tools/browser/browser-execution.ts +13 -13
  379. package/src/tools/browser/browser-manager.ts +3 -3
  380. package/src/tools/browser/chrome-cdp.ts +5 -5
  381. package/src/tools/browser/jit-auth.ts +2 -2
  382. package/src/tools/browser/network-recorder.test.ts +2 -2
  383. package/src/tools/browser/network-recorder.ts +3 -3
  384. package/src/tools/browser/runtime-check.ts +3 -3
  385. package/src/tools/claude-code/claude-code.ts +2 -2
  386. package/src/tools/computer-use/definitions.ts +18 -18
  387. package/src/tools/credential-execution/make-authenticated-request.ts +4 -4
  388. package/src/tools/credential-execution/manage-secure-command-tool.ts +3 -3
  389. package/src/tools/credential-execution/run-authenticated-command.ts +4 -4
  390. package/src/tools/credentials/broker-types.ts +5 -5
  391. package/src/tools/credentials/broker.ts +15 -15
  392. package/src/tools/credentials/metadata-store.ts +2 -2
  393. package/src/tools/credentials/resolve.ts +1 -1
  394. package/src/tools/credentials/selection.ts +1 -1
  395. package/src/tools/credentials/tool-policy.ts +1 -1
  396. package/src/tools/credentials/vault.ts +115 -25
  397. package/src/tools/execution-target.ts +2 -2
  398. package/src/tools/executor.ts +7 -7
  399. package/src/tools/filesystem/edit.ts +2 -2
  400. package/src/tools/filesystem/read.ts +1 -1
  401. package/src/tools/filesystem/write.ts +1 -1
  402. package/src/tools/host-filesystem/edit.ts +2 -1
  403. package/src/tools/host-filesystem/read.ts +2 -1
  404. package/src/tools/host-filesystem/write.ts +1 -1
  405. package/src/tools/host-terminal/host-shell.ts +9 -8
  406. package/src/tools/mcp/mcp-tool-factory.ts +7 -6
  407. package/src/tools/memory/definitions.ts +6 -5
  408. package/src/tools/memory/handlers.test.ts +1 -1
  409. package/src/tools/network/__tests__/web-search.test.ts +3 -3
  410. package/src/tools/network/domain-normalize.ts +2 -2
  411. package/src/tools/network/script-proxy/session-manager.ts +10 -10
  412. package/src/tools/network/web-fetch.ts +1 -1
  413. package/src/tools/network/web-search.ts +3 -3
  414. package/src/tools/permission-checker.ts +8 -8
  415. package/src/tools/registry.ts +7 -7
  416. package/src/tools/schedule/list.ts +2 -2
  417. package/src/tools/schema-transforms.ts +31 -21
  418. package/src/tools/secret-detection-handler.ts +1 -1
  419. package/src/tools/sensitive-output-placeholders.ts +1 -1
  420. package/src/tools/shared/filesystem/edit-engine.ts +1 -1
  421. package/src/tools/shared/filesystem/file-ops-service.ts +3 -3
  422. package/src/tools/shared/filesystem/image-read.ts +25 -5
  423. package/src/tools/shared/filesystem/path-policy.ts +2 -2
  424. package/src/tools/shared/shell-output.ts +1 -1
  425. package/src/tools/side-effects.ts +1 -1
  426. package/src/tools/skills/execute.ts +1 -1
  427. package/src/tools/skills/load.ts +3 -3
  428. package/src/tools/skills/sandbox-runner.ts +3 -3
  429. package/src/tools/subagent/read.ts +1 -1
  430. package/src/tools/subagent/spawn.ts +2 -2
  431. package/src/tools/swarm/delegate.ts +3 -3
  432. package/src/tools/system/request-permission.ts +5 -4
  433. package/src/tools/terminal/backends/native.ts +4 -4
  434. package/src/tools/terminal/parser.ts +6 -6
  435. package/src/tools/terminal/sandbox-diagnostics.ts +1 -1
  436. package/src/tools/terminal/shell.ts +16 -16
  437. package/src/tools/tool-approval-handler.ts +21 -12
  438. package/src/tools/tool-manifest.ts +4 -4
  439. package/src/tools/types.ts +3 -3
  440. package/src/tools/ui-surface/definitions.ts +9 -37
  441. package/src/tools/watcher/list.ts +1 -1
  442. package/src/util/logger.ts +7 -2
  443. package/src/util/retry.ts +29 -1
  444. package/src/workspace/migrations/007-web-search-provider-rename.ts +37 -0
  445. package/src/workspace/migrations/registry.ts +2 -0
  446. package/src/__tests__/cli-help-reference-sync.test.ts +0 -26
  447. package/src/__tests__/onboarding-starter-tasks.test.ts +0 -190
  448. package/src/cli/reference.ts +0 -38
  449. package/src/memory/job-handlers/capability-cards.ts +0 -420
  450. package/src/runtime/routes/thread-starter-routes.ts +0 -294
@@ -13,22 +13,26 @@ metadata:
13
13
 
14
14
  You are a unified messaging assistant with access to multiple platforms (Slack, Gmail, Telegram, and more). Use the messaging tools to help users read, search, organize, draft, and send messages across all connected platforms.
15
15
 
16
+ ## External Identity
17
+
18
+ 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.
19
+
16
20
  For Gmail management (archive, label, triage, declutter), load the **gmail** skill. For email sequences, load the **sequences** skill.
17
21
 
18
22
  ## Email Routing Priority
19
23
 
20
- 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.
24
+ 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.
21
25
 
22
- 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.
26
+ 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.
23
27
 
24
28
  ## Communication Style
25
29
 
26
- - **Be action-oriented.** When the user asks to do something ("declutter", "check my email"), start doing it immediately. Don't ask for permission to read their inbox that's obviously what they want.
27
- - **Keep it human.** Never mention OAuth, tokens, APIs, sandboxes, credential proxies, or other technical internals. If something isn't working, say "Gmail needs to be reconnected" not "the OAuth2 access token for integration:google has expired."
30
+ - **Be action-oriented.** When the user asks to do something ("declutter", "check my email"), start doing it immediately. Don't ask for permission to read their inbox - that's obviously what they want.
31
+ - **Keep it human.** Never mention OAuth, tokens, APIs, sandboxes, credential proxies, or other technical internals. If something isn't working, say "Gmail needs to be reconnected" - not "the OAuth2 access token for integration:google has expired."
28
32
  - **Show progress.** When running a tool that scans many emails, tell the user what you're doing: "Scanning your inbox for clutter..." Don't go silent.
29
- - **Be brief and warm.** One or two sentences per update is plenty. Don't over-explain what you're about to do just do it and narrate lightly.
33
+ - **Be brief and warm.** One or two sentences per update is plenty. Don't over-explain what you're about to do - just do it and narrate lightly.
30
34
 
31
- When a platform is connected (auth test succeeds), always use the messaging API tools for that platform. Never fall back to browser automation, shell commands (bash, curl), or any other approach for operations that messaging tools can handle. The messaging tools handle authentication internally never try to access tokens or call APIs directly. Browser automation is only appropriate for initial credential setup (OAuth consent screens), not for day-to-day messaging operations.
35
+ When a platform is connected (auth test succeeds), always use the messaging API tools for that platform. Never fall back to browser automation, shell commands (bash, curl), or any other approach for operations that messaging tools can handle. The messaging tools handle authentication internally - never try to access tokens or call APIs directly. Browser automation is only appropriate for initial credential setup (OAuth consent screens), not for day-to-day messaging operations.
32
36
 
33
37
  ## Connection Setup
34
38
 
@@ -40,20 +44,20 @@ Telegram setup requires a publicly reachable URL for webhook delivery. The **pub
40
44
 
41
45
  ### Email Connection Flow
42
46
 
43
- When the user asks to "connect my email", "set up email", "manage my email", or similar and has not named a specific provider:
47
+ When the user asks to "connect my email", "set up email", "manage my email", or similar - and has not named a specific provider:
44
48
 
45
49
  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.
46
- 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.
50
+ 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.
47
51
  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.
48
52
 
49
53
  ### Gmail
50
54
 
51
- 1. **Try connecting directly first.** Call `credential_store` with `action: "oauth2_connect"` and `service: "gmail"`. The tool auto-fills Google's OAuth endpoints and looks up any previously stored client credentials so this single call may be all that's needed.
55
+ 1. **Try connecting directly first.** Call `credential_store` with `action: "oauth2_connect"` and `service: "gmail"`. The tool auto-fills Google's OAuth endpoints and looks up any previously stored client credentials - so this single call may be all that's needed.
52
56
  2. **If it fails because no client_id is found:** The user needs to create Google Cloud OAuth credentials first. Load the **google-oauth-applescript** skill:
53
57
  - Call `skill_load` with `skill: "google-oauth-applescript"` to load the dependency skill.
54
58
  - 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:
55
59
  - **message:** "Ready to set up Gmail?"
56
- - **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."
60
+ - **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."
57
61
  - **confirmLabel:** "Get Started"
58
62
  - **cancelLabel:** "Not Now"
59
63
  - 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.
@@ -66,7 +70,7 @@ Slack connects via Socket Mode using a bot token and app-level token (not OAuth)
66
70
  - Call `skill_load` with `skill: "slack-app-setup"` to load the dependency skill.
67
71
  - Tell the user Slack isn't connected yet and briefly explain what the setup involves, then follow the skill's guided flow.
68
72
 
69
- The slack-app-setup skill handles: manifest-driven app creation, app token and bot token collection via secure prompt (never accept tokens pasted in plaintext chat), token validation, workspace metadata storage, and optional guardian verification. Socket Mode connects automatically once both credentials are stored.
73
+ The slack-app-setup skill handles: manifest-driven app creation, app token and bot token collection via secure prompt (never accept tokens pasted in plaintext chat), and Slack connection setup through the same settings handler used by the Settings UI. That handler validates the bot token, stores workspace metadata, and activates Socket Mode. The skill also covers optional guardian verification.
70
74
 
71
75
  ### Telegram
72
76
 
@@ -75,7 +79,7 @@ Telegram uses a bot token (not OAuth). Load the **telegram-setup** skill (which
75
79
  - Call `skill_load` with `skill: "telegram-setup"` to load the dependency skill.
76
80
  - Tell the user: _"I've loaded a setup guide for Telegram. It will walk you through connecting a Telegram bot to your assistant."_
77
81
 
78
- The telegram-setup skill handles: verifying the bot token from @BotFather, generating a webhook secret, registering bot commands, and storing credentials securely via the secure credential prompt flow. **Never accept a Telegram bot token pasted in plaintext chat always use the secure prompt.** Webhook registration with Telegram is handled automatically by the gateway on startup and whenever credentials change.
82
+ The telegram-setup skill handles: verifying the bot token from @BotFather, generating a webhook secret, registering bot commands, and storing credentials securely via the secure credential prompt flow. **Never accept a Telegram bot token pasted in plaintext chat - always use the secure prompt.** Webhook registration with Telegram is handled automatically by the gateway on startup and whenever credentials change.
79
83
 
80
84
  The telegram-setup skill also includes **guardian verification**, which links your Telegram account as the trusted guardian for the bot.
81
85
 
@@ -92,7 +96,7 @@ The guardian-verify-setup skill handles the full outbound verification flow for
92
96
  When a messaging tool fails with a token or authorization error:
93
97
 
94
98
  1. **Try to reconnect silently.** Call `credential_store` with `action: "oauth2_connect"` and the appropriate `service`. This often resolves expired tokens automatically.
95
- 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-applescript** for Gmail). The user came to you to get something done, not to troubleshoot OAuth make it seamless.
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-applescript** for Gmail). The user came to you to get something done, not to troubleshoot OAuth - make it seamless.
96
100
  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.
97
101
  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.
98
102
 
@@ -100,8 +104,8 @@ When a messaging tool fails with a token or authorization error:
100
104
 
101
105
  - If the user specifies a platform (e.g., "check my Slack"), pass it as the `platform` parameter.
102
106
  - If only one platform is connected, it is auto-selected.
103
- - If multiple platforms are connected and the user doesn't specify, ask which platform they mean or search across all of them.
104
- - **Be action-oriented with email.** When the user says "email" and wants to _do_ something (declutter, check, search, send), check what's connected first. If nothing is connected, ask which provider briefly and then go straight into setup don't present menus, options lists, or explain the setup process. Just do it.
107
+ - If multiple platforms are connected and the user doesn't specify, ask which platform they mean - or search across all of them.
108
+ - **Be action-oriented with email.** When the user says "email" and wants to _do_ something (declutter, check, search, send), check what's connected first. If nothing is connected, ask which provider briefly and then go straight into setup - don't present menus, options lists, or explain the setup process. Just do it.
105
109
 
106
110
  ## Capabilities
107
111
 
@@ -111,21 +115,21 @@ When a messaging tool fails with a token or authorization error:
111
115
  - **List Conversations**: Show channels, inboxes, DMs with unread counts
112
116
  - **Read Messages**: Read message history from a conversation
113
117
  - **Search**: Search messages with platform-appropriate query syntax
114
- - **Send / Reply**: Send a message or reply in a thread (via `thread_id`). High risk requires user approval.
118
+ - **Send / Reply**: Send a message or reply in a thread (via `thread_id`). High risk - requires user approval.
115
119
  - **Mark Read**: Mark conversation as read
116
120
 
117
121
  ### Telegram
118
122
 
119
123
  Telegram is supported as a messaging provider with limited capabilities compared to Slack and Gmail due to Bot API constraints:
120
124
 
121
- - **Send**: Send a message to a known chat ID (high risk requires user approval)
125
+ - **Send**: Send a message to a known chat ID (high risk - requires user approval)
122
126
  - **Auth Test**: Verify bot token and show bot info
123
127
 
124
128
  **Not available** (Bot API limitations):
125
129
 
126
- - List conversations the Bot API does not expose a method to enumerate chats a bot belongs to
127
- - Read message history bots cannot retrieve past messages from a chat
128
- - Search messages no search API is available for bots
130
+ - List conversations - the Bot API does not expose a method to enumerate chats a bot belongs to
131
+ - Read message history - bots cannot retrieve past messages from a chat
132
+ - Search messages - no search API is available for bots
129
133
 
130
134
  **Bot-account limits:**
131
135
 
@@ -136,10 +140,10 @@ Telegram is supported as a messaging provider with limited capabilities compared
136
140
 
137
141
  - **Add Reaction**: Add an emoji reaction to a message
138
142
  - **Leave Channel**: Leave a Slack channel
139
- - **Edit Message**: `slack_edit_message` edit a message the assistant previously sent. Requires `channel_id` and the message timestamp (`ts`) from the original send response. High risk requires confidence score.
140
- - **Delete Message**: `slack_delete_message` delete a message the assistant previously sent. Requires `channel_id` and the message timestamp (`ts`). High risk requires confidence score. This is irreversible.
143
+ - **Edit Message**: `slack_edit_message` - edit a message the assistant previously sent. Requires `channel_id` and the message timestamp (`ts`) from the original send response. High risk - requires confidence score.
144
+ - **Delete Message**: `slack_delete_message` - delete a message the assistant previously sent. Requires `channel_id` and the message timestamp (`ts`). High risk - requires confidence score. This is irreversible.
141
145
 
142
- When sending a Slack message, retain the `ts` (message timestamp) from the send response it is needed to edit or delete that message later. Only messages sent by the assistant's bot can be edited or deleted.
146
+ When sending a Slack message, retain the `ts` (message timestamp) from the send response - it is needed to edit or delete that message later. Only messages sent by the assistant's bot can be edited or deleted.
143
147
 
144
148
  ## Slack Search Syntax
145
149
 
@@ -183,7 +187,7 @@ Medium and high risk tools require a confidence score between 0 and 1:
183
187
  When a user asks to declutter, clean up, or organize their email:
184
188
 
185
189
  - **Gmail connected**: Load the **gmail** skill, which has the full decluttering workflow with `gmail_sender_digest`, `gmail_archive`, `gmail_unsubscribe`, and `gmail_filters`.
186
- - **Non-Gmail email connected**: Use the generic tools (`messaging_sender_digest`, `messaging_archive_by_sender`) they work with any provider that supports these operations. Skip unsubscribe and filter offers since they are Gmail-specific.
190
+ - **Non-Gmail email connected**: Use the generic tools (`messaging_sender_digest`, `messaging_archive_by_sender`) - they work with any provider that supports these operations. Skip unsubscribe and filter offers since they are Gmail-specific.
187
191
  - **Nothing connected**: Ask which email provider they use. If it's Gmail, go straight into the Gmail connection flow. For other providers, let the user know only Gmail is supported right now and offer to set up Gmail instead. Don't present a menu of options or explain what OAuth is.
188
192
 
189
193
  ### Non-Gmail Decluttering Workflow
@@ -191,7 +195,7 @@ When a user asks to declutter, clean up, or organize their email:
191
195
  1. **Scan**: Call `messaging_sender_digest`. Default query targets promotions from the last 90 days.
192
196
  2. **Present**: Show results as a `ui_show` table with `selectionMode: "multiple"`:
193
197
  - **Columns (exactly 2)**: Sender, Emails Found
194
- - **Pre-select all rows** (`selected: true`) users deselect what they want to keep
198
+ - **Pre-select all rows** (`selected: true`) - users deselect what they want to keep
195
199
  - **Caption**: Data scope, e.g. "Newsletters, notifications, and outreach from last 90 days. Deselect anything you want to keep."
196
200
  - **Action button (exactly 1)**: "Archive Selected" (primary). **NEVER offer Delete, Trash, or any destructive action.**
197
201
  3. **Wait for user action**: Stop and wait. Do NOT proceed until the user clicks the action button.
@@ -17,7 +17,7 @@
17
17
  "type": "string",
18
18
  "description": "Email address of the account to use. Required when multiple accounts are connected for the same platform. If omitted, uses the most recently connected account."
19
19
  },
20
- "reason": {
20
+ "activity": {
21
21
  "type": "string",
22
22
  "description": "Brief non-technical explanation of why this tool is being called"
23
23
  }
@@ -54,7 +54,7 @@
54
54
  "type": "number",
55
55
  "description": "Maximum number of conversations to return (default 200)"
56
56
  },
57
- "reason": {
57
+ "activity": {
58
58
  "type": "string",
59
59
  "description": "Brief non-technical explanation of why this tool is being called"
60
60
  }
@@ -91,7 +91,7 @@
91
91
  "type": "number",
92
92
  "description": "Maximum number of messages to return (default 50)"
93
93
  },
94
- "reason": {
94
+ "activity": {
95
95
  "type": "string",
96
96
  "description": "Brief non-technical explanation of why this tool is being called"
97
97
  }
@@ -125,7 +125,7 @@
125
125
  "type": "number",
126
126
  "description": "Maximum number of results to return (default 20)"
127
127
  },
128
- "reason": {
128
+ "activity": {
129
129
  "type": "string",
130
130
  "description": "Brief non-technical explanation of why this tool is being called"
131
131
  }
@@ -182,7 +182,7 @@
182
182
  "type": "number",
183
183
  "description": "Confidence score (0-1) for this action"
184
184
  },
185
- "reason": {
185
+ "activity": {
186
186
  "type": "string",
187
187
  "description": "Brief non-technical explanation of why this tool is being called"
188
188
  }
@@ -216,7 +216,7 @@
216
216
  "type": "string",
217
217
  "description": "Specific message ID to mark as read (optional)"
218
218
  },
219
- "reason": {
219
+ "activity": {
220
220
  "type": "string",
221
221
  "description": "Brief non-technical explanation of why this tool is being called"
222
222
  }
@@ -250,7 +250,7 @@
250
250
  "type": "string",
251
251
  "description": "Optional search filter (e.g. 'to:alice@example.com' for Gmail, 'from:@me' for Slack)"
252
252
  },
253
- "reason": {
253
+ "activity": {
254
254
  "type": "string",
255
255
  "description": "Brief non-technical explanation of why this tool is being called"
256
256
  }
@@ -296,7 +296,7 @@
296
296
  "type": "string",
297
297
  "description": "Draft ID (for delete)"
298
298
  },
299
- "reason": {
299
+ "activity": {
300
300
  "type": "string",
301
301
  "description": "Brief non-technical explanation of why this tool is being called"
302
302
  }
@@ -336,9 +336,9 @@
336
336
  },
337
337
  "page_token": {
338
338
  "type": "string",
339
- "description": "Resume token from a previous scan (rarely needed scans now cover up to 5,000 messages in a single call)"
339
+ "description": "Resume token from a previous scan (rarely needed - scans now cover up to 5,000 messages in a single call)"
340
340
  },
341
- "reason": {
341
+ "activity": {
342
342
  "type": "string",
343
343
  "description": "Brief non-technical explanation of why this tool is being called"
344
344
  }
@@ -371,7 +371,7 @@
371
371
  "type": "number",
372
372
  "description": "Confidence score (0-1) for this action"
373
373
  },
374
- "reason": {
374
+ "activity": {
375
375
  "type": "string",
376
376
  "description": "Brief non-technical explanation of why this tool is being called"
377
377
  }
@@ -58,7 +58,7 @@ export async function run(
58
58
  // Gmail: create a draft instead of sending directly
59
59
  if (provider.id === "gmail") {
60
60
  const gmailConn = conn as OAuthConnection;
61
- // Reply mode: thread_id provided create a threaded draft with reply-all recipients
61
+ // Reply mode: thread_id provided - create a threaded draft with reply-all recipients
62
62
  if (threadId) {
63
63
  // Fetch thread messages to extract recipients and threading headers
64
64
  const list = await listMessages(gmailConn, `thread:${threadId}`, 10);
@@ -130,7 +130,7 @@ export async function resolveProvider(
130
130
  * for the given messaging provider.
131
131
  *
132
132
  * Non-OAuth providers (e.g. Telegram) use isConnected() and don't need
133
- * tokens they receive an empty string which the string overload handles.
133
+ * tokens - they receive an empty string which the string overload handles.
134
134
  */
135
135
  export async function getProviderConnection(
136
136
  provider: MessagingProvider,
@@ -17,15 +17,15 @@ Use `send_notification` for user-facing alerts and notifications. This tool rout
17
17
 
18
18
  ## Deduplication (`dedupe_key`)
19
19
 
20
- - `dedupe_key` suppresses duplicate signals **permanently**. A second notification with the same key is **dropped entirely** for the lifetime of the assistant's event store. Once a key has been used, it cannot be reused any future notification with the same key will be silently discarded.
20
+ - `dedupe_key` suppresses duplicate signals **permanently**. A second notification with the same key is **dropped entirely** for the lifetime of the assistant's event store. Once a key has been used, it cannot be reused - any future notification with the same key will be silently discarded.
21
21
  - Never reuse a `dedupe_key` across logically distinct notifications, even if they are related. The key means "this exact event already fired," not "these events are in the same category."
22
22
  - If you omit `dedupe_key`, the LLM decision engine may generate one automatically based on signal context. This means even keyless signals can be deduplicated if the engine considers them duplicates of a recent event.
23
23
 
24
24
  ## Conversation Grouping
25
25
 
26
- Conversation grouping is handled by the LLM-powered decision engine, not by any parameter you pass. There is no explicit "post to conversation X" parameter conversation reuse is inferred, not commanded.
26
+ Conversation grouping is handled by the LLM-powered decision engine, not by any parameter you pass. There is no explicit "post to conversation X" parameter - conversation reuse is inferred, not commanded.
27
27
 
28
- **How it works:** The engine evaluates recent notification conversation candidates and decides whether a new signal is a continuation of an existing conversation based on `source_event_name`, provenance metadata, and message content. Use natural, descriptive titles and bodies the engine groups by semantic relatedness, not string matching.
28
+ **How it works:** The engine evaluates recent notification conversation candidates and decides whether a new signal is a continuation of an existing conversation based on `source_event_name`, provenance metadata, and message content. Use natural, descriptive titles and bodies - the engine groups by semantic relatedness, not string matching.
29
29
 
30
30
  **`source_event_name` is the primary grouping signal.** Use a stable event name for notifications that belong to the same logical stream (e.g. `dog.news.thread.reply` for all replies in a thread). Use a distinct event name when the notification represents a genuinely different kind of event.
31
31
 
@@ -3,7 +3,7 @@
3
3
  "tools": [
4
4
  {
5
5
  "name": "send_notification",
6
- "description": "Send a notification through the unified notification router. The router decides channels/copy from preferences and urgency hints. Include a confidence score (0-1).",
6
+ "description": "Send an immediate notification. Fires instantly with no delay capability. For one-time future alerts, use schedule_create with fire_at. For recurring alerts, use schedule_create with expression (cron/RRULE). The router decides channels/copy from preferences and urgency hints. Include a confidence score (0-1).",
7
7
  "category": "notifications",
8
8
  "risk": "medium",
9
9
  "input_schema": {
@@ -66,7 +66,7 @@
66
66
  "type": "number",
67
67
  "description": "Confidence score (0-1) for this action"
68
68
  },
69
- "reason": {
69
+ "activity": {
70
70
  "type": "string",
71
71
  "description": "Brief non-technical explanation of why this tool is being called"
72
72
  }
@@ -110,14 +110,14 @@ export async function run(
110
110
  asNonEmptyString(input.source_event_name) ?? "user.send_notification";
111
111
  const requestedConversationId =
112
112
  asNonEmptyString(input.conversation_id) ?? context.conversationId;
113
- const sourceSessionId = requestedConversationId ?? context.conversationId;
113
+ const sourceContextId = requestedConversationId ?? context.conversationId;
114
114
  const title = asNonEmptyString(input.title);
115
115
  const dedupeKey = asNonEmptyString(input.dedupe_key);
116
116
 
117
117
  const contextPayload: Record<string, unknown> = {
118
118
  requestedMessage: message,
119
119
  requestedByTool: "send_notification",
120
- requestedBySessionId: context.conversationId,
120
+ requestedByContextId: context.conversationId,
121
121
  };
122
122
  if (title) contextPayload.requestedTitle = title;
123
123
  if (requestedConversationId)
@@ -130,7 +130,7 @@ export async function run(
130
130
  await emitNotificationSignal({
131
131
  sourceEventName,
132
132
  sourceChannel: "assistant_tool",
133
- sourceSessionId,
133
+ sourceContextId,
134
134
  attentionHints: {
135
135
  requiresAction: parseBool(input.requires_action, true),
136
136
  urgency,
@@ -22,7 +22,7 @@ Use `swarm_delegate` when facing complex multi-part tasks that benefit from para
22
22
 
23
23
  ## When NOT to use
24
24
 
25
- - Simple single-step requests just do them directly.
25
+ - Simple single-step requests - just do them directly.
26
26
  - Tasks that are inherently sequential (each step depends on the previous result).
27
27
  - Requests where the user is asking for a quick answer, not a deep workflow.
28
28
 
@@ -21,7 +21,7 @@
21
21
  "type": "number",
22
22
  "description": "Maximum concurrent workers (1-6, default from config)"
23
23
  },
24
- "reason": {
24
+ "activity": {
25
25
  "type": "string",
26
26
  "description": "Brief non-technical explanation of what you are doing and why, shown to the user as a status update. Use simple language a non-technical person would understand."
27
27
  }
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: phone-calls
3
- description: "Make outgoing phone calls, receive incoming calls, and pull up past call transcripts. Everything needed for your assistant to act as an AI receptionist."
3
+ description: "Make outgoing phone calls, receive incoming calls, and pull up past call transcripts"
4
4
  compatibility: "Designed for Vellum personal assistants"
5
5
  metadata:
6
6
  emoji: "📞"
@@ -19,6 +19,10 @@ metadata:
19
19
 
20
20
  You are helping the user set up and manage phone calls via Twilio. This skill covers enabling the calls feature, placing outbound calls, receiving inbound calls, and interacting with live calls. Twilio credential storage, phone number provisioning, and public ingress are handled by the **twilio-setup** skill.
21
21
 
22
+ ## External Identity
23
+
24
+ When speaking on behalf of your user during calls, 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.
25
+
22
26
  # Overview
23
27
 
24
28
  The calling system uses Twilio's ConversationRelay for both **outbound** and **inbound** voice calls with **ElevenLabs** providing the text-to-speech voice. After Twilio setup, the assistant configures ElevenLabs as the TTS provider and prompts the user to choose a voice from a curated list of supported options.
@@ -80,7 +84,7 @@ After they are verified, ask them what they think of your voice and offer to let
80
84
  Use the `call_start` tool to place outbound calls. Every call requires:
81
85
 
82
86
  - **phone_number**: The number to call in E.164 format (e.g. `+14155551234`)
83
- - **task**: What the call should accomplish this becomes the AI voice agent's objective
87
+ - **task**: What the call should accomplish - this becomes the AI voice agent's objective
84
88
  - **context** (optional): Additional background information for the conversation
85
89
 
86
90
  ### Example calls:
@@ -144,7 +148,7 @@ Once Twilio is configured and the assistant has a phone number, inbound calls wo
144
148
 
145
149
  1. The gateway resolves the assistant by phone number and forwards to the runtime
146
150
  2. A new voice session is created, keyed by the Twilio CallSid
147
- 3. The LLM-driven orchestrator answers in receptionist mode greeting the caller warmly and asking how it can help
151
+ 3. The LLM-driven orchestrator answers in receptionist mode - greeting the caller warmly and asking how it can help
148
152
  4. The conversation proceeds naturally, with ASK_GUARDIAN dispatches to consult the user when needed
149
153
 
150
154
  No additional configuration is needed beyond Twilio setup and `calls.enabled` being `true`. As long as the phone number has been provisioned/assigned, inbound calls are handled automatically.
@@ -185,7 +189,7 @@ The follow-up flow works across all guardian channels. The guardian can receive
185
189
 
186
190
  #### Steering with instructions
187
191
 
188
- When there is **no pending question** but the call is still active, the user can send steering instructions via the HTTP API (`POST /v1/calls/:id/instruction`) to proactively guide the call in real time for example:
192
+ When there is **no pending question** but the call is still active, the user can send steering instructions via the HTTP API (`POST /v1/calls/:id/instruction`) to proactively guide the call in real time - for example:
189
193
 
190
194
  - "Ask them about their cancellation policy too"
191
195
  - "Wrap up the call, we have what we need"
@@ -198,13 +202,13 @@ The instruction is injected into the AI voice agent's conversation context as hi
198
202
 
199
203
  ### Call status values
200
204
 
201
- - **initiated** Call is being placed
202
- - **ringing** Phone is ringing on the other end
203
- - **in_progress** Call is connected, conversation is active
204
- - **waiting_on_user** AI agent needs input from the user (check pending question)
205
- - **completed** Call ended successfully
206
- - **failed** Call failed (check lastError for details)
207
- - **cancelled** Call was manually cancelled
205
+ - **initiated** - Call is being placed
206
+ - **ringing** - Phone is ringing on the other end
207
+ - **in_progress** - Call is connected, conversation is active
208
+ - **waiting_on_user** - AI agent needs input from the user (check pending question)
209
+ - **completed** - Call ended successfully
210
+ - **failed** - Call failed (check lastError for details)
211
+ - **cancelled** - Call was manually cancelled
208
212
 
209
213
  ### Ending a call early
210
214
 
@@ -218,6 +222,6 @@ call_end call_session_id="<session_id>" reason="User requested to end the call"
218
222
 
219
223
  For detailed information on the following topics, see the reference files:
220
224
 
221
- - **[Retrieving Past Call Transcripts](references/TRANSCRIPTS.md)** How to find and query full bidirectional call transcripts from the database
222
- - **[Configuration Reference & Call Quality Tips](references/CONFIG.md)** All call-related config settings, defaults, and tips for writing effective call tasks
223
- - **[Troubleshooting](references/TROUBLESHOOTING.md)** Common error messages, connectivity issues, and debugging steps
225
+ - **[Retrieving Past Call Transcripts](references/TRANSCRIPTS.md)** - How to find and query full bidirectional call transcripts from the database
226
+ - **[Configuration Reference & Call Quality Tips](references/CONFIG.md)** - All call-related config settings, defaults, and tips for writing effective call tasks
227
+ - **[Troubleshooting](references/TROUBLESHOOTING.md)** - Common error messages, connectivity issues, and debugging steps
@@ -26,7 +26,7 @@
26
26
  "enum": ["assistant_number", "user_number"],
27
27
  "description": "Which phone number to use as the caller ID. assistant_number uses the AI assistant's Twilio number; user_number uses the user's verified personal number."
28
28
  },
29
- "reason": {
29
+ "activity": {
30
30
  "type": "string",
31
31
  "description": "Brief non-technical explanation of why this tool is being called"
32
32
  }
@@ -48,7 +48,7 @@
48
48
  "type": "string",
49
49
  "description": "Specific call session ID to check. If omitted, checks for an active call in the current conversation."
50
50
  },
51
- "reason": {
51
+ "activity": {
52
52
  "type": "string",
53
53
  "description": "Brief non-technical explanation of why this tool is being called"
54
54
  }
@@ -74,7 +74,7 @@
74
74
  "type": "string",
75
75
  "description": "Reason for ending the call"
76
76
  },
77
- "reason": {
77
+ "activity": {
78
78
  "type": "string",
79
79
  "description": "Brief non-technical explanation of why this tool is being called"
80
80
  }
@@ -44,13 +44,13 @@ When crafting tasks for the AI voice agent, follow these guidelines for the best
44
44
  ## Writing good task descriptions
45
45
 
46
46
  - **Be specific about the objective**: "Make a dinner reservation for 2 at 7pm tonight" is better than "Call the restaurant"
47
- - **Include relevant context**: Names, account numbers, appointment details anything the agent might need
47
+ - **Include relevant context**: Names, account numbers, appointment details - anything the agent might need
48
48
  - **Specify what information to collect**: "Ask about their return policy and store hours" tells the agent what to gather
49
49
  - **Set clear completion criteria**: The agent knows to end the call when the task is fulfilled
50
50
 
51
51
  ## Providing context
52
52
 
53
- The `context` field is powerful use it to give the agent background that helps it sound natural:
53
+ The `context` field is powerful - use it to give the agent background that helps it sound natural:
54
54
 
55
55
  - User's name and identifying details (for making appointments, verifying accounts)
56
56
  - Preferences and constraints (dietary restrictions, budget limits, scheduling conflicts)
@@ -21,8 +21,8 @@ sqlite3 ~/.vellum/workspace/data/db/assistant.db \
21
21
 
22
22
  This returns all messages in chronological order with:
23
23
 
24
- - `role: "user"` caller speech (prefixed with `[SPEAKER]` tags) and system events
25
- - `role: "assistant"` assistant responses, including `text` content and any `tool_use`/`tool_result` blocks
24
+ - `role: "user"` - caller speech (prefixed with `[SPEAKER]` tags) and system events
25
+ - `role: "assistant"` - assistant responses, including `text` content and any `tool_use`/`tool_result` blocks
26
26
 
27
27
  ## Quick one-liner for the most recent call
28
28
 
@@ -52,7 +52,7 @@ Or re-run the public-ingress skill to auto-detect and save the new URL.
52
52
 
53
53
  ## Call drops after 30 seconds of silence
54
54
 
55
- The system has a 30-second silence timeout. If nobody speaks for 30 seconds during normal conversation, the agent will ask "Are you still there?" This is expected behavior. During guardian wait states (inbound access-request wait or in-call guardian consultation wait), this generic silence nudge is suppressed the guardian-wait heartbeat messaging is used instead.
55
+ The system has a 30-second silence timeout. If nobody speaks for 30 seconds during normal conversation, the agent will ask "Are you still there?" This is expected behavior. During guardian wait states (inbound access-request wait or in-call guardian consultation wait), this generic silence nudge is suppressed - the guardian-wait heartbeat messaging is used instead.
56
56
 
57
57
  ## Call quality sounds off
58
58
 
@@ -34,7 +34,7 @@
34
34
  "type": "number",
35
35
  "description": "Relative priority \u2014 higher numbers take precedence. Defaults to 0."
36
36
  },
37
- "reason": {
37
+ "activity": {
38
38
  "type": "string",
39
39
  "description": "Brief non-technical explanation of why this tool is being called"
40
40
  }
@@ -60,7 +60,7 @@
60
60
  "type": "string",
61
61
  "description": "Filter by category (e.g. \"scheduling\", \"triage\"). Omit to show all."
62
62
  },
63
- "reason": {
63
+ "activity": {
64
64
  "type": "string",
65
65
  "description": "Brief non-technical explanation of why this tool is being called"
66
66
  }
@@ -106,7 +106,7 @@
106
106
  "type": "number",
107
107
  "description": "Updated priority"
108
108
  },
109
- "reason": {
109
+ "activity": {
110
110
  "type": "string",
111
111
  "description": "Brief non-technical explanation of why this tool is being called"
112
112
  }
@@ -128,7 +128,7 @@
128
128
  "type": "string",
129
129
  "description": "ID of the playbook to delete (from playbook_list results)"
130
130
  },
131
- "reason": {
131
+ "activity": {
132
132
  "type": "string",
133
133
  "description": "Brief non-technical explanation of why this tool is being called"
134
134
  }