@vellumai/assistant 0.9.0 → 0.10.0-staging.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (572) hide show
  1. package/ARCHITECTURE.md +18 -34
  2. package/bun.lock +7 -8
  3. package/docs/activation-funnel-telemetry.md +28 -22
  4. package/docs/architecture/security.md +29 -28
  5. package/docs/stt-provider-onboarding.md +3 -5
  6. package/docs/workflows-testing.md +13 -44
  7. package/docs/workflows.md +3 -5
  8. package/node_modules/@vellumai/ces-client/src/__tests__/ces-client.test.ts +47 -0
  9. package/node_modules/@vellumai/ces-client/src/rpc-client.ts +28 -5
  10. package/node_modules/@vellumai/environments/src/seeds.ts +2 -5
  11. package/node_modules/@vellumai/gateway-client/src/admission-policy-contract.ts +97 -0
  12. package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +10 -0
  13. package/node_modules/@vellumai/gateway-client/src/index.ts +32 -6
  14. package/node_modules/@vellumai/gateway-client/src/outbound-contract.ts +119 -0
  15. package/node_modules/@vellumai/gateway-client/src/types.ts +15 -84
  16. package/openapi.yaml +976 -63
  17. package/package.json +2 -1
  18. package/scripts/sync-llm-catalog.ts +6 -15
  19. package/scripts/sync-web-search-catalog.ts +3 -11
  20. package/src/__tests__/access-request-card-view.test.ts +98 -0
  21. package/src/__tests__/access-request-seed-content-blocks.test.ts +2 -4
  22. package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +72 -32
  23. package/src/__tests__/agent-loop-compaction-strip.test.ts +241 -0
  24. package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +16 -13
  25. package/src/__tests__/agent-loop-output-hooks.test.ts +69 -0
  26. package/src/__tests__/agent-loop-override-profile.test.ts +25 -0
  27. package/src/__tests__/always-loaded-tools-guard.test.ts +2 -3
  28. package/src/__tests__/app-compiler.test.ts +15 -1
  29. package/src/__tests__/app-dir-path-guard.test.ts +0 -1
  30. package/src/__tests__/assistant-feature-flag-guard.test.ts +1 -4
  31. package/src/__tests__/assistant-feature-flag-guardrails.test.ts +0 -2
  32. package/src/__tests__/auth-fallback-events-store.test.ts +6 -14
  33. package/src/__tests__/avatar-identity-sync.test.ts +2 -27
  34. package/src/__tests__/btw-routes.test.ts +6 -8
  35. package/src/__tests__/call-pointer-messages.test.ts +28 -0
  36. package/src/__tests__/cancel-clears-processing.test.ts +89 -0
  37. package/src/__tests__/channel-approval-routes.test.ts +0 -4
  38. package/src/__tests__/channel-inbound-disk-pressure.test.ts +5 -15
  39. package/src/__tests__/checker.test.ts +0 -3
  40. package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +3 -4
  41. package/src/__tests__/compactor-image-manifest-trust.test.ts +21 -1
  42. package/src/__tests__/compactor-summary-call-truncation.test.ts +223 -0
  43. package/src/__tests__/config-loader-backfill.test.ts +268 -27
  44. package/src/__tests__/config-schema.test.ts +35 -0
  45. package/src/__tests__/config-watcher.test.ts +0 -18
  46. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +2 -2
  47. package/src/__tests__/contact-store-user-file.test.ts +0 -6
  48. package/src/__tests__/contacts-tools.test.ts +29 -0
  49. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +22 -0
  50. package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -0
  51. package/src/__tests__/conversation-agent-loop.test.ts +58 -0
  52. package/src/__tests__/conversation-attention-telegram.test.ts +0 -1
  53. package/src/__tests__/conversation-lifecycle.test.ts +7 -9
  54. package/src/__tests__/conversation-load-history-repair.test.ts +101 -0
  55. package/src/__tests__/conversation-routes-guardian-reply.test.ts +15 -12
  56. package/src/__tests__/conversation-surfaces-activation-emit.test.ts +6 -3
  57. package/src/__tests__/conversation-title-service.test.ts +62 -0
  58. package/src/__tests__/credential-broker.test.ts +449 -1
  59. package/src/__tests__/credential-execution-shell-lockdown.test.ts +18 -11
  60. package/src/__tests__/credential-execution-tools.test.ts +0 -1
  61. package/src/__tests__/credential-prompt-route.test.ts +4 -4
  62. package/src/__tests__/credential-routes.test.ts +360 -0
  63. package/src/__tests__/credential-security-invariants.test.ts +4 -13
  64. package/src/__tests__/disk-pressure-policy.test.ts +12 -0
  65. package/src/__tests__/disk-usage.test.ts +65 -0
  66. package/src/__tests__/dynamic-page-surface.test.ts +152 -1
  67. package/src/__tests__/fixtures/credential-security-fixtures.ts +2 -33
  68. package/src/__tests__/gateway-flag-listener.test.ts +110 -1
  69. package/src/__tests__/gateway-only-guard.test.ts +3 -7
  70. package/src/__tests__/guardian-binding-drift-heal.test.ts +1 -1
  71. package/src/__tests__/guardian-card-withdrawal.test.ts +403 -0
  72. package/src/__tests__/guardian-decision-primitive-canonical.test.ts +5 -3
  73. package/src/__tests__/guardian-grant-minting.test.ts +3 -35
  74. package/src/__tests__/guardian-routing-invariants.test.ts +64 -26
  75. package/src/__tests__/guardian-routing-state.test.ts +0 -1
  76. package/src/__tests__/headless-browser-mode.test.ts +10 -0
  77. package/src/__tests__/headless-browser-navigate.test.ts +8 -3
  78. package/src/__tests__/helpers/create-guardian-binding.ts +0 -1
  79. package/src/__tests__/host-browser-proxy.test.ts +87 -0
  80. package/src/__tests__/identity-routes.test.ts +0 -189
  81. package/src/__tests__/inbound-invite-redemption.test.ts +4 -4
  82. package/src/__tests__/injector-v3-suppression.test.ts +27 -20
  83. package/src/__tests__/internal-telemetry-routes.test.ts +6 -14
  84. package/src/__tests__/invite-redemption-service.test.ts +4 -7
  85. package/src/__tests__/llm-callsite-catalog.test.ts +5 -6
  86. package/src/__tests__/llm-catalog-parity.test.ts +30 -23
  87. package/src/__tests__/llm-resolver.test.ts +70 -24
  88. package/src/__tests__/llm-schema.test.ts +1 -0
  89. package/src/__tests__/managed-profile-guard.test.ts +163 -4
  90. package/src/__tests__/mcp-health-check.test.ts +6 -7
  91. package/src/__tests__/media-stream-server-integration.test.ts +317 -13
  92. package/src/__tests__/oauth-provider-seed-logos.test.ts +4 -6
  93. package/src/__tests__/onboarding-persona-write.test.ts +1 -1
  94. package/src/__tests__/path-policy.test.ts +34 -0
  95. package/src/__tests__/persona-resolver.test.ts +49 -14
  96. package/src/__tests__/plugin-api-model-profiles.test.ts +178 -0
  97. package/src/__tests__/plugin-api-provider.test.ts +24 -0
  98. package/src/__tests__/plugin-tool-contribution.test.ts +6 -3
  99. package/src/__tests__/post-compaction-reinjection-idempotency.test.ts +214 -0
  100. package/src/__tests__/provider-send-message-override-profile.test.ts +76 -0
  101. package/src/__tests__/reaction-persistence.test.ts +150 -29
  102. package/src/__tests__/registry.test.ts +2 -7
  103. package/src/__tests__/relay-server.test.ts +285 -0
  104. package/src/__tests__/runtime-attachment-metadata.test.ts +0 -1
  105. package/src/__tests__/schedule-routes-workflow-validation.test.ts +1 -10
  106. package/src/__tests__/schedule-routes.test.ts +0 -30
  107. package/src/__tests__/schedule-tools.test.ts +2 -18
  108. package/src/__tests__/scheduler-reuse-conversation.test.ts +8 -5
  109. package/src/__tests__/skill-execute-input.test.ts +51 -1
  110. package/src/__tests__/skill-runtime-path.test.ts +2 -3
  111. package/src/__tests__/skills.test.ts +51 -0
  112. package/src/__tests__/slack-notification-approval-card.test.ts +176 -0
  113. package/src/__tests__/slack-reaction-canonical-approval.test.ts +285 -0
  114. package/src/__tests__/subagent-tools.test.ts +266 -0
  115. package/src/__tests__/surface-completion-nudge-hook.test.ts +367 -0
  116. package/src/__tests__/task-progress-nudge-hook.test.ts +1 -1
  117. package/src/__tests__/title-generate-hook.test.ts +100 -3
  118. package/src/__tests__/token-estimator-accuracy.benchmark.test.ts +1 -29
  119. package/src/__tests__/token-manager.test.ts +519 -0
  120. package/src/__tests__/tool-approval-seed-content-blocks.test.ts +1 -1
  121. package/src/__tests__/tool-audit-listener.test.ts +7 -7
  122. package/src/__tests__/tool-executor-lifecycle-events.test.ts +6 -3
  123. package/src/__tests__/tool-executor.test.ts +0 -79
  124. package/src/__tests__/trusted-contact-approval-notifier.test.ts +4 -2
  125. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +220 -3
  126. package/src/__tests__/trusted-contact-multichannel.test.ts +3 -3
  127. package/src/__tests__/trusted-contact-verification.test.ts +8 -10
  128. package/src/__tests__/twilio-routes.test.ts +81 -1
  129. package/src/__tests__/voice-invite-redemption.test.ts +2 -3
  130. package/src/__tests__/weak-open-model.test.ts +30 -0
  131. package/src/__tests__/web-search-catalog-parity.test.ts +6 -25
  132. package/src/__tests__/workspace-greetings.test.ts +152 -0
  133. package/src/__tests__/workspace-migration-105-enable-memory-v3-live-for-new-workspaces.test.ts +149 -0
  134. package/src/__tests__/workspace-migration-108-drop-balanced-economy-profile.test.ts +285 -0
  135. package/src/__tests__/workspace-migration-add-send-diagnostics.test.ts +1 -1
  136. package/src/__tests__/workspace-migration-drop-collect-usage-data.test.ts +118 -0
  137. package/src/__tests__/workspace-migration-drop-send-diagnostics.test.ts +118 -0
  138. package/src/a2a/__tests__/e2e-a2a-channel.test.ts +0 -4
  139. package/src/agent/loop.ts +49 -29
  140. package/src/api/README.md +6 -6
  141. package/src/api/events/tool-result.ts +6 -0
  142. package/src/api/events/workflow-completed.ts +53 -0
  143. package/src/api/events/workflow-leaf-finished.ts +38 -0
  144. package/src/api/events/workflow-leaf-started.ts +35 -0
  145. package/src/api/events/workflow-progress.ts +32 -0
  146. package/src/api/events/workflow-started.ts +31 -0
  147. package/src/api/index.ts +40 -0
  148. package/src/api/responses/conversation-message.ts +28 -4
  149. package/src/api/responses/home.ts +26 -4
  150. package/src/api/responses/workflow-journal.ts +53 -0
  151. package/src/approvals/guardian-card-withdrawal.ts +145 -0
  152. package/src/approvals/guardian-decision-primitive.ts +26 -3
  153. package/src/approvals/guardian-request-resolvers.ts +183 -80
  154. package/src/calls/__tests__/channel-admission-reader.test.ts +132 -0
  155. package/src/calls/__tests__/relay-setup-router.test.ts +350 -0
  156. package/src/calls/call-pointer-messages.ts +10 -4
  157. package/src/calls/channel-admission-reader.ts +104 -0
  158. package/src/calls/guardian-dispatch.ts +17 -45
  159. package/src/calls/media-stream-server.ts +84 -2
  160. package/src/calls/relay-access-wait.ts +1 -1
  161. package/src/calls/relay-server.ts +66 -0
  162. package/src/calls/relay-setup-router.ts +82 -1
  163. package/src/calls/twilio-routes.ts +17 -8
  164. package/src/calls/voice-session-bridge.ts +2 -2
  165. package/src/cli/commands/clients.ts +3 -0
  166. package/src/cli/commands/{__tests__ → memory/__tests__}/memory-v2-compare-render.test.ts +1 -1
  167. package/src/cli/commands/{__tests__ → memory/__tests__}/memory-v2.test.ts +8 -7
  168. package/src/cli/commands/{__tests__ → memory/__tests__}/memory-v3.test.ts +5 -4
  169. package/src/cli/commands/memory/index.ts +30 -0
  170. package/src/cli/commands/{memory-v2-compare-render.ts → memory/memory-v2-compare-render.ts} +1 -1
  171. package/src/cli/commands/{memory-v2.ts → memory/memory-v2.ts} +6 -15
  172. package/src/cli/commands/{memory-v3.ts → memory/memory-v3.ts} +97 -11
  173. package/src/cli/commands/oauth/status.test.ts +36 -0
  174. package/src/cli/commands/oauth/status.ts +23 -3
  175. package/src/cli/commands/plugins.ts +197 -4
  176. package/src/cli/lib/__tests__/diff-plugin.test.ts +443 -0
  177. package/src/cli/lib/__tests__/inspect-plugin.test.ts +54 -0
  178. package/src/cli/lib/__tests__/merge-plugin-tree.test.ts +443 -0
  179. package/src/cli/lib/__tests__/plugin-surfaces.test.ts +111 -0
  180. package/src/cli/lib/__tests__/upgrade-plugin.test.ts +295 -2
  181. package/src/cli/lib/diff-plugin.ts +346 -0
  182. package/src/cli/lib/inspect-plugin.ts +12 -1
  183. package/src/cli/lib/install-from-github.ts +105 -17
  184. package/src/cli/lib/merge-plugin-tree.ts +328 -0
  185. package/src/cli/lib/plugin-fingerprint.ts +14 -0
  186. package/src/cli/lib/plugin-surfaces.ts +104 -0
  187. package/src/cli/lib/upgrade-plugin.ts +298 -10
  188. package/src/cli/program.ts +2 -6
  189. package/src/config/__tests__/sync-gated-profiles.test.ts +368 -0
  190. package/src/config/assistant-feature-flags.ts +22 -7
  191. package/src/config/bundled-skills/contacts/tools/contact-search.ts +0 -1
  192. package/src/config/bundled-skills/messaging/SKILL.md +6 -4
  193. package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +9 -8
  194. package/src/config/bundled-skills/subagent/SKILL.md +4 -0
  195. package/src/config/bundled-skills/subagent/TOOLS.json +4 -0
  196. package/src/config/bundled-skills/workflows/SKILL.md +14 -8
  197. package/src/config/bundled-tool-registry.ts +2 -7
  198. package/src/config/call-site-defaults.ts +15 -2
  199. package/src/config/feature-flag-registry.json +46 -31
  200. package/src/config/inference-profile-validation.ts +26 -0
  201. package/src/config/llm-resolver.ts +3 -0
  202. package/src/config/loader.ts +4 -0
  203. package/src/config/memory-v3-gate.ts +11 -0
  204. package/src/config/profile-order.ts +28 -0
  205. package/src/config/schema.ts +8 -6
  206. package/src/config/schemas/__tests__/memory-v3.test.ts +1 -0
  207. package/src/config/schemas/call-site-catalog.ts +7 -0
  208. package/src/config/schemas/channels.ts +11 -0
  209. package/src/config/schemas/elevenlabs.ts +0 -1
  210. package/src/config/schemas/llm.ts +31 -0
  211. package/src/config/schemas/memory-lifecycle.ts +3 -7
  212. package/src/config/schemas/memory-v3.ts +6 -0
  213. package/src/config/schemas/platform.ts +0 -8
  214. package/src/config/schemas/services.ts +18 -0
  215. package/src/config/seed-inference-profiles.ts +109 -44
  216. package/src/config/skills.ts +21 -0
  217. package/src/config/sync-gated-profiles.ts +220 -0
  218. package/src/contacts/contact-store.ts +89 -106
  219. package/src/contacts/contacts-write.ts +5 -22
  220. package/src/contacts/types.ts +0 -1
  221. package/src/context/compactor.ts +88 -54
  222. package/src/context/strip-injections.ts +58 -10
  223. package/src/context/token-estimator.ts +1 -1
  224. package/src/credential-execution/process-manager.ts +55 -14
  225. package/src/credential-execution/prompted-credential.ts +2 -3
  226. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +3 -2
  227. package/src/daemon/config-watcher.ts +0 -4
  228. package/src/daemon/conversation-agent-loop-handlers.ts +2 -0
  229. package/src/daemon/conversation-agent-loop.ts +114 -22
  230. package/src/daemon/conversation-history.ts +1 -1
  231. package/src/daemon/conversation-lifecycle.ts +3 -5
  232. package/src/daemon/conversation-process.ts +13 -5
  233. package/src/daemon/conversation-runtime-assembly.ts +13 -15
  234. package/src/daemon/conversation-slash.ts +2 -23
  235. package/src/daemon/conversation-surfaces.ts +26 -0
  236. package/src/daemon/conversation-tool-setup.ts +27 -14
  237. package/src/daemon/conversation.ts +66 -14
  238. package/src/daemon/disk-pressure-policy.ts +5 -3
  239. package/src/daemon/handlers/__tests__/config-a2a-complete.test.ts +0 -1
  240. package/src/daemon/handlers/__tests__/config-a2a-redeem.test.ts +0 -1
  241. package/src/daemon/handlers/config-a2a.ts +0 -2
  242. package/src/daemon/handlers/config-channels.ts +15 -16
  243. package/src/daemon/handlers/config-slack-channel.ts +22 -3
  244. package/src/daemon/handlers/conversations.ts +107 -0
  245. package/src/daemon/host-browser-proxy.ts +41 -0
  246. package/src/daemon/lifecycle.ts +55 -27
  247. package/src/daemon/message-provenance.ts +2 -0
  248. package/src/daemon/message-types/contacts.ts +0 -1
  249. package/src/daemon/message-types/conversations.ts +3 -3
  250. package/src/daemon/message-types/sync.ts +0 -1
  251. package/src/daemon/message-types/web-activity.ts +7 -1
  252. package/src/daemon/message-types/workflows.ts +83 -1
  253. package/src/daemon/orphan-reaper.test.ts +0 -19
  254. package/src/daemon/orphan-reaper.ts +2 -24
  255. package/src/daemon/server.ts +0 -10
  256. package/src/daemon/tool-setup-types.ts +4 -0
  257. package/src/daemon/trust-context.ts +1 -1
  258. package/src/events/tool-audit-listener.ts +2 -2
  259. package/src/home/feed-source-enrichment.test.ts +151 -0
  260. package/src/home/feed-source-enrichment.ts +176 -0
  261. package/src/home/relationship-state.ts +2 -4
  262. package/src/instrument.ts +18 -6
  263. package/src/ipc/__tests__/binary-result-ipc.test.ts +81 -0
  264. package/src/ipc/__tests__/clients-list-ipc.test.ts +20 -0
  265. package/src/ipc/assistant-server.ts +37 -4
  266. package/src/ipc/gateway-flag-listener.ts +18 -2
  267. package/src/memory/__tests__/auto-analysis-enqueue.test.ts +5 -16
  268. package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +7 -11
  269. package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +37 -7
  270. package/src/memory/__tests__/memory-retrospective-job.test.ts +229 -401
  271. package/src/memory/__tests__/onboarding-events-store.test.ts +7 -7
  272. package/src/memory/auth-fallback-events-store.ts +2 -2
  273. package/src/memory/auto-analysis-enqueue.ts +3 -5
  274. package/src/memory/bookmark-crud.ts +1 -2
  275. package/src/memory/canonical-guardian-store.ts +39 -1
  276. package/src/memory/conversation-crud.ts +9 -4
  277. package/src/memory/conversation-key-store.ts +17 -2
  278. package/src/memory/conversation-title-service.ts +64 -7
  279. package/src/memory/db-init.ts +17 -17
  280. package/src/memory/embedding-backend.ts +38 -1
  281. package/src/memory/embedding-billing-breaker.ts +96 -0
  282. package/src/memory/jobs-store.ts +25 -13
  283. package/src/memory/jobs-worker.ts +54 -1
  284. package/src/memory/lifecycle-events-store.ts +2 -2
  285. package/src/memory/memory-retrospective-constants.ts +4 -4
  286. package/src/memory/memory-retrospective-enqueue.ts +31 -6
  287. package/src/memory/memory-retrospective-job.ts +28 -227
  288. package/src/memory/migrations/129-contact-channels-access-fields.ts +18 -9
  289. package/src/memory/migrations/131-drop-legacy-member-guardian-tables.ts +14 -2
  290. package/src/memory/migrations/289-contact-channels-unique-ext-user.ts +10 -0
  291. package/src/memory/migrations/291-contact-channels-renormalize-addresses.ts +72 -0
  292. package/src/memory/migrations/292-schedule-default-no-reuse-conversation.test.ts +67 -0
  293. package/src/memory/migrations/292-schedule-default-no-reuse-conversation.ts +25 -0
  294. package/src/memory/migrations/293-workflow-journal-leaf-tokens.ts +32 -0
  295. package/src/memory/migrations/294-drop-external-user-id.ts +31 -0
  296. package/src/memory/migrations/295-drop-approval-prompt-ts-tracker.ts +20 -0
  297. package/src/memory/migrations/296-rewrite-balanced-economy-profile-pins.test.ts +110 -0
  298. package/src/memory/migrations/296-rewrite-balanced-economy-profile-pins.ts +68 -0
  299. package/src/memory/migrations/__tests__/131-drop-legacy-member-guardian-tables.test.ts +154 -0
  300. package/src/memory/migrations/__tests__/289-contact-channels-unique-ext-user.test.ts +31 -0
  301. package/src/memory/migrations/__tests__/291-contact-channels-renormalize-addresses.test.ts +341 -0
  302. package/src/memory/migrations/__tests__/run-migrations.test.ts +52 -0
  303. package/src/memory/migrations/index.ts +6 -0
  304. package/src/memory/migrations/run-migrations.ts +41 -0
  305. package/src/memory/migrations/validate-migration-state.ts +1 -1
  306. package/src/memory/onboarding-events-store.ts +3 -3
  307. package/src/memory/schema/contacts.ts +0 -5
  308. package/src/memory/skill-loaded-events-store.test.ts +7 -15
  309. package/src/memory/skill-loaded-events-store.ts +2 -2
  310. package/src/memory/tool-executed-events-store.test.ts +7 -7
  311. package/src/memory/turn-trace-store.test.ts +736 -0
  312. package/src/memory/turn-trace-store.ts +364 -0
  313. package/src/memory/v2/__tests__/consolidation-job.test.ts +8 -0
  314. package/src/memory/v2/__tests__/skill-content.test.ts +30 -0
  315. package/src/memory/v2/consolidation-job.ts +2 -2
  316. package/src/memory/v2/skill-content.ts +25 -7
  317. package/src/memory/v2/skill-store.ts +7 -1
  318. package/src/memory/v3-eval/__tests__/eval-packets.test.ts +248 -0
  319. package/src/memory/v3-eval/eval-packets.ts +546 -0
  320. package/src/messaging/providers/slack/adapter.ts +1 -1
  321. package/src/messaging/providers/slack/api.ts +31 -0
  322. package/src/messaging/providers/slack/send.test.ts +114 -2
  323. package/src/messaging/providers/slack/send.ts +30 -7
  324. package/src/messaging/providers/slack/withdraw.test.ts +200 -0
  325. package/src/messaging/providers/slack/withdraw.ts +161 -0
  326. package/src/notifications/AGENTS.md +2 -0
  327. package/src/notifications/access-request-copy.ts +72 -59
  328. package/src/notifications/adapters/shared.ts +29 -0
  329. package/src/notifications/adapters/slack.ts +58 -103
  330. package/src/notifications/adapters/telegram.ts +2 -20
  331. package/src/notifications/approval-card-data.ts +333 -0
  332. package/src/notifications/broadcaster.ts +16 -3
  333. package/src/notifications/canonical-delivery-recorder.ts +139 -0
  334. package/src/notifications/copy-composer.ts +3 -3
  335. package/src/notifications/decision-engine.ts +4 -2
  336. package/src/notifications/destination-resolver.ts +4 -6
  337. package/src/notifications/guardian-question-mode.ts +10 -0
  338. package/src/notifications/home-feed-side-effect.ts +7 -16
  339. package/src/notifications/notification-utils.ts +19 -20
  340. package/src/notifications/signal.ts +79 -43
  341. package/src/notifications/types.ts +98 -121
  342. package/src/oauth/AGENTS.md +5 -24
  343. package/src/permissions/checker.test.ts +51 -0
  344. package/src/permissions/checker.ts +185 -26
  345. package/src/permissions/ipc-risk-types.ts +24 -0
  346. package/src/permissions/question-prompter.test.ts +27 -0
  347. package/src/permissions/question-prompter.ts +4 -0
  348. package/src/platform/client.test.ts +119 -0
  349. package/src/platform/client.ts +66 -0
  350. package/src/platform/consent-cache.test.ts +267 -0
  351. package/src/platform/consent-cache.ts +174 -0
  352. package/src/plugin-api/constants.ts +1 -1
  353. package/src/plugin-api/index.ts +33 -1
  354. package/src/plugin-api/model-profiles.ts +33 -0
  355. package/src/plugin-api/types.ts +50 -2
  356. package/src/plugins/defaults/advisor/__tests__/advisor-gate.test.ts +56 -0
  357. package/src/plugins/defaults/advisor/__tests__/advisor-state-store.test.ts +43 -0
  358. package/src/plugins/defaults/advisor/__tests__/agent-loop-integration.test.ts +137 -0
  359. package/src/plugins/defaults/advisor/__tests__/consult.test.ts +153 -0
  360. package/src/plugins/defaults/advisor/__tests__/hooks.test.ts +138 -0
  361. package/src/plugins/defaults/advisor/__tests__/transcript.test.ts +147 -0
  362. package/src/plugins/defaults/advisor/advisor-gate.ts +29 -0
  363. package/src/plugins/defaults/advisor/advisor-state-store.ts +94 -0
  364. package/src/plugins/defaults/advisor/config.ts +21 -0
  365. package/src/plugins/defaults/advisor/consult.ts +93 -0
  366. package/src/plugins/defaults/advisor/hooks/post-model-call.ts +34 -0
  367. package/src/plugins/defaults/advisor/hooks/pre-model-call.ts +30 -0
  368. package/src/plugins/defaults/advisor/hooks/user-prompt-submit.ts +19 -0
  369. package/src/plugins/defaults/advisor/package.json +14 -0
  370. package/src/plugins/defaults/advisor/steering.ts +67 -0
  371. package/src/plugins/defaults/advisor/tools/advisor.ts +65 -0
  372. package/src/plugins/defaults/advisor/transcript.ts +76 -0
  373. package/src/plugins/defaults/index.ts +60 -0
  374. package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +22 -9
  375. package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit.ts +2 -2
  376. package/src/plugins/defaults/memory-retrieval/tail-reinjection-strip.ts +64 -0
  377. package/src/plugins/defaults/memory-retrieval/unified-turn-context.ts +29 -21
  378. package/src/plugins/defaults/memory-v3-shadow/__tests__/carry-integration.test.ts +1 -0
  379. package/src/plugins/defaults/memory-v3-shadow/__tests__/injection.test.ts +1 -0
  380. package/src/plugins/defaults/memory-v3-shadow/__tests__/maintain-job.test.ts +129 -9
  381. package/src/plugins/defaults/memory-v3-shadow/__tests__/orchestrate.test.ts +31 -4
  382. package/src/plugins/defaults/memory-v3-shadow/__tests__/selection-log-store.test.ts +77 -2
  383. package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +1 -0
  384. package/src/plugins/defaults/memory-v3-shadow/injector.ts +7 -10
  385. package/src/plugins/defaults/memory-v3-shadow/maintain-job.ts +144 -11
  386. package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +32 -20
  387. package/src/plugins/defaults/memory-v3-shadow/selection-log-store.ts +56 -3
  388. package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +23 -2
  389. package/src/plugins/defaults/surface-completion-nudge/hooks/post-model-call.ts +276 -0
  390. package/src/plugins/defaults/surface-completion-nudge/hooks/stop.ts +22 -0
  391. package/src/plugins/defaults/surface-completion-nudge/nudge-state-store.ts +46 -0
  392. package/src/plugins/defaults/surface-completion-nudge/package.json +14 -0
  393. package/src/plugins/defaults/task-progress-nudge/hooks/post-tool-use.ts +3 -13
  394. package/src/plugins/defaults/title-generate/hooks/stop.ts +56 -21
  395. package/src/prompts/persona-resolver.ts +14 -4
  396. package/src/prompts/templates/system-sections.ts +7 -2
  397. package/src/providers/__tests__/provider-env-vars.test.ts +6 -0
  398. package/src/providers/__tests__/provider-secret-catalog.test.ts +1 -0
  399. package/src/providers/__tests__/retry-callsite.test.ts +176 -0
  400. package/src/providers/atlascloud/client.ts +85 -0
  401. package/src/providers/fetch-provider-catalog.ts +85 -0
  402. package/src/providers/inference/adapter-factory.ts +3 -0
  403. package/src/providers/model-catalog.ts +58 -0
  404. package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +33 -0
  405. package/src/providers/openai/chat-completions-provider.ts +7 -0
  406. package/src/providers/openai/responses-provider.ts +10 -0
  407. package/src/providers/provider-send-message.ts +11 -3
  408. package/src/providers/retry.ts +53 -12
  409. package/src/providers/search-provider-catalog.ts +10 -0
  410. package/src/providers/weak-open-model.ts +22 -0
  411. package/src/runtime/AGENTS.md +0 -1
  412. package/src/runtime/__tests__/agent-wake.test.ts +181 -0
  413. package/src/runtime/__tests__/client-health.test.ts +44 -0
  414. package/src/runtime/access-request-helper.ts +21 -53
  415. package/src/runtime/actor-trust-resolver.ts +59 -63
  416. package/src/runtime/agent-wake.ts +52 -0
  417. package/src/runtime/assistant-event-hub.ts +18 -4
  418. package/src/runtime/auth/__tests__/route-policy.test.ts +12 -0
  419. package/src/runtime/auth/require-bound-guardian.ts +1 -4
  420. package/src/runtime/btw-sidechain.ts +3 -6
  421. package/src/runtime/capabilities.test.ts +120 -0
  422. package/src/runtime/capabilities.ts +197 -0
  423. package/src/runtime/channel-approval-types.ts +22 -45
  424. package/src/runtime/channel-invite-transports/telegram.ts +4 -4
  425. package/src/runtime/channel-retry-sweep.ts +1 -0
  426. package/src/runtime/channel-verification-service.ts +3 -3
  427. package/src/runtime/client-health.ts +26 -0
  428. package/src/runtime/confirmation-request-guardian-bridge.ts +38 -29
  429. package/src/runtime/effective-capabilities.test.ts +128 -0
  430. package/src/runtime/effective-capabilities.ts +84 -0
  431. package/src/runtime/guardian-reply-router.ts +106 -21
  432. package/src/runtime/invite-redemption-service.ts +9 -25
  433. package/src/runtime/migrations/__tests__/vbundle-builder-fd-leak.test.ts +123 -0
  434. package/src/runtime/migrations/vbundle-builder.ts +49 -20
  435. package/src/runtime/pending-interactions.ts +15 -0
  436. package/src/runtime/routes/__tests__/client-routes.test.ts +13 -0
  437. package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +67 -0
  438. package/src/runtime/routes/__tests__/plugins-routes.test.ts +240 -1
  439. package/src/runtime/routes/app-routes.ts +1 -1
  440. package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +2 -2
  441. package/src/runtime/routes/assets/vellum-design-system.css +1959 -0
  442. package/src/runtime/routes/browser-tabs-routes.ts +9 -0
  443. package/src/runtime/routes/btw-routes.ts +1 -27
  444. package/src/runtime/routes/canonical-guardian-expiry-sweep.ts +17 -8
  445. package/src/runtime/routes/client-routes.ts +10 -0
  446. package/src/runtime/routes/contact-routes.ts +31 -8
  447. package/src/runtime/routes/conversation-compaction-routes.ts +1 -1
  448. package/src/runtime/routes/conversation-management-routes.ts +80 -1
  449. package/src/runtime/routes/conversation-query-routes.ts +68 -22
  450. package/src/runtime/routes/conversation-routes.ts +39 -14
  451. package/src/runtime/routes/credential-routes.ts +40 -16
  452. package/src/runtime/routes/empty-state-greeting-cache.ts +1 -2
  453. package/src/runtime/routes/events-routes.ts +1 -3
  454. package/src/runtime/routes/guardian-approval-interception.ts +14 -73
  455. package/src/runtime/routes/guardian-approval-prompt.ts +22 -4
  456. package/src/runtime/routes/home-feed-routes.ts +8 -3
  457. package/src/runtime/routes/identity-routes.ts +1 -296
  458. package/src/runtime/routes/inbound-message-handler.ts +214 -228
  459. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +89 -7
  460. package/src/runtime/routes/inbound-stages/admission-policy.test.ts +154 -0
  461. package/src/runtime/routes/inbound-stages/admission-policy.ts +140 -0
  462. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +3 -3
  463. package/src/runtime/routes/inbound-stages/background-dispatch.ts +11 -6
  464. package/src/runtime/routes/inbound-stages/escalation-intercept.ts +1 -2
  465. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +1 -2
  466. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +7 -7
  467. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +47 -28
  468. package/src/runtime/routes/inbound-stages/reaction-intercept.ts +358 -0
  469. package/src/runtime/routes/index.ts +2 -0
  470. package/src/runtime/routes/integrations/slack/__tests__/channel.test.ts +8 -0
  471. package/src/runtime/routes/integrations/slack/channel.ts +36 -0
  472. package/src/runtime/routes/internal-telemetry-routes.ts +1 -1
  473. package/src/runtime/routes/mcp-auth-routes.ts +233 -41
  474. package/src/runtime/routes/memory-eval-routes.ts +87 -0
  475. package/src/runtime/routes/notification-routes.ts +122 -133
  476. package/src/runtime/routes/platform-routes.ts +2 -2
  477. package/src/runtime/routes/plugins-routes.ts +202 -3
  478. package/src/runtime/routes/schedule-routes.ts +0 -22
  479. package/src/runtime/routes/secret-routes.ts +10 -0
  480. package/src/runtime/routes/surface-action-routes.ts +2 -1
  481. package/src/runtime/routes/tool-call-question-enrichment.test.ts +146 -0
  482. package/src/runtime/routes/tool-call-question-enrichment.ts +66 -0
  483. package/src/runtime/routes/workflow-routes.test.ts +229 -44
  484. package/src/runtime/routes/workflow-routes.ts +131 -29
  485. package/src/runtime/routes/workspace-greetings.ts +55 -0
  486. package/src/runtime/sync/resource-sync-events.ts +1 -11
  487. package/src/runtime/tool-grant-request-helper.ts +18 -16
  488. package/src/runtime/trust-context-resolver.ts +8 -5
  489. package/src/schedule/inference-profile.ts +2 -14
  490. package/src/schedule/schedule-store.ts +1 -1
  491. package/src/schedule/scheduler-types.ts +5 -1
  492. package/src/security/__tests__/provider-key-env-fallback.test.ts +6 -0
  493. package/src/security/secret-patterns.ts +3 -0
  494. package/src/subagent/manager.ts +17 -4
  495. package/src/subagent/types.ts +6 -0
  496. package/src/telemetry/trace-collection-policy.test.ts +28 -0
  497. package/src/telemetry/trace-collection-policy.ts +30 -0
  498. package/src/telemetry/types.ts +89 -0
  499. package/src/telemetry/usage-telemetry-reporter.test.ts +586 -36
  500. package/src/telemetry/usage-telemetry-reporter.ts +148 -41
  501. package/src/tools/AGENTS.md +3 -3
  502. package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +31 -0
  503. package/src/tools/browser/browser-execution.ts +30 -19
  504. package/src/tools/document/document-tool.ts +2 -3
  505. package/src/tools/executor.ts +5 -3
  506. package/src/tools/host-terminal/host-shell.ts +5 -4
  507. package/src/tools/memory/register.ts +2 -2
  508. package/src/tools/network/__tests__/web-fetch-firecrawl.test.ts +360 -0
  509. package/src/tools/network/__tests__/web-search.test.ts +143 -0
  510. package/src/tools/network/web-fetch.ts +372 -1
  511. package/src/tools/network/web-search-error.ts +1 -1
  512. package/src/tools/network/web-search.ts +213 -10
  513. package/src/tools/permission-checker.ts +4 -3
  514. package/src/tools/registry.ts +20 -0
  515. package/src/tools/schedule/create.ts +7 -12
  516. package/src/tools/schedule/update.ts +4 -11
  517. package/src/tools/shared/filesystem/path-policy.ts +39 -13
  518. package/src/tools/side-effects.ts +2 -17
  519. package/src/tools/skills/execute.ts +33 -0
  520. package/src/tools/subagent/spawn.ts +61 -12
  521. package/src/tools/terminal/shell.ts +10 -4
  522. package/src/tools/tool-approval-handler.ts +18 -13
  523. package/src/tools/tool-manifest.ts +0 -2
  524. package/src/tools/types.ts +9 -0
  525. package/src/tools/ui-surface/definitions.ts +64 -3
  526. package/src/tools/verification-control-plane-policy.ts +3 -1
  527. package/src/tools/workflows/run-workflow.test.ts +8 -18
  528. package/src/tools/workflows/run-workflow.ts +1 -0
  529. package/src/util/disk-usage.ts +78 -23
  530. package/src/util/platform.ts +10 -3
  531. package/src/watcher/telemetry.ts +2 -2
  532. package/src/workflows/capabilities.ts +2 -3
  533. package/src/workflows/engine.test.ts +175 -1
  534. package/src/workflows/engine.ts +82 -0
  535. package/src/workflows/journal-store.test.ts +70 -0
  536. package/src/workflows/journal-store.ts +18 -3
  537. package/src/workflows/run-manager.test.ts +171 -28
  538. package/src/workflows/run-manager.ts +66 -24
  539. package/src/workspace/migrations/105-enable-memory-v3-live-for-new-workspaces.ts +63 -0
  540. package/src/workspace/migrations/106-drop-collect-usage-data.ts +47 -0
  541. package/src/workspace/migrations/107-drop-send-diagnostics.ts +47 -0
  542. package/src/workspace/migrations/108-drop-balanced-economy-profile.ts +129 -0
  543. package/src/workspace/migrations/registry.ts +8 -0
  544. package/src/__tests__/app-control-no-global-cgevent.test.ts +0 -98
  545. package/src/__tests__/credential-security-e2e.test.ts +0 -362
  546. package/src/__tests__/credential-vault-unit.test.ts +0 -1528
  547. package/src/__tests__/credential-vault.test.ts +0 -1706
  548. package/src/__tests__/identity-intro-cache.test.ts +0 -315
  549. package/src/__tests__/secret-onetime-send.test.ts +0 -182
  550. package/src/cli/commands/__tests__/task.test.ts +0 -914
  551. package/src/cli/commands/task.ts +0 -771
  552. package/src/config/bundled-skills/personal-page/SKILL.md +0 -57
  553. package/src/config/bundled-skills/personal-page/TOOLS.json +0 -27
  554. package/src/config/bundled-skills/personal-page/tools/app-refresh.ts +0 -17
  555. package/src/config/preloaded-apps/personal-page/src/components/About.tsx +0 -22
  556. package/src/config/preloaded-apps/personal-page/src/components/App.tsx +0 -16
  557. package/src/config/preloaded-apps/personal-page/src/components/Features.tsx +0 -77
  558. package/src/config/preloaded-apps/personal-page/src/components/Hero.tsx +0 -57
  559. package/src/config/preloaded-apps/personal-page/src/components/Pending.tsx +0 -28
  560. package/src/config/preloaded-apps/personal-page/src/components/animations.tsx +0 -234
  561. package/src/config/preloaded-apps/personal-page/src/components/icons.tsx +0 -48
  562. package/src/config/preloaded-apps/personal-page/src/components/media.ts +0 -16
  563. package/src/config/preloaded-apps/personal-page/src/index.html +0 -20
  564. package/src/config/preloaded-apps/personal-page/src/main.tsx +0 -7
  565. package/src/config/preloaded-apps/personal-page/src/profile-data.ts +0 -82
  566. package/src/config/preloaded-apps/personal-page/src/styles.css +0 -759
  567. package/src/memory/__tests__/preloaded-apps.test.ts +0 -85
  568. package/src/memory/preloaded-apps.ts +0 -116
  569. package/src/notifications/tool-approval-copy.ts +0 -142
  570. package/src/runtime/routes/approval-prompt-ts-tracker.ts +0 -78
  571. package/src/runtime/routes/identity-intro-cache.ts +0 -172
  572. package/src/tools/credentials/vault.ts +0 -712
@@ -1,712 +0,0 @@
1
- import {
2
- formatSlackChannelStatus,
3
- isSlackChannelCredential,
4
- persistPromptedCredential,
5
- storeSlackChannelCredential,
6
- } from "../../credential-execution/prompted-credential.js";
7
- import {
8
- clearSlackUserToken,
9
- type SlackChannelConfigResult,
10
- } from "../../daemon/handlers/config-slack-channel.js";
11
- import { syncManualTokenConnection } from "../../oauth/manual-token-connection.js";
12
- import {
13
- disconnectOAuthProvider,
14
- getActiveConnection,
15
- } from "../../oauth/oauth-store.js";
16
- import { RiskLevel } from "../../permissions/types.js";
17
- import { credentialKey } from "../../security/credential-key.js";
18
- import {
19
- deleteSecureKeyAsync,
20
- listSecureKeysAsync,
21
- setSecureKeyAsync,
22
- } from "../../security/secure-keys.js";
23
- import { getLogger } from "../../util/logger.js";
24
- import type {
25
- ToolContext,
26
- ToolDefinition,
27
- ToolExecutionResult,
28
- } from "../types.js";
29
- import {
30
- assertMetadataWritable,
31
- deleteCredentialMetadata,
32
- getCredentialMetadata,
33
- listCredentialMetadata,
34
- upsertCredentialMetadata,
35
- } from "./metadata-store.js";
36
- import type {
37
- CredentialInjectionTemplate,
38
- CredentialPolicyInput,
39
- } from "./policy-types.js";
40
- import { toPolicyFromInput, validatePolicyInput } from "./policy-validate.js";
41
-
42
- const log = getLogger("credential-vault");
43
-
44
- export const credentialStoreTool = {
45
- name: "credential_store",
46
- description:
47
- "Store, list, delete, or prompt for credentials in the secure vault",
48
- category: "credentials",
49
- executionTarget: "sandbox",
50
- defaultRiskLevel: RiskLevel.Low,
51
-
52
- input_schema: {
53
- type: "object",
54
- properties: {
55
- action: {
56
- type: "string",
57
- enum: ["store", "list", "delete", "prompt"],
58
- description:
59
- 'The operation to perform. Use "prompt" to request a secret via secure UI - the value never enters the conversation.',
60
- },
61
- service: {
62
- type: "string",
63
- description: "Service name, e.g. google, github",
64
- },
65
- account: {
66
- type: "string",
67
- description:
68
- "Account identifier (e.g. email address) to target a specific connection when multiple accounts are connected for the same service. If omitted, uses the most recently connected account.",
69
- },
70
- field: {
71
- type: "string",
72
- description: "Field name, e.g. password, username, recovery_email",
73
- },
74
- value: {
75
- type: "string",
76
- description: "The credential value (only for store action)",
77
- },
78
- label: {
79
- type: "string",
80
- description:
81
- 'Display label for the prompt UI (only for prompt action), e.g. "GitHub Personal Access Token"',
82
- },
83
- description: {
84
- type: "string",
85
- description:
86
- 'Optional context shown in the prompt UI (only for prompt action), e.g. "Needed to push changes"',
87
- },
88
- placeholder: {
89
- type: "string",
90
- description:
91
- 'Placeholder text for the input field (only for prompt action), e.g. "ghp_xxxxxxxxxxxx"',
92
- },
93
- allowed_tools: {
94
- type: "array",
95
- items: { type: "string" },
96
- description:
97
- 'Tools/capabilities allowed to use this credential (for store/prompt actions), e.g. ["assistant_browser_fill_credential"]. Empty = deny all.',
98
- },
99
- allowed_domains: {
100
- type: "array",
101
- items: { type: "string" },
102
- description:
103
- 'Domains where this credential may be used (for store/prompt actions), e.g. ["github.com"]. Empty = deny all.',
104
- },
105
- usage_description: {
106
- type: "string",
107
- description:
108
- 'Human-readable description of intended usage (for store/prompt actions), e.g. "GitHub login for pushing changes"',
109
- },
110
- alias: {
111
- type: "string",
112
- description:
113
- 'Human-friendly name for this credential (only for store action), e.g. "fal-primary"',
114
- },
115
- injection_templates: {
116
- type: "array",
117
- items: {
118
- type: "object",
119
- properties: {
120
- hostPattern: {
121
- type: "string",
122
- description:
123
- 'Glob pattern for matching request hosts, e.g. "*.fal.ai"',
124
- },
125
- injectionType: {
126
- type: "string",
127
- enum: ["header", "query"],
128
- description: "Where to inject the credential value",
129
- },
130
- headerName: {
131
- type: "string",
132
- description: 'Header name when injectionType is "header"',
133
- },
134
- valuePrefix: {
135
- type: "string",
136
- description:
137
- 'Prefix prepended to the secret value, e.g. "Key ", "Bearer "',
138
- },
139
- queryParamName: {
140
- type: "string",
141
- description: 'Query parameter name when injectionType is "query"',
142
- },
143
- },
144
- required: ["hostPattern", "injectionType"],
145
- },
146
- description:
147
- "Templates describing how to inject this credential into proxied requests (for store and prompt actions)",
148
- },
149
- },
150
- required: ["action"],
151
- },
152
-
153
- async execute(
154
- input: Record<string, unknown>,
155
- context: ToolContext,
156
- ): Promise<ToolExecutionResult> {
157
- const action = input.action as string;
158
-
159
- switch (action) {
160
- case "store": {
161
- const service = input.service as string | undefined;
162
- const field = input.field as string | undefined;
163
- const value = input.value as string | undefined;
164
-
165
- if (!service || typeof service !== "string") {
166
- return {
167
- content: "Error: service is required for store action",
168
- isError: true,
169
- };
170
- }
171
- if (!field || typeof field !== "string") {
172
- return {
173
- content: "Error: field is required for store action",
174
- isError: true,
175
- };
176
- }
177
- if (!value || typeof value !== "string") {
178
- return {
179
- content: "Error: value is required for store action",
180
- isError: true,
181
- };
182
- }
183
-
184
- const policyInput: CredentialPolicyInput = {
185
- allowed_tools: input.allowed_tools as string[] | undefined,
186
- allowed_domains: input.allowed_domains as string[] | undefined,
187
- usage_description: input.usage_description as string | undefined,
188
- };
189
- const policyResult = validatePolicyInput(policyInput);
190
- if (!policyResult.valid) {
191
- return {
192
- content: `Error: ${policyResult.errors.join("; ")}`,
193
- isError: true,
194
- };
195
- }
196
- const policy = toPolicyFromInput(policyInput);
197
-
198
- const alias = input.alias;
199
- if (alias !== undefined && typeof alias !== "string") {
200
- return { content: "Error: alias must be a string", isError: true };
201
- }
202
- const rawTemplates = input.injection_templates as unknown[] | undefined;
203
-
204
- // Validate injection templates
205
- let injectionTemplates: CredentialInjectionTemplate[] | undefined;
206
- if (rawTemplates !== undefined) {
207
- if (!Array.isArray(rawTemplates)) {
208
- return {
209
- content: "Error: injection_templates must be an array",
210
- isError: true,
211
- };
212
- }
213
- const templateErrors: string[] = [];
214
- injectionTemplates = [];
215
- for (let i = 0; i < rawTemplates.length; i++) {
216
- const t = rawTemplates[i] as Record<string, unknown>;
217
- if (typeof t !== "object" || t == null) {
218
- templateErrors.push(
219
- `injection_templates[${i}] must be an object`,
220
- );
221
- continue;
222
- }
223
- if (
224
- typeof t.hostPattern !== "string" ||
225
- t.hostPattern.trim().length === 0
226
- ) {
227
- templateErrors.push(
228
- `injection_templates[${i}].hostPattern must be a non-empty string`,
229
- );
230
- }
231
- if (t.injectionType !== "header" && t.injectionType !== "query") {
232
- templateErrors.push(
233
- `injection_templates[${i}].injectionType must be 'header' or 'query'`,
234
- );
235
- } else if (t.injectionType === "header") {
236
- if (
237
- typeof t.headerName !== "string" ||
238
- t.headerName.trim().length === 0
239
- ) {
240
- templateErrors.push(
241
- `injection_templates[${i}].headerName is required when injectionType is 'header'`,
242
- );
243
- }
244
- } else if (t.injectionType === "query") {
245
- if (
246
- typeof t.queryParamName !== "string" ||
247
- t.queryParamName.trim().length === 0
248
- ) {
249
- templateErrors.push(
250
- `injection_templates[${i}].queryParamName is required when injectionType is 'query'`,
251
- );
252
- }
253
- }
254
- if (
255
- t.valuePrefix !== undefined &&
256
- typeof t.valuePrefix !== "string"
257
- ) {
258
- templateErrors.push(
259
- `injection_templates[${i}].valuePrefix must be a string`,
260
- );
261
- }
262
- if (templateErrors.length === 0) {
263
- injectionTemplates.push({
264
- hostPattern: t.hostPattern as string,
265
- injectionType: t.injectionType as "header" | "query",
266
- headerName:
267
- typeof t.headerName === "string" ? t.headerName : undefined,
268
- valuePrefix:
269
- typeof t.valuePrefix === "string" ? t.valuePrefix : undefined,
270
- queryParamName:
271
- typeof t.queryParamName === "string"
272
- ? t.queryParamName
273
- : undefined,
274
- });
275
- }
276
- }
277
- if (templateErrors.length > 0) {
278
- return {
279
- content: `Error: ${templateErrors.join("; ")}`,
280
- isError: true,
281
- };
282
- }
283
- }
284
-
285
- try {
286
- assertMetadataWritable();
287
- } catch {
288
- return {
289
- content:
290
- "Error: credential metadata file has an unrecognized version; cannot store credentials",
291
- isError: true,
292
- };
293
- }
294
-
295
- let slackChannelResult: SlackChannelConfigResult | undefined;
296
- if (isSlackChannelCredential(service, field)) {
297
- slackChannelResult = await storeSlackChannelCredential(field, value);
298
- if (!slackChannelResult.success) {
299
- return {
300
- content: `Error: ${
301
- slackChannelResult.error ?? "failed to configure Slack channel"
302
- }`,
303
- isError: true,
304
- };
305
- }
306
- } else {
307
- const key = credentialKey(service, field);
308
- const ok = await setSecureKeyAsync(key, value);
309
- if (!ok) {
310
- return {
311
- content: "Error: failed to store credential",
312
- isError: true,
313
- };
314
- }
315
- }
316
- try {
317
- upsertCredentialMetadata(service, field, {
318
- allowedTools: policyInput.allowed_tools,
319
- allowedDomains: policyInput.allowed_domains,
320
- usageDescription: policy.usageDescription,
321
- alias,
322
- injectionTemplates,
323
- });
324
- } catch (err) {
325
- log.warn(
326
- { service, field, err },
327
- "metadata write failed after storing credential",
328
- );
329
- }
330
- if (!isSlackChannelCredential(service, field)) {
331
- await syncManualTokenConnection(service);
332
- }
333
- const metadata = getCredentialMetadata(service, field);
334
- const credIdSuffix = metadata
335
- ? ` (credential_id: ${metadata.credentialId})`
336
- : "";
337
- const retrieveHint = ` Retrieve with: \`assistant credentials reveal --service ${service} --field ${field}\``;
338
- return {
339
- content: `Stored credential for ${service}/${field}.${credIdSuffix}${retrieveHint}${
340
- slackChannelResult
341
- ? formatSlackChannelStatus(slackChannelResult)
342
- : ""
343
- }`,
344
- isError: false,
345
- };
346
- }
347
-
348
- case "list": {
349
- try {
350
- assertMetadataWritable();
351
- } catch {
352
- return {
353
- content:
354
- "Error: credential metadata file has an unrecognized version; cannot list credentials",
355
- isError: true,
356
- };
357
- }
358
-
359
- const allMetadata = listCredentialMetadata();
360
- // Verify secrets still exist by reading all key names once (instead of
361
- // per-entry getSecureKeyAsync calls that each re-read/re-derive the store).
362
- // Uses the async variant to include keys from the credential store.
363
- let secureKeySet: Set<string> | undefined;
364
- try {
365
- secureKeySet = new Set((await listSecureKeysAsync()).accounts);
366
- } catch (err) {
367
- log.error(
368
- { err },
369
- "Failed to read secure store while listing credentials",
370
- );
371
- return {
372
- content:
373
- "Error: failed to read secure storage; cannot list credentials",
374
- isError: true,
375
- };
376
- }
377
- const entries = allMetadata
378
- .filter((m) => {
379
- if (secureKeySet)
380
- return secureKeySet.has(credentialKey(m.service, m.field));
381
- return true;
382
- })
383
- .map((m) => {
384
- const entry: Record<string, unknown> = {
385
- credential_id: m.credentialId,
386
- service: m.service,
387
- field: m.field,
388
- };
389
- if (m.alias) {
390
- entry.alias = m.alias;
391
- }
392
- if (m.injectionTemplates && m.injectionTemplates.length > 0) {
393
- entry.injection_templates = {
394
- count: m.injectionTemplates.length,
395
- host_patterns: m.injectionTemplates.map((t) => t.hostPattern),
396
- };
397
- }
398
- return entry;
399
- });
400
- return { content: JSON.stringify(entries, null, 2), isError: false };
401
- }
402
-
403
- case "delete": {
404
- const service = input.service as string | undefined;
405
- const field = input.field as string | undefined;
406
-
407
- if (!service || typeof service !== "string") {
408
- return {
409
- content: "Error: service is required for delete action",
410
- isError: true,
411
- };
412
- }
413
- if (!field || typeof field !== "string") {
414
- return {
415
- content: "Error: field is required for delete action",
416
- isError: true,
417
- };
418
- }
419
-
420
- try {
421
- assertMetadataWritable();
422
- } catch {
423
- return {
424
- content:
425
- "Error: credential metadata file has an unrecognized version; cannot delete credentials",
426
- isError: true,
427
- };
428
- }
429
-
430
- // Surgical delete for the Slack user_token: it grants read-only access
431
- // to channels the bot isn't a member of, but the Socket Mode connection
432
- // is powered by the bot + app tokens. Tearing down the oauth_connection
433
- // row when only user_token is removed would flap the integration's
434
- // connected state until the next sync. Keep bot+app teardown behavior
435
- // unchanged — those tokens are what the connection depends on.
436
- if (service === "slack_channel" && field === "user_token") {
437
- const slackResult = await clearSlackUserToken();
438
- if (!slackResult.success) {
439
- return {
440
- content: `Error: ${
441
- slackResult.error ?? "failed to delete Slack user token"
442
- }`,
443
- isError: true,
444
- };
445
- }
446
- return {
447
- content: `Deleted credential for ${service}/${field}.`,
448
- isError: false,
449
- };
450
- }
451
-
452
- const key = credentialKey(service, field);
453
- const result = await deleteSecureKeyAsync(key);
454
- if (result === "error") {
455
- return {
456
- content: `Error: failed to delete credential ${service}/${field} from secure storage`,
457
- isError: true,
458
- };
459
- }
460
- if (result === "not-found") {
461
- return {
462
- content: `Error: credential ${service}/${field} not found`,
463
- isError: true,
464
- };
465
- }
466
- try {
467
- deleteCredentialMetadata(service, field);
468
- } catch (err) {
469
- log.warn(
470
- { service, field, err },
471
- "metadata delete failed after removing credential",
472
- );
473
- }
474
- // Also clean up any OAuth connection for this service (best-effort)
475
- try {
476
- const accountHint = input.account as string | undefined;
477
- let oauthResult: "disconnected" | "not-found" | "error";
478
- if (accountHint) {
479
- const targetConn = getActiveConnection(service, {
480
- account: accountHint,
481
- });
482
- oauthResult = targetConn
483
- ? await disconnectOAuthProvider(service, undefined, targetConn.id)
484
- : "not-found";
485
- } else {
486
- oauthResult = await disconnectOAuthProvider(service);
487
- }
488
- if (oauthResult === "error") {
489
- log.warn(
490
- { service },
491
- "OAuth disconnect failed after removing credential - secure key deletion error",
492
- );
493
- }
494
- } catch (err) {
495
- log.warn(
496
- { service, err },
497
- "OAuth disconnect failed after removing credential",
498
- );
499
- }
500
- return {
501
- content: `Deleted credential for ${service}/${field}.`,
502
- isError: false,
503
- };
504
- }
505
-
506
- case "prompt": {
507
- const service = input.service as string | undefined;
508
- const field = input.field as string | undefined;
509
-
510
- if (!service || typeof service !== "string") {
511
- return {
512
- content: "Error: service is required for prompt action",
513
- isError: true,
514
- };
515
- }
516
- if (!field || typeof field !== "string") {
517
- return {
518
- content: "Error: field is required for prompt action",
519
- isError: true,
520
- };
521
- }
522
-
523
- if (!context.requestSecret) {
524
- return {
525
- content: "Error: secret prompting not available in this context",
526
- isError: true,
527
- };
528
- }
529
-
530
- const label = (input.label as string) || `${service} ${field}`;
531
- const description = input.description as string | undefined;
532
- const placeholder = input.placeholder as string | undefined;
533
-
534
- const promptPolicyInput: CredentialPolicyInput = {
535
- allowed_tools: input.allowed_tools as string[] | undefined,
536
- allowed_domains: input.allowed_domains as string[] | undefined,
537
- usage_description: input.usage_description as string | undefined,
538
- };
539
- const promptPolicyResult = validatePolicyInput(promptPolicyInput);
540
- if (!promptPolicyResult.valid) {
541
- return {
542
- content: `Error: ${promptPolicyResult.errors.join("; ")}`,
543
- isError: true,
544
- };
545
- }
546
- const promptPolicy = toPolicyFromInput(promptPolicyInput);
547
-
548
- // Parse and validate injection templates (same logic as store action)
549
- const promptRawTemplates = input.injection_templates as
550
- | unknown[]
551
- | undefined;
552
- let promptInjectionTemplates: CredentialInjectionTemplate[] | undefined;
553
- if (promptRawTemplates !== undefined) {
554
- if (!Array.isArray(promptRawTemplates)) {
555
- return {
556
- content: "Error: injection_templates must be an array",
557
- isError: true,
558
- };
559
- }
560
- const promptTemplateErrors: string[] = [];
561
- promptInjectionTemplates = [];
562
- for (let i = 0; i < promptRawTemplates.length; i++) {
563
- const t = promptRawTemplates[i] as Record<string, unknown>;
564
- if (typeof t !== "object" || t == null) {
565
- promptTemplateErrors.push(
566
- `injection_templates[${i}] must be an object`,
567
- );
568
- continue;
569
- }
570
- if (
571
- typeof t.hostPattern !== "string" ||
572
- t.hostPattern.trim().length === 0
573
- ) {
574
- promptTemplateErrors.push(
575
- `injection_templates[${i}].hostPattern must be a non-empty string`,
576
- );
577
- }
578
- if (t.injectionType !== "header" && t.injectionType !== "query") {
579
- promptTemplateErrors.push(
580
- `injection_templates[${i}].injectionType must be 'header' or 'query'`,
581
- );
582
- } else if (t.injectionType === "header") {
583
- if (
584
- typeof t.headerName !== "string" ||
585
- t.headerName.trim().length === 0
586
- ) {
587
- promptTemplateErrors.push(
588
- `injection_templates[${i}].headerName is required when injectionType is 'header'`,
589
- );
590
- }
591
- } else if (t.injectionType === "query") {
592
- if (
593
- typeof t.queryParamName !== "string" ||
594
- t.queryParamName.trim().length === 0
595
- ) {
596
- promptTemplateErrors.push(
597
- `injection_templates[${i}].queryParamName is required when injectionType is 'query'`,
598
- );
599
- }
600
- }
601
- if (
602
- t.valuePrefix !== undefined &&
603
- typeof t.valuePrefix !== "string"
604
- ) {
605
- promptTemplateErrors.push(
606
- `injection_templates[${i}].valuePrefix must be a string`,
607
- );
608
- }
609
- if (promptTemplateErrors.length === 0) {
610
- promptInjectionTemplates.push({
611
- hostPattern: t.hostPattern as string,
612
- injectionType: t.injectionType as "header" | "query",
613
- headerName:
614
- typeof t.headerName === "string" ? t.headerName : undefined,
615
- valuePrefix:
616
- typeof t.valuePrefix === "string" ? t.valuePrefix : undefined,
617
- queryParamName:
618
- typeof t.queryParamName === "string"
619
- ? t.queryParamName
620
- : undefined,
621
- });
622
- }
623
- }
624
- if (promptTemplateErrors.length > 0) {
625
- return {
626
- content: `Error: ${promptTemplateErrors.join("; ")}`,
627
- isError: true,
628
- };
629
- }
630
- }
631
-
632
- try {
633
- assertMetadataWritable();
634
- } catch {
635
- return {
636
- content:
637
- "Error: credential metadata file has an unrecognized version; cannot store credentials",
638
- isError: true,
639
- };
640
- }
641
-
642
- const result = await context.requestSecret({
643
- service,
644
- field,
645
- label,
646
- description,
647
- placeholder,
648
- purpose: promptPolicy.usageDescription,
649
- allowedTools:
650
- promptPolicy.allowedTools.length > 0
651
- ? promptPolicy.allowedTools
652
- : undefined,
653
- allowedDomains:
654
- promptPolicy.allowedDomains.length > 0
655
- ? promptPolicy.allowedDomains
656
- : undefined,
657
- });
658
- if (!result.value) {
659
- if (result.error === "unsupported_channel") {
660
- return {
661
- content:
662
- "Secure credential entry cannot be opened over this channel. The user needs to complete this step from the desktop app, or run this flow from there directly.",
663
- isError: true,
664
- };
665
- }
666
- return {
667
- content: "User cancelled the credential prompt.",
668
- isError: false,
669
- };
670
- }
671
-
672
- const persisted = await persistPromptedCredential({
673
- service,
674
- field,
675
- value: result.value,
676
- delivery: result.delivery,
677
- policy: {
678
- allowedTools: promptPolicyInput.allowed_tools,
679
- allowedDomains: promptPolicyInput.allowed_domains,
680
- usageDescription: promptPolicy.usageDescription,
681
- injectionTemplates: promptInjectionTemplates,
682
- },
683
- });
684
- if (persisted.outcome === "error") {
685
- return { content: `Error: ${persisted.message}`, isError: true };
686
- }
687
- if (persisted.outcome === "transient") {
688
- return {
689
- content: `One-time credential provided for ${service}/${field}. The value was NOT saved to the vault and will be consumed by the next operation.`,
690
- isError: false,
691
- };
692
- }
693
- const promptMeta = getCredentialMetadata(service, field);
694
- const promptCredIdSuffix = promptMeta
695
- ? ` (credential_id: ${promptMeta.credentialId})`
696
- : "";
697
- const promptRetrieveHint = ` Retrieve with: \`assistant credentials reveal --service ${service} --field ${field}\``;
698
- return {
699
- content: `Credential stored for ${service}/${field}.${promptCredIdSuffix}${promptRetrieveHint}${
700
- persisted.slackChannel
701
- ? formatSlackChannelStatus(persisted.slackChannel)
702
- : ""
703
- }`,
704
- isError: false,
705
- };
706
- }
707
-
708
- default:
709
- return { content: `Error: unknown action "${action}"`, isError: true };
710
- }
711
- },
712
- } satisfies ToolDefinition;