@vellumai/assistant 0.8.1 → 0.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (506) hide show
  1. package/ARCHITECTURE.md +2 -7
  2. package/Dockerfile +75 -1
  3. package/bun.lock +11 -1
  4. package/docker-entrypoint.sh +5 -0
  5. package/docker-init-apt-root.sh +94 -0
  6. package/docker-kata-apt-env.sh +39 -0
  7. package/docs/plugins.md +88 -47
  8. package/docs/skills.md +9 -7
  9. package/examples/plugins/echo/README.md +27 -27
  10. package/examples/plugins/echo/package.json +3 -0
  11. package/examples/plugins/echo/register.ts +31 -31
  12. package/node_modules/@vellumai/slack-text/src/index.test.ts +114 -14
  13. package/node_modules/@vellumai/slack-text/src/index.ts +82 -18
  14. package/openapi.yaml +325 -3
  15. package/package.json +3 -1
  16. package/scripts/generate-openapi.ts +83 -10
  17. package/scripts/sync-llm-catalog.ts +2 -2
  18. package/scripts/sync-web-search-catalog.ts +47 -25
  19. package/src/__tests__/agent-image-optimize.test.ts +11 -3
  20. package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +131 -0
  21. package/src/__tests__/anthropic-provider.test.ts +45 -0
  22. package/src/__tests__/app-builder-tool-scripts.test.ts +9 -3
  23. package/src/__tests__/app-executors.test.ts +220 -4
  24. package/src/__tests__/auto-analysis-end-to-end.test.ts +35 -0
  25. package/src/__tests__/bundled-asset.test.ts +6 -6
  26. package/src/__tests__/channel-availability-routes.test.ts +206 -0
  27. package/src/__tests__/channel-delivery-store.test.ts +289 -1
  28. package/src/__tests__/circuit-breaker-pipeline.test.ts +0 -1
  29. package/src/__tests__/clawhub.test.ts +75 -16
  30. package/src/__tests__/compactor-tail-resolution.test.ts +41 -0
  31. package/src/__tests__/config-schema.test.ts +21 -0
  32. package/src/__tests__/config-set-route.test.ts +80 -0
  33. package/src/__tests__/config-sounds-sync.test.ts +97 -0
  34. package/src/__tests__/config-watcher-skill-reseed.test.ts +453 -0
  35. package/src/__tests__/context-search-conversations-source.test.ts +117 -2
  36. package/src/__tests__/context-search-memory-v2-source.test.ts +0 -1
  37. package/src/__tests__/context-search-workspace-source.test.ts +7 -0
  38. package/src/__tests__/context-token-estimator.test.ts +1 -0
  39. package/src/__tests__/conversation-abort-tool-results.test.ts +4 -1
  40. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +1 -0
  41. package/src/__tests__/conversation-agent-loop-overflow.test.ts +92 -92
  42. package/src/__tests__/conversation-agent-loop.test.ts +2 -0
  43. package/src/__tests__/conversation-error.test.ts +42 -3
  44. package/src/__tests__/conversation-fork-crud.test.ts +82 -0
  45. package/src/__tests__/conversation-inference-profile-route.test.ts +40 -4
  46. package/src/__tests__/conversation-lifecycle.test.ts +173 -0
  47. package/src/__tests__/conversation-message-sync-tags.test.ts +97 -0
  48. package/src/__tests__/conversation-pairing.test.ts +54 -0
  49. package/src/__tests__/conversation-process-callsite.test.ts +4 -1
  50. package/src/__tests__/conversation-provider-retry-repair.test.ts +5 -1
  51. package/src/__tests__/conversation-queue.test.ts +4 -1
  52. package/src/__tests__/conversation-runtime-assembly.test.ts +76 -9
  53. package/src/__tests__/conversation-slash-queue.test.ts +59 -1
  54. package/src/__tests__/conversation-slash-unknown.test.ts +4 -1
  55. package/src/__tests__/conversation-surfaces-table-action.test.ts +360 -0
  56. package/src/__tests__/conversation-sync-tags.test.ts +235 -0
  57. package/src/__tests__/conversation-workspace-injection.test.ts +5 -1
  58. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +5 -1
  59. package/src/__tests__/credential-security-invariants.test.ts +3 -2
  60. package/src/__tests__/db-slack-external-content-normalization.test.ts +301 -0
  61. package/src/__tests__/delete-managed-skill-tool.test.ts +55 -13
  62. package/src/__tests__/disk-pressure-tools.test.ts +1 -0
  63. package/src/__tests__/dm-backfill.test.ts +121 -10
  64. package/src/__tests__/document-tool-security.test.ts +258 -0
  65. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +0 -1
  66. package/src/__tests__/edit-propagation.test.ts +33 -0
  67. package/src/__tests__/empty-response-pipeline.test.ts +0 -4
  68. package/src/__tests__/external-plugin-loader.test.ts +60 -36
  69. package/src/__tests__/filing-service.test.ts +140 -0
  70. package/src/__tests__/get-skill-detail-audit.test.ts +0 -4
  71. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +43 -62
  72. package/src/__tests__/helpers/tar-fixtures.ts +39 -0
  73. package/src/__tests__/helpers/wait-for.ts +21 -0
  74. package/src/__tests__/history-repair-pipeline.test.ts +0 -3
  75. package/src/__tests__/history-repair.test.ts +73 -0
  76. package/src/__tests__/host-app-control-proxy.test.ts +266 -10
  77. package/src/__tests__/image-credentials.test.ts +1 -1
  78. package/src/__tests__/inbound-slack-persistence.test.ts +2 -0
  79. package/src/__tests__/inference-no-mode-boot-e2e.test.ts +1 -1
  80. package/src/__tests__/inference-profile-reaper.test.ts +4 -2
  81. package/src/__tests__/inference-profile-session-handler.test.ts +18 -6
  82. package/src/__tests__/inference-profile-session-ipc.test.ts +17 -5
  83. package/src/__tests__/injector-chain.test.ts +10 -8
  84. package/src/__tests__/install-skill-routing.test.ts +155 -37
  85. package/src/__tests__/lifecycle-memory-v2-seed.test.ts +92 -3
  86. package/src/__tests__/list-messages-page-latest.test.ts +55 -0
  87. package/src/__tests__/llm-call-pipeline.test.ts +0 -3
  88. package/src/__tests__/llm-catalog-parity.test.ts +55 -13
  89. package/src/__tests__/llm-request-log-source-clickhouse.test.ts +34 -0
  90. package/src/__tests__/llm-request-log-source-factory.test.ts +29 -53
  91. package/src/__tests__/llm-usage-store.test.ts +114 -0
  92. package/src/__tests__/managed-profile-guard.test.ts +31 -29
  93. package/src/__tests__/managed-skill-lifecycle.test.ts +109 -18
  94. package/src/__tests__/managed-store.test.ts +84 -192
  95. package/src/__tests__/media-generate-image.test.ts +1 -1
  96. package/src/__tests__/memory-retrieval-pipeline.test.ts +0 -2
  97. package/src/__tests__/messages-after-tiebreaker.test.ts +122 -0
  98. package/src/__tests__/oauth-commands-routes.test.ts +168 -16
  99. package/src/__tests__/oauth-provider-profiles.test.ts +9 -0
  100. package/src/__tests__/openai-provider.test.ts +24 -0
  101. package/src/__tests__/openai-responses-cutover-guard.test.ts +17 -9
  102. package/src/__tests__/overflow-reduce-pipeline.test.ts +0 -2
  103. package/src/__tests__/persistence-pipeline.test.ts +0 -2
  104. package/src/__tests__/{managed-proxy-context.test.ts → platform-proxy-context.test.ts} +1 -1
  105. package/src/__tests__/platform.test.ts +2 -0
  106. package/src/__tests__/plugin-api-shim.test.ts +125 -0
  107. package/src/__tests__/plugin-bootstrap.test.ts +10 -36
  108. package/src/__tests__/plugin-external-api.test.ts +68 -0
  109. package/src/__tests__/plugin-registry.test.ts +0 -77
  110. package/src/__tests__/plugin-route-contribution.test.ts +0 -1
  111. package/src/__tests__/plugin-skill-contribution.test.ts +0 -2
  112. package/src/__tests__/plugin-tool-contribution.test.ts +16 -15
  113. package/src/__tests__/plugin-types.test.ts +3 -13
  114. package/src/__tests__/process-message-background-slack.test.ts +8 -1
  115. package/src/__tests__/process-message-display-content.test.ts +421 -0
  116. package/src/__tests__/provider-catalog-visibility.test.ts +142 -0
  117. package/src/__tests__/provider-error-scenarios.test.ts +111 -0
  118. package/src/__tests__/{provider-managed-proxy-integration.test.ts → provider-platform-proxy-integration.test.ts} +8 -8
  119. package/src/__tests__/scaffold-managed-skill-tool.test.ts +65 -13
  120. package/src/__tests__/schedule-routes.test.ts +50 -3
  121. package/src/__tests__/schedule-store.test.ts +94 -0
  122. package/src/__tests__/scheduler-reuse-conversation.test.ts +54 -7
  123. package/src/__tests__/schema-transforms.test.ts +20 -0
  124. package/src/__tests__/search-skills-unified.test.ts +0 -5
  125. package/src/__tests__/server-history-render.test.ts +43 -0
  126. package/src/__tests__/skill-load-feature-flag.test.ts +0 -12
  127. package/src/__tests__/skill-load-tool.test.ts +27 -89
  128. package/src/__tests__/skill-memory.test.ts +23 -3
  129. package/src/__tests__/skills-file-content-endpoint.test.ts +9 -38
  130. package/src/__tests__/skills-files-catalog-fallback.test.ts +0 -3
  131. package/src/__tests__/skills-install-extract.test.ts +49 -38
  132. package/src/__tests__/skills-install-staging.test.ts +159 -0
  133. package/src/__tests__/skills-uninstall.test.ts +9 -41
  134. package/src/__tests__/skills.test.ts +51 -58
  135. package/src/__tests__/slack-channel-config.test.ts +9 -0
  136. package/src/__tests__/subagent-tool-filtering.test.ts +50 -0
  137. package/src/__tests__/system-prompt.test.ts +737 -63
  138. package/src/__tests__/terminal-tools.test.ts +28 -1
  139. package/src/__tests__/thread-backfill.test.ts +557 -27
  140. package/src/__tests__/title-generate-pipeline.test.ts +0 -13
  141. package/src/__tests__/token-estimate-pipeline.test.ts +0 -3
  142. package/src/__tests__/tool-error-pipeline.test.ts +0 -3
  143. package/src/__tests__/tool-execute-pipeline.test.ts +0 -5
  144. package/src/__tests__/tool-executor-lifecycle-events.test.ts +1 -1
  145. package/src/__tests__/tool-executor.test.ts +16 -4
  146. package/src/__tests__/tool-result-truncate-pipeline.test.ts +0 -12
  147. package/src/__tests__/turn-events-store.test.ts +256 -0
  148. package/src/__tests__/twilio-routes.test.ts +4 -0
  149. package/src/__tests__/user-plugin-loader.test.ts +0 -7
  150. package/src/__tests__/voice-session-bridge.test.ts +198 -0
  151. package/src/__tests__/web-search-catalog-parity.test.ts +32 -10
  152. package/src/__tests__/workspace-migration-057-repair-stale-gemini-model-ids.test.ts +115 -3
  153. package/src/__tests__/workspace-migration-072-seed-reply-suggestion-callsite.test.ts +50 -0
  154. package/src/__tests__/workspace-migration-073-repair-recall-callsite-empty-profile.test.ts +153 -0
  155. package/src/__tests__/workspace-migration-085-memory-v2-bm25-b-reembed-disabled-v2-pages.test.ts +220 -0
  156. package/src/__tests__/workspace-migration-086-revert-stale-gemini-mis-rewrites.test.ts +269 -0
  157. package/src/__tests__/workspace-migration-remove-legacy-skills-index.test.ts +309 -0
  158. package/src/__tests__/workspace-migrations-runner.test.ts +111 -3
  159. package/src/acp/resolve-agent.ts +1 -1
  160. package/src/agent/image-optimize.ts +13 -5
  161. package/src/calls/voice-session-bridge.ts +61 -42
  162. package/src/channels/types.ts +108 -0
  163. package/src/cli/__tests__/unknown-command.test.ts +24 -0
  164. package/src/cli/commands/__tests__/changelog.test.ts +304 -319
  165. package/src/cli/commands/__tests__/schedules.test.ts +491 -0
  166. package/src/cli/commands/changelog.ts +106 -42
  167. package/src/cli/commands/conversations.ts +102 -17
  168. package/src/cli/commands/default-action.ts +10 -53
  169. package/src/cli/commands/notifications.ts +329 -317
  170. package/src/cli/commands/plugins.ts +185 -0
  171. package/src/cli/commands/schedules.ts +391 -0
  172. package/src/cli/commands/telemetry.ts +40 -0
  173. package/src/cli/lib/__tests__/cli-colors.test.ts +48 -0
  174. package/src/cli/lib/__tests__/confirm-prompt.test.ts +159 -0
  175. package/src/cli/lib/__tests__/install-from-github.test.ts +355 -0
  176. package/src/cli/lib/__tests__/list-installed-plugins.test.ts +154 -0
  177. package/src/cli/lib/__tests__/uninstall-plugin.test.ts +124 -0
  178. package/src/cli/lib/__tests__/unknown-command.test.ts +106 -0
  179. package/src/cli/lib/cli-colors.ts +12 -0
  180. package/src/cli/lib/confirm-prompt.ts +79 -0
  181. package/src/cli/lib/install-from-github.ts +304 -0
  182. package/src/cli/lib/list-installed-plugins.ts +137 -0
  183. package/src/cli/lib/uninstall-plugin.ts +82 -0
  184. package/src/cli/lib/unknown-command.ts +111 -0
  185. package/src/cli/program.ts +38 -2
  186. package/src/config/bundled-skills/app-builder/SKILL.md +23 -21
  187. package/src/config/bundled-skills/app-builder/TOOLS.json +7 -0
  188. package/src/config/bundled-skills/computer-use/TOOLS.json +15 -52
  189. package/src/config/bundled-skills/document/SKILL.md +23 -3
  190. package/src/config/bundled-skills/document/TOOLS.json +53 -0
  191. package/src/config/bundled-skills/document/tools/document-delete.ts +12 -0
  192. package/src/config/bundled-skills/document/tools/document-list.ts +12 -0
  193. package/src/config/bundled-skills/document/tools/document-read.ts +12 -0
  194. package/src/config/bundled-skills/skill-management/SKILL.md +2 -2
  195. package/src/config/bundled-skills/skill-management/TOOLS.json +7 -7
  196. package/src/config/bundled-tool-registry.ts +6 -0
  197. package/src/config/feature-flag-registry.json +41 -1
  198. package/src/config/loader.ts +64 -38
  199. package/src/config/schema.ts +7 -10
  200. package/src/config/schemas/__tests__/llm-request-logs.test.ts +36 -0
  201. package/src/config/schemas/channels.ts +8 -0
  202. package/src/config/schemas/compaction.ts +28 -0
  203. package/src/config/schemas/heartbeat.ts +9 -0
  204. package/src/config/schemas/llm-request-logs.ts +31 -7
  205. package/src/config/schemas/llm.ts +3 -0
  206. package/src/config/schemas/memory-retrieval.ts +18 -0
  207. package/src/config/schemas/tools.ts +14 -0
  208. package/src/config/skills.ts +3 -96
  209. package/src/context/compactor.ts +1047 -0
  210. package/src/context/token-estimator.ts +2 -2
  211. package/src/context/window-manager.ts +197 -1520
  212. package/src/credential-execution/managed-catalog.ts +37 -0
  213. package/src/credential-health/credential-health-service.ts +280 -19
  214. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +34 -0
  215. package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +138 -0
  216. package/src/daemon/__tests__/conversation-tool-setup.test.ts +74 -0
  217. package/src/daemon/approval-generators.ts +8 -6
  218. package/src/daemon/config-watcher.ts +94 -31
  219. package/src/daemon/conversation-agent-loop.ts +169 -9
  220. package/src/daemon/conversation-error.ts +171 -37
  221. package/src/daemon/conversation-lifecycle.ts +53 -40
  222. package/src/daemon/conversation-messaging.ts +25 -6
  223. package/src/daemon/conversation-process.ts +49 -12
  224. package/src/daemon/conversation-runtime-assembly.ts +16 -1
  225. package/src/daemon/conversation-slash.ts +12 -5
  226. package/src/daemon/conversation-store.ts +11 -4
  227. package/src/daemon/conversation-tool-setup.ts +39 -7
  228. package/src/daemon/conversation.ts +33 -1
  229. package/src/daemon/external-plugins-bootstrap.ts +217 -181
  230. package/src/daemon/first-greeting.ts +22 -2
  231. package/src/daemon/handlers/config-model.ts +6 -5
  232. package/src/daemon/handlers/config-slack-channel.ts +15 -3
  233. package/src/daemon/handlers/shared.ts +14 -5
  234. package/src/daemon/handlers/skills.ts +111 -108
  235. package/src/daemon/history-repair.ts +28 -1
  236. package/src/daemon/host-app-control-proxy.ts +98 -23
  237. package/src/daemon/lifecycle.ts +45 -35
  238. package/src/daemon/meet-host-supervisor.ts +5 -4
  239. package/src/daemon/memory-v2-startup.ts +49 -0
  240. package/src/daemon/message-protocol.ts +1 -0
  241. package/src/daemon/message-types/conversations.ts +25 -0
  242. package/src/daemon/message-types/messages.ts +61 -0
  243. package/src/daemon/message-types/subagents.ts +1 -0
  244. package/src/daemon/message-types/sync.ts +1 -0
  245. package/src/daemon/pkb-reminder-builder.test.ts +1 -1
  246. package/src/daemon/pkb-reminder-builder.ts +1 -1
  247. package/src/daemon/plugin-source-watcher.ts +146 -0
  248. package/src/daemon/process-message.ts +21 -3
  249. package/src/daemon/server.ts +11 -2
  250. package/src/daemon/skill-memory-refresh.ts +29 -0
  251. package/src/documents/document-store.ts +221 -3
  252. package/src/embedded/plugin-api.ts +40 -0
  253. package/src/filing/filing-service.ts +39 -0
  254. package/src/heartbeat/__tests__/heartbeat-service.test.ts +91 -6
  255. package/src/heartbeat/heartbeat-run-store.ts +2 -1
  256. package/src/heartbeat/heartbeat-service.ts +41 -0
  257. package/src/home/__tests__/feed-types.test.ts +40 -0
  258. package/src/home/feed-types.ts +22 -0
  259. package/src/home/post-connect-feed.ts +1 -0
  260. package/src/index.ts +18 -1
  261. package/src/live-voice/__tests__/live-voice-stt.test.ts +57 -0
  262. package/src/mcp/client.ts +20 -4
  263. package/src/media/image-credentials.ts +3 -3
  264. package/src/memory/__tests__/bookmark-crud.test.ts +33 -27
  265. package/src/memory/__tests__/conversation-queries.test.ts +263 -0
  266. package/src/memory/__tests__/jobs-worker-v2-graph-trigger-embed.test.ts +113 -0
  267. package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +119 -14
  268. package/src/memory/__tests__/message-content.test.ts +35 -0
  269. package/src/memory/bookmark-crud.ts +42 -10
  270. package/src/memory/context-search/sources/conversations.ts +62 -2
  271. package/src/memory/context-search/sources/workspace.ts +4 -0
  272. package/src/memory/conversation-crud.ts +63 -19
  273. package/src/memory/conversation-queries.ts +110 -10
  274. package/src/memory/db-init.ts +6 -0
  275. package/src/memory/delivery-crud.ts +152 -5
  276. package/src/memory/embedding-backend.ts +4 -4
  277. package/src/memory/external-conversation-store.ts +66 -5
  278. package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +66 -9
  279. package/src/memory/graph/conversation-graph-memory.ts +31 -15
  280. package/src/memory/graph/tools.ts +3 -3
  281. package/src/memory/indexer.ts +34 -29
  282. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +73 -0
  283. package/src/memory/jobs/embed-concept-page.ts +20 -11
  284. package/src/memory/jobs-worker.ts +6 -1
  285. package/src/memory/llm-request-log-source-clickhouse.ts +17 -10
  286. package/src/memory/llm-request-log-source.ts +19 -52
  287. package/src/memory/llm-usage-store.ts +125 -5
  288. package/src/memory/memory-retrospective-startup-cleanup.ts +72 -5
  289. package/src/memory/message-content.ts +1 -1
  290. package/src/memory/migrations/109-external-conversation-bindings.ts +15 -4
  291. package/src/memory/migrations/229-delete-private-conversations.test.ts +38 -1
  292. package/src/memory/migrations/229-delete-private-conversations.ts +7 -0
  293. package/src/memory/migrations/247-external-conversation-binding-thread-id.ts +78 -0
  294. package/src/memory/migrations/248-create-onboarding-events.ts +21 -0
  295. package/src/memory/migrations/249-normalize-slack-external-content.ts +240 -0
  296. package/src/memory/migrations/index.ts +6 -0
  297. package/src/memory/migrations/registry.ts +8 -0
  298. package/src/memory/onboarding-events-store.ts +106 -0
  299. package/src/memory/schema/bookmarks.ts +0 -2
  300. package/src/memory/schema/calls.ts +1 -0
  301. package/src/memory/schema/inference.ts +1 -3
  302. package/src/memory/schema/infrastructure.ts +12 -0
  303. package/src/memory/turn-events-store.ts +127 -2
  304. package/src/memory/v2/__tests__/activation.test.ts +0 -8
  305. package/src/memory/v2/__tests__/injection.test.ts +98 -8
  306. package/src/memory/v2/__tests__/migration.test.ts +87 -0
  307. package/src/memory/v2/__tests__/page-index.test.ts +83 -0
  308. package/src/memory/v2/__tests__/prompts-router.test.ts +58 -6
  309. package/src/memory/v2/__tests__/qdrant.test.ts +66 -3
  310. package/src/memory/v2/__tests__/router.test.ts +15 -0
  311. package/src/memory/v2/__tests__/skill-store.test.ts +387 -8
  312. package/src/memory/v2/injection.ts +32 -6
  313. package/src/memory/v2/migration.ts +49 -19
  314. package/src/memory/v2/page-index.ts +35 -5
  315. package/src/memory/v2/prompts/router.ts +11 -8
  316. package/src/memory/v2/prompts/sweep.ts +2 -2
  317. package/src/memory/v2/qdrant.ts +135 -7
  318. package/src/memory/v2/router.ts +9 -8
  319. package/src/memory/v2/skill-store.ts +120 -35
  320. package/src/messaging/providers/slack/__tests__/adapter-token-routing.test.ts +45 -5
  321. package/src/messaging/providers/slack/__tests__/download.test.ts +231 -0
  322. package/src/messaging/providers/slack/adapter.ts +43 -5
  323. package/src/messaging/providers/slack/client.ts +27 -0
  324. package/src/messaging/providers/slack/deep-link.ts +65 -0
  325. package/src/messaging/providers/slack/download.ts +104 -0
  326. package/src/messaging/providers/slack/message-metadata.test.ts +32 -0
  327. package/src/messaging/providers/slack/message-metadata.ts +27 -0
  328. package/src/messaging/providers/slack/render-transcript.test.ts +134 -0
  329. package/src/messaging/providers/slack/render-transcript.ts +69 -5
  330. package/src/messaging/providers/slack/types.ts +20 -1
  331. package/src/notifications/conversation-pairing.ts +2 -1
  332. package/src/notifications/decision-engine.ts +2 -1
  333. package/src/notifications/emit-signal.ts +20 -1
  334. package/src/notifications/home-feed-side-effect.ts +54 -0
  335. package/src/notifications/signal.ts +3 -1
  336. package/src/oauth/connection-resolver.ts +8 -4
  337. package/src/oauth/platform-connection.ts +6 -2
  338. package/src/oauth/seed-providers.ts +10 -1
  339. package/src/permissions/checker.ts +2 -0
  340. package/src/permissions/ipc-risk-types.ts +1 -0
  341. package/src/permissions/question-prompter.test.ts +416 -0
  342. package/src/permissions/question-prompter.ts +294 -0
  343. package/src/platform/client.test.ts +1 -1
  344. package/src/platform/client.ts +1 -1
  345. package/src/plugin-api/constants.ts +26 -0
  346. package/src/plugin-api/index.ts +34 -1
  347. package/src/plugin-api/types.ts +104 -22
  348. package/src/plugins/defaults/circuit-breaker.ts +0 -5
  349. package/src/plugins/defaults/compaction.ts +0 -4
  350. package/src/plugins/defaults/empty-response.ts +0 -2
  351. package/src/plugins/defaults/history-repair.ts +0 -2
  352. package/src/plugins/defaults/injectors.ts +36 -3
  353. package/src/plugins/defaults/llm-call.ts +0 -2
  354. package/src/plugins/defaults/memory-retrieval.ts +0 -1
  355. package/src/plugins/defaults/overflow-reduce.ts +0 -1
  356. package/src/plugins/defaults/persistence.ts +0 -2
  357. package/src/plugins/defaults/title-generate.ts +0 -5
  358. package/src/plugins/defaults/token-estimate.ts +0 -2
  359. package/src/plugins/defaults/tool-error.ts +0 -7
  360. package/src/plugins/defaults/tool-execute.ts +0 -2
  361. package/src/plugins/defaults/tool-result-truncate.ts +0 -4
  362. package/src/plugins/ensure-plugin-api-shim.ts +96 -0
  363. package/src/plugins/external-api.ts +104 -0
  364. package/src/plugins/external-plugin-loader.ts +105 -32
  365. package/src/plugins/feature-gate.ts +22 -0
  366. package/src/plugins/pipeline.ts +37 -0
  367. package/src/plugins/registry.ts +48 -80
  368. package/src/plugins/types.ts +31 -26
  369. package/src/plugins/user-loader.ts +21 -2
  370. package/src/proactive-artifact/aux-message-injector.ts +11 -0
  371. package/src/proactive-artifact/job.test.ts +37 -5
  372. package/src/prompts/__tests__/system-prompt.test.ts +12 -0
  373. package/src/prompts/__tests__/task-progress-hint-section.test.ts +99 -0
  374. package/src/prompts/normalize-onboarding.ts +27 -0
  375. package/src/prompts/sections.ts +302 -0
  376. package/src/prompts/system-prompt.ts +63 -166
  377. package/src/prompts/templates/BOOTSTRAP.md +17 -1
  378. package/src/prompts/templates/system-sections.ts +173 -0
  379. package/src/providers/__tests__/inference.test.ts +22 -7
  380. package/src/providers/anthropic/client.ts +28 -28
  381. package/src/providers/connection-resolution.ts +7 -0
  382. package/src/providers/inference/adapter-factory.ts +41 -4
  383. package/src/providers/inference/connections.ts +74 -29
  384. package/src/providers/inference/resolve-auth.ts +12 -4
  385. package/src/providers/model-catalog.ts +294 -12
  386. package/src/providers/openai/chat-completions-provider.ts +10 -2
  387. package/src/providers/openrouter/client.ts +7 -0
  388. package/src/providers/{managed-proxy → platform-proxy}/constants.ts +4 -1
  389. package/src/providers/{managed-proxy → platform-proxy}/context.ts +3 -3
  390. package/src/providers/provider-availability.ts +17 -2
  391. package/src/providers/provider-catalog-visibility.ts +36 -0
  392. package/src/providers/registry.ts +22 -14
  393. package/src/providers/retry.ts +47 -1
  394. package/src/runtime/__tests__/agent-wake.test.ts +152 -0
  395. package/src/runtime/agent-wake.ts +42 -14
  396. package/src/runtime/auth/route-policy.ts +8 -1
  397. package/src/runtime/btw-sidechain.ts +2 -0
  398. package/src/runtime/http-types.ts +19 -0
  399. package/src/runtime/migrations/origin-mode.ts +1 -1
  400. package/src/runtime/pending-interactions.ts +1 -0
  401. package/src/runtime/routes/__tests__/bookmark-routes.test.ts +17 -0
  402. package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +5 -1
  403. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +107 -20
  404. package/src/runtime/routes/__tests__/question-routes.test.ts +395 -0
  405. package/src/runtime/routes/__tests__/tts-routes.test.ts +64 -1
  406. package/src/runtime/routes/acp-routes-list.test.ts +143 -0
  407. package/src/runtime/routes/acp-routes.ts +5 -3
  408. package/src/runtime/routes/auth-routes.ts +1 -1
  409. package/src/runtime/routes/bookmark-routes.ts +5 -3
  410. package/src/runtime/routes/btw-routes.ts +5 -1
  411. package/src/runtime/routes/channel-availability-routes.ts +121 -0
  412. package/src/runtime/routes/conversation-cli-routes.ts +44 -3
  413. package/src/runtime/routes/conversation-list-routes.ts +3 -20
  414. package/src/runtime/routes/conversation-management-routes.ts +17 -42
  415. package/src/runtime/routes/conversation-query-routes.ts +40 -35
  416. package/src/runtime/routes/conversation-routes.ts +90 -11
  417. package/src/runtime/routes/documents-routes.ts +25 -86
  418. package/src/runtime/routes/group-routes.ts +5 -0
  419. package/src/runtime/routes/inbound-conversation.ts +28 -8
  420. package/src/runtime/routes/inbound-message-handler.ts +236 -41
  421. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +111 -0
  422. package/src/runtime/routes/inbound-stages/background-dispatch.ts +32 -1
  423. package/src/runtime/routes/inbound-stages/edit-intercept.ts +17 -4
  424. package/src/runtime/routes/index.ts +6 -0
  425. package/src/runtime/routes/inference-profile-session-handler.ts +17 -44
  426. package/src/runtime/routes/inference-profile-session-reaper.ts +7 -21
  427. package/src/runtime/routes/inference-provider-connection-routes.ts +65 -21
  428. package/src/runtime/routes/integrations/slack/share.ts +4 -52
  429. package/src/runtime/routes/integrations/slack/token.ts +43 -0
  430. package/src/runtime/routes/integrations/twilio.ts +6 -13
  431. package/src/runtime/routes/notification-routes.ts +1 -1
  432. package/src/runtime/routes/oauth-commands-routes.ts +105 -15
  433. package/src/runtime/routes/oauth-lifecycle-routes.ts +43 -0
  434. package/src/runtime/routes/question-routes.ts +259 -0
  435. package/src/runtime/routes/rename-conversation-routes.ts +2 -33
  436. package/src/runtime/routes/schedule-routes.ts +4 -7
  437. package/src/runtime/routes/subagents-routes.ts +57 -18
  438. package/src/runtime/routes/telemetry-routes.ts +27 -0
  439. package/src/runtime/routes/tts-routes.ts +27 -2
  440. package/src/runtime/routes/workspace-routes.test.ts +43 -0
  441. package/src/runtime/routes/workspace-routes.ts +28 -0
  442. package/src/runtime/services/conversation-serializer.ts +39 -7
  443. package/src/runtime/sync/resource-sync-events.ts +93 -1
  444. package/src/schedule/schedule-store.ts +27 -2
  445. package/src/schedule/scheduler.ts +9 -1
  446. package/src/security/__tests__/untrusted-content.test.ts +86 -0
  447. package/src/security/untrusted-content.ts +93 -8
  448. package/src/skills/catalog-files.ts +1 -1
  449. package/src/skills/catalog-install.ts +233 -116
  450. package/src/skills/clawhub.ts +70 -13
  451. package/src/skills/managed-store.ts +4 -119
  452. package/src/skills/skillssh-registry.ts +27 -48
  453. package/src/subagent/manager.ts +15 -7
  454. package/src/telemetry/types.ts +113 -1
  455. package/src/telemetry/usage-telemetry-reporter.test.ts +312 -5
  456. package/src/telemetry/usage-telemetry-reporter.ts +113 -7
  457. package/src/tools/apps/executors.ts +58 -7
  458. package/src/tools/ask-question/ask-question-tool.test.ts +509 -0
  459. package/src/tools/ask-question/ask-question-tool.ts +304 -0
  460. package/src/tools/browser/browser-execution.ts +15 -11
  461. package/src/tools/computer-use/definitions.ts +3 -3
  462. package/src/tools/credentials/vault.ts +1 -1
  463. package/src/tools/document/document-tool.ts +124 -1
  464. package/src/tools/filesystem/edit.ts +1 -1
  465. package/src/tools/filesystem/list.ts +1 -1
  466. package/src/tools/filesystem/read.ts +1 -1
  467. package/src/tools/filesystem/write.ts +5 -2
  468. package/src/tools/host-filesystem/transfer.ts +1 -1
  469. package/src/tools/host-terminal/host-shell.ts +1 -1
  470. package/src/tools/permission-checker.ts +1 -1
  471. package/src/tools/registry.ts +17 -7
  472. package/src/tools/schedule/create.ts +2 -2
  473. package/src/tools/schema-transforms.ts +7 -2
  474. package/src/tools/side-effects.ts +1 -0
  475. package/src/tools/skills/delete-managed.ts +4 -4
  476. package/src/tools/skills/execute.ts +1 -1
  477. package/src/tools/skills/scaffold-managed.ts +3 -2
  478. package/src/tools/subagent/notify-parent.ts +1 -1
  479. package/src/tools/system/request-permission.ts +2 -2
  480. package/src/tools/terminal/safe-env.ts +60 -1
  481. package/src/tools/tool-manifest.ts +2 -0
  482. package/src/tools/types.ts +72 -21
  483. package/src/tools/ui-surface/definitions.ts +6 -5
  484. package/src/tts/__tests__/provider-adapters.test.ts +76 -2
  485. package/src/tts/providers/elevenlabs-provider.ts +75 -1
  486. package/src/types/onboarding-context.ts +2 -0
  487. package/src/util/errors.ts +17 -0
  488. package/src/util/platform.ts +10 -0
  489. package/src/watcher/__tests__/engine.test.ts +22 -0
  490. package/src/watcher/engine.ts +6 -2
  491. package/src/workspace/migrations/057-repair-stale-gemini-model-ids.ts +80 -15
  492. package/src/workspace/migrations/072-seed-reply-suggestion-callsite.ts +35 -22
  493. package/src/workspace/migrations/073-repair-recall-callsite-empty-profile.ts +3 -1
  494. package/src/workspace/migrations/083-system-prompt-prefix-to-file.ts +191 -0
  495. package/src/workspace/migrations/084-remove-legacy-skills-index.ts +276 -0
  496. package/src/workspace/migrations/085-memory-v2-bm25-b-reembed-disabled-v2-pages.ts +137 -0
  497. package/src/workspace/migrations/086-revert-stale-gemini-mis-rewrites.ts +198 -0
  498. package/src/workspace/migrations/registry.ts +8 -0
  499. package/src/workspace/migrations/runner.ts +39 -9
  500. package/src/workspace/migrations/types.ts +4 -0
  501. package/examples/plugins/echo/bun.lock +0 -25
  502. package/src/__tests__/context-window-manager.test.ts +0 -2481
  503. package/src/context/__tests__/compact-prompt.test.ts +0 -63
  504. package/src/context/prompts/compact.md +0 -26
  505. package/src/prompts/__tests__/build-cli-reference-section.test.ts +0 -37
  506. /package/src/__tests__/{secret-routes-managed-proxy.test.ts → secret-routes-platform-proxy.test.ts} +0 -0
@@ -24,11 +24,7 @@
24
24
  "properties": {
25
25
  "click_type": {
26
26
  "type": "string",
27
- "enum": [
28
- "single",
29
- "double",
30
- "right"
31
- ],
27
+ "enum": ["single", "double", "right"],
32
28
  "description": "Type of click to perform (default: \"single\")"
33
29
  },
34
30
  "element_id": {
@@ -52,9 +48,7 @@
52
48
  "description": "ID of the specific client to target. Required when multiple clients support host_cu; omit when only one is connected. Obtain IDs from `assistant clients list --capability host_cu`."
53
49
  }
54
50
  },
55
- "required": [
56
- "reasoning"
57
- ]
51
+ "required": ["reasoning"]
58
52
  },
59
53
  "executor": "tools/computer-use-click.ts",
60
54
  "execution_target": "host"
@@ -80,10 +74,7 @@
80
74
  "description": "ID of the specific client to target. Required when multiple clients support host_cu; omit when only one is connected. Obtain IDs from `assistant clients list --capability host_cu`."
81
75
  }
82
76
  },
83
- "required": [
84
- "text",
85
- "reasoning"
86
- ]
77
+ "required": ["text", "reasoning"]
87
78
  },
88
79
  "executor": "tools/computer-use-type-text.ts",
89
80
  "execution_target": "host"
@@ -109,10 +100,7 @@
109
100
  "description": "ID of the specific client to target. Required when multiple clients support host_cu; omit when only one is connected. Obtain IDs from `assistant clients list --capability host_cu`."
110
101
  }
111
102
  },
112
- "required": [
113
- "key",
114
- "reasoning"
115
- ]
103
+ "required": ["key", "reasoning"]
116
104
  },
117
105
  "executor": "tools/computer-use-key.ts",
118
106
  "execution_target": "host"
@@ -139,12 +127,7 @@
139
127
  },
140
128
  "direction": {
141
129
  "type": "string",
142
- "enum": [
143
- "up",
144
- "down",
145
- "left",
146
- "right"
147
- ],
130
+ "enum": ["up", "down", "left", "right"],
148
131
  "description": "Scroll direction"
149
132
  },
150
133
  "amount": {
@@ -160,11 +143,7 @@
160
143
  "description": "ID of the specific client to target. Required when multiple clients support host_cu; omit when only one is connected. Obtain IDs from `assistant clients list --capability host_cu`."
161
144
  }
162
145
  },
163
- "required": [
164
- "direction",
165
- "amount",
166
- "reasoning"
167
- ]
146
+ "required": ["direction", "amount", "reasoning"]
168
147
  },
169
148
  "executor": "tools/computer-use-scroll.ts",
170
149
  "execution_target": "host"
@@ -210,9 +189,7 @@
210
189
  "description": "ID of the specific client to target. Required when multiple clients support host_cu; omit when only one is connected. Obtain IDs from `assistant clients list --capability host_cu`."
211
190
  }
212
191
  },
213
- "required": [
214
- "reasoning"
215
- ]
192
+ "required": ["reasoning"]
216
193
  },
217
194
  "executor": "tools/computer-use-drag.ts",
218
195
  "execution_target": "host"
@@ -238,10 +215,7 @@
238
215
  "description": "ID of the specific client to target. Required when multiple clients support host_cu; omit when only one is connected. Obtain IDs from `assistant clients list --capability host_cu`."
239
216
  }
240
217
  },
241
- "required": [
242
- "duration_ms",
243
- "reasoning"
244
- ]
218
+ "required": ["duration_ms", "reasoning"]
245
219
  },
246
220
  "executor": "tools/computer-use-wait.ts",
247
221
  "execution_target": "host"
@@ -267,17 +241,14 @@
267
241
  "description": "ID of the specific client to target. Required when multiple clients support host_cu; omit when only one is connected. Obtain IDs from `assistant clients list --capability host_cu`."
268
242
  }
269
243
  },
270
- "required": [
271
- "app_name",
272
- "reasoning"
273
- ]
244
+ "required": ["app_name", "reasoning"]
274
245
  },
275
246
  "executor": "tools/computer-use-open-app.ts",
276
247
  "execution_target": "host"
277
248
  },
278
249
  {
279
250
  "name": "computer_use_run_applescript",
280
- "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).",
251
+ "description": "Run an AppleScript command. Prefer this over click/type when possible - it doesn't move the cursor or interrupt foreground activity. Never use 'do shell script' inside AppleScript (blocked for security).",
281
252
  "category": "computer-use",
282
253
  "risk": "medium",
283
254
  "input_schema": {
@@ -296,10 +267,7 @@
296
267
  "description": "ID of the specific client to target. Required when multiple clients support host_cu; omit when only one is connected. Obtain IDs from `assistant clients list --capability host_cu`."
297
268
  }
298
269
  },
299
- "required": [
300
- "script",
301
- "reasoning"
302
- ]
270
+ "required": ["script", "reasoning"]
303
271
  },
304
272
  "executor": "tools/computer-use-run-applescript.ts",
305
273
  "execution_target": "host"
@@ -317,16 +285,14 @@
317
285
  "description": "Human-readable summary of what was accomplished"
318
286
  }
319
287
  },
320
- "required": [
321
- "summary"
322
- ]
288
+ "required": ["summary"]
323
289
  },
324
290
  "executor": "tools/computer-use-done.ts",
325
291
  "execution_target": "host"
326
292
  },
327
293
  {
328
294
  "name": "computer_use_respond",
329
- "description": "Respond to the user with a text answer instead of performing computer actions. Use this when you can answer directly without interacting with the screen.",
295
+ "description": "Reply with a text answer instead of performing computer actions. Use this when you can answer directly without interacting with the screen.",
330
296
  "category": "computer-use",
331
297
  "risk": "low",
332
298
  "input_schema": {
@@ -334,17 +300,14 @@
334
300
  "properties": {
335
301
  "answer": {
336
302
  "type": "string",
337
- "description": "The text answer to display to the user"
303
+ "description": "The text answer to display"
338
304
  },
339
305
  "reasoning": {
340
306
  "type": "string",
341
307
  "description": "Explanation of how you determined the answer"
342
308
  }
343
309
  },
344
- "required": [
345
- "answer",
346
- "reasoning"
347
- ]
310
+ "required": ["answer", "reasoning"]
348
311
  },
349
312
  "executor": "tools/computer-use-respond.ts",
350
313
  "execution_target": "host"
@@ -18,13 +18,33 @@ Create and edit long-form documents using the built-in rich text editor. Documen
18
18
 
19
19
  - **document_create** - Opens a new document editor with an optional title and initial Markdown content. Returns a `surface_id` for subsequent updates.
20
20
  - **document_update** - Updates content in an open document editor by `surface_id`. Supports `replace` (overwrite) and `append` (add to end) modes.
21
+ - **document_read** - Reads the current content of a document by `surface_id` when it belongs to the current conversation, or when the current actor is the guardian/local user. Use to verify content before editing.
22
+ - **document_list** - Lists documents. Without `query`, lists the current conversation's documents. With `query`, searches by title; guardian/local users can search across conversations, while other actors are scoped to the current conversation.
23
+ - **document_delete** - Deletes a document by `surface_id`. Use to clean up unwanted documents.
21
24
 
22
- ## Workflow
25
+ ## Retrieving existing documents
26
+
27
+ When the user asks to see, open, or pull up a document:
28
+
29
+ 1. Check the `<active_documents>` block in your context — it lists all documents in this conversation with their `surface_id` and title. If the document is there, call `document_read` with its `surface_id`. Done in one call.
30
+ 2. If the document is NOT in `<active_documents>`, call `document_list` with a `query` matching the document title. For guardian/local users, this searches across previous conversations and sessions.
31
+ 3. Once you have the `surface_id`, call `document_read` to retrieve the content.
32
+
33
+ **Never** search the filesystem, conversation history, or archives to find a document. Always use `document_list` with a `query`.
34
+
35
+ ## Creating a new document
23
36
 
24
37
  1. **Create the document**: Call `document_create` with a title (inferred from the request). Call the tool immediately, not after conversational preamble.
25
- 2. **Write content in Markdown**: Use proper structure (`#` for titles, `##` for sections), **bold**, *italic*, code blocks, tables, lists, blockquotes as appropriate.
38
+ 2. **Write content in Markdown**: Use proper structure (`#` for titles, `##` for sections), **bold**, _italic_, code blocks, tables, lists, blockquotes as appropriate.
26
39
  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.
27
- 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.
40
+
41
+ ## Editing an existing document
42
+
43
+ When the user requests changes to a document:
44
+
45
+ 1. Find the `surface_id` from the `<active_documents>` context block.
46
+ 2. Use `document_update` with the existing `surface_id` — do NOT call `document_create` again.
47
+ 3. Use `mode: "replace"` for full rewrites or `mode: "append"` for additions.
28
48
 
29
49
  ## Usage Notes
30
50
 
@@ -48,6 +48,59 @@
48
48
  },
49
49
  "executor": "tools/document-update.ts",
50
50
  "execution_target": "host"
51
+ },
52
+ {
53
+ "name": "document_read",
54
+ "description": "Read the current content of a document by its surface_id when it belongs to the current conversation, or when the current actor is the guardian/local user. Use this to verify document state before making edits.",
55
+ "category": "document",
56
+ "risk": "low",
57
+ "input_schema": {
58
+ "type": "object",
59
+ "properties": {
60
+ "surface_id": {
61
+ "type": "string",
62
+ "description": "The ID of the document to read"
63
+ }
64
+ },
65
+ "required": ["surface_id"]
66
+ },
67
+ "executor": "tools/document-read.ts",
68
+ "execution_target": "host"
69
+ },
70
+ {
71
+ "name": "document_list",
72
+ "description": "List documents. Without a query, lists documents in the current conversation. With a query, searches documents by title; guardian/local users can search across conversations, while other actors are scoped to the current conversation.",
73
+ "category": "document",
74
+ "risk": "low",
75
+ "input_schema": {
76
+ "type": "object",
77
+ "properties": {
78
+ "query": {
79
+ "type": "string",
80
+ "description": "Search documents by title. Omit to list only the current conversation's documents."
81
+ }
82
+ }
83
+ },
84
+ "executor": "tools/document-list.ts",
85
+ "execution_target": "host"
86
+ },
87
+ {
88
+ "name": "document_delete",
89
+ "description": "Delete a document by its surface_id.",
90
+ "category": "document",
91
+ "risk": "low",
92
+ "input_schema": {
93
+ "type": "object",
94
+ "properties": {
95
+ "surface_id": {
96
+ "type": "string",
97
+ "description": "The ID of the document to delete"
98
+ }
99
+ },
100
+ "required": ["surface_id"]
101
+ },
102
+ "executor": "tools/document-delete.ts",
103
+ "execution_target": "host"
51
104
  }
52
105
  ]
53
106
  }
@@ -0,0 +1,12 @@
1
+ import { executeDocumentDelete } from "../../../../tools/document/document-tool.js";
2
+ import type {
3
+ ToolContext,
4
+ ToolExecutionResult,
5
+ } from "../../../../tools/types.js";
6
+
7
+ export async function run(
8
+ input: Record<string, unknown>,
9
+ context: ToolContext,
10
+ ): Promise<ToolExecutionResult> {
11
+ return executeDocumentDelete(input, context);
12
+ }
@@ -0,0 +1,12 @@
1
+ import { executeDocumentList } from "../../../../tools/document/document-tool.js";
2
+ import type {
3
+ ToolContext,
4
+ ToolExecutionResult,
5
+ } from "../../../../tools/types.js";
6
+
7
+ export async function run(
8
+ input: Record<string, unknown>,
9
+ context: ToolContext,
10
+ ): Promise<ToolExecutionResult> {
11
+ return executeDocumentList(input, context);
12
+ }
@@ -0,0 +1,12 @@
1
+ import { executeDocumentRead } from "../../../../tools/document/document-tool.js";
2
+ import type {
3
+ ToolContext,
4
+ ToolExecutionResult,
5
+ } from "../../../../tools/types.js";
6
+
7
+ export async function run(
8
+ input: Record<string, unknown>,
9
+ context: ToolContext,
10
+ ): Promise<ToolExecutionResult> {
11
+ return executeDocumentRead(input, context);
12
+ }
@@ -18,6 +18,6 @@ Manage the lifecycle of custom managed skills in `{workspaceDir}/skills`.
18
18
  ## Capabilities
19
19
 
20
20
  - **Scaffold** a new managed skill with YAML frontmatter and markdown body
21
- - **Delete** an existing managed skill and remove it from the SKILLS.md index
21
+ - **Delete** an existing managed skill directory
22
22
 
23
- Skills created via `scaffold_managed_skill` become available for `skill_load` immediately.
23
+ Skills created via `scaffold_managed_skill` become available for `skill_load` when a valid top-level `SKILL.md` is written under the skill directory.
@@ -3,7 +3,7 @@
3
3
  "tools": [
4
4
  {
5
5
  "name": "scaffold_managed_skill",
6
- "description": "Create or update a managed skill in {workspaceDir}/skills. The skill becomes available for skill_load immediately. Never persist a skill without explicit user consent. Before persisting, test the snippet: write to a temp file with bash and run with `bun run /tmp/vellum-eval/snippet.ts`. Iterate up to 3 attempts, then ask the user. Clean up temp files after. Do not use file_write for temp files outside the working directory. After a skill is written, the next turn may run in a recreated conversation due to file-watcher eviction - continue normally.",
6
+ "description": "Create or update a managed skill in {workspaceDir}/skills. The skill becomes available for skill_load when a valid top-level SKILL.md is written under the skill directory. Never persist a skill without explicit user consent. Before persisting, test the snippet: write to a temp file with bash and run with `bun run /tmp/vellum-eval/snippet.ts`. Iterate up to 3 attempts, then ask the user. Clean up temp files after. Do not use file_write for temp files outside the working directory. After a skill is written, the next turn may run in a recreated conversation due to file-watcher eviction - continue normally.",
7
7
  "category": "skills",
8
8
  "risk": "high",
9
9
  "input_schema": {
@@ -33,14 +33,14 @@
33
33
  "type": "boolean",
34
34
  "description": "Whether to overwrite an existing skill with the same ID (default: false)."
35
35
  },
36
- "add_to_index": {
37
- "type": "boolean",
38
- "description": "Whether to add the skill to SKILLS.md index (default: true)."
39
- },
40
36
  "includes": {
41
37
  "type": "array",
42
38
  "items": { "type": "string" },
43
39
  "description": "Optional list of child skill IDs that this skill includes (metadata only, no auto-activation)."
40
+ },
41
+ "add_to_index": {
42
+ "type": "boolean",
43
+ "description": "Deprecated no-op compatibility field. Skills are discovered from top-level SKILL.md files."
44
44
  }
45
45
  },
46
46
  "required": ["skill_id", "name", "description", "body_markdown"]
@@ -50,7 +50,7 @@
50
50
  },
51
51
  {
52
52
  "name": "delete_managed_skill",
53
- "description": "Delete a managed skill from {workspaceDir}/skills and remove it from the SKILLS.md index. Never delete a skill without explicit user confirmation. After deletion, the next turn may run in a recreated conversation due to file-watcher eviction - continue normally.",
53
+ "description": "Delete a managed skill directory from {workspaceDir}/skills. Never delete a skill without explicit user confirmation. After deletion, the next turn may run in a recreated conversation due to file-watcher eviction - continue normally.",
54
54
  "category": "skills",
55
55
  "risk": "high",
56
56
  "input_schema": {
@@ -62,7 +62,7 @@
62
62
  },
63
63
  "remove_from_index": {
64
64
  "type": "boolean",
65
- "description": "Whether to remove the skill from SKILLS.md index (default: true)."
65
+ "description": "Deprecated no-op compatibility field. Skill deletion does not edit SKILLS.md."
66
66
  }
67
67
  },
68
68
  "required": ["skill_id"]
@@ -52,6 +52,9 @@ import * as contactSearch from "./bundled-skills/contacts/tools/contact-search.j
52
52
  import * as googleContacts from "./bundled-skills/contacts/tools/google-contacts.js";
53
53
  // ── document ───────────────────────────────────────────────────────────────────
54
54
  import * as documentCreate from "./bundled-skills/document/tools/document-create.js";
55
+ import * as documentDelete from "./bundled-skills/document/tools/document-delete.js";
56
+ import * as documentList from "./bundled-skills/document/tools/document-list.js";
57
+ import * as documentRead from "./bundled-skills/document/tools/document-read.js";
55
58
  import * as documentUpdate from "./bundled-skills/document/tools/document-update.js";
56
59
  // ── followups ──────────────────────────────────────────────────────────────────
57
60
  import * as followupCreate from "./bundled-skills/followups/tools/followup-create.js";
@@ -168,6 +171,9 @@ export const bundledToolRegistry = new Map<string, SkillToolScript>([
168
171
 
169
172
  // document
170
173
  ["document:tools/document-create.ts", documentCreate],
174
+ ["document:tools/document-delete.ts", documentDelete],
175
+ ["document:tools/document-list.ts", documentList],
176
+ ["document:tools/document-read.ts", documentRead],
171
177
  ["document:tools/document-update.ts", documentUpdate],
172
178
 
173
179
  // followups
@@ -281,6 +281,14 @@
281
281
  "description": "Enable the app-control skill (per-app screenshot + raw input bypassing AX tree)",
282
282
  "defaultEnabled": false
283
283
  },
284
+ {
285
+ "id": "species-migration",
286
+ "scope": "assistant",
287
+ "key": "species-migration",
288
+ "label": "Species Migration",
289
+ "description": "Enable the Species Migration skill for migrating from OpenClaw, Hermes, Manus, and other assistant species into Vellum.",
290
+ "defaultEnabled": false
291
+ },
284
292
  {
285
293
  "id": "analyze-conversation",
286
294
  "scope": "assistant",
@@ -294,7 +302,39 @@
294
302
  "scope": "assistant",
295
303
  "key": "pro-plan-adjust",
296
304
  "label": "Pro Plan Adjust",
297
- "description": "Show the rich Plan card (current plan, features, Manage/Upgrade CTA) at the top of the macOS Settings Billing tab.",
305
+ "description": "Show the rich Plan card (current plan, features, Manage/Upgrade CTA) at the top of the macOS Settings \u2192 Billing tab.",
306
+ "defaultEnabled": false
307
+ },
308
+ {
309
+ "id": "external-plugins",
310
+ "scope": "assistant",
311
+ "key": "external-plugins",
312
+ "label": "External Plugins",
313
+ "description": "Enable the external-plugin install path: the `assistant plugins` CLI subcommand and the declarative external-plugin loader convention (`<workspaceDir>/plugins/<name>/` directories containing `package.json` plus interface dirs). Gates an unstable surface that may change shape before stabilizing.",
314
+ "defaultEnabled": false
315
+ },
316
+ {
317
+ "id": "provider-zai",
318
+ "scope": "assistant",
319
+ "key": "provider-zai",
320
+ "label": "z.ai Provider",
321
+ "description": "Enable the z.ai (Zhipu AI) provider and its GLM models in the provider picker and model selection UI",
322
+ "defaultEnabled": false
323
+ },
324
+ {
325
+ "id": "provider-deepseek",
326
+ "scope": "assistant",
327
+ "key": "provider-deepseek",
328
+ "label": "DeepSeek Provider",
329
+ "description": "Enable the DeepSeek direct API provider and its models (V4 Pro, V4 Flash) in the provider picker and model selection UI",
330
+ "defaultEnabled": false
331
+ },
332
+ {
333
+ "id": "provider-minimax",
334
+ "scope": "assistant",
335
+ "key": "provider-minimax",
336
+ "label": "MiniMax Provider",
337
+ "description": "Enable the MiniMax direct API provider and its models (M2.7, M2.5, M2.1, M2, and highspeed variants) in the provider picker and model selection UI",
298
338
  "defaultEnabled": false
299
339
  }
300
340
  ]
@@ -25,6 +25,7 @@ const log = getLogger("config");
25
25
  let cached: AssistantConfig | null = null;
26
26
  let cachedFileSignature: ConfigFileSignature | null = null;
27
27
  let loading = false;
28
+ let suppressConfigDiskWritesDepth = 0;
28
29
 
29
30
  type ConfigFileSignature =
30
31
  | {
@@ -683,49 +684,54 @@ export function loadConfig(): AssistantConfig {
683
684
  configFileExisted = false;
684
685
  }
685
686
 
686
- // Warn about and strip deprecated config fields so users know their
687
- // settings are no longer honored rather than silently dropping them.
688
- warnAndStripDeprecatedFields(fileConfig, configPath);
687
+ if (suppressConfigDiskWritesDepth === 0) {
688
+ warnAndStripDeprecatedFields(fileConfig, configPath);
689
+ }
689
690
 
690
691
  // Validate and apply defaults via Zod schema
691
692
  let config = validateWithSchema(fileConfig);
692
693
 
693
- // Managed Gemini embedding defaults migration.
694
- // When on a managed platform (IS_PLATFORM=true) with the feature flag
695
- // enabled and no explicit embedding provider chosen (provider=auto),
696
- // persist Gemini embedding defaults into the raw config file.
697
- // Idempotent: once provider=gemini is written, subsequent loads skip this.
698
- if (config.memory.embeddings.provider === "auto") {
699
- try {
700
- if (
701
- (process.env.IS_PLATFORM === "true" ||
702
- process.env.IS_PLATFORM === "1") &&
703
- isManagedGeminiFFEnabled(config)
704
- ) {
705
- setNestedValue(fileConfig, "memory.embeddings.provider", "gemini");
706
- setNestedValue(
707
- fileConfig,
708
- "memory.embeddings.geminiModel",
709
- "gemini-embedding-2",
710
- );
711
- setNestedValue(
712
- fileConfig,
713
- "memory.embeddings.geminiDimensions",
714
- 3072,
715
- );
716
- setNestedValue(fileConfig, "memory.qdrant.vectorSize", 3072);
717
- writeFileSync(configPath, JSON.stringify(fileConfig, null, 2) + "\n");
718
- log.info(
719
- "Applied managed Gemini embedding defaults (provider=gemini, model=gemini-embedding-2, dimensions=3072, vectorSize=3072)",
694
+ if (suppressConfigDiskWritesDepth === 0) {
695
+ // Managed Gemini embedding defaults migration.
696
+ // When on a managed platform (IS_PLATFORM=true) with the feature flag
697
+ // enabled and no explicit embedding provider chosen (provider=auto),
698
+ // persist Gemini embedding defaults into the raw config file.
699
+ // Idempotent: once provider=gemini is written, subsequent loads skip this.
700
+ if (config.memory.embeddings.provider === "auto") {
701
+ try {
702
+ if (
703
+ (process.env.IS_PLATFORM === "true" ||
704
+ process.env.IS_PLATFORM === "1") &&
705
+ isManagedGeminiFFEnabled(config)
706
+ ) {
707
+ setNestedValue(fileConfig, "memory.embeddings.provider", "gemini");
708
+ setNestedValue(
709
+ fileConfig,
710
+ "memory.embeddings.geminiModel",
711
+ "gemini-embedding-2",
712
+ );
713
+ setNestedValue(
714
+ fileConfig,
715
+ "memory.embeddings.geminiDimensions",
716
+ 3072,
717
+ );
718
+ setNestedValue(fileConfig, "memory.qdrant.vectorSize", 3072);
719
+ writeFileSync(
720
+ configPath,
721
+ JSON.stringify(fileConfig, null, 2) + "\n",
722
+ );
723
+ log.info(
724
+ "Applied managed Gemini embedding defaults (provider=gemini, model=gemini-embedding-2, dimensions=3072, vectorSize=3072)",
725
+ );
726
+ // Re-validate so the returned config reflects the migration.
727
+ config = validateWithSchema(fileConfig);
728
+ }
729
+ } catch (err) {
730
+ log.warn(
731
+ { err },
732
+ "Managed Gemini defaults migration failed — continuing with existing config",
720
733
  );
721
- // Re-validate so the returned config reflects the migration.
722
- config = validateWithSchema(fileConfig);
723
734
  }
724
- } catch (err) {
725
- log.warn(
726
- { err },
727
- "Managed Gemini defaults migration failed — continuing with existing config",
728
- );
729
735
  }
730
736
  }
731
737
 
@@ -763,7 +769,7 @@ export function loadConfig(): AssistantConfig {
763
769
  // changes were inert because the merge only filled absent keys and never
764
770
  // reconciled existing values. Contract: disk = user intent, in-memory
765
771
  // cache = effective values.
766
- if (!configFileExisted) {
772
+ if (!configFileExisted && suppressConfigDiskWritesDepth === 0) {
767
773
  try {
768
774
  const dir = dirname(configPath);
769
775
  if (!existsSync(dir)) {
@@ -842,6 +848,26 @@ export function invalidateConfigCache(): void {
842
848
  loading = false;
843
849
  }
844
850
 
851
+ export async function withSuppressedConfigDiskWrites<T>(
852
+ fn: () => T | Promise<T>,
853
+ ): Promise<T> {
854
+ suppressConfigDiskWritesDepth++;
855
+ try {
856
+ return await fn();
857
+ } finally {
858
+ suppressConfigDiskWritesDepth--;
859
+ }
860
+ }
861
+
862
+ export function withSuppressedConfigDiskWritesSync<T>(fn: () => T): T {
863
+ suppressConfigDiskWritesDepth++;
864
+ try {
865
+ return fn();
866
+ } finally {
867
+ suppressConfigDiskWritesDepth--;
868
+ }
869
+ }
870
+
845
871
  /**
846
872
  * Load the raw config from disk without any secure-storage merging.
847
873
  * Used by CLI config commands to read/write the file directly.
@@ -25,6 +25,7 @@ import {
25
25
  TwilioConfigSchema,
26
26
  WhatsAppConfigSchema,
27
27
  } from "./schemas/channels.js";
28
+ import { CompactionConfigSchema } from "./schemas/compaction.js";
28
29
  import { ConversationsConfigSchema } from "./schemas/conversations.js";
29
30
  import { FilingConfigSchema } from "./schemas/filing.js";
30
31
  import { HeartbeatConfigSchema } from "./schemas/heartbeat.js";
@@ -52,6 +53,7 @@ import {
52
53
  RateLimitConfigSchema,
53
54
  TimeoutConfigSchema,
54
55
  } from "./schemas/timeouts.js";
56
+ import { ToolsConfigSchema } from "./schemas/tools.js";
55
57
  import { UpdatesConfigSchema } from "./schemas/updates.js";
56
58
  import { WorkspaceGitConfigSchema } from "./schemas/workspace-git.js";
57
59
 
@@ -82,9 +84,7 @@ export const AssistantConfigSchema = z
82
84
  // ensures the loader's leaf-deletion recovery path can repair a partially
83
85
  // invalid `llm` block without falling back to `cloneDefaultConfig()`.
84
86
  llm: LLMSchema.default(LLMSchema.parse({})),
85
- llmRequestLogs: LlmRequestLogsConfigSchema.default(
86
- LlmRequestLogsConfigSchema.parse({}),
87
- ),
87
+ llmRequestLogs: LlmRequestLogsConfigSchema,
88
88
  filing: FilingConfigSchema.default(FilingConfigSchema.parse({})),
89
89
  heartbeat: HeartbeatConfigSchema.default(HeartbeatConfigSchema.parse({})),
90
90
  updates: UpdatesConfigSchema.default(UpdatesConfigSchema.parse({})),
@@ -103,6 +103,9 @@ export const AssistantConfigSchema = z
103
103
  workspaceGit: WorkspaceGitConfigSchema.default(
104
104
  WorkspaceGitConfigSchema.parse({}),
105
105
  ),
106
+ compaction: CompactionConfigSchema.default(
107
+ CompactionConfigSchema.parse({}),
108
+ ),
106
109
  twilio: TwilioConfigSchema.default(TwilioConfigSchema.parse({})),
107
110
  calls: CallsConfigSchema.default(CallsConfigSchema.parse({})),
108
111
  whatsapp: WhatsAppConfigSchema.default(WhatsAppConfigSchema.parse({})),
@@ -115,6 +118,7 @@ export const AssistantConfigSchema = z
115
118
  NotificationsConfigSchema.parse({}),
116
119
  ),
117
120
  ui: UiConfigSchema.default(UiConfigSchema.parse({})),
121
+ tools: ToolsConfigSchema.default(ToolsConfigSchema.parse({})),
118
122
  // Per-plugin config blocks keyed by plugin name. The schema is intentionally
119
123
  // permissive — each plugin's manifest supplies its own validator which the
120
124
  // plugin bootstrap (`external-plugins-bootstrap.ts`) runs against the raw
@@ -145,13 +149,6 @@ export const AssistantConfigSchema = z
145
149
  .max(200, "maxStepsPerSession must be <= 200")
146
150
  .default(50)
147
151
  .describe("Maximum number of computer-use steps per session"),
148
- systemPromptPrefix: z
149
- .string({ error: "systemPromptPrefix must be a string" })
150
- .nullable()
151
- .default(null)
152
- .describe(
153
- "Custom text injected at the very beginning of the system prompt. Defaults to null (no injection).",
154
- ),
155
152
  })
156
153
  .superRefine((config, ctx) => {
157
154
  const llmContextWindow = config.llm?.default?.contextWindow;