@vellumai/assistant 0.4.44 → 0.4.45

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 (681) hide show
  1. package/.prettierignore +4 -0
  2. package/ARCHITECTURE.md +34 -31
  3. package/README.md +4 -4
  4. package/bun.lock +10 -35
  5. package/docs/architecture/integrations.md +102 -197
  6. package/docs/architecture/keychain-broker.md +1 -1
  7. package/docs/architecture/memory.md +2 -2
  8. package/docs/architecture/scheduling.md +1 -1
  9. package/docs/architecture/security.md +11 -11
  10. package/docs/error-handling.md +1 -1
  11. package/docs/trusted-contact-access.md +3 -3
  12. package/drizzle/meta/0000_snapshot.json +34 -100
  13. package/drizzle/meta/_journal.json +1 -1
  14. package/drizzle.config.ts +4 -4
  15. package/package.json +3 -2
  16. package/scripts/capture-x-graphql.ts +237 -141
  17. package/scripts/generate-bundled-tool-registry.ts +223 -0
  18. package/src/__tests__/access-request-decision.test.ts +0 -1
  19. package/src/__tests__/actor-token-service.test.ts +23 -24
  20. package/src/__tests__/agent-loop.test.ts +0 -131
  21. package/src/__tests__/always-loaded-tools-guard.test.ts +71 -0
  22. package/src/__tests__/amazon-cdp-integration.test.ts +11 -9
  23. package/src/__tests__/approval-primitive.test.ts +0 -1
  24. package/src/__tests__/approval-routes-http.test.ts +11 -1
  25. package/src/__tests__/asset-materialize-tool.test.ts +0 -1
  26. package/src/__tests__/asset-search-tool.test.ts +0 -1
  27. package/src/__tests__/assistant-attachment-directive.test.ts +1 -1
  28. package/src/__tests__/assistant-events-sse-hardening.test.ts +0 -1
  29. package/src/__tests__/assistant-feature-flag-guardrails.test.ts +0 -2
  30. package/src/__tests__/assistant-feature-flags-integration.test.ts +70 -18
  31. package/src/__tests__/assistant-id-boundary-guard.test.ts +6 -6
  32. package/src/__tests__/attachments-store.test.ts +0 -1
  33. package/src/__tests__/avatar-e2e.test.ts +74 -115
  34. package/src/__tests__/avatar-router.test.ts +25 -62
  35. package/src/__tests__/browser-manager.test.ts +24 -0
  36. package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +4 -3
  37. package/src/__tests__/browser-skill-endstate.test.ts +8 -11
  38. package/src/__tests__/btw-routes.test.ts +326 -0
  39. package/src/__tests__/bundled-skill-retrieval-guard.test.ts +23 -9
  40. package/src/__tests__/call-controller.test.ts +0 -1
  41. package/src/__tests__/call-conversation-messages.test.ts +0 -1
  42. package/src/__tests__/call-domain.test.ts +0 -1
  43. package/src/__tests__/call-pointer-messages.test.ts +0 -1
  44. package/src/__tests__/call-recovery.test.ts +0 -1
  45. package/src/__tests__/call-routes-http.test.ts +0 -1
  46. package/src/__tests__/call-store.test.ts +0 -1
  47. package/src/__tests__/canonical-guardian-store.test.ts +0 -1
  48. package/src/__tests__/channel-approval-routes.test.ts +1 -1
  49. package/src/__tests__/channel-approvals.test.ts +1 -1
  50. package/src/__tests__/channel-delivery-store.test.ts +0 -1
  51. package/src/__tests__/channel-guardian.test.ts +5 -7
  52. package/src/__tests__/channel-retry-sweep.test.ts +0 -1
  53. package/src/__tests__/checker.test.ts +4 -11
  54. package/src/__tests__/compaction.benchmark.test.ts +16 -14
  55. package/src/__tests__/computer-use-session-lifecycle.test.ts +10 -11
  56. package/src/__tests__/computer-use-session-working-dir.test.ts +2 -6
  57. package/src/__tests__/computer-use-skill-lifecycle-cleanup.test.ts +2 -5
  58. package/src/__tests__/computer-use-tools.test.ts +35 -31
  59. package/src/__tests__/config-schema.test.ts +11 -15
  60. package/src/__tests__/config-watcher.test.ts +0 -1
  61. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -1
  62. package/src/__tests__/conflict-store.test.ts +0 -1
  63. package/src/__tests__/connection-policy.test.ts +4 -7
  64. package/src/__tests__/contacts-tools.test.ts +0 -1
  65. package/src/__tests__/context-memory-e2e.test.ts +2 -4
  66. package/src/__tests__/context-overflow-reducer.test.ts +2 -4
  67. package/src/__tests__/context-window-manager.test.ts +147 -60
  68. package/src/__tests__/contradiction-checker.test.ts +0 -1
  69. package/src/__tests__/conversation-attention-store.test.ts +0 -1
  70. package/src/__tests__/conversation-attention-telegram.test.ts +1 -1
  71. package/src/__tests__/conversation-pairing.test.ts +2 -2
  72. package/src/__tests__/conversation-routes-guardian-reply.test.ts +25 -1
  73. package/src/__tests__/conversation-routes-slash-commands.test.ts +381 -0
  74. package/src/__tests__/conversation-store.test.ts +0 -1
  75. package/src/__tests__/conversation-unread-route.test.ts +1 -2
  76. package/src/__tests__/credential-security-invariants.test.ts +7 -8
  77. package/src/__tests__/cross-provider-web-search.test.ts +353 -0
  78. package/src/__tests__/daemon-assistant-events.test.ts +6 -7
  79. package/src/__tests__/db-schedule-syntax-migration.test.ts +15 -3
  80. package/src/__tests__/delete-managed-skill-tool.test.ts +5 -9
  81. package/src/__tests__/deterministic-verification-control-plane.test.ts +0 -1
  82. package/src/__tests__/diagnostics-export.test.ts +189 -0
  83. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +0 -1
  84. package/src/__tests__/emit-signal-routing-intent.test.ts +3 -3
  85. package/src/__tests__/entity-extractor.test.ts +0 -1
  86. package/src/__tests__/entity-search.test.ts +0 -1
  87. package/src/__tests__/ephemeral-permissions.test.ts +2 -4
  88. package/src/__tests__/file-read-tool.test.ts +86 -0
  89. package/src/__tests__/followup-tools.test.ts +0 -1
  90. package/src/__tests__/frontmatter.test.ts +77 -34
  91. package/src/__tests__/gateway-only-enforcement.test.ts +0 -1
  92. package/src/__tests__/gateway-only-guard.test.ts +1 -1
  93. package/src/__tests__/guardian-action-conversation-turn.test.ts +0 -1
  94. package/src/__tests__/guardian-action-followup-executor.test.ts +0 -1
  95. package/src/__tests__/guardian-action-followup-store.test.ts +0 -1
  96. package/src/__tests__/guardian-action-grant-mint-consume.test.ts +0 -1
  97. package/src/__tests__/guardian-action-late-reply.test.ts +0 -1
  98. package/src/__tests__/guardian-action-store.test.ts +0 -1
  99. package/src/__tests__/guardian-action-sweep.test.ts +0 -1
  100. package/src/__tests__/guardian-decision-primitive-canonical.test.ts +0 -1
  101. package/src/__tests__/guardian-dispatch.test.ts +1 -2
  102. package/src/__tests__/guardian-grant-minting.test.ts +1 -1
  103. package/src/__tests__/guardian-outbound-http.test.ts +0 -1
  104. package/src/__tests__/guardian-principal-id-roundtrip.test.ts +0 -1
  105. package/src/__tests__/guardian-routing-invariants.test.ts +1 -1
  106. package/src/__tests__/guardian-routing-state.test.ts +0 -1
  107. package/src/__tests__/guardian-verification-voice-binding.test.ts +0 -1
  108. package/src/__tests__/guardian-verify-setup-skill-regression.test.ts +3 -5
  109. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +28 -426
  110. package/src/__tests__/host-bash-proxy.test.ts +335 -0
  111. package/src/__tests__/host-file-proxy.test.ts +374 -0
  112. package/src/__tests__/host-shell-tool.test.ts +147 -1
  113. package/src/__tests__/http-user-message-parity.test.ts +361 -0
  114. package/src/__tests__/inbound-invite-redemption.test.ts +0 -1
  115. package/src/__tests__/integration-status.test.ts +3 -8
  116. package/src/__tests__/intent-routing.test.ts +7 -46
  117. package/src/__tests__/invite-redemption-service.test.ts +0 -1
  118. package/src/__tests__/invite-routes-http.test.ts +0 -1
  119. package/src/__tests__/llm-usage-store.test.ts +0 -1
  120. package/src/__tests__/managed-avatar-client.test.ts +101 -55
  121. package/src/__tests__/managed-skill-lifecycle.test.ts +9 -18
  122. package/src/__tests__/managed-store.test.ts +94 -21
  123. package/src/__tests__/media-reuse-story.e2e.test.ts +0 -1
  124. package/src/__tests__/memory-context-benchmark.benchmark.test.ts +2 -4
  125. package/src/__tests__/memory-lifecycle-e2e.test.ts +0 -1
  126. package/src/__tests__/memory-recall-quality.test.ts +0 -1
  127. package/src/__tests__/memory-regressions.experimental.test.ts +0 -1
  128. package/src/__tests__/memory-regressions.test.ts +0 -1
  129. package/src/__tests__/memory-retrieval.benchmark.test.ts +0 -1
  130. package/src/__tests__/memory-upsert-concurrency.test.ts +0 -1
  131. package/src/__tests__/messaging-send-tool.test.ts +35 -0
  132. package/src/__tests__/messaging-skill-split.test.ts +138 -0
  133. package/src/__tests__/migration-cross-version-compatibility.test.ts +0 -1
  134. package/src/__tests__/migration-export-http.test.ts +2 -3
  135. package/src/__tests__/migration-import-commit-http.test.ts +1 -2
  136. package/src/__tests__/migration-import-preflight-http.test.ts +1 -2
  137. package/src/__tests__/migration-validate-http.test.ts +1 -2
  138. package/src/__tests__/native-web-search.test.ts +475 -0
  139. package/src/__tests__/navigate-settings-tab.test.ts +84 -0
  140. package/src/__tests__/non-member-access-request.test.ts +0 -1
  141. package/src/__tests__/notification-broadcaster.test.ts +15 -15
  142. package/src/__tests__/notification-decision-strategy.test.ts +6 -6
  143. package/src/__tests__/notification-deep-link.test.ts +7 -7
  144. package/src/__tests__/notification-guardian-path.test.ts +2 -3
  145. package/src/__tests__/notification-telegram-adapter.test.ts +1 -1
  146. package/src/__tests__/notification-thread-candidates.test.ts +4 -4
  147. package/src/__tests__/onboarding-starter-tasks.test.ts +0 -1
  148. package/src/__tests__/playbook-execution.test.ts +0 -1
  149. package/src/__tests__/playbook-tools.test.ts +0 -1
  150. package/src/__tests__/profile-compiler.test.ts +0 -1
  151. package/src/__tests__/provider-managed-proxy-integration.test.ts +25 -0
  152. package/src/__tests__/qdrant-collection-migration.test.ts +223 -0
  153. package/src/__tests__/recording-handler.test.ts +30 -94
  154. package/src/__tests__/registry.test.ts +28 -35
  155. package/src/__tests__/relay-server.test.ts +0 -1
  156. package/src/__tests__/ride-shotgun-handler.test.ts +4 -20
  157. package/src/__tests__/runtime-attachment-metadata.test.ts +0 -1
  158. package/src/__tests__/runtime-events-sse-parity.test.ts +3 -4
  159. package/src/__tests__/runtime-events-sse.test.ts +0 -1
  160. package/src/__tests__/sandbox-diagnostics.test.ts +0 -1
  161. package/src/__tests__/scaffold-managed-skill-tool.test.ts +30 -28
  162. package/src/__tests__/schedule-store.test.ts +441 -1
  163. package/src/__tests__/schedule-tools.test.ts +468 -7
  164. package/src/__tests__/scheduler-recurrence.test.ts +196 -23
  165. package/src/__tests__/scoped-approval-grants.test.ts +0 -1
  166. package/src/__tests__/scoped-grant-security-matrix.test.ts +0 -1
  167. package/src/__tests__/secret-prompt-log-hygiene.test.ts +6 -3
  168. package/src/__tests__/secret-response-routing.test.ts +4 -1
  169. package/src/__tests__/send-endpoint-busy.test.ts +14 -2
  170. package/src/__tests__/send-notification-tool.test.ts +0 -7
  171. package/src/__tests__/sequence-store.test.ts +0 -1
  172. package/src/__tests__/server-history-render.test.ts +1 -2
  173. package/src/__tests__/session-abort-tool-results.test.ts +0 -1
  174. package/src/__tests__/session-agent-loop.test.ts +46 -6
  175. package/src/__tests__/session-confirmation-signals.test.ts +0 -1
  176. package/src/__tests__/session-conflict-gate.test.ts +2 -6
  177. package/src/__tests__/session-error.test.ts +5 -14
  178. package/src/__tests__/session-init.benchmark.test.ts +3 -5
  179. package/src/__tests__/session-load-history-repair.test.ts +0 -1
  180. package/src/__tests__/session-media-retry.test.ts +12 -74
  181. package/src/__tests__/session-pre-run-repair.test.ts +0 -1
  182. package/src/__tests__/session-profile-injection.test.ts +2 -6
  183. package/src/__tests__/session-provider-retry-repair.test.ts +2 -6
  184. package/src/__tests__/session-queue.test.ts +94 -139
  185. package/src/__tests__/session-skill-tools.test.ts +115 -115
  186. package/src/__tests__/session-slash-known.test.ts +0 -1
  187. package/src/__tests__/session-slash-queue.test.ts +0 -1
  188. package/src/__tests__/session-slash-unknown.test.ts +0 -1
  189. package/src/__tests__/session-surfaces-task-progress.test.ts +34 -0
  190. package/src/__tests__/session-usage.test.ts +0 -1
  191. package/src/__tests__/session-workspace-cache-state.test.ts +2 -6
  192. package/src/__tests__/session-workspace-injection.test.ts +2 -6
  193. package/src/__tests__/session-workspace-tool-tracking.test.ts +2 -6
  194. package/src/__tests__/skill-feature-flags-integration.test.ts +180 -184
  195. package/src/__tests__/skill-feature-flags.test.ts +125 -18
  196. package/src/__tests__/skill-load-feature-flag.test.ts +1 -2
  197. package/src/__tests__/skill-load-tool.test.ts +194 -2
  198. package/src/__tests__/skill-projection-feature-flag.test.ts +27 -16
  199. package/src/__tests__/skill-projection.benchmark.test.ts +15 -14
  200. package/src/__tests__/skills.test.ts +14 -53
  201. package/src/__tests__/slack-channel-config.test.ts +0 -1
  202. package/src/__tests__/slack-inbound-verification.test.ts +0 -1
  203. package/src/__tests__/slack-skill.test.ts +1 -1
  204. package/src/__tests__/subagent-tools.test.ts +2 -2
  205. package/src/__tests__/system-prompt.test.ts +4 -3
  206. package/src/__tests__/task-compiler.test.ts +0 -1
  207. package/src/__tests__/task-management-tools.test.ts +0 -1
  208. package/src/__tests__/task-memory-cleanup.test.ts +0 -1
  209. package/src/__tests__/task-runner.test.ts +0 -1
  210. package/src/__tests__/task-scheduler.test.ts +0 -1
  211. package/src/__tests__/terminal-tools.test.ts +0 -1
  212. package/src/__tests__/test-support/computer-use-skill-harness.ts +2 -4
  213. package/src/__tests__/thread-seed-composer.test.ts +5 -5
  214. package/src/__tests__/tool-approval-handler.test.ts +0 -1
  215. package/src/__tests__/tool-execution-abort-cleanup.test.ts +0 -1
  216. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +0 -1
  217. package/src/__tests__/tool-executor.test.ts +8 -86
  218. package/src/__tests__/tool-grant-request-escalation.test.ts +0 -1
  219. package/src/__tests__/tool-notification-listener.test.ts +1 -1
  220. package/src/__tests__/tool-preview-lifecycle.test.ts +416 -0
  221. package/src/__tests__/trust-store.test.ts +80 -4
  222. package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
  223. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +0 -1
  224. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +0 -1
  225. package/src/__tests__/trusted-contact-multichannel.test.ts +0 -1
  226. package/src/__tests__/trusted-contact-verification.test.ts +0 -1
  227. package/src/__tests__/twilio-provider.test.ts +0 -1
  228. package/src/__tests__/twilio-routes.test.ts +0 -1
  229. package/src/__tests__/{request-file-tool.test.ts → ui-file-upload-surface.test.ts} +11 -72
  230. package/src/__tests__/update-bulletin.test.ts +0 -1
  231. package/src/__tests__/usage-cache-backfill-migration.test.ts +0 -1
  232. package/src/__tests__/usage-routes.test.ts +0 -1
  233. package/src/__tests__/verification-control-plane-policy.test.ts +4 -4
  234. package/src/__tests__/voice-invite-redemption.test.ts +0 -1
  235. package/src/__tests__/voice-scoped-grant-consumer.test.ts +0 -1
  236. package/src/__tests__/voice-session-bridge.test.ts +9 -1
  237. package/src/__tests__/web-fetch.test.ts +57 -0
  238. package/src/__tests__/workspace-git-service.test.ts +5 -14
  239. package/src/__tests__/workspace-policy.test.ts +0 -1
  240. package/src/agent/loop.ts +22 -34
  241. package/src/bundler/bundle-signer.ts +4 -4
  242. package/src/calls/call-controller.ts +1 -1
  243. package/src/calls/relay-server.ts +1 -1
  244. package/src/calls/twilio-rest.ts +1 -1
  245. package/src/calls/voice-session-bridge.ts +3 -1
  246. package/src/cli/__tests__/notifications.test.ts +3 -4
  247. package/src/cli/commands/map.ts +2 -6
  248. package/src/cli/commands/mcp.ts +73 -15
  249. package/src/cli/commands/notifications.ts +4 -4
  250. package/src/cli/commands/sessions.ts +9 -1
  251. package/src/cli/commands/skills.ts +6 -10
  252. package/src/cli/http-client.ts +2 -3
  253. package/src/cli/main-screen.tsx +10 -10
  254. package/src/cli/program.ts +0 -4
  255. package/src/cli/reference.ts +0 -2
  256. package/src/cli.ts +15 -9
  257. package/src/config/__tests__/bundled-tool-registry-guard.test.ts +120 -0
  258. package/src/config/bundled-skills/_shared/CLI_RETRIEVAL_PATTERN.md +11 -0
  259. package/src/config/bundled-skills/app-builder/SKILL.md +6 -1
  260. package/src/config/bundled-skills/browser/SKILL.md +6 -1
  261. package/src/config/bundled-skills/chatgpt-import/SKILL.md +5 -1
  262. package/src/config/bundled-skills/claude-code/SKILL.md +5 -1
  263. package/src/config/bundled-skills/computer-use/SKILL.md +6 -1
  264. package/src/config/bundled-skills/computer-use/TOOLS.json +6 -69
  265. package/src/config/bundled-skills/computer-use/tools/computer-use-click.ts +10 -1
  266. package/src/config/bundled-skills/contacts/SKILL.md +10 -1
  267. package/src/config/bundled-skills/contacts/TOOLS.json +35 -0
  268. package/src/config/bundled-skills/{messaging → contacts}/tools/google-contacts.ts +9 -2
  269. package/src/config/bundled-skills/document/SKILL.md +4 -1
  270. package/src/config/bundled-skills/doordash/SKILL.md +8 -1
  271. package/src/config/bundled-skills/doordash/lib/shared/platform.ts +4 -1
  272. package/src/config/bundled-skills/followups/SKILL.md +4 -1
  273. package/src/config/bundled-skills/gmail/SKILL.md +180 -0
  274. package/src/config/bundled-skills/gmail/TOOLS.json +506 -0
  275. package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +149 -0
  276. package/src/config/bundled-skills/gmail/tools/gmail-attachments.ts +110 -0
  277. package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-draft.ts +1 -1
  278. package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-filters.ts +1 -1
  279. package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-follow-up.ts +1 -1
  280. package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-forward.ts +1 -1
  281. package/src/config/bundled-skills/gmail/tools/gmail-label.ts +50 -0
  282. package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-outreach-scan.ts +8 -90
  283. package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-send-draft.ts +1 -1
  284. package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-sender-digest.ts +2 -2
  285. package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-trash.ts +1 -1
  286. package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-unsubscribe.ts +1 -1
  287. package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-vacation.ts +1 -1
  288. package/src/config/bundled-skills/gmail/tools/shared.ts +47 -0
  289. package/src/config/bundled-skills/google-calendar/SKILL.md +5 -1
  290. package/src/config/bundled-skills/image-studio/SKILL.md +5 -1
  291. package/src/config/bundled-skills/knowledge-graph/SKILL.md +4 -1
  292. package/src/config/bundled-skills/media-processing/SKILL.md +7 -13
  293. package/src/config/bundled-skills/media-processing/TOOLS.json +0 -22
  294. package/src/config/bundled-skills/media-processing/tools/generate-clip.ts +12 -1
  295. package/src/config/bundled-skills/messaging/SKILL.md +23 -139
  296. package/src/config/bundled-skills/messaging/TOOLS.json +33 -1215
  297. package/src/config/bundled-skills/messaging/tools/gmail-mime-helpers.ts +42 -0
  298. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +165 -2
  299. package/src/config/bundled-skills/messaging/tools/messaging-sender-digest.ts +1 -13
  300. package/src/config/bundled-skills/messaging/tools/shared.ts +81 -34
  301. package/src/config/bundled-skills/notifications/SKILL.md +5 -1
  302. package/src/config/bundled-skills/orchestration/SKILL.md +30 -0
  303. package/src/config/bundled-skills/orchestration/TOOLS.json +35 -0
  304. package/src/config/bundled-skills/{reminder/tools/reminder-create.ts → orchestration/tools/swarm-delegate.ts} +3 -3
  305. package/src/config/bundled-skills/phone-calls/SKILL.md +9 -1
  306. package/src/config/bundled-skills/playbooks/SKILL.md +4 -1
  307. package/src/config/bundled-skills/schedule/SKILL.md +70 -9
  308. package/src/config/bundled-skills/schedule/TOOLS.json +38 -6
  309. package/src/config/bundled-skills/screen-watch/SKILL.md +28 -0
  310. package/src/config/bundled-skills/screen-watch/TOOLS.json +35 -0
  311. package/src/config/bundled-skills/{reminder/tools/reminder-cancel.ts → screen-watch/tools/start-screen-watch.ts} +3 -3
  312. package/src/config/bundled-skills/sequences/SKILL.md +47 -0
  313. package/src/config/bundled-skills/sequences/TOOLS.json +340 -0
  314. package/src/config/bundled-skills/sequences/tools/sequence-update.ts +128 -0
  315. package/src/config/bundled-skills/sequences/tools/shared.ts +9 -0
  316. package/src/config/bundled-skills/settings/SKILL.md +12 -0
  317. package/src/config/bundled-skills/settings/TOOLS.json +112 -0
  318. package/src/config/bundled-skills/settings/tools/navigate-settings-tab.ts +43 -0
  319. package/src/config/bundled-skills/settings/tools/open-system-settings.ts +52 -0
  320. package/src/config/bundled-skills/{computer-use/tools/computer-use-right-click.ts → settings/tools/set-avatar.ts} +2 -6
  321. package/src/{tools/system/voice-config.ts → config/bundled-skills/settings/tools/voice-config-update.ts} +59 -96
  322. package/src/config/bundled-skills/skill-management/SKILL.md +18 -0
  323. package/src/config/bundled-skills/skill-management/TOOLS.json +90 -0
  324. package/src/config/bundled-skills/{computer-use/tools/computer-use-double-click.ts → skill-management/tools/delete-managed.ts} +2 -6
  325. package/src/config/bundled-skills/skill-management/tools/scaffold-managed.ts +12 -0
  326. package/src/config/bundled-skills/slack/SKILL.md +5 -1
  327. package/src/config/bundled-skills/subagent/SKILL.md +4 -1
  328. package/src/config/bundled-skills/tasks/SKILL.md +5 -2
  329. package/src/config/bundled-skills/transcribe/SKILL.md +4 -1
  330. package/src/config/bundled-skills/watcher/SKILL.md +4 -1
  331. package/src/config/bundled-tool-registry.ts +118 -107
  332. package/src/config/env.ts +5 -2
  333. package/src/config/feature-flag-registry.json +25 -9
  334. package/src/config/loader.ts +10 -2
  335. package/src/config/schema.ts +19 -16
  336. package/src/config/schemas/inference.ts +12 -22
  337. package/src/config/schemas/memory-storage.ts +19 -1
  338. package/src/config/schemas/platform.ts +0 -16
  339. package/src/config/skill-state.ts +11 -8
  340. package/src/config/skills.ts +83 -32
  341. package/src/context/token-estimator.ts +11 -0
  342. package/src/context/window-manager.ts +180 -151
  343. package/src/daemon/computer-use-session.ts +11 -43
  344. package/src/daemon/daemon-control.ts +4 -1
  345. package/src/daemon/handlers/config-channels.ts +5 -9
  346. package/src/daemon/handlers/config-ingress.ts +0 -4
  347. package/src/daemon/handlers/config-model.ts +7 -13
  348. package/src/daemon/handlers/config-telegram.ts +4 -8
  349. package/src/daemon/handlers/config-voice.ts +2 -5
  350. package/src/daemon/handlers/dictation.ts +2 -12
  351. package/src/daemon/handlers/identity.ts +0 -105
  352. package/src/daemon/handlers/recording.ts +3 -23
  353. package/src/daemon/handlers/session-history.ts +1 -1
  354. package/src/daemon/handlers/sessions.ts +53 -72
  355. package/src/daemon/handlers/shared.ts +7 -28
  356. package/src/daemon/handlers/skills.ts +31 -27
  357. package/src/daemon/host-bash-proxy.ts +148 -0
  358. package/src/daemon/host-file-proxy.ts +135 -0
  359. package/src/daemon/lifecycle.ts +49 -24
  360. package/src/daemon/mcp-reload-service.ts +123 -0
  361. package/src/daemon/message-protocol.ts +6 -0
  362. package/src/daemon/message-types/browser.ts +1 -1
  363. package/src/daemon/message-types/computer-use.ts +1 -4
  364. package/src/daemon/message-types/guardian-actions.ts +1 -1
  365. package/src/daemon/message-types/host-bash.ts +18 -0
  366. package/src/daemon/message-types/host-file.ts +44 -0
  367. package/src/daemon/message-types/integrations.ts +1 -67
  368. package/src/daemon/message-types/messages.ts +15 -0
  369. package/src/daemon/message-types/schedules.ts +11 -27
  370. package/src/daemon/message-types/sessions.ts +2 -1
  371. package/src/daemon/message-types/settings.ts +1 -1
  372. package/src/daemon/message-types/shared.ts +1 -1
  373. package/src/daemon/ride-shotgun-handler.ts +2 -42
  374. package/src/daemon/server.ts +43 -10
  375. package/src/daemon/session-agent-loop-handlers.ts +48 -7
  376. package/src/daemon/session-agent-loop.ts +97 -66
  377. package/src/daemon/session-attachments.ts +1 -1
  378. package/src/daemon/session-error.ts +17 -16
  379. package/src/daemon/session-lifecycle.ts +20 -1
  380. package/src/daemon/session-media-retry.ts +1 -15
  381. package/src/daemon/session-messaging.ts +14 -6
  382. package/src/daemon/session-process.ts +36 -7
  383. package/src/daemon/session-queue-manager.ts +62 -103
  384. package/src/daemon/session-runtime-assembly.ts +27 -0
  385. package/src/daemon/session-skill-tools.ts +12 -11
  386. package/src/daemon/session-slash.ts +7 -0
  387. package/src/daemon/session-surfaces.ts +19 -97
  388. package/src/daemon/session-tool-setup.ts +146 -6
  389. package/src/daemon/session.ts +77 -13
  390. package/src/errors.ts +0 -2
  391. package/src/export/formatter.ts +6 -0
  392. package/src/mcp/mcp-oauth-provider.ts +1 -3
  393. package/src/media/avatar-router.ts +20 -28
  394. package/src/media/avatar-types.ts +7 -14
  395. package/src/media/managed-avatar-client.ts +70 -34
  396. package/src/memory/conversation-title-service.ts +1 -2
  397. package/src/memory/db-init.ts +16 -0
  398. package/src/memory/embedding-backend.ts +129 -27
  399. package/src/memory/embedding-gemini.test.ts +256 -0
  400. package/src/memory/embedding-gemini.ts +47 -13
  401. package/src/memory/embedding-local.ts +14 -2
  402. package/src/memory/embedding-ollama.ts +15 -2
  403. package/src/memory/embedding-openai.ts +15 -2
  404. package/src/memory/embedding-types.test.ts +116 -0
  405. package/src/memory/embedding-types.ts +61 -0
  406. package/src/memory/fingerprint.ts +1 -1
  407. package/src/memory/indexer.ts +25 -1
  408. package/src/memory/job-handlers/embedding.test.ts +258 -0
  409. package/src/memory/job-handlers/embedding.ts +81 -1
  410. package/src/memory/job-handlers/index-maintenance.ts +35 -1
  411. package/src/memory/job-handlers/media-processing.ts +11 -1
  412. package/src/memory/job-utils.ts +21 -6
  413. package/src/memory/jobs-store.ts +5 -1
  414. package/src/memory/jobs-worker.ts +8 -0
  415. package/src/memory/message-content.ts +66 -0
  416. package/src/memory/migrations/100-core-tables.ts +1 -31
  417. package/src/memory/migrations/104-core-indexes.ts +0 -11
  418. package/src/memory/migrations/145-drop-accounts-table.ts +19 -0
  419. package/src/memory/migrations/146-schedule-oneshot-routing.ts +94 -0
  420. package/src/memory/migrations/147-migrate-reminders-to-schedules.ts +129 -0
  421. package/src/memory/migrations/148-drop-reminders-table.ts +18 -0
  422. package/src/memory/migrations/index.ts +4 -0
  423. package/src/memory/migrations/registry.ts +19 -0
  424. package/src/memory/qdrant-client.ts +158 -43
  425. package/src/memory/retriever.test.ts +0 -1
  426. package/src/memory/retriever.ts +12 -2
  427. package/src/memory/schema/infrastructure.ts +5 -29
  428. package/src/memory/search/formatting.ts +34 -9
  429. package/src/memory/search/semantic.ts +57 -2
  430. package/src/memory/search/types.ts +2 -1
  431. package/src/notifications/AGENTS.md +2 -2
  432. package/src/notifications/README.md +59 -58
  433. package/src/notifications/adapters/macos.ts +1 -1
  434. package/src/notifications/broadcaster.ts +5 -5
  435. package/src/notifications/copy-composer.ts +1 -1
  436. package/src/notifications/decision-engine.ts +2 -2
  437. package/src/notifications/destination-resolver.ts +2 -2
  438. package/src/notifications/emit-signal.ts +8 -8
  439. package/src/notifications/signal.ts +1 -1
  440. package/src/notifications/thread-seed-composer.ts +1 -1
  441. package/src/oauth/connect-orchestrator.ts +1 -1
  442. package/src/oauth/token-persistence.ts +1 -1
  443. package/src/permissions/checker.ts +12 -1
  444. package/src/permissions/defaults.ts +10 -14
  445. package/src/permissions/trust-store.ts +37 -0
  446. package/src/permissions/workspace-policy.ts +0 -1
  447. package/src/prompts/__tests__/build-cli-reference-section.test.ts +11 -0
  448. package/src/prompts/computer-use-prompt.ts +1 -1
  449. package/src/prompts/system-prompt.ts +29 -30
  450. package/src/prompts/templates/SOUL.md +1 -2
  451. package/src/prompts/templates/UPDATES.md +16 -7
  452. package/src/providers/anthropic/client.ts +87 -33
  453. package/src/providers/gemini/client.ts +6 -0
  454. package/src/providers/managed-proxy/constants.ts +5 -0
  455. package/src/providers/openai/client.ts +15 -0
  456. package/src/providers/registry.ts +2 -2
  457. package/src/providers/types.ts +24 -2
  458. package/src/runtime/AGENTS.md +18 -0
  459. package/src/runtime/assistant-event-hub.ts +2 -3
  460. package/src/runtime/assistant-event.ts +4 -4
  461. package/src/runtime/auth/__tests__/context.test.ts +5 -5
  462. package/src/runtime/auth/__tests__/credential-service.test.ts +0 -1
  463. package/src/runtime/auth/__tests__/guard-tests.test.ts +2 -2
  464. package/src/runtime/auth/__tests__/{ipc-auth-context.test.ts → local-auth-context.test.ts} +21 -21
  465. package/src/runtime/auth/__tests__/route-policy.test.ts +2 -2
  466. package/src/runtime/auth/__tests__/scopes.test.ts +7 -7
  467. package/src/runtime/auth/__tests__/subject.test.ts +8 -8
  468. package/src/runtime/auth/__tests__/token-service.test.ts +0 -1
  469. package/src/runtime/auth/route-policy.ts +8 -4
  470. package/src/runtime/auth/scopes.ts +1 -1
  471. package/src/runtime/auth/subject.ts +4 -4
  472. package/src/runtime/auth/token-service.ts +0 -23
  473. package/src/runtime/auth/types.ts +3 -3
  474. package/src/runtime/guardian-action-followup-executor.ts +1 -1
  475. package/src/runtime/guardian-action-grant-minter.ts +1 -1
  476. package/src/runtime/guardian-action-service.ts +3 -3
  477. package/src/runtime/http-server.ts +15 -2
  478. package/src/runtime/invite-service.ts +3 -3
  479. package/src/runtime/local-actor-identity.ts +17 -22
  480. package/src/runtime/pending-interactions.ts +21 -9
  481. package/src/runtime/routes/app-management-routes.ts +2 -3
  482. package/src/runtime/routes/approval-routes.ts +1 -3
  483. package/src/runtime/routes/btw-routes.ts +155 -0
  484. package/src/runtime/routes/computer-use-routes.ts +77 -31
  485. package/src/runtime/routes/conversation-routes.ts +230 -46
  486. package/src/runtime/routes/diagnostics-routes.ts +63 -29
  487. package/src/runtime/routes/documents-routes.ts +2 -2
  488. package/src/runtime/routes/global-search-routes.ts +1 -1
  489. package/src/runtime/routes/host-bash-routes.ts +83 -0
  490. package/src/runtime/routes/host-file-routes.ts +79 -0
  491. package/src/runtime/routes/integrations/slack/share.ts +1 -1
  492. package/src/runtime/routes/log-export-routes.ts +120 -0
  493. package/src/runtime/routes/mcp-routes.ts +20 -0
  494. package/src/runtime/routes/migration-routes.ts +3 -3
  495. package/src/runtime/routes/pairing-routes.ts +1 -1
  496. package/src/runtime/routes/recording-routes.ts +6 -4
  497. package/src/runtime/routes/schedule-routes.ts +31 -5
  498. package/src/runtime/routes/session-management-routes.ts +2 -6
  499. package/src/runtime/routes/session-query-routes.ts +18 -15
  500. package/src/runtime/routes/settings-routes.ts +7 -261
  501. package/src/runtime/routes/skills-routes.ts +7 -6
  502. package/src/runtime/routes/subagents-routes.ts +4 -10
  503. package/src/runtime/routes/surface-action-routes.ts +3 -14
  504. package/src/runtime/routes/surface-content-routes.ts +22 -5
  505. package/src/runtime/routes/work-items-routes.ts +21 -25
  506. package/src/runtime/routes/workspace-routes.test.ts +3 -3
  507. package/src/runtime/routes/workspace-utils.ts +1 -1
  508. package/src/runtime/telegram-streaming-delivery.ts +3 -0
  509. package/src/runtime/verification-outbound-actions.ts +2 -2
  510. package/src/schedule/integration-status.ts +0 -6
  511. package/src/schedule/schedule-store.ts +234 -43
  512. package/src/schedule/scheduler.ts +73 -74
  513. package/src/security/oauth2.ts +1 -1
  514. package/src/sequence/store.ts +12 -2
  515. package/src/skills/frontmatter.ts +19 -77
  516. package/src/skills/managed-store.ts +11 -2
  517. package/src/subagent/manager.ts +5 -3
  518. package/src/tasks/ephemeral-permissions.ts +3 -5
  519. package/src/tools/AGENTS.md +0 -1
  520. package/src/tools/browser/browser-manager.ts +17 -11
  521. package/src/tools/browser/jit-auth.ts +4 -1
  522. package/src/tools/claude-code/claude-code.ts +1 -1
  523. package/src/tools/computer-use/definitions.ts +48 -60
  524. package/src/tools/document/document-tool.ts +6 -6
  525. package/src/tools/filesystem/edit.ts +2 -1
  526. package/src/tools/filesystem/read.ts +20 -2
  527. package/src/tools/filesystem/write.ts +2 -1
  528. package/src/tools/host-filesystem/edit.ts +17 -1
  529. package/src/tools/host-filesystem/read.ts +16 -1
  530. package/src/tools/host-filesystem/write.ts +15 -1
  531. package/src/tools/host-terminal/host-shell.ts +24 -0
  532. package/src/tools/memory/definitions.ts +45 -81
  533. package/src/tools/memory/handlers.test.ts +0 -1
  534. package/src/tools/memory/handlers.ts +1 -1
  535. package/src/tools/memory/register.ts +26 -60
  536. package/src/tools/network/script-proxy/session-manager.ts +6 -8
  537. package/src/tools/network/web-fetch.ts +7 -1
  538. package/src/tools/network/web-search.ts +2 -1
  539. package/src/tools/registry.ts +23 -0
  540. package/src/tools/schedule/create.ts +113 -5
  541. package/src/tools/schedule/list.ts +57 -15
  542. package/src/tools/schedule/update.ts +73 -3
  543. package/src/tools/shared/filesystem/image-read.ts +192 -0
  544. package/src/tools/side-effects.ts +1 -7
  545. package/src/tools/skills/delete-managed.ts +27 -64
  546. package/src/tools/skills/execute.ts +54 -0
  547. package/src/tools/skills/load.ts +127 -5
  548. package/src/tools/skills/scaffold-managed.ts +93 -172
  549. package/src/tools/subagent/message.ts +0 -7
  550. package/src/tools/subagent/spawn.ts +1 -1
  551. package/src/tools/swarm/delegate.ts +0 -3
  552. package/src/tools/system/avatar-generator.ts +13 -19
  553. package/src/tools/system/request-permission.ts +2 -1
  554. package/src/tools/terminal/safe-env.ts +1 -0
  555. package/src/tools/tool-manifest.ts +41 -47
  556. package/src/tools/types.ts +6 -2
  557. package/src/tools/ui-surface/definitions.ts +0 -55
  558. package/src/util/errors.ts +0 -10
  559. package/src/workspace/git-service.ts +0 -2
  560. package/src/__tests__/account-registry.test.ts +0 -258
  561. package/src/__tests__/email-classifier.test.ts +0 -25
  562. package/src/__tests__/gmail-integration.test.ts +0 -97
  563. package/src/__tests__/handle-user-message-secret-resume.test.ts +0 -172
  564. package/src/__tests__/managed-twitter-guardrails.test.ts +0 -357
  565. package/src/__tests__/recording-intent-fallback.test.ts +0 -199
  566. package/src/__tests__/recording-intent.test.ts +0 -985
  567. package/src/__tests__/recording-state-machine.test.ts +0 -1574
  568. package/src/__tests__/reminder-store.test.ts +0 -350
  569. package/src/__tests__/reminder.test.ts +0 -337
  570. package/src/__tests__/scan-result-store.test.ts +0 -121
  571. package/src/__tests__/twitter-platform-proxy-client.test.ts +0 -475
  572. package/src/__tests__/view-image-tool.test.ts +0 -241
  573. package/src/cli/commands/amazon/cart.ts +0 -513
  574. package/src/cli/commands/amazon/checkout.ts +0 -394
  575. package/src/cli/commands/amazon/client.ts +0 -513
  576. package/src/cli/commands/amazon/index.ts +0 -885
  577. package/src/cli/commands/amazon/product-details.ts +0 -145
  578. package/src/cli/commands/amazon/request-extractor.ts +0 -187
  579. package/src/cli/commands/amazon/search.ts +0 -76
  580. package/src/cli/commands/amazon/session.ts +0 -108
  581. package/src/cli/commands/twitter/__tests__/cli-read-routing.test.ts +0 -345
  582. package/src/cli/commands/twitter/__tests__/cli-routing.test.ts +0 -252
  583. package/src/cli/commands/twitter/__tests__/oauth-client.test.ts +0 -151
  584. package/src/cli/commands/twitter/index.ts +0 -420
  585. package/src/cli/commands/twitter/oauth-client.ts +0 -60
  586. package/src/cli/commands/twitter/router.ts +0 -351
  587. package/src/cli/commands/twitter/types.ts +0 -30
  588. package/src/config/bundled-skills/agentmail/SKILL.md +0 -132
  589. package/src/config/bundled-skills/agentmail/icon.svg +0 -21
  590. package/src/config/bundled-skills/amazon/SKILL.md +0 -136
  591. package/src/config/bundled-skills/amazon/icon.svg +0 -13
  592. package/src/config/bundled-skills/api-mapping/SKILL.md +0 -78
  593. package/src/config/bundled-skills/api-mapping/icon.svg +0 -18
  594. package/src/config/bundled-skills/cli-discover/SKILL.md +0 -68
  595. package/src/config/bundled-skills/deploy-fullstack-vercel/SKILL.md +0 -179
  596. package/src/config/bundled-skills/document-writer/SKILL.md +0 -195
  597. package/src/config/bundled-skills/elevenlabs-voice/SKILL.md +0 -140
  598. package/src/config/bundled-skills/email-setup/SKILL.md +0 -68
  599. package/src/config/bundled-skills/frontend-design/SKILL.md +0 -44
  600. package/src/config/bundled-skills/frontend-design/icon.svg +0 -16
  601. package/src/config/bundled-skills/google-oauth-setup/SKILL.md +0 -452
  602. package/src/config/bundled-skills/guardian-verify-setup/SKILL.md +0 -203
  603. package/src/config/bundled-skills/influencer/SKILL.md +0 -144
  604. package/src/config/bundled-skills/influencer/scripts/client.ts +0 -1269
  605. package/src/config/bundled-skills/influencer/scripts/influencer.ts +0 -267
  606. package/src/config/bundled-skills/macos-automation/SKILL.md +0 -65
  607. package/src/config/bundled-skills/macos-automation/icon.svg +0 -12
  608. package/src/config/bundled-skills/mcp-setup/SKILL.md +0 -75
  609. package/src/config/bundled-skills/media-processing/tools/media-diagnostics.ts +0 -184
  610. package/src/config/bundled-skills/messaging/tools/gmail-archive-by-query.ts +0 -80
  611. package/src/config/bundled-skills/messaging/tools/gmail-archive.ts +0 -29
  612. package/src/config/bundled-skills/messaging/tools/gmail-batch-archive.ts +0 -56
  613. package/src/config/bundled-skills/messaging/tools/gmail-batch-label.ts +0 -34
  614. package/src/config/bundled-skills/messaging/tools/gmail-download-attachment.ts +0 -47
  615. package/src/config/bundled-skills/messaging/tools/gmail-label.ts +0 -31
  616. package/src/config/bundled-skills/messaging/tools/gmail-list-attachments.ts +0 -67
  617. package/src/config/bundled-skills/messaging/tools/gmail-send-with-attachments.ts +0 -97
  618. package/src/config/bundled-skills/messaging/tools/gmail-summarize-thread.ts +0 -87
  619. package/src/config/bundled-skills/messaging/tools/gmail-triage.ts +0 -135
  620. package/src/config/bundled-skills/messaging/tools/messaging-analyze-activity.ts +0 -24
  621. package/src/config/bundled-skills/messaging/tools/messaging-reply.ts +0 -201
  622. package/src/config/bundled-skills/messaging/tools/send-notification.ts +0 -1
  623. package/src/config/bundled-skills/messaging/tools/sequence-cancel.ts +0 -27
  624. package/src/config/bundled-skills/messaging/tools/sequence-pause.ts +0 -48
  625. package/src/config/bundled-skills/messaging/tools/sequence-resume.ts +0 -27
  626. package/src/config/bundled-skills/messaging/tools/sequence-update.ts +0 -56
  627. package/src/config/bundled-skills/notion/SKILL.md +0 -240
  628. package/src/config/bundled-skills/notion-oauth-setup/SKILL.md +0 -126
  629. package/src/config/bundled-skills/oauth-setup/SKILL.md +0 -143
  630. package/src/config/bundled-skills/public-ingress/SKILL.md +0 -258
  631. package/src/config/bundled-skills/reminder/SKILL.md +0 -79
  632. package/src/config/bundled-skills/reminder/TOOLS.json +0 -89
  633. package/src/config/bundled-skills/reminder/tools/reminder-list.ts +0 -12
  634. package/src/config/bundled-skills/restaurant-reservation/SKILL.md +0 -141
  635. package/src/config/bundled-skills/screen-recording/SKILL.md +0 -148
  636. package/src/config/bundled-skills/self-upgrade/SKILL.md +0 -69
  637. package/src/config/bundled-skills/skills-catalog/SKILL.md +0 -78
  638. package/src/config/bundled-skills/slack-app-setup/SKILL.md +0 -178
  639. package/src/config/bundled-skills/slack-digest-setup/SKILL.md +0 -163
  640. package/src/config/bundled-skills/slack-oauth-setup/SKILL.md +0 -157
  641. package/src/config/bundled-skills/start-the-day/SKILL.md +0 -70
  642. package/src/config/bundled-skills/start-the-day/icon.svg +0 -13
  643. package/src/config/bundled-skills/telegram-setup/SKILL.md +0 -105
  644. package/src/config/bundled-skills/time-based-actions/SKILL.md +0 -142
  645. package/src/config/bundled-skills/twilio-setup/SKILL.md +0 -232
  646. package/src/config/bundled-skills/twitter/SKILL.md +0 -206
  647. package/src/config/bundled-skills/twitter/icon.svg +0 -14
  648. package/src/config/bundled-skills/typescript-eval/SKILL.md +0 -60
  649. package/src/config/bundled-skills/vercel-token-setup/SKILL.md +0 -214
  650. package/src/config/bundled-skills/voice-setup/SKILL.md +0 -131
  651. package/src/config/bundled-skills/voice-setup/icon.svg +0 -20
  652. package/src/daemon/handlers/pairing.ts +0 -119
  653. package/src/daemon/handlers/session-user-message.ts +0 -961
  654. package/src/daemon/recording-executor.ts +0 -180
  655. package/src/daemon/recording-intent-fallback.ts +0 -162
  656. package/src/daemon/recording-intent.ts +0 -493
  657. package/src/memory/account-store.ts +0 -117
  658. package/src/messaging/activity-analyzer.ts +0 -76
  659. package/src/messaging/email-classifier.ts +0 -208
  660. package/src/messaging/index.ts +0 -2
  661. package/src/messaging/outreach-classifier.ts +0 -185
  662. package/src/messaging/thread-summarizer.ts +0 -346
  663. package/src/messaging/types.ts +0 -17
  664. package/src/tools/browser/x-auto-navigate.ts +0 -254
  665. package/src/tools/credentials/account-registry.ts +0 -144
  666. package/src/tools/filesystem/view-image.ts +0 -244
  667. package/src/tools/reminder/reminder-store.ts +0 -194
  668. package/src/tools/reminder/reminder.ts +0 -158
  669. package/src/tools/system/navigate-settings.ts +0 -74
  670. package/src/tools/system/open-system-settings.ts +0 -85
  671. package/src/tools/system/version.ts +0 -54
  672. package/src/twitter/platform-proxy-client.ts +0 -408
  673. /package/src/config/bundled-skills/{messaging → gmail}/tools/scan-result-store.ts +0 -0
  674. /package/src/config/bundled-skills/{messaging → sequences}/tools/sequence-analytics.ts +0 -0
  675. /package/src/config/bundled-skills/{messaging → sequences}/tools/sequence-create.ts +0 -0
  676. /package/src/config/bundled-skills/{messaging → sequences}/tools/sequence-delete.ts +0 -0
  677. /package/src/config/bundled-skills/{messaging → sequences}/tools/sequence-enroll.ts +0 -0
  678. /package/src/config/bundled-skills/{messaging → sequences}/tools/sequence-enrollment-list.ts +0 -0
  679. /package/src/config/bundled-skills/{messaging → sequences}/tools/sequence-get.ts +0 -0
  680. /package/src/config/bundled-skills/{messaging → sequences}/tools/sequence-import.ts +0 -0
  681. /package/src/config/bundled-skills/{messaging → sequences}/tools/sequence-list.ts +0 -0
@@ -763,6 +763,11 @@ export async function executeWebFetch(
763
763
  `start_index (${startIndex}) exceeded available content length (${processed.length}).`,
764
764
  );
765
765
  }
766
+ if (html && !rawMode && processed.length < 200) {
767
+ notices.push(
768
+ `Extracted text content is very short (${processed.length} characters). The page may require JavaScript rendering for full content.`,
769
+ );
770
+ }
766
771
 
767
772
  const content = formatWebFetchOutput({
768
773
  requestedUrl: safeRequestedUrl,
@@ -877,4 +882,5 @@ class WebFetchTool implements Tool {
877
882
  }
878
883
  }
879
884
 
880
- registerTool(new WebFetchTool());
885
+ export const webFetchTool = new WebFetchTool();
886
+ registerTool(webFetchTool);
@@ -382,4 +382,5 @@ class WebSearchTool implements Tool {
382
382
  }
383
383
  }
384
384
 
385
- registerTool(new WebSearchTool());
385
+ export const webSearchTool = new WebSearchTool();
386
+ registerTool(webSearchTool);
@@ -239,6 +239,18 @@ export function registerMcpTools(newTools: Tool[]): Tool[] {
239
239
  return accepted;
240
240
  }
241
241
 
242
+ /**
243
+ * Unregister all MCP-origin tools from the registry.
244
+ */
245
+ export function unregisterAllMcpTools(): void {
246
+ for (const [name, tool] of tools) {
247
+ if (tool.origin === "mcp") {
248
+ tools.delete(name);
249
+ log.info({ name }, "MCP tool unregistered (reload)");
250
+ }
251
+ }
252
+ }
253
+
242
254
  /**
243
255
  * Unregister all tools belonging to a specific MCP server.
244
256
  */
@@ -260,6 +272,17 @@ export function getMcpToolNames(): string[] {
260
272
  .map((t) => t.name);
261
273
  }
262
274
 
275
+ /**
276
+ * Return tool definitions for all currently registered MCP-origin tools.
277
+ * Used by the session resolver to dynamically pick up MCP tools that
278
+ * were registered after session creation (e.g. via `vellum mcp reload`).
279
+ */
280
+ export function getMcpToolDefinitions(): ToolDefinition[] {
281
+ return Array.from(tools.values())
282
+ .filter((t) => t.origin === "mcp")
283
+ .map((t) => t.getDefinition());
284
+ }
285
+
263
286
  /**
264
287
  * Return the names of all currently registered skill-origin tools.
265
288
  */
@@ -1,6 +1,10 @@
1
1
  import { formatIntegrationSummary } from "../../schedule/integration-status.js";
2
2
  import { validateRruleSetLines } from "../../schedule/recurrence-engine.js";
3
3
  import { normalizeScheduleSyntax } from "../../schedule/recurrence-types.js";
4
+ import type {
5
+ RoutingIntent,
6
+ ScheduleMode,
7
+ } from "../../schedule/schedule-store.js";
4
8
  import {
5
9
  createSchedule,
6
10
  describeCronExpression,
@@ -9,6 +13,13 @@ import {
9
13
  } from "../../schedule/schedule-store.js";
10
14
  import type { ToolContext, ToolExecutionResult } from "../types.js";
11
15
 
16
+ const VALID_MODES: ScheduleMode[] = ["notify", "execute"];
17
+ const VALID_ROUTING_INTENTS: RoutingIntent[] = [
18
+ "single_channel",
19
+ "multi_channel",
20
+ "all_channels",
21
+ ];
22
+
12
23
  export async function executeScheduleCreate(
13
24
  input: Record<string, unknown>,
14
25
  _context: ToolContext,
@@ -17,6 +28,12 @@ export async function executeScheduleCreate(
17
28
  const timezone = (input.timezone as string) ?? null;
18
29
  const message = input.message as string;
19
30
  const enabled = (input.enabled as boolean) ?? true;
31
+ const fireAt = input.fire_at as string | undefined;
32
+ const mode = (input.mode as ScheduleMode | undefined) ?? "execute";
33
+ const routingIntent = input.routing_intent as string | undefined;
34
+ const routingHints = input.routing_hints as
35
+ | Record<string, unknown>
36
+ | undefined;
20
37
 
21
38
  if (!name || typeof name !== "string") {
22
39
  return {
@@ -31,6 +48,90 @@ export async function executeScheduleCreate(
31
48
  };
32
49
  }
33
50
 
51
+ // Validate mode
52
+ if (!VALID_MODES.includes(mode)) {
53
+ return {
54
+ content: `Error: mode must be one of: ${VALID_MODES.join(", ")}`,
55
+ isError: true,
56
+ };
57
+ }
58
+
59
+ // Validate routing_intent
60
+ if (
61
+ routingIntent !== undefined &&
62
+ !VALID_ROUTING_INTENTS.includes(routingIntent as RoutingIntent)
63
+ ) {
64
+ return {
65
+ content: `Error: routing_intent must be one of: ${VALID_ROUTING_INTENTS.join(", ")}`,
66
+ isError: true,
67
+ };
68
+ }
69
+
70
+ // ── One-shot schedule (fire_at) ──────────────────────────────────
71
+ if (fireAt) {
72
+ const fireAtMs = Date.parse(fireAt);
73
+ if (isNaN(fireAtMs)) {
74
+ return {
75
+ content:
76
+ "Error: fire_at must be a valid ISO 8601 timestamp (e.g. 2025-06-15T09:00:00Z)",
77
+ isError: true,
78
+ };
79
+ }
80
+ // Require explicit timezone (Z, ±HH:MM, or ±HHMM offset) to avoid host-timezone ambiguity
81
+ if (!/(?:Z|[+-]\d{2}:?\d{2})\s*$/.test(fireAt)) {
82
+ return {
83
+ content:
84
+ "Error: fire_at must include a timezone offset (e.g. 2025-06-15T09:00:00Z or 2025-06-15T09:00:00+05:30)",
85
+ isError: true,
86
+ };
87
+ }
88
+ if (fireAtMs <= Date.now()) {
89
+ return {
90
+ content: "Error: fire_at must be in the future",
91
+ isError: true,
92
+ };
93
+ }
94
+
95
+ try {
96
+ const job = createSchedule({
97
+ name,
98
+ cronExpression: null,
99
+ timezone,
100
+ message,
101
+ enabled,
102
+ syntax: "cron",
103
+ expression: null,
104
+ nextRunAt: fireAtMs,
105
+ mode,
106
+ routingIntent: routingIntent as RoutingIntent | undefined,
107
+ routingHints,
108
+ });
109
+
110
+ const fireDate = formatLocalDate(job.nextRunAt);
111
+ const integrations = formatIntegrationSummary();
112
+ return {
113
+ content: [
114
+ `One-shot schedule created successfully.`,
115
+ ` ID: ${job.id}`,
116
+ ` Name: ${job.name}`,
117
+ ` Type: one-shot`,
118
+ ` Mode: ${job.mode}`,
119
+ ` Fire at: ${fireDate}`,
120
+ ` Enabled: ${job.enabled}`,
121
+ ` Status: ${job.status}`,
122
+ ``,
123
+ `Integrations: ${integrations}`,
124
+ `\u26a0 If this schedule requires an integration that isn't connected, it will fail at runtime. Warn the user about any missing capabilities before confirming the schedule is ready.`,
125
+ ].join("\n"),
126
+ isError: false,
127
+ };
128
+ } catch (err) {
129
+ const msg = err instanceof Error ? err.message : String(err);
130
+ return { content: `Error creating schedule: ${msg}`, isError: true };
131
+ }
132
+ }
133
+
134
+ // ── Recurring schedule (expression) ──────────────────────────────
34
135
  const resolved = normalizeScheduleSyntax({
35
136
  syntax: input.syntax as "cron" | "rrule" | undefined,
36
137
  expression: input.expression as string | undefined,
@@ -38,7 +139,8 @@ export async function executeScheduleCreate(
38
139
 
39
140
  if (!resolved) {
40
141
  return {
41
- content: "Error: expression is required",
142
+ content:
143
+ "Error: expression is required for recurring schedules (or provide fire_at for one-shot)",
42
144
  isError: true,
43
145
  };
44
146
  }
@@ -75,21 +177,27 @@ export async function executeScheduleCreate(
75
177
  enabled,
76
178
  syntax: resolved.syntax,
77
179
  expression: resolved.expression,
180
+ mode,
181
+ routingIntent: routingIntent as RoutingIntent | undefined,
182
+ routingHints,
78
183
  });
79
184
 
80
185
  const scheduleDescription =
81
- job.syntax === "rrule"
82
- ? job.expression
83
- : describeCronExpression(job.cronExpression);
186
+ job.expression == null
187
+ ? "One-time"
188
+ : job.syntax === "rrule"
189
+ ? job.expression
190
+ : describeCronExpression(job.cronExpression);
84
191
 
85
192
  const nextRunDate = formatLocalDate(job.nextRunAt);
86
193
  const integrations = formatIntegrationSummary();
87
194
  return {
88
195
  content: [
89
- `Schedule created successfully.`,
196
+ `Recurring schedule created successfully.`,
90
197
  ` ID: ${job.id}`,
91
198
  ` Name: ${job.name}`,
92
199
  ` Syntax: ${job.syntax}`,
200
+ ` Mode: ${job.mode}`,
93
201
  ` Schedule: ${scheduleDescription}${
94
202
  job.timezone ? ` (${job.timezone})` : ""
95
203
  }`,
@@ -10,9 +10,10 @@ import type { ToolContext, ToolExecutionResult } from "../types.js";
10
10
 
11
11
  function describeSchedule(job: {
12
12
  syntax: string;
13
- expression: string;
14
- cronExpression: string;
13
+ expression: string | null;
14
+ cronExpression: string | null;
15
15
  }): string {
16
+ if (job.expression == null) return "One-time";
16
17
  if (job.syntax === "rrule") {
17
18
  const label = hasSetConstructs(job.expression) ? "[RRULE set] " : "";
18
19
  return `${label}${job.expression}`;
@@ -20,6 +21,10 @@ function describeSchedule(job: {
20
21
  return describeCronExpression(job.cronExpression);
21
22
  }
22
23
 
24
+ function isOneShot(job: { expression: string | null }): boolean {
25
+ return job.expression == null;
26
+ }
27
+
23
28
  export async function executeScheduleList(
24
29
  input: Record<string, unknown>,
25
30
  _context: ToolContext,
@@ -34,23 +39,51 @@ export async function executeScheduleList(
34
39
  return { content: `Error: Schedule not found: ${jobId}`, isError: true };
35
40
  }
36
41
 
42
+ const oneShot = isOneShot(job);
43
+
37
44
  const runs = getScheduleRuns(jobId, 5);
38
45
  const lines = [
39
46
  `Schedule: ${job.name}`,
40
47
  ` ID: ${job.id}`,
41
- ` Syntax: ${job.syntax}`,
42
- ` Expression: ${job.expression}`,
43
- ` Schedule: ${describeSchedule(job)}${
44
- job.timezone ? ` (${job.timezone})` : ""
45
- }`,
48
+ ` Type: ${oneShot ? "one-shot" : "recurring"}`,
49
+ ` Mode: ${job.mode}`,
50
+ ` Status: ${job.status}`,
51
+ ];
52
+
53
+ if (oneShot) {
54
+ lines.push(` Fire at: ${formatLocalDate(job.nextRunAt)}`);
55
+ } else {
56
+ lines.push(
57
+ ` Syntax: ${job.syntax}`,
58
+ ` Expression: ${job.expression ?? "(one-time)"}`,
59
+ ` Schedule: ${describeSchedule(job)}${
60
+ job.timezone ? ` (${job.timezone})` : ""
61
+ }`,
62
+ );
63
+ }
64
+
65
+ lines.push(
46
66
  ` Enabled: ${job.enabled}`,
47
67
  ` Message: ${job.message}`,
48
- ` Next run: ${formatLocalDate(job.nextRunAt)}`,
68
+ );
69
+
70
+ if (!oneShot) {
71
+ lines.push(
72
+ ` Next run: ${formatLocalDate(job.nextRunAt)}`,
73
+ );
74
+ }
75
+
76
+ lines.push(
49
77
  ` Last run: ${job.lastRunAt ? formatLocalDate(job.lastRunAt) : "never"}`,
50
78
  ` Last status: ${job.lastStatus ?? "n/a"}`,
51
79
  ` Retry count: ${job.retryCount}`,
52
80
  ` Created: ${formatLocalDate(job.createdAt)}`,
53
- ];
81
+ );
82
+
83
+ // Show routing intent in detail view when not the default
84
+ if (job.routingIntent !== "all_channels") {
85
+ lines.push(` Routing: ${job.routingIntent}`);
86
+ }
54
87
 
55
88
  if (runs.length > 0) {
56
89
  lines.push("", `Recent runs (${runs.length}):`);
@@ -78,12 +111,21 @@ export async function executeScheduleList(
78
111
  const lines = [`Schedules (${jobs.length}):`];
79
112
  for (const job of jobs) {
80
113
  const status = job.enabled ? "enabled" : "disabled";
81
- const next = job.enabled ? formatLocalDate(job.nextRunAt) : "n/a";
82
- lines.push(
83
- ` - [${status}] ${job.name} (id: ${job.id}) ([${
84
- job.syntax
85
- }] ${describeSchedule(job)}) — next: ${next}`,
86
- );
114
+ const oneShot = isOneShot(job);
115
+
116
+ if (oneShot) {
117
+ const fireTime = formatLocalDate(job.nextRunAt);
118
+ lines.push(
119
+ ` - [${status}] ${job.name} (id: ${job.id}) (one-shot, ${job.mode}) — fire at: ${fireTime} [${job.status}]`,
120
+ );
121
+ } else {
122
+ const next = job.enabled ? formatLocalDate(job.nextRunAt) : "n/a";
123
+ lines.push(
124
+ ` - [${status}] ${job.name} (id: ${job.id}) ([${
125
+ job.syntax
126
+ }] ${describeSchedule(job)}, ${job.mode}) — next: ${next}`,
127
+ );
128
+ }
87
129
  }
88
130
 
89
131
  return { content: lines.join("\n"), isError: false };
@@ -4,13 +4,25 @@ import {
4
4
  normalizeScheduleSyntax,
5
5
  type ScheduleSyntax,
6
6
  } from "../../schedule/recurrence-types.js";
7
+ import type {
8
+ RoutingIntent,
9
+ ScheduleMode,
10
+ } from "../../schedule/schedule-store.js";
7
11
  import {
8
12
  describeCronExpression,
9
13
  formatLocalDate,
14
+ getSchedule,
10
15
  updateSchedule,
11
16
  } from "../../schedule/schedule-store.js";
12
17
  import type { ToolContext, ToolExecutionResult } from "../types.js";
13
18
 
19
+ const VALID_MODES: ScheduleMode[] = ["notify", "execute"];
20
+ const VALID_ROUTING_INTENTS: RoutingIntent[] = [
21
+ "single_channel",
22
+ "multi_channel",
23
+ "all_channels",
24
+ ];
25
+
14
26
  export async function executeScheduleUpdate(
15
27
  input: Record<string, unknown>,
16
28
  _context: ToolContext,
@@ -20,12 +32,64 @@ export async function executeScheduleUpdate(
20
32
  return { content: "Error: job_id is required", isError: true };
21
33
  }
22
34
 
35
+ // Prevent changing a one-shot to recurring or vice versa
36
+ if (input.expression !== undefined || input.fire_at !== undefined) {
37
+ const existing = getSchedule(jobId);
38
+ if (!existing) {
39
+ return { content: `Error: Schedule not found: ${jobId}`, isError: true };
40
+ }
41
+ const isExistingOneShot = existing.expression == null;
42
+ if (isExistingOneShot && input.expression !== undefined) {
43
+ return {
44
+ content:
45
+ "Error: Cannot change a one-shot schedule to recurring. Delete and recreate instead.",
46
+ isError: true,
47
+ };
48
+ }
49
+ if (!isExistingOneShot && input.fire_at !== undefined) {
50
+ return {
51
+ content:
52
+ "Error: Cannot change a recurring schedule to one-shot. Delete and recreate instead.",
53
+ isError: true,
54
+ };
55
+ }
56
+ }
57
+
23
58
  const updates: Record<string, unknown> = {};
24
59
  if (input.name !== undefined) updates.name = input.name;
25
60
  if (input.timezone !== undefined) updates.timezone = input.timezone;
26
61
  if (input.message !== undefined) updates.message = input.message;
27
62
  if (input.enabled !== undefined) updates.enabled = input.enabled;
28
63
 
64
+ // Mode validation and pass-through
65
+ if (input.mode !== undefined) {
66
+ const mode = input.mode as ScheduleMode;
67
+ if (!VALID_MODES.includes(mode)) {
68
+ return {
69
+ content: `Error: mode must be one of: ${VALID_MODES.join(", ")}`,
70
+ isError: true,
71
+ };
72
+ }
73
+ updates.mode = mode;
74
+ }
75
+
76
+ // Routing intent validation and pass-through
77
+ if (input.routing_intent !== undefined) {
78
+ const routingIntent = input.routing_intent as RoutingIntent;
79
+ if (!VALID_ROUTING_INTENTS.includes(routingIntent)) {
80
+ return {
81
+ content: `Error: routing_intent must be one of: ${VALID_ROUTING_INTENTS.join(", ")}`,
82
+ isError: true,
83
+ };
84
+ }
85
+ updates.routingIntent = routingIntent;
86
+ }
87
+
88
+ // Routing hints pass-through
89
+ if (input.routing_hints !== undefined) {
90
+ updates.routingHints = input.routing_hints;
91
+ }
92
+
29
93
  // Auto-detect syntax when expression changes without explicit syntax
30
94
  if (input.expression !== undefined || input.syntax !== undefined) {
31
95
  const resolved = normalizeScheduleSyntax({
@@ -85,6 +149,9 @@ export async function executeScheduleUpdate(
85
149
  enabled?: boolean;
86
150
  syntax?: ScheduleSyntax;
87
151
  expression?: string;
152
+ mode?: ScheduleMode;
153
+ routingIntent?: RoutingIntent;
154
+ routingHints?: Record<string, unknown>;
88
155
  },
89
156
  );
90
157
 
@@ -93,15 +160,18 @@ export async function executeScheduleUpdate(
93
160
  }
94
161
 
95
162
  const scheduleDescription =
96
- job.syntax === "rrule"
97
- ? job.expression
98
- : describeCronExpression(job.cronExpression);
163
+ job.expression == null
164
+ ? "One-time"
165
+ : job.syntax === "rrule"
166
+ ? job.expression
167
+ : describeCronExpression(job.cronExpression);
99
168
 
100
169
  return {
101
170
  content: [
102
171
  `Schedule updated successfully.`,
103
172
  ` Name: ${job.name}`,
104
173
  ` Syntax: ${job.syntax}`,
174
+ ` Mode: ${job.mode}`,
105
175
  ` Schedule: ${scheduleDescription}${job.timezone ? ` (${job.timezone})` : ""}`,
106
176
  ` Enabled: ${job.enabled}`,
107
177
  ` Next run: ${job.enabled ? formatLocalDate(job.nextRunAt) : "n/a (disabled)"}`,
@@ -0,0 +1,192 @@
1
+ import { execFileSync } from "node:child_process";
2
+ import { readFileSync, statSync, unlinkSync } from "node:fs";
3
+ import { tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+
6
+ import type { ImageContent } from "../../../providers/types.js";
7
+ import type { ToolExecutionResult } from "../../types.js";
8
+
9
+ export const IMAGE_EXTENSIONS = new Set([
10
+ ".jpg",
11
+ ".jpeg",
12
+ ".png",
13
+ ".gif",
14
+ ".webp",
15
+ ]);
16
+
17
+ const MAX_SIZE_BYTES = 20 * 1024 * 1024; // 20 MB
18
+
19
+ // Images above this threshold get auto-optimized via sips (macOS) to avoid
20
+ // sending multi-MB base64 payloads to the LLM API.
21
+ const OPTIMIZE_THRESHOLD_BYTES = 1 * 1024 * 1024; // 1 MB
22
+ const OPTIMIZE_MAX_DIMENSION = 1568; // Anthropic's recommended max
23
+ const OPTIMIZE_JPEG_QUALITY = 80;
24
+
25
+ /**
26
+ * Detect the actual image format from the first bytes of the buffer.
27
+ * Returns the MIME type, or null if unrecognised.
28
+ */
29
+ function detectMediaType(buf: Buffer): string | null {
30
+ if (buf.length < 12) return null;
31
+
32
+ // JPEG: FF D8 FF
33
+ if (buf[0] === 0xff && buf[1] === 0xd8 && buf[2] === 0xff) {
34
+ return "image/jpeg";
35
+ }
36
+ // PNG: 89 50 4E 47 0D 0A 1A 0A
37
+ if (
38
+ buf[0] === 0x89 &&
39
+ buf[1] === 0x50 &&
40
+ buf[2] === 0x4e &&
41
+ buf[3] === 0x47
42
+ ) {
43
+ return "image/png";
44
+ }
45
+ // GIF: 47 49 46 38
46
+ if (
47
+ buf[0] === 0x47 &&
48
+ buf[1] === 0x49 &&
49
+ buf[2] === 0x46 &&
50
+ buf[3] === 0x38
51
+ ) {
52
+ return "image/gif";
53
+ }
54
+ // WebP: RIFF....WEBP
55
+ if (
56
+ buf[0] === 0x52 &&
57
+ buf[1] === 0x49 &&
58
+ buf[2] === 0x46 &&
59
+ buf[3] === 0x46 &&
60
+ buf[8] === 0x57 &&
61
+ buf[9] === 0x45 &&
62
+ buf[10] === 0x42 &&
63
+ buf[11] === 0x50
64
+ ) {
65
+ return "image/webp";
66
+ }
67
+
68
+ return null;
69
+ }
70
+
71
+ /**
72
+ * Use macOS `sips` to resize and convert an image to JPEG.
73
+ * Returns the path to the optimized temp file, or null if sips is unavailable.
74
+ */
75
+ function optimizeWithSips(srcPath: string): string | null {
76
+ const tmpPath = join(tmpdir(), `vellum-view-image-${Date.now()}.jpg`);
77
+ try {
78
+ execFileSync(
79
+ "sips",
80
+ [
81
+ "--resampleHeightWidthMax",
82
+ String(OPTIMIZE_MAX_DIMENSION),
83
+ "-s",
84
+ "format",
85
+ "jpeg",
86
+ "-s",
87
+ "formatOptions",
88
+ String(OPTIMIZE_JPEG_QUALITY),
89
+ srcPath,
90
+ "--out",
91
+ tmpPath,
92
+ ],
93
+ { stdio: "pipe", timeout: 15_000 },
94
+ );
95
+ return tmpPath;
96
+ } catch {
97
+ return null;
98
+ }
99
+ }
100
+
101
+ /**
102
+ * Read an image file from disk, optionally optimize it, and return a
103
+ * ToolExecutionResult with base64-encoded image content blocks.
104
+ *
105
+ * The caller is responsible for path resolution and sandbox enforcement —
106
+ * `resolvedPath` must be an already-validated absolute path.
107
+ */
108
+ export function readImageFile(resolvedPath: string): ToolExecutionResult {
109
+ let stat;
110
+ try {
111
+ stat = statSync(resolvedPath);
112
+ } catch {
113
+ return {
114
+ content: `Error: file not found: ${resolvedPath}`,
115
+ isError: true,
116
+ };
117
+ }
118
+
119
+ if (!stat.isFile()) {
120
+ return { content: `Error: ${resolvedPath} is not a file`, isError: true };
121
+ }
122
+
123
+ if (stat.size > MAX_SIZE_BYTES) {
124
+ const sizeMB = (stat.size / (1024 * 1024)).toFixed(1);
125
+ return {
126
+ content: `Error: image too large (${sizeMB} MB). Maximum is 20 MB.`,
127
+ isError: true,
128
+ };
129
+ }
130
+
131
+ let buffer: Buffer;
132
+ let optimized = false;
133
+ let tmpPath: string | null = null;
134
+
135
+ try {
136
+ if (stat.size > OPTIMIZE_THRESHOLD_BYTES) {
137
+ tmpPath = optimizeWithSips(resolvedPath);
138
+ if (tmpPath) {
139
+ buffer = readFileSync(tmpPath) as Buffer;
140
+ optimized = true;
141
+ } else {
142
+ buffer = readFileSync(resolvedPath) as Buffer;
143
+ }
144
+ } else {
145
+ buffer = readFileSync(resolvedPath) as Buffer;
146
+ }
147
+ } catch (err) {
148
+ const msg = err instanceof Error ? err.message : String(err);
149
+ return { content: `Error reading file: ${msg}`, isError: true };
150
+ } finally {
151
+ if (tmpPath) {
152
+ try {
153
+ unlinkSync(tmpPath);
154
+ } catch {
155
+ /* ignore cleanup errors */
156
+ }
157
+ }
158
+ }
159
+
160
+ // Detect actual format from magic bytes — never trust the file extension
161
+ // alone, since sips converts to JPEG and files can be misnamed.
162
+ const detectedType = detectMediaType(buffer);
163
+ if (!detectedType) {
164
+ return {
165
+ content: `Error: could not detect image format for ${resolvedPath}. The file may be corrupt.`,
166
+ isError: true,
167
+ };
168
+ }
169
+
170
+ const base64Data = buffer.toString("base64");
171
+
172
+ const imageBlock: ImageContent = {
173
+ type: "image" as const,
174
+ source: {
175
+ type: "base64" as const,
176
+ media_type: detectedType,
177
+ data: base64Data,
178
+ },
179
+ };
180
+
181
+ const sizeSuffix = optimized
182
+ ? ` (optimized from ${(stat.size / 1024).toFixed(0)} KB to ${(
183
+ buffer.length / 1024
184
+ ).toFixed(0)} KB)`
185
+ : "";
186
+
187
+ return {
188
+ content: `Image loaded: ${resolvedPath} (${buffer.length} bytes, ${detectedType})${sizeSuffix}`,
189
+ isError: false,
190
+ contentBlocks: [imageBlock],
191
+ };
192
+ }
@@ -23,8 +23,6 @@ const SIDE_EFFECT_TOOLS: ReadonlySet<string> = new Set([
23
23
  "browser_fill_credential",
24
24
  "document_create",
25
25
  "document_update",
26
- "reminder_create",
27
- "reminder_cancel",
28
26
  "schedule_create",
29
27
  "schedule_update",
30
28
  "schedule_delete",
@@ -35,7 +33,7 @@ const SIDE_EFFECT_TOOLS: ReadonlySet<string> = new Set([
35
33
  * (i.e. it can modify the filesystem, execute arbitrary commands, or trigger
36
34
  * external actions). Read-only and informational tools return `false`.
37
35
  *
38
- * For mixed-action tools (e.g. account_manage, credential_store), the optional
36
+ * For mixed-action tools (e.g. credential_store), the optional
39
37
  * `input` parameter is inspected to distinguish mutating actions (create,
40
38
  * update, cancel) from read-only ones (list, get).
41
39
  */
@@ -46,10 +44,6 @@ export function isSideEffectTool(
46
44
  if (SIDE_EFFECT_TOOLS.has(toolName)) return true;
47
45
 
48
46
  // Action-aware checks for mixed-action tools
49
- if (toolName === "account_manage") {
50
- const action = input?.action;
51
- return action === "create" || action === "update";
52
- }
53
47
  if (toolName === "credential_store") {
54
48
  const action = input?.action;
55
49
  return (