@rudderjs/ai 1.17.3 → 1.18.0

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 (377) hide show
  1. package/README.md +19 -1274
  2. package/dist/budget-orm/index.d.ts +1 -95
  3. package/dist/budget-orm/index.d.ts.map +1 -1
  4. package/dist/budget-orm/index.js +4 -176
  5. package/dist/budget-orm/index.js.map +1 -1
  6. package/dist/chat-mentions.d.ts +1 -58
  7. package/dist/chat-mentions.d.ts.map +1 -1
  8. package/dist/chat-mentions.js +4 -80
  9. package/dist/chat-mentions.js.map +1 -1
  10. package/dist/commands/ai-eval.d.ts +1 -92
  11. package/dist/commands/ai-eval.d.ts.map +1 -1
  12. package/dist/commands/ai-eval.js +4 -377
  13. package/dist/commands/ai-eval.js.map +1 -1
  14. package/dist/commands/make-agent.d.ts +1 -2
  15. package/dist/commands/make-agent.d.ts.map +1 -1
  16. package/dist/commands/make-agent.js +4 -22
  17. package/dist/commands/make-agent.js.map +1 -1
  18. package/dist/computer-use/index.d.ts +1 -52
  19. package/dist/computer-use/index.d.ts.map +1 -1
  20. package/dist/computer-use/index.js +4 -50
  21. package/dist/computer-use/index.js.map +1 -1
  22. package/dist/conversation-orm/index.d.ts +1 -108
  23. package/dist/conversation-orm/index.d.ts.map +1 -1
  24. package/dist/conversation-orm/index.js +4 -214
  25. package/dist/conversation-orm/index.js.map +1 -1
  26. package/dist/doctor.d.ts +1 -1
  27. package/dist/doctor.d.ts.map +1 -1
  28. package/dist/doctor.js +4 -65
  29. package/dist/doctor.js.map +1 -1
  30. package/dist/eval/index.d.ts +1 -270
  31. package/dist/eval/index.d.ts.map +1 -1
  32. package/dist/eval/index.js +4 -509
  33. package/dist/eval/index.js.map +1 -1
  34. package/dist/gateway/index.d.ts +1 -10
  35. package/dist/gateway/index.d.ts.map +1 -1
  36. package/dist/gateway/index.js +4 -10
  37. package/dist/gateway/index.js.map +1 -1
  38. package/dist/index.d.ts +1 -66
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +4 -78
  41. package/dist/index.js.map +1 -1
  42. package/dist/mcp/index.d.ts +1 -15
  43. package/dist/mcp/index.d.ts.map +1 -1
  44. package/dist/mcp/index.js +4 -14
  45. package/dist/mcp/index.js.map +1 -1
  46. package/dist/memory-embedding/index.d.ts +1 -120
  47. package/dist/memory-embedding/index.d.ts.map +1 -1
  48. package/dist/memory-embedding/index.js +4 -228
  49. package/dist/memory-embedding/index.js.map +1 -1
  50. package/dist/memory-orm/index.d.ts +1 -117
  51. package/dist/memory-orm/index.d.ts.map +1 -1
  52. package/dist/memory-orm/index.js +4 -186
  53. package/dist/memory-orm/index.js.map +1 -1
  54. package/dist/node/index.d.ts +1 -2
  55. package/dist/node/index.d.ts.map +1 -1
  56. package/dist/node/index.js +4 -2
  57. package/dist/node/index.js.map +1 -1
  58. package/dist/observers.d.ts +1 -129
  59. package/dist/observers.d.ts.map +1 -1
  60. package/dist/observers.js +4 -39
  61. package/dist/observers.js.map +1 -1
  62. package/dist/react/index.d.ts +1 -15
  63. package/dist/react/index.d.ts.map +1 -1
  64. package/dist/react/index.js +4 -15
  65. package/dist/react/index.js.map +1 -1
  66. package/dist/server/index.d.ts +1 -1
  67. package/dist/server/index.d.ts.map +1 -1
  68. package/dist/server/index.js +4 -1
  69. package/dist/server/index.js.map +1 -1
  70. package/package.json +9 -13
  71. package/boost/guidelines.md +0 -260
  72. package/boost/skills/ai-agents/SKILL.md +0 -240
  73. package/boost/skills/ai-tools/SKILL.md +0 -260
  74. package/dist/agent-run-store.d.ts +0 -161
  75. package/dist/agent-run-store.d.ts.map +0 -1
  76. package/dist/agent-run-store.js +0 -98
  77. package/dist/agent-run-store.js.map +0 -1
  78. package/dist/agent-sse.d.ts +0 -153
  79. package/dist/agent-sse.d.ts.map +0 -1
  80. package/dist/agent-sse.js +0 -282
  81. package/dist/agent-sse.js.map +0 -1
  82. package/dist/agent.d.ts +0 -508
  83. package/dist/agent.d.ts.map +0 -1
  84. package/dist/agent.js +0 -1538
  85. package/dist/agent.js.map +0 -1
  86. package/dist/attachment.d.ts +0 -31
  87. package/dist/attachment.d.ts.map +0 -1
  88. package/dist/attachment.js +0 -89
  89. package/dist/attachment.js.map +0 -1
  90. package/dist/audio.d.ts +0 -45
  91. package/dist/audio.d.ts.map +0 -1
  92. package/dist/audio.js +0 -93
  93. package/dist/audio.js.map +0 -1
  94. package/dist/base64.d.ts +0 -7
  95. package/dist/base64.d.ts.map +0 -1
  96. package/dist/base64.js +0 -39
  97. package/dist/base64.js.map +0 -1
  98. package/dist/budget/pricing.d.ts +0 -124
  99. package/dist/budget/pricing.d.ts.map +0 -1
  100. package/dist/budget/pricing.js +0 -175
  101. package/dist/budget/pricing.js.map +0 -1
  102. package/dist/budget/storage.d.ts +0 -104
  103. package/dist/budget/storage.d.ts.map +0 -1
  104. package/dist/budget/storage.js +0 -0
  105. package/dist/budget/storage.js.map +0 -1
  106. package/dist/budget/with-budget.d.ts +0 -119
  107. package/dist/budget/with-budget.d.ts.map +0 -1
  108. package/dist/budget/with-budget.js +0 -175
  109. package/dist/budget/with-budget.js.map +0 -1
  110. package/dist/cached-embedding.d.ts +0 -14
  111. package/dist/cached-embedding.d.ts.map +0 -1
  112. package/dist/cached-embedding.js +0 -44
  113. package/dist/cached-embedding.js.map +0 -1
  114. package/dist/computer-use/actions.d.ts +0 -214
  115. package/dist/computer-use/actions.d.ts.map +0 -1
  116. package/dist/computer-use/actions.js +0 -48
  117. package/dist/computer-use/actions.js.map +0 -1
  118. package/dist/computer-use/errors.d.ts +0 -57
  119. package/dist/computer-use/errors.d.ts.map +0 -1
  120. package/dist/computer-use/errors.js +0 -76
  121. package/dist/computer-use/errors.js.map +0 -1
  122. package/dist/computer-use/playwright.d.ts +0 -76
  123. package/dist/computer-use/playwright.d.ts.map +0 -1
  124. package/dist/computer-use/playwright.js +0 -270
  125. package/dist/computer-use/playwright.js.map +0 -1
  126. package/dist/computer-use/tool.d.ts +0 -154
  127. package/dist/computer-use/tool.d.ts.map +0 -1
  128. package/dist/computer-use/tool.js +0 -210
  129. package/dist/computer-use/tool.js.map +0 -1
  130. package/dist/continuation-validation.d.ts +0 -85
  131. package/dist/continuation-validation.d.ts.map +0 -1
  132. package/dist/continuation-validation.js +0 -166
  133. package/dist/continuation-validation.js.map +0 -1
  134. package/dist/conversation-persistence.d.ts +0 -46
  135. package/dist/conversation-persistence.d.ts.map +0 -1
  136. package/dist/conversation-persistence.js +0 -176
  137. package/dist/conversation-persistence.js.map +0 -1
  138. package/dist/conversation.d.ts +0 -11
  139. package/dist/conversation.d.ts.map +0 -1
  140. package/dist/conversation.js +0 -55
  141. package/dist/conversation.js.map +0 -1
  142. package/dist/eval/fixtures.d.ts +0 -65
  143. package/dist/eval/fixtures.d.ts.map +0 -1
  144. package/dist/eval/fixtures.js +0 -110
  145. package/dist/eval/fixtures.js.map +0 -1
  146. package/dist/eval/html-reporter.d.ts +0 -25
  147. package/dist/eval/html-reporter.d.ts.map +0 -1
  148. package/dist/eval/html-reporter.js +0 -209
  149. package/dist/eval/html-reporter.js.map +0 -1
  150. package/dist/eval/json-reporter.d.ts +0 -43
  151. package/dist/eval/json-reporter.d.ts.map +0 -1
  152. package/dist/eval/json-reporter.js +0 -40
  153. package/dist/eval/json-reporter.js.map +0 -1
  154. package/dist/facade.d.ts +0 -96
  155. package/dist/facade.d.ts.map +0 -1
  156. package/dist/facade.js +0 -146
  157. package/dist/facade.js.map +0 -1
  158. package/dist/fake.d.ts +0 -201
  159. package/dist/fake.d.ts.map +0 -1
  160. package/dist/fake.js +0 -428
  161. package/dist/fake.js.map +0 -1
  162. package/dist/file-search.d.ts +0 -168
  163. package/dist/file-search.d.ts.map +0 -1
  164. package/dist/file-search.js +0 -158
  165. package/dist/file-search.js.map +0 -1
  166. package/dist/files.d.ts +0 -27
  167. package/dist/files.d.ts.map +0 -1
  168. package/dist/files.js +0 -44
  169. package/dist/files.js.map +0 -1
  170. package/dist/gateway/http-gateway-adapter.d.ts +0 -94
  171. package/dist/gateway/http-gateway-adapter.d.ts.map +0 -1
  172. package/dist/gateway/http-gateway-adapter.js +0 -106
  173. package/dist/gateway/http-gateway-adapter.js.map +0 -1
  174. package/dist/gateway/sse.d.ts +0 -28
  175. package/dist/gateway/sse.d.ts.map +0 -1
  176. package/dist/gateway/sse.js +0 -78
  177. package/dist/gateway/sse.js.map +0 -1
  178. package/dist/handoff.d.ts +0 -95
  179. package/dist/handoff.d.ts.map +0 -1
  180. package/dist/handoff.js +0 -78
  181. package/dist/handoff.js.map +0 -1
  182. package/dist/handoffs-driver.d.ts +0 -58
  183. package/dist/handoffs-driver.d.ts.map +0 -1
  184. package/dist/handoffs-driver.js +0 -103
  185. package/dist/handoffs-driver.js.map +0 -1
  186. package/dist/image.d.ts +0 -40
  187. package/dist/image.d.ts.map +0 -1
  188. package/dist/image.js +0 -109
  189. package/dist/image.js.map +0 -1
  190. package/dist/mcp/client-tools.d.ts +0 -39
  191. package/dist/mcp/client-tools.d.ts.map +0 -1
  192. package/dist/mcp/client-tools.js +0 -147
  193. package/dist/mcp/client-tools.js.map +0 -1
  194. package/dist/mcp/server-from-agent.d.ts +0 -24
  195. package/dist/mcp/server-from-agent.d.ts.map +0 -1
  196. package/dist/mcp/server-from-agent.js +0 -113
  197. package/dist/mcp/server-from-agent.js.map +0 -1
  198. package/dist/mcp/types.d.ts +0 -64
  199. package/dist/mcp/types.d.ts.map +0 -1
  200. package/dist/mcp/types.js +0 -6
  201. package/dist/mcp/types.js.map +0 -1
  202. package/dist/memory-extract.d.ts +0 -60
  203. package/dist/memory-extract.d.ts.map +0 -1
  204. package/dist/memory-extract.js +0 -163
  205. package/dist/memory-extract.js.map +0 -1
  206. package/dist/memory-inject.d.ts +0 -39
  207. package/dist/memory-inject.d.ts.map +0 -1
  208. package/dist/memory-inject.js +0 -135
  209. package/dist/memory-inject.js.map +0 -1
  210. package/dist/memory.d.ts +0 -55
  211. package/dist/memory.d.ts.map +0 -1
  212. package/dist/memory.js +0 -132
  213. package/dist/memory.js.map +0 -1
  214. package/dist/middleware.d.ts +0 -18
  215. package/dist/middleware.d.ts.map +0 -1
  216. package/dist/middleware.js +0 -72
  217. package/dist/middleware.js.map +0 -1
  218. package/dist/node/attachment.d.ts +0 -6
  219. package/dist/node/attachment.d.ts.map +0 -1
  220. package/dist/node/attachment.js +0 -35
  221. package/dist/node/attachment.js.map +0 -1
  222. package/dist/node/transcription.d.ts +0 -4
  223. package/dist/node/transcription.d.ts.map +0 -1
  224. package/dist/node/transcription.js +0 -8
  225. package/dist/node/transcription.js.map +0 -1
  226. package/dist/output.d.ts +0 -22
  227. package/dist/output.d.ts.map +0 -1
  228. package/dist/output.js +0 -60
  229. package/dist/output.js.map +0 -1
  230. package/dist/provider-tools.d.ts +0 -87
  231. package/dist/provider-tools.d.ts.map +0 -1
  232. package/dist/provider-tools.js +0 -189
  233. package/dist/provider-tools.js.map +0 -1
  234. package/dist/providers/anthropic.d.ts +0 -24
  235. package/dist/providers/anthropic.d.ts.map +0 -1
  236. package/dist/providers/anthropic.js +0 -405
  237. package/dist/providers/anthropic.js.map +0 -1
  238. package/dist/providers/azure.d.ts +0 -13
  239. package/dist/providers/azure.d.ts.map +0 -1
  240. package/dist/providers/azure.js +0 -15
  241. package/dist/providers/azure.js.map +0 -1
  242. package/dist/providers/bedrock.d.ts +0 -75
  243. package/dist/providers/bedrock.d.ts.map +0 -1
  244. package/dist/providers/bedrock.js +0 -181
  245. package/dist/providers/bedrock.js.map +0 -1
  246. package/dist/providers/cohere.d.ts +0 -13
  247. package/dist/providers/cohere.d.ts.map +0 -1
  248. package/dist/providers/cohere.js +0 -87
  249. package/dist/providers/cohere.js.map +0 -1
  250. package/dist/providers/deepseek.d.ts +0 -12
  251. package/dist/providers/deepseek.d.ts.map +0 -1
  252. package/dist/providers/deepseek.js +0 -15
  253. package/dist/providers/deepseek.js.map +0 -1
  254. package/dist/providers/elevenlabs.d.ts +0 -98
  255. package/dist/providers/elevenlabs.d.ts.map +0 -1
  256. package/dist/providers/elevenlabs.js +0 -229
  257. package/dist/providers/elevenlabs.js.map +0 -1
  258. package/dist/providers/google-cache-registry.d.ts +0 -132
  259. package/dist/providers/google-cache-registry.d.ts.map +0 -1
  260. package/dist/providers/google-cache-registry.js +0 -209
  261. package/dist/providers/google-cache-registry.js.map +0 -1
  262. package/dist/providers/google.d.ts +0 -38
  263. package/dist/providers/google.d.ts.map +0 -1
  264. package/dist/providers/google.js +0 -903
  265. package/dist/providers/google.js.map +0 -1
  266. package/dist/providers/groq.d.ts +0 -12
  267. package/dist/providers/groq.d.ts.map +0 -1
  268. package/dist/providers/groq.js +0 -15
  269. package/dist/providers/groq.js.map +0 -1
  270. package/dist/providers/jina.d.ts +0 -13
  271. package/dist/providers/jina.d.ts.map +0 -1
  272. package/dist/providers/jina.js +0 -90
  273. package/dist/providers/jina.js.map +0 -1
  274. package/dist/providers/mistral.d.ts +0 -13
  275. package/dist/providers/mistral.d.ts.map +0 -1
  276. package/dist/providers/mistral.js +0 -46
  277. package/dist/providers/mistral.js.map +0 -1
  278. package/dist/providers/ollama.d.ts +0 -11
  279. package/dist/providers/ollama.d.ts.map +0 -1
  280. package/dist/providers/ollama.js +0 -15
  281. package/dist/providers/ollama.js.map +0 -1
  282. package/dist/providers/openai.d.ts +0 -79
  283. package/dist/providers/openai.d.ts.map +0 -1
  284. package/dist/providers/openai.js +0 -792
  285. package/dist/providers/openai.js.map +0 -1
  286. package/dist/providers/openrouter.d.ts +0 -43
  287. package/dist/providers/openrouter.d.ts.map +0 -1
  288. package/dist/providers/openrouter.js +0 -21
  289. package/dist/providers/openrouter.js.map +0 -1
  290. package/dist/providers/voyage.d.ts +0 -91
  291. package/dist/providers/voyage.d.ts.map +0 -1
  292. package/dist/providers/voyage.js +0 -166
  293. package/dist/providers/voyage.js.map +0 -1
  294. package/dist/providers/xai.d.ts +0 -12
  295. package/dist/providers/xai.d.ts.map +0 -1
  296. package/dist/providers/xai.js +0 -15
  297. package/dist/providers/xai.js.map +0 -1
  298. package/dist/queue-job.d.ts +0 -100
  299. package/dist/queue-job.d.ts.map +0 -1
  300. package/dist/queue-job.js +0 -185
  301. package/dist/queue-job.js.map +0 -1
  302. package/dist/react/agent-run.d.ts +0 -111
  303. package/dist/react/agent-run.d.ts.map +0 -1
  304. package/dist/react/agent-run.js +0 -107
  305. package/dist/react/agent-run.js.map +0 -1
  306. package/dist/react/useAgentRun.d.ts +0 -68
  307. package/dist/react/useAgentRun.d.ts.map +0 -1
  308. package/dist/react/useAgentRun.js +0 -125
  309. package/dist/react/useAgentRun.js.map +0 -1
  310. package/dist/registry.d.ts +0 -45
  311. package/dist/registry.d.ts.map +0 -1
  312. package/dist/registry.js +0 -131
  313. package/dist/registry.js.map +0 -1
  314. package/dist/rerank.d.ts +0 -20
  315. package/dist/rerank.d.ts.map +0 -1
  316. package/dist/rerank.js +0 -40
  317. package/dist/rerank.js.map +0 -1
  318. package/dist/resume-approval.d.ts +0 -30
  319. package/dist/resume-approval.d.ts.map +0 -1
  320. package/dist/resume-approval.js +0 -147
  321. package/dist/resume-approval.js.map +0 -1
  322. package/dist/sanitize-conversation.d.ts +0 -43
  323. package/dist/sanitize-conversation.d.ts.map +0 -1
  324. package/dist/sanitize-conversation.js +0 -85
  325. package/dist/sanitize-conversation.js.map +0 -1
  326. package/dist/scoped-tool.d.ts +0 -98
  327. package/dist/scoped-tool.d.ts.map +0 -1
  328. package/dist/scoped-tool.js +0 -174
  329. package/dist/scoped-tool.js.map +0 -1
  330. package/dist/server/provider.d.ts +0 -22
  331. package/dist/server/provider.d.ts.map +0 -1
  332. package/dist/server/provider.js +0 -194
  333. package/dist/server/provider.js.map +0 -1
  334. package/dist/similarity-search.d.ts +0 -163
  335. package/dist/similarity-search.d.ts.map +0 -1
  336. package/dist/similarity-search.js +0 -147
  337. package/dist/similarity-search.js.map +0 -1
  338. package/dist/sub-agent-run-store.d.ts +0 -157
  339. package/dist/sub-agent-run-store.d.ts.map +0 -1
  340. package/dist/sub-agent-run-store.js +0 -87
  341. package/dist/sub-agent-run-store.js.map +0 -1
  342. package/dist/tool-execution.d.ts +0 -16
  343. package/dist/tool-execution.d.ts.map +0 -1
  344. package/dist/tool-execution.js +0 -498
  345. package/dist/tool-execution.js.map +0 -1
  346. package/dist/tool-helpers.d.ts +0 -77
  347. package/dist/tool-helpers.d.ts.map +0 -1
  348. package/dist/tool-helpers.js +0 -117
  349. package/dist/tool-helpers.js.map +0 -1
  350. package/dist/tool.d.ts +0 -216
  351. package/dist/tool.d.ts.map +0 -1
  352. package/dist/tool.js +0 -175
  353. package/dist/tool.js.map +0 -1
  354. package/dist/transcription.d.ts +0 -42
  355. package/dist/transcription.d.ts.map +0 -1
  356. package/dist/transcription.js +0 -77
  357. package/dist/transcription.js.map +0 -1
  358. package/dist/types.d.ts +0 -1020
  359. package/dist/types.d.ts.map +0 -1
  360. package/dist/types.js +0 -2
  361. package/dist/types.js.map +0 -1
  362. package/dist/util/hash.d.ts +0 -11
  363. package/dist/util/hash.d.ts.map +0 -1
  364. package/dist/util/hash.js +0 -23
  365. package/dist/util/hash.js.map +0 -1
  366. package/dist/vector-stores/index.d.ts +0 -96
  367. package/dist/vector-stores/index.d.ts.map +0 -1
  368. package/dist/vector-stores/index.js +0 -153
  369. package/dist/vector-stores/index.js.map +0 -1
  370. package/dist/vercel-protocol.d.ts +0 -18
  371. package/dist/vercel-protocol.d.ts.map +0 -1
  372. package/dist/vercel-protocol.js +0 -75
  373. package/dist/vercel-protocol.js.map +0 -1
  374. package/dist/zod-to-json-schema.d.ts +0 -16
  375. package/dist/zod-to-json-schema.d.ts.map +0 -1
  376. package/dist/zod-to-json-schema.js +0 -17
  377. package/dist/zod-to-json-schema.js.map +0 -1
@@ -1,260 +0,0 @@
1
- # @rudderjs/ai
2
-
3
- ## Overview
4
-
5
- AI engine for Rudder providing a provider-agnostic agent framework with tool calling, streaming, middleware, attachments, conversation persistence, structured output, and queued execution. Supports Anthropic, OpenAI, Google, Ollama, DeepSeek, xAI, Groq, Mistral, and Azure OpenAI out of the box. Models are addressed via `provider/model` strings (e.g. `anthropic/claude-sonnet-4-5`), and the `AiRegistry` handles provider resolution and failover.
6
-
7
- ## Key Patterns
8
-
9
- ### Creating Agents
10
-
11
- Extend the `Agent` class for reusable agents, or use `agent()` for inline one-offs:
12
-
13
- ```ts
14
- class SearchAgent extends Agent implements HasTools, HasMiddleware {
15
- instructions() { return 'You are a search assistant.' }
16
- model() { return 'anthropic/claude-sonnet-4-5' }
17
- tools() { return [searchTool] }
18
- middleware() { return [loggingMiddleware] }
19
- }
20
- const response = await new SearchAgent().prompt('Find users named John')
21
-
22
- // Inline agents
23
- await agent({ instructions: 'You are helpful.', tools: [weatherTool] }).prompt('Hello')
24
- await agent('You are helpful.').prompt('Hello') // simplest form
25
- ```
26
-
27
- ### Using Providers (Anthropic, OpenAI, Google, etc.)
28
-
29
- Configure providers in `config/ai.ts`. The Node-only `AiProvider` lives at `@rudderjs/ai/server` (the main `@rudderjs/ai` entry is runtime-agnostic and has no provider class):
30
-
31
- ```ts
32
- // config/ai.ts — providers: anthropic, openai, google, ollama, deepseek, xai, groq, mistral, azure, openrouter, bedrock
33
- import type { AiConfig } from '@rudderjs/ai'
34
-
35
- export default {
36
- default: 'anthropic/claude-sonnet-4-5',
37
- providers: {
38
- anthropic: { apiKey: process.env.ANTHROPIC_API_KEY },
39
- openai: { apiKey: process.env.OPENAI_API_KEY },
40
- ollama: { driver: 'ollama', baseUrl: 'http://localhost:11434' },
41
- },
42
- } satisfies AiConfig
43
-
44
- // bootstrap/providers.ts
45
- import { AiProvider } from '@rudderjs/ai/server'
46
- export default [AiProvider]
47
- ```
48
-
49
- Provider auto-discovery (`defaultProviders()`) finds `AiProvider` automatically via the `rudderjs.providerSubpath` field in `@rudderjs/ai/package.json` — no manual subpath import needed when using auto-discovery.
50
-
51
- Agents support failover: `failover() { return ['openai/gpt-4o'] }`. The same pattern is on the media generators: `ImageGenerator.of('...').model('openai/dall-e-3').failover('google/imagen-3').generate()` (also `AudioGenerator`, `Transcription`).
52
-
53
- **Prompt caching.** Mark stable parts of the prompt as cacheable — providers translate to native primitives (Anthropic `cache_control`, OpenAI `prompt_cache_key`, Google `cachedContent`).
54
-
55
- ```ts
56
- class SupportAgent extends Agent {
57
- cacheable() { return { instructions: true, tools: true, messages: 2 } }
58
- // ^ cache first 2 messages
59
- }
60
- ```
61
-
62
- Per-call override: `agent.prompt(input, { cache: false })` to disable; `{ cache: {...} }` to replace. All three big providers (Anthropic, OpenAI, Google) are wired up. The `ttl` field is Google-only and defaults to `'1h'`; Anthropic and OpenAI ignore it.
63
-
64
- ### Tools
65
-
66
- Define tools with Zod schemas. Tools are either `server` (executed on backend) or `client` (forwarded to frontend):
67
-
68
- ```ts
69
- const weatherTool = toolDefinition({
70
- name: 'get_weather',
71
- description: 'Get weather for a location',
72
- inputSchema: z.object({ location: z.string() }),
73
- }).server(async ({ location }) => ({ temp: 72, unit: 'F', location }))
74
- ```
75
-
76
- ### Subagents (`agent.asTool()`)
77
-
78
- Wrap one agent as a tool another agent can call. Defaults: `inputSchema = { prompt: string }`, `modelOutput = response.text`. Pass `inputSchema` + `prompt` for a typed schema.
79
-
80
- ```ts
81
- class Planner extends Agent implements HasTools {
82
- instructions() { return 'You break work into steps. Use `research` for facts.' }
83
- tools() {
84
- return [
85
- new ResearchAgent().asTool({
86
- name: 'research',
87
- description: 'Research a topic in depth.',
88
- }),
89
- ]
90
- }
91
- }
92
- ```
93
-
94
- By default the subagent runs via `prompt()` (non-streaming). Pass `streaming: true` to surface inner progress as `tool-update` chunks (default projection emits `agent_start` / `tool_call` / `agent_done`, plus `agent_pending_approval` for inner approval gates); pass `(chunk) => SubAgentUpdate | null` for a custom projector. To propagate inner pauses upward through the parent loop, also pass `suspendable: { runStore }` (suspend without streaming throws at builder time) — `asTool` handles BOTH client-tool pauses AND approval pauses symmetrically, persisting a snapshot with a `pauseKind: 'client_tool' | 'approval'` discriminator. The host's continuation calls `Agent.resumeAsTool(subRunId, results, { runStore, agent })` for client-tool resumes, or `Agent.resumeAsTool(subRunId, [], { runStore, agent, approvedToolCallIds: [...] })` (or `rejectedToolCallIds`) for approval resumes. The returned `'paused'` variant carries `pauseKind` so the host can route the next round-trip correctly. `InMemorySubAgentRunStore` works for tests; `CachedSubAgentRunStore` plugs into `@rudderjs/cache` for multi-worker persistence.
95
-
96
- ### Middleware
97
-
98
- Middleware hooks into the agent loop lifecycle. Hooks: `onConfig`, `onStart`, `onIteration`, `onChunk`, `onBeforeToolCall`, `onAfterToolCall`, `onToolPhaseComplete`, `onUsage`, `onAbort`, `onError`, `onFinish`.
99
-
100
- ```ts
101
- const loggingMiddleware: AiMiddleware = {
102
- onStart(ctx) { console.log(`[AI] Request ${ctx.requestId} started`) },
103
- onUsage(ctx, usage) { console.log(`[AI] Tokens: ${usage.totalTokens}`) },
104
- onBeforeToolCall(ctx, toolName, args) {
105
- if (toolName === 'dangerous_tool') return { type: 'skip', result: 'Tool disabled' }
106
- return undefined // continue normally
107
- },
108
- onChunk(ctx, chunk) { return chunk }, // transform or return null to drop
109
- }
110
- ```
111
-
112
- ### Attachments
113
-
114
- Send images and documents alongside prompts. The main entry has runtime-agnostic factories (`fromBase64`, `fromUrl`, `fromString`); for path-based loading import from `@rudderjs/ai/node`:
115
-
116
- ```ts
117
- import { Image, Document } from '@rudderjs/ai'
118
- import { imageFromPath } from '@rudderjs/ai/node'
119
-
120
- const img = await imageFromPath('./screenshot.png') // Node-only
121
- const doc = await Document.fromUrl('https://example.com/report.pdf')
122
-
123
- await myAgent.prompt('Describe this image and summarize the doc', {
124
- attachments: [img.toAttachment(), doc.toAttachment()],
125
- })
126
- ```
127
-
128
- ### Conversations
129
-
130
- Persist multi-turn conversations with `ConversationStore`. Register via `setConversationStore()` or pass `conversations` in AI config:
131
-
132
- ```ts
133
- setConversationStore(new MemoryConversationStore())
134
- const response = await myAgent.forUser('user-123').prompt('Hello') // creates conversation
135
- const follow = await myAgent.continue(response.conversationId).prompt('Follow up')
136
- ```
137
-
138
- For chat agents that should always auto-persist for the active user, override `conversational()` on the class — `agent.prompt(input)` then auto-loads + auto-saves without each caller passing the user id:
139
-
140
- ```ts
141
- class ChatAgent extends Agent {
142
- conversational() { return { user: Auth.user()?.id } } // null user → opt-out
143
- }
144
- await new ChatAgent().prompt('Hi') // auto-loads thread
145
- await new ChatAgent().prompt('still you?') // resumes per (user, class)
146
- ```
147
-
148
- Returning `false` (default) keeps the agent stateless. Optional `historyLimit: N` caps loaded messages. Per-call `{ conversation: false }` opts out; `forUser`/`continue` always win.
149
-
150
- ### Streaming
151
-
152
- Use `.stream()` for real-time token delivery:
153
-
154
- ```ts
155
- const { stream, response } = myAgent.stream('Write a story')
156
-
157
- for await (const chunk of stream) {
158
- if (chunk.type === 'text-delta') process.stdout.write(chunk.text ?? '')
159
- if (chunk.type === 'tool-call') console.log('Tool called:', chunk.toolCall)
160
- }
161
-
162
- const final = await response // full AgentResponse after stream ends
163
- ```
164
-
165
- ### MCP integration (`@rudderjs/ai/mcp`)
166
-
167
- Bridge agents and Model Context Protocol servers in both directions. Optional peer: `@modelcontextprotocol/sdk`.
168
-
169
- **Consume MCP tools in an agent:**
170
-
171
- ```ts
172
- import { mcpClientTools } from '@rudderjs/ai/mcp'
173
-
174
- const tools = await mcpClientTools('https://api.example.com/mcp')
175
- // or: await mcpClientTools({ command: 'npx', args: ['some-mcp-server'] })
176
-
177
- class ResearchAgent extends Agent {
178
- instructions() { return 'You can call remote MCP tools.' }
179
- tools() { return tools }
180
- }
181
- ```
182
-
183
- **Expose an agent as an MCP server** (callable from Claude Desktop, Cursor, etc.):
184
-
185
- ```ts
186
- import { mcpServerFromAgent } from '@rudderjs/ai/mcp'
187
- import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
188
-
189
- // Default: each agent.tools() entry becomes an MCP tool
190
- const server = await mcpServerFromAgent(MyAgent)
191
-
192
- // Or expose the whole agent as one prompt-tool
193
- const promptServer = await mcpServerFromAgent(MyAgent, { expose: 'agent' })
194
-
195
- await server.connect(new StdioServerTransport())
196
- ```
197
-
198
- When mcpClientTools owns the underlying client (URL or stdio transport), the returned array exposes `close()` for shutdown — call it when the agent is done. With a caller-provided client, lifecycle stays with the caller.
199
-
200
- ### Queued prompts + live broadcast (`agent.queue().broadcast()`)
201
-
202
- `agent.queue(input)` ships the run to the background queue (`@rudderjs/queue`). Add `.broadcast(channel)` to stream chunks to a `@rudderjs/broadcast` channel as the job runs — background AI work + live UI without polling.
203
-
204
- ```ts
205
- import { agent } from '@rudderjs/ai'
206
-
207
- // Plain queued — no live updates
208
- await agent('You help with refunds.')
209
- .queue('Process refund for order #1234')
210
- .onQueue('ai')
211
- .send()
212
-
213
- // Stream chunks to the user's channel as they arrive
214
- await new SupportAgent()
215
- .queue('Help with refund request')
216
- .broadcast(`user.${userId}.support`)
217
- .send()
218
- ```
219
-
220
- Subscribers on the channel receive `chunk` events (one per `StreamChunk`), then a `done` event with the final `AgentResponse`, or an `error` event on failure. Optional `eventPrefix` namespaces events: `.broadcast('chan', { eventPrefix: 'agent.' })` emits `agent.chunk` / `agent.done` / `agent.error`.
221
-
222
- `@rudderjs/broadcast`'s in-process WS state is process-local — same-process web + `queue:work` works out of the box; a separate worker process needs a future pub/sub bridge.
223
-
224
- ### Structured Output
225
-
226
- Use `Output` to constrain responses to typed schemas:
227
-
228
- ```ts
229
- import { Output } from '@rudderjs/ai'
230
-
231
- const sentiment = Output.choice({ options: ['positive', 'negative', 'neutral'] as const })
232
- const extraction = Output.object({ schema: z.object({ name: z.string(), age: z.number() }) })
233
- const items = Output.array({ element: z.object({ title: z.string() }) })
234
- ```
235
-
236
- ## Common Pitfalls
237
-
238
- - **Model string format**: Always use `provider/model` (e.g. `anthropic/claude-sonnet-4-5`). A bare model name throws.
239
- - **Optional SDK deps**: Provider SDKs (`@anthropic-ai/sdk`, `openai`, `@google/genai`) are optional dependencies. Install the ones you need.
240
- - **ConversationStore required for `.forUser()`/`.continue()`**: Call `setConversationStore()` or pass `conversations` in the AI config. Without it, conversation methods throw.
241
- - **Tool loop limits**: `maxSteps()` defaults to 20. If the agent hits the limit it stops silently. Increase it for complex multi-tool workflows.
242
- - **Parallel tool execution**: when the model emits multiple tool calls in a single step, their `execute()` functions run concurrently by default. Streamed chunks still emit in tool-call order. Opt out via `prompt(..., { parallelTools: false })` or override `parallelTools()` on the agent class for tools with non-idempotent shared state.
243
- - **Streaming response access**: `await response` only resolves after the stream is fully consumed. Always iterate the stream first.
244
- - **Embeddings**: Only providers that implement `createEmbedding()` support `AI.embed()`. Currently OpenAI-compatible providers.
245
-
246
- ## Key Imports
247
-
248
- ```ts
249
- import { AiProvider } from '@rudderjs/ai/server' // service provider (Node only)
250
- import { Agent, agent, ConversableAgent } from '@rudderjs/ai' // agents
251
- import { AI } from '@rudderjs/ai' // facade (AI.prompt, AI.agent, AI.embed)
252
- import { toolDefinition } from '@rudderjs/ai' // tool builder
253
- import { Image, Document } from '@rudderjs/ai' // attachments
254
- import { MemoryConversationStore, setConversationStore } from '@rudderjs/ai'
255
- import { Output } from '@rudderjs/ai' // structured output
256
- import { AiRegistry } from '@rudderjs/ai' // provider registry
257
- import { mcpClientTools, mcpServerFromAgent } from '@rudderjs/ai/mcp' // MCP bridge (Node)
258
- import { stepCountIs, hasToolCall } from '@rudderjs/ai' // stop conditions
259
- import type { AgentResponse, AiConfig, AiMiddleware, AnyTool, HasTools, HasMiddleware } from '@rudderjs/ai'
260
- ```
@@ -1,240 +0,0 @@
1
- ---
2
- name: ai-agents
3
- description: Building AI agents with tools, streaming, conversation memory, approval flows, and middleware in Rudder
4
- license: MIT
5
- appliesTo:
6
- - '@rudderjs/ai'
7
- trigger: building an `Agent` class, calling `Agent.prompt()`/`.stream()`, defining `tools()` or `middleware()`, or wiring conversations / failover
8
- skip: writing a tool definition by itself — load `ai-tools` instead
9
- metadata:
10
- author: rudderjs
11
- ---
12
-
13
- # AI Agents
14
-
15
- ## When to use this skill
16
-
17
- Load this skill when you need to build an AI agent, run prompts with tool loops, stream responses, persist conversations, use approval gates, or queue agent work for background execution.
18
-
19
- ## Key concepts
20
-
21
- - **Agent base class**: Extend `Agent` and implement `instructions()`. Optionally override `model()`, `tools()`, `maxSteps()`, `stopWhen()`, `temperature()`, `middleware()`.
22
- - **Anonymous agents**: Use the `agent()` function for inline, one-off agents without a class.
23
- - **Tool loop**: The agent runs a loop: prompt model -> execute tool calls -> feed results back -> repeat until stop condition.
24
- - **Streaming**: `agent.stream()` returns `{ stream: AsyncIterable<StreamChunk>, response: Promise<AgentResponse> }`.
25
- - **Conversations**: `agent.forUser(id).prompt()` or `agent.continue(conversationId).prompt()` for persistent memory.
26
- - **Provider/model string**: Format is `'provider/model'` (e.g. `'anthropic/claude-sonnet-4-5'`, `'openai/gpt-4o'`).
27
- - **Finish reasons**: `'stop'`, `'tool_calls'`, `'length'`, `'client_tool_calls'`, `'tool_approval_required'`.
28
-
29
- ## Step-by-step
30
-
31
- ### 1. Create an agent class
32
-
33
- ```ts
34
- // app/Agents/ResearchAgent.ts
35
- import { Agent } from '@rudderjs/ai'
36
- import type { HasTools, AnyTool } from '@rudderjs/ai'
37
-
38
- export class ResearchAgent extends Agent implements HasTools {
39
- instructions(): string {
40
- return `You are a research assistant. Use the search tool to find
41
- information and summarize your findings clearly.`
42
- }
43
-
44
- model(): string {
45
- return 'anthropic/claude-sonnet-4-5'
46
- }
47
-
48
- tools(): AnyTool[] {
49
- return [searchTool, summarizeTool]
50
- }
51
-
52
- maxSteps(): number {
53
- return 10
54
- }
55
- }
56
- ```
57
-
58
- ### 2. Run a prompt (non-streaming)
59
-
60
- ```ts
61
- const agent = new ResearchAgent()
62
-
63
- const response = await agent.prompt('What is Rudder?')
64
- console.log(response.text) // final text output
65
- console.log(response.steps) // array of AgentStep
66
- console.log(response.usage) // { promptTokens, completionTokens, totalTokens }
67
- ```
68
-
69
- ### 3. Stream a response
70
-
71
- ```ts
72
- const { stream, response } = agent.stream('Explain TypeScript decorators')
73
-
74
- for await (const chunk of stream) {
75
- switch (chunk.type) {
76
- case 'text-delta':
77
- process.stdout.write(chunk.text ?? '')
78
- break
79
- case 'tool-call':
80
- console.log(`Calling tool: ${chunk.toolCall?.name}`)
81
- break
82
- case 'tool-result':
83
- console.log(`Tool result:`, chunk.result)
84
- break
85
- case 'tool-update':
86
- console.log(`Progress:`, chunk.update)
87
- break
88
- case 'finish':
89
- console.log(`Done: ${chunk.finishReason}`)
90
- break
91
- }
92
- }
93
-
94
- const finalResponse = await response
95
- ```
96
-
97
- ### 4. Use anonymous agents (inline)
98
-
99
- ```ts
100
- import { agent } from '@rudderjs/ai'
101
-
102
- // Simple string instructions
103
- const response = await agent('You are a helpful assistant.').prompt('Hello')
104
-
105
- // With tools and model
106
- const response = await agent({
107
- instructions: 'You are a search assistant.',
108
- tools: [searchTool],
109
- model: 'anthropic/claude-sonnet-4-5',
110
- }).prompt('Find users named John')
111
- ```
112
-
113
- ### 5. Conversation persistence
114
-
115
- ```ts
116
- const myAgent = new ResearchAgent()
117
-
118
- // Start a new conversation for a user
119
- const response1 = await myAgent.forUser('user-123').prompt('What is TypeScript?')
120
- const convId = response1.conversationId!
121
-
122
- // Continue the same conversation
123
- const response2 = await myAgent.continue(convId).prompt('Tell me more about generics')
124
- // The agent sees the full conversation history
125
-
126
- // Streaming with conversations
127
- const { stream, response } = myAgent.forUser('user-123').stream('Explain async/await')
128
- ```
129
-
130
- A `ConversationStore` must be registered. The built-in `MemoryConversationStore` works for dev; implement the `ConversationStore` interface for production (database-backed).
131
-
132
- ### 6. Stop conditions
133
-
134
- ```ts
135
- import { Agent, stepCountIs, hasToolCall } from '@rudderjs/ai'
136
-
137
- class MyAgent extends Agent {
138
- instructions() { return 'You are helpful.' }
139
-
140
- stopWhen() {
141
- return [
142
- stepCountIs(5), // stop after 5 iterations
143
- hasToolCall('final_answer'), // stop when this tool is called
144
- ]
145
- // Multiple conditions use OR logic -- stops when any is true
146
- }
147
- }
148
- ```
149
-
150
- ### 7. Per-step control (prepareStep)
151
-
152
- ```ts
153
- class AdaptiveAgent extends Agent {
154
- instructions() { return 'You are helpful.' }
155
-
156
- prepareStep(ctx: { stepNumber: number; steps: AgentStep[]; messages: AiMessage[] }) {
157
- if (ctx.stepNumber > 3) {
158
- return { model: 'anthropic/claude-haiku-3' } // cheaper model for later steps
159
- }
160
- return {}
161
- }
162
- }
163
- ```
164
-
165
- ### 8. Middleware
166
-
167
- ```ts
168
- import type { AiMiddleware } from '@rudderjs/ai'
169
-
170
- const loggingMiddleware: AiMiddleware = {
171
- name: 'logging',
172
- onStart(ctx) { console.log(`Agent started, model: ${ctx.model}`) },
173
- onChunk(ctx, chunk) {
174
- if (chunk.type === 'text-delta') process.stdout.write(chunk.text ?? '')
175
- return chunk // return null to suppress the chunk
176
- },
177
- onBeforeToolCall(ctx, toolName, args) {
178
- console.log(`Calling ${toolName}`, args)
179
- // Return { type: 'skip', result: 'mocked' } to skip execution
180
- // Return { type: 'abort', reason: 'blocked' } to abort the loop
181
- },
182
- onAfterToolCall(ctx, toolName, args, result) {
183
- console.log(`${toolName} returned`, result)
184
- },
185
- onUsage(ctx, usage) {
186
- console.log(`Tokens: ${usage.totalTokens}`)
187
- },
188
- onError(ctx, error) {
189
- console.error('Agent error:', error)
190
- },
191
- }
192
-
193
- class MyAgent extends Agent implements HasMiddleware {
194
- instructions() { return 'You are helpful.' }
195
- middleware() { return [loggingMiddleware] }
196
- }
197
- ```
198
-
199
- ### 9. Queue for background execution
200
-
201
- ```ts
202
- const myAgent = new ResearchAgent()
203
-
204
- // Queue for async processing (requires @rudderjs/queue)
205
- myAgent.queue('Analyze this dataset').dispatch()
206
- ```
207
-
208
- ### 10. Failover providers
209
-
210
- ```ts
211
- class ResilientAgent extends Agent {
212
- instructions() { return 'You are helpful.' }
213
- model() { return 'anthropic/claude-sonnet-4-5' }
214
- failover() { return ['openai/gpt-4o', 'google/gemini-2.0-flash'] }
215
- }
216
- ```
217
-
218
- ### 11. Attachments (images/documents)
219
-
220
- ```ts
221
- const response = await agent('Describe this image.').prompt('What do you see?', {
222
- attachments: [
223
- { type: 'image', data: base64String, mimeType: 'image/png' },
224
- { type: 'document', data: pdfBase64, mimeType: 'application/pdf', name: 'report.pdf' },
225
- ],
226
- })
227
- ```
228
-
229
- ## Examples
230
-
231
- See `playground/app/Agents/ResearchAgent.ts` for a working agent class.
232
-
233
- ## Common pitfalls
234
-
235
- - **Provider SDK not installed**: Each provider's SDK is an optional peer dependency. Install only what you use: `@anthropic-ai/sdk`, `openai`, `@google/genai`.
236
- - **No default model**: If `model()` returns `undefined`, the agent uses the registry default from `config/ai.ts`. Make sure one is configured.
237
- - **ConversationStore missing**: `forUser()` / `continue()` throw if no `ConversationStore` is registered. Register one via `setConversationStore()` or through the AI service provider.
238
- - **maxSteps exhaustion**: Default is 20 iterations. If the agent hits `maxSteps`, it stops with whatever text it has. Override `maxSteps()` for agents that need more iterations.
239
- - **Streaming vs non-streaming tool updates**: `yield` from an `async function*` tool execute emits `tool-update` chunks during streaming. In non-streaming `prompt()`, yields are silently drained.
240
- - **Client tools**: Tools without an `execute` function are client tools. The loop pauses with `finishReason: 'client_tool_calls'` and returns `pendingClientToolCalls` for browser-side execution.