@vellumai/assistant 0.6.5 → 0.6.6

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 (443) hide show
  1. package/AGENTS.md +9 -1
  2. package/ARCHITECTURE.md +15 -17
  3. package/Dockerfile +6 -4
  4. package/__tests__/permissions/gateway-threshold-reader.test.ts +283 -0
  5. package/docs/architecture/integrations.md +32 -39
  6. package/docs/architecture/memory.md +25 -30
  7. package/docs/architecture/security.md +7 -6
  8. package/docs/browser-use-architecture-phase2.md +63 -20
  9. package/docs/plugins.md +761 -0
  10. package/examples/plugins/echo/README.md +132 -0
  11. package/examples/plugins/echo/package.json +17 -0
  12. package/examples/plugins/echo/register.ts +187 -0
  13. package/node_modules/@vellumai/egress-proxy/src/types.ts +19 -0
  14. package/openapi.yaml +212 -68
  15. package/package.json +1 -1
  16. package/src/__tests__/app-compiler.test.ts +57 -0
  17. package/src/__tests__/approval-cascade.test.ts +7 -2
  18. package/src/__tests__/auto-analysis-end-to-end.test.ts +1 -0
  19. package/src/__tests__/avatar-generator.test.ts +4 -2
  20. package/src/__tests__/bundled-asset.test.ts +6 -6
  21. package/src/__tests__/catalog-cache.test.ts +69 -0
  22. package/src/__tests__/checker.test.ts +459 -171
  23. package/src/__tests__/circuit-breaker-pipeline.test.ts +406 -0
  24. package/src/__tests__/compaction-events.test.ts +501 -0
  25. package/src/__tests__/compaction-pipeline.test.ts +210 -0
  26. package/src/__tests__/compaction-strip-metadata-clear.test.ts +181 -0
  27. package/src/__tests__/compaction-timeout-recovery.test.ts +262 -0
  28. package/src/__tests__/config-model-image-provider.test.ts +110 -0
  29. package/src/__tests__/config-schema.test.ts +22 -9
  30. package/src/__tests__/config-watcher-cleanup-throttle.test.ts +0 -4
  31. package/src/__tests__/contacts-tools.test.ts +26 -0
  32. package/src/__tests__/context-overflow-policy.test.ts +7 -7
  33. package/src/__tests__/context-window-manager.test.ts +355 -4
  34. package/src/__tests__/conversation-abort-tool-results.test.ts +4 -1
  35. package/src/__tests__/conversation-agent-loop-overflow.test.ts +26 -30
  36. package/src/__tests__/conversation-agent-loop.test.ts +30 -141
  37. package/src/__tests__/conversation-confirmation-signals.test.ts +6 -1
  38. package/src/__tests__/conversation-history-web-search.test.ts +1 -0
  39. package/src/__tests__/conversation-init.benchmark.test.ts +2 -16
  40. package/src/__tests__/conversation-pairing.test.ts +174 -10
  41. package/src/__tests__/conversation-pre-run-repair.test.ts +4 -1
  42. package/src/__tests__/conversation-process-callsite.test.ts +3 -0
  43. package/src/__tests__/conversation-provider-retry-repair.test.ts +16 -7
  44. package/src/__tests__/conversation-queue.test.ts +29 -14
  45. package/src/__tests__/conversation-routes-disk-view.test.ts +7 -6
  46. package/src/__tests__/conversation-runtime-assembly.test.ts +155 -110
  47. package/src/__tests__/conversation-runtime-workspace.test.ts +23 -38
  48. package/src/__tests__/conversation-seed-composer.test.ts +2 -2
  49. package/src/__tests__/conversation-slash-queue.test.ts +7 -2
  50. package/src/__tests__/conversation-slash-unknown.test.ts +25 -2
  51. package/src/__tests__/conversation-speed-override.test.ts +6 -1
  52. package/src/__tests__/conversation-title-service.test.ts +116 -0
  53. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +41 -2
  54. package/src/__tests__/conversation-usage.test.ts +1 -1
  55. package/src/__tests__/conversation-workspace-cache-state.test.ts +4 -1
  56. package/src/__tests__/conversation-workspace-injection.test.ts +3 -0
  57. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +4 -1
  58. package/src/__tests__/credential-health-service.test.ts +78 -9
  59. package/src/__tests__/credential-security-invariants.test.ts +2 -2
  60. package/src/__tests__/db-schedule-syntax-migration.test.ts +1 -0
  61. package/src/__tests__/empty-response-pipeline.test.ts +305 -0
  62. package/src/__tests__/extension-id-sync-guard.test.ts +3 -3
  63. package/src/__tests__/first-greeting.test.ts +247 -5
  64. package/src/__tests__/headless-browser-mode.test.ts +57 -0
  65. package/src/__tests__/history-repair-pipeline.test.ts +399 -0
  66. package/src/__tests__/host-browser-e2e-cloud.test.ts +307 -0
  67. package/src/__tests__/host-browser-e2e-self-hosted.test.ts +3 -3
  68. package/src/__tests__/host-proxy-interface.test.ts +36 -2
  69. package/src/__tests__/image-credentials.test.ts +137 -0
  70. package/src/__tests__/image-service-dispatcher.test.ts +186 -0
  71. package/src/__tests__/injector-chain.test.ts +526 -0
  72. package/src/__tests__/intent-routing.test.ts +0 -26
  73. package/src/__tests__/llm-call-pipeline.test.ts +285 -0
  74. package/src/__tests__/llm-schema.test.ts +1 -1
  75. package/src/__tests__/media-generate-image.test.ts +119 -13
  76. package/src/__tests__/memory-retrieval-pipeline.test.ts +401 -0
  77. package/src/__tests__/memory-upsert-concurrency.test.ts +1 -0
  78. package/src/__tests__/migration-import-from-url.test.ts +5 -68
  79. package/src/__tests__/model-intents.test.ts +4 -2
  80. package/src/__tests__/notification-broadcaster.test.ts +3 -3
  81. package/src/__tests__/notification-decision-strategy.test.ts +0 -11
  82. package/src/__tests__/notification-schedule-notify-dedup.test.ts +108 -0
  83. package/src/__tests__/oauth-apps-routes.test.ts +1 -1
  84. package/src/__tests__/oauth-cli.test.ts +14 -12
  85. package/src/__tests__/oauth-connect-orchestrator.test.ts +4 -13
  86. package/src/__tests__/oauth-provider-serializer.test.ts +6 -4
  87. package/src/__tests__/oauth-provider-visibility.test.ts +3 -5
  88. package/src/__tests__/oauth-providers-routes.test.ts +3 -2
  89. package/src/__tests__/oauth-store.test.ts +41 -76
  90. package/src/__tests__/onboarding-template-contract.test.ts +16 -64
  91. package/src/__tests__/openai-image-service.test.ts +368 -0
  92. package/src/__tests__/overflow-reduce-pipeline.test.ts +676 -0
  93. package/src/__tests__/permission-checker-host-gate.test.ts +0 -24
  94. package/src/__tests__/persist-onboarding-artifacts.test.ts +266 -0
  95. package/src/__tests__/persistence-pipeline.test.ts +377 -0
  96. package/src/__tests__/pipeline-runner.test.ts +565 -0
  97. package/src/__tests__/platform.test.ts +5 -2
  98. package/src/__tests__/plugin-bootstrap.test.ts +483 -0
  99. package/src/__tests__/plugin-registry.test.ts +273 -0
  100. package/src/__tests__/plugin-route-contribution.test.ts +288 -0
  101. package/src/__tests__/plugin-skill-contribution.test.ts +367 -0
  102. package/src/__tests__/plugin-tool-contribution.test.ts +286 -0
  103. package/src/__tests__/plugin-types.test.ts +320 -0
  104. package/src/__tests__/pricing.test.ts +44 -12
  105. package/src/__tests__/proxy-approval-callback.test.ts +69 -8
  106. package/src/__tests__/reaction-persistence.test.ts +1 -0
  107. package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +1 -0
  108. package/src/__tests__/registry.test.ts +0 -2
  109. package/src/__tests__/schedule-routes.test.ts +131 -1
  110. package/src/__tests__/scheduler-recurrence.test.ts +14 -70
  111. package/src/__tests__/scheduler-reuse-conversation.test.ts +10 -50
  112. package/src/__tests__/secret-detection-handler.test.ts +0 -10
  113. package/src/__tests__/shell-identity.test.ts +0 -134
  114. package/src/__tests__/suggestion-routes.test.ts +103 -4
  115. package/src/__tests__/task-memory-cleanup.test.ts +1 -0
  116. package/src/__tests__/task-scheduler.test.ts +3 -15
  117. package/src/__tests__/test-preload.ts +11 -0
  118. package/src/__tests__/title-generate-pipeline.test.ts +224 -0
  119. package/src/__tests__/token-estimate-pipeline.test.ts +431 -0
  120. package/src/__tests__/tool-error-pipeline.test.ts +244 -0
  121. package/src/__tests__/tool-execute-pipeline.test.ts +431 -0
  122. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +0 -6
  123. package/src/__tests__/tool-executor-shell-integration.test.ts +7 -10
  124. package/src/__tests__/tool-executor.test.ts +141 -0
  125. package/src/__tests__/tool-result-truncate-pipeline.test.ts +356 -0
  126. package/src/__tests__/tool-result-truncation.test.ts +0 -110
  127. package/src/__tests__/user-plugin-loader.test.ts +191 -0
  128. package/src/__tests__/workspace-migration-046-seed-conversation-starters-callsite.test.ts +185 -0
  129. package/src/__tests__/workspace-migration-049-release-notes-default-sonnet.test.ts +100 -0
  130. package/src/__tests__/workspace-migration-050-seed-main-agent-opus-callsite.test.ts +171 -0
  131. package/src/__tests__/workspace-migration-051-seed-conversation-summarization-callsite.test.ts +252 -0
  132. package/src/__tests__/workspace-migration-remove-hooks.test.ts +99 -0
  133. package/src/__tests__/workspace-policy.test.ts +21 -3
  134. package/src/agent/loop.ts +340 -102
  135. package/src/approvals/__tests__/guardian-feed-event.test.ts +304 -0
  136. package/src/approvals/guardian-request-resolvers.ts +80 -0
  137. package/src/backup/__tests__/backup-worker.test.ts +2 -13
  138. package/src/backup/backup-worker.ts +3 -15
  139. package/src/bundler/app-compiler.ts +84 -1
  140. package/src/calls/call-state.ts +2 -2
  141. package/src/channels/__tests__/types.test.ts +3 -3
  142. package/src/channels/types.ts +6 -4
  143. package/src/cli/__tests__/notifications.test.ts +87 -211
  144. package/src/cli/commands/__tests__/backup.test.ts +1 -1
  145. package/src/cli/commands/__tests__/image-generation.test.ts +255 -35
  146. package/src/cli/commands/__tests__/inference-send.test.ts +12 -0
  147. package/src/cli/commands/__tests__/tts-synthesize.test.ts +12 -0
  148. package/src/cli/commands/backup.ts +2 -2
  149. package/src/cli/commands/clients.ts +138 -0
  150. package/src/cli/commands/completions.ts +2 -9
  151. package/src/cli/commands/conversations.ts +55 -7
  152. package/src/cli/commands/image-generation.ts +33 -34
  153. package/src/cli/commands/notifications.ts +68 -103
  154. package/src/cli/commands/oauth/__tests__/providers-register.test.ts +1 -1
  155. package/src/cli/commands/oauth/__tests__/providers-update.test.ts +1 -1
  156. package/src/cli/commands/oauth/connect.ts +2 -2
  157. package/src/cli/commands/oauth/providers.ts +176 -8
  158. package/src/cli/commands/oauth/status.ts +46 -36
  159. package/src/cli/commands/skills.ts +3 -4
  160. package/src/cli/program.ts +25 -29
  161. package/src/config/__tests__/backup-schema.test.ts +7 -2
  162. package/src/config/bundled-skills/app-builder/SKILL.md +2 -2
  163. package/src/config/bundled-skills/app-builder/references/WIDGETS.md +10 -10
  164. package/src/config/bundled-skills/contacts/tools/contact-merge.ts +66 -87
  165. package/src/config/bundled-skills/contacts/tools/contact-search.ts +28 -51
  166. package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +22 -40
  167. package/src/config/bundled-skills/image-studio/SKILL.md +2 -1
  168. package/src/config/bundled-skills/image-studio/TOOLS.json +2 -1
  169. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +23 -39
  170. package/src/config/bundled-skills/messaging/SKILL.md +3 -3
  171. package/src/config/bundled-skills/messaging/tools/__tests__/messaging-feed-events.test.ts +207 -0
  172. package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +12 -0
  173. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +58 -0
  174. package/src/config/bundled-skills/schedule/SKILL.md +8 -3
  175. package/src/config/bundled-skills/schedule/TOOLS.json +15 -7
  176. package/src/config/bundled-skills/schedule/references/SCRIPT_MODE_PATTERNS.md +59 -0
  177. package/src/config/bundled-tool-registry.ts +0 -15
  178. package/src/config/feature-flag-registry.json +17 -1
  179. package/src/config/schema.ts +19 -0
  180. package/src/config/schemas/backup.ts +1 -1
  181. package/src/config/schemas/conversations.ts +16 -0
  182. package/src/config/schemas/llm.ts +2 -3
  183. package/src/config/schemas/security.ts +6 -6
  184. package/src/config/schemas/tts.ts +11 -0
  185. package/src/config/skill-state.ts +6 -2
  186. package/src/config/skills.ts +94 -5
  187. package/src/context/__tests__/compact-prompt.test.ts +27 -9
  188. package/src/context/prompts/compact.md +26 -12
  189. package/src/context/tool-result-truncation.ts +3 -63
  190. package/src/context/window-manager.ts +190 -16
  191. package/src/credential-health/credential-health-service.ts +19 -6
  192. package/src/daemon/__tests__/conversation-feed-event.test.ts +317 -0
  193. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +4 -12
  194. package/src/daemon/__tests__/conversation-tool-setup.test.ts +14 -15
  195. package/src/daemon/config-watcher.ts +0 -2
  196. package/src/daemon/context-overflow-policy.ts +4 -13
  197. package/src/daemon/conversation-agent-loop-handlers.ts +83 -22
  198. package/src/daemon/conversation-agent-loop.ts +984 -683
  199. package/src/daemon/conversation-history.ts +10 -19
  200. package/src/daemon/conversation-lifecycle.ts +37 -19
  201. package/src/daemon/conversation-notifiers.ts +2 -110
  202. package/src/daemon/conversation-process.ts +14 -7
  203. package/src/daemon/conversation-runtime-assembly.ts +532 -411
  204. package/src/daemon/conversation-tool-setup.ts +41 -4
  205. package/src/daemon/conversation.ts +80 -35
  206. package/src/daemon/external-plugins-bootstrap.ts +478 -0
  207. package/src/daemon/first-greeting.ts +191 -14
  208. package/src/daemon/handlers/config-model.ts +11 -0
  209. package/src/daemon/handlers/skills.ts +5 -1
  210. package/src/daemon/lifecycle.ts +33 -68
  211. package/src/daemon/message-types/computer-use.ts +2 -34
  212. package/src/daemon/message-types/conversations.ts +49 -0
  213. package/src/daemon/message-types/messages.ts +12 -0
  214. package/src/daemon/server.ts +5 -3
  215. package/src/daemon/shutdown-handlers.ts +2 -12
  216. package/src/daemon/tool-side-effects.ts +14 -56
  217. package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +160 -0
  218. package/src/heartbeat/heartbeat-service.ts +24 -1
  219. package/src/home/__tests__/feed-population-integration.test.ts +312 -0
  220. package/src/home/emit-feed-event.ts +7 -0
  221. package/src/home/feed-types.ts +41 -2
  222. package/src/home/rewrite-command-preview.ts +66 -0
  223. package/src/ipc/__tests__/socket-path.test.ts +11 -50
  224. package/src/ipc/cli-client.ts +1 -1
  225. package/src/ipc/cli-server.ts +3 -3
  226. package/src/ipc/gateway-client.ts +4 -1
  227. package/src/ipc/routes/browser-context.ts +2 -0
  228. package/src/ipc/routes/browser.ts +1 -0
  229. package/src/ipc/routes/get-contact.ts +16 -0
  230. package/src/ipc/routes/index.ts +14 -0
  231. package/src/ipc/routes/list-clients.ts +31 -0
  232. package/src/ipc/routes/merge-contacts.ts +17 -0
  233. package/src/ipc/routes/notification.ts +133 -0
  234. package/src/ipc/routes/rename-conversation.ts +59 -0
  235. package/src/ipc/routes/search-contacts.ts +19 -0
  236. package/src/ipc/routes/upsert-contact.ts +25 -0
  237. package/src/ipc/socket-path.ts +14 -38
  238. package/src/media/app-icon-generator.ts +23 -46
  239. package/src/media/avatar-router.ts +26 -41
  240. package/src/media/gemini-image-service.ts +8 -41
  241. package/src/media/image-credentials.ts +73 -0
  242. package/src/media/image-service.ts +85 -0
  243. package/src/media/openai-image-service.ts +131 -0
  244. package/src/media/types.ts +46 -0
  245. package/src/memory/conversation-crud.ts +48 -18
  246. package/src/memory/conversation-queries.ts +57 -4
  247. package/src/memory/conversation-title-service.ts +25 -0
  248. package/src/memory/db-init.ts +8 -0
  249. package/src/memory/embedding-gemini.test.ts +41 -2
  250. package/src/memory/embedding-gemini.ts +6 -1
  251. package/src/memory/graph/bootstrap.test.ts +282 -0
  252. package/src/memory/graph/bootstrap.ts +8 -5
  253. package/src/memory/graph/extraction.ts +10 -2
  254. package/src/memory/graph/graph-search.test.ts +1 -0
  255. package/src/memory/graph/inspect.ts +2 -2
  256. package/src/memory/graph/retriever.ts +10 -3
  257. package/src/memory/migrations/041-approval-prompt-ts-tracker.ts +26 -0
  258. package/src/memory/migrations/149-oauth-tables.ts +1 -0
  259. package/src/memory/migrations/223-schedule-script-column.ts +11 -0
  260. package/src/memory/migrations/224-oauth-providers-managed-service-is-paid.ts +24 -0
  261. package/src/memory/migrations/225-oauth-providers-available-scopes.ts +13 -0
  262. package/src/memory/migrations/index.ts +4 -0
  263. package/src/memory/pkb/pkb-index.test.ts +1 -0
  264. package/src/memory/pkb/pkb-reconcile.test.ts +1 -0
  265. package/src/memory/pkb/pkb-search.test.ts +65 -4
  266. package/src/memory/pkb/pkb-search.ts +40 -18
  267. package/src/memory/qdrant-client.test.ts +60 -0
  268. package/src/memory/qdrant-client.ts +25 -0
  269. package/src/memory/schema/infrastructure.ts +1 -0
  270. package/src/memory/schema/oauth.ts +4 -1
  271. package/src/messaging/providers/slack/render-transcript.test.ts +77 -29
  272. package/src/messaging/providers/slack/render-transcript.ts +58 -0
  273. package/src/notifications/conversation-pairing.ts +78 -19
  274. package/src/notifications/copy-composer.ts +0 -5
  275. package/src/notifications/emit-signal.ts +1 -1
  276. package/src/notifications/signal.ts +1 -2
  277. package/src/oauth/AGENTS.md +1 -1
  278. package/src/oauth/__tests__/identity-verifier.test.ts +2 -1
  279. package/src/oauth/connect-orchestrator.ts +8 -34
  280. package/src/oauth/connect-types.ts +6 -10
  281. package/src/oauth/manual-token-connection.ts +23 -0
  282. package/src/oauth/oauth-store.ts +30 -14
  283. package/src/oauth/provider-serializer.ts +6 -1
  284. package/src/oauth/seed-providers.ts +56 -108
  285. package/src/outbound-proxy/http-forwarder.ts +9 -0
  286. package/src/permissions/approval-policy.test.ts +293 -18
  287. package/src/permissions/approval-policy.ts +110 -58
  288. package/src/permissions/arg-parser.test.ts +161 -0
  289. package/src/permissions/arg-parser.ts +141 -0
  290. package/src/permissions/bash-risk-classifier.test.ts +414 -2
  291. package/src/permissions/bash-risk-classifier.ts +303 -60
  292. package/src/permissions/checker.ts +157 -29
  293. package/src/permissions/command-registry.test.ts +239 -0
  294. package/src/permissions/command-registry.ts +234 -54
  295. package/src/permissions/defaults.ts +5 -4
  296. package/src/permissions/gateway-threshold-reader.ts +196 -0
  297. package/src/permissions/prompter.ts +4 -0
  298. package/src/permissions/risk-types.ts +61 -4
  299. package/src/permissions/schedule-risk-classifier.test.ts +129 -0
  300. package/src/permissions/schedule-risk-classifier.ts +85 -0
  301. package/src/permissions/shell-identity.ts +2 -42
  302. package/src/permissions/types.ts +2 -0
  303. package/src/permissions/workspace-policy.ts +8 -3
  304. package/src/plugins/defaults/circuit-breaker.ts +146 -0
  305. package/src/plugins/defaults/compaction.ts +145 -0
  306. package/src/plugins/defaults/empty-response.ts +126 -0
  307. package/src/plugins/defaults/history-repair.ts +85 -0
  308. package/src/plugins/defaults/index.ts +116 -0
  309. package/src/plugins/defaults/injectors.ts +491 -0
  310. package/src/plugins/defaults/llm-call.ts +82 -0
  311. package/src/plugins/defaults/memory-retrieval.ts +226 -0
  312. package/src/plugins/defaults/overflow-reduce.ts +181 -0
  313. package/src/plugins/defaults/persistence.ts +129 -0
  314. package/src/plugins/defaults/title-generate.ts +95 -0
  315. package/src/plugins/defaults/token-estimate.ts +104 -0
  316. package/src/plugins/defaults/tool-error.ts +126 -0
  317. package/src/plugins/defaults/tool-execute.ts +89 -0
  318. package/src/plugins/defaults/tool-result-truncate.ts +88 -0
  319. package/src/plugins/pipeline.ts +316 -0
  320. package/src/plugins/plugin-skill-contributions.ts +292 -0
  321. package/src/plugins/registry.ts +241 -0
  322. package/src/plugins/types.ts +1134 -0
  323. package/src/plugins/user-loader.ts +177 -0
  324. package/src/prompts/templates/BOOTSTRAP.md +27 -77
  325. package/src/providers/model-catalog.ts +52 -29
  326. package/src/providers/model-intents.ts +1 -1
  327. package/src/providers/openrouter/client.ts +5 -1
  328. package/src/providers/speech-to-text/deepgram-realtime.test.ts +61 -0
  329. package/src/providers/speech-to-text/deepgram-realtime.ts +57 -0
  330. package/src/providers/speech-to-text/xai-realtime.test.ts +72 -4
  331. package/src/providers/speech-to-text/xai-realtime.ts +39 -14
  332. package/src/runtime/AGENTS.md +25 -16
  333. package/src/runtime/__tests__/browser-extension-pair-routes.test.ts +3 -3
  334. package/src/runtime/__tests__/client-registry.test.ts +293 -0
  335. package/src/runtime/client-registry.ts +261 -0
  336. package/src/runtime/http-server.ts +77 -8
  337. package/src/runtime/http-types.ts +0 -2
  338. package/src/runtime/migrations/vbundle-builder.ts +1 -22
  339. package/src/runtime/routes/approval-prompt-ts-tracker.ts +51 -31
  340. package/src/runtime/routes/approval-routes.ts +17 -0
  341. package/src/runtime/routes/browser-extension-pair-routes.ts +27 -8
  342. package/src/runtime/routes/conversation-routes.ts +223 -116
  343. package/src/runtime/routes/inbound-message-handler.ts +88 -13
  344. package/src/runtime/routes/memory-item-routes.test.ts +1 -0
  345. package/src/runtime/routes/migration-routes.ts +0 -3
  346. package/src/runtime/routes/playground/__tests__/force-compact.test.ts +284 -0
  347. package/src/runtime/routes/playground/__tests__/guard.test.ts +80 -0
  348. package/src/runtime/routes/playground/__tests__/inject-failures.test.ts +294 -0
  349. package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +271 -0
  350. package/src/runtime/routes/playground/__tests__/seed-conversation.test.ts +202 -0
  351. package/src/runtime/routes/playground/__tests__/seeded-conversations.test.ts +309 -0
  352. package/src/runtime/routes/playground/__tests__/state.test.ts +224 -0
  353. package/src/runtime/routes/playground/conversation-not-found.ts +29 -0
  354. package/src/runtime/routes/playground/deps.ts +56 -0
  355. package/src/runtime/routes/playground/force-compact.ts +73 -0
  356. package/src/runtime/routes/playground/guard.ts +37 -0
  357. package/src/runtime/routes/playground/index.ts +28 -0
  358. package/src/runtime/routes/playground/inject-failures.ts +159 -0
  359. package/src/runtime/routes/playground/reset-circuit.ts +115 -0
  360. package/src/runtime/routes/playground/seed-conversation.ts +139 -0
  361. package/src/runtime/routes/playground/seeded-conversations.ts +78 -0
  362. package/src/runtime/routes/playground/state.ts +78 -0
  363. package/src/runtime/routes/schedule-routes.ts +89 -8
  364. package/src/runtime/skill-route-registry.ts +75 -15
  365. package/src/schedule/run-script.ts +68 -0
  366. package/src/schedule/schedule-store.ts +7 -1
  367. package/src/schedule/scheduler.ts +48 -8
  368. package/src/skills/catalog-cache.ts +12 -5
  369. package/src/tools/browser/__tests__/browser-status.test.ts +189 -0
  370. package/src/tools/browser/browser-execution.ts +88 -19
  371. package/src/tools/browser/cdp-client/__tests__/extension-cdp-client.test.ts +230 -0
  372. package/src/tools/browser/cdp-client/__tests__/factory.test.ts +146 -3
  373. package/src/tools/browser/cdp-client/extension-cdp-client.ts +54 -3
  374. package/src/tools/browser/cdp-client/factory.ts +15 -4
  375. package/src/tools/executor.ts +126 -74
  376. package/src/tools/network/script-proxy/session-manager.ts +37 -1
  377. package/src/tools/permission-checker.ts +98 -49
  378. package/src/tools/policy-context.ts +4 -0
  379. package/src/tools/registry.ts +140 -3
  380. package/src/tools/schedule/create.ts +23 -8
  381. package/src/tools/schedule/update.ts +3 -1
  382. package/src/tools/secret-detection-handler.ts +0 -51
  383. package/src/tools/system/avatar-generator.ts +6 -2
  384. package/src/tools/types.ts +28 -2
  385. package/src/util/platform.ts +7 -2
  386. package/src/util/pricing.ts +26 -3
  387. package/src/workspace/migrations/006-services-config.ts +2 -4
  388. package/src/workspace/migrations/022-move-hooks-to-workspace.ts +2 -3
  389. package/src/workspace/migrations/041-backfill-google-gmail-settings-scope.ts +3 -4
  390. package/src/workspace/migrations/046-seed-conversation-starters-callsite.ts +108 -0
  391. package/src/workspace/migrations/047-remove-watch-callsites.ts +54 -0
  392. package/src/workspace/migrations/048-remove-workspace-hooks.ts +81 -0
  393. package/src/workspace/migrations/049-release-notes-default-sonnet.ts +80 -0
  394. package/src/workspace/migrations/050-seed-main-agent-opus-callsite.ts +86 -0
  395. package/src/workspace/migrations/051-seed-conversation-summarization-callsite.ts +128 -0
  396. package/src/workspace/migrations/registry.ts +12 -0
  397. package/tsconfig.json +1 -1
  398. package/hook-templates/debug-prompt-logger/hook.json +0 -7
  399. package/hook-templates/debug-prompt-logger/run.sh +0 -66
  400. package/src/__tests__/compaction-circuit-breaker.test.ts +0 -336
  401. package/src/__tests__/context-overflow-approval.test.ts +0 -156
  402. package/src/__tests__/hooks-blocking.test.ts +0 -178
  403. package/src/__tests__/hooks-cli.test.ts +0 -182
  404. package/src/__tests__/hooks-config.test.ts +0 -108
  405. package/src/__tests__/hooks-discovery.test.ts +0 -211
  406. package/src/__tests__/hooks-integration.test.ts +0 -196
  407. package/src/__tests__/hooks-manager.test.ts +0 -226
  408. package/src/__tests__/hooks-runner.test.ts +0 -175
  409. package/src/__tests__/hooks-settings.test.ts +0 -160
  410. package/src/__tests__/hooks-templates.test.ts +0 -169
  411. package/src/__tests__/hooks-ts-runner.test.ts +0 -170
  412. package/src/__tests__/hooks-watch.test.ts +0 -112
  413. package/src/__tests__/notification-schedule-dedup.test.ts +0 -213
  414. package/src/__tests__/oauth-scope-policy.test.ts +0 -180
  415. package/src/__tests__/send-notification-tool.test.ts +0 -83
  416. package/src/cli/commands/shotgun.ts +0 -266
  417. package/src/config/bundled-skills/conversations/SKILL.md +0 -20
  418. package/src/config/bundled-skills/conversations/TOOLS.json +0 -23
  419. package/src/config/bundled-skills/conversations/tools/rename-conversation.ts +0 -88
  420. package/src/config/bundled-skills/heartbeat/SKILL.md +0 -43
  421. package/src/config/bundled-skills/notifications/SKILL.md +0 -40
  422. package/src/config/bundled-skills/notifications/TOOLS.json +0 -80
  423. package/src/config/bundled-skills/notifications/tools/send-notification.ts +0 -152
  424. package/src/config/bundled-skills/notifications/tools/shared.ts +0 -13
  425. package/src/config/bundled-skills/screen-watch/SKILL.md +0 -27
  426. package/src/config/bundled-skills/screen-watch/TOOLS.json +0 -35
  427. package/src/config/bundled-skills/screen-watch/tools/start-screen-watch.ts +0 -12
  428. package/src/config/bundled-skills/skills-catalog/SKILL.md +0 -84
  429. package/src/daemon/context-overflow-approval.ts +0 -52
  430. package/src/daemon/watch-handler.ts +0 -399
  431. package/src/hooks/cli.ts +0 -253
  432. package/src/hooks/config.ts +0 -100
  433. package/src/hooks/discovery.ts +0 -135
  434. package/src/hooks/manager.ts +0 -179
  435. package/src/hooks/runner.ts +0 -117
  436. package/src/hooks/templates.ts +0 -77
  437. package/src/hooks/types.ts +0 -75
  438. package/src/oauth/scope-policy.ts +0 -89
  439. package/src/runtime/gateway-internal-client.ts +0 -94
  440. package/src/runtime/routes/watch-routes.ts +0 -156
  441. package/src/signals/shotgun.ts +0 -203
  442. package/src/tools/watch/screen-watch.ts +0 -144
  443. package/src/tools/watch/watch-state.ts +0 -142
@@ -0,0 +1,16 @@
1
+ import { z } from "zod";
2
+
3
+ export const ConversationsConfigSchema = z
4
+ .object({
5
+ skipAutoRetitling: z
6
+ .boolean({
7
+ error: "conversations.skipAutoRetitling must be a boolean",
8
+ })
9
+ .default(false)
10
+ .describe(
11
+ "When true, skip the second-pass title regeneration that fires after the third user turn. The initial auto-generated title and manual renames are unaffected.",
12
+ ),
13
+ })
14
+ .describe("Conversation behavior configuration");
15
+
16
+ export type ConversationsConfig = z.infer<typeof ConversationsConfigSchema>;
@@ -57,8 +57,6 @@ export const LLMCallSiteEnum = z.enum([
57
57
  "guardianQuestionCopy",
58
58
  "approvalCopy",
59
59
  "approvalConversation",
60
- "watchCommentary",
61
- "watchSummary",
62
60
  "interactionClassifier",
63
61
  "styleAnalyzer",
64
62
  "inviteInstructionGenerator",
@@ -66,6 +64,7 @@ export const LLMCallSiteEnum = z.enum([
66
64
  "meetConsentMonitor",
67
65
  "meetChatOpportunity",
68
66
  "inference",
67
+ "feedEventCopy",
69
68
  ]);
70
69
  export type LLMCallSite = z.infer<typeof LLMCallSiteEnum>;
71
70
 
@@ -244,7 +243,7 @@ export type PricingOverride = z.infer<typeof PricingOverrideSchema>;
244
243
  */
245
244
  export const LLMConfigBase = z.object({
246
245
  provider: LLMProvider.default("anthropic"),
247
- model: ModelSchema.default("claude-opus-4-7"),
246
+ model: ModelSchema.default("claude-sonnet-4-6"),
248
247
  maxTokens: MaxTokensSchema.default(64000),
249
248
  effort: EffortEnum.default("max"),
250
249
  speed: SpeedEnum.default("standard"),
@@ -89,25 +89,25 @@ export const PermissionsConfigSchema = z
89
89
  ),
90
90
  autoApproveUpTo: z
91
91
  .union([
92
- z.enum(["none", "low", "medium"], {
92
+ z.enum(["none", "low", "medium", "high"], {
93
93
  error:
94
- "permissions.autoApproveUpTo must be one of: none, low, medium",
94
+ "permissions.autoApproveUpTo must be one of: none, low, medium, high",
95
95
  }),
96
96
  z.object({
97
97
  conversation: z
98
- .enum(["none", "low", "medium"])
98
+ .enum(["none", "low", "medium", "high"])
99
99
  .default("low")
100
100
  .describe(
101
101
  "Threshold for interactive conversation sessions (default: low)",
102
102
  ),
103
103
  background: z
104
- .enum(["none", "low", "medium"])
104
+ .enum(["none", "low", "medium", "high"])
105
105
  .default("medium")
106
106
  .describe(
107
107
  "Threshold for non-interactive guardian sessions (default: medium)",
108
108
  ),
109
109
  headless: z
110
- .enum(["none", "low", "medium"])
110
+ .enum(["none", "low", "medium", "high"])
111
111
  .default("none")
112
112
  .describe(
113
113
  "Threshold for non-interactive non-guardian sessions (default: none)",
@@ -117,7 +117,7 @@ export const PermissionsConfigSchema = z
117
117
  .default({ conversation: "low", background: "medium", headless: "none" })
118
118
  .describe(
119
119
  "Auto-approve tools at or below this risk level without prompting. " +
120
- "Accepts a scalar ('none', 'low', 'medium') applied to all contexts, " +
120
+ "Accepts a scalar ('none', 'low', 'medium', 'high') applied to all contexts, " +
121
121
  "or an object with per-context overrides: { conversation, background, headless }.",
122
122
  ),
123
123
  })
@@ -182,6 +182,7 @@ export const TtsXaiProviderConfigSchema = z
182
182
  .string({
183
183
  error: "services.tts.providers.xai.language must be a string",
184
184
  })
185
+ .transform((v) => v || "auto")
185
186
  .default("auto")
186
187
  .describe(
187
188
  "BCP-47 language code (e.g. 'en-US') or 'auto' for auto-detection",
@@ -250,6 +251,16 @@ for (const id of VALID_TTS_PROVIDERS) {
250
251
  );
251
252
  }
252
253
  }
254
+ const catalogKeys = new Set<string>(VALID_TTS_PROVIDERS);
255
+ for (const id of schemaKeys) {
256
+ if (!catalogKeys.has(id)) {
257
+ throw new Error(
258
+ `TTS provider "${id}" has a schema entry in TtsProvidersSchema but ` +
259
+ `is not registered in the provider catalog. Add it to ` +
260
+ `provider-catalog.ts or remove it from TtsProvidersSchema.`,
261
+ );
262
+ }
263
+ }
253
264
 
254
265
  /**
255
266
  * Canonical TTS service configuration.
@@ -54,8 +54,12 @@ export function resolveSkillStates(
54
54
  if (entry && typeof entry.enabled === "boolean") {
55
55
  isEnabled = entry.enabled;
56
56
  } else {
57
- // Default: bundled and managed (user-installed) skills are enabled, others are disabled
58
- isEnabled = skill.source === "bundled" || skill.source === "managed";
57
+ // Default: bundled, managed (user-installed), and plugin-contributed
58
+ // skills are enabled. Others (workspace, extra) are disabled by default.
59
+ isEnabled =
60
+ skill.source === "bundled" ||
61
+ skill.source === "managed" ||
62
+ skill.source === "plugin";
59
63
  }
60
64
 
61
65
  if (!isEnabled) {
@@ -18,6 +18,10 @@ import {
18
18
 
19
19
  import { z } from "zod";
20
20
 
21
+ import {
22
+ getPluginContributedSkillDefinition,
23
+ getPluginContributedSkillSummaries,
24
+ } from "../plugins/plugin-skill-contributions.js";
21
25
  import {
22
26
  extractAllText,
23
27
  getConfiguredProvider,
@@ -59,7 +63,24 @@ const SkillMetadataSchema = z
59
63
  })
60
64
  .passthrough();
61
65
 
62
- export type SkillSource = "bundled" | "managed" | "workspace" | "extra";
66
+ /**
67
+ * Origin of a skill in the merged catalog.
68
+ *
69
+ * - `bundled`: ships inside the assistant binary under `bundled-skills/`.
70
+ * - `managed`: installed into `~/.vellum/workspace/skills/` from our catalog.
71
+ * - `workspace`: user-authored skill living in a conversation's working dir.
72
+ * - `extra`: third-party directory roots passed via `loadSkillCatalog`'s
73
+ * `extraDirs` argument (primarily for tests).
74
+ * - `plugin`: contributed at runtime by a loaded plugin via
75
+ * `PluginSkillRegistration`. Body is held in-memory by
76
+ * `plugins/plugin-skill-contributions.ts`, not on disk.
77
+ */
78
+ export type SkillSource =
79
+ | "bundled"
80
+ | "managed"
81
+ | "workspace"
82
+ | "extra"
83
+ | "plugin";
63
84
 
64
85
  // ─── Core interfaces ─────────────────────────────────────────────────────────
65
86
 
@@ -819,6 +840,37 @@ export function loadSkillCatalog(
819
840
  catalog.push(skill);
820
841
  }
821
842
 
843
+ // Load plugin-contributed skills. They sit above bundled/extra but below
844
+ // managed and workspace so that user-authored filesystem skills can
845
+ // override a plugin-provided skill by declaring the same id under
846
+ // `~/.vellum/workspace/skills/`. Registration is owned by the plugin
847
+ // bootstrap — this call is a pure read against the in-memory registry.
848
+ const pluginSkills = getPluginContributedSkillSummaries();
849
+ for (const skill of pluginSkills) {
850
+ if (seenIds.has(skill.id)) {
851
+ const existingIndex = catalog.findIndex((s) => s.id === skill.id);
852
+ if (
853
+ existingIndex !== -1 &&
854
+ (catalog[existingIndex].source === "bundled" ||
855
+ catalog[existingIndex].source === "extra")
856
+ ) {
857
+ log.info(
858
+ { id: skill.id, pluginSkill: true },
859
+ "Plugin skill overrides bundled/extra skill",
860
+ );
861
+ catalog[existingIndex] = skill;
862
+ continue;
863
+ }
864
+ log.warn(
865
+ { id: skill.id },
866
+ "Skipping duplicate plugin skill id (already present in catalog)",
867
+ );
868
+ continue;
869
+ }
870
+ seenIds.add(skill.id);
871
+ catalog.push(skill);
872
+ }
873
+
822
874
  // Load managed (user) skills, which take precedence over bundled skills with the same ID
823
875
  const skillsDir = getSkillsDir();
824
876
  const indexedDirectories = getIndexedSkillDirectories(skillsDir);
@@ -829,16 +881,24 @@ export function loadSkillCatalog(
829
881
  if (!skill) continue;
830
882
 
831
883
  if (seenIds.has(skill.id)) {
832
- // If the existing entry is bundled, the user skill overrides it
884
+ // If the existing entry is bundled, extra, or plugin-contributed, the
885
+ // user skill overrides it. Only another `managed` or `workspace` entry
886
+ // (already at or above managed precedence) is treated as a true
887
+ // duplicate.
833
888
  const existingIndex = catalog.findIndex((s) => s.id === skill.id);
834
889
  if (
835
890
  existingIndex !== -1 &&
836
891
  (catalog[existingIndex].bundled ||
837
- catalog[existingIndex].source === "extra")
892
+ catalog[existingIndex].source === "extra" ||
893
+ catalog[existingIndex].source === "plugin")
838
894
  ) {
839
895
  log.info(
840
- { id: skill.id, directory },
841
- "User skill overrides bundled skill",
896
+ {
897
+ id: skill.id,
898
+ directory,
899
+ overriding: catalog[existingIndex].source,
900
+ },
901
+ "User skill overrides existing catalog entry",
842
902
  );
843
903
  catalog[existingIndex] = skillSummaryFromDefinition(skill, "managed");
844
904
  continue;
@@ -1018,6 +1078,35 @@ export function listReferenceFiles(directoryPath: string): string | null {
1018
1078
  }
1019
1079
 
1020
1080
  function loadSkillDefinition(skill: SkillSummary): SkillLookupResult {
1081
+ // Plugin-contributed skills live in-memory, not on disk. The registry
1082
+ // (see `plugins/plugin-skill-contributions.ts`) stores a pre-built
1083
+ // SkillDefinition we can return directly — no file read, no frontmatter
1084
+ // parse. We still run placeholder / feature-gate substitution on the
1085
+ // body so plugin skills behave the same as filesystem skills from the
1086
+ // model's perspective.
1087
+ if (skill.source === "plugin") {
1088
+ const pluginDef = getPluginContributedSkillDefinition(skill.id);
1089
+ if (!pluginDef) {
1090
+ // The skill was in the catalog when the selector ran but has since
1091
+ // been unregistered (plugin hot-reload, shutdown race). Fail loudly
1092
+ // rather than returning a mystery undefined.
1093
+ return {
1094
+ error: `Plugin-contributed skill "${skill.id}" is no longer registered`,
1095
+ };
1096
+ }
1097
+ // Shallow-clone so mutating the returned `body` below does not touch
1098
+ // the registry's stored copy — the registry must stay the source of
1099
+ // truth across repeated `skill_load` calls.
1100
+ const loaded: SkillDefinition = { ...pluginDef };
1101
+ loaded.body = loaded.body.replaceAll("{baseDir}", loaded.directoryPath);
1102
+ loaded.body = loaded.body.replaceAll(
1103
+ "{workspaceDir}",
1104
+ getWorkspaceDirDisplay(),
1105
+ );
1106
+ loaded.body = applyFeatureGatedSections(loaded.body);
1107
+ return { skill: loaded };
1108
+ }
1109
+
1021
1110
  let loaded: SkillDefinition | null;
1022
1111
  if (skill.bundled) {
1023
1112
  loaded = readBundledSkillFromDirectory(skill.directoryPath);
@@ -11,9 +11,26 @@ describe("compact.md prompt asset", () => {
11
11
  expect(prompt.length).toBeGreaterThan(0);
12
12
  });
13
13
 
14
- test("contains the '## Goals' section header (canary for truncation)", () => {
14
+ test("contains explicit length target (canary against accidental 'concise' reversion)", () => {
15
15
  const prompt = loadCompactPrompt();
16
- expect(prompt).toContain("## Goals");
16
+ expect(prompt).toContain("1500");
17
+ expect(prompt).toContain("4000");
18
+ expect(prompt.toLowerCase()).toContain("tokens");
19
+ });
20
+
21
+ test("includes the never-include guidance for injection tags", () => {
22
+ const prompt = loadCompactPrompt();
23
+ expect(prompt).toContain("<memory");
24
+ expect(prompt).toContain("<turn_context>");
25
+ expect(prompt.toLowerCase()).toContain("never include");
26
+ });
27
+
28
+ test("lists the flexible section headers", () => {
29
+ const prompt = loadCompactPrompt();
30
+ expect(prompt).toContain("## What We're Working On");
31
+ expect(prompt).toContain("## Decisions & Commitments");
32
+ expect(prompt).toContain("## Facts Worth Remembering");
33
+ expect(prompt).toContain("## Open Threads");
17
34
  });
18
35
  });
19
36
 
@@ -29,17 +46,18 @@ describe("loadCompactPromptOrFallback", () => {
29
46
  throw new Error("compact.md missing");
30
47
  });
31
48
  expect(result.length).toBeGreaterThan(0);
32
- expect(result).toContain("## Goals");
33
- expect(result).toContain("## Constraints");
34
- expect(result).toContain("## Decisions");
35
- expect(result).toContain("## Open Conversations");
36
- expect(result).toContain("## Key Artifacts");
37
- expect(result).toContain("## Recent Progress");
49
+ // Fallback must carry the same core guidance as the on-disk prompt so
50
+ // summary quality doesn't silently collapse when the bundled asset is
51
+ // missing (partial deploys, filesystem corruption).
52
+ expect(result).toContain("1500");
53
+ expect(result).toContain("4000");
54
+ expect(result).toContain("<memory");
55
+ expect(result.toLowerCase()).toContain("never include");
38
56
  });
39
57
 
40
58
  test("uses loadCompactPrompt as the default loader", () => {
41
59
  const result = loadCompactPromptOrFallback();
42
60
  expect(result.length).toBeGreaterThan(0);
43
- expect(result).toContain("## Goals");
61
+ expect(result).toContain("1500");
44
62
  });
45
63
  });
@@ -1,12 +1,26 @@
1
- You compress long assistant conversations into durable working memory.
2
- Focus on actionable state, not prose.
3
- Preserve concrete facts: goals, constraints, decisions, pending questions, file paths, commands, errors, and TODOs.
4
- Remove repetition and stale details that were superseded.
5
- Thread anchors: when a "Retained Thread References" section is present, each listed reply cites its parent via `→ Mxxxxxx`. If that parent appears in the Transcript, preserve its text verbatim (reactions may be aggregated as "N users reacted"). Omit when the section is absent.
6
- Return concise markdown using these section headers exactly:
7
- ## Goals
8
- ## Constraints
9
- ## Decisions
10
- ## Open Conversations
11
- ## Key Artifacts
12
- ## Recent Progress
1
+ You are summarizing a long conversation so that the assistant can keep working with it after older messages are dropped. Your summary will REPLACE those messages — the assistant's only access to what was said earlier will be what you write here.
2
+
3
+ Be thorough. Capture what happened, why it mattered, what's unresolved, and what was felt. Do not compress away emotional tone, relationship context, or nuance. Keep specific details (names, numbers, file paths, commands, URLs, exact phrasings) when they might matter later.
4
+
5
+ Target length: aim for 1500–4000 tokens. Use the upper end of that range when the conversation is rich in decisions, relationships, emotional content, or threads that are still open. Use the lower end when the conversation is short or a simple task execution.
6
+
7
+ Open with a 1–2 paragraph narrative describing what the conversation is about and where it currently stands. Then use `## ` section headers. Use these headers when they apply; skip sections that have nothing to say; add your own headers when something important doesn't fit:
8
+
9
+ - `## What We're Working On` — active tasks, projects, intentions
10
+ - `## Decisions & Commitments` — what was decided, what was promised, by whom
11
+ - `## Facts Worth Remembering` — durable details: names, preferences, constraints, background
12
+ - `## Open Threads` — unresolved questions, pending follow-ups, things the user is still thinking about
13
+ - `## Emotional Arc / Relationship Notes` — tone, feelings expressed, relational context (include when relevant; omit otherwise)
14
+ - `## Artifacts & References` — files, URLs, commands, code snippets, external systems referenced
15
+
16
+ If an existing summary is provided, update it: merge new information in, prefer the most recent and explicit detail on conflicts, and preserve anything that is still unresolved or still true. Do not restart from scratch.
17
+
18
+ **Never include in the summary:**
19
+
20
+ - Content inside `<memory __injected>`, `<memory>`, `<turn_context>`, `<workspace>`, `<knowledge_base>`, `<system_reminder>`, `<now_scratchpad>`, `<NOW.md …>`, `<active_thread>`, `<channel_capabilities>`, `<transport_hints>`, `<system_notice>`, or any other angle-bracket-tagged system blocks. These are system metadata attached to messages, not part of what the user or assistant said. Ignore them entirely.
21
+ - Tool-call boilerplate (retries, failed attempts the assistant recovered from, routine status updates). Summarize the *outcome* instead.
22
+ - Repetitive chit-chat that adds nothing to working memory.
23
+
24
+ **Thread anchors (Slack only):** if the input includes a "Retained Thread References" section, each listed reply cites its parent via `→ Mxxxxxx`. If that parent message appears in the transcript, preserve its text verbatim in the summary (reactions may be aggregated as "N users reacted"). Omit this entirely when no such section is present.
25
+
26
+ Return only the summary itself in markdown — no preamble, no meta-commentary about what you're doing.
@@ -70,72 +70,12 @@ export function calculateMaxToolResultChars(
70
70
  );
71
71
  }
72
72
 
73
- /**
74
- * Check whether a tool-result content block exceeds the computed character
75
- * budget for the given context window.
76
- */
77
- export function isOversizedToolResult(
78
- block: ToolResultContent,
79
- contextWindowTokens: number,
80
- ): boolean {
81
- if (typeof block.content !== "string") {
82
- return false;
83
- }
84
- const maxChars = calculateMaxToolResultChars(contextWindowTokens);
85
- return block.content.length > maxChars;
86
- }
87
-
88
- /**
89
- * If the tool-result block is oversized, return a shallow copy with its
90
- * `.content` truncated. Otherwise return the block unchanged.
91
- */
92
- export function truncateToolResultBlock(
93
- block: ToolResultContent,
94
- contextWindowTokens: number,
95
- ): ToolResultContent {
96
- const maxChars = calculateMaxToolResultChars(contextWindowTokens);
97
- if (block.content.length <= maxChars) {
98
- return block;
99
- }
100
- return {
101
- ...block,
102
- content: truncateToolResultText(block.content, maxChars),
103
- };
104
- }
105
-
106
- /**
107
- * Map over an array of content blocks, truncating any oversized tool results.
108
- * Returns a new array and the number of blocks that were truncated.
109
- */
110
- export function truncateOversizedToolResults(
111
- blocks: ContentBlock[],
112
- contextWindowTokens: number,
113
- ): { blocks: ContentBlock[]; truncatedCount: number } {
114
- let truncatedCount = 0;
115
-
116
- const mapped = blocks.map((block) => {
117
- if (block.type !== "tool_result") {
118
- return block;
119
- }
120
- const toolBlock = block as ToolResultContent;
121
- if (isOversizedToolResult(toolBlock, contextWindowTokens)) {
122
- truncatedCount++;
123
- return truncateToolResultBlock(toolBlock, contextWindowTokens);
124
- }
125
- return block;
126
- });
127
-
128
- return { blocks: mapped, truncatedCount };
129
- }
130
-
131
73
  /**
132
74
  * Aggressively truncate all tool-result text across an entire message history.
133
75
  *
134
- * Unlike `truncateOversizedToolResults` (which operates on a flat block array
135
- * for a single turn), this walks every message and truncates tool_result
136
- * `.content` strings that exceed `maxChars`. This is used during overflow
137
- * recovery where we need to shrink the overall payload, not just individual
138
- * oversized results.
76
+ * Walks every message and truncates tool_result `.content` strings that
77
+ * exceed `maxChars`. Used during overflow recovery where we need to shrink
78
+ * the overall payload, not just individual oversized results.
139
79
  */
140
80
  export function truncateToolResultsAcrossHistory(
141
81
  messages: Message[],