@vellumai/assistant 0.4.56 → 0.4.57

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 (450) hide show
  1. package/ARCHITECTURE.md +10 -10
  2. package/Dockerfile +3 -0
  3. package/README.md +11 -11
  4. package/docs/architecture/integrations.md +2 -2
  5. package/docs/architecture/memory.md +3 -4
  6. package/docs/credential-execution-service.md +13 -20
  7. package/node_modules/@vellumai/ces-contracts/src/error.ts +5 -4
  8. package/package.json +1 -1
  9. package/src/__tests__/actor-token-service.test.ts +7 -7
  10. package/src/__tests__/anthropic-provider.test.ts +172 -0
  11. package/src/__tests__/app-builder-tool-scripts.test.ts +15 -1
  12. package/src/__tests__/approval-cascade.test.ts +2 -2
  13. package/src/__tests__/approval-routes-http.test.ts +3 -4
  14. package/src/__tests__/asset-materialize-tool.test.ts +5 -5
  15. package/src/__tests__/asset-search-tool.test.ts +1 -1
  16. package/src/__tests__/assistant-attachments.test.ts +5 -5
  17. package/src/__tests__/assistant-events-sse-hardening.test.ts +1 -1
  18. package/src/__tests__/assistant-feature-flags-integration.test.ts +50 -38
  19. package/src/__tests__/attachments-store.test.ts +2 -2
  20. package/src/__tests__/avatar-e2e.test.ts +5 -3
  21. package/src/__tests__/browser-skill-endstate.test.ts +0 -1
  22. package/src/__tests__/call-routes-http.test.ts +2 -2
  23. package/src/__tests__/callback-handoff-copy.test.ts +1 -1
  24. package/src/__tests__/cancel-resolves-conversation-key.test.ts +158 -0
  25. package/src/__tests__/channel-readiness-routes.test.ts +0 -1
  26. package/src/__tests__/channel-readiness-service.test.ts +0 -1
  27. package/src/__tests__/checker.test.ts +31 -32
  28. package/src/__tests__/chrome-cdp.test.ts +47 -18
  29. package/src/__tests__/claude-code-skill-regression.test.ts +2 -2
  30. package/src/__tests__/config-schema-cmd.test.ts +2 -2
  31. package/src/__tests__/config-schema.test.ts +9 -18
  32. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +1 -1
  33. package/src/__tests__/conversation-abort-tool-results.test.ts +4 -4
  34. package/src/__tests__/conversation-agent-loop-overflow.test.ts +2 -2
  35. package/src/__tests__/conversation-agent-loop.test.ts +11 -4
  36. package/src/__tests__/conversation-attachments.test.ts +1 -1
  37. package/src/__tests__/conversation-confirmation-signals.test.ts +2 -2
  38. package/src/__tests__/conversation-error.test.ts +33 -0
  39. package/src/__tests__/conversation-init.benchmark.test.ts +0 -1
  40. package/src/__tests__/conversation-load-history-repair.test.ts +1 -1
  41. package/src/__tests__/conversation-pairing.test.ts +1 -1
  42. package/src/__tests__/conversation-pre-run-repair.test.ts +4 -4
  43. package/src/__tests__/conversation-provider-retry-repair.test.ts +4 -4
  44. package/src/__tests__/conversation-queue.test.ts +23 -14
  45. package/src/__tests__/conversation-routes-slash-commands.test.ts +3 -3
  46. package/src/__tests__/conversation-runtime-assembly.test.ts +185 -173
  47. package/src/__tests__/conversation-seed-composer.test.ts +1 -1
  48. package/src/__tests__/conversation-slash-queue.test.ts +4 -4
  49. package/src/__tests__/conversation-slash-unknown.test.ts +4 -4
  50. package/src/__tests__/conversation-starter-routes.test.ts +291 -0
  51. package/src/__tests__/conversation-wipe.test.ts +438 -0
  52. package/src/__tests__/conversation-workspace-cache-state.test.ts +2 -3
  53. package/src/__tests__/conversation-workspace-injection.test.ts +4 -5
  54. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +4 -5
  55. package/src/__tests__/credential-security-e2e.test.ts +20 -0
  56. package/src/__tests__/credential-security-invariants.test.ts +1 -0
  57. package/src/__tests__/credential-vault-unit.test.ts +227 -0
  58. package/src/__tests__/credentials-cli.test.ts +3 -0
  59. package/src/__tests__/date-context.test.ts +59 -377
  60. package/src/__tests__/drop-capability-card-state-migration.test.ts +169 -0
  61. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +11 -45
  62. package/src/__tests__/emit-signal-routing-intent.test.ts +3 -3
  63. package/src/__tests__/encrypted-store.test.ts +237 -15
  64. package/src/__tests__/ephemeral-permissions.test.ts +4 -5
  65. package/src/__tests__/event-bus.test.ts +3 -3
  66. package/src/__tests__/gateway-only-enforcement.test.ts +2 -2
  67. package/src/__tests__/gateway-only-guard.test.ts +1 -0
  68. package/src/__tests__/gemini-image-service.test.ts +4 -4
  69. package/src/__tests__/gemini-provider.test.ts +6 -9
  70. package/src/__tests__/guardian-binding-drift-heal.test.ts +128 -0
  71. package/src/__tests__/guardian-dispatch.test.ts +0 -1
  72. package/src/__tests__/host-shell-tool.test.ts +6 -6
  73. package/src/__tests__/http-user-message-parity.test.ts +2 -2
  74. package/src/__tests__/intent-routing.test.ts +51 -99
  75. package/src/__tests__/invite-routes-http.test.ts +5 -0
  76. package/src/__tests__/list-messages-attachments.test.ts +1 -1
  77. package/src/__tests__/managed-proxy-context.test.ts +2 -5
  78. package/src/__tests__/managed-skill-lifecycle.test.ts +8 -8
  79. package/src/__tests__/media-generate-image.test.ts +32 -15
  80. package/src/__tests__/media-reuse-story.e2e.test.ts +1 -1
  81. package/src/__tests__/memory-context-benchmark.benchmark.test.ts +1 -1
  82. package/src/__tests__/memory-lifecycle-e2e.test.ts +24 -18
  83. package/src/__tests__/memory-recall-quality.test.ts +4 -3
  84. package/src/__tests__/memory-regressions.test.ts +86 -90
  85. package/src/__tests__/migration-cross-version-compatibility.test.ts +32 -32
  86. package/src/__tests__/migration-export-http.test.ts +26 -27
  87. package/src/__tests__/migration-import-commit-http.test.ts +165 -37
  88. package/src/__tests__/migration-import-preflight-http.test.ts +81 -20
  89. package/src/__tests__/migration-validate-http.test.ts +16 -16
  90. package/src/__tests__/model-intents.test.ts +1 -1
  91. package/src/__tests__/no-domain-routing-in-prompt-guard.test.ts +1 -1
  92. package/src/__tests__/notification-broadcaster.test.ts +1 -1
  93. package/src/__tests__/notification-decision-fallback.test.ts +2 -2
  94. package/src/__tests__/notification-decision-identity.test.ts +8 -9
  95. package/src/__tests__/notification-decision-strategy.test.ts +1 -1
  96. package/src/__tests__/notification-deep-link.test.ts +1 -1
  97. package/src/__tests__/notification-guardian-path.test.ts +0 -1
  98. package/src/__tests__/notification-schedule-dedup.test.ts +7 -7
  99. package/src/__tests__/oauth-store.test.ts +1 -3
  100. package/src/__tests__/oauth2-gateway-transport.test.ts +6 -1
  101. package/src/__tests__/onboarding-template-contract.test.ts +23 -59
  102. package/src/__tests__/provider-error-scenarios.test.ts +154 -0
  103. package/src/__tests__/provider-fail-open-selection.test.ts +2 -2
  104. package/src/__tests__/provider-managed-proxy-integration.test.ts +8 -9
  105. package/src/__tests__/provider-registry-ollama.test.ts +5 -2
  106. package/src/__tests__/qdrant-manager.test.ts +7 -7
  107. package/src/__tests__/ratelimit.test.ts +0 -74
  108. package/src/__tests__/recording-handler.test.ts +0 -1
  109. package/src/__tests__/require-fresh-approval.test.ts +1 -1
  110. package/src/__tests__/runtime-attachment-metadata.test.ts +1 -1
  111. package/src/__tests__/runtime-events-sse-parity.test.ts +1 -1
  112. package/src/__tests__/runtime-events-sse.test.ts +1 -1
  113. package/src/__tests__/scheduler-recurrence.test.ts +46 -2
  114. package/src/__tests__/schema-transforms.test.ts +114 -54
  115. package/src/__tests__/secret-onetime-send.test.ts +20 -0
  116. package/src/__tests__/secret-routes-managed-proxy.test.ts +5 -2
  117. package/src/__tests__/secret-scanner-executor.test.ts +1 -2
  118. package/src/__tests__/send-endpoint-busy.test.ts +63 -4
  119. package/src/__tests__/send-notification-tool.test.ts +2 -2
  120. package/src/__tests__/shell-credential-ref.test.ts +0 -1
  121. package/src/__tests__/shell-tool-proxy-mode.test.ts +1 -2
  122. package/src/__tests__/skill-memory.test.ts +547 -0
  123. package/src/__tests__/skill-script-runner-sandbox.test.ts +1 -2
  124. package/src/__tests__/slack-app-setup-skill-regression.test.ts +37 -0
  125. package/src/__tests__/slack-channel-config.test.ts +109 -94
  126. package/src/__tests__/swarm-conversation-integration.test.ts +2 -2
  127. package/src/__tests__/swarm-recursion.test.ts +2 -2
  128. package/src/__tests__/swarm-tool.test.ts +2 -2
  129. package/src/__tests__/system-prompt.test.ts +19 -66
  130. package/src/__tests__/telegram-config.test.ts +121 -0
  131. package/src/__tests__/terminal-tools.test.ts +1 -1
  132. package/src/__tests__/tool-execution-abort-cleanup.test.ts +1 -2
  133. package/src/__tests__/tool-executor-lifecycle-events.test.ts +1 -1
  134. package/src/__tests__/tool-executor-shell-integration.test.ts +1 -1
  135. package/src/__tests__/tool-executor.test.ts +1 -1
  136. package/src/__tests__/trace-emitter.test.ts +8 -1
  137. package/src/__tests__/trust-store.test.ts +7 -8
  138. package/src/__tests__/twilio-routes.test.ts +1 -18
  139. package/src/__tests__/user-reference.test.ts +82 -2
  140. package/src/__tests__/vbundle-pax-and-symlink.test.ts +196 -0
  141. package/src/__tests__/verification-control-plane-policy.test.ts +1 -1
  142. package/src/approvals/guardian-request-resolvers.ts +3 -3
  143. package/src/avatar/ascii-renderer.ts +2 -2
  144. package/src/avatar/png-renderer.ts +2 -2
  145. package/src/avatar/resvg-lazy.ts +21 -0
  146. package/src/calls/guardian-dispatch.ts +1 -1
  147. package/src/calls/relay-access-wait.ts +2 -2
  148. package/src/calls/twilio-rest.ts +0 -248
  149. package/src/cli/AGENTS.md +5 -8
  150. package/src/cli/__tests__/notifications.test.ts +5 -5
  151. package/src/cli/commands/avatar.ts +64 -2
  152. package/src/cli/commands/conversations.ts +131 -1
  153. package/src/cli/commands/credentials.ts +2 -0
  154. package/src/cli/commands/notifications.ts +3 -3
  155. package/src/cli.ts +10 -0
  156. package/src/config/bundled-skills/acp/SKILL.md +5 -5
  157. package/src/config/bundled-skills/acp/TOOLS.json +6 -6
  158. package/src/config/bundled-skills/app-builder/SKILL.md +42 -42
  159. package/src/config/bundled-skills/app-builder/TOOLS.json +10 -10
  160. package/src/config/bundled-skills/browser/SKILL.md +15 -15
  161. package/src/config/bundled-skills/browser/TOOLS.json +14 -14
  162. package/src/config/bundled-skills/chatgpt-import/SKILL.md +2 -2
  163. package/src/config/bundled-skills/chatgpt-import/TOOLS.json +1 -1
  164. package/src/config/bundled-skills/chatgpt-import/tools/chatgpt-import.ts +1 -1
  165. package/src/config/bundled-skills/claude-code/SKILL.md +5 -5
  166. package/src/config/bundled-skills/computer-use/SKILL.md +2 -2
  167. package/src/config/bundled-skills/computer-use/TOOLS.json +15 -15
  168. package/src/config/bundled-skills/contacts/SKILL.md +3 -3
  169. package/src/config/bundled-skills/contacts/TOOLS.json +4 -4
  170. package/src/config/bundled-skills/document/SKILL.md +4 -4
  171. package/src/config/bundled-skills/document/TOOLS.json +2 -2
  172. package/src/config/bundled-skills/followups/TOOLS.json +3 -3
  173. package/src/config/bundled-skills/gmail/SKILL.md +32 -32
  174. package/src/config/bundled-skills/gmail/TOOLS.json +16 -16
  175. package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +1 -1
  176. package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +1 -1
  177. package/src/config/bundled-skills/google-calendar/SKILL.md +1 -1
  178. package/src/config/bundled-skills/google-calendar/TOOLS.json +5 -5
  179. package/src/config/bundled-skills/google-calendar/types.ts +1 -1
  180. package/src/config/bundled-skills/heartbeat/SKILL.md +43 -0
  181. package/src/config/bundled-skills/image-studio/SKILL.md +3 -3
  182. package/src/config/bundled-skills/image-studio/TOOLS.json +2 -3
  183. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +16 -12
  184. package/src/config/bundled-skills/media-processing/SKILL.md +40 -40
  185. package/src/config/bundled-skills/media-processing/TOOLS.json +8 -8
  186. package/src/config/bundled-skills/media-processing/__tests__/concurrency-pool.test.ts +2 -2
  187. package/src/config/bundled-skills/media-processing/__tests__/preprocess.test.ts +1 -1
  188. package/src/config/bundled-skills/media-processing/services/gemini-map.ts +5 -5
  189. package/src/config/bundled-skills/media-processing/services/gemini-video.ts +2 -2
  190. package/src/config/bundled-skills/media-processing/services/preprocess.ts +2 -2
  191. package/src/config/bundled-skills/media-processing/services/processing-pipeline.ts +2 -2
  192. package/src/config/bundled-skills/media-processing/services/reduce.ts +3 -3
  193. package/src/config/bundled-skills/media-processing/tools/generate-clip.ts +2 -2
  194. package/src/config/bundled-skills/media-processing/tools/query-media-events.ts +1 -1
  195. package/src/config/bundled-skills/messaging/SKILL.md +29 -25
  196. package/src/config/bundled-skills/messaging/TOOLS.json +11 -11
  197. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +1 -1
  198. package/src/config/bundled-skills/messaging/tools/shared.ts +1 -1
  199. package/src/config/bundled-skills/notifications/SKILL.md +3 -3
  200. package/src/config/bundled-skills/notifications/TOOLS.json +2 -2
  201. package/src/config/bundled-skills/notifications/tools/send-notification.ts +3 -3
  202. package/src/config/bundled-skills/orchestration/SKILL.md +1 -1
  203. package/src/config/bundled-skills/orchestration/TOOLS.json +1 -1
  204. package/src/config/bundled-skills/phone-calls/SKILL.md +18 -14
  205. package/src/config/bundled-skills/phone-calls/TOOLS.json +3 -3
  206. package/src/config/bundled-skills/phone-calls/references/CONFIG.md +2 -2
  207. package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +2 -2
  208. package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +1 -1
  209. package/src/config/bundled-skills/playbooks/TOOLS.json +4 -4
  210. package/src/config/bundled-skills/schedule/SKILL.md +26 -26
  211. package/src/config/bundled-skills/schedule/TOOLS.json +5 -5
  212. package/src/config/bundled-skills/screen-watch/SKILL.md +3 -3
  213. package/src/config/bundled-skills/screen-watch/TOOLS.json +1 -1
  214. package/src/config/bundled-skills/sequences/SKILL.md +2 -2
  215. package/src/config/bundled-skills/sequences/TOOLS.json +10 -10
  216. package/src/config/bundled-skills/sequences/tools/sequence-analytics.ts +2 -2
  217. package/src/config/bundled-skills/sequences/tools/sequence-enroll.ts +2 -2
  218. package/src/config/bundled-skills/sequences/tools/sequence-enrollment-list.ts +1 -1
  219. package/src/config/bundled-skills/sequences/tools/sequence-get.ts +1 -1
  220. package/src/config/bundled-skills/sequences/tools/sequence-import.ts +3 -3
  221. package/src/config/bundled-skills/sequences/tools/sequence-list.ts +1 -1
  222. package/src/config/bundled-skills/sequences/tools/sequence-update.ts +1 -1
  223. package/src/config/bundled-skills/settings/TOOLS.json +3 -3
  224. package/src/config/bundled-skills/settings/tools/open-system-settings.ts +1 -1
  225. package/src/config/bundled-skills/skill-management/TOOLS.json +5 -5
  226. package/src/config/bundled-skills/skills-catalog/SKILL.md +84 -0
  227. package/src/config/bundled-skills/slack/SKILL.md +2 -2
  228. package/src/config/bundled-skills/slack/TOOLS.json +8 -8
  229. package/src/config/bundled-skills/slack/tools/slack-scan-digest.ts +3 -3
  230. package/src/config/bundled-skills/subagent/TOOLS.json +5 -5
  231. package/src/config/bundled-skills/tasks/SKILL.md +1 -1
  232. package/src/config/bundled-skills/tasks/TOOLS.json +9 -9
  233. package/src/config/bundled-skills/transcribe/SKILL.md +5 -5
  234. package/src/config/bundled-skills/transcribe/TOOLS.json +1 -1
  235. package/src/config/bundled-skills/transcribe/tools/transcribe-media.ts +10 -10
  236. package/src/config/bundled-skills/watcher/SKILL.md +4 -4
  237. package/src/config/bundled-skills/watcher/TOOLS.json +5 -5
  238. package/src/config/feature-flag-registry.json +33 -17
  239. package/src/config/schemas/sandbox.ts +1 -1
  240. package/src/config/schemas/services.ts +13 -3
  241. package/src/config/schemas/timeouts.ts +0 -10
  242. package/src/contacts/contact-store.ts +63 -0
  243. package/src/contacts/contacts-write.ts +1 -1
  244. package/src/daemon/assistant-attachments.ts +2 -2
  245. package/src/daemon/conversation-agent-loop-handlers.ts +2 -2
  246. package/src/daemon/conversation-agent-loop.ts +7 -30
  247. package/src/daemon/conversation-error.ts +24 -0
  248. package/src/daemon/conversation-memory.ts +8 -7
  249. package/src/daemon/conversation-runtime-assembly.ts +139 -274
  250. package/src/daemon/conversation-slash.ts +7 -26
  251. package/src/daemon/conversation-surfaces.ts +14 -0
  252. package/src/daemon/conversation-tool-setup.ts +9 -8
  253. package/src/daemon/conversation.ts +2 -0
  254. package/src/daemon/daemon-control.ts +1 -1
  255. package/src/daemon/date-context.ts +10 -83
  256. package/src/daemon/handlers/config-channels.ts +12 -2
  257. package/src/daemon/handlers/config-slack-channel.ts +7 -1
  258. package/src/daemon/handlers/config-telegram.ts +6 -1
  259. package/src/daemon/handlers/conversations.ts +2 -2
  260. package/src/daemon/handlers/skills.ts +4 -0
  261. package/src/daemon/lifecycle.ts +28 -4
  262. package/src/daemon/providers-setup.ts +1 -1
  263. package/src/daemon/server.ts +1 -5
  264. package/src/daemon/shutdown-handlers.ts +9 -3
  265. package/src/daemon/tool-side-effects.ts +40 -0
  266. package/src/daemon/trace-emitter.ts +25 -2
  267. package/src/events/domain-events.ts +1 -1
  268. package/src/events/tool-permission-telemetry-listener.ts +46 -0
  269. package/src/inbound/platform-callback-registration.ts +0 -18
  270. package/src/media/app-icon-generator.ts +15 -8
  271. package/src/media/avatar-router.ts +15 -8
  272. package/src/media/gemini-image-service.ts +125 -21
  273. package/src/memory/attachments-store.ts +3 -3
  274. package/src/memory/channel-verification-sessions.ts +6 -6
  275. package/src/memory/conversation-crud.ts +196 -1
  276. package/src/memory/{thread-starters-cadence.ts → conversation-starters-cadence.ts} +9 -42
  277. package/src/memory/conversation-title-service.ts +2 -3
  278. package/src/memory/db-init.ts +25 -1
  279. package/src/memory/invite-store.ts +4 -4
  280. package/src/memory/items-extractor.ts +4 -4
  281. package/src/memory/job-handlers/{thread-starters.ts → conversation-starters.ts} +123 -38
  282. package/src/memory/jobs-store.ts +3 -2
  283. package/src/memory/jobs-worker.ts +7 -5
  284. package/src/memory/lifecycle-events-store.ts +63 -0
  285. package/src/memory/migrations/172-rename-created-by-session-id.ts +27 -0
  286. package/src/memory/migrations/173-rename-source-session-id.ts +16 -0
  287. package/src/memory/migrations/174-rename-thread-starters-table.ts +52 -0
  288. package/src/memory/migrations/175-create-lifecycle-events.ts +15 -0
  289. package/src/memory/migrations/176-drop-capability-card-state.ts +36 -0
  290. package/src/memory/migrations/177-create-trace-events-table.ts +40 -0
  291. package/src/memory/migrations/index.ts +6 -0
  292. package/src/memory/migrations/registry.ts +13 -0
  293. package/src/memory/retriever.test.ts +223 -96
  294. package/src/memory/retriever.ts +115 -138
  295. package/src/memory/schema/calls.ts +1 -1
  296. package/src/memory/schema/contacts.ts +1 -1
  297. package/src/memory/schema/infrastructure.ts +29 -0
  298. package/src/memory/schema/memory-core.ts +7 -17
  299. package/src/memory/schema/notifications.ts +1 -1
  300. package/src/memory/search/formatting.ts +23 -6
  301. package/src/memory/search/lexical.ts +2 -0
  302. package/src/memory/search/semantic.ts +2 -0
  303. package/src/memory/search/staleness.ts +1 -0
  304. package/src/memory/search/types.ts +4 -0
  305. package/src/memory/task-memory-cleanup.ts +96 -6
  306. package/src/memory/trace-event-store.ts +148 -0
  307. package/src/notifications/README.md +1 -1
  308. package/src/notifications/decision-engine.ts +2 -2
  309. package/src/notifications/emit-signal.ts +4 -4
  310. package/src/notifications/events-store.ts +4 -4
  311. package/src/notifications/signal.ts +1 -1
  312. package/src/oauth/manual-token-connection.ts +49 -25
  313. package/src/permissions/checker.ts +6 -5
  314. package/src/permissions/defaults.ts +4 -4
  315. package/src/prompts/__tests__/build-cli-reference-section.test.ts +9 -90
  316. package/src/prompts/cache-boundary.ts +8 -0
  317. package/src/prompts/system-prompt.ts +105 -634
  318. package/src/prompts/templates/BOOTSTRAP.md +166 -33
  319. package/src/prompts/templates/IDENTITY.md +8 -23
  320. package/src/prompts/templates/SOUL.md +20 -41
  321. package/src/prompts/templates/USER.md +3 -19
  322. package/src/prompts/user-reference.ts +14 -16
  323. package/src/providers/anthropic/client.ts +46 -2
  324. package/src/providers/gemini/client.ts +6 -9
  325. package/src/providers/managed-proxy/constants.ts +1 -7
  326. package/src/providers/managed-proxy/context.ts +0 -1
  327. package/src/providers/model-intents.ts +5 -5
  328. package/src/providers/openai/client.ts +10 -1
  329. package/src/providers/openrouter/client.ts +1 -0
  330. package/src/providers/ratelimit.ts +0 -35
  331. package/src/providers/registry.ts +3 -5
  332. package/src/providers/retry.ts +18 -1
  333. package/src/runtime/access-request-helper.ts +1 -1
  334. package/src/runtime/auth/route-policy.ts +7 -0
  335. package/src/runtime/channel-verification-service.ts +1 -1
  336. package/src/runtime/confirmation-request-guardian-bridge.ts +1 -1
  337. package/src/runtime/guardian-vellum-migration.ts +63 -1
  338. package/src/runtime/http-server.ts +8 -4
  339. package/src/runtime/migrations/vbundle-builder.ts +212 -32
  340. package/src/runtime/migrations/vbundle-import-analyzer.ts +74 -8
  341. package/src/runtime/migrations/vbundle-importer.ts +66 -1
  342. package/src/runtime/migrations/vbundle-validator.ts +17 -3
  343. package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +4 -4
  344. package/src/runtime/routes/attachment-routes.ts +2 -2
  345. package/src/runtime/routes/btw-routes.ts +9 -0
  346. package/src/runtime/routes/channel-verification-routes.ts +19 -2
  347. package/src/runtime/routes/conversation-management-routes.ts +55 -1
  348. package/src/runtime/routes/conversation-query-routes.ts +1 -1
  349. package/src/runtime/routes/conversation-routes.ts +49 -5
  350. package/src/runtime/routes/conversation-starter-routes.ts +207 -0
  351. package/src/runtime/routes/guardian-bootstrap-routes.ts +13 -9
  352. package/src/runtime/routes/inbound-stages/escalation-intercept.ts +1 -1
  353. package/src/runtime/routes/inbound-stages/verification-intercept.ts +1 -1
  354. package/src/runtime/routes/migration-routes.ts +25 -13
  355. package/src/runtime/routes/secret-routes.ts +18 -0
  356. package/src/runtime/routes/settings-routes.ts +8 -8
  357. package/src/runtime/routes/telemetry-routes.ts +53 -0
  358. package/src/runtime/routes/trace-event-routes.ts +62 -0
  359. package/src/runtime/tool-grant-request-helper.ts +1 -1
  360. package/src/runtime/verification-outbound-actions.ts +47 -31
  361. package/src/security/encrypted-store.ts +263 -78
  362. package/src/skills/catalog-install.ts +10 -0
  363. package/src/skills/managed-store.ts +2 -0
  364. package/src/skills/skill-memory.ts +220 -0
  365. package/src/subagent/manager.ts +1 -4
  366. package/src/telemetry/types.ts +10 -1
  367. package/src/telemetry/usage-telemetry-reporter.test.ts +1 -1
  368. package/src/telemetry/usage-telemetry-reporter.ts +51 -4
  369. package/src/tools/AGENTS.md +11 -11
  370. package/src/tools/acp/spawn.ts +1 -1
  371. package/src/tools/apps/executors.ts +8 -8
  372. package/src/tools/apps/registry.ts +1 -1
  373. package/src/tools/assets/materialize.ts +6 -6
  374. package/src/tools/assets/search.ts +10 -10
  375. package/src/tools/browser/__tests__/auth-cache.test.ts +2 -2
  376. package/src/tools/browser/__tests__/auth-detector.test.ts +4 -4
  377. package/src/tools/browser/auth-detector.ts +6 -6
  378. package/src/tools/browser/browser-execution.ts +13 -13
  379. package/src/tools/browser/browser-manager.ts +3 -3
  380. package/src/tools/browser/chrome-cdp.ts +5 -5
  381. package/src/tools/browser/jit-auth.ts +2 -2
  382. package/src/tools/browser/network-recorder.test.ts +2 -2
  383. package/src/tools/browser/network-recorder.ts +3 -3
  384. package/src/tools/browser/runtime-check.ts +3 -3
  385. package/src/tools/claude-code/claude-code.ts +2 -2
  386. package/src/tools/computer-use/definitions.ts +18 -18
  387. package/src/tools/credential-execution/make-authenticated-request.ts +4 -4
  388. package/src/tools/credential-execution/manage-secure-command-tool.ts +3 -3
  389. package/src/tools/credential-execution/run-authenticated-command.ts +4 -4
  390. package/src/tools/credentials/broker-types.ts +5 -5
  391. package/src/tools/credentials/broker.ts +15 -15
  392. package/src/tools/credentials/metadata-store.ts +2 -2
  393. package/src/tools/credentials/resolve.ts +1 -1
  394. package/src/tools/credentials/selection.ts +1 -1
  395. package/src/tools/credentials/tool-policy.ts +1 -1
  396. package/src/tools/credentials/vault.ts +115 -25
  397. package/src/tools/execution-target.ts +2 -2
  398. package/src/tools/executor.ts +7 -7
  399. package/src/tools/filesystem/edit.ts +2 -2
  400. package/src/tools/filesystem/read.ts +1 -1
  401. package/src/tools/filesystem/write.ts +1 -1
  402. package/src/tools/host-filesystem/edit.ts +2 -1
  403. package/src/tools/host-filesystem/read.ts +2 -1
  404. package/src/tools/host-filesystem/write.ts +1 -1
  405. package/src/tools/host-terminal/host-shell.ts +9 -8
  406. package/src/tools/mcp/mcp-tool-factory.ts +7 -6
  407. package/src/tools/memory/definitions.ts +6 -5
  408. package/src/tools/memory/handlers.test.ts +1 -1
  409. package/src/tools/network/__tests__/web-search.test.ts +3 -3
  410. package/src/tools/network/domain-normalize.ts +2 -2
  411. package/src/tools/network/script-proxy/session-manager.ts +10 -10
  412. package/src/tools/network/web-fetch.ts +1 -1
  413. package/src/tools/network/web-search.ts +3 -3
  414. package/src/tools/permission-checker.ts +8 -8
  415. package/src/tools/registry.ts +7 -7
  416. package/src/tools/schedule/list.ts +2 -2
  417. package/src/tools/schema-transforms.ts +31 -21
  418. package/src/tools/secret-detection-handler.ts +1 -1
  419. package/src/tools/sensitive-output-placeholders.ts +1 -1
  420. package/src/tools/shared/filesystem/edit-engine.ts +1 -1
  421. package/src/tools/shared/filesystem/file-ops-service.ts +3 -3
  422. package/src/tools/shared/filesystem/image-read.ts +25 -5
  423. package/src/tools/shared/filesystem/path-policy.ts +2 -2
  424. package/src/tools/shared/shell-output.ts +1 -1
  425. package/src/tools/side-effects.ts +1 -1
  426. package/src/tools/skills/execute.ts +1 -1
  427. package/src/tools/skills/load.ts +3 -3
  428. package/src/tools/skills/sandbox-runner.ts +3 -3
  429. package/src/tools/subagent/read.ts +1 -1
  430. package/src/tools/subagent/spawn.ts +2 -2
  431. package/src/tools/swarm/delegate.ts +3 -3
  432. package/src/tools/system/request-permission.ts +5 -4
  433. package/src/tools/terminal/backends/native.ts +4 -4
  434. package/src/tools/terminal/parser.ts +6 -6
  435. package/src/tools/terminal/sandbox-diagnostics.ts +1 -1
  436. package/src/tools/terminal/shell.ts +16 -16
  437. package/src/tools/tool-approval-handler.ts +21 -12
  438. package/src/tools/tool-manifest.ts +4 -4
  439. package/src/tools/types.ts +3 -3
  440. package/src/tools/ui-surface/definitions.ts +9 -37
  441. package/src/tools/watcher/list.ts +1 -1
  442. package/src/util/logger.ts +7 -2
  443. package/src/util/retry.ts +29 -1
  444. package/src/workspace/migrations/007-web-search-provider-rename.ts +37 -0
  445. package/src/workspace/migrations/registry.ts +2 -0
  446. package/src/__tests__/cli-help-reference-sync.test.ts +0 -26
  447. package/src/__tests__/onboarding-starter-tasks.test.ts +0 -190
  448. package/src/cli/reference.ts +0 -38
  449. package/src/memory/job-handlers/capability-cards.ts +0 -420
  450. package/src/runtime/routes/thread-starter-routes.ts +0 -294
@@ -58,7 +58,7 @@ mock.module("../config/loader.js", () => ({
58
58
  model: "test",
59
59
  provider: "test",
60
60
  memory: { enabled: false },
61
- rateLimit: { maxRequestsPerMinute: 0, maxTokensPerSession: 0 },
61
+ rateLimit: { maxRequestsPerMinute: 0 },
62
62
  secretDetection: { enabled: false },
63
63
  calls: {
64
64
  enabled: true,
@@ -80,7 +80,7 @@ mock.module("../config/loader.js", () => ({
80
80
  model: "test",
81
81
  provider: "test",
82
82
  memory: { enabled: false },
83
- rateLimit: { maxRequestsPerMinute: 0, maxTokensPerSession: 0 },
83
+ rateLimit: { maxRequestsPerMinute: 0 },
84
84
  secretDetection: { enabled: false },
85
85
  ingress: {
86
86
  publicBaseUrl: "https://test.example.com",
@@ -22,6 +22,7 @@ const ALLOWLIST = new Set([
22
22
  // Matched by prefix check below: gateway/
23
23
 
24
24
  // --- Intentional local daemon-control paths ---
25
+ "assistant/src/cli/commands/conversations.ts", // CLI wipe talks to runtime directly
25
26
  "clients/shared/Network/DaemonClient.swift",
26
27
  "clients/macos/vellum-assistant/App/AppDelegate.swift",
27
28
  "clients/macos/vellum-assistant/Features/Settings/SettingsConnectTab.swift",
@@ -111,7 +111,7 @@ describe("generateImage", () => {
111
111
  expect(result.images).toHaveLength(1);
112
112
  expect(result.images[0].mimeType).toBe("image/png");
113
113
  expect(result.images[0].dataBase64).toBe("abc123");
114
- expect(result.resolvedModel).toBe("gemini-2.5-flash-image");
114
+ expect(result.resolvedModel).toBe("gemini-3.1-flash-image-preview");
115
115
  });
116
116
 
117
117
  test("generate mode collects text commentary from response", async () => {
@@ -168,7 +168,7 @@ describe("generateImage", () => {
168
168
 
169
169
  expect(lastGenerateParams).not.toBeNull();
170
170
  expect((lastGenerateParams as Record<string, unknown>).model).toBe(
171
- "gemini-2.5-flash-image",
171
+ "gemini-3.1-flash-image-preview",
172
172
  );
173
173
  });
174
174
 
@@ -180,12 +180,12 @@ describe("generateImage", () => {
180
180
  {
181
181
  prompt: "test",
182
182
  mode: "generate",
183
- model: "gemini-3-pro-image",
183
+ model: "gemini-3-pro-image-preview",
184
184
  },
185
185
  );
186
186
 
187
187
  expect((lastGenerateParams as Record<string, unknown>).model).toBe(
188
- "gemini-3-pro-image",
188
+ "gemini-3-pro-image-preview",
189
189
  );
190
190
  });
191
191
 
@@ -739,17 +739,14 @@ describe("GeminiProvider", () => {
739
739
  expect(lastConstructorOpts).toEqual({ apiKey: "test-key" });
740
740
  });
741
741
 
742
- test("sets vertexai mode with httpOptions.baseUrl when managedBaseUrl is provided", () => {
742
+ test("sets httpOptions.baseUrl when managedBaseUrl is provided", () => {
743
743
  new GeminiProvider("managed-key", "gemini-3-flash", {
744
- managedBaseUrl: "https://platform.example.com/v1/runtime-proxy/vertex",
744
+ managedBaseUrl: "https://platform.example.com/v1/runtime-proxy/gemini",
745
745
  });
746
746
  expect(lastConstructorOpts).toEqual({
747
- vertexai: true,
748
- project: "proxy",
749
- location: "us-central1",
747
+ apiKey: "managed-key",
750
748
  httpOptions: {
751
- baseUrl: "https://platform.example.com/v1/runtime-proxy/vertex",
752
- headers: { Authorization: "Bearer managed-key" },
749
+ baseUrl: "https://platform.example.com/v1/runtime-proxy/gemini",
753
750
  },
754
751
  });
755
752
  });
@@ -759,7 +756,7 @@ describe("GeminiProvider", () => {
759
756
  "managed-key",
760
757
  "gemini-3-flash",
761
758
  {
762
- managedBaseUrl: "https://platform.example.com/v1/runtime-proxy/vertex",
759
+ managedBaseUrl: "https://platform.example.com/v1/runtime-proxy/gemini",
763
760
  },
764
761
  );
765
762
 
@@ -784,7 +781,7 @@ describe("GeminiProvider", () => {
784
781
  "managed-key",
785
782
  "gemini-3-flash",
786
783
  {
787
- managedBaseUrl: "https://platform.example.com/v1/runtime-proxy/vertex",
784
+ managedBaseUrl: "https://platform.example.com/v1/runtime-proxy/gemini",
788
785
  },
789
786
  );
790
787
 
@@ -0,0 +1,128 @@
1
+ import { mkdtempSync, rmSync } from "node:fs";
2
+ import { tmpdir } from "node:os";
3
+ import { join } from "node:path";
4
+ import { afterAll, beforeEach, describe, expect, mock, test } from "bun:test";
5
+
6
+ const testDir = mkdtempSync(
7
+ join(tmpdir(), "guardian-binding-drift-heal-test-"),
8
+ );
9
+
10
+ mock.module("../util/platform.js", () => ({
11
+ getDataDir: () => testDir,
12
+ isMacOS: () => process.platform === "darwin",
13
+ isLinux: () => process.platform === "linux",
14
+ isWindows: () => process.platform === "win32",
15
+ getPidPath: () => join(testDir, "test.pid"),
16
+ getDbPath: () => join(testDir, "test.db"),
17
+ getLogPath: () => join(testDir, "test.log"),
18
+ ensureDataDir: () => {},
19
+ }));
20
+
21
+ mock.module("../util/logger.js", () => ({
22
+ getLogger: () =>
23
+ new Proxy({} as Record<string, unknown>, {
24
+ get: () => () => {},
25
+ }),
26
+ }));
27
+
28
+ import { findGuardianForChannel } from "../contacts/contact-store.js";
29
+ import { createGuardianBinding } from "../contacts/contacts-write.js";
30
+ import { getDb, initializeDb, resetDb } from "../memory/db.js";
31
+ import { healGuardianBindingDrift } from "../runtime/guardian-vellum-migration.js";
32
+
33
+ initializeDb();
34
+
35
+ function resetTables(): void {
36
+ const db = getDb();
37
+ db.run("DELETE FROM contact_channels");
38
+ db.run("DELETE FROM contacts");
39
+ }
40
+
41
+ describe("healGuardianBindingDrift", () => {
42
+ beforeEach(() => {
43
+ resetTables();
44
+ });
45
+
46
+ afterAll(() => {
47
+ resetDb();
48
+ try {
49
+ rmSync(testDir, { recursive: true });
50
+ } catch {
51
+ // best-effort cleanup
52
+ }
53
+ });
54
+
55
+ test("heals drift when both principals have vellum-principal- prefix", () => {
56
+ // Simulate DB reset: new guardian binding with a different UUID
57
+ createGuardianBinding({
58
+ channel: "vellum",
59
+ guardianExternalUserId: "vellum-principal-new-uuid",
60
+ guardianDeliveryChatId: "local",
61
+ guardianPrincipalId: "vellum-principal-new-uuid",
62
+ verifiedVia: "startup-migration",
63
+ });
64
+
65
+ // Client arrives with the old JWT principal
66
+ const healed = healGuardianBindingDrift("vellum-principal-old-uuid");
67
+ expect(healed).toBe(true);
68
+
69
+ // Guardian binding now matches the old JWT
70
+ const guardian = findGuardianForChannel("vellum");
71
+ expect(guardian).not.toBeNull();
72
+ expect(guardian!.contact.principalId).toBe("vellum-principal-old-uuid");
73
+ expect(guardian!.channel.externalUserId).toBe("vellum-principal-old-uuid");
74
+ });
75
+
76
+ test("no-op when principals already match", () => {
77
+ createGuardianBinding({
78
+ channel: "vellum",
79
+ guardianExternalUserId: "vellum-principal-same",
80
+ guardianDeliveryChatId: "local",
81
+ guardianPrincipalId: "vellum-principal-same",
82
+ verifiedVia: "startup-migration",
83
+ });
84
+
85
+ const healed = healGuardianBindingDrift("vellum-principal-same");
86
+ expect(healed).toBe(false);
87
+ });
88
+
89
+ test("refuses to heal when incoming principal lacks vellum-principal- prefix", () => {
90
+ createGuardianBinding({
91
+ channel: "vellum",
92
+ guardianExternalUserId: "vellum-principal-aaa",
93
+ guardianDeliveryChatId: "local",
94
+ guardianPrincipalId: "vellum-principal-aaa",
95
+ verifiedVia: "startup-migration",
96
+ });
97
+
98
+ // External/platform principal — should NOT be adopted
99
+ const healed = healGuardianBindingDrift("platform-user-12345");
100
+ expect(healed).toBe(false);
101
+
102
+ // Guardian unchanged
103
+ const guardian = findGuardianForChannel("vellum");
104
+ expect(guardian!.contact.principalId).toBe("vellum-principal-aaa");
105
+ });
106
+
107
+ test("refuses to heal when stored principal lacks vellum-principal- prefix", () => {
108
+ createGuardianBinding({
109
+ channel: "vellum",
110
+ guardianExternalUserId: "verified-phone-guardian",
111
+ guardianDeliveryChatId: "local",
112
+ guardianPrincipalId: "verified-phone-guardian",
113
+ verifiedVia: "challenge",
114
+ });
115
+
116
+ // Even with a vellum-principal- incoming, don't overwrite a real binding
117
+ const healed = healGuardianBindingDrift("vellum-principal-attacker");
118
+ expect(healed).toBe(false);
119
+
120
+ const guardian = findGuardianForChannel("vellum");
121
+ expect(guardian!.contact.principalId).toBe("verified-phone-guardian");
122
+ });
123
+
124
+ test("returns false when no guardian binding exists", () => {
125
+ const healed = healGuardianBindingDrift("vellum-principal-orphan");
126
+ expect(healed).toBe(false);
127
+ });
128
+ });
@@ -195,7 +195,6 @@ describe("guardian-dispatch", () => {
195
195
  expect(vellumDelivery!.destination_conversation_id).toBe("conv-vellum-1");
196
196
 
197
197
  const signalParams = emitCalls[0] as Record<string, unknown>;
198
- expect(signalParams.skipVellumThread).toBeUndefined();
199
198
  expect(typeof signalParams.onConversationCreated).toBe("function");
200
199
  });
201
200
 
@@ -29,14 +29,14 @@ const mockConfig = {
29
29
  shellMaxTimeoutSec: 600,
30
30
  permissionTimeoutSec: 300,
31
31
  },
32
- sandbox: { enabled: true },
33
- rateLimit: { maxRequestsPerMinute: 0, maxTokensPerSession: 0 },
32
+ rateLimit: { maxRequestsPerMinute: 0 },
34
33
  secretDetection: {
35
34
  enabled: true,
36
35
  action: "warn" as const,
37
36
  entropyThreshold: 4.0,
38
37
  },
39
38
  auditLog: { retentionDays: 0 },
39
+ sandbox: { enabled: true },
40
40
  };
41
41
 
42
42
  // Track whether wrapCommand was ever called — host_bash must never invoke it
@@ -283,11 +283,11 @@ describe("host_bash — regression: no proxied-mode additions", () => {
283
283
  expect(schemaProps).not.toHaveProperty("credential_ids");
284
284
  });
285
285
 
286
- test("schema only contains the expected properties (command, working_dir, timeout_seconds, reason)", () => {
286
+ test("schema only contains the expected properties (command, working_dir, timeout_seconds, activity)", () => {
287
287
  const propertyNames = Object.keys(schemaProps).sort();
288
288
  expect(propertyNames).toEqual([
289
+ "activity",
289
290
  "command",
290
- "reason",
291
291
  "timeout_seconds",
292
292
  "working_dir",
293
293
  ]);
@@ -348,10 +348,10 @@ describe("host_bash — regression: no proxied-mode additions", () => {
348
348
  expect(definition.name).toBe("host_bash");
349
349
  });
350
350
 
351
- test("required fields contains command and reason", () => {
351
+ test("required fields contains command and activity", () => {
352
352
  expect(
353
353
  (definition.input_schema as Record<string, unknown>).required,
354
- ).toEqual(["command", "reason"]);
354
+ ).toEqual(["command", "activity"]);
355
355
  });
356
356
  });
357
357
 
@@ -142,9 +142,9 @@ mock.module("../config/loader.js", () => ({
142
142
  "image-generation": {
143
143
  mode: "your-own",
144
144
  provider: "gemini",
145
- model: "gemini-2.5-flash-image",
145
+ model: "gemini-3.1-flash-image-preview",
146
146
  },
147
- "web-search": { mode: "your-own", provider: "anthropic-native" },
147
+ "web-search": { mode: "your-own", provider: "inference-provider-native" },
148
148
  },
149
149
  }),
150
150
  }));
@@ -54,7 +54,6 @@ mock.module("../config/loader.js", () => ({
54
54
  getConfig: () => ({
55
55
  ui: {},
56
56
 
57
- sandbox: { enabled: false, backend: "local" },
58
57
  assistantFeatureFlagValues: {},
59
58
  services: {
60
59
  inference: {
@@ -65,9 +64,9 @@ mock.module("../config/loader.js", () => ({
65
64
  "image-generation": {
66
65
  mode: "your-own",
67
66
  provider: "gemini",
68
- model: "gemini-2.5-flash-image",
67
+ model: "gemini-3.1-flash-image-preview",
69
68
  },
70
- "web-search": { mode: "your-own", provider: "anthropic-native" },
69
+ "web-search": { mode: "your-own", provider: "inference-provider-native" },
71
70
  },
72
71
  }),
73
72
  loadConfig: () => ({}),
@@ -105,11 +104,25 @@ const scheduleCreateDef = scheduleToolsJson.tools.find(
105
104
  (t: { name: string }) => t.name === "schedule_create",
106
105
  );
107
106
 
107
+ // Load send_notification description from the bundled skill TOOLS.json
108
+ const notifToolsJson = JSON.parse(
109
+ readFileSync(
110
+ join(
111
+ import.meta.dirname,
112
+ "../config/bundled-skills/notifications/TOOLS.json",
113
+ ),
114
+ "utf-8",
115
+ ),
116
+ );
117
+ const sendNotificationDef = notifToolsJson.tools.find(
118
+ (t: { name: string }) => t.name === "send_notification",
119
+ );
120
+
108
121
  // =====================================================================
109
- // 1. System prompt: buildTaskScheduleReminderRoutingSection
122
+ // 1. Routing section removed from system prompt — guidance in tool descriptions
110
123
  // =====================================================================
111
124
 
112
- describe("Task/Schedule routing section in system prompt", () => {
125
+ describe("Task/Schedule routing NOT in system prompt (moved to tool descriptions)", () => {
113
126
  beforeEach(() => {
114
127
  mkdirSync(TEST_DIR, { recursive: true });
115
128
  });
@@ -120,55 +133,12 @@ describe("Task/Schedule routing section in system prompt", () => {
120
133
  }
121
134
  });
122
135
 
123
- test("system prompt includes the routing section heading", () => {
136
+ test("system prompt does not contain the old routing section", () => {
124
137
  const prompt = buildSystemPrompt();
125
- expect(prompt).toContain(
138
+ expect(prompt).not.toContain(
126
139
  "## Tool Routing: Tasks vs Schedules vs Notifications",
127
140
  );
128
141
  });
129
-
130
- test("routing section lists all three tools in the summary table", () => {
131
- const prompt = buildSystemPrompt();
132
- expect(prompt).toContain("`task_list_add`");
133
- expect(prompt).toContain("`schedule_create`");
134
- expect(prompt).toContain("`send_notification`");
135
- });
136
-
137
- test("routing section warns that send_notification is immediate-only", () => {
138
- const prompt = buildSystemPrompt();
139
- expect(prompt).toContain("send_notification` is immediate-only");
140
- expect(prompt).toContain("fires NOW");
141
- });
142
-
143
- test("routing section includes quick routing rules", () => {
144
- const prompt = buildSystemPrompt();
145
- expect(prompt).toContain("Quick routing rules");
146
- expect(prompt).toContain("Future time, one-shot");
147
- expect(prompt).toContain("Recurring pattern");
148
- expect(prompt).toContain("No time, track as work");
149
- });
150
-
151
- test("routing section documents entity type routing", () => {
152
- const prompt = buildSystemPrompt();
153
- expect(prompt).toContain(
154
- "Entity type routing: work items vs task templates",
155
- );
156
- expect(prompt).toContain("**Work items**");
157
- expect(prompt).toContain("**Task templates**");
158
- });
159
-
160
- test("routing section references the Time-Based Actions skill", () => {
161
- const prompt = buildSystemPrompt();
162
- expect(prompt).toContain("Time-Based Actions");
163
- });
164
-
165
- test("routing section is present in the system prompt", () => {
166
- const prompt = buildSystemPrompt();
167
- const taskRoutingIdx = prompt.indexOf(
168
- "## Tool Routing: Tasks vs Schedules vs Notifications",
169
- );
170
- expect(taskRoutingIdx).toBeGreaterThanOrEqual(0);
171
- });
172
142
  });
173
143
 
174
144
  // =====================================================================
@@ -228,6 +198,18 @@ describe("schedule_create tool description", () => {
228
198
  });
229
199
  });
230
200
 
201
+ describe("send_notification tool description", () => {
202
+ test("states it fires immediately with no delay", () => {
203
+ expect(sendNotificationDef).toBeDefined();
204
+ expect(sendNotificationDef.description).toContain("immediate");
205
+ expect(sendNotificationDef.description).toContain("no delay");
206
+ });
207
+
208
+ test("redirects to schedule_create for future alerts", () => {
209
+ expect(sendNotificationDef.description).toContain("schedule_create");
210
+ });
211
+ });
212
+
231
213
  // =====================================================================
232
214
  // 3. Cross-tool consistency: schedule and task tools agree on routing boundaries
233
215
  // =====================================================================
@@ -244,10 +226,10 @@ describe("cross-tool routing consistency", () => {
244
226
  });
245
227
 
246
228
  // =====================================================================
247
- // 4. Activation hints in <available_skills> XML (replaces domain routing sections)
229
+ // 4. Activation hints in skills catalog (replaces domain routing sections)
248
230
  // =====================================================================
249
231
 
250
- describe("Activation hints in available_skills XML", () => {
232
+ describe("Activation hints in skills catalog", () => {
251
233
  beforeEach(() => {
252
234
  mkdirSync(TEST_DIR, { recursive: true });
253
235
  });
@@ -258,61 +240,31 @@ describe("Activation hints in available_skills XML", () => {
258
240
  }
259
241
  });
260
242
 
261
- test("available_skills XML does NOT contain location attribute", () => {
243
+ test("phone-calls skill includes hints and avoid-when in catalog line", () => {
262
244
  const prompt = buildSystemPrompt();
263
- const start = prompt.indexOf("<available_skills>");
264
- const end = prompt.indexOf("</available_skills>");
265
- expect(start).not.toBe(-1);
266
- expect(end).not.toBe(-1);
267
- const skillsXml = prompt.substring(start, end);
268
- expect(skillsXml).not.toContain("location=");
245
+ const line = prompt.split("\n").find((l) => l.includes("**phone-calls**"));
246
+ expect(line).toBeDefined();
247
+ // Activation hints and avoid-when are folded into the description
248
+ expect(line).toContain("Twilio");
249
+ expect(line).toContain("Avoid: ");
250
+ expect(line).toContain("voice-setup");
269
251
  });
270
252
 
271
- test("phone-calls bundled skill has hints and avoid-when attributes in XML", () => {
253
+ test("orchestration skill includes hints and avoid-when in catalog line", () => {
272
254
  const prompt = buildSystemPrompt();
273
- const start = prompt.indexOf("<available_skills>");
274
- const end = prompt.indexOf("</available_skills>");
275
- expect(start).not.toBe(-1);
276
- expect(end).not.toBe(-1);
277
- const skillsXml = prompt.substring(start, end);
278
- expect(skillsXml).toContain('id="phone-calls"');
279
- const skillLine = skillsXml
255
+ const line = prompt
280
256
  .split("\n")
281
- .find((l) => l.includes('id="phone-calls"'));
282
- expect(skillLine).toBeDefined();
283
- expect(skillLine).toContain("hints=");
284
- expect(skillLine).toContain("avoid-when=");
257
+ .find((l) => l.includes("**orchestration**"));
258
+ expect(line).toBeDefined();
259
+ expect(line).toContain("parallel");
260
+ expect(line).toContain("Single-focus");
285
261
  });
286
262
 
287
- test("orchestration bundled skill has hints and avoid-when attributes in XML", () => {
263
+ test("browser skill includes hints in catalog line", () => {
288
264
  const prompt = buildSystemPrompt();
289
- const start = prompt.indexOf("<available_skills>");
290
- const end = prompt.indexOf("</available_skills>");
291
- expect(start).not.toBe(-1);
292
- expect(end).not.toBe(-1);
293
- const skillsXml = prompt.substring(start, end);
294
- expect(skillsXml).toContain('id="orchestration"');
295
- const skillLine = skillsXml
296
- .split("\n")
297
- .find((l) => l.includes('id="orchestration"'));
298
- expect(skillLine).toBeDefined();
299
- expect(skillLine).toContain("hints=");
300
- expect(skillLine).toContain("avoid-when=");
301
- });
302
-
303
- test("browser bundled skill has hints attribute in XML", () => {
304
- const prompt = buildSystemPrompt();
305
- const start = prompt.indexOf("<available_skills>");
306
- const end = prompt.indexOf("</available_skills>");
307
- expect(start).not.toBe(-1);
308
- expect(end).not.toBe(-1);
309
- const skillsXml = prompt.substring(start, end);
310
- expect(skillsXml).toContain('id="browser"');
311
- const skillLine = skillsXml
312
- .split("\n")
313
- .find((l) => l.includes('id="browser"'));
314
- expect(skillLine).toBeDefined();
315
- expect(skillLine).toContain("hints=");
265
+ const line = prompt.split("\n").find((l) => l.includes("**browser**"));
266
+ expect(line).toBeDefined();
267
+ expect(line).toContain("browser_*");
316
268
  });
317
269
 
318
270
  test("domain routing sections are no longer in system prompt", () => {
@@ -38,6 +38,11 @@ mock.module("../telegram/bot-username.js", () => ({
38
38
  getTelegramBotUsername: () => mockTelegramBotUsername,
39
39
  }));
40
40
 
41
+ // Mock invite instruction generator — skip LLM calls in tests.
42
+ mock.module("../runtime/invite-instruction-generator.js", () => ({
43
+ generateInviteInstruction: async () => "Mock invite instruction for testing.",
44
+ }));
45
+
41
46
  // Mock startInviteCall from call-domain — test env lacks Twilio credentials.
42
47
  let mockStartInviteCallResult:
43
48
  | { ok: true; callSid: string }
@@ -39,7 +39,7 @@ mock.module("../config/loader.js", () => ({
39
39
  model: "test",
40
40
  provider: "test",
41
41
  memory: { enabled: false },
42
- rateLimit: { maxRequestsPerMinute: 0, maxTokensPerSession: 0 },
42
+ rateLimit: { maxRequestsPerMinute: 0 },
43
43
  }),
44
44
  }));
45
45
 
@@ -110,10 +110,7 @@ describe("buildManagedBaseUrl", () => {
110
110
  "https://platform.example.com/v1/runtime-proxy/anthropic",
111
111
  );
112
112
  expect(await buildManagedBaseUrl("gemini")).toBe(
113
- "https://platform.example.com/v1/runtime-proxy/vertex",
114
- );
115
- expect(await buildManagedBaseUrl("vertex")).toBe(
116
- "https://platform.example.com/v1/runtime-proxy/vertex",
113
+ "https://platform.example.com/v1/runtime-proxy/gemini",
117
114
  );
118
115
  });
119
116
 
@@ -132,7 +129,7 @@ describe("buildManagedBaseUrl", () => {
132
129
  mockPlatformBaseUrl = "";
133
130
  mockAssistantApiKey = null;
134
131
  expect(await buildManagedBaseUrl("anthropic")).toBeUndefined();
135
- expect(await buildManagedBaseUrl("vertex")).toBeUndefined();
132
+ expect(await buildManagedBaseUrl("gemini")).toBeUndefined();
136
133
  });
137
134
  });
138
135
 
@@ -16,8 +16,7 @@ const mockConfig = {
16
16
  shellMaxTimeoutSec: 600,
17
17
  permissionTimeoutSec: 300,
18
18
  },
19
- sandbox: { enabled: false },
20
- rateLimit: { maxRequestsPerMinute: 0, maxTokensPerSession: 0 },
19
+ rateLimit: { maxRequestsPerMinute: 0 },
21
20
  secretDetection: {
22
21
  enabled: true,
23
22
  action: "warn" as const,
@@ -33,9 +32,9 @@ const mockConfig = {
33
32
  "image-generation": {
34
33
  mode: "your-own",
35
34
  provider: "gemini",
36
- model: "gemini-2.5-flash-image",
35
+ model: "gemini-3.1-flash-image-preview",
37
36
  },
38
- "web-search": { mode: "your-own", provider: "anthropic-native" },
37
+ "web-search": { mode: "your-own", provider: "inference-provider-native" },
39
38
  },
40
39
  };
41
40
 
@@ -138,11 +137,12 @@ describe("managed skill lifecycle: scaffold → catalog → prompt → delete",
138
137
  expect(found!.name).toBe("Lifecycle Test");
139
138
  expect(found!.description).toBe("Integration test skill.");
140
139
 
141
- // Step 4: Verify skill appears in system prompt
140
+ // Step 4: Verify skill appears in system prompt (markdown bullet: **id**: description)
142
141
  const prompt = buildSystemPrompt();
143
- expect(prompt).toContain("lifecycle-test");
144
- expect(prompt).toContain("Lifecycle Test");
145
- expect(prompt).toContain("## Dynamic Skill Authoring Workflow");
142
+ expect(prompt).toContain("**lifecycle-test**");
143
+ expect(prompt).toContain("Integration test skill");
144
+ // Dynamic Skill Authoring section moved to tool descriptions; prompt should not contain it
145
+ expect(prompt).not.toContain("## Dynamic Skill Authoring Workflow");
146
146
 
147
147
  // Step 5: Delete the skill
148
148
  const deleteResult = await executeDeleteManagedSkill(