@vellumai/assistant 0.8.4 → 0.8.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 (802) hide show
  1. package/AGENTS.md +33 -1
  2. package/ARCHITECTURE.md +3 -3
  3. package/bunfig.toml +6 -1
  4. package/docs/browser-use-architecture-phase2.md +1 -1
  5. package/docs/credential-execution-service.md +6 -6
  6. package/docs/plugins.md +4 -3
  7. package/knip.json +2 -1
  8. package/node_modules/@vellumai/skill-host-contracts/src/client.ts +12 -13
  9. package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +4 -1
  10. package/node_modules/@vellumai/skill-host-contracts/src/tool-types.ts +16 -14
  11. package/openapi.yaml +2748 -216
  12. package/package.json +1 -1
  13. package/src/__tests__/actor-token-service.test.ts +3 -2
  14. package/src/__tests__/agent-loop-exit-reason.test.ts +102 -9
  15. package/src/__tests__/agent-loop-override-profile.test.ts +2 -1
  16. package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +1 -0
  17. package/src/__tests__/agent-wake-override-profile.test.ts +1 -0
  18. package/src/__tests__/always-loaded-tools-guard.test.ts +2 -2
  19. package/src/__tests__/annotate-risk-options.test.ts +1 -0
  20. package/src/__tests__/anthropic-provider.test.ts +34 -37
  21. package/src/__tests__/approval-cascade.test.ts +1 -0
  22. package/src/__tests__/approval-routes-http.test.ts +9 -13
  23. package/src/__tests__/assert-not-live-db.ts +79 -0
  24. package/src/__tests__/assistant-event-hub-self-exclusion.test.ts +293 -0
  25. package/src/__tests__/assistant-feature-flags-integration.test.ts +12 -28
  26. package/src/__tests__/audit-log-rotation.test.ts +72 -18
  27. package/src/__tests__/auto-analysis-end-to-end.test.ts +6 -6
  28. package/src/__tests__/background-workers-disk-pressure.test.ts +8 -11
  29. package/src/__tests__/browser-skill-endstate.test.ts +3 -3
  30. package/src/__tests__/btw-routes.test.ts +5 -5
  31. package/src/__tests__/call-controller.test.ts +3 -3
  32. package/src/__tests__/cancel-resolves-conversation-key.test.ts +1 -1
  33. package/src/__tests__/channel-approval-routes.test.ts +3 -2
  34. package/src/__tests__/channel-guardian.test.ts +6 -5
  35. package/src/__tests__/channel-readiness-slack-remote.test.ts +175 -0
  36. package/src/__tests__/channel-reply-delivery.test.ts +35 -0
  37. package/src/__tests__/channel-retry-sweep.test.ts +320 -3
  38. package/src/__tests__/checker.test.ts +18 -27
  39. package/src/__tests__/compaction-events.test.ts +2 -0
  40. package/src/__tests__/compaction-trail-store.test.ts +264 -0
  41. package/src/__tests__/compactor-call-site-logging.test.ts +215 -0
  42. package/src/__tests__/compactor-preserved-tail-count.test.ts +1 -0
  43. package/src/__tests__/computer-use-skill-manifest-regression.test.ts +12 -16
  44. package/src/__tests__/computer-use-tools.test.ts +14 -18
  45. package/src/__tests__/config-loader-backfill.test.ts +13 -28
  46. package/src/__tests__/config-loader-corrupt.test.ts +5 -5
  47. package/src/__tests__/config-loader-platform-defaults.test.ts +93 -26
  48. package/src/__tests__/config-loader-quarantine-bulletin.test.ts +3 -3
  49. package/src/__tests__/config-managed-gemini-defaults.test.ts +3 -4
  50. package/src/__tests__/config-schema.test.ts +10 -10
  51. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -1
  52. package/src/__tests__/connection-model-compat.test.ts +83 -0
  53. package/src/__tests__/contacts-tools.test.ts +3 -2
  54. package/src/__tests__/context-token-estimator.test.ts +22 -0
  55. package/src/__tests__/conversation-abort-tool-results.test.ts +5 -0
  56. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +2 -1
  57. package/src/__tests__/conversation-agent-loop-handlers-max-tokens.test.ts +55 -0
  58. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +2 -1
  59. package/src/__tests__/conversation-agent-loop-overflow.test.ts +231 -2
  60. package/src/__tests__/conversation-agent-loop.test.ts +581 -54
  61. package/src/__tests__/conversation-analysis-routes.test.ts +1 -0
  62. package/src/__tests__/conversation-app-control-instantiation.test.ts +31 -24
  63. package/src/__tests__/conversation-app-control-lifecycle.test.ts +1 -0
  64. package/src/__tests__/conversation-attention-store.test.ts +101 -0
  65. package/src/__tests__/conversation-attention-telegram.test.ts +3 -2
  66. package/src/__tests__/conversation-clear-safety.test.ts +25 -25
  67. package/src/__tests__/conversation-confirmation-signals.test.ts +1 -0
  68. package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +1 -1
  69. package/src/__tests__/conversation-disk-view-integration.test.ts +2 -2
  70. package/src/__tests__/conversation-error.test.ts +61 -0
  71. package/src/__tests__/conversation-fork-crud.test.ts +239 -15
  72. package/src/__tests__/conversation-fork-route.test.ts +3 -2
  73. package/src/__tests__/conversation-history-web-search.test.ts +1 -0
  74. package/src/__tests__/conversation-inference-profile-list.test.ts +3 -2
  75. package/src/__tests__/conversation-inference-profile-route.test.ts +3 -2
  76. package/src/__tests__/conversation-lifecycle.test.ts +53 -11
  77. package/src/__tests__/conversation-list-source.test.ts +3 -2
  78. package/src/__tests__/conversation-load-history-repair.test.ts +2 -1
  79. package/src/__tests__/{conversation-load-cleaned-at.test.ts → conversation-load-history-stripped.test.ts} +14 -13
  80. package/src/__tests__/conversation-pairing.test.ts +53 -0
  81. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +26 -7
  82. package/src/__tests__/conversation-process-callsite.test.ts +1 -0
  83. package/src/__tests__/conversation-provider-retry-repair.test.ts +6 -0
  84. package/src/__tests__/conversation-queue.test.ts +333 -291
  85. package/src/__tests__/conversation-routes-disk-view.test.ts +112 -18
  86. package/src/__tests__/conversation-routes-guardian-reply.test.ts +33 -8
  87. package/src/__tests__/conversation-routes-slash-commands.test.ts +68 -2
  88. package/src/__tests__/conversation-runtime-assembly.test.ts +78 -0
  89. package/src/__tests__/conversation-skill-tools.test.ts +40 -147
  90. package/src/__tests__/conversation-slash-queue.test.ts +84 -32
  91. package/src/__tests__/conversation-slash-unknown.test.ts +5 -0
  92. package/src/__tests__/conversation-speed-override.test.ts +1 -0
  93. package/src/__tests__/conversation-store.test.ts +1 -1
  94. package/src/__tests__/conversation-surfaces-action-delivery.test.ts +46 -0
  95. package/src/__tests__/conversation-surfaces-data-persist.test.ts +1 -0
  96. package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +6 -3
  97. package/src/__tests__/conversation-surfaces-standalone.test.ts +6 -3
  98. package/src/__tests__/conversation-surfaces-state-update.test.ts +3 -3
  99. package/src/__tests__/conversation-surfaces-table-action.test.ts +7 -17
  100. package/src/__tests__/conversation-sync-tags.test.ts +218 -35
  101. package/src/__tests__/conversation-title-service.test.ts +1 -0
  102. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +30 -0
  103. package/src/__tests__/conversation-usage.test.ts +1 -0
  104. package/src/__tests__/conversation-workspace-cache-state.test.ts +2 -0
  105. package/src/__tests__/conversation-workspace-injection.test.ts +6 -1
  106. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +6 -1
  107. package/src/__tests__/credential-broker-browser-fill.test.ts +3 -3
  108. package/src/__tests__/credential-broker-server-use.test.ts +5 -5
  109. package/src/__tests__/credential-execution-client.test.ts +72 -1
  110. package/src/__tests__/credential-execution-feature-gates.test.ts +19 -19
  111. package/src/__tests__/credential-execution-tools.test.ts +6 -6
  112. package/src/__tests__/credential-health-service.test.ts +252 -3
  113. package/src/__tests__/credential-security-invariants.test.ts +6 -5
  114. package/src/__tests__/credential-vault-unit.test.ts +21 -21
  115. package/src/__tests__/credential-vault.test.ts +5 -5
  116. package/src/__tests__/cross-provider-web-search.test.ts +56 -2
  117. package/src/__tests__/db-connection-isolation.test.ts +7 -6
  118. package/src/__tests__/db-conversation-fork-lineage-migration.test.ts +8 -10
  119. package/src/__tests__/db-conversation-inference-profile-migration.test.ts +7 -10
  120. package/src/__tests__/db-llm-request-log-provider-migration.test.ts +9 -15
  121. package/src/__tests__/db-test-helpers.ts +58 -0
  122. package/src/__tests__/disk-pressure-guard.test.ts +58 -41
  123. package/src/__tests__/disk-pressure-lifecycle.test.ts +13 -10
  124. package/src/__tests__/disk-pressure-routes.test.ts +0 -33
  125. package/src/__tests__/disk-pressure-tools.test.ts +0 -4
  126. package/src/__tests__/dm-persistence.test.ts +26 -40
  127. package/src/__tests__/document-create-dedupe.test.ts +189 -0
  128. package/src/__tests__/document-find-replace.test.ts +3 -2
  129. package/src/__tests__/document-tool-security.test.ts +81 -2
  130. package/src/__tests__/dynamic-page-surface.test.ts +2 -2
  131. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +5 -4
  132. package/src/__tests__/email-html-renderer.test.ts +12 -0
  133. package/src/__tests__/encrypted-store-test-helpers.ts +56 -0
  134. package/src/__tests__/encrypted-store.test.ts +11 -9
  135. package/src/__tests__/feature-flag-test-helpers.ts +53 -0
  136. package/src/__tests__/filing-service.test.ts +1 -0
  137. package/src/__tests__/first-greeting.test.ts +62 -12
  138. package/src/__tests__/gateway-flag-listener.test.ts +236 -0
  139. package/src/__tests__/gemini-provider.test.ts +104 -0
  140. package/src/__tests__/guardian-action-sweep.test.ts +3 -2
  141. package/src/__tests__/guardian-dispatch.test.ts +0 -1
  142. package/src/__tests__/guardian-outbound-http.test.ts +10 -7
  143. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +48 -3
  144. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +2 -1
  145. package/src/__tests__/heartbeat-disk-pressure.test.ts +5 -0
  146. package/src/__tests__/heartbeat-service.test.ts +5 -0
  147. package/src/__tests__/helpers/mock-logger.ts +26 -0
  148. package/src/__tests__/host-bash-routes.test.ts +1 -0
  149. package/src/__tests__/host-cu-routes-targeted.test.ts +1 -0
  150. package/src/__tests__/host-file-routes-targeted.test.ts +1 -0
  151. package/src/__tests__/host-shell-tool.test.ts +6 -5
  152. package/src/__tests__/host-transfer-routes-targeted.test.ts +1 -0
  153. package/src/__tests__/http-conversation-lineage.test.ts +3 -2
  154. package/src/__tests__/http-user-message-parity.test.ts +29 -7
  155. package/src/__tests__/identity-intro-cache.test.ts +133 -22
  156. package/src/__tests__/inbound-slack-persistence.test.ts +44 -72
  157. package/src/__tests__/inference-profile-reaper.test.ts +3 -2
  158. package/src/__tests__/inference-profile-session-ipc.test.ts +3 -2
  159. package/src/__tests__/init-feature-flag-overrides.test.ts +5 -6
  160. package/src/__tests__/injector-disk-pressure.test.ts +3 -17
  161. package/src/__tests__/inline-skill-load-permissions.test.ts +4 -4
  162. package/src/__tests__/list-messages-hidden-metadata.test.ts +80 -0
  163. package/src/__tests__/list-messages-tool-merge.test.ts +70 -11
  164. package/src/__tests__/llm-context-normalization.test.ts +42 -0
  165. package/src/__tests__/llm-request-log-call-site.test.ts +136 -0
  166. package/src/__tests__/llm-request-log-source-clickhouse.test.ts +26 -0
  167. package/src/__tests__/llm-resolver.test.ts +408 -9
  168. package/src/__tests__/llm-schema.test.ts +1 -1
  169. package/src/__tests__/llm-usage-store.test.ts +66 -0
  170. package/src/__tests__/logger.test.ts +89 -0
  171. package/src/__tests__/manual-token-reconciliation.test.ts +76 -1
  172. package/src/__tests__/mcp-abort-signal.test.ts +16 -2
  173. package/src/__tests__/mcp-client-auth.test.ts +14 -0
  174. package/src/__tests__/media-generate-image.test.ts +31 -0
  175. package/src/__tests__/memory-v2-static-injector.test.ts +7 -7
  176. package/src/__tests__/messaging-send-tool.test.ts +1 -0
  177. package/src/__tests__/migration-import-from-url.test.ts +3 -3
  178. package/src/__tests__/mock-gateway-ipc.ts +18 -2
  179. package/src/__tests__/model-intents.test.ts +4 -6
  180. package/src/__tests__/native-web-search.test.ts +30 -2
  181. package/src/__tests__/notification-deep-link.test.ts +62 -0
  182. package/src/__tests__/notification-guardian-path.test.ts +0 -1
  183. package/src/__tests__/oauth-commands-routes.test.ts +37 -0
  184. package/src/__tests__/oauth-provider-visibility.test.ts +8 -8
  185. package/src/__tests__/oauth-store.test.ts +3 -2
  186. package/src/__tests__/onboarding-template-contract.test.ts +4 -3
  187. package/src/__tests__/openai-provider.test.ts +54 -9
  188. package/src/__tests__/openai-responses-provider.test.ts +176 -14
  189. package/src/__tests__/openrouter-provider-only.test.ts +27 -5
  190. package/src/__tests__/outbound-slack-persistence.test.ts +46 -1
  191. package/src/__tests__/pending-interactions-resolved-event.test.ts +0 -1
  192. package/src/__tests__/persistence-pipeline.test.ts +139 -1
  193. package/src/__tests__/persistence-secret-redaction.test.ts +83 -12
  194. package/src/__tests__/platform-bash-auto-approve.test.ts +2 -2
  195. package/src/__tests__/platform.test.ts +2 -2
  196. package/src/__tests__/plugin-api-tool-definition.test.ts +92 -0
  197. package/src/__tests__/plugin-bootstrap.test.ts +11 -13
  198. package/src/__tests__/plugin-tool-contribution.test.ts +50 -40
  199. package/src/__tests__/plugin-types.test.ts +3 -2
  200. package/src/__tests__/prechat-onboarding-contract.test.ts +131 -98
  201. package/src/__tests__/pricing.test.ts +12 -0
  202. package/src/__tests__/process-message-background-slack.test.ts +21 -16
  203. package/src/__tests__/process-message-display-content.test.ts +19 -22
  204. package/src/__tests__/provider-catalog-visibility.test.ts +9 -9
  205. package/src/__tests__/provider-platform-proxy-integration.test.ts +216 -4
  206. package/src/__tests__/provider-registry-ollama.test.ts +45 -22
  207. package/src/__tests__/prune-jobs-changes-parser.test.ts +61 -0
  208. package/src/__tests__/recording-handler.test.ts +1 -0
  209. package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +1 -0
  210. package/src/__tests__/registry.test.ts +84 -84
  211. package/src/__tests__/relay-server.test.ts +10 -10
  212. package/src/__tests__/require-fresh-approval.test.ts +2 -2
  213. package/src/__tests__/runtime-attachment-metadata.test.ts +3 -2
  214. package/src/__tests__/runtime-events-sse-bilingual.test.ts +154 -0
  215. package/src/__tests__/schedule-store.test.ts +16 -1
  216. package/src/__tests__/scheduler-reuse-conversation.test.ts +48 -3
  217. package/src/__tests__/secret-ingress-http.test.ts +5 -1
  218. package/src/__tests__/secure-keys.test.ts +3 -3
  219. package/src/__tests__/send-endpoint-busy.test.ts +81 -42
  220. package/src/__tests__/server-history-render.test.ts +4 -1
  221. package/src/__tests__/shell-tool-proxy-mode.test.ts +1 -1
  222. package/src/__tests__/skill-feature-flags-integration.test.ts +8 -10
  223. package/src/__tests__/skill-feature-flags.test.ts +16 -18
  224. package/src/__tests__/skill-load-feature-flag.test.ts +5 -5
  225. package/src/__tests__/skill-projection-feature-flag.test.ts +48 -37
  226. package/src/__tests__/skill-projection.benchmark.test.ts +7 -13
  227. package/src/__tests__/skill-tool-factory.test.ts +97 -96
  228. package/src/__tests__/slack-channel-config.test.ts +3 -3
  229. package/src/__tests__/subagent-call-site-routing.test.ts +11 -3
  230. package/src/__tests__/subagent-disposal.test.ts +27 -8
  231. package/src/__tests__/subagent-fork-notifications.test.ts +24 -9
  232. package/src/__tests__/subagent-fork-spawn.test.ts +13 -4
  233. package/src/__tests__/subagent-manager-notify.test.ts +20 -8
  234. package/src/__tests__/subagent-notify-parent.test.ts +6 -5
  235. package/src/__tests__/subagent-spawn-tool-fork.test.ts +58 -0
  236. package/src/__tests__/subagent-tools.test.ts +2 -1
  237. package/src/__tests__/suggestion-routes.test.ts +2 -0
  238. package/src/__tests__/sync-message-contract.test.ts +59 -0
  239. package/src/__tests__/system-prompt.test.ts +183 -131
  240. package/src/__tests__/terminal-tools.test.ts +1 -1
  241. package/src/__tests__/test-preload-verifier.ts +68 -0
  242. package/src/__tests__/test-preload.ts +32 -39
  243. package/src/__tests__/tool-approval-handler.test.ts +1 -5
  244. package/src/__tests__/tool-execute-pipeline.test.ts +2 -2
  245. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +2 -5
  246. package/src/__tests__/tool-executor-lifecycle-events.test.ts +35 -12
  247. package/src/__tests__/tool-executor.test.ts +64 -72
  248. package/src/__tests__/tool-grant-request-escalation.test.ts +1 -6
  249. package/src/__tests__/tool-preview-lifecycle.test.ts +1 -0
  250. package/src/__tests__/tool-result-metadata-plumbing.test.ts +1 -0
  251. package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
  252. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +1 -6
  253. package/src/__tests__/trusted-contact-multichannel.test.ts +0 -1
  254. package/src/__tests__/twilio-routes.test.ts +3 -2
  255. package/src/__tests__/ui-file-upload-surface.test.ts +2 -2
  256. package/src/__tests__/usage-routes.test.ts +3 -0
  257. package/src/__tests__/validate-input.test.ts +381 -0
  258. package/src/__tests__/verification-control-plane-policy.test.ts +3 -2
  259. package/src/__tests__/voice-scoped-grant-consumer.test.ts +2 -1
  260. package/src/__tests__/voice-session-bridge.test.ts +37 -28
  261. package/src/__tests__/workspace-git-service.test.ts +6 -5
  262. package/src/__tests__/workspace-migration-089-move-memory-tree-out-of-v3.test.ts +86 -0
  263. package/src/__tests__/workspace-migration-090-memory-router-cost-optimized-profile.test.ts +326 -0
  264. package/src/__tests__/workspace-migration-091-retighten-migration-onboarding-thread.test.ts +166 -0
  265. package/src/acp/__tests__/prepare-agent-env.test.ts +146 -0
  266. package/src/acp/prepare-agent-env.ts +78 -0
  267. package/src/acp/session-manager.ts +6 -7
  268. package/src/agent/loop.ts +88 -0
  269. package/src/api/README.md +127 -0
  270. package/src/api/constants/call-sites.ts +27 -0
  271. package/src/api/events/assistant-outbound-attachment.ts +51 -0
  272. package/src/api/events/assistant-text-delta.ts +32 -0
  273. package/src/api/events/assistant-turn-start.ts +33 -0
  274. package/src/api/events/document-comment-created.ts +48 -0
  275. package/src/api/events/document-comment-deleted.ts +24 -0
  276. package/src/api/events/document-comment-reopened.ts +25 -0
  277. package/src/api/events/document-comment-resolved.ts +27 -0
  278. package/src/api/events/generation-cancelled.ts +24 -0
  279. package/src/api/events/generation-handoff.ts +41 -0
  280. package/src/api/events/message-complete.ts +42 -0
  281. package/src/api/events/open-url.ts +30 -0
  282. package/src/api/events/relationship-state-updated.ts +25 -0
  283. package/src/api/events/tool-use-start.ts +32 -0
  284. package/src/api/index.ts +129 -0
  285. package/src/api/package.json +10 -0
  286. package/src/api/responses/llm-context-response.ts +39 -0
  287. package/src/api/responses/llm-request-log-entry.ts +93 -0
  288. package/src/api/responses/memory-recall-log.ts +65 -0
  289. package/src/api/responses/memory-v2-activation-log.ts +78 -0
  290. package/src/background-wake/background-wake-routes.test.ts +868 -0
  291. package/src/background-wake/platform-client.test.ts +308 -0
  292. package/src/background-wake/platform-client.ts +167 -0
  293. package/src/background-wake/publisher.ts +91 -0
  294. package/src/background-wake/runtime-registry.ts +24 -0
  295. package/src/background-wake/wake-intent-hooks.test.ts +282 -0
  296. package/src/calls/guardian-dispatch.ts +1 -0
  297. package/src/calls/voice-session-bridge.ts +4 -4
  298. package/src/cli/commands/__tests__/browser.test.ts +23 -5
  299. package/src/cli/commands/__tests__/conversations-slack.test.ts +16 -0
  300. package/src/cli/commands/__tests__/domain-register.test.ts +110 -0
  301. package/src/cli/commands/__tests__/domain-status.test.ts +33 -33
  302. package/src/cli/commands/__tests__/inference-send.test.ts +108 -5
  303. package/src/cli/commands/__tests__/memory-v2-compare-render.test.ts +98 -0
  304. package/src/cli/commands/__tests__/memory-v2.test.ts +1 -0
  305. package/src/cli/commands/__tests__/memory-v3-render.test.ts +340 -0
  306. package/src/cli/commands/__tests__/notifications.test.ts +184 -40
  307. package/src/cli/commands/browser.ts +247 -0
  308. package/src/cli/commands/channels/__tests__/channels.test.ts +143 -0
  309. package/src/cli/commands/channels/index.ts +229 -0
  310. package/src/cli/commands/domain.ts +91 -41
  311. package/src/cli/commands/inference.ts +93 -40
  312. package/src/cli/commands/memory-v2-compare-render.ts +115 -0
  313. package/src/cli/commands/memory-v2.ts +176 -1
  314. package/src/cli/commands/memory-v3-render.ts +491 -0
  315. package/src/cli/commands/memory-v3.ts +567 -0
  316. package/src/cli/commands/notifications.ts +365 -55
  317. package/src/cli/lib/open-browser.ts +7 -2
  318. package/src/cli/program.ts +4 -0
  319. package/src/config/assistant-feature-flags.ts +39 -46
  320. package/src/config/bundled-skills/document-editor/SKILL.md +16 -3
  321. package/src/config/bundled-skills/document-editor/TOOLS.json +18 -0
  322. package/src/config/bundled-skills/document-editor/tools/document-open.ts +12 -0
  323. package/src/config/bundled-skills/image-studio/SKILL.md +4 -0
  324. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +2 -2
  325. package/src/config/bundled-skills/media-processing/tools/ingest-media.ts +13 -8
  326. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +10 -3
  327. package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +16 -14
  328. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +7 -2
  329. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +7 -2
  330. package/src/config/bundled-skills/schedule/SKILL.md +1 -1
  331. package/src/config/bundled-skills/schedule/TOOLS.json +2 -2
  332. package/src/config/bundled-skills/settings/tools/open-system-settings.ts +1 -0
  333. package/src/config/bundled-tool-registry.ts +2 -0
  334. package/src/config/call-site-defaults.ts +8 -7
  335. package/src/config/feature-flag-cache.ts +86 -0
  336. package/src/config/feature-flag-registry.json +33 -17
  337. package/src/config/llm-context-resolution.ts +10 -1
  338. package/src/config/llm-resolver.ts +121 -15
  339. package/src/config/loader.ts +4 -5
  340. package/src/config/schemas/__tests__/memory-v2.test.ts +228 -1
  341. package/src/config/schemas/call-site-catalog.ts +21 -7
  342. package/src/config/schemas/heartbeat.ts +1 -1
  343. package/src/config/schemas/llm.ts +102 -2
  344. package/src/config/schemas/memory-v2.ts +272 -0
  345. package/src/config/schemas/memory.ts +2 -1
  346. package/src/config/schemas/services.ts +6 -2
  347. package/src/config/seed-inference-profiles.ts +36 -16
  348. package/src/context/compactor.ts +52 -0
  349. package/src/context/token-estimator.ts +10 -5
  350. package/src/conversations/__tests__/message-consolidation.test.ts +350 -0
  351. package/src/conversations/message-consolidation.ts +404 -0
  352. package/src/credential-execution/executable-discovery.ts +40 -0
  353. package/src/credential-execution/process-manager.ts +6 -2
  354. package/src/credential-health/credential-health-service.ts +125 -40
  355. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +3 -6
  356. package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +13 -15
  357. package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +2 -3
  358. package/src/daemon/__tests__/daemon-skill-host.test.ts +2 -0
  359. package/src/daemon/__tests__/meet-manifest-loader.test.ts +25 -12
  360. package/src/daemon/__tests__/native-web-search-metadata.test.ts +1 -0
  361. package/src/daemon/__tests__/switch-inference-profile-tool.test.ts +107 -0
  362. package/src/daemon/__tests__/web-search-status-text.test.ts +1 -0
  363. package/src/daemon/conversation-agent-loop-handlers.ts +390 -80
  364. package/src/daemon/conversation-agent-loop.ts +244 -90
  365. package/src/daemon/conversation-error.ts +64 -6
  366. package/src/daemon/conversation-lifecycle.ts +27 -22
  367. package/src/daemon/conversation-messaging.ts +84 -43
  368. package/src/daemon/conversation-process.ts +74 -37
  369. package/src/daemon/conversation-runtime-assembly.ts +38 -17
  370. package/src/daemon/conversation-skill-tools.ts +14 -30
  371. package/src/daemon/conversation-surfaces.ts +69 -34
  372. package/src/daemon/conversation-tool-setup.ts +77 -32
  373. package/src/daemon/conversation-usage.ts +2 -0
  374. package/src/daemon/conversation.ts +40 -75
  375. package/src/daemon/daemon-control.ts +1 -1
  376. package/src/daemon/daemon-skill-host.ts +9 -2
  377. package/src/daemon/disk-pressure-guard.ts +39 -29
  378. package/src/daemon/first-greeting.ts +31 -13
  379. package/src/daemon/handlers/config-model.test.ts +1 -0
  380. package/src/daemon/handlers/conversations.ts +11 -3
  381. package/src/daemon/handlers/shared.ts +6 -1
  382. package/src/daemon/host-browser-proxy.ts +5 -5
  383. package/src/daemon/host-cu-proxy.ts +4 -4
  384. package/src/daemon/host-file-proxy.ts +4 -4
  385. package/src/daemon/host-proxy-base.ts +4 -4
  386. package/src/daemon/host-transfer-proxy.ts +10 -10
  387. package/src/daemon/lifecycle.ts +29 -26
  388. package/src/daemon/mcp-reload-service.ts +1 -1
  389. package/src/daemon/meet-manifest-loader.ts +11 -24
  390. package/src/daemon/message-types/conversations.ts +22 -27
  391. package/src/daemon/message-types/document-comments.ts +8 -44
  392. package/src/daemon/message-types/home.ts +2 -14
  393. package/src/daemon/message-types/integrations.ts +2 -7
  394. package/src/daemon/message-types/messages.ts +25 -48
  395. package/src/daemon/message-types/subagents.ts +6 -0
  396. package/src/daemon/message-types/sync.ts +14 -0
  397. package/src/daemon/process-message.ts +9 -9
  398. package/src/daemon/providers-setup.ts +1 -1
  399. package/src/daemon/server.ts +16 -0
  400. package/src/daemon/shutdown-handlers.ts +24 -5
  401. package/src/daemon/switch-inference-profile-tool.ts +62 -0
  402. package/src/daemon/tool-setup-types.ts +7 -0
  403. package/src/daemon/wake-target-adapter.ts +10 -0
  404. package/src/documents/document-store.ts +38 -0
  405. package/src/export/__tests__/transcript-formatter.test.ts +1 -0
  406. package/src/heartbeat/__tests__/heartbeat-service.test.ts +30 -1
  407. package/src/heartbeat/heartbeat-service.ts +63 -0
  408. package/src/home/__tests__/feed-writer.test.ts +161 -0
  409. package/src/home/__tests__/post-connect-feed.test.ts +1 -0
  410. package/src/home/__tests__/suggested-prompts.test.ts +55 -59
  411. package/src/home/feed-writer.ts +146 -7
  412. package/src/home/home-greeting.ts +0 -9
  413. package/src/home/suggested-prompts.ts +27 -154
  414. package/src/ipc/__tests__/cli-ipc.test.ts +1 -0
  415. package/src/ipc/gateway-client.test.ts +4 -1
  416. package/src/ipc/gateway-flag-listener.ts +123 -0
  417. package/src/ipc/skill-routes/__tests__/memory.test.ts +1 -0
  418. package/src/ipc/skill-routes/__tests__/registries.test.ts +36 -7
  419. package/src/ipc/skill-routes/memory.ts +4 -3
  420. package/src/ipc/skill-routes/registries.ts +35 -40
  421. package/src/memory/__tests__/db-async-query.test.ts +165 -0
  422. package/src/memory/__tests__/db-maintenance.test.ts +115 -0
  423. package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +242 -0
  424. package/src/memory/__tests__/jobs-store-job-classes.test.ts +28 -1
  425. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +26 -5
  426. package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +1 -0
  427. package/src/memory/__tests__/memory-retrospective-job.test.ts +8 -0
  428. package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +1 -0
  429. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +31 -0
  430. package/src/memory/auto-analysis-enqueue.ts +5 -1
  431. package/src/memory/conversation-attention-store.ts +17 -3
  432. package/src/memory/conversation-crud.ts +423 -182
  433. package/src/memory/conversation-starters-cadence.ts +3 -1
  434. package/src/memory/conversation-title-service.ts +19 -3
  435. package/src/memory/db-async-query.ts +214 -0
  436. package/src/memory/db-connection.ts +29 -19
  437. package/src/memory/db-init.ts +14 -0
  438. package/src/memory/db-maintenance.ts +30 -21
  439. package/src/memory/db-singleton.ts +77 -0
  440. package/src/memory/delivery-channels.ts +82 -0
  441. package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +2 -4
  442. package/src/memory/graph/bootstrap.ts +8 -1
  443. package/src/memory/graph/capability-seed.ts +7 -3
  444. package/src/memory/graph/conversation-graph-memory.ts +100 -17
  445. package/src/memory/graph/extraction.ts +1 -5
  446. package/src/memory/graph/graph-search.ts +7 -1
  447. package/src/memory/graph/retriever.test.ts +3 -3
  448. package/src/memory/indexer.ts +28 -18
  449. package/src/memory/job-handlers/cleanup.ts +76 -18
  450. package/src/memory/job-handlers/conversation-starters.ts +1 -4
  451. package/src/memory/job-handlers/embedding.test.ts +3 -2
  452. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +5 -2
  453. package/src/memory/jobs/embed-pkb-file.ts +6 -1
  454. package/src/memory/jobs-store.ts +14 -0
  455. package/src/memory/jobs-worker.ts +66 -22
  456. package/src/memory/llm-request-log-source-clickhouse.ts +122 -2
  457. package/src/memory/llm-request-log-source-local.ts +31 -0
  458. package/src/memory/llm-request-log-source.ts +40 -2
  459. package/src/memory/llm-request-log-store.ts +228 -1
  460. package/src/memory/llm-usage-store.ts +24 -0
  461. package/src/memory/memory-retrospective-enqueue.ts +8 -1
  462. package/src/memory/memory-retrospective-job.ts +5 -0
  463. package/src/memory/memory-v2-activation-log-store.ts +110 -7
  464. package/src/memory/migrations/260-rename-cleaned-at.ts +44 -0
  465. package/src/memory/migrations/261-llm-usage-add-raw-usage.ts +36 -0
  466. package/src/memory/migrations/262-memory-v3-coactivation.ts +57 -0
  467. package/src/memory/migrations/263-memory-v3-auto-edges.ts +50 -0
  468. package/src/memory/migrations/264-llm-request-log-call-site.ts +29 -0
  469. package/src/memory/migrations/265-drop-provider-connection-status.ts +26 -0
  470. package/src/memory/migrations/266-messages-client-message-id.ts +43 -0
  471. package/src/memory/migrations/index.ts +19 -0
  472. package/src/memory/migrations/registry.ts +33 -0
  473. package/src/memory/schema/conversations.ts +10 -2
  474. package/src/memory/schema/inference.ts +0 -1
  475. package/src/memory/schema/infrastructure.ts +21 -0
  476. package/src/memory/tool-usage-store.ts +36 -8
  477. package/src/memory/v2/__tests__/backfill-jobs.test.ts +5 -2
  478. package/src/memory/v2/__tests__/consolidation-job.test.ts +1 -0
  479. package/src/memory/v2/__tests__/harness-compare.test.ts +186 -0
  480. package/src/memory/v2/__tests__/harness-metrics.test.ts +83 -0
  481. package/src/memory/v2/__tests__/harness-oracle.test.ts +257 -0
  482. package/src/memory/v2/__tests__/harness-replay-input.test.ts +230 -0
  483. package/src/memory/v2/__tests__/harness-runner.test.ts +135 -0
  484. package/src/memory/v2/__tests__/injection.test.ts +127 -98
  485. package/src/memory/v2/__tests__/qdrant.test.ts +36 -0
  486. package/src/memory/v2/__tests__/router.test.ts +171 -3
  487. package/src/memory/v2/__tests__/sweep-job.test.ts +6 -3
  488. package/src/memory/v2/harness/compare.ts +57 -0
  489. package/src/memory/v2/harness/metrics.ts +128 -0
  490. package/src/memory/v2/harness/oracle.ts +145 -0
  491. package/src/memory/v2/harness/replay-input.ts +240 -0
  492. package/src/memory/v2/harness/retriever.ts +74 -0
  493. package/src/memory/v2/harness/router-retriever.ts +43 -0
  494. package/src/memory/v2/harness/runner.ts +112 -0
  495. package/src/memory/v2/harness/trace.ts +64 -0
  496. package/src/memory/v2/injection.ts +21 -15
  497. package/src/memory/v2/prompts/router.ts +26 -1
  498. package/src/memory/v2/qdrant.ts +14 -2
  499. package/src/memory/v2/router.ts +171 -18
  500. package/src/memory/v3/__tests__/coactivation-store.test.ts +422 -0
  501. package/src/memory/v3/__tests__/consolidation-job.test.ts +466 -0
  502. package/src/memory/v3/__tests__/coretrieval-seed.test.ts +270 -0
  503. package/src/memory/v3/__tests__/edge-learning-job.test.ts +324 -0
  504. package/src/memory/v3/__tests__/edges.test.ts +706 -0
  505. package/src/memory/v3/__tests__/filter.test.ts +560 -0
  506. package/src/memory/v3/__tests__/gate.test.ts +637 -0
  507. package/src/memory/v3/__tests__/index-composition.test.ts +291 -0
  508. package/src/memory/v3/__tests__/loop.test.ts +775 -0
  509. package/src/memory/v3/__tests__/retriever.test.ts +226 -0
  510. package/src/memory/v3/__tests__/scouts.test.ts +489 -0
  511. package/src/memory/v3/__tests__/shadow-diff.test.ts +225 -0
  512. package/src/memory/v3/__tests__/shadow-middleware.test.ts +398 -0
  513. package/src/memory/v3/__tests__/system-prompts.test.ts +154 -0
  514. package/src/memory/v3/__tests__/traversal.test.ts +508 -0
  515. package/src/memory/v3/__tests__/tree-index.test.ts +280 -0
  516. package/src/memory/v3/__tests__/tree-store.test.ts +529 -0
  517. package/src/memory/v3/__tests__/tree-walk.test.ts +784 -0
  518. package/src/memory/v3/__tests__/validate.test.ts +277 -0
  519. package/src/memory/v3/auto-edges.ts +223 -0
  520. package/src/memory/v3/coactivation-store.ts +124 -0
  521. package/src/memory/v3/consolidation-job.ts +323 -0
  522. package/src/memory/v3/coretrieval-seed.ts +240 -0
  523. package/src/memory/v3/edge-learning-job.ts +160 -0
  524. package/src/memory/v3/edges.ts +286 -0
  525. package/src/memory/v3/filter.ts +286 -0
  526. package/src/memory/v3/gate.ts +349 -0
  527. package/src/memory/v3/index-composition.ts +126 -0
  528. package/src/memory/v3/llm-capture.ts +46 -0
  529. package/src/memory/v3/loop.ts +430 -0
  530. package/src/memory/v3/maintenance.ts +144 -0
  531. package/src/memory/v3/prompt-context.ts +33 -0
  532. package/src/memory/v3/prompts/consolidation.ts +458 -0
  533. package/src/memory/v3/prompts/system-prompts.ts +196 -0
  534. package/src/memory/v3/retriever.ts +33 -0
  535. package/src/memory/v3/scouts.ts +431 -0
  536. package/src/memory/v3/shadow-diff.ts +287 -0
  537. package/src/memory/v3/shadow-middleware.ts +347 -0
  538. package/src/memory/v3/traversal.ts +211 -0
  539. package/src/memory/v3/tree-index.ts +237 -0
  540. package/src/memory/v3/tree-store.ts +394 -0
  541. package/src/memory/v3/tree-walk.ts +356 -0
  542. package/src/memory/v3/types.ts +65 -0
  543. package/src/memory/v3/validate.ts +323 -0
  544. package/src/notifications/__tests__/emit-signal-home-feed.test.ts +1 -0
  545. package/src/notifications/__tests__/home-feed-side-effect.test.ts +1 -0
  546. package/src/notifications/adapters/macos.ts +18 -1
  547. package/src/notifications/adapters/platform.ts +1 -1
  548. package/src/notifications/adapters/slack.ts +45 -11
  549. package/src/notifications/broadcaster.ts +114 -63
  550. package/src/notifications/conversation-pairing.ts +23 -3
  551. package/src/notifications/decision-engine.ts +1 -4
  552. package/src/notifications/decisions-store.ts +32 -1
  553. package/src/notifications/deliveries-store.ts +45 -0
  554. package/src/notifications/edit-notification.ts +201 -0
  555. package/src/notifications/emit-signal.ts +40 -50
  556. package/src/notifications/signal.ts +10 -0
  557. package/src/notifications/types.ts +37 -0
  558. package/src/oauth/byo-connection.test.ts +67 -3
  559. package/src/oauth/byo-connection.ts +32 -5
  560. package/src/oauth/connect-orchestrator.ts +9 -0
  561. package/src/oauth/connection-resolver.test.ts +76 -0
  562. package/src/oauth/connection-resolver.ts +49 -10
  563. package/src/oauth/manual-token-connection.ts +51 -3
  564. package/src/oauth/seed-providers.ts +3 -0
  565. package/src/permissions/approval-policy.test.ts +19 -5
  566. package/src/permissions/approval-policy.ts +14 -3
  567. package/src/permissions/checker.ts +21 -8
  568. package/src/permissions/prompter.ts +3 -3
  569. package/src/permissions/question-prompter.ts +5 -2
  570. package/src/permissions/secret-prompter.ts +2 -2
  571. package/src/platform/client.test.ts +24 -1
  572. package/src/platform/client.ts +8 -0
  573. package/src/platform/feature-gate.ts +15 -0
  574. package/src/plugin-api/index.ts +4 -0
  575. package/src/plugin-api/types.ts +7 -33
  576. package/src/plugins/defaults/index.ts +6 -0
  577. package/src/plugins/defaults/injectors.ts +20 -19
  578. package/src/plugins/defaults/persistence.ts +25 -6
  579. package/src/plugins/external-plugin-loader.ts +5 -68
  580. package/src/plugins/types.ts +68 -29
  581. package/src/proactive-artifact/aux-message-injector.ts +17 -4
  582. package/src/proactive-artifact/job.test.ts +1 -0
  583. package/src/prompts/__tests__/system-prompt.test.ts +4 -4
  584. package/src/prompts/__tests__/task-progress-hint-section.test.ts +3 -9
  585. package/src/prompts/persona-resolver.ts +36 -21
  586. package/src/prompts/sections.ts +39 -7
  587. package/src/prompts/system-prompt.ts +84 -221
  588. package/src/prompts/template-detection.ts +10 -4
  589. package/src/prompts/templates/BOOTSTRAP.md +9 -13
  590. package/src/prompts/templates/IDENTITY.md +0 -2
  591. package/src/prompts/templates/system-sections.ts +230 -8
  592. package/src/providers/__tests__/connection-model-compat.test.ts +233 -0
  593. package/src/providers/__tests__/registry-native-web-search.test.ts +122 -0
  594. package/src/providers/__tests__/retry-callsite.test.ts +85 -5
  595. package/src/providers/anthropic/client.ts +32 -66
  596. package/src/providers/call-site-routing.ts +42 -6
  597. package/src/providers/connection-model-compat.ts +61 -0
  598. package/src/providers/connection-resolution.ts +47 -14
  599. package/src/providers/fireworks/client.ts +1 -0
  600. package/src/providers/gemini/client.ts +70 -6
  601. package/src/providers/inference/__tests__/adapter-factory-openai-compatible.test.ts +0 -2
  602. package/src/providers/inference/__tests__/base-url-security.test.ts +2 -3
  603. package/src/providers/inference/__tests__/{connections-status-label.test.ts → connections-label.test.ts} +12 -111
  604. package/src/providers/inference/adapter-factory.ts +3 -0
  605. package/src/providers/inference/auth.ts +0 -8
  606. package/src/providers/inference/connections.ts +3 -66
  607. package/src/providers/inference/resolve-auth.ts +2 -3
  608. package/src/providers/minimax/client.ts +106 -0
  609. package/src/providers/model-catalog.ts +78 -1
  610. package/src/providers/model-intents.ts +4 -4
  611. package/src/providers/openai/__tests__/api-error-detail.test.ts +120 -0
  612. package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +157 -5
  613. package/src/providers/openai/chat-completions-provider.ts +116 -15
  614. package/src/providers/openai/codex-models.ts +20 -0
  615. package/src/providers/openai/responses-provider.ts +87 -30
  616. package/src/providers/openrouter/client.ts +13 -8
  617. package/src/providers/provider-send-message.ts +20 -5
  618. package/src/providers/registry.ts +48 -8
  619. package/src/providers/retry.ts +50 -7
  620. package/src/providers/search-provider-catalog.ts +17 -9
  621. package/src/providers/thinking-config.ts +26 -1
  622. package/src/providers/types.ts +9 -0
  623. package/src/providers/usage-tracking.ts +2 -0
  624. package/src/runtime/AGENTS.md +2 -2
  625. package/src/runtime/__tests__/agent-wake.test.ts +1 -0
  626. package/src/runtime/__tests__/background-job-runner.test.ts +1 -0
  627. package/src/runtime/access-request-helper.ts +1 -0
  628. package/src/runtime/agent-wake.ts +1 -0
  629. package/src/runtime/assistant-event-hub.ts +76 -6
  630. package/src/runtime/auth/route-policy.ts +46 -0
  631. package/src/runtime/btw-sidechain.ts +0 -6
  632. package/src/runtime/channel-readiness-service.ts +68 -0
  633. package/src/runtime/channel-reply-delivery.ts +23 -0
  634. package/src/runtime/channel-retry-sweep.ts +47 -14
  635. package/src/runtime/confirmation-request-guardian-bridge.ts +1 -1
  636. package/src/runtime/http-types.ts +0 -2
  637. package/src/runtime/migrations/vbundle-builder.ts +12 -4
  638. package/src/runtime/pending-interactions.ts +0 -1
  639. package/src/runtime/routes/__tests__/bookmark-routes.test.ts +1 -0
  640. package/src/runtime/routes/__tests__/conversation-compaction-routes.test.ts +406 -0
  641. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +204 -0
  642. package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +1 -1
  643. package/src/runtime/routes/__tests__/home-feed-routes.test.ts +209 -1
  644. package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +13 -50
  645. package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +76 -9
  646. package/src/runtime/routes/__tests__/memory-v3-simulate-params.test.ts +35 -0
  647. package/src/runtime/routes/__tests__/plugins-routes.test.ts +512 -0
  648. package/src/runtime/routes/__tests__/slack-channel-routes.test.ts +3 -2
  649. package/src/runtime/routes/__tests__/surface-content-routes.test.ts +294 -0
  650. package/src/runtime/routes/__tests__/task-routes.test.ts +48 -3
  651. package/src/runtime/routes/acp-routes-list.test.ts +3 -0
  652. package/src/runtime/routes/acp-routes.test.ts +255 -6
  653. package/src/runtime/routes/acp-routes.ts +8 -1
  654. package/src/runtime/routes/app-management-routes.ts +111 -4
  655. package/src/runtime/routes/avatar-routes.ts +10 -10
  656. package/src/runtime/routes/background-wake-routes.ts +356 -0
  657. package/src/runtime/routes/browser-tabs-routes.ts +200 -0
  658. package/src/runtime/routes/btw-routes.ts +4 -10
  659. package/src/runtime/routes/conversation-analysis-routes.ts +6 -0
  660. package/src/runtime/routes/conversation-cli-routes.ts +1 -1
  661. package/src/runtime/routes/conversation-compaction-routes.ts +263 -0
  662. package/src/runtime/routes/conversation-list-routes.ts +159 -4
  663. package/src/runtime/routes/conversation-management-routes.ts +108 -26
  664. package/src/runtime/routes/conversation-query-routes.ts +200 -44
  665. package/src/runtime/routes/conversation-routes.ts +409 -521
  666. package/src/runtime/routes/conversation-starter-routes.ts +6 -3
  667. package/src/runtime/routes/conversations-import-routes.ts +19 -6
  668. package/src/runtime/routes/disk-pressure-routes.ts +1 -1
  669. package/src/runtime/routes/documents-routes.ts +10 -1
  670. package/src/runtime/routes/domain-routes.ts +60 -10
  671. package/src/runtime/routes/email-routes.ts +5 -2
  672. package/src/runtime/routes/events-routes.ts +54 -10
  673. package/src/runtime/routes/group-routes.ts +35 -8
  674. package/src/runtime/routes/home-feed-routes.ts +129 -0
  675. package/src/runtime/routes/host-browser-routes.ts +10 -2
  676. package/src/runtime/routes/host-cu-routes.ts +2 -2
  677. package/src/runtime/routes/identity-intro-cache.ts +61 -16
  678. package/src/runtime/routes/identity-routes.ts +30 -9
  679. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +96 -3
  680. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +530 -6
  681. package/src/runtime/routes/inbound-stages/background-dispatch.ts +57 -8
  682. package/src/runtime/routes/index.ts +10 -0
  683. package/src/runtime/routes/inference-profile-session-handler.ts +22 -12
  684. package/src/runtime/routes/inference-profile-session-routes.ts +7 -1
  685. package/src/runtime/routes/inference-provider-connection-routes.ts +5 -26
  686. package/src/runtime/routes/integrations/vercel.ts +15 -0
  687. package/src/runtime/routes/llm-call-sites-routes.ts +32 -5
  688. package/src/runtime/routes/llm-context-normalization.ts +7 -2
  689. package/src/runtime/routes/memory-item-routes.ts +8 -3
  690. package/src/runtime/routes/memory-v2-routes.ts +215 -5
  691. package/src/runtime/routes/memory-v3-routes.ts +474 -0
  692. package/src/runtime/routes/migration-routes.ts +32 -28
  693. package/src/runtime/routes/notification-routes.ts +63 -1
  694. package/src/runtime/routes/oauth-commands-routes.ts +6 -1
  695. package/src/runtime/routes/plugins-routes.ts +337 -0
  696. package/src/runtime/routes/rename-conversation-routes.ts +6 -2
  697. package/src/runtime/routes/secret-routes.ts +25 -5
  698. package/src/runtime/routes/settings-routes.ts +12 -11
  699. package/src/runtime/routes/slack-channel-routes.ts +5 -4
  700. package/src/runtime/routes/surface-action-routes.ts +1 -38
  701. package/src/runtime/routes/surface-content-routes.ts +12 -5
  702. package/src/runtime/routes/surface-conversation-resolver.ts +65 -0
  703. package/src/runtime/routes/wipe-conversation-routes.ts +3 -0
  704. package/src/runtime/routes/workspace-routes.ts +25 -10
  705. package/src/runtime/services/__tests__/analyze-conversation.test.ts +2 -0
  706. package/src/runtime/slack-dm-text-delivery.ts +177 -0
  707. package/src/runtime/sync/resource-sync-events.ts +106 -38
  708. package/src/runtime/sync/sync-publisher.test.ts +49 -0
  709. package/src/runtime/sync/sync-publisher.ts +2 -1
  710. package/src/runtime/tool-grant-request-helper.ts +1 -0
  711. package/src/runtime/verification-outbound-actions.ts +73 -1
  712. package/src/schedule/schedule-store.ts +8 -1
  713. package/src/schedule/scheduler.ts +111 -15
  714. package/src/security/__tests__/provider-key-env-fallback.test.ts +3 -3
  715. package/src/security/encrypted-store.ts +7 -16
  716. package/src/security/store-path-override.ts +61 -0
  717. package/src/signals/user-message.ts +5 -8
  718. package/src/skills/validate-input.ts +177 -0
  719. package/src/subagent/manager.ts +13 -13
  720. package/src/subagent/types.ts +6 -0
  721. package/src/tasks/tool-sanitizer.ts +2 -2
  722. package/src/telemetry/types.ts +12 -0
  723. package/src/telemetry/usage-telemetry-reporter.test.ts +48 -0
  724. package/src/telemetry/usage-telemetry-reporter.ts +1 -0
  725. package/src/tools/acp/spawn.test.ts +119 -0
  726. package/src/tools/acp/spawn.ts +15 -2
  727. package/src/tools/apps/definitions.ts +36 -28
  728. package/src/tools/ask-question/ask-question-tool.test.ts +3 -3
  729. package/src/tools/ask-question/ask-question-tool.ts +38 -45
  730. package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +2 -8
  731. package/src/tools/browser/__tests__/pinned-tabs.test.ts +70 -0
  732. package/src/tools/browser/browser-execution.ts +16 -3
  733. package/src/tools/browser/cdp-client/__tests__/browser-tabs-factory.test.ts +402 -0
  734. package/src/tools/browser/cdp-client/__tests__/types.test.ts +3 -0
  735. package/src/tools/browser/cdp-client/cdp-inspect-client.ts +12 -0
  736. package/src/tools/browser/cdp-client/extension-cdp-client.ts +27 -1
  737. package/src/tools/browser/cdp-client/factory.ts +100 -17
  738. package/src/tools/browser/cdp-client/local-cdp-client.ts +12 -0
  739. package/src/tools/browser/cdp-client/types.ts +65 -0
  740. package/src/tools/browser/pinned-tabs.ts +96 -40
  741. package/src/tools/computer-use/definitions.ts +282 -336
  742. package/src/tools/credential-execution/make-authenticated-request.ts +3 -9
  743. package/src/tools/credential-execution/manage-secure-command-tool.ts +3 -9
  744. package/src/tools/credential-execution/run-authenticated-command.ts +3 -9
  745. package/src/tools/credentials/vault.ts +3 -9
  746. package/src/tools/document/document-tool.ts +189 -7
  747. package/src/tools/execution-target.ts +18 -23
  748. package/src/tools/executor.ts +24 -56
  749. package/src/tools/filesystem/edit.ts +3 -9
  750. package/src/tools/filesystem/list.ts +3 -9
  751. package/src/tools/filesystem/read.ts +3 -9
  752. package/src/tools/filesystem/write.ts +3 -9
  753. package/src/tools/host-filesystem/edit.test.ts +1 -0
  754. package/src/tools/host-filesystem/edit.ts +3 -9
  755. package/src/tools/host-filesystem/read.test.ts +1 -0
  756. package/src/tools/host-filesystem/read.ts +3 -9
  757. package/src/tools/host-filesystem/transfer.test.ts +31 -6
  758. package/src/tools/host-filesystem/transfer.ts +3 -9
  759. package/src/tools/host-filesystem/write.test.ts +1 -0
  760. package/src/tools/host-filesystem/write.ts +3 -9
  761. package/src/tools/host-terminal/host-shell.ts +3 -9
  762. package/src/tools/mcp/mcp-tool-factory.ts +1 -10
  763. package/src/tools/memory/register.test.ts +1 -1
  764. package/src/tools/memory/register.ts +4 -9
  765. package/src/tools/network/__tests__/managed-search-proxy.test.ts +282 -0
  766. package/src/tools/network/__tests__/web-search.test.ts +211 -3
  767. package/src/tools/network/managed-search-proxy.ts +183 -0
  768. package/src/tools/network/web-fetch.ts +3 -9
  769. package/src/tools/network/web-search.ts +224 -76
  770. package/src/tools/policy-context.ts +3 -1
  771. package/src/tools/registry.ts +150 -123
  772. package/src/tools/schedule/create.ts +1 -1
  773. package/src/tools/schema-transforms.ts +1 -1
  774. package/src/tools/skills/execute.ts +3 -9
  775. package/src/tools/skills/load.ts +3 -9
  776. package/src/tools/skills/skill-tool-factory.ts +18 -44
  777. package/src/tools/subagent/notify-parent.ts +3 -9
  778. package/src/tools/subagent/spawn.ts +3 -0
  779. package/src/tools/system/request-permission.ts +3 -9
  780. package/src/tools/terminal/shell.ts +3 -9
  781. package/src/tools/tool-approval-handler.ts +10 -4
  782. package/src/tools/tool-defaults.ts +94 -0
  783. package/src/tools/tool-name-aliases.ts +72 -14
  784. package/src/tools/types.ts +32 -101
  785. package/src/tools/ui-surface/definitions.ts +104 -108
  786. package/src/types/onboarding-context.ts +6 -0
  787. package/src/usage/attribution.ts +32 -1
  788. package/src/usage/pricing.ts +23 -0
  789. package/src/usage/types.ts +12 -0
  790. package/src/util/browser.ts +7 -2
  791. package/src/util/logger.ts +16 -7
  792. package/src/util/platform.ts +7 -2
  793. package/src/util/sqlite3-runtime.ts +65 -0
  794. package/src/workspace/migrations/086-revert-stale-gemini-mis-rewrites.ts +1 -0
  795. package/src/workspace/migrations/089-move-memory-tree-out-of-v3.ts +86 -0
  796. package/src/workspace/migrations/090-memory-router-cost-optimized-profile.ts +109 -0
  797. package/src/workspace/migrations/091-retighten-migration-onboarding-thread.ts +41 -0
  798. package/src/workspace/migrations/registry.ts +6 -0
  799. package/src/__tests__/compaction-strip-metadata-clear.test.ts +0 -206
  800. package/src/__tests__/message-complete-display-id.test.ts +0 -175
  801. package/src/daemon/query-complexity-router.ts +0 -75
  802. package/src/prompts/cache-boundary.ts +0 -8
@@ -2,7 +2,6 @@ import type { ToolDefinition } from "../providers/types.js";
2
2
  import { getLogger } from "../util/logger.js";
3
3
  import { coreAppProxyTools } from "./apps/definitions.js";
4
4
  import { registerAppTools } from "./apps/registry.js";
5
- import { allComputerUseTools } from "./computer-use/definitions.js";
6
5
  import { hostFileEditTool } from "./host-filesystem/edit.js";
7
6
  import { hostFileReadTool } from "./host-filesystem/read.js";
8
7
  import { hostFileTransferTool } from "./host-filesystem/transfer.js";
@@ -10,7 +9,7 @@ import { hostFileWriteTool } from "./host-filesystem/write.js";
10
9
  import { hostShellTool } from "./host-terminal/host-shell.js";
11
10
  import { toProviderSafeToolName } from "./provider-tool-name.js";
12
11
  import { registerSystemTools } from "./system/register.js";
13
- import type { LoadedPluginTool, Tool } from "./types.js";
12
+ import type { LoadedTool, OwnerInfo, Tool } from "./types.js";
14
13
  import { allUiSurfaceTools } from "./ui-surface/definitions.js";
15
14
  import { registerUiSurfaceTools } from "./ui-surface/registry.js";
16
15
 
@@ -18,6 +17,15 @@ const log = getLogger("tool-registry");
18
17
 
19
18
  const tools = new Map<string, Tool>();
20
19
 
20
+ // Authoritative map of tool ownership, keyed by tool name. Populated by the
21
+ // `register*` functions and read by `getToolOwner()`. Lives on the registry
22
+ // (not on the `Tool` object) so callers cannot spoof ownership by writing a
23
+ // field on the manifest — the only way to claim a tool is to go through a
24
+ // `register*` function, which stamps the owner from its arguments. Core
25
+ // tools intentionally have no entry here; `getToolOwner` returns `undefined`
26
+ // for them.
27
+ const ownersByName = new Map<string, OwnerInfo>();
28
+
21
29
  // ── External tool registry ───────────────────────────────────────────
22
30
  // Skills register their tools here at initialization time so the tool
23
31
  // manifest can include them without importing from `../skills/`.
@@ -28,7 +36,10 @@ const tools = new Map<string, Tool>();
28
36
  // feature-flag check until after the daemon has run
29
37
  // `mergeDefaultWorkspaceConfig()`, so skills see the merged config
30
38
  // instead of forcing an early `loadConfig()` against unmerged defaults.
31
- const externalToolProviders: Array<() => Tool[]> = [];
39
+ const externalToolProviders: Array<{
40
+ owner: OwnerInfo;
41
+ provider: () => Tool[];
42
+ }> = [];
32
43
 
33
44
  /**
34
45
  * Register tools provided by an external skill. Called during skill
@@ -44,20 +55,30 @@ const externalToolProviders: Array<() => Tool[]> = [];
44
55
  * dependency: skills/load.ts → … → meet-join/register.ts → tool-manifest.ts
45
56
  * → skills/load.ts. Keeping it here lets external skill bootstraps import
46
57
  * from registry.ts, which is already a leaf in the dependency graph.
58
+ *
59
+ * `owner` records which extension produced these tools — typed
60
+ * {@link OwnerInfo} so ownership flows through `ownersByName` at
61
+ * `initializeTools()` time, the same way `register*` registers it for
62
+ * IPC-loaded tools. Eager (boot-time) skill bootstraps go through this
63
+ * path rather than `registerSkillTools`, so this is where their owner
64
+ * lookup gets established.
47
65
  */
48
66
  export function registerExternalTools(
67
+ owner: OwnerInfo,
49
68
  toolsOrProvider: Tool[] | (() => Tool[]),
50
69
  ): void {
51
70
  const provider =
52
71
  typeof toolsOrProvider === "function"
53
72
  ? toolsOrProvider
54
73
  : () => toolsOrProvider;
55
- externalToolProviders.push(provider);
74
+ externalToolProviders.push({ owner, provider });
56
75
  }
57
76
 
58
- /** Return all externally registered tools. */
59
- function getExternalTools(): Tool[] {
60
- return externalToolProviders.flatMap((provider) => provider());
77
+ /** Return all externally registered tools paired with their owners. */
78
+ function getExternalTools(): Array<{ owner: OwnerInfo; tool: Tool }> {
79
+ return externalToolProviders.flatMap(({ owner, provider }) =>
80
+ provider().map((tool) => ({ owner, tool })),
81
+ );
61
82
  }
62
83
 
63
84
  // Snapshot of core tools captured after initializeTools() completes.
@@ -76,6 +97,27 @@ const skillRefCount = new Map<string, number>();
76
97
  // separate and covers the case of two extensions choosing the same tool name.
77
98
  const pluginRefCount = new Map<string, number>();
78
99
 
100
+ /**
101
+ * Format an owner for log messages and error strings. Returns a stable
102
+ * human-readable description (e.g. `skill "deploy"`, `plugin "weather"`,
103
+ * `MCP server "github"`). When an owner is missing (core tool) or has an
104
+ * unrecognized kind, returns a fallback string so log/error sites never
105
+ * produce `undefined` interpolations.
106
+ */
107
+ function describeOwner(owner: OwnerInfo | undefined): string {
108
+ if (!owner) return "core tool";
109
+ switch (owner.kind) {
110
+ case "skill":
111
+ return `skill "${owner.id}"`;
112
+ case "plugin":
113
+ return `plugin "${owner.id}"`;
114
+ case "mcp":
115
+ return `MCP server "${owner.id}"`;
116
+ default:
117
+ return `${(owner as OwnerInfo).kind}-origin tool`;
118
+ }
119
+ }
120
+
79
121
  function withProviderSafeToolName(tool: Tool): Tool {
80
122
  const safeName = toProviderSafeToolName(tool.name);
81
123
  if (safeName === tool.name) {
@@ -85,12 +127,6 @@ function withProviderSafeToolName(tool: Tool): Tool {
85
127
  return {
86
128
  ...tool,
87
129
  name: safeName,
88
- getDefinition(): ToolDefinition {
89
- return {
90
- ...tool.getDefinition(),
91
- name: safeName,
92
- };
93
- },
94
130
  };
95
131
  }
96
132
 
@@ -113,106 +149,98 @@ export function getAllTools(): Tool[] {
113
149
  }
114
150
 
115
151
  /**
116
- * Register multiple skill-origin tools at once.
152
+ * Return the recorded owner for a tool, or `undefined` if the tool is
153
+ * core-origin (no owner) or unknown. Consumers that need to gate behavior on
154
+ * which extension contributed a tool (permissions checker, approval-handler
155
+ * load hints, conversation-skill-tools projection) call this rather than
156
+ * reading owner off the `Tool` object — the registry is the single source of
157
+ * truth for ownership.
158
+ */
159
+ export function getToolOwner(name: string): OwnerInfo | undefined {
160
+ return ownersByName.get(name);
161
+ }
162
+
163
+ /**
164
+ * Register multiple skill-origin tools owned by `skillId`.
165
+ *
117
166
  * Skips any tool whose name collides with a core tool (logs a warning instead
118
167
  * of throwing so the remaining tools in the batch still get registered).
119
168
  * Throws if a tool name collides with a skill tool owned by a different skill.
120
- * Allows replacement when the incoming tool has the same ownerSkillId as the existing one,
121
- * which supports hot-reloading a skill without tearing down first.
169
+ * Allows replacement when the incoming tool has the same skill owner id as
170
+ * the existing one, which supports hot-reloading a skill without tearing
171
+ * down first.
172
+ *
173
+ * Ownership is recorded in {@link ownersByName} keyed by tool name; the
174
+ * `Tool` object itself carries no owner metadata, so callers cannot spoof
175
+ * ownership by writing fields on the manifest.
122
176
  */
123
- export function registerSkillTools(newTools: Tool[]): Tool[] {
177
+ export function registerSkillTools(skillId: string, newTools: Tool[]): Tool[] {
124
178
  // Filter out tools that collide with core tools, and validate the rest.
125
179
  const accepted: Tool[] = [];
126
180
  for (const tool of newTools) {
127
181
  const existing = tools.get(tool.name);
128
182
  if (existing) {
129
- const existingIsCore = existing.origin === "core" || !existing.origin;
183
+ const existingIsCore = !ownersByName.has(tool.name);
130
184
  if (existingIsCore) {
131
185
  log.warn(
132
- { toolName: tool.name, skillId: tool.ownerSkillId },
133
- `Skill "${tool.ownerSkillId}" tried to register tool "${tool.name}" which conflicts with a core tool. Skipping.`,
186
+ { toolName: tool.name, ownerSkillId: skillId },
187
+ `Skill "${skillId}" tried to register tool "${tool.name}" which conflicts with a core tool. Skipping.`,
134
188
  );
135
189
  continue;
136
190
  }
137
- // Existing is from a different origin (plugin/mcp) or a different
191
+ // Existing is from a different owner (plugin/mcp) or a different
138
192
  // skill — skill tools can only replace themselves (hot-reload).
139
- if (
140
- existing.origin !== "skill" ||
141
- existing.ownerSkillId !== tool.ownerSkillId
142
- ) {
143
- const owner =
144
- existing.origin === "skill"
145
- ? `skill "${existing.ownerSkillId}"`
146
- : existing.origin === "plugin"
147
- ? `plugin "${existing.ownerPluginId}"`
148
- : existing.origin === "mcp"
149
- ? `MCP server "${existing.ownerMcpServerId}"`
150
- : `${existing.origin ?? "unknown"}-origin tool`;
193
+ const existingOwner = ownersByName.get(tool.name);
194
+ const existingSkillId =
195
+ existingOwner?.kind === "skill" ? existingOwner.id : undefined;
196
+ if (existingOwner?.kind !== "skill" || existingSkillId !== skillId) {
151
197
  throw new Error(
152
- `Skill tool "${tool.name}" is already registered by ${owner}`,
198
+ `Skill tool "${tool.name}" is already registered by ${describeOwner(existingOwner)}`,
153
199
  );
154
200
  }
155
201
  }
156
202
  accepted.push(tool);
157
203
  }
158
204
 
159
- // Collect unique skill IDs from the batch to bump ref counts
160
- const skillIds = new Set<string>();
161
205
  for (const tool of accepted) {
162
206
  tools.set(tool.name, tool);
163
- if (tool.ownerSkillId) skillIds.add(tool.ownerSkillId);
207
+ ownersByName.set(tool.name, { kind: "skill", id: skillId });
164
208
  log.info(
165
- { name: tool.name, ownerSkillId: tool.ownerSkillId },
209
+ { name: tool.name, ownerSkillId: skillId },
166
210
  "Skill tool registered",
167
211
  );
168
212
  }
169
213
 
170
- for (const id of skillIds) {
171
- skillRefCount.set(id, (skillRefCount.get(id) ?? 0) + 1);
214
+ if (accepted.length > 0) {
215
+ skillRefCount.set(skillId, (skillRefCount.get(skillId) ?? 0) + 1);
172
216
  }
173
217
 
174
218
  return accepted;
175
219
  }
176
220
 
177
221
  /**
178
- * Register tools contributed by a plugin. Stamps `origin: "plugin"` and
179
- * `ownerPluginId: pluginName` on every incoming tool so plugin ownership is
180
- * tracked in a namespace disjoint from skill tools if a plugin's
181
- * `manifest.name` happens to match a skill id, the two do not share refcount
182
- * state or conflict-detection paths.
222
+ * Register tools contributed by the plugin named `pluginName`. Records the
223
+ * plugin owner in {@link ownersByName} keyed by tool name ownership lives
224
+ * on the registry, never on the `Tool` object itself, so the bootstrap
225
+ * cannot be spoofed into claiming tools on behalf of an unrelated extension
226
+ * by forging fields on the manifest. Plugin ownership is tracked in a
227
+ * namespace disjoint from skill tools: if a plugin's `manifest.name`
228
+ * happens to match a skill id, the two do not share refcount state or
229
+ * conflict-detection paths.
183
230
  *
184
231
  * Conflict handling mirrors {@link registerSkillTools}: collisions with core
185
232
  * tools log a warning and skip; collisions with tools owned by a different
186
233
  * plugin, skill, or MCP server throw; re-registering the same plugin's own
187
234
  * tool (hot reload) is allowed.
188
- *
189
- * The stamp is authoritative: any pre-existing `origin` / `ownerPluginId` /
190
- * `ownerSkillId` / `ownerMcpServerId` fields on the incoming tools are
191
- * overwritten so the bootstrap cannot be spoofed into claiming tools on
192
- * behalf of an unrelated extension.
193
235
  */
194
236
  export function registerPluginTools(
195
237
  pluginName: string,
196
- newTools: LoadedPluginTool[],
238
+ newTools: LoadedTool[],
197
239
  ): Tool[] {
198
240
  const stamped: Tool[] = newTools.map((pluginTool) => {
199
- const { input_schema, ...rest } = pluginTool;
200
241
  const tool: Tool = {
201
- ...rest,
242
+ ...pluginTool,
202
243
  category: "plugin",
203
- origin: "plugin" as const,
204
- ownerPluginId: pluginName,
205
- ownerSkillId: undefined,
206
- ownerMcpServerId: undefined,
207
- ownerSkillBundled: undefined,
208
- ownerSkillVersionHash: undefined,
209
- getDefinition(): ToolDefinition {
210
- return {
211
- name: pluginTool.name,
212
- description: pluginTool.description,
213
- input_schema,
214
- };
215
- },
216
244
  };
217
245
  return withProviderSafeToolName(tool);
218
246
  });
@@ -221,25 +249,26 @@ export function registerPluginTools(
221
249
  for (const tool of stamped) {
222
250
  const existing = tools.get(tool.name);
223
251
  if (existing) {
224
- const existingIsCore = existing.origin === "core" || !existing.origin;
252
+ const existingIsCore = !ownersByName.has(tool.name);
225
253
  if (existingIsCore) {
226
254
  log.warn(
227
- { toolName: tool.name, pluginName },
255
+ { toolName: tool.name, ownerPluginId: pluginName },
228
256
  `Plugin "${pluginName}" tried to register tool "${tool.name}" which conflicts with a core tool. Skipping.`,
229
257
  );
230
258
  continue;
231
259
  }
232
- if (existing.origin === "plugin") {
233
- if (existing.ownerPluginId !== pluginName) {
260
+ const existingOwner = ownersByName.get(tool.name);
261
+ if (existingOwner?.kind === "plugin") {
262
+ if (existingOwner.id !== pluginName) {
234
263
  throw new Error(
235
- `Plugin tool "${tool.name}" is already registered by plugin "${existing.ownerPluginId}"`,
264
+ `Plugin tool "${tool.name}" is already registered by plugin "${existingOwner.id}"`,
236
265
  );
237
266
  }
238
267
  // Same plugin re-registering its own tool (hot reload) — allow.
239
268
  } else {
240
269
  // Conflict with a skill or MCP-owned tool.
241
270
  throw new Error(
242
- `Plugin "${pluginName}" tried to register tool "${tool.name}" which conflicts with a ${existing.origin}-origin tool`,
271
+ `Plugin "${pluginName}" tried to register tool "${tool.name}" which conflicts with ${describeOwner(existingOwner)}`,
243
272
  );
244
273
  }
245
274
  }
@@ -248,8 +277,9 @@ export function registerPluginTools(
248
277
 
249
278
  for (const tool of accepted) {
250
279
  tools.set(tool.name, tool);
280
+ ownersByName.set(tool.name, { kind: "plugin", id: pluginName });
251
281
  log.info(
252
- { name: tool.name, ownerPluginId: tool.ownerPluginId },
282
+ { name: tool.name, ownerPluginId: pluginName },
253
283
  "Plugin tool registered",
254
284
  );
255
285
  }
@@ -278,10 +308,11 @@ export function unregisterPluginTools(pluginName: string): void {
278
308
  }
279
309
 
280
310
  pluginRefCount.delete(pluginName);
281
- for (const [name, tool] of tools) {
282
- if (tool.origin === "plugin" && tool.ownerPluginId === pluginName) {
311
+ for (const [name, owner] of ownersByName) {
312
+ if (owner.kind === "plugin" && owner.id === pluginName) {
283
313
  tools.delete(name);
284
- log.info({ name, pluginName }, "Plugin tool unregistered");
314
+ ownersByName.delete(name);
315
+ log.info({ name, ownerPluginId: pluginName }, "Plugin tool unregistered");
285
316
  }
286
317
  }
287
318
  }
@@ -310,60 +341,52 @@ export function unregisterSkillTools(skillId: string): void {
310
341
 
311
342
  // Last reference - actually remove the tools
312
343
  skillRefCount.delete(skillId);
313
- for (const [name, tool] of tools) {
314
- if (tool.origin === "skill" && tool.ownerSkillId === skillId) {
344
+ for (const [name, owner] of ownersByName) {
345
+ if (owner.kind === "skill" && owner.id === skillId) {
315
346
  tools.delete(name);
316
- log.info({ name, skillId }, "Skill tool unregistered");
347
+ ownersByName.delete(name);
348
+ log.info({ name, ownerSkillId: skillId }, "Skill tool unregistered");
317
349
  }
318
350
  }
319
351
  }
320
352
 
321
353
  /**
322
- * Register multiple MCP-origin tools at once.
354
+ * Register multiple MCP-origin tools owned by the MCP server `serverId`.
355
+ *
323
356
  * Skips any tool whose name collides with a core tool (logs a warning).
324
357
  * Throws if a tool name collides with a tool owned by a different MCP server.
358
+ *
359
+ * Ownership is recorded in {@link ownersByName} keyed by tool name; the
360
+ * `Tool` object itself carries no owner metadata.
325
361
  */
326
- export function registerMcpTools(newTools: Tool[]): Tool[] {
362
+ export function registerMcpTools(serverId: string, newTools: Tool[]): Tool[] {
327
363
  const accepted: Tool[] = [];
328
364
  for (const tool of newTools) {
329
365
  const existing = tools.get(tool.name);
330
366
  if (existing) {
331
- const existingIsCore = existing.origin === "core" || !existing.origin;
367
+ const existingIsCore = !ownersByName.has(tool.name);
332
368
  if (existingIsCore) {
333
369
  log.warn(
334
- { toolName: tool.name, serverId: tool.ownerMcpServerId },
335
- `MCP server "${tool.ownerMcpServerId}" tried to register tool "${tool.name}" which conflicts with a core tool. Skipping.`,
336
- );
337
- continue;
338
- }
339
- if (existing.origin === "skill") {
340
- log.warn(
341
- {
342
- toolName: tool.name,
343
- serverId: tool.ownerMcpServerId,
344
- skillId: existing.ownerSkillId,
345
- },
346
- `MCP server "${tool.ownerMcpServerId}" tried to register tool "${tool.name}" which conflicts with skill tool from "${existing.ownerSkillId}". Skipping.`,
370
+ { toolName: tool.name, ownerMcpServerId: serverId },
371
+ `MCP server "${serverId}" tried to register tool "${tool.name}" which conflicts with a core tool. Skipping.`,
347
372
  );
348
373
  continue;
349
374
  }
350
- if (existing.origin === "plugin") {
375
+ const existingOwner = ownersByName.get(tool.name);
376
+ if (existingOwner?.kind === "skill" || existingOwner?.kind === "plugin") {
351
377
  log.warn(
352
378
  {
353
379
  toolName: tool.name,
354
- serverId: tool.ownerMcpServerId,
355
- pluginName: existing.ownerPluginId,
380
+ ownerMcpServerId: serverId,
381
+ existingOwner,
356
382
  },
357
- `MCP server "${tool.ownerMcpServerId}" tried to register tool "${tool.name}" which conflicts with plugin tool from "${existing.ownerPluginId}". Skipping.`,
383
+ `MCP server "${serverId}" tried to register tool "${tool.name}" which conflicts with ${describeOwner(existingOwner)}. Skipping.`,
358
384
  );
359
385
  continue;
360
386
  }
361
- if (
362
- existing.origin === "mcp" &&
363
- existing.ownerMcpServerId !== tool.ownerMcpServerId
364
- ) {
387
+ if (existingOwner?.kind === "mcp" && existingOwner.id !== serverId) {
365
388
  throw new Error(
366
- `MCP tool "${tool.name}" is already registered by MCP server "${existing.ownerMcpServerId}"`,
389
+ `MCP tool "${tool.name}" is already registered by MCP server "${existingOwner.id}"`,
367
390
  );
368
391
  }
369
392
  }
@@ -372,8 +395,9 @@ export function registerMcpTools(newTools: Tool[]): Tool[] {
372
395
 
373
396
  for (const tool of accepted) {
374
397
  tools.set(tool.name, tool);
398
+ ownersByName.set(tool.name, { kind: "mcp", id: serverId });
375
399
  log.info(
376
- { name: tool.name, ownerMcpServerId: tool.ownerMcpServerId },
400
+ { name: tool.name, ownerMcpServerId: serverId },
377
401
  "MCP tool registered",
378
402
  );
379
403
  }
@@ -385,9 +409,10 @@ export function registerMcpTools(newTools: Tool[]): Tool[] {
385
409
  * Unregister all MCP-origin tools from the registry.
386
410
  */
387
411
  export function unregisterAllMcpTools(): void {
388
- for (const [name, tool] of tools) {
389
- if (tool.origin === "mcp") {
412
+ for (const [name, owner] of ownersByName) {
413
+ if (owner.kind === "mcp") {
390
414
  tools.delete(name);
415
+ ownersByName.delete(name);
391
416
  log.info({ name }, "MCP tool unregistered (reload)");
392
417
  }
393
418
  }
@@ -399,9 +424,9 @@ export function unregisterAllMcpTools(): void {
399
424
  * were registered after session creation (e.g. via `vellum mcp reload`).
400
425
  */
401
426
  export function getMcpToolDefinitions(): ToolDefinition[] {
402
- return Array.from(tools.values())
403
- .filter((t) => t.origin === "mcp")
404
- .map((t) => t.getDefinition());
427
+ return Array.from(tools.values()).filter(
428
+ (t) => ownersByName.get(t.name)?.kind === "mcp",
429
+ );
405
430
  }
406
431
 
407
432
  /**
@@ -409,7 +434,7 @@ export function getMcpToolDefinitions(): ToolDefinition[] {
409
434
  */
410
435
  export function getSkillToolNames(): string[] {
411
436
  return Array.from(tools.values())
412
- .filter((t) => t.origin === "skill")
437
+ .filter((t) => ownersByName.get(t.name)?.kind === "skill")
413
438
  .map((t) => t.name);
414
439
  }
415
440
 
@@ -421,16 +446,14 @@ export function getSkillRefCount(skillId: string): number {
421
446
  }
422
447
 
423
448
  export function getAllToolDefinitions(): ToolDefinition[] {
424
- // Exclude proxy tools (e.g. computer_use_* tools) - they are projected
425
- // into sessions by the skill system, not via the global tool list.
426
449
  // Exclude skill-origin tools - they are managed by the session-level
427
450
  // skill projection system (projectSkillTools) and must not leak into
428
451
  // the base tool list, which is shared across sessions via the global
429
452
  // registry. Including them here causes "Tool names must be unique"
430
453
  // errors when the projection appends the same tools a second time.
431
- return getAllTools()
432
- .filter((t) => t.executionMode !== "proxy" && t.origin !== "skill")
433
- .map((t) => t.getDefinition());
454
+ return getAllTools().filter(
455
+ (t) => ownersByName.get(t.name)?.kind !== "skill",
456
+ );
434
457
  }
435
458
 
436
459
  export async function initializeTools(): Promise<void> {
@@ -458,10 +481,13 @@ export async function initializeTools(): Promise<void> {
458
481
  // External skill tools — registered by skill bootstrap modules via
459
482
  // `registerExternalTools()`. Called at init time (not spread into
460
483
  // `explicitTools`) so registrations that happen between module-load
461
- // and `initializeTools()` are picked up.
462
- const extTools = getExternalTools();
463
- for (const tool of extTools) {
484
+ // and `initializeTools()` are picked up. Each provider pairs its tools
485
+ // with an OwnerInfo so the registry can record ownership in
486
+ // {@link ownersByName} alongside the bare `registerTool()` install.
487
+ const extEntries = getExternalTools();
488
+ for (const { owner, tool } of extEntries) {
464
489
  registerTool(tool);
490
+ ownersByName.set(tool.name, owner);
465
491
  }
466
492
 
467
493
  // Host tools are registered explicitly so host access stays opt-in until
@@ -499,18 +525,17 @@ export async function initializeTools(): Promise<void> {
499
525
  const manifestToolNames = new Set<string>([
500
526
  ...eagerModuleToolNames,
501
527
  ...explicitTools.map((t: Tool) => t.name),
502
- ...extTools.map((t: Tool) => t.name),
528
+ ...extEntries.map(({ tool }) => tool.name),
503
529
  ...hostTools.map((t: Tool) => t.name),
504
530
  ...cesTools.map((t: Tool) => t.name),
505
- ...allComputerUseTools.map((t: Tool) => t.name),
506
531
  ...allUiSurfaceTools.map((t: Tool) => t.name),
507
532
  ...coreAppProxyTools.map((t: Tool) => t.name),
508
533
  ]);
509
534
 
510
535
  coreToolsSnapshot = new Map<string, Tool>();
511
536
  for (const [name, tool] of tools) {
512
- if (tool.origin === "skill") continue;
513
- if (tool.origin === "plugin") continue;
537
+ const ownerKind = ownersByName.get(name)?.kind;
538
+ if (ownerKind === "skill" || ownerKind === "plugin") continue;
514
539
  // Exclude pre-existing tools not declared in the manifest
515
540
  if (preExisting.has(name) && !manifestToolNames.has(name)) continue;
516
541
  coreToolsSnapshot.set(name, tool);
@@ -532,6 +557,7 @@ export async function initializeTools(): Promise<void> {
532
557
  */
533
558
  export function __resetRegistryForTesting(): void {
534
559
  tools.clear();
560
+ ownersByName.clear();
535
561
  skillRefCount.clear();
536
562
  pluginRefCount.clear();
537
563
 
@@ -549,6 +575,7 @@ export function __resetRegistryForTesting(): void {
549
575
  */
550
576
  export function __clearRegistryForTesting(): void {
551
577
  tools.clear();
578
+ ownersByName.clear();
552
579
  skillRefCount.clear();
553
580
  pluginRefCount.clear();
554
581
  }
@@ -43,7 +43,7 @@ export async function executeScheduleCreate(
43
43
  | Record<string, unknown>
44
44
  | undefined;
45
45
  const quiet = (input.quiet as boolean) ?? false;
46
- const reuseConversation = (input.reuse_conversation as boolean) ?? false;
46
+ const reuseConversation = input.reuse_conversation as boolean | undefined;
47
47
  const maxRetries = input.max_retries as number | undefined;
48
48
  const retryBackoffMs = input.retry_backoff_ms as number | undefined;
49
49
 
@@ -12,7 +12,7 @@ export const ACTIVITY_SKIP_SET = new Set<string>();
12
12
  * or has a non-object schema.
13
13
  *
14
14
  * CRITICAL: Never mutates the input definitions - always returns deep clones
15
- * for any modified definition, since `getDefinition()` returns shared refs.
15
+ * for any modified definition, since `Tool.input_schema` is a shared ref.
16
16
  */
17
17
  export function injectActivityField(
18
18
  definitions: ToolDefinition[],
@@ -1,5 +1,4 @@
1
1
  import { RiskLevel } from "../../permissions/types.js";
2
- import type { ToolDefinition } from "../../providers/types.js";
3
2
  import { registerTool } from "../registry.js";
4
3
  import type { Tool, ToolContext, ToolExecutionResult } from "../types.js";
5
4
 
@@ -8,13 +7,10 @@ class SkillExecuteTool implements Tool {
8
7
  description =
9
8
  "Execute a tool provided by a loaded skill. Use this instead of calling skill tools directly. The skill's instructions (from skill_load) describe available tools and their parameters. For browser automation, use the `assistant browser` CLI commands instead.";
10
9
  category = "skills";
10
+ executionTarget = "sandbox" as const;
11
11
  defaultRiskLevel = RiskLevel.Low;
12
12
 
13
- getDefinition(): ToolDefinition {
14
- return {
15
- name: this.name,
16
- description: this.description,
17
- input_schema: {
13
+ input_schema = {
18
14
  type: "object",
19
15
  properties: {
20
16
  tool: {
@@ -34,9 +30,7 @@ class SkillExecuteTool implements Tool {
34
30
  },
35
31
  },
36
32
  required: ["tool", "input", "activity"],
37
- },
38
- };
39
- }
33
+ };
40
34
 
41
35
  async execute(
42
36
  _input: Record<string, unknown>,
@@ -11,7 +11,6 @@ import {
11
11
  loadSkillCatalog,
12
12
  } from "../../config/skills.js";
13
13
  import { RiskLevel } from "../../permissions/types.js";
14
- import type { ToolDefinition } from "../../providers/types.js";
15
14
  import {
16
15
  autoInstallFromCatalog,
17
16
  resolveCatalog,
@@ -126,13 +125,10 @@ export class SkillLoadTool implements Tool {
126
125
  description =
127
126
  "Load full instructions for a skill. Works for both bundled skills (listed in the catalog) and custom workspace skills.";
128
127
  category = "skills";
128
+ executionTarget = "sandbox" as const;
129
129
  defaultRiskLevel = RiskLevel.Low;
130
130
 
131
- getDefinition(): ToolDefinition {
132
- return {
133
- name: this.name,
134
- description: this.description,
135
- input_schema: {
131
+ input_schema = {
136
132
  type: "object",
137
133
  properties: {
138
134
  skill: {
@@ -141,9 +137,7 @@ export class SkillLoadTool implements Tool {
141
137
  },
142
138
  },
143
139
  required: ["skill"],
144
- },
145
- };
146
- }
140
+ };
147
141
 
148
142
  async execute(
149
143
  input: Record<string, unknown>,