@vellumai/assistant 0.4.56 → 0.5.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 (457) 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 +204 -185
  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 +249 -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__/file-read-tool.test.ts +40 -0
  67. package/src/__tests__/gateway-only-enforcement.test.ts +2 -2
  68. package/src/__tests__/gateway-only-guard.test.ts +1 -0
  69. package/src/__tests__/gemini-image-service.test.ts +4 -4
  70. package/src/__tests__/gemini-provider.test.ts +6 -9
  71. package/src/__tests__/guardian-binding-drift-heal.test.ts +128 -0
  72. package/src/__tests__/guardian-dispatch.test.ts +0 -1
  73. package/src/__tests__/host-file-read-tool.test.ts +87 -0
  74. package/src/__tests__/host-shell-tool.test.ts +6 -6
  75. package/src/__tests__/http-user-message-parity.test.ts +2 -2
  76. package/src/__tests__/identity-intro-cache.test.ts +209 -0
  77. package/src/__tests__/intent-routing.test.ts +51 -99
  78. package/src/__tests__/invite-routes-http.test.ts +5 -0
  79. package/src/__tests__/list-messages-attachments.test.ts +1 -1
  80. package/src/__tests__/managed-proxy-context.test.ts +2 -5
  81. package/src/__tests__/managed-skill-lifecycle.test.ts +8 -8
  82. package/src/__tests__/media-generate-image.test.ts +32 -15
  83. package/src/__tests__/media-reuse-story.e2e.test.ts +1 -1
  84. package/src/__tests__/memory-context-benchmark.benchmark.test.ts +1 -1
  85. package/src/__tests__/memory-lifecycle-e2e.test.ts +24 -18
  86. package/src/__tests__/memory-recall-quality.test.ts +4 -3
  87. package/src/__tests__/memory-regressions.test.ts +86 -90
  88. package/src/__tests__/migration-cross-version-compatibility.test.ts +32 -32
  89. package/src/__tests__/migration-export-http.test.ts +26 -27
  90. package/src/__tests__/migration-import-commit-http.test.ts +165 -37
  91. package/src/__tests__/migration-import-preflight-http.test.ts +81 -20
  92. package/src/__tests__/migration-validate-http.test.ts +16 -16
  93. package/src/__tests__/model-intents.test.ts +2 -2
  94. package/src/__tests__/no-domain-routing-in-prompt-guard.test.ts +1 -1
  95. package/src/__tests__/non-member-access-request.test.ts +3 -3
  96. package/src/__tests__/notification-broadcaster.test.ts +1 -1
  97. package/src/__tests__/notification-decision-fallback.test.ts +2 -2
  98. package/src/__tests__/notification-decision-identity.test.ts +8 -9
  99. package/src/__tests__/notification-decision-strategy.test.ts +1 -1
  100. package/src/__tests__/notification-deep-link.test.ts +1 -1
  101. package/src/__tests__/notification-guardian-path.test.ts +0 -1
  102. package/src/__tests__/notification-schedule-dedup.test.ts +7 -7
  103. package/src/__tests__/oauth-store.test.ts +1 -3
  104. package/src/__tests__/oauth2-gateway-transport.test.ts +6 -1
  105. package/src/__tests__/onboarding-template-contract.test.ts +23 -59
  106. package/src/__tests__/provider-error-scenarios.test.ts +154 -0
  107. package/src/__tests__/provider-fail-open-selection.test.ts +2 -2
  108. package/src/__tests__/provider-managed-proxy-integration.test.ts +8 -9
  109. package/src/__tests__/provider-registry-ollama.test.ts +5 -2
  110. package/src/__tests__/qdrant-manager.test.ts +7 -7
  111. package/src/__tests__/ratelimit.test.ts +0 -74
  112. package/src/__tests__/recording-handler.test.ts +0 -1
  113. package/src/__tests__/require-fresh-approval.test.ts +1 -1
  114. package/src/__tests__/runtime-attachment-metadata.test.ts +1 -1
  115. package/src/__tests__/runtime-events-sse-parity.test.ts +1 -1
  116. package/src/__tests__/runtime-events-sse.test.ts +1 -1
  117. package/src/__tests__/scheduler-recurrence.test.ts +46 -2
  118. package/src/__tests__/schema-transforms.test.ts +114 -54
  119. package/src/__tests__/secret-onetime-send.test.ts +20 -0
  120. package/src/__tests__/secret-routes-managed-proxy.test.ts +5 -2
  121. package/src/__tests__/secret-scanner-executor.test.ts +1 -2
  122. package/src/__tests__/send-endpoint-busy.test.ts +63 -4
  123. package/src/__tests__/send-notification-tool.test.ts +2 -2
  124. package/src/__tests__/shell-credential-ref.test.ts +0 -1
  125. package/src/__tests__/shell-tool-proxy-mode.test.ts +1 -2
  126. package/src/__tests__/skill-memory.test.ts +549 -0
  127. package/src/__tests__/skill-script-runner-sandbox.test.ts +1 -2
  128. package/src/__tests__/slack-app-setup-skill-regression.test.ts +37 -0
  129. package/src/__tests__/slack-channel-config.test.ts +109 -94
  130. package/src/__tests__/swarm-conversation-integration.test.ts +2 -2
  131. package/src/__tests__/swarm-recursion.test.ts +2 -2
  132. package/src/__tests__/swarm-tool.test.ts +2 -2
  133. package/src/__tests__/system-prompt.test.ts +19 -66
  134. package/src/__tests__/telegram-config.test.ts +121 -0
  135. package/src/__tests__/terminal-tools.test.ts +1 -1
  136. package/src/__tests__/tool-execution-abort-cleanup.test.ts +1 -2
  137. package/src/__tests__/tool-executor-lifecycle-events.test.ts +1 -1
  138. package/src/__tests__/tool-executor-shell-integration.test.ts +1 -1
  139. package/src/__tests__/tool-executor.test.ts +1 -1
  140. package/src/__tests__/trace-emitter.test.ts +8 -1
  141. package/src/__tests__/trust-store.test.ts +7 -8
  142. package/src/__tests__/twilio-routes.test.ts +1 -18
  143. package/src/__tests__/user-reference.test.ts +82 -2
  144. package/src/__tests__/vbundle-pax-and-symlink.test.ts +196 -0
  145. package/src/__tests__/verification-control-plane-policy.test.ts +1 -1
  146. package/src/approvals/guardian-request-resolvers.ts +3 -3
  147. package/src/avatar/ascii-renderer.ts +2 -2
  148. package/src/avatar/png-renderer.ts +2 -2
  149. package/src/avatar/resvg-lazy.ts +21 -0
  150. package/src/calls/guardian-dispatch.ts +1 -1
  151. package/src/calls/relay-access-wait.ts +2 -2
  152. package/src/calls/twilio-rest.ts +0 -248
  153. package/src/cli/AGENTS.md +5 -8
  154. package/src/cli/__tests__/notifications.test.ts +5 -5
  155. package/src/cli/commands/avatar.ts +64 -2
  156. package/src/cli/commands/conversations.ts +131 -1
  157. package/src/cli/commands/credentials.ts +2 -0
  158. package/src/cli/commands/notifications.ts +3 -3
  159. package/src/cli.ts +10 -0
  160. package/src/config/bundled-skills/acp/SKILL.md +5 -5
  161. package/src/config/bundled-skills/acp/TOOLS.json +6 -6
  162. package/src/config/bundled-skills/app-builder/SKILL.md +42 -42
  163. package/src/config/bundled-skills/app-builder/TOOLS.json +10 -10
  164. package/src/config/bundled-skills/browser/SKILL.md +15 -15
  165. package/src/config/bundled-skills/browser/TOOLS.json +14 -14
  166. package/src/config/bundled-skills/chatgpt-import/SKILL.md +2 -2
  167. package/src/config/bundled-skills/chatgpt-import/TOOLS.json +1 -1
  168. package/src/config/bundled-skills/chatgpt-import/tools/chatgpt-import.ts +1 -1
  169. package/src/config/bundled-skills/claude-code/SKILL.md +5 -5
  170. package/src/config/bundled-skills/computer-use/SKILL.md +2 -2
  171. package/src/config/bundled-skills/computer-use/TOOLS.json +15 -15
  172. package/src/config/bundled-skills/contacts/SKILL.md +3 -3
  173. package/src/config/bundled-skills/contacts/TOOLS.json +4 -4
  174. package/src/config/bundled-skills/document/SKILL.md +4 -4
  175. package/src/config/bundled-skills/document/TOOLS.json +2 -2
  176. package/src/config/bundled-skills/followups/TOOLS.json +3 -3
  177. package/src/config/bundled-skills/gmail/SKILL.md +32 -32
  178. package/src/config/bundled-skills/gmail/TOOLS.json +16 -16
  179. package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +1 -1
  180. package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +1 -1
  181. package/src/config/bundled-skills/google-calendar/SKILL.md +1 -1
  182. package/src/config/bundled-skills/google-calendar/TOOLS.json +5 -5
  183. package/src/config/bundled-skills/google-calendar/types.ts +1 -1
  184. package/src/config/bundled-skills/heartbeat/SKILL.md +43 -0
  185. package/src/config/bundled-skills/image-studio/SKILL.md +3 -3
  186. package/src/config/bundled-skills/image-studio/TOOLS.json +2 -3
  187. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +16 -12
  188. package/src/config/bundled-skills/media-processing/SKILL.md +40 -40
  189. package/src/config/bundled-skills/media-processing/TOOLS.json +8 -8
  190. package/src/config/bundled-skills/media-processing/__tests__/concurrency-pool.test.ts +2 -2
  191. package/src/config/bundled-skills/media-processing/__tests__/preprocess.test.ts +1 -1
  192. package/src/config/bundled-skills/media-processing/services/gemini-map.ts +5 -5
  193. package/src/config/bundled-skills/media-processing/services/gemini-video.ts +2 -2
  194. package/src/config/bundled-skills/media-processing/services/preprocess.ts +2 -2
  195. package/src/config/bundled-skills/media-processing/services/processing-pipeline.ts +2 -2
  196. package/src/config/bundled-skills/media-processing/services/reduce.ts +3 -3
  197. package/src/config/bundled-skills/media-processing/tools/generate-clip.ts +2 -2
  198. package/src/config/bundled-skills/media-processing/tools/query-media-events.ts +1 -1
  199. package/src/config/bundled-skills/messaging/SKILL.md +29 -25
  200. package/src/config/bundled-skills/messaging/TOOLS.json +11 -11
  201. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +1 -1
  202. package/src/config/bundled-skills/messaging/tools/shared.ts +1 -1
  203. package/src/config/bundled-skills/notifications/SKILL.md +3 -3
  204. package/src/config/bundled-skills/notifications/TOOLS.json +2 -2
  205. package/src/config/bundled-skills/notifications/tools/send-notification.ts +3 -3
  206. package/src/config/bundled-skills/orchestration/SKILL.md +1 -1
  207. package/src/config/bundled-skills/orchestration/TOOLS.json +1 -1
  208. package/src/config/bundled-skills/phone-calls/SKILL.md +18 -14
  209. package/src/config/bundled-skills/phone-calls/TOOLS.json +3 -3
  210. package/src/config/bundled-skills/phone-calls/references/CONFIG.md +2 -2
  211. package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +2 -2
  212. package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +1 -1
  213. package/src/config/bundled-skills/playbooks/TOOLS.json +4 -4
  214. package/src/config/bundled-skills/schedule/SKILL.md +26 -26
  215. package/src/config/bundled-skills/schedule/TOOLS.json +5 -5
  216. package/src/config/bundled-skills/screen-watch/SKILL.md +3 -3
  217. package/src/config/bundled-skills/screen-watch/TOOLS.json +1 -1
  218. package/src/config/bundled-skills/sequences/SKILL.md +2 -2
  219. package/src/config/bundled-skills/sequences/TOOLS.json +10 -10
  220. package/src/config/bundled-skills/sequences/tools/sequence-analytics.ts +2 -2
  221. package/src/config/bundled-skills/sequences/tools/sequence-enroll.ts +2 -2
  222. package/src/config/bundled-skills/sequences/tools/sequence-enrollment-list.ts +1 -1
  223. package/src/config/bundled-skills/sequences/tools/sequence-get.ts +1 -1
  224. package/src/config/bundled-skills/sequences/tools/sequence-import.ts +3 -3
  225. package/src/config/bundled-skills/sequences/tools/sequence-list.ts +1 -1
  226. package/src/config/bundled-skills/sequences/tools/sequence-update.ts +1 -1
  227. package/src/config/bundled-skills/settings/TOOLS.json +3 -3
  228. package/src/config/bundled-skills/settings/tools/open-system-settings.ts +1 -1
  229. package/src/config/bundled-skills/skill-management/TOOLS.json +5 -5
  230. package/src/config/bundled-skills/skills-catalog/SKILL.md +84 -0
  231. package/src/config/bundled-skills/slack/SKILL.md +2 -2
  232. package/src/config/bundled-skills/slack/TOOLS.json +8 -8
  233. package/src/config/bundled-skills/slack/tools/slack-scan-digest.ts +3 -3
  234. package/src/config/bundled-skills/subagent/TOOLS.json +5 -5
  235. package/src/config/bundled-skills/tasks/SKILL.md +1 -1
  236. package/src/config/bundled-skills/tasks/TOOLS.json +9 -9
  237. package/src/config/bundled-skills/transcribe/SKILL.md +5 -5
  238. package/src/config/bundled-skills/transcribe/TOOLS.json +1 -1
  239. package/src/config/bundled-skills/transcribe/tools/transcribe-media.ts +10 -10
  240. package/src/config/bundled-skills/watcher/SKILL.md +4 -4
  241. package/src/config/bundled-skills/watcher/TOOLS.json +5 -5
  242. package/src/config/feature-flag-registry.json +33 -17
  243. package/src/config/schemas/sandbox.ts +1 -1
  244. package/src/config/schemas/services.ts +13 -3
  245. package/src/config/schemas/timeouts.ts +0 -10
  246. package/src/contacts/contact-store.ts +63 -0
  247. package/src/contacts/contacts-write.ts +1 -1
  248. package/src/daemon/assistant-attachments.ts +2 -2
  249. package/src/daemon/conversation-agent-loop-handlers.ts +2 -2
  250. package/src/daemon/conversation-agent-loop.ts +7 -30
  251. package/src/daemon/conversation-error.ts +24 -0
  252. package/src/daemon/conversation-memory.ts +8 -7
  253. package/src/daemon/conversation-runtime-assembly.ts +141 -275
  254. package/src/daemon/conversation-slash.ts +7 -26
  255. package/src/daemon/conversation-surfaces.ts +14 -0
  256. package/src/daemon/conversation-tool-setup.ts +9 -8
  257. package/src/daemon/conversation.ts +2 -0
  258. package/src/daemon/daemon-control.ts +1 -1
  259. package/src/daemon/date-context.ts +10 -83
  260. package/src/daemon/handlers/config-channels.ts +12 -2
  261. package/src/daemon/handlers/config-slack-channel.ts +7 -1
  262. package/src/daemon/handlers/config-telegram.ts +6 -1
  263. package/src/daemon/handlers/conversations.ts +2 -2
  264. package/src/daemon/handlers/skills.ts +4 -0
  265. package/src/daemon/lifecycle.ts +28 -4
  266. package/src/daemon/providers-setup.ts +1 -1
  267. package/src/daemon/server.ts +1 -5
  268. package/src/daemon/shutdown-handlers.ts +9 -3
  269. package/src/daemon/tool-side-effects.ts +40 -0
  270. package/src/daemon/trace-emitter.ts +26 -2
  271. package/src/events/domain-events.ts +1 -1
  272. package/src/events/tool-permission-telemetry-listener.ts +46 -0
  273. package/src/inbound/platform-callback-registration.ts +0 -18
  274. package/src/media/app-icon-generator.ts +15 -8
  275. package/src/media/avatar-router.ts +15 -8
  276. package/src/media/gemini-image-service.ts +125 -21
  277. package/src/memory/attachments-store.ts +3 -3
  278. package/src/memory/channel-verification-sessions.ts +6 -6
  279. package/src/memory/conversation-crud.ts +196 -1
  280. package/src/memory/{thread-starters-cadence.ts → conversation-starters-cadence.ts} +9 -42
  281. package/src/memory/conversation-title-service.ts +2 -3
  282. package/src/memory/db-init.ts +25 -1
  283. package/src/memory/invite-store.ts +4 -4
  284. package/src/memory/items-extractor.ts +4 -4
  285. package/src/memory/job-handlers/{thread-starters.ts → conversation-starters.ts} +123 -38
  286. package/src/memory/jobs-store.ts +3 -2
  287. package/src/memory/jobs-worker.ts +7 -5
  288. package/src/memory/lifecycle-events-store.ts +63 -0
  289. package/src/memory/migrations/172-rename-created-by-session-id.ts +27 -0
  290. package/src/memory/migrations/173-rename-source-session-id.ts +16 -0
  291. package/src/memory/migrations/174-rename-thread-starters-table.ts +52 -0
  292. package/src/memory/migrations/175-create-lifecycle-events.ts +15 -0
  293. package/src/memory/migrations/176-drop-capability-card-state.ts +36 -0
  294. package/src/memory/migrations/177-create-trace-events-table.ts +40 -0
  295. package/src/memory/migrations/index.ts +6 -0
  296. package/src/memory/migrations/registry.ts +13 -0
  297. package/src/memory/retriever.test.ts +223 -96
  298. package/src/memory/retriever.ts +115 -138
  299. package/src/memory/schema/calls.ts +1 -1
  300. package/src/memory/schema/contacts.ts +1 -1
  301. package/src/memory/schema/infrastructure.ts +29 -0
  302. package/src/memory/schema/memory-core.ts +7 -17
  303. package/src/memory/schema/notifications.ts +1 -1
  304. package/src/memory/search/formatting.ts +23 -6
  305. package/src/memory/search/lexical.ts +2 -0
  306. package/src/memory/search/semantic.ts +2 -0
  307. package/src/memory/search/staleness.ts +5 -1
  308. package/src/memory/search/types.ts +4 -0
  309. package/src/memory/task-memory-cleanup.ts +96 -6
  310. package/src/memory/trace-event-store.ts +148 -0
  311. package/src/notifications/README.md +1 -1
  312. package/src/notifications/decision-engine.ts +45 -4
  313. package/src/notifications/emit-signal.ts +5 -4
  314. package/src/notifications/events-store.ts +4 -4
  315. package/src/notifications/signal.ts +1 -1
  316. package/src/oauth/manual-token-connection.ts +49 -25
  317. package/src/permissions/checker.ts +6 -5
  318. package/src/permissions/defaults.ts +4 -4
  319. package/src/prompts/__tests__/build-cli-reference-section.test.ts +9 -90
  320. package/src/prompts/cache-boundary.ts +8 -0
  321. package/src/prompts/system-prompt.ts +105 -634
  322. package/src/prompts/templates/BOOTSTRAP.md +172 -33
  323. package/src/prompts/templates/IDENTITY.md +8 -24
  324. package/src/prompts/templates/SOUL.md +20 -41
  325. package/src/prompts/templates/USER.md +3 -19
  326. package/src/prompts/user-reference.ts +14 -16
  327. package/src/providers/anthropic/client.ts +51 -19
  328. package/src/providers/gemini/client.ts +6 -9
  329. package/src/providers/managed-proxy/constants.ts +1 -7
  330. package/src/providers/managed-proxy/context.ts +0 -1
  331. package/src/providers/model-intents.ts +5 -5
  332. package/src/providers/openai/client.ts +10 -1
  333. package/src/providers/openrouter/client.ts +1 -0
  334. package/src/providers/ratelimit.ts +0 -35
  335. package/src/providers/registry.ts +3 -5
  336. package/src/providers/retry.ts +18 -1
  337. package/src/runtime/access-request-helper.ts +16 -2
  338. package/src/runtime/auth/route-policy.ts +7 -0
  339. package/src/runtime/channel-verification-service.ts +1 -1
  340. package/src/runtime/confirmation-request-guardian-bridge.ts +1 -1
  341. package/src/runtime/guardian-vellum-migration.ts +61 -1
  342. package/src/runtime/http-server.ts +8 -4
  343. package/src/runtime/migrations/vbundle-builder.ts +212 -32
  344. package/src/runtime/migrations/vbundle-import-analyzer.ts +74 -8
  345. package/src/runtime/migrations/vbundle-importer.ts +66 -1
  346. package/src/runtime/migrations/vbundle-validator.ts +17 -3
  347. package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +4 -4
  348. package/src/runtime/routes/attachment-routes.ts +2 -2
  349. package/src/runtime/routes/btw-routes.ts +93 -0
  350. package/src/runtime/routes/channel-verification-routes.ts +19 -2
  351. package/src/runtime/routes/conversation-management-routes.ts +55 -1
  352. package/src/runtime/routes/conversation-query-routes.ts +1 -1
  353. package/src/runtime/routes/conversation-routes.ts +49 -5
  354. package/src/runtime/routes/conversation-starter-routes.ts +207 -0
  355. package/src/runtime/routes/guardian-bootstrap-routes.ts +13 -9
  356. package/src/runtime/routes/identity-intro-cache.ts +105 -0
  357. package/src/runtime/routes/identity-routes.ts +51 -0
  358. package/src/runtime/routes/inbound-stages/escalation-intercept.ts +1 -1
  359. package/src/runtime/routes/inbound-stages/verification-intercept.ts +1 -1
  360. package/src/runtime/routes/migration-routes.ts +25 -13
  361. package/src/runtime/routes/secret-routes.ts +18 -0
  362. package/src/runtime/routes/settings-routes.ts +9 -9
  363. package/src/runtime/routes/telemetry-routes.ts +53 -0
  364. package/src/runtime/routes/trace-event-routes.ts +62 -0
  365. package/src/runtime/tool-grant-request-helper.ts +1 -1
  366. package/src/runtime/verification-outbound-actions.ts +47 -31
  367. package/src/security/encrypted-store.ts +262 -78
  368. package/src/skills/catalog-install.ts +10 -0
  369. package/src/skills/managed-store.ts +2 -0
  370. package/src/skills/skill-memory.ts +222 -0
  371. package/src/subagent/manager.ts +1 -4
  372. package/src/telemetry/types.ts +10 -1
  373. package/src/telemetry/usage-telemetry-reporter.test.ts +7 -2
  374. package/src/telemetry/usage-telemetry-reporter.ts +53 -4
  375. package/src/tools/AGENTS.md +11 -11
  376. package/src/tools/acp/spawn.ts +1 -1
  377. package/src/tools/apps/executors.ts +8 -8
  378. package/src/tools/apps/registry.ts +1 -1
  379. package/src/tools/assets/materialize.ts +6 -6
  380. package/src/tools/assets/search.ts +10 -10
  381. package/src/tools/browser/__tests__/auth-cache.test.ts +2 -2
  382. package/src/tools/browser/__tests__/auth-detector.test.ts +4 -4
  383. package/src/tools/browser/auth-detector.ts +6 -6
  384. package/src/tools/browser/browser-execution.ts +13 -13
  385. package/src/tools/browser/browser-manager.ts +3 -3
  386. package/src/tools/browser/chrome-cdp.ts +5 -5
  387. package/src/tools/browser/jit-auth.ts +2 -2
  388. package/src/tools/browser/network-recorder.test.ts +2 -2
  389. package/src/tools/browser/network-recorder.ts +3 -3
  390. package/src/tools/browser/runtime-check.ts +3 -3
  391. package/src/tools/claude-code/claude-code.ts +2 -2
  392. package/src/tools/computer-use/definitions.ts +18 -18
  393. package/src/tools/credential-execution/make-authenticated-request.ts +4 -4
  394. package/src/tools/credential-execution/manage-secure-command-tool.ts +3 -3
  395. package/src/tools/credential-execution/run-authenticated-command.ts +4 -4
  396. package/src/tools/credentials/broker-types.ts +5 -5
  397. package/src/tools/credentials/broker.ts +15 -15
  398. package/src/tools/credentials/metadata-store.ts +2 -2
  399. package/src/tools/credentials/resolve.ts +1 -1
  400. package/src/tools/credentials/selection.ts +1 -1
  401. package/src/tools/credentials/tool-policy.ts +1 -1
  402. package/src/tools/credentials/vault.ts +115 -25
  403. package/src/tools/execution-target.ts +2 -2
  404. package/src/tools/executor.ts +7 -7
  405. package/src/tools/filesystem/edit.ts +2 -2
  406. package/src/tools/filesystem/read.ts +15 -4
  407. package/src/tools/filesystem/write.ts +1 -1
  408. package/src/tools/host-filesystem/edit.ts +2 -1
  409. package/src/tools/host-filesystem/read.ts +18 -1
  410. package/src/tools/host-filesystem/write.ts +1 -1
  411. package/src/tools/host-terminal/host-shell.ts +9 -8
  412. package/src/tools/mcp/mcp-tool-factory.ts +7 -6
  413. package/src/tools/memory/definitions.ts +6 -5
  414. package/src/tools/memory/handlers.test.ts +1 -1
  415. package/src/tools/network/__tests__/web-search.test.ts +3 -3
  416. package/src/tools/network/domain-normalize.ts +2 -2
  417. package/src/tools/network/script-proxy/session-manager.ts +10 -10
  418. package/src/tools/network/web-fetch.ts +1 -1
  419. package/src/tools/network/web-search.ts +3 -3
  420. package/src/tools/permission-checker.ts +8 -8
  421. package/src/tools/registry.ts +7 -7
  422. package/src/tools/schedule/list.ts +2 -2
  423. package/src/tools/schema-transforms.ts +31 -21
  424. package/src/tools/secret-detection-handler.ts +1 -1
  425. package/src/tools/sensitive-output-placeholders.ts +1 -1
  426. package/src/tools/shared/filesystem/edit-engine.ts +1 -1
  427. package/src/tools/shared/filesystem/file-ops-service.ts +3 -3
  428. package/src/tools/shared/filesystem/image-read.ts +25 -5
  429. package/src/tools/shared/filesystem/path-policy.ts +2 -2
  430. package/src/tools/shared/shell-output.ts +1 -1
  431. package/src/tools/side-effects.ts +1 -1
  432. package/src/tools/skills/execute.ts +1 -1
  433. package/src/tools/skills/load.ts +3 -3
  434. package/src/tools/skills/sandbox-runner.ts +3 -3
  435. package/src/tools/subagent/read.ts +1 -1
  436. package/src/tools/subagent/spawn.ts +2 -2
  437. package/src/tools/swarm/delegate.ts +3 -3
  438. package/src/tools/system/request-permission.ts +5 -4
  439. package/src/tools/terminal/backends/native.ts +4 -4
  440. package/src/tools/terminal/parser.ts +6 -6
  441. package/src/tools/terminal/sandbox-diagnostics.ts +1 -1
  442. package/src/tools/terminal/shell.ts +16 -16
  443. package/src/tools/tool-approval-handler.ts +21 -12
  444. package/src/tools/tool-manifest.ts +4 -4
  445. package/src/tools/types.ts +3 -3
  446. package/src/tools/ui-surface/definitions.ts +9 -37
  447. package/src/tools/watcher/list.ts +1 -1
  448. package/src/util/logger.ts +7 -2
  449. package/src/util/pricing.ts +4 -0
  450. package/src/util/retry.ts +29 -1
  451. package/src/workspace/migrations/007-web-search-provider-rename.ts +37 -0
  452. package/src/workspace/migrations/registry.ts +2 -0
  453. package/src/__tests__/cli-help-reference-sync.test.ts +0 -26
  454. package/src/__tests__/onboarding-starter-tasks.test.ts +0 -190
  455. package/src/cli/reference.ts +0 -38
  456. package/src/memory/job-handlers/capability-cards.ts +0 -420
  457. package/src/runtime/routes/thread-starter-routes.ts +0 -294
@@ -3,18 +3,18 @@
3
3
  "tools": [
4
4
  {
5
5
  "name": "computer_use_observe",
6
- "description": "Capture the current screen state. Returns the accessibility tree with [ID] element references and optionally a screenshot.\n\nThe accessibility tree shows interactive elements like [3] AXButton 'Save' or [17] AXTextField 'Search'. Use element_id to target these elements in subsequent actions this is much more reliable than pixel coordinates.\n\nCall this before your first computer use action, or to check screen state without acting.",
6
+ "description": "Capture the current screen state. Returns the accessibility tree with [ID] element references and optionally a screenshot.\n\nThe accessibility tree shows interactive elements like [3] AXButton 'Save' or [17] AXTextField 'Search'. Use element_id to target these elements in subsequent actions - this is much more reliable than pixel coordinates.\n\nCall this before your first computer use action, or to check screen state without acting.",
7
7
  "category": "computer-use",
8
8
  "risk": "low",
9
9
  "input_schema": {
10
10
  "type": "object",
11
11
  "properties": {
12
- "reason": {
12
+ "activity": {
13
13
  "type": "string",
14
14
  "description": "Brief non-technical explanation of why this tool is being called"
15
15
  }
16
16
  },
17
- "required": ["reason"]
17
+ "required": ["activity"]
18
18
  },
19
19
  "executor": "tools/computer-use-observe.ts",
20
20
  "execution_target": "host"
@@ -48,7 +48,7 @@
48
48
  "type": "string",
49
49
  "description": "Explanation of what you see and why you are clicking here"
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": "Explanation of what you are typing and why"
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
  }
@@ -100,7 +100,7 @@
100
100
  "type": "string",
101
101
  "description": "Explanation of why you are pressing this key"
102
102
  },
103
- "reason": {
103
+ "activity": {
104
104
  "type": "string",
105
105
  "description": "Brief non-technical explanation of why this tool is being called"
106
106
  }
@@ -143,7 +143,7 @@
143
143
  "type": "string",
144
144
  "description": "Explanation of why you are scrolling"
145
145
  },
146
- "reason": {
146
+ "activity": {
147
147
  "type": "string",
148
148
  "description": "Brief non-technical explanation of why this tool is being called"
149
149
  }
@@ -189,7 +189,7 @@
189
189
  "type": "string",
190
190
  "description": "Explanation of what you are dragging and why"
191
191
  },
192
- "reason": {
192
+ "activity": {
193
193
  "type": "string",
194
194
  "description": "Brief non-technical explanation of why this tool is being called"
195
195
  }
@@ -215,7 +215,7 @@
215
215
  "type": "string",
216
216
  "description": "Explanation of what you are waiting for"
217
217
  },
218
- "reason": {
218
+ "activity": {
219
219
  "type": "string",
220
220
  "description": "Brief non-technical explanation of why this tool is being called"
221
221
  }
@@ -227,7 +227,7 @@
227
227
  },
228
228
  {
229
229
  "name": "computer_use_open_app",
230
- "description": "Open or switch to a macOS application by name. Preferred over cmd+tab for switching apps \u2014 more reliable and explicit.",
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
232
  "risk": "low",
233
233
  "input_schema": {
@@ -241,7 +241,7 @@
241
241
  "type": "string",
242
242
  "description": "Explanation of why you need to open or switch to this app"
243
243
  },
244
- "reason": {
244
+ "activity": {
245
245
  "type": "string",
246
246
  "description": "Brief non-technical explanation of why this tool is being called"
247
247
  }
@@ -253,7 +253,7 @@
253
253
  },
254
254
  {
255
255
  "name": "computer_use_run_applescript",
256
- "description": "Run an AppleScript command. Prefer this over click/type when possible \u2014 it doesn't move the cursor or interrupt the user. Never use 'do shell script' inside AppleScript (blocked for security).",
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
258
  "risk": "low",
259
259
  "input_schema": {
@@ -267,7 +267,7 @@
267
267
  "type": "string",
268
268
  "description": "Explanation of what this script does and why AppleScript is better than UI interaction for this step"
269
269
  },
270
- "reason": {
270
+ "activity": {
271
271
  "type": "string",
272
272
  "description": "Brief non-technical explanation of why this tool is being called"
273
273
  }
@@ -289,7 +289,7 @@
289
289
  "type": "string",
290
290
  "description": "Human-readable summary of what was accomplished"
291
291
  },
292
- "reason": {
292
+ "activity": {
293
293
  "type": "string",
294
294
  "description": "Brief non-technical explanation of why this tool is being called"
295
295
  }
@@ -315,7 +315,7 @@
315
315
  "type": "string",
316
316
  "description": "Explanation of how you determined the answer"
317
317
  },
318
- "reason": {
318
+ "activity": {
319
319
  "type": "string",
320
320
  "description": "Brief non-technical explanation of why this tool is being called"
321
321
  }
@@ -291,7 +291,7 @@ If the user provides a phone number without the `+` country code prefix, ask the
291
291
 
292
292
  ### Create an email invite
293
293
 
294
- Use this when the guardian wants to invite someone to message the assistant via email. Email invites use a 6-digit code the invitee sends the code to the assistant's email address to redeem access.
294
+ Use this when the guardian wants to invite someone to message the assistant via email. Email invites use a 6-digit code - the invitee sends the code to the assistant's email address to redeem access.
295
295
 
296
296
  ```bash
297
297
  assistant contacts invites create --source-channel email --contact-id "<contact_id>" --contact-name "<invitee_name>" --max-uses 1 --note "<optional note, e.g. the person it is for>" --json
@@ -322,7 +322,7 @@ If the assistant's email address is not available (AgentMail not configured), te
322
322
 
323
323
  ### Create a WhatsApp invite
324
324
 
325
- Use this when the guardian wants to invite someone to message the assistant on WhatsApp. WhatsApp invites use a 6-digit code the invitee sends the code to the assistant's WhatsApp number to redeem access.
325
+ Use this when the guardian wants to invite someone to message the assistant on WhatsApp. WhatsApp invites use a 6-digit code - the invitee sends the code to the assistant's WhatsApp number to redeem access.
326
326
 
327
327
  ```bash
328
328
  assistant contacts invites create --source-channel whatsapp --contact-id "<contact_id>" --contact-name "<invitee_name>" --max-uses 1 --note "<optional note, e.g. the person it is for>" --json
@@ -443,7 +443,7 @@ Replace `<invite_id>` with the invite's `id` from the list response. The same re
443
443
 
444
444
  ## Google Contacts
445
445
 
446
- Use `google_contacts` to list or search the user's Google Contacts by name or email. Returns name, email, phone, and organization. Requires the `contacts.readonly` OAuth scope users may need to re-authorize Gmail to grant this additional permission.
446
+ Use `google_contacts` to list or search the user's Google Contacts by name or email. Returns name, email, phone, and organization. Requires the `contacts.readonly` OAuth scope - users may need to re-authorize Gmail to grant this additional permission.
447
447
 
448
448
  ## Contact Fields
449
449
 
@@ -52,7 +52,7 @@
52
52
  "required": ["type", "address"]
53
53
  }
54
54
  },
55
- "reason": {
55
+ "activity": {
56
56
  "type": "string",
57
57
  "description": "Brief non-technical explanation of why this tool is being called"
58
58
  }
@@ -86,7 +86,7 @@
86
86
  "type": "number",
87
87
  "description": "Maximum results to return (default 20, max 100)"
88
88
  },
89
- "reason": {
89
+ "activity": {
90
90
  "type": "string",
91
91
  "description": "Brief non-technical explanation of why this tool is being called"
92
92
  }
@@ -112,7 +112,7 @@
112
112
  "type": "string",
113
113
  "description": "ID of the contact to merge into the kept contact (will be deleted)"
114
114
  },
115
- "reason": {
115
+ "activity": {
116
116
  "type": "string",
117
117
  "description": "Brief non-technical explanation of why this tool is being called"
118
118
  }
@@ -147,7 +147,7 @@
147
147
  "type": "string",
148
148
  "description": "Pagination token (for list)"
149
149
  },
150
- "reason": {
150
+ "activity": {
151
151
  "type": "string",
152
152
  "description": "Brief non-technical explanation of why this tool is being called"
153
153
  },
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: document
3
- description: Write, draft, or compose long-form text (blog posts, articles, essays, reports, guides). Use when the user says write, draft, compose, or create a blog/article/essay.
3
+ description: Write, draft, or compose long-form text (blog posts, articles, essays, reports, guides)
4
4
  compatibility: "Designed for Vellum personal assistants"
5
5
  metadata:
6
6
  emoji: "📄"
@@ -12,14 +12,14 @@ Create and edit long-form documents using the built-in rich text editor. Documen
12
12
 
13
13
  ## Tools
14
14
 
15
- - **document_create** Opens a new document editor with an optional title and initial Markdown content. Returns a `surface_id` for subsequent updates.
16
- - **document_update** Updates content in an open document editor by `surface_id`. Supports `replace` (overwrite) and `append` (add to end) modes.
15
+ - **document_create** - Opens a new document editor with an optional title and initial Markdown content. Returns a `surface_id` for subsequent updates.
16
+ - **document_update** - Updates content in an open document editor by `surface_id`. Supports `replace` (overwrite) and `append` (add to end) modes.
17
17
 
18
18
  ## Workflow
19
19
 
20
20
  1. **Create the document**: Call `document_create` with a title (inferred from the request). Call the tool immediately, not after conversational preamble.
21
21
  2. **Write content in Markdown**: Use proper structure (`#` for titles, `##` for sections), **bold**, *italic*, code blocks, tables, lists, blockquotes as appropriate.
22
- 3. **CRITICAL Stream content in chunks**: Call `document_update` MULTIPLE times, not just once. Break content into logical chunks (paragraphs, sections, or every 200-300 words). Call `document_update` with `mode: "append"` for EACH chunk separately. The user experiences real-time content appearing as you write.
22
+ 3. **CRITICAL - Stream content in chunks**: Call `document_update` MULTIPLE times, not just once. Break content into logical chunks (paragraphs, sections, or every 200-300 words). Call `document_update` with `mode: "append"` for EACH chunk separately. The user experiences real-time content appearing as you write.
23
23
  4. **Respond to edits**: When the user requests changes via the docked chat, use `document_update` with `replace` for full rewrites or `append` for additions.
24
24
 
25
25
  ## Usage Notes
@@ -17,7 +17,7 @@
17
17
  "type": "string",
18
18
  "description": "Initial Markdown content to populate the editor (optional)"
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
  }
@@ -47,7 +47,7 @@
47
47
  "enum": ["replace", "append"],
48
48
  "description": "Whether to replace all content or append to the end. Defaults to append."
49
49
  },
50
- "reason": {
50
+ "activity": {
51
51
  "type": "string",
52
52
  "description": "Brief non-technical explanation of why this tool is being called"
53
53
  }
@@ -29,7 +29,7 @@
29
29
  "type": "string",
30
30
  "description": "Optional recurrence schedule ID to fire a reminder when overdue"
31
31
  },
32
- "reason": {
32
+ "activity": {
33
33
  "type": "string",
34
34
  "description": "Brief non-technical explanation of why this tool is being called"
35
35
  }
@@ -64,7 +64,7 @@
64
64
  "type": "boolean",
65
65
  "description": "When true, return only pending follow-ups past their expected response deadline"
66
66
  },
67
- "reason": {
67
+ "activity": {
68
68
  "type": "string",
69
69
  "description": "Brief non-technical explanation of why this tool is being called"
70
70
  }
@@ -94,7 +94,7 @@
94
94
  "type": "string",
95
95
  "description": "Conversation ID to match (used with channel for auto-resolution)"
96
96
  },
97
- "reason": {
97
+ "activity": {
98
98
  "type": "string",
99
99
  "description": "Brief non-technical explanation of why this tool is being called"
100
100
  }
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: gmail
3
- description: Archive, label, draft, unsubscribe, and manage Gmail with smart inbox tools
3
+ description: Archive, label, draft, unsubscribe, and manage Gmail
4
4
  compatibility: "Designed for Vellum personal assistants"
5
5
  metadata:
6
6
  emoji: "📨"
@@ -8,31 +8,31 @@ metadata:
8
8
  display-name: "Gmail"
9
9
  ---
10
10
 
11
- This skill provides Gmail-specific tools. For cross-platform messaging (send, read, search, reply), use the **messaging** skill. Gmail tools depend on the messaging skill's provider infrastructure load messaging first if Gmail is not yet connected.
11
+ This skill provides Gmail-specific tools. For cross-platform messaging (send, read, search, reply), use the **messaging** skill. Gmail tools depend on the messaging skill's provider infrastructure - load messaging first if Gmail is not yet connected.
12
12
 
13
13
  ## Email Routing Priority
14
14
 
15
- 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.
15
+ 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.
16
16
 
17
- 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.
17
+ 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.
18
18
 
19
19
  ## Communication Style
20
20
 
21
- - **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.
22
- - **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."
21
+ - **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.
22
+ - **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."
23
23
  - **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.
24
- - **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.
24
+ - **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.
25
25
 
26
26
  ## Connection Setup
27
27
 
28
28
  ### Gmail
29
29
 
30
- 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.
30
+ 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.
31
31
  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:
32
32
  - Call `skill_load` with `skill: "google-oauth-applescript"` to load the dependency skill.
33
33
  - 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:
34
34
  - **message:** "Ready to set up Gmail?"
35
- - **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."
35
+ - **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."
36
36
  - **confirmLabel:** "Get Started"
37
37
  - **cancelLabel:** "Not Now"
38
38
  - 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.
@@ -43,7 +43,7 @@ Do not offer AgentMail as an option or mention it unless the user specifically a
43
43
  When a Gmail tool fails with a token or authorization error:
44
44
 
45
45
  1. **Try to reconnect silently.** Call `credential_store` with `action: "oauth2_connect"` and `service: "gmail"`. 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-applescript**). The user came to you to get something done, not to troubleshoot OAuth make it seamless.
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-applescript**). The user came to you to get something done, not to troubleshoot OAuth - make it seamless.
47
47
  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
48
  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
49
 
@@ -59,20 +59,20 @@ When a Gmail tool fails with a token or authorization error:
59
59
 
60
60
  ### Attachments
61
61
 
62
- - **Attachments**: `gmail_attachments` list or download Gmail attachments. Use `action: "list"` to enumerate attachments on a message (returns filename, MIME type, size, and attachment ID), then `action: "download"` with `attachment_id` and `filename` to save a specific attachment to disk.
63
- - **Send with Attachments**: `messaging_send` with `attachment_paths` create a Gmail draft with file attachments (reads files from disk, builds multipart MIME)
62
+ - **Attachments**: `gmail_attachments` - list or download Gmail attachments. Use `action: "list"` to enumerate attachments on a message (returns filename, MIME type, size, and attachment ID), then `action: "download"` with `attachment_id` and `filename` to save a specific attachment to disk.
63
+ - **Send with Attachments**: `messaging_send` with `attachment_paths` - create a Gmail draft with file attachments (reads files from disk, builds multipart MIME)
64
64
 
65
65
  Workflow: use `gmail_attachments` with `action: "list"` to discover attachments, then `gmail_attachments` with `action: "download"` to save them locally.
66
66
 
67
67
  ### Forward & Thread Operations
68
68
 
69
- - **Forward**: `gmail_forward` forward a message to another recipient, preserving all attachments. Optionally prepend your own text
70
- - **Follow-up Tracking**: `gmail_follow_up` track/untrack messages for follow-up using a dedicated "Follow-up" label, or list all tracked messages
69
+ - **Forward**: `gmail_forward` - forward a message to another recipient, preserving all attachments. Optionally prepend your own text
70
+ - **Follow-up Tracking**: `gmail_follow_up` - track/untrack messages for follow-up using a dedicated "Follow-up" label, or list all tracked messages
71
71
 
72
72
  ### Inbox Automation
73
73
 
74
- - **Filters**: `gmail_filters` list, create, or delete Gmail filters. Filter criteria include from, to, subject, query, has_attachment. Actions include adding/removing labels and forwarding
75
- - **Vacation Responder**: `gmail_vacation` get, enable, or disable the vacation auto-responder with custom message, date range, and domain/contact restrictions
74
+ - **Filters**: `gmail_filters` - list, create, or delete Gmail filters. Filter criteria include from, to, subject, query, has_attachment. Actions include adding/removing labels and forwarding
75
+ - **Vacation Responder**: `gmail_vacation` - get, enable, or disable the vacation auto-responder with custom message, date range, and domain/contact restrictions
76
76
 
77
77
  ## Drafting vs Sending (Gmail)
78
78
 
@@ -92,7 +92,7 @@ Gmail uses a **draft-first workflow**. All compose and reply tools create Gmail
92
92
 
93
93
  When replying to or continuing an email thread:
94
94
 
95
- - Use `messaging_send` with the thread's `thread_id` it automatically handles threading, reply-all recipients, and subject lines.
95
+ - Use `messaging_send` with the thread's `thread_id` - it automatically handles threading, reply-all recipients, and subject lines.
96
96
  - The `in_reply_to` field on `gmail_draft` requires the **RFC 822 Message-ID header** (looks like `<CABx...@mail.gmail.com>`), NOT the Gmail message ID (which looks like `18e4a5b2c3d4e5f6`). Get it by reading the thread messages and extracting the `Message-ID` header.
97
97
 
98
98
  ## Gmail Search Syntax
@@ -112,9 +112,9 @@ When searching Gmail, the query uses Gmail's search operators:
112
112
 
113
113
  ## Email Decluttering
114
114
 
115
- When a user asks to declutter, clean up, or organize their email start scanning immediately. Don't ask what kind of cleanup they want or request permission to read their inbox. Go straight to scanning but once results are ready, always show them via `ui_show` and let the user choose actions before archiving or unsubscribing.
115
+ When a user asks to declutter, clean up, or organize their email - start scanning immediately. Don't ask what kind of cleanup they want or request permission to read their inbox. Go straight to scanning - but once results are ready, always show them via `ui_show` and let the user choose actions before archiving or unsubscribing.
116
116
 
117
- **CRITICAL**: Never call `gmail_archive`, `gmail_unsubscribe`, or `messaging_archive_by_sender` unless the user has clicked an action button on the table for that specific batch. Each batch of results requires its own explicit user confirmation via the table UI. If the user says "keep going" or "keep decluttering," that means scan and present a new table NOT auto-archive. Previous batch approvals do not carry forward, but **deselections DO carry forward**: when the user deselects senders from a cleanup table, the system records those deselections as user preferences. Before building the next cleanup table, check `<dynamic-user-profile>` for previously deselected senders and exclude them from future cleanup tables the user already indicated they want to keep those.
117
+ **CRITICAL**: Never call `gmail_archive`, `gmail_unsubscribe`, or `messaging_archive_by_sender` unless the user has clicked an action button on the table for that specific batch. Each batch of results requires its own explicit user confirmation via the table UI. If the user says "keep going" or "keep decluttering," that means scan and present a new table - NOT auto-archive. Previous batch approvals do not carry forward, but **deselections DO carry forward**: when the user deselects senders from a cleanup table, the system records those deselections as user preferences. Before building the next cleanup table, check `<dynamic-user-profile>` for previously deselected senders and exclude them from future cleanup tables - the user already indicated they want to keep those.
118
118
 
119
119
  ### Workflow
120
120
 
@@ -122,17 +122,17 @@ When a user asks to declutter, clean up, or organize their email — start scann
122
122
  2. **Present**: Show results as a `ui_show` table with `selectionMode: "multiple"`:
123
123
  - **Columns (exactly 3)**: Sender, Emails Found, Unsub?
124
124
  - **Unsub? cell values**: Use rich cell format: `{ "text": "Yes", "icon": "checkmark.circle.fill", "iconColor": "success" }` when `has_unsubscribe` is true, `{ "text": "No", "icon": "minus.circle", "iconColor": "muted" }` when false.
125
- - **Pre-select all rows** (`selected: true`) users deselect what they want to keep
126
- - **Caption**: Include two parts separated by a newline: (1) data scope, e.g. "Newsletters, notifications, and outreach from last 90 days. Deselect anything you want to keep." (adjusted to match the query used), and (2) the Unsub? column legend: "Unsub? \"Yes\" means these emails contain an unsubscribe link, so I can opt you out automatically. \"No\" means no unsubscribe link was found these will be archived but you may continue receiving them."
125
+ - **Pre-select all rows** (`selected: true`) - users deselect what they want to keep
126
+ - **Caption**: Include two parts separated by a newline: (1) data scope, e.g. "Newsletters, notifications, and outreach from last 90 days. Deselect anything you want to keep." (adjusted to match the query used), and (2) the Unsub? column legend: "Unsub? - \"Yes\" means these emails contain an unsubscribe link, so I can opt you out automatically. \"No\" means no unsubscribe link was found - these will be archived but you may continue receiving them."
127
127
  - **Action buttons (exactly 2)**: "Archive & Unsubscribe" (primary), "Archive Only" (secondary). **NEVER offer Delete, Trash, or any destructive action.**
128
128
  3. **Wait for user action**: Stop and wait. Do NOT proceed to archiving or unsubscribing until the user clicks one of the action buttons on the table. When the user clicks an action button:
129
- - **Dismiss the table immediately** with `ui_dismiss` it collapses to a completion chip
129
+ - **Dismiss the table immediately** with `ui_dismiss` - it collapses to a completion chip
130
130
  - **Show a `task_progress` card** with steps for each phase (e.g., "Archiving 89 senders (2,400 emails)", "Unsubscribing from 72 senders"). Update each step from `in_progress` → `completed` as each phase finishes.
131
131
  - When all senders are processed, set the progress card's `status: "completed"`.
132
- 4. **Act on selection** batch, don't loop:
133
- - **Archive all at once**: Call `gmail_archive` **once** with `scan_id` + **all** selected senders' `id` values in the `sender_ids` array. The tool resolves message IDs server-side and batches the Gmail API calls internally never loop sender-by-sender.
134
- - **Unsubscribe in bulk**: If the action is "Archive & Unsubscribe", call `gmail_unsubscribe` for each sender that has `has_unsubscribe: true` but emit **all** unsubscribe tool calls in a **single assistant response** (parallel tool use) rather than one-at-a-time across separate turns.
135
- 5. **Accurate summary**: The scan counts are exact the `message_count` shown in the table matches the number of messages archived. Format: "Cleaned up [total_archived] emails from [sender_count] senders. Unsubscribed from [unsub_count]."
132
+ 4. **Act on selection** - batch, don't loop:
133
+ - **Archive all at once**: Call `gmail_archive` **once** with `scan_id` + **all** selected senders' `id` values in the `sender_ids` array. The tool resolves message IDs server-side and batches the Gmail API calls internally - never loop sender-by-sender.
134
+ - **Unsubscribe in bulk**: If the action is "Archive & Unsubscribe", call `gmail_unsubscribe` for each sender that has `has_unsubscribe: true` - but emit **all** unsubscribe tool calls in a **single assistant response** (parallel tool use) rather than one-at-a-time across separate turns.
135
+ 5. **Accurate summary**: The scan counts are exact - the `message_count` shown in the table matches the number of messages archived. Format: "Cleaned up [total_archived] emails from [sender_count] senders. Unsubscribed from [unsub_count]."
136
136
  6. **Ongoing protection offer**: After reporting results, offer auto-archive filters:
137
137
  - "Want me to set up auto-archive filters so future emails from these senders skip your inbox?"
138
138
  - If yes, call `gmail_filters` with `action: "create"` for each sender with `from` set to the sender's email and `remove_label_ids: ["INBOX"]`.
@@ -142,21 +142,21 @@ When a user asks to declutter, clean up, or organize their email — start scann
142
142
 
143
143
  - **Zero results**: Tell the user "No newsletter emails found" and suggest broadening the query (e.g. removing the category filter or extending the date range)
144
144
  - **Unsubscribe failures**: Report per-sender success/failure; the existing `gmail_unsubscribe` tool handles edge cases
145
- - **Truncation handling**: The scan covers up to 5,000 messages by default (cap 10,000). If `truncated` is true, the top senders are still captured don't offer to scan more. Tell the user: "Scanned [N] messages here are your top senders."
146
- - **Time budget exceeded**: If the scan returns `time_budget_exceeded: true`, present whatever results were collected. Do not retry or continue the partial results are useful as-is.
145
+ - **Truncation handling**: The scan covers up to 5,000 messages by default (cap 10,000). If `truncated` is true, the top senders are still captured - don't offer to scan more. Tell the user: "Scanned [N] messages - here are your top senders."
146
+ - **Time budget exceeded**: If the scan returns `time_budget_exceeded: true`, present whatever results were collected. Do not retry or continue - the partial results are useful as-is.
147
147
 
148
148
  ## Scan ID
149
149
 
150
- Scan tools (`gmail_sender_digest`, `gmail_outreach_scan`) return a `scan_id` that references message IDs stored server-side. This keeps thousands of message IDs out of the conversation context. `gmail_outreach_scan` is a pure data aggregation tool it finds senders without List-Unsubscribe headers (potential cold outreach) and does not use LLM classification.
150
+ Scan tools (`gmail_sender_digest`, `gmail_outreach_scan`) return a `scan_id` that references message IDs stored server-side. This keeps thousands of message IDs out of the conversation context. `gmail_outreach_scan` is a pure data aggregation tool - it finds senders without List-Unsubscribe headers (potential cold outreach) and does not use LLM classification.
151
151
 
152
152
  - Pass `scan_id` + `sender_ids` to `gmail_archive` instead of `message_ids`
153
- - Scan results expire after **30 minutes** if archiving fails with an expiration error, re-run the scan
153
+ - Scan results expire after **30 minutes** - if archiving fails with an expiration error, re-run the scan
154
154
  - Raw `message_ids` still work as a fallback for non-scan workflows
155
155
 
156
156
  ## Batch Operations
157
157
 
158
158
  - `gmail_archive` supports `scan_id` + `sender_ids` (preferred for declutter workflows) or raw `message_ids`.
159
- - `gmail_label` supports `message_id` or `message_ids` only it does not accept `scan_id`.
159
+ - `gmail_label` supports `message_id` or `message_ids` only - it does not accept `scan_id`.
160
160
  - First scan to get a `scan_id`, then use `gmail_archive` to batch-archive by sender.
161
161
  - Always confirm with the user before batch operations on large numbers of messages.
162
162
 
@@ -164,7 +164,7 @@ Scan tools (`gmail_sender_digest`, `gmail_outreach_scan`) return a `scan_id` tha
164
164
 
165
165
  Before composing any email that references a date or time:
166
166
 
167
- 1. Check the `<temporal_context>` block in the current turn for today's date and upcoming dates
167
+ 1. Check the `<temporal_context>` block in the current turn for today's date and timezone
168
168
  2. Verify that "tomorrow" means the day after today's date, "next week" means the upcoming Monday–Friday, etc.
169
169
  3. If the email references a date from another message, cross-check it against the temporal context to ensure it's in the future
170
170
 
@@ -39,7 +39,7 @@
39
39
  "type": "number",
40
40
  "description": "Confidence score (0-1) for this action"
41
41
  },
42
- "reason": {
42
+ "activity": {
43
43
  "type": "string",
44
44
  "description": "Brief non-technical explanation of why this tool is being called"
45
45
  },
@@ -90,7 +90,7 @@
90
90
  "type": "number",
91
91
  "description": "Confidence score (0-1) for this action"
92
92
  },
93
- "reason": {
93
+ "activity": {
94
94
  "type": "string",
95
95
  "description": "Brief non-technical explanation of why this tool is being called"
96
96
  },
@@ -120,7 +120,7 @@
120
120
  "type": "number",
121
121
  "description": "Confidence score (0-1) for this action"
122
122
  },
123
- "reason": {
123
+ "activity": {
124
124
  "type": "string",
125
125
  "description": "Brief non-technical explanation of why this tool is being called"
126
126
  },
@@ -150,7 +150,7 @@
150
150
  "type": "number",
151
151
  "description": "Confidence score (0-1) for this action"
152
152
  },
153
- "reason": {
153
+ "activity": {
154
154
  "type": "string",
155
155
  "description": "Brief non-technical explanation of why this tool is being called"
156
156
  },
@@ -196,7 +196,7 @@
196
196
  "type": "string",
197
197
  "description": "BCC recipients (comma-separated email addresses)"
198
198
  },
199
- "reason": {
199
+ "activity": {
200
200
  "type": "string",
201
201
  "description": "Brief non-technical explanation of why this tool is being called"
202
202
  },
@@ -226,7 +226,7 @@
226
226
  "type": "number",
227
227
  "description": "Confidence score (0-1) for this action"
228
228
  },
229
- "reason": {
229
+ "activity": {
230
230
  "type": "string",
231
231
  "description": "Brief non-technical explanation of why this tool is being called"
232
232
  },
@@ -265,7 +265,7 @@
265
265
  "type": "string",
266
266
  "description": "Filename to save as (required for download)"
267
267
  },
268
- "reason": {
268
+ "activity": {
269
269
  "type": "string",
270
270
  "description": "Brief non-technical explanation of why this tool is being called"
271
271
  },
@@ -303,7 +303,7 @@
303
303
  "type": "number",
304
304
  "description": "Confidence score (0-1) for this action"
305
305
  },
306
- "reason": {
306
+ "activity": {
307
307
  "type": "string",
308
308
  "description": "Brief non-technical explanation of why this tool is being called"
309
309
  },
@@ -338,7 +338,7 @@
338
338
  "type": "number",
339
339
  "description": "Confidence score (0-1) for this action"
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
  },
@@ -411,7 +411,7 @@
411
411
  "type": "number",
412
412
  "description": "Confidence score (0-1) for this action"
413
413
  },
414
- "reason": {
414
+ "activity": {
415
415
  "type": "string",
416
416
  "description": "Brief non-technical explanation of why this tool is being called"
417
417
  },
@@ -466,7 +466,7 @@
466
466
  "type": "number",
467
467
  "description": "Confidence score (0-1) for this action"
468
468
  },
469
- "reason": {
469
+ "activity": {
470
470
  "type": "string",
471
471
  "description": "Brief non-technical explanation of why this tool is being called"
472
472
  },
@@ -502,9 +502,9 @@
502
502
  },
503
503
  "page_token": {
504
504
  "type": "string",
505
- "description": "Resume token from a previous scan (rarely needed scans now cover up to 10,000 messages in a single call)"
505
+ "description": "Resume token from a previous scan (rarely needed - scans now cover up to 10,000 messages in a single call)"
506
506
  },
507
- "reason": {
507
+ "activity": {
508
508
  "type": "string",
509
509
  "description": "Brief non-technical explanation of why this tool is being called"
510
510
  },
@@ -519,7 +519,7 @@
519
519
  },
520
520
  {
521
521
  "name": "gmail_outreach_scan",
522
- "description": "Scan Gmail inbox for senders without List-Unsubscribe headers (potential cold outreach). Returns top senders with message counts and sample subjects. Read-only use gmail_archive and gmail_filters for cleanup.",
522
+ "description": "Scan Gmail inbox for senders without List-Unsubscribe headers (potential cold outreach). Returns top senders with message counts and sample subjects. Read-only - use gmail_archive and gmail_filters for cleanup.",
523
523
  "category": "gmail",
524
524
  "risk": "low",
525
525
  "input_schema": {
@@ -539,9 +539,9 @@
539
539
  },
540
540
  "page_token": {
541
541
  "type": "string",
542
- "description": "Resume token from a previous scan (rarely needed scans now cover up to 5,000 messages in a single call)"
542
+ "description": "Resume token from a previous scan (rarely needed - scans now cover up to 5,000 messages in a single call)"
543
543
  },
544
- "reason": {
544
+ "activity": {
545
545
  "type": "string",
546
546
  "description": "Brief non-technical explanation of why this tool is being called"
547
547
  },
@@ -124,7 +124,7 @@ export async function run(
124
124
 
125
125
  // Batch path for scan_id+sender_ids and message_ids
126
126
  if (!messageIds?.length) {
127
- return err("Resolved message list is empty no messages to archive.");
127
+ return err("Resolved message list is empty - no messages to archive.");
128
128
  }
129
129
 
130
130
  try {
@@ -171,7 +171,7 @@ export async function run(
171
171
  agg.hasMore = true;
172
172
  }
173
173
 
174
- // Track date range compare using internalDate (epoch ms) for reliability
174
+ // Track date range - compare using internalDate (epoch ms) for reliability
175
175
  const msgEpoch = msg.internalDate ? Number(msg.internalDate) : 0;
176
176
  const oldestEpoch = agg.oldestDate
177
177
  ? new Date(agg.oldestDate).getTime()
@@ -17,7 +17,7 @@ Before using any Calendar tool, verify that Google Calendar is connected by atte
17
17
  1. **Do NOT call `credential_store oauth2_connect` yourself.** You do not have valid OAuth client credentials, and fabricating a client_id will cause a "401: invalid_client" error from Google.
18
18
  2. Instead, load the **google-oauth-applescript** skill, which walks the user through creating real credentials in Google Cloud Console:
19
19
  - Call `skill_load` with `skill: "google-oauth-applescript"` to load the dependency skill.
20
- 3. Tell the user: _"Google Calendar isn't connected yet. I've loaded a setup guide that will walk you through connecting your Google account it only takes a couple of minutes."_
20
+ 3. Tell the user: _"Google Calendar isn't connected yet. I've loaded a setup guide that will walk you through connecting your Google account - it only takes a couple of minutes."_
21
21
 
22
22
  ## Capabilities
23
23