@vellumai/assistant 0.3.4 → 0.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (506) hide show
  1. package/Dockerfile +2 -0
  2. package/README.md +88 -2
  3. package/eslint.config.mjs +31 -0
  4. package/package.json +1 -1
  5. package/scripts/ipc/check-swift-decoder-drift.ts +4 -1
  6. package/scripts/ipc/generate-swift.ts +31 -2
  7. package/src/__tests__/__snapshots__/ipc-snapshot.test.ts.snap +438 -1
  8. package/src/__tests__/approval-conversation-turn.test.ts +214 -0
  9. package/src/__tests__/approval-hardcoded-copy-guard.test.ts +41 -0
  10. package/src/__tests__/approval-message-composer.test.ts +253 -0
  11. package/src/__tests__/browser-manager.test.ts +1 -0
  12. package/src/__tests__/call-conversation-messages.test.ts +130 -0
  13. package/src/__tests__/call-domain.test.ts +12 -2
  14. package/src/__tests__/call-orchestrator.test.ts +799 -249
  15. package/src/__tests__/call-pointer-messages.test.ts +148 -0
  16. package/src/__tests__/call-recovery.test.ts +3 -0
  17. package/src/__tests__/call-routes-http.test.ts +32 -2
  18. package/src/__tests__/call-store.test.ts +3 -0
  19. package/src/__tests__/channel-approval-routes.test.ts +1277 -98
  20. package/src/__tests__/channel-approval.test.ts +37 -0
  21. package/src/__tests__/channel-approvals.test.ts +36 -50
  22. package/src/__tests__/channel-guardian.test.ts +630 -22
  23. package/src/__tests__/channel-readiness-service.test.ts +324 -0
  24. package/src/__tests__/checker.test.ts +14 -7
  25. package/src/__tests__/clarification-resolver.test.ts +44 -24
  26. package/src/__tests__/commit-message-enrichment-service.test.ts +9 -4
  27. package/src/__tests__/computer-use-session-working-dir.test.ts +8 -0
  28. package/src/__tests__/config-schema.test.ts +14 -8
  29. package/src/__tests__/context-window-manager.test.ts +30 -2
  30. package/src/__tests__/contradiction-checker.test.ts +20 -5
  31. package/src/__tests__/credential-security-invariants.test.ts +7 -2
  32. package/src/__tests__/daemon-lifecycle.test.ts +13 -12
  33. package/src/__tests__/db-migration-rollback.test.ts +752 -0
  34. package/src/__tests__/dictation-mode-detection.test.ts +63 -0
  35. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +2 -0
  36. package/src/__tests__/entity-search.test.ts +615 -0
  37. package/src/__tests__/fuzzy-match-property.test.ts +5 -5
  38. package/src/__tests__/guardian-action-store.test.ts +123 -0
  39. package/src/__tests__/guardian-action-sweep.test.ts +277 -0
  40. package/src/__tests__/guardian-dispatch.test.ts +389 -0
  41. package/src/__tests__/guardian-question-copy.test.ts +47 -0
  42. package/src/__tests__/handlers-telegram-config.test.ts +4 -2
  43. package/src/__tests__/handlers-twilio-config.test.ts +533 -0
  44. package/src/__tests__/intent-routing.test.ts +2 -0
  45. package/src/__tests__/ipc-snapshot.test.ts +291 -1
  46. package/src/__tests__/memory-upsert-concurrency.test.ts +828 -0
  47. package/src/__tests__/messaging-send-tool.test.ts +65 -0
  48. package/src/__tests__/model-intents.test.ts +96 -0
  49. package/src/__tests__/no-direct-anthropic-sdk-imports.test.ts +42 -0
  50. package/src/__tests__/oauth2-gateway-transport.test.ts +130 -0
  51. package/src/__tests__/onboarding-starter-tasks.test.ts +2 -0
  52. package/src/__tests__/provider-commit-message-generator.test.ts +89 -13
  53. package/src/__tests__/provider-error-scenarios.test.ts +621 -0
  54. package/src/__tests__/provider-fail-open-selection.test.ts +119 -0
  55. package/src/__tests__/qdrant-manager.test.ts +27 -20
  56. package/src/__tests__/relay-server.test.ts +779 -40
  57. package/src/__tests__/run-orchestrator-assistant-events.test.ts +6 -0
  58. package/src/__tests__/run-orchestrator.test.ts +42 -4
  59. package/src/__tests__/runtime-runs-http.test.ts +17 -1
  60. package/src/__tests__/runtime-runs.test.ts +16 -0
  61. package/src/__tests__/schedule-store.test.ts +18 -4
  62. package/src/__tests__/scheduler-recurrence.test.ts +13 -4
  63. package/src/__tests__/session-abort-tool-results.test.ts +6 -0
  64. package/src/__tests__/session-agent-loop.test.ts +857 -0
  65. package/src/__tests__/session-conflict-gate.test.ts +6 -0
  66. package/src/__tests__/session-pre-run-repair.test.ts +6 -0
  67. package/src/__tests__/session-profile-injection.test.ts +6 -0
  68. package/src/__tests__/session-provider-retry-repair.test.ts +6 -0
  69. package/src/__tests__/session-queue.test.ts +6 -0
  70. package/src/__tests__/session-runtime-assembly.test.ts +321 -13
  71. package/src/__tests__/session-slash-known.test.ts +6 -0
  72. package/src/__tests__/session-slash-queue.test.ts +6 -0
  73. package/src/__tests__/session-slash-unknown.test.ts +6 -0
  74. package/src/__tests__/session-surfaces-task-progress.test.ts +2 -0
  75. package/src/__tests__/session-tool-setup-app-refresh.test.ts +1 -0
  76. package/src/__tests__/session-tool-setup-memory-scope.test.ts +1 -0
  77. package/src/__tests__/session-tool-setup-side-effect-flag.test.ts +1 -0
  78. package/src/__tests__/session-workspace-injection.test.ts +6 -0
  79. package/src/__tests__/session-workspace-tool-tracking.test.ts +6 -0
  80. package/src/__tests__/skills.test.ts +2 -0
  81. package/src/__tests__/sms-messaging-provider.test.ts +126 -0
  82. package/src/__tests__/starter-task-flow.test.ts +2 -0
  83. package/src/__tests__/swarm-dag-pathological.test.ts +535 -0
  84. package/src/__tests__/system-prompt.test.ts +2 -0
  85. package/src/__tests__/task-management-tools.test.ts +2 -2
  86. package/src/__tests__/task-runner.test.ts +14 -4
  87. package/src/__tests__/terminal-tools.test.ts +25 -19
  88. package/src/__tests__/tool-execution-abort-cleanup.test.ts +545 -0
  89. package/src/__tests__/tool-executor-shell-integration.test.ts +11 -11
  90. package/src/__tests__/tool-executor.test.ts +23 -24
  91. package/src/__tests__/trust-store.test.ts +3 -3
  92. package/src/__tests__/twilio-rest.test.ts +29 -0
  93. package/src/__tests__/twilio-routes-elevenlabs.test.ts +3 -0
  94. package/src/__tests__/twilio-routes-twiml.test.ts +11 -0
  95. package/src/__tests__/twilio-routes.test.ts +167 -11
  96. package/src/__tests__/twitter-cli-error-shaping.test.ts +2 -2
  97. package/src/__tests__/user-reference.test.ts +2 -0
  98. package/src/__tests__/voice-quality.test.ts +222 -0
  99. package/src/__tests__/web-search.test.ts +46 -30
  100. package/src/__tests__/work-item-output.test.ts +110 -0
  101. package/src/agent/loop.ts +1 -1
  102. package/src/agent-heartbeat/agent-heartbeat-service.ts +2 -10
  103. package/src/amazon/client.ts +1418 -0
  104. package/src/amazon/request-extractor.ts +135 -0
  105. package/src/amazon/session.ts +109 -0
  106. package/src/autonomy/autonomy-store.ts +5 -5
  107. package/src/browser-extension-relay/client.ts +124 -0
  108. package/src/browser-extension-relay/protocol.ts +63 -0
  109. package/src/browser-extension-relay/server.ts +177 -0
  110. package/src/bundler/app-bundler.ts +3 -3
  111. package/src/bundler/bundle-signer.ts +1 -1
  112. package/src/bundler/signature-verifier.ts +1 -1
  113. package/src/calls/call-conversation-messages.ts +33 -0
  114. package/src/calls/call-domain.ts +114 -10
  115. package/src/calls/call-orchestrator.ts +268 -59
  116. package/src/calls/call-pointer-messages.ts +53 -0
  117. package/src/calls/call-recovery.ts +3 -8
  118. package/src/calls/call-store.ts +69 -87
  119. package/src/calls/elevenlabs-config.ts +3 -2
  120. package/src/calls/guardian-action-sweep.ts +105 -0
  121. package/src/calls/guardian-dispatch.ts +203 -0
  122. package/src/calls/guardian-question-copy.ts +133 -0
  123. package/src/calls/relay-server.ts +466 -8
  124. package/src/calls/speaker-identification.ts +1 -1
  125. package/src/calls/twilio-config.ts +22 -14
  126. package/src/calls/twilio-provider.ts +6 -4
  127. package/src/calls/twilio-rest.ts +308 -7
  128. package/src/calls/twilio-routes.ts +65 -12
  129. package/src/calls/types.ts +3 -1
  130. package/src/channels/types.ts +25 -0
  131. package/src/cli/amazon.ts +815 -0
  132. package/src/cli/config-commands.ts +2 -2
  133. package/src/cli/core-commands.ts +4 -3
  134. package/src/cli/influencer.ts +244 -0
  135. package/src/cli/map.ts +89 -6
  136. package/src/cli.ts +1 -1
  137. package/src/config/agent-schema.ts +171 -0
  138. package/src/config/bundled-skills/amazon/SKILL.md +127 -0
  139. package/src/config/bundled-skills/amazon/icon.svg +13 -0
  140. package/src/config/bundled-skills/api-mapping/SKILL.md +78 -0
  141. package/src/config/bundled-skills/browser/SKILL.md +1 -0
  142. package/src/config/bundled-skills/browser/TOOLS.json +17 -0
  143. package/src/config/bundled-skills/browser/tools/browser-wait-for-download.ts +25 -0
  144. package/src/config/bundled-skills/doordash/SKILL.md +51 -51
  145. package/src/config/bundled-skills/email-setup/SKILL.md +14 -5
  146. package/src/config/bundled-skills/google-oauth-setup/SKILL.md +183 -0
  147. package/src/config/bundled-skills/influencer/SKILL.md +144 -0
  148. package/src/config/bundled-skills/knowledge-graph/SKILL.md +15 -0
  149. package/src/config/bundled-skills/knowledge-graph/TOOLS.json +56 -0
  150. package/src/config/bundled-skills/knowledge-graph/tools/graph-query.ts +185 -0
  151. package/src/config/bundled-skills/macos-automation/icon.svg +12 -0
  152. package/src/config/bundled-skills/media-processing/SKILL.md +176 -0
  153. package/src/config/bundled-skills/media-processing/TOOLS.json +230 -0
  154. package/src/config/bundled-skills/media-processing/__tests__/concurrency-pool.test.ts +77 -0
  155. package/src/config/bundled-skills/media-processing/__tests__/cost-tracker.test.ts +69 -0
  156. package/src/config/bundled-skills/media-processing/__tests__/preprocess.test.ts +303 -0
  157. package/src/config/bundled-skills/media-processing/services/concurrency-pool.ts +55 -0
  158. package/src/config/bundled-skills/media-processing/services/cost-tracker.ts +86 -0
  159. package/src/config/bundled-skills/media-processing/services/gemini-map.ts +339 -0
  160. package/src/config/bundled-skills/media-processing/services/preprocess.ts +551 -0
  161. package/src/config/bundled-skills/media-processing/services/processing-pipeline.ts +259 -0
  162. package/src/config/bundled-skills/media-processing/services/reduce.ts +197 -0
  163. package/src/config/bundled-skills/media-processing/tools/analyze-keyframes.ts +136 -0
  164. package/src/config/bundled-skills/media-processing/tools/extract-keyframes.ts +59 -0
  165. package/src/config/bundled-skills/media-processing/tools/generate-clip.ts +195 -0
  166. package/src/config/bundled-skills/media-processing/tools/ingest-media.ts +197 -0
  167. package/src/config/bundled-skills/media-processing/tools/media-diagnostics.ts +143 -0
  168. package/src/config/bundled-skills/media-processing/tools/media-status.ts +75 -0
  169. package/src/config/bundled-skills/media-processing/tools/query-media-events.ts +65 -0
  170. package/src/config/bundled-skills/messaging/SKILL.md +33 -8
  171. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +4 -7
  172. package/src/config/bundled-skills/messaging/tools/messaging-reply.ts +2 -1
  173. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +5 -1
  174. package/src/config/bundled-skills/phone-calls/SKILL.md +88 -23
  175. package/src/config/bundled-skills/twitter/SKILL.md +19 -3
  176. package/src/config/bundled-skills/twitter/icon.svg +14 -0
  177. package/src/config/bundled-tool-registry.ts +310 -0
  178. package/src/config/calls-schema.ts +181 -0
  179. package/src/config/core-schema.ts +309 -0
  180. package/src/config/defaults.ts +28 -3
  181. package/src/config/env-registry.ts +162 -0
  182. package/src/config/env.ts +175 -0
  183. package/src/config/loader.ts +6 -6
  184. package/src/config/memory-schema.ts +528 -0
  185. package/src/config/sandbox-schema.ts +55 -0
  186. package/src/config/schema.ts +158 -1133
  187. package/src/config/skill-state.ts +1 -1
  188. package/src/config/skills-schema.ts +32 -0
  189. package/src/config/skills.ts +35 -24
  190. package/src/config/system-prompt.ts +131 -56
  191. package/src/config/templates/IDENTITY.md +2 -2
  192. package/src/config/templates/SOUL.md +1 -1
  193. package/src/config/types.ts +1 -0
  194. package/src/config/user-reference.ts +4 -9
  195. package/src/config/vellum-skills/catalog.json +6 -7
  196. package/src/config/vellum-skills/chatgpt-import/tools/chatgpt-import.ts +5 -1
  197. package/src/config/vellum-skills/slack-oauth-setup/SKILL.md +4 -3
  198. package/src/config/vellum-skills/sms-setup/SKILL.md +216 -0
  199. package/src/config/vellum-skills/twilio-setup/SKILL.md +40 -8
  200. package/src/context/window-manager.ts +27 -7
  201. package/src/daemon/approval-generators.ts +186 -0
  202. package/src/daemon/approved-devices-store.ts +140 -0
  203. package/src/daemon/assistant-attachments.ts +1 -1
  204. package/src/daemon/classifier.ts +35 -32
  205. package/src/daemon/config-watcher.ts +1 -1
  206. package/src/daemon/daemon-control.ts +217 -0
  207. package/src/daemon/handlers/apps.ts +2 -3
  208. package/src/daemon/handlers/config-channels.ts +158 -0
  209. package/src/daemon/handlers/config-inbox.ts +540 -0
  210. package/src/daemon/handlers/config-ingress.ts +231 -0
  211. package/src/daemon/handlers/config-integrations.ts +258 -0
  212. package/src/daemon/handlers/config-model.ts +143 -0
  213. package/src/daemon/handlers/config-parental.ts +163 -0
  214. package/src/daemon/handlers/config-scheduling.ts +172 -0
  215. package/src/daemon/handlers/config-slack.ts +92 -0
  216. package/src/daemon/handlers/config-telegram.ts +301 -0
  217. package/src/daemon/handlers/config-tools.ts +177 -0
  218. package/src/daemon/handlers/config-trust.ts +104 -0
  219. package/src/daemon/handlers/config-twilio.ts +1080 -0
  220. package/src/daemon/handlers/config.ts +53 -1689
  221. package/src/daemon/handlers/diagnostics.ts +1 -1
  222. package/src/daemon/handlers/dictation.ts +180 -0
  223. package/src/daemon/handlers/documents.ts +18 -32
  224. package/src/daemon/handlers/identity.ts +14 -23
  225. package/src/daemon/handlers/index.ts +11 -0
  226. package/src/daemon/handlers/misc.ts +3 -5
  227. package/src/daemon/handlers/pairing.ts +98 -0
  228. package/src/daemon/handlers/sessions.ts +56 -5
  229. package/src/daemon/handlers/shared.ts +6 -1
  230. package/src/daemon/handlers/skills.ts +1 -1
  231. package/src/daemon/handlers/twitter-auth.ts +2 -0
  232. package/src/daemon/handlers/work-items.ts +17 -9
  233. package/src/daemon/handlers/workspace-files.ts +4 -3
  234. package/src/daemon/install-cli-launchers.ts +113 -0
  235. package/src/daemon/ipc-contract/apps.ts +356 -0
  236. package/src/daemon/ipc-contract/browser.ts +74 -0
  237. package/src/daemon/ipc-contract/computer-use.ts +151 -0
  238. package/src/daemon/ipc-contract/diagnostics.ts +56 -0
  239. package/src/daemon/ipc-contract/documents.ts +74 -0
  240. package/src/daemon/ipc-contract/inbox.ts +209 -0
  241. package/src/daemon/ipc-contract/integrations.ts +284 -0
  242. package/src/daemon/ipc-contract/memory.ts +48 -0
  243. package/src/daemon/ipc-contract/messages.ts +211 -0
  244. package/src/daemon/ipc-contract/pairing.ts +45 -0
  245. package/src/daemon/ipc-contract/parental-control.ts +95 -0
  246. package/src/daemon/ipc-contract/schedules.ts +97 -0
  247. package/src/daemon/ipc-contract/sessions.ts +315 -0
  248. package/src/daemon/ipc-contract/shared.ts +42 -0
  249. package/src/daemon/ipc-contract/skills.ts +120 -0
  250. package/src/daemon/ipc-contract/subagents.ts +58 -0
  251. package/src/daemon/ipc-contract/surfaces.ts +250 -0
  252. package/src/daemon/ipc-contract/trust.ts +60 -0
  253. package/src/daemon/ipc-contract/work-items.ts +225 -0
  254. package/src/daemon/ipc-contract/workspace.ts +113 -0
  255. package/src/daemon/ipc-contract-inventory.json +70 -0
  256. package/src/daemon/ipc-contract-inventory.ts +55 -29
  257. package/src/daemon/ipc-contract.ts +229 -2426
  258. package/src/daemon/ipc-protocol.ts +1 -1
  259. package/src/daemon/ipc-validate.ts +7 -0
  260. package/src/daemon/lifecycle.ts +97 -377
  261. package/src/daemon/pairing-store.ts +177 -0
  262. package/src/daemon/providers-setup.ts +43 -0
  263. package/src/daemon/ride-shotgun-handler.ts +68 -3
  264. package/src/daemon/server.ts +66 -46
  265. package/src/daemon/session-agent-loop-handlers.ts +421 -0
  266. package/src/daemon/session-agent-loop.ts +117 -275
  267. package/src/daemon/session-dynamic-profile.ts +1 -1
  268. package/src/daemon/session-history.ts +1 -1
  269. package/src/daemon/session-media-retry.ts +1 -1
  270. package/src/daemon/session-messaging.ts +37 -2
  271. package/src/daemon/session-notifiers.ts +5 -25
  272. package/src/daemon/session-process.ts +99 -59
  273. package/src/daemon/session-queue-manager.ts +96 -4
  274. package/src/daemon/session-runtime-assembly.ts +199 -10
  275. package/src/daemon/session-surfaces.ts +19 -4
  276. package/src/daemon/session-tool-setup.ts +30 -30
  277. package/src/daemon/session-workspace.ts +1 -1
  278. package/src/daemon/session.ts +35 -2
  279. package/src/daemon/shutdown-handlers.ts +122 -0
  280. package/src/daemon/trace-emitter.ts +1 -1
  281. package/src/daemon/watch-handler.ts +36 -33
  282. package/src/doordash/cart-queries.ts +787 -0
  283. package/src/doordash/client.ts +144 -127
  284. package/src/doordash/order-queries.ts +85 -0
  285. package/src/doordash/queries.ts +10 -1308
  286. package/src/doordash/search-queries.ts +203 -0
  287. package/src/doordash/session.ts +3 -2
  288. package/src/doordash/store-queries.ts +246 -0
  289. package/src/doordash/types.ts +367 -0
  290. package/src/email/providers/agentmail.ts +2 -1
  291. package/src/email/providers/index.ts +3 -2
  292. package/src/email/service.ts +3 -2
  293. package/src/errors.ts +43 -0
  294. package/src/home-base/prebuilt/seed.ts +1 -1
  295. package/src/hooks/cli.ts +6 -5
  296. package/src/hooks/config.ts +6 -8
  297. package/src/hooks/discovery.ts +6 -5
  298. package/src/hooks/manager.ts +4 -3
  299. package/src/hooks/runner.ts +2 -2
  300. package/src/hooks/templates.ts +5 -5
  301. package/src/inbound/public-ingress-urls.ts +6 -4
  302. package/src/index.ts +4 -2
  303. package/src/influencer/client.ts +1104 -0
  304. package/src/instrument.ts +4 -3
  305. package/src/logfire.ts +4 -3
  306. package/src/memory/admin.ts +25 -35
  307. package/src/memory/attachments-store.ts +4 -7
  308. package/src/memory/channel-delivery-store.ts +30 -1
  309. package/src/memory/channel-guardian-store.ts +202 -2
  310. package/src/memory/clarification-resolver.ts +37 -33
  311. package/src/memory/conflict-store.ts +67 -61
  312. package/src/memory/contradiction-checker.ts +141 -117
  313. package/src/memory/conversation-store.ts +335 -51
  314. package/src/memory/db-connection.ts +27 -4
  315. package/src/memory/db-init.ts +265 -4
  316. package/src/memory/db.ts +14 -1
  317. package/src/memory/embedding-backend.ts +27 -5
  318. package/src/memory/embedding-ollama.ts +2 -1
  319. package/src/memory/entity-extractor.ts +38 -35
  320. package/src/memory/guardian-action-store.ts +430 -0
  321. package/src/memory/inbox-escalation-projection.ts +59 -0
  322. package/src/memory/inbox-thread-store.ts +218 -0
  323. package/src/memory/ingress-invite-store.ts +338 -0
  324. package/src/memory/ingress-member-store.ts +350 -0
  325. package/src/memory/items-extractor.ts +91 -97
  326. package/src/memory/job-handlers/index-maintenance.ts +3 -3
  327. package/src/memory/job-handlers/media-processing.ts +69 -0
  328. package/src/memory/job-handlers/summarization.ts +32 -26
  329. package/src/memory/job-utils.ts +3 -10
  330. package/src/memory/jobs-store.ts +8 -10
  331. package/src/memory/jobs-worker.ts +55 -36
  332. package/src/memory/media-store.ts +759 -0
  333. package/src/memory/migrations/001-job-deferrals.ts +45 -0
  334. package/src/memory/migrations/002-tool-invocations-fk.ts +43 -0
  335. package/src/memory/migrations/003-memory-fts-backfill.ts +24 -0
  336. package/src/memory/migrations/004-entity-relation-dedup.ts +87 -0
  337. package/src/memory/migrations/005-fingerprint-scope-unique.ts +80 -0
  338. package/src/memory/migrations/006-scope-salted-fingerprints.ts +62 -0
  339. package/src/memory/migrations/007-assistant-id-to-self.ts +254 -0
  340. package/src/memory/migrations/008-remove-assistant-id-columns.ts +208 -0
  341. package/src/memory/migrations/009-llm-usage-events-drop-assistant-id.ts +83 -0
  342. package/src/memory/migrations/010-ext-conv-bindings-channel-chat-unique.ts +56 -0
  343. package/src/memory/migrations/011-call-sessions-provider-sid-dedup.ts +63 -0
  344. package/src/memory/migrations/012-call-sessions-add-initiated-from.ts +19 -0
  345. package/src/memory/migrations/013-guardian-action-tables.ts +68 -0
  346. package/src/memory/migrations/014-backfill-inbox-thread-state.ts +76 -0
  347. package/src/memory/migrations/015-drop-active-search-index.ts +27 -0
  348. package/src/memory/migrations/016-memory-segments-indexes.ts +11 -0
  349. package/src/memory/migrations/017-memory-items-indexes.ts +10 -0
  350. package/src/memory/migrations/018-remaining-table-indexes.ts +13 -0
  351. package/src/memory/migrations/index.ts +24 -0
  352. package/src/memory/migrations/registry.ts +79 -0
  353. package/src/memory/migrations/validate-migration-state.ts +69 -0
  354. package/src/memory/qdrant-manager.ts +49 -8
  355. package/src/memory/query-builder.ts +1 -1
  356. package/src/memory/raw-query.ts +119 -0
  357. package/src/memory/recall-cache.ts +4 -1
  358. package/src/memory/retriever.ts +165 -47
  359. package/src/memory/schema-migration.ts +25 -984
  360. package/src/memory/schema.ts +228 -7
  361. package/src/memory/search/entity.ts +205 -31
  362. package/src/memory/search/lexical.ts +81 -52
  363. package/src/memory/search/ranking.ts +27 -23
  364. package/src/memory/search/semantic.ts +157 -19
  365. package/src/memory/search/types.ts +24 -0
  366. package/src/memory/shared-app-links-store.ts +4 -5
  367. package/src/memory/validation.ts +19 -0
  368. package/src/messaging/draft-store.ts +5 -6
  369. package/src/messaging/provider-types.ts +2 -0
  370. package/src/messaging/providers/sms/adapter.ts +201 -0
  371. package/src/messaging/providers/sms/client.ts +93 -0
  372. package/src/messaging/providers/sms/types.ts +7 -0
  373. package/src/messaging/providers/telegram-bot/adapter.ts +2 -5
  374. package/src/messaging/providers/whatsapp/adapter.ts +136 -0
  375. package/src/messaging/providers/whatsapp/client.ts +67 -0
  376. package/src/messaging/style-analyzer.ts +5 -4
  377. package/src/messaging/thread-summarizer.ts +61 -69
  378. package/src/messaging/triage-engine.ts +62 -71
  379. package/src/migrations/config-merge.ts +53 -0
  380. package/src/migrations/data-layout.ts +68 -0
  381. package/src/migrations/data-merge.ts +33 -0
  382. package/src/migrations/hooks-merge.ts +90 -0
  383. package/src/migrations/index.ts +6 -0
  384. package/src/migrations/log.ts +23 -0
  385. package/src/migrations/skills-merge.ts +33 -0
  386. package/src/migrations/workspace-layout.ts +79 -0
  387. package/src/permissions/checker.ts +133 -11
  388. package/src/permissions/prompter.ts +14 -0
  389. package/src/permissions/shell-identity.ts +31 -1
  390. package/src/permissions/trust-store.ts +21 -1
  391. package/src/providers/anthropic/client.ts +4 -4
  392. package/src/providers/failover.ts +2 -2
  393. package/src/providers/model-intents.ts +70 -0
  394. package/src/providers/ollama/client.ts +2 -1
  395. package/src/providers/provider-send-message.ts +176 -0
  396. package/src/providers/registry.ts +71 -30
  397. package/src/providers/retry.ts +35 -1
  398. package/src/providers/types.ts +12 -1
  399. package/src/runtime/approval-conversation-turn.ts +97 -0
  400. package/src/runtime/approval-message-composer.ts +253 -0
  401. package/src/runtime/channel-approval-parser.ts +36 -2
  402. package/src/runtime/channel-approvals.ts +11 -24
  403. package/src/runtime/channel-guardian-service.ts +88 -21
  404. package/src/runtime/channel-readiness-service.ts +418 -0
  405. package/src/runtime/channel-readiness-types.ts +35 -0
  406. package/src/runtime/channel-retry-sweep.ts +184 -0
  407. package/src/runtime/guardian-context-resolver.ts +108 -0
  408. package/src/runtime/http-server.ts +275 -717
  409. package/src/runtime/http-types.ts +59 -3
  410. package/src/runtime/middleware/auth.ts +116 -0
  411. package/src/runtime/middleware/error-handler.ts +33 -0
  412. package/src/runtime/middleware/twilio-validation.ts +127 -0
  413. package/src/runtime/routes/app-routes.ts +1 -1
  414. package/src/runtime/routes/call-routes.ts +51 -7
  415. package/src/runtime/routes/channel-delivery-routes.ts +170 -0
  416. package/src/runtime/routes/channel-guardian-routes.ts +1191 -0
  417. package/src/runtime/routes/channel-inbound-routes.ts +1152 -0
  418. package/src/runtime/routes/channel-route-shared.ts +144 -0
  419. package/src/runtime/routes/channel-routes.ts +32 -1588
  420. package/src/runtime/routes/conversation-routes.ts +50 -7
  421. package/src/runtime/routes/events-routes.ts +2 -2
  422. package/src/runtime/routes/identity-routes.ts +126 -0
  423. package/src/runtime/routes/pairing-routes.ts +143 -0
  424. package/src/runtime/routes/run-routes.ts +15 -1
  425. package/src/runtime/run-orchestrator.ts +86 -35
  426. package/src/schedule/schedule-store.ts +36 -32
  427. package/src/schedule/scheduler.ts +3 -3
  428. package/src/security/encrypted-store.ts +5 -7
  429. package/src/security/oauth2.ts +45 -15
  430. package/src/security/parental-control-store.ts +183 -0
  431. package/src/security/secret-allowlist.ts +4 -3
  432. package/src/security/secret-scanner.ts +5 -5
  433. package/src/security/secure-keys.ts +1 -1
  434. package/src/security/token-manager.ts +3 -2
  435. package/src/services/vercel-deploy.ts +6 -2
  436. package/src/skills/tool-manifest.ts +3 -3
  437. package/src/skills/vellum-catalog-remote.ts +75 -16
  438. package/src/slack/slack-webhook.ts +2 -1
  439. package/src/swarm/orchestrator.ts +92 -1
  440. package/src/swarm/router-planner.ts +6 -9
  441. package/src/swarm/worker-prompts.ts +9 -12
  442. package/src/tasks/task-compiler.ts +19 -28
  443. package/src/tasks/task-runner.ts +1 -1
  444. package/src/tools/assets/materialize.ts +2 -2
  445. package/src/tools/assets/search.ts +15 -14
  446. package/src/tools/browser/__tests__/auth-detector.test.ts +1 -0
  447. package/src/tools/browser/auto-navigate.ts +1 -0
  448. package/src/tools/browser/browser-execution.ts +10 -1
  449. package/src/tools/browser/browser-manager.ts +119 -4
  450. package/src/tools/browser/network-recorder.ts +5 -0
  451. package/src/tools/calls/call-start.ts +1 -0
  452. package/src/tools/credentials/broker.ts +11 -2
  453. package/src/tools/credentials/metadata-store.ts +18 -14
  454. package/src/tools/credentials/post-connect-hooks.ts +61 -0
  455. package/src/tools/credentials/vault.ts +49 -23
  456. package/src/tools/execution-target.ts +11 -1
  457. package/src/tools/executor.ts +68 -9
  458. package/src/tools/host-terminal/cli-discover.ts +1 -1
  459. package/src/tools/network/script-proxy/http-forwarder.ts +1 -1
  460. package/src/tools/network/script-proxy/mitm-handler.ts +1 -1
  461. package/src/tools/network/script-proxy/server.ts +1 -1
  462. package/src/tools/network/script-proxy/session-manager.ts +6 -5
  463. package/src/tools/network/web-fetch.ts +18 -2
  464. package/src/tools/network/web-search.ts +8 -4
  465. package/src/tools/reminder/reminder-store.ts +14 -15
  466. package/src/tools/schedule/create.ts +1 -0
  467. package/src/tools/schedule/list.ts +2 -1
  468. package/src/tools/shared/filesystem/file-ops-service.ts +5 -7
  469. package/src/tools/skills/skill-script-runner.ts +24 -9
  470. package/src/tools/skills/skill-tool-factory.ts +1 -0
  471. package/src/tools/tasks/work-item-enqueue.ts +2 -2
  472. package/src/tools/terminal/evaluate-typescript.ts +21 -12
  473. package/src/tools/terminal/parser.ts +50 -0
  474. package/src/tools/types.ts +2 -0
  475. package/src/tools/watcher/delete.ts +6 -0
  476. package/src/tools/weather/service.ts +1 -1
  477. package/src/twitter/client.ts +190 -24
  478. package/src/twitter/router.ts +1 -1
  479. package/src/twitter/session.ts +4 -3
  480. package/src/util/clipboard.ts +1 -1
  481. package/src/util/errors.ts +65 -8
  482. package/src/util/fs.ts +40 -0
  483. package/src/util/json.ts +10 -0
  484. package/src/util/log-redact.ts +189 -0
  485. package/src/util/logger.ts +19 -17
  486. package/src/util/object.ts +3 -0
  487. package/src/util/platform.ts +105 -363
  488. package/src/util/pricing.ts +1 -1
  489. package/src/util/promise-guard.ts +1 -1
  490. package/src/util/retry.ts +19 -0
  491. package/src/util/row-mapper.ts +79 -0
  492. package/src/util/silently.ts +21 -0
  493. package/src/watcher/engine.ts +5 -1
  494. package/src/watcher/provider-types.ts +20 -0
  495. package/src/watcher/providers/github.ts +156 -0
  496. package/src/watcher/providers/gmail.ts +1 -0
  497. package/src/watcher/providers/google-calendar.ts +1 -0
  498. package/src/watcher/providers/linear.ts +460 -0
  499. package/src/watcher/providers/slack.ts +1 -0
  500. package/src/work-items/work-item-runner.ts +1 -1
  501. package/src/workspace/git-service.ts +1 -1
  502. package/src/workspace/provider-commit-message-generator.ts +51 -22
  503. package/src/__tests__/call-bridge.test.ts +0 -517
  504. package/src/__tests__/session-process-bridge.test.ts +0 -244
  505. package/src/calls/call-bridge.ts +0 -168
  506. package/src/config/vellum-skills/google-oauth-setup/SKILL.md +0 -199
@@ -0,0 +1,183 @@
1
+ ---
2
+ name: "Google OAuth Setup"
3
+ description: "Set up Google Cloud OAuth credentials for Gmail and Calendar using browser automation"
4
+ user-invocable: true
5
+ includes: ["browser", "public-ingress"]
6
+ metadata: {"vellum": {"emoji": "\ud83d\udd11"}}
7
+ ---
8
+
9
+ You are helping your user set up Google Cloud OAuth credentials so Gmail and Google Calendar integrations can connect. You will automate the entire GCP setup via the browser while the user watches via screencast. The user's only manual action is signing in to their Google account — everything else is fully automated.
10
+
11
+ ## Client Check
12
+
13
+ If the user is on Telegram (or any non-macOS client without browser automation):
14
+
15
+ > "Gmail setup requires browser automation, which is available on the macOS app. Please open the Vellum app on your Mac and ask me to connect Gmail there — I'll handle the rest automatically."
16
+
17
+ Stop here. Do not attempt a manual walkthrough.
18
+
19
+ ## Prerequisites
20
+
21
+ Before starting, check that `ingress.publicBaseUrl` is configured (`INGRESS_PUBLIC_BASE_URL` env var or workspace config). If it is not set, load and execute the **public-ingress** skill first (`skill_load` with `skill: "public-ingress"`) to set up an ngrok tunnel and persist the public URL. The OAuth redirect URI depends on this value.
22
+
23
+ ## Step 1: Single Upfront Confirmation
24
+
25
+ Use `ui_show` with `surface_type: "confirmation"` and this message:
26
+
27
+ > **Set up Google Cloud for Gmail & Calendar**
28
+ >
29
+ > Here's what will happen:
30
+ > 1. **A browser opens** — you sign in to your Google account
31
+ > 2. **I automate everything** — project creation, APIs, OAuth config, credentials
32
+ > 3. **You enter credentials** from a downloaded file (secure prompt — I never see them)
33
+ > 4. **You authorize Vellum** with one click
34
+ >
35
+ > The whole thing takes 2-3 minutes. Ready?
36
+
37
+ If the user declines, acknowledge and stop. No further confirmations are needed after this point.
38
+
39
+ ## Step 2: Open Google Cloud Console
40
+
41
+ Use `browser_navigate` to go to `https://console.cloud.google.com/`.
42
+
43
+ Take a `browser_screenshot` and `browser_snapshot` to check the page state:
44
+ - **If a sign-in page appears:** Tell the user: "Please sign in to your Google account in the browser preview panel (or the Chrome window that just opened)." Then **auto-detect sign-in completion** by polling `browser_snapshot` every 5-10 seconds. Check if the current URL has moved away from `accounts.google.com` to `console.cloud.google.com`. Do NOT ask the user to "let me know when you're done" — detect it automatically. Once sign-in is detected, tell the user: "Signed in! Starting the automated setup now..."
45
+ - **If already signed in** (URL is already `console.cloud.google.com`): Tell the user: "Already signed in — starting setup now..." and continue immediately.
46
+ - **If a CAPTCHA appears:** The browser automation's built-in handoff will handle this. If it persists, tell the user: "There's a CAPTCHA in the browser — please complete it and I'll continue automatically."
47
+ - **If the console dashboard loads:** Continue to Step 3.
48
+
49
+ ## Step 3: Create or Select a Project
50
+
51
+ Tell the user: "Creating Google Cloud project 'Vellum Assistant'..."
52
+
53
+ Navigate to `https://console.cloud.google.com/projectcreate`.
54
+
55
+ Take a `browser_snapshot`. Fill in the project name:
56
+ - Use `browser_type` to set the project name to "Vellum Assistant"
57
+ - Use `browser_click` to submit the "Create" button
58
+
59
+ Wait a few seconds, take a `browser_screenshot` and `browser_snapshot` to confirm. If the project already exists, navigate to its dashboard. Note the project ID for subsequent steps.
60
+
61
+ Tell the user: "Project created!"
62
+
63
+ ## Step 4: Enable Gmail and Calendar APIs
64
+
65
+ Tell the user: "Enabling Gmail and Calendar APIs..."
66
+
67
+ Navigate to `https://console.cloud.google.com/apis/library/gmail.googleapis.com?project=PROJECT_ID` (substitute actual project ID).
68
+
69
+ Take a `browser_snapshot`:
70
+ - If already enabled (shows "API enabled" or "Manage" button): skip.
71
+ - If not: click the "Enable" button and wait.
72
+
73
+ Then navigate to `https://console.cloud.google.com/apis/library/calendar-json.googleapis.com?project=PROJECT_ID`.
74
+
75
+ Same check — enable if needed.
76
+
77
+ Take a `browser_screenshot` to show result. Tell the user: "APIs enabled!"
78
+
79
+ ## Step 5: Configure OAuth Consent Screen
80
+
81
+ Tell the user: "Configuring OAuth consent screen — this is the longest step, but it's fully automated..."
82
+
83
+ Navigate to `https://console.cloud.google.com/apis/credentials/consent?project=PROJECT_ID`.
84
+
85
+ Take a `browser_snapshot`:
86
+ - If consent screen is already configured: skip to Step 6.
87
+ - If user type selection appears: select "External" and click "Create".
88
+
89
+ Fill in the consent screen form:
90
+ 1. **App name:** "Vellum Assistant"
91
+ 2. **User support email:** Select the user's email from the dropdown
92
+ 3. **Developer contact email:** Type the user's email address
93
+ 4. Leave other fields as defaults
94
+
95
+ Navigate through the wizard pages:
96
+ - App information page: Fill fields, click "Save and Continue"
97
+ - Scopes page: Click "Add or Remove Scopes", search for and select:
98
+ - `https://www.googleapis.com/auth/gmail.readonly`
99
+ - `https://www.googleapis.com/auth/gmail.modify`
100
+ - `https://www.googleapis.com/auth/gmail.send`
101
+ - `https://www.googleapis.com/auth/calendar.readonly`
102
+ - `https://www.googleapis.com/auth/calendar.events`
103
+ - `https://www.googleapis.com/auth/userinfo.email`
104
+ - Click "Update" then "Save and Continue"
105
+ - Test users page: Add the user's email as a test user, click "Save and Continue"
106
+ - Summary page: Click "Back to Dashboard"
107
+
108
+ Tell the user: "Consent screen configured!"
109
+
110
+ ## Step 6: Create OAuth Credentials
111
+
112
+ Tell the user: "Creating OAuth credentials..."
113
+
114
+ Navigate to `https://console.cloud.google.com/apis/credentials?project=PROJECT_ID`.
115
+
116
+ Click "+ Create Credentials" then select "OAuth client ID".
117
+
118
+ Take a `browser_snapshot` and fill in:
119
+ 1. **Application type:** Select "Web application"
120
+ 2. **Name:** "Vellum Assistant"
121
+ 3. **Authorized redirect URIs:** Click "Add URI" and enter `${ingress.publicBaseUrl}/webhooks/oauth/callback`
122
+
123
+ Click "Create".
124
+
125
+ ## Step 7: Download Credentials JSON
126
+
127
+ Tell the user: "Almost done — downloading credentials..."
128
+
129
+ After the credentials dialog appears, click the "Download JSON" button (it may say "DOWNLOAD JSON" or show a download icon).
130
+
131
+ Use `browser_wait_for_download` to wait for the file to download.
132
+
133
+ Tell the user: "Credentials downloaded!"
134
+
135
+ ## Step 8: Secure Credential Entry
136
+
137
+ Tell the user: "I've downloaded the credentials file. Please open it and enter the values below. I won't see what you type — these go directly to secure storage."
138
+
139
+ ```
140
+ credential_store prompt:
141
+ service: "integration:gmail"
142
+ field: "client_id"
143
+ label: "Google OAuth Client ID"
144
+ description: "Open the downloaded JSON file and copy the client_id value"
145
+ placeholder: "123456789.apps.googleusercontent.com"
146
+ ```
147
+
148
+ ```
149
+ credential_store prompt:
150
+ service: "integration:gmail"
151
+ field: "client_secret"
152
+ label: "Google OAuth Client Secret"
153
+ description: "Copy the client_secret value from the same JSON file"
154
+ placeholder: "GOCSPX-..."
155
+ ```
156
+
157
+ ## Step 9: OAuth2 Authorization
158
+
159
+ Tell the user: "Opening Google sign-in so you can authorize Vellum. Just click 'Allow' on the consent page."
160
+
161
+ Use `credential_store` with:
162
+
163
+ ```
164
+ action: "oauth2_connect"
165
+ service: "integration:gmail"
166
+ ```
167
+
168
+ This auto-reads client_id/client_secret from the secure store and auto-fills auth_url, token_url, scopes, and extra_params from well-known config.
169
+
170
+ **If the user sees a "This app isn't verified" warning:** Tell them this is normal for apps in testing mode. Click "Advanced" then "Go to Vellum Assistant (unsafe)" to proceed.
171
+
172
+ ## Step 10: Done!
173
+
174
+ "**Gmail and Calendar are connected!** You can now read, search, and send emails, plus view and manage your calendar. Try asking me to check your inbox or show your upcoming events!"
175
+
176
+ ## Error Handling
177
+
178
+ - **Page load failures:** Retry navigation once. If it still fails, tell the user and ask them to check their internet connection.
179
+ - **Permission errors in GCP:** The user may need billing enabled or organization-level permissions. Explain clearly and ask them to resolve it.
180
+ - **Consent screen already configured:** Don't overwrite — skip to credential creation.
181
+ - **Element not found:** Take a fresh `browser_snapshot` to re-assess. GCP UI may have changed. Tell the user what you're looking for if stuck.
182
+ - **OAuth flow timeout or failure:** Offer to retry. The credentials are already stored, so reconnecting only requires re-running the authorization flow.
183
+ - **Any unexpected state:** Take a `browser_screenshot` and `browser_snapshot`, describe what you see, and ask the user for guidance.
@@ -0,0 +1,144 @@
1
+ ---
2
+ name: "Influencer Research"
3
+ description: "Research influencers on Instagram, TikTok, and X/Twitter using the Chrome extension relay"
4
+ user-invocable: true
5
+ metadata: {"vellum": {"emoji": "🔍"}}
6
+ ---
7
+
8
+ You can research and discover influencers across Instagram, TikTok, and X/Twitter using the `vellum influencer` CLI.
9
+
10
+ ## CLI Setup
11
+
12
+ **IMPORTANT: Always use `host_bash` (not `bash`) for all `vellum influencer` commands.** The influencer CLI needs host access for the Chrome extension relay and the `vellum` binary, neither of which are available inside the sandbox.
13
+
14
+ `vellum influencer` is a built-in subcommand of the Vellum assistant CLI. If `vellum` is not found, prepend `PATH="$HOME/.local/bin:$PATH"` to the command.
15
+
16
+ ## Prerequisites
17
+
18
+ - The Chrome extension relay must be connected (user should have the Vellum extension loaded in Chrome)
19
+ - The user must be **logged in** on each platform they want to search (Instagram, TikTok, X) in their Chrome browser
20
+ - The extension MUST have the `debugger` permission (required to bypass CSP on Instagram and other Meta sites)
21
+ - If the relay is not connected, tell the user: "Please open Chrome, click the Vellum extension icon, and click Connect — then I'll retry."
22
+
23
+ ## Platform-Specific Architecture
24
+
25
+ ### Instagram
26
+ Instagram's search at `/explore/search/keyword/?q=...` shows a **grid of posts**, NOT profiles. The discovery flow is:
27
+ 1. Search by keyword → extract post links (`/p/` and `/reel/`)
28
+ 2. Visit each post → find the author username from page links
29
+ 3. Deduplicate usernames
30
+ 4. Visit each unique profile → scrape stats from `meta[name="description"]` (most reliable source, format: "49K Followers, 463 Following, 551 Posts - Display Name (@user)")
31
+ 5. Filter and rank by criteria
32
+
33
+ **CSP Note:** Instagram blocks `eval()`, `new Function()`, inline scripts, and blob URLs via strict CSP. The extension uses `chrome.debugger` API (CDP Runtime.evaluate) as a fallback, which bypasses all CSP restrictions.
34
+
35
+ ### TikTok
36
+ TikTok has a dedicated user search at `/search/user?q=...`. Each result card produces a predictable text pattern in `innerText`:
37
+ ```
38
+ DisplayName
39
+ username
40
+ 77.9K
41
+ Followers
42
+ ·
43
+ 1.5M
44
+ Likes
45
+ Follow
46
+ ```
47
+ We parse this pattern directly (DOM class selectors are obfuscated and unreliable on TikTok). After extracting usernames and follower counts, we visit each profile for bios.
48
+
49
+ ### X/Twitter
50
+ X has a people search at `/search?q=...&f=user` with `[data-testid="UserCell"]` components containing username, display name, bio, and verified status.
51
+
52
+ ## Typical Flow
53
+
54
+ When the user asks to find or research influencers:
55
+
56
+ 1. **Understand the criteria.** Ask about:
57
+ - **Niche/topic** — what kind of influencers? (fitness, beauty, tech, food, etc.)
58
+ - **Platforms** — Instagram, TikTok, X/Twitter, or all three?
59
+ - **Follower range** — micro (1K-10K), mid-tier (10K-100K), macro (100K-1M), mega (1M+)?
60
+ - **Verified only?** — do they need the blue checkmark?
61
+ - Don't over-ask. If the user says "find me fitness influencers on Instagram", that's enough to start.
62
+
63
+ 2. **Search** — run `vellum influencer search "<query>" --platforms <platforms> [options] --json`
64
+
65
+ 3. **Present results** — show a clean summary of each influencer found:
66
+ - Username and display name
67
+ - Platform
68
+ - Follower count
69
+ - Bio snippet
70
+ - Verified status
71
+ - Content themes detected
72
+ - Profile URL
73
+
74
+ 4. **Deep dive** (if needed) — run `vellum influencer profile <username> --platform <platform> --json` to get detailed data on a specific influencer.
75
+
76
+ 5. **Compare** (if needed) — run `vellum influencer compare instagram:user1 twitter:user2 tiktok:user3 --json` to compare influencers side by side.
77
+
78
+ ## Follower Range Shortcuts
79
+
80
+ When the user describes influencer tiers, map to these ranges:
81
+ - **Nano**: `--min-followers 1000 --max-followers 10000`
82
+ - **Micro**: `--min-followers 10000 --max-followers 100000`
83
+ - **Mid-tier**: `--min-followers 100000 --max-followers 500000`
84
+ - **Macro**: `--min-followers 500000 --max-followers 1000000`
85
+ - **Mega**: `--min-followers 1000000`
86
+
87
+ Human-friendly numbers are supported: `10k`, `100k`, `1m`, etc.
88
+
89
+ ## Command Reference
90
+
91
+ ```
92
+ vellum influencer search "<query>" [options] --json
93
+ --platforms <list> Comma-separated: instagram,tiktok,twitter (default: all three)
94
+ --min-followers <n> Minimum follower count (e.g. 10k, 100000)
95
+ --max-followers <n> Maximum follower count (e.g. 1m, 500k)
96
+ --limit <n> Max results per platform (default: 10)
97
+ --verified Only return verified accounts
98
+
99
+ vellum influencer profile <username> --platform <platform> --json
100
+ --platform <platform> instagram, tiktok, or twitter (default: instagram)
101
+
102
+ vellum influencer compare <platform:username ...> --json
103
+ Arguments are space-separated platform:username pairs
104
+ e.g. instagram:nike twitter:nike tiktok:nike
105
+ ```
106
+
107
+ ## Important Behavior
108
+
109
+ - **Use `--json` flag** on all commands for reliable parsing.
110
+ - **Always use `host_bash`** for these commands, never `bash`.
111
+ - **Be patient with results.** The tool navigates actual browser tabs, so each platform search takes 10-30 seconds. Warn the user it may take a moment.
112
+ - **Rate limiting.** Don't hammer the platforms. The tool has built-in delays, but avoid running many searches in rapid succession.
113
+ - **Present results nicely.** Use tables or formatted lists. Group by platform. Highlight standout profiles.
114
+ - **Offer next steps.** After showing results, ask if they want to:
115
+ - Get more details on specific profiles
116
+ - Compare top picks side by side
117
+ - Search with different criteria
118
+ - Export the results
119
+ - **Handle errors gracefully.** If a platform fails (e.g. not logged in), show results from the platforms that worked and mention which one failed.
120
+ - **Do NOT use the browser skill.** All influencer research goes through the CLI, not browser automation.
121
+
122
+ ## Example Interactions
123
+
124
+ **User**: "Find me fitness influencers on Instagram and TikTok"
125
+
126
+ 1. `vellum influencer search "fitness coach workout" --platforms instagram,tiktok --limit 10 --json`
127
+ 2. Present results grouped by platform with follower counts and bios
128
+ 3. "I found 8 fitness influencers on Instagram and 6 on TikTok. Want me to dig deeper into any of these profiles?"
129
+
130
+ **User**: "I need micro-influencers in the beauty niche, verified only"
131
+
132
+ 1. `vellum influencer search "beauty makeup skincare" --platforms instagram,tiktok,twitter --min-followers 10k --max-followers 100k --verified --limit 10 --json`
133
+ 2. Present filtered results
134
+ 3. Offer to compare top picks
135
+
136
+ **User**: "Compare @username1 on Instagram with @username2 on TikTok"
137
+
138
+ 1. `vellum influencer compare instagram:username1 tiktok:username2 --json`
139
+ 2. Present side-by-side comparison with followers, engagement, bio, themes
140
+
141
+ **User**: "Tell me more about @specificuser on Instagram"
142
+
143
+ 1. `vellum influencer profile specificuser --platform instagram --json`
144
+ 2. Show full profile details including bio, follower/following counts, verified status, content themes
@@ -0,0 +1,15 @@
1
+ # Knowledge Graph
2
+
3
+ Query the entity knowledge graph to explore relationships between people, projects, tools, and other entities tracked in memory.
4
+
5
+ ## When to use
6
+
7
+ - When the user asks about relationships between entities ("what tools does project X use?", "who works on project Y?")
8
+ - When the user wants to explore connected entities across the knowledge graph
9
+ - When automatic memory recall doesn't surface the right relationship-based information
10
+
11
+ ## Capabilities
12
+
13
+ - **Neighbors**: Find entities directly connected to seed entities (optionally filtered by relation and entity type)
14
+ - **Typed traversal**: Multi-step traversal with type constraints at each step (e.g., "me -> works_on -> projects -> uses -> tools")
15
+ - **Intersection**: Find entities reachable from ALL given seeds (e.g., "projects both Alice and Bob work on")
@@ -0,0 +1,56 @@
1
+ {
2
+ "version": 1,
3
+ "tools": [
4
+ {
5
+ "name": "knowledge_graph_query",
6
+ "description": "Query the entity knowledge graph to find related entities and their associated memory items. Supports three query types: 'neighbors' (direct connections), 'typed_traversal' (multi-step with type filters), and 'intersection' (entities reachable from ALL seeds).",
7
+ "category": "memory",
8
+ "risk": "low",
9
+ "input_schema": {
10
+ "type": "object",
11
+ "properties": {
12
+ "query_type": {
13
+ "type": "string",
14
+ "enum": ["neighbors", "typed_traversal", "intersection"],
15
+ "description": "Type of graph query to execute"
16
+ },
17
+ "seeds": {
18
+ "type": "array",
19
+ "items": { "type": "string" },
20
+ "description": "Entity names or aliases to use as starting points"
21
+ },
22
+ "steps": {
23
+ "type": "array",
24
+ "items": {
25
+ "type": "object",
26
+ "properties": {
27
+ "relation_types": {
28
+ "type": "array",
29
+ "items": { "type": "string" },
30
+ "description": "Relation types to follow (e.g., 'uses', 'works_on', 'depends_on')"
31
+ },
32
+ "entity_types": {
33
+ "type": "array",
34
+ "items": { "type": "string" },
35
+ "description": "Entity types to include (e.g., 'person', 'project', 'tool')"
36
+ }
37
+ }
38
+ },
39
+ "description": "Traversal steps for typed_traversal and intersection queries. Each step defines type filters for one hop."
40
+ },
41
+ "max_results": {
42
+ "type": "number",
43
+ "description": "Maximum number of entities to return (default: 20)"
44
+ },
45
+ "include_items": {
46
+ "type": "boolean",
47
+ "description": "Include associated memory items for each found entity (default: true)"
48
+ }
49
+ },
50
+ "required": ["query_type", "seeds"]
51
+ },
52
+ "executor": "tools/graph-query.ts",
53
+ "execution_target": "host"
54
+ }
55
+ ]
56
+ }
@@ -0,0 +1,185 @@
1
+ import { initializeDb, getDb } from '../../../../memory/db.js';
2
+ import { findMatchedEntities, findNeighborEntities, getEntityLinkedItemCandidates, collectTypedNeighbors } from '../../../../memory/search/entity.js';
3
+ import { memoryEntities } from '../../../../memory/schema.js';
4
+ import { inArray } from 'drizzle-orm';
5
+ import type { TraversalStep } from '../../../../memory/search/types.js';
6
+ import type { EntityRelationType, EntityType } from '../../../../memory/entity-extractor.js';
7
+ import type { ToolContext, ToolExecutionResult } from '../../../../tools/types.js';
8
+
9
+ interface GraphQueryInput {
10
+ query_type: 'neighbors' | 'typed_traversal' | 'intersection';
11
+ seeds: string[];
12
+ steps?: Array<{
13
+ relation_types?: string[];
14
+ entity_types?: string[];
15
+ }>;
16
+ max_results?: number;
17
+ include_items?: boolean;
18
+ }
19
+
20
+ interface EntityResult {
21
+ id: string;
22
+ name: string;
23
+ type: string;
24
+ aliases: string[];
25
+ items?: Array<{ subject: string; statement: string }>;
26
+ }
27
+
28
+ export async function run(
29
+ input: Record<string, unknown>,
30
+ _context: ToolContext,
31
+ ): Promise<ToolExecutionResult> {
32
+ const params = input as unknown as GraphQueryInput;
33
+
34
+ initializeDb();
35
+
36
+ const maxResults = params.max_results ?? 20;
37
+ const includeItems = params.include_items ?? true;
38
+
39
+ // Resolve seed entity names to IDs
40
+ const seedEntityIds: string[] = [];
41
+ const resolvedSeeds: Array<{ name: string; id: string }> = [];
42
+ for (const seedName of params.seeds) {
43
+ const matched = findMatchedEntities(seedName, 5);
44
+ if (matched.length > 0) {
45
+ seedEntityIds.push(matched[0].id);
46
+ resolvedSeeds.push({ name: seedName, id: matched[0].id });
47
+ }
48
+ }
49
+
50
+ if (seedEntityIds.length === 0) {
51
+ return {
52
+ content: JSON.stringify({
53
+ error: 'No matching entities found for the provided seed names',
54
+ seeds: params.seeds,
55
+ }),
56
+ isError: true,
57
+ };
58
+ }
59
+
60
+ // For intersection queries, all seeds must resolve — dropping any seed silently
61
+ // changes semantics from "reachable from ALL seeds" to "reachable from resolved seeds"
62
+ if (params.query_type === 'intersection' && seedEntityIds.length < params.seeds.length) {
63
+ const unresolvedSeeds = params.seeds.filter(
64
+ name => !resolvedSeeds.some(s => s.name === name),
65
+ );
66
+ return {
67
+ content: JSON.stringify({
68
+ error: 'Some seed entities could not be resolved. Intersection requires all seeds to match.',
69
+ unresolved_seeds: unresolvedSeeds,
70
+ resolved_seeds: resolvedSeeds,
71
+ }),
72
+ isError: true,
73
+ };
74
+ }
75
+
76
+ let resultEntityIds: string[];
77
+
78
+ switch (params.query_type) {
79
+ case 'neighbors': {
80
+ const steps = params.steps?.[0];
81
+ const result = findNeighborEntities(seedEntityIds, {
82
+ maxEdges: 40,
83
+ maxNeighborEntities: maxResults,
84
+ maxDepth: 1,
85
+ relationTypes: steps?.relation_types as EntityRelationType[] | undefined,
86
+ entityTypes: steps?.entity_types as EntityType[] | undefined,
87
+ });
88
+ resultEntityIds = result.neighborEntityIds;
89
+ break;
90
+ }
91
+
92
+ case 'typed_traversal': {
93
+ const traversalSteps: TraversalStep[] = (params.steps ?? []).map(s => ({
94
+ relationTypes: s.relation_types as EntityRelationType[] | undefined,
95
+ entityTypes: s.entity_types as EntityType[] | undefined,
96
+ }));
97
+ resultEntityIds = collectTypedNeighbors(seedEntityIds, traversalSteps, {
98
+ maxResultsPerStep: maxResults,
99
+ maxEdgesPerStep: 40,
100
+ });
101
+ break;
102
+ }
103
+
104
+ case 'intersection': {
105
+ // Run typed traversal from each seed independently, then intersect
106
+ const traversalSteps: TraversalStep[] = (params.steps ?? []).map(s => ({
107
+ relationTypes: s.relation_types as EntityRelationType[] | undefined,
108
+ entityTypes: s.entity_types as EntityType[] | undefined,
109
+ }));
110
+
111
+ const resultSets: Set<string>[] = [];
112
+ for (const seedId of seedEntityIds) {
113
+ const result = collectTypedNeighbors([seedId], traversalSteps, {
114
+ maxResultsPerStep: maxResults,
115
+ maxEdgesPerStep: 40,
116
+ });
117
+ resultSets.push(new Set(result));
118
+ }
119
+
120
+ if (resultSets.length === 0) {
121
+ resultEntityIds = [];
122
+ } else {
123
+ // Intersect all sets
124
+ const intersection = [...resultSets[0]].filter(id =>
125
+ resultSets.every(set => set.has(id))
126
+ );
127
+ resultEntityIds = intersection;
128
+ }
129
+ break;
130
+ }
131
+
132
+ default:
133
+ return {
134
+ content: JSON.stringify({ error: `Unknown query_type: ${params.query_type}` }),
135
+ isError: true,
136
+ };
137
+ }
138
+
139
+ // Look up entity details
140
+ const db = getDb();
141
+ const entities: EntityResult[] = [];
142
+
143
+ if (resultEntityIds.length > 0) {
144
+ const entityRows = db
145
+ .select()
146
+ .from(memoryEntities)
147
+ .where(inArray(memoryEntities.id, resultEntityIds.slice(0, maxResults)))
148
+ .all();
149
+
150
+ for (const row of entityRows) {
151
+ const entity: EntityResult = {
152
+ id: row.id,
153
+ name: row.name,
154
+ type: row.type,
155
+ aliases: row.aliases ? JSON.parse(row.aliases) as string[] : [],
156
+ };
157
+
158
+ if (includeItems) {
159
+ const candidates = getEntityLinkedItemCandidates([row.id], {
160
+ source: 'entity_direct',
161
+ scopeIds: _context.memoryScopeId ? [_context.memoryScopeId] : undefined,
162
+ });
163
+ entity.items = candidates.slice(0, 5).map(c => {
164
+ const parts = c.text.split(': ');
165
+ return {
166
+ subject: parts[0] ?? '',
167
+ statement: parts.slice(1).join(': ') || c.text,
168
+ };
169
+ });
170
+ }
171
+
172
+ entities.push(entity);
173
+ }
174
+ }
175
+
176
+ return {
177
+ content: JSON.stringify({
178
+ query_type: params.query_type,
179
+ resolved_seeds: resolvedSeeds,
180
+ result_count: entities.length,
181
+ entities,
182
+ }, null, 2),
183
+ isError: false,
184
+ };
185
+ }
@@ -0,0 +1,12 @@
1
+ <svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
2
+ <rect x="2" y="2" width="12" height="11" fill="#e8e8e8" stroke="#333" stroke-width="1"/>
3
+ <rect x="3" y="3" width="10" height="9" fill="#f5f5f5"/>
4
+ <circle cx="8" cy="7" r="2" fill="#0071e3"/>
5
+ <rect x="5" y="5" width="1" height="1" fill="#333"/>
6
+ <rect x="10" y="5" width="1" height="1" fill="#333"/>
7
+ <rect x="5" y="9" width="1" height="1" fill="#333"/>
8
+ <rect x="10" y="9" width="1" height="1" fill="#333"/>
9
+ <path d="M 8 4 L 8 6 M 6 7 L 8 7 M 8 8 L 8 10 M 8 7 L 10 7" stroke="#0071e3" stroke-width="1" fill="none"/>
10
+ <rect x="3" y="13" width="10" height="1" fill="#333"/>
11
+ <rect x="4" y="14" width="8" height="1" fill="#0071e3"/>
12
+ </svg>