@tambo-ai/react 0.68.0 → 0.69.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 (326) hide show
  1. package/README.md +1 -1
  2. package/dist/context-helpers/context-helpers.test.js +16 -4
  3. package/dist/context-helpers/context-helpers.test.js.map +1 -1
  4. package/dist/context-helpers/current-interactables-context-helper.d.ts +2 -2
  5. package/dist/context-helpers/current-interactables-context-helper.d.ts.map +1 -1
  6. package/dist/context-helpers/current-interactables-context-helper.js +31 -15
  7. package/dist/context-helpers/current-interactables-context-helper.js.map +1 -1
  8. package/dist/context-helpers/registry.d.ts +2 -2
  9. package/dist/context-helpers/registry.d.ts.map +1 -1
  10. package/dist/context-helpers/registry.js.map +1 -1
  11. package/dist/context-helpers/types.d.ts +2 -2
  12. package/dist/context-helpers/types.d.ts.map +1 -1
  13. package/dist/context-helpers/types.js.map +1 -1
  14. package/dist/hooks/use-message-images.test.js +174 -37
  15. package/dist/hooks/use-message-images.test.js.map +1 -1
  16. package/dist/hooks/use-tambo-voice.d.ts +1 -1
  17. package/dist/hooks/use-tambo-voice.js +1 -1
  18. package/dist/hooks/use-tambo-voice.js.map +1 -1
  19. package/dist/hooks/use-tambo-voice.test.d.ts +2 -0
  20. package/dist/hooks/use-tambo-voice.test.d.ts.map +1 -0
  21. package/dist/hooks/use-tambo-voice.test.js +239 -0
  22. package/dist/hooks/use-tambo-voice.test.js.map +1 -0
  23. package/dist/index.d.ts +2 -2
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js.map +1 -1
  26. package/dist/mcp/elicitation.d.ts.map +1 -1
  27. package/dist/mcp/elicitation.js +12 -0
  28. package/dist/mcp/elicitation.js.map +1 -1
  29. package/dist/mcp/elicitation.test.js +8 -1
  30. package/dist/mcp/elicitation.test.js.map +1 -1
  31. package/dist/mcp/mcp-client.d.ts +6 -10
  32. package/dist/mcp/mcp-client.d.ts.map +1 -1
  33. package/dist/mcp/mcp-client.js.map +1 -1
  34. package/dist/mcp/mcp-hooks.d.ts +12 -60
  35. package/dist/mcp/mcp-hooks.d.ts.map +1 -1
  36. package/dist/mcp/mcp-hooks.js +90 -10
  37. package/dist/mcp/mcp-hooks.js.map +1 -1
  38. package/dist/mcp/mcp-hooks.test.js +423 -0
  39. package/dist/mcp/mcp-hooks.test.js.map +1 -1
  40. package/dist/mcp/tambo-mcp-provider.d.ts.map +1 -1
  41. package/dist/mcp/tambo-mcp-provider.js +3 -0
  42. package/dist/mcp/tambo-mcp-provider.js.map +1 -1
  43. package/dist/mcp/tambo-mcp-provider.test.js +37 -0
  44. package/dist/mcp/tambo-mcp-provider.test.js.map +1 -1
  45. package/dist/model/component-metadata.d.ts +53 -20
  46. package/dist/model/component-metadata.d.ts.map +1 -1
  47. package/dist/model/component-metadata.js.map +1 -1
  48. package/dist/model/tambo-interactable.d.ts +6 -0
  49. package/dist/model/tambo-interactable.d.ts.map +1 -1
  50. package/dist/model/tambo-interactable.js.map +1 -1
  51. package/dist/providers/index.d.ts +1 -1
  52. package/dist/providers/index.d.ts.map +1 -1
  53. package/dist/providers/index.js.map +1 -1
  54. package/dist/providers/tambo-client-provider.d.ts +8 -0
  55. package/dist/providers/tambo-client-provider.d.ts.map +1 -1
  56. package/dist/providers/tambo-client-provider.js +10 -11
  57. package/dist/providers/tambo-client-provider.js.map +1 -1
  58. package/dist/providers/tambo-client-provider.test.d.ts +2 -0
  59. package/dist/providers/tambo-client-provider.test.d.ts.map +1 -0
  60. package/dist/providers/tambo-client-provider.test.js +208 -0
  61. package/dist/providers/tambo-client-provider.test.js.map +1 -0
  62. package/dist/providers/tambo-context-attachment-provider.d.ts +34 -92
  63. package/dist/providers/tambo-context-attachment-provider.d.ts.map +1 -1
  64. package/dist/providers/tambo-context-attachment-provider.js +62 -105
  65. package/dist/providers/tambo-context-attachment-provider.js.map +1 -1
  66. package/dist/providers/tambo-context-attachment-provider.test.js +229 -463
  67. package/dist/providers/tambo-context-attachment-provider.test.js.map +1 -1
  68. package/dist/providers/tambo-interactable-provider.d.ts +2 -0
  69. package/dist/providers/tambo-interactable-provider.d.ts.map +1 -1
  70. package/dist/providers/tambo-interactable-provider.js +29 -4
  71. package/dist/providers/tambo-interactable-provider.js.map +1 -1
  72. package/dist/providers/tambo-interactable-provider.test.js +1 -1
  73. package/dist/providers/tambo-interactable-provider.test.js.map +1 -1
  74. package/dist/providers/tambo-interactables-additional-context.test.js +2 -5
  75. package/dist/providers/tambo-interactables-additional-context.test.js.map +1 -1
  76. package/dist/providers/tambo-provider.d.ts +2 -3
  77. package/dist/providers/tambo-provider.d.ts.map +1 -1
  78. package/dist/providers/tambo-provider.js +5 -6
  79. package/dist/providers/tambo-provider.js.map +1 -1
  80. package/dist/providers/tambo-registry-provider.test.js +16 -0
  81. package/dist/providers/tambo-registry-provider.test.js.map +1 -1
  82. package/dist/providers/tambo-registry-schema-compat.test.js +31 -0
  83. package/dist/providers/tambo-registry-schema-compat.test.js.map +1 -1
  84. package/dist/providers/tambo-thread-input-provider.d.ts +1 -1
  85. package/dist/providers/tambo-thread-input-provider.d.ts.map +1 -1
  86. package/dist/providers/tambo-thread-input-provider.js +5 -1
  87. package/dist/providers/tambo-thread-input-provider.js.map +1 -1
  88. package/dist/providers/tambo-thread-provider-initial-messages.test.js +84 -2
  89. package/dist/providers/tambo-thread-provider-initial-messages.test.js.map +1 -1
  90. package/dist/providers/tambo-thread-provider.d.ts.map +1 -1
  91. package/dist/providers/tambo-thread-provider.js +53 -42
  92. package/dist/providers/tambo-thread-provider.js.map +1 -1
  93. package/dist/providers/tambo-thread-provider.test.js +368 -262
  94. package/dist/providers/tambo-thread-provider.test.js.map +1 -1
  95. package/dist/schema/json-schema.js +29 -29
  96. package/dist/schema/json-schema.js.map +1 -1
  97. package/dist/schema/schema.test.js +237 -0
  98. package/dist/schema/schema.test.js.map +1 -1
  99. package/dist/schema/standard-schema.d.ts +1 -0
  100. package/dist/schema/standard-schema.d.ts.map +1 -1
  101. package/dist/schema/standard-schema.js +18 -13
  102. package/dist/schema/standard-schema.js.map +1 -1
  103. package/dist/schema/standard-schema.test.d.ts +2 -0
  104. package/dist/schema/standard-schema.test.d.ts.map +1 -0
  105. package/dist/schema/standard-schema.test.js +165 -0
  106. package/dist/schema/standard-schema.test.js.map +1 -0
  107. package/dist/schema/validate.test.js +149 -0
  108. package/dist/schema/validate.test.js.map +1 -1
  109. package/dist/schema/zod.d.ts +7 -4
  110. package/dist/schema/zod.d.ts.map +1 -1
  111. package/dist/schema/zod.js +65 -22
  112. package/dist/schema/zod.js.map +1 -1
  113. package/dist/schema/zod.test.js +112 -0
  114. package/dist/schema/zod.test.js.map +1 -1
  115. package/dist/testing/tools.d.ts +4 -1
  116. package/dist/testing/tools.d.ts.map +1 -1
  117. package/dist/testing/tools.js +6 -1
  118. package/dist/testing/tools.js.map +1 -1
  119. package/dist/util/generate-component.d.ts.map +1 -1
  120. package/dist/util/generate-component.js +18 -3
  121. package/dist/util/generate-component.js.map +1 -1
  122. package/dist/util/generate-component.test.d.ts +2 -0
  123. package/dist/util/generate-component.test.d.ts.map +1 -0
  124. package/dist/util/generate-component.test.js +340 -0
  125. package/dist/util/generate-component.test.js.map +1 -0
  126. package/dist/util/is-promise.d.ts +9 -0
  127. package/dist/util/is-promise.d.ts.map +1 -0
  128. package/dist/util/is-promise.js +20 -0
  129. package/dist/util/is-promise.js.map +1 -0
  130. package/dist/util/is-promise.test.d.ts +2 -0
  131. package/dist/util/is-promise.test.d.ts.map +1 -0
  132. package/dist/util/is-promise.test.js +48 -0
  133. package/dist/util/is-promise.test.js.map +1 -0
  134. package/dist/util/query-utils.test.d.ts +2 -0
  135. package/dist/util/query-utils.test.d.ts.map +1 -0
  136. package/dist/util/query-utils.test.js +382 -0
  137. package/dist/util/query-utils.test.js.map +1 -0
  138. package/dist/util/registry-validators.d.ts.map +1 -1
  139. package/dist/util/registry-validators.js +7 -0
  140. package/dist/util/registry-validators.js.map +1 -1
  141. package/dist/util/registry-validators.test.js +57 -0
  142. package/dist/util/registry-validators.test.js.map +1 -1
  143. package/dist/util/registry.d.ts.map +1 -1
  144. package/dist/util/registry.js +9 -0
  145. package/dist/util/registry.js.map +1 -1
  146. package/dist/util/registry.test.js +323 -1
  147. package/dist/util/registry.test.js.map +1 -1
  148. package/dist/util/resource-validators.test.d.ts +2 -0
  149. package/dist/util/resource-validators.test.d.ts.map +1 -0
  150. package/dist/util/resource-validators.test.js +90 -0
  151. package/dist/util/resource-validators.test.js.map +1 -0
  152. package/dist/util/tool-caller.d.ts +2 -2
  153. package/dist/util/tool-caller.d.ts.map +1 -1
  154. package/dist/util/tool-caller.js +8 -8
  155. package/dist/util/tool-caller.js.map +1 -1
  156. package/dist/util/validate-component-name.test.d.ts +2 -0
  157. package/dist/util/validate-component-name.test.d.ts.map +1 -0
  158. package/dist/util/validate-component-name.test.js +35 -0
  159. package/dist/util/validate-component-name.test.js.map +1 -0
  160. package/esm/context-helpers/context-helpers.test.js +16 -4
  161. package/esm/context-helpers/context-helpers.test.js.map +1 -1
  162. package/esm/context-helpers/current-interactables-context-helper.d.ts +2 -2
  163. package/esm/context-helpers/current-interactables-context-helper.d.ts.map +1 -1
  164. package/esm/context-helpers/current-interactables-context-helper.js +31 -15
  165. package/esm/context-helpers/current-interactables-context-helper.js.map +1 -1
  166. package/esm/context-helpers/registry.d.ts +2 -2
  167. package/esm/context-helpers/registry.d.ts.map +1 -1
  168. package/esm/context-helpers/registry.js.map +1 -1
  169. package/esm/context-helpers/types.d.ts +2 -2
  170. package/esm/context-helpers/types.d.ts.map +1 -1
  171. package/esm/context-helpers/types.js.map +1 -1
  172. package/esm/hooks/use-message-images.test.js +174 -37
  173. package/esm/hooks/use-message-images.test.js.map +1 -1
  174. package/esm/hooks/use-tambo-voice.d.ts +1 -1
  175. package/esm/hooks/use-tambo-voice.js +1 -1
  176. package/esm/hooks/use-tambo-voice.js.map +1 -1
  177. package/esm/hooks/use-tambo-voice.test.d.ts +2 -0
  178. package/esm/hooks/use-tambo-voice.test.d.ts.map +1 -0
  179. package/esm/hooks/use-tambo-voice.test.js +234 -0
  180. package/esm/hooks/use-tambo-voice.test.js.map +1 -0
  181. package/esm/index.d.ts +2 -2
  182. package/esm/index.d.ts.map +1 -1
  183. package/esm/index.js.map +1 -1
  184. package/esm/mcp/elicitation.d.ts.map +1 -1
  185. package/esm/mcp/elicitation.js +12 -0
  186. package/esm/mcp/elicitation.js.map +1 -1
  187. package/esm/mcp/elicitation.test.js +8 -1
  188. package/esm/mcp/elicitation.test.js.map +1 -1
  189. package/esm/mcp/mcp-client.d.ts +6 -10
  190. package/esm/mcp/mcp-client.d.ts.map +1 -1
  191. package/esm/mcp/mcp-client.js.map +1 -1
  192. package/esm/mcp/mcp-hooks.d.ts +12 -60
  193. package/esm/mcp/mcp-hooks.d.ts.map +1 -1
  194. package/esm/mcp/mcp-hooks.js +57 -10
  195. package/esm/mcp/mcp-hooks.js.map +1 -1
  196. package/esm/mcp/mcp-hooks.test.js +423 -0
  197. package/esm/mcp/mcp-hooks.test.js.map +1 -1
  198. package/esm/mcp/tambo-mcp-provider.d.ts.map +1 -1
  199. package/esm/mcp/tambo-mcp-provider.js +3 -0
  200. package/esm/mcp/tambo-mcp-provider.js.map +1 -1
  201. package/esm/mcp/tambo-mcp-provider.test.js +37 -0
  202. package/esm/mcp/tambo-mcp-provider.test.js.map +1 -1
  203. package/esm/model/component-metadata.d.ts +53 -20
  204. package/esm/model/component-metadata.d.ts.map +1 -1
  205. package/esm/model/component-metadata.js.map +1 -1
  206. package/esm/model/tambo-interactable.d.ts +6 -0
  207. package/esm/model/tambo-interactable.d.ts.map +1 -1
  208. package/esm/model/tambo-interactable.js.map +1 -1
  209. package/esm/providers/index.d.ts +1 -1
  210. package/esm/providers/index.d.ts.map +1 -1
  211. package/esm/providers/index.js.map +1 -1
  212. package/esm/providers/tambo-client-provider.d.ts +8 -0
  213. package/esm/providers/tambo-client-provider.d.ts.map +1 -1
  214. package/esm/providers/tambo-client-provider.js +11 -12
  215. package/esm/providers/tambo-client-provider.js.map +1 -1
  216. package/esm/providers/tambo-client-provider.test.d.ts +2 -0
  217. package/esm/providers/tambo-client-provider.test.d.ts.map +1 -0
  218. package/esm/providers/tambo-client-provider.test.js +203 -0
  219. package/esm/providers/tambo-client-provider.test.js.map +1 -0
  220. package/esm/providers/tambo-context-attachment-provider.d.ts +34 -92
  221. package/esm/providers/tambo-context-attachment-provider.d.ts.map +1 -1
  222. package/esm/providers/tambo-context-attachment-provider.js +63 -106
  223. package/esm/providers/tambo-context-attachment-provider.js.map +1 -1
  224. package/esm/providers/tambo-context-attachment-provider.test.js +230 -464
  225. package/esm/providers/tambo-context-attachment-provider.test.js.map +1 -1
  226. package/esm/providers/tambo-interactable-provider.d.ts +2 -0
  227. package/esm/providers/tambo-interactable-provider.d.ts.map +1 -1
  228. package/esm/providers/tambo-interactable-provider.js +29 -4
  229. package/esm/providers/tambo-interactable-provider.js.map +1 -1
  230. package/esm/providers/tambo-interactable-provider.test.js +1 -1
  231. package/esm/providers/tambo-interactable-provider.test.js.map +1 -1
  232. package/esm/providers/tambo-interactables-additional-context.test.js +2 -5
  233. package/esm/providers/tambo-interactables-additional-context.test.js.map +1 -1
  234. package/esm/providers/tambo-provider.d.ts +2 -3
  235. package/esm/providers/tambo-provider.d.ts.map +1 -1
  236. package/esm/providers/tambo-provider.js +5 -6
  237. package/esm/providers/tambo-provider.js.map +1 -1
  238. package/esm/providers/tambo-registry-provider.test.js +16 -0
  239. package/esm/providers/tambo-registry-provider.test.js.map +1 -1
  240. package/esm/providers/tambo-registry-schema-compat.test.js +31 -0
  241. package/esm/providers/tambo-registry-schema-compat.test.js.map +1 -1
  242. package/esm/providers/tambo-thread-input-provider.d.ts +1 -1
  243. package/esm/providers/tambo-thread-input-provider.d.ts.map +1 -1
  244. package/esm/providers/tambo-thread-input-provider.js +5 -1
  245. package/esm/providers/tambo-thread-input-provider.js.map +1 -1
  246. package/esm/providers/tambo-thread-provider-initial-messages.test.js +84 -2
  247. package/esm/providers/tambo-thread-provider-initial-messages.test.js.map +1 -1
  248. package/esm/providers/tambo-thread-provider.d.ts.map +1 -1
  249. package/esm/providers/tambo-thread-provider.js +53 -42
  250. package/esm/providers/tambo-thread-provider.js.map +1 -1
  251. package/esm/providers/tambo-thread-provider.test.js +368 -262
  252. package/esm/providers/tambo-thread-provider.test.js.map +1 -1
  253. package/esm/schema/json-schema.js +1 -1
  254. package/esm/schema/json-schema.js.map +1 -1
  255. package/esm/schema/schema.test.js +238 -1
  256. package/esm/schema/schema.test.js.map +1 -1
  257. package/esm/schema/standard-schema.d.ts +1 -0
  258. package/esm/schema/standard-schema.d.ts.map +1 -1
  259. package/esm/schema/standard-schema.js +18 -13
  260. package/esm/schema/standard-schema.js.map +1 -1
  261. package/esm/schema/standard-schema.test.d.ts +2 -0
  262. package/esm/schema/standard-schema.test.d.ts.map +1 -0
  263. package/esm/schema/standard-schema.test.js +130 -0
  264. package/esm/schema/standard-schema.test.js.map +1 -0
  265. package/esm/schema/validate.test.js +149 -0
  266. package/esm/schema/validate.test.js.map +1 -1
  267. package/esm/schema/zod.d.ts +7 -4
  268. package/esm/schema/zod.d.ts.map +1 -1
  269. package/esm/schema/zod.js +65 -22
  270. package/esm/schema/zod.js.map +1 -1
  271. package/esm/schema/zod.test.js +113 -1
  272. package/esm/schema/zod.test.js.map +1 -1
  273. package/esm/testing/tools.d.ts +4 -1
  274. package/esm/testing/tools.d.ts.map +1 -1
  275. package/esm/testing/tools.js +6 -1
  276. package/esm/testing/tools.js.map +1 -1
  277. package/esm/util/generate-component.d.ts.map +1 -1
  278. package/esm/util/generate-component.js +18 -3
  279. package/esm/util/generate-component.js.map +1 -1
  280. package/esm/util/generate-component.test.d.ts +2 -0
  281. package/esm/util/generate-component.test.d.ts.map +1 -0
  282. package/esm/util/generate-component.test.js +302 -0
  283. package/esm/util/generate-component.test.js.map +1 -0
  284. package/esm/util/is-promise.d.ts +9 -0
  285. package/esm/util/is-promise.d.ts.map +1 -0
  286. package/esm/util/is-promise.js +17 -0
  287. package/esm/util/is-promise.js.map +1 -0
  288. package/esm/util/is-promise.test.d.ts +2 -0
  289. package/esm/util/is-promise.test.d.ts.map +1 -0
  290. package/esm/util/is-promise.test.js +46 -0
  291. package/esm/util/is-promise.test.js.map +1 -0
  292. package/esm/util/query-utils.test.d.ts +2 -0
  293. package/esm/util/query-utils.test.d.ts.map +1 -0
  294. package/esm/util/query-utils.test.js +380 -0
  295. package/esm/util/query-utils.test.js.map +1 -0
  296. package/esm/util/registry-validators.d.ts.map +1 -1
  297. package/esm/util/registry-validators.js +7 -0
  298. package/esm/util/registry-validators.js.map +1 -1
  299. package/esm/util/registry-validators.test.js +57 -0
  300. package/esm/util/registry-validators.test.js.map +1 -1
  301. package/esm/util/registry.d.ts.map +1 -1
  302. package/esm/util/registry.js +9 -0
  303. package/esm/util/registry.js.map +1 -1
  304. package/esm/util/registry.test.js +324 -2
  305. package/esm/util/registry.test.js.map +1 -1
  306. package/esm/util/resource-validators.test.d.ts +2 -0
  307. package/esm/util/resource-validators.test.d.ts.map +1 -0
  308. package/esm/util/resource-validators.test.js +88 -0
  309. package/esm/util/resource-validators.test.js.map +1 -0
  310. package/esm/util/tool-caller.d.ts +2 -2
  311. package/esm/util/tool-caller.d.ts.map +1 -1
  312. package/esm/util/tool-caller.js +8 -8
  313. package/esm/util/tool-caller.js.map +1 -1
  314. package/esm/util/validate-component-name.test.d.ts +2 -0
  315. package/esm/util/validate-component-name.test.d.ts.map +1 -0
  316. package/esm/util/validate-component-name.test.js +33 -0
  317. package/esm/util/validate-component-name.test.js.map +1 -0
  318. package/package.json +15 -23
  319. package/dist/schema/alias.d.ts +0 -3
  320. package/dist/schema/alias.d.ts.map +0 -1
  321. package/dist/schema/alias.js +0 -6
  322. package/dist/schema/alias.js.map +0 -1
  323. package/esm/schema/alias.d.ts +0 -3
  324. package/esm/schema/alias.d.ts.map +0 -1
  325. package/esm/schema/alias.js +0 -13
  326. package/esm/schema/alias.js.map +0 -1
@@ -504,6 +504,142 @@ describe("useTamboMcpPromptList - individual server caching", () => {
504
504
  expect(promptNames).toContain("server-b:prompt-b");
505
505
  });
506
506
  });
507
+ describe("useTamboMcpPromptList - search filtering", () => {
508
+ let queryClient;
509
+ beforeEach(() => {
510
+ createImpl = jest.fn();
511
+ queryClient = new react_query_1.QueryClient({
512
+ defaultOptions: {
513
+ queries: {
514
+ retry: false,
515
+ },
516
+ },
517
+ });
518
+ });
519
+ afterEach(() => {
520
+ queryClient.clear();
521
+ });
522
+ it("should filter MCP prompts locally by search string", async () => {
523
+ const serverAPrompts = {
524
+ prompts: [
525
+ { name: "create-issue", description: "Create a new issue" },
526
+ { name: "list-tasks", description: "List all tasks" },
527
+ { name: "search-docs", description: "Search documentation" },
528
+ ],
529
+ };
530
+ const mockClientA = {
531
+ listTools: jest.fn().mockResolvedValue([]),
532
+ listPrompts: jest.fn().mockResolvedValue(serverAPrompts),
533
+ listResources: jest.fn().mockResolvedValue({ resources: [] }),
534
+ close: jest.fn(),
535
+ };
536
+ const clientA = {
537
+ client: mockClientA,
538
+ listTools: jest.fn().mockResolvedValue([]),
539
+ close: jest.fn(),
540
+ };
541
+ createImpl.mockImplementation(async () => clientA);
542
+ let capturedPrompts = [];
543
+ const Capture = ({ search }) => {
544
+ const { data: prompts } = (0, mcp_hooks_1.useTamboMcpPromptList)(search);
545
+ (0, react_2.useEffect)(() => {
546
+ if (prompts) {
547
+ capturedPrompts = prompts;
548
+ }
549
+ }, [prompts]);
550
+ return null;
551
+ };
552
+ const { rerender } = (0, react_1.render)(react_2.default.createElement(tambo_client_provider_1.TamboClientContext.Provider, { value: {
553
+ client: { baseURL: "https://api.tambo.co" },
554
+ queryClient,
555
+ isUpdatingToken: false,
556
+ } },
557
+ react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { mcpServers: [
558
+ {
559
+ url: "https://server-a.example",
560
+ transport: mcp_client_1.MCPTransport.SSE,
561
+ },
562
+ ] },
563
+ react_2.default.createElement(tambo_mcp_token_provider_1.TamboMcpTokenProvider, null,
564
+ react_2.default.createElement(tambo_mcp_provider_1.TamboMcpProvider, null,
565
+ react_2.default.createElement(Capture, null))))));
566
+ // Wait for all prompts to be loaded (no search)
567
+ await (0, react_1.waitFor)(() => {
568
+ expect(capturedPrompts.length).toBe(3);
569
+ });
570
+ // Now search for "issue"
571
+ rerender(react_2.default.createElement(tambo_client_provider_1.TamboClientContext.Provider, { value: {
572
+ client: { baseURL: "https://api.tambo.co" },
573
+ queryClient,
574
+ isUpdatingToken: false,
575
+ } },
576
+ react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { mcpServers: [
577
+ {
578
+ url: "https://server-a.example",
579
+ transport: mcp_client_1.MCPTransport.SSE,
580
+ },
581
+ ] },
582
+ react_2.default.createElement(tambo_mcp_token_provider_1.TamboMcpTokenProvider, null,
583
+ react_2.default.createElement(tambo_mcp_provider_1.TamboMcpProvider, null,
584
+ react_2.default.createElement(Capture, { search: "issue" }))))));
585
+ // Should only have the create-issue prompt
586
+ await (0, react_1.waitFor)(() => {
587
+ expect(capturedPrompts.length).toBe(1);
588
+ });
589
+ expect(capturedPrompts[0].prompt.name).toBe("server-a:create-issue");
590
+ // MCP listPrompts should only be called once (not re-fetched on search change)
591
+ expect(mockClientA.listPrompts).toHaveBeenCalledTimes(1);
592
+ });
593
+ it("should filter prompts case-insensitively", async () => {
594
+ const serverAPrompts = {
595
+ prompts: [
596
+ { name: "Create-Issue", description: "Create a new issue" },
597
+ { name: "list-tasks", description: "List all tasks" },
598
+ ],
599
+ };
600
+ const mockClientA = {
601
+ listTools: jest.fn().mockResolvedValue([]),
602
+ listPrompts: jest.fn().mockResolvedValue(serverAPrompts),
603
+ listResources: jest.fn().mockResolvedValue({ resources: [] }),
604
+ close: jest.fn(),
605
+ };
606
+ const clientA = {
607
+ client: mockClientA,
608
+ listTools: jest.fn().mockResolvedValue([]),
609
+ close: jest.fn(),
610
+ };
611
+ createImpl.mockImplementation(async () => clientA);
612
+ let capturedPrompts = [];
613
+ const Capture = ({ search }) => {
614
+ const { data: prompts } = (0, mcp_hooks_1.useTamboMcpPromptList)(search);
615
+ (0, react_2.useEffect)(() => {
616
+ if (prompts) {
617
+ capturedPrompts = prompts;
618
+ }
619
+ }, [prompts]);
620
+ return null;
621
+ };
622
+ (0, react_1.render)(react_2.default.createElement(tambo_client_provider_1.TamboClientContext.Provider, { value: {
623
+ client: { baseURL: "https://api.tambo.co" },
624
+ queryClient,
625
+ isUpdatingToken: false,
626
+ } },
627
+ react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { mcpServers: [
628
+ {
629
+ url: "https://server-a.example",
630
+ transport: mcp_client_1.MCPTransport.SSE,
631
+ },
632
+ ] },
633
+ react_2.default.createElement(tambo_mcp_token_provider_1.TamboMcpTokenProvider, null,
634
+ react_2.default.createElement(tambo_mcp_provider_1.TamboMcpProvider, null,
635
+ react_2.default.createElement(Capture, { search: "CREATE" }))))));
636
+ // Should find "Create-Issue" even though search is uppercase
637
+ await (0, react_1.waitFor)(() => {
638
+ expect(capturedPrompts.length).toBe(1);
639
+ });
640
+ expect(capturedPrompts[0].prompt.name).toBe("server-a:Create-Issue");
641
+ });
642
+ });
507
643
  describe("useTamboMcpResourceList - resource management", () => {
508
644
  let queryClient;
509
645
  beforeEach(() => {
@@ -815,6 +951,293 @@ describe("useTamboMcpResourceList - resource management", () => {
815
951
  expect(updatedUris).not.toContain("server-b:file:///workspace/code.js"); // Server B removed
816
952
  });
817
953
  });
954
+ describe("useTamboMcpResourceList - search filtering", () => {
955
+ let queryClient;
956
+ beforeEach(() => {
957
+ createImpl = jest.fn();
958
+ queryClient = new react_query_1.QueryClient({
959
+ defaultOptions: {
960
+ queries: {
961
+ retry: false,
962
+ },
963
+ },
964
+ });
965
+ });
966
+ afterEach(() => {
967
+ queryClient.clear();
968
+ });
969
+ it("should filter MCP resources locally by search string", async () => {
970
+ const serverAResources = {
971
+ resources: [
972
+ {
973
+ uri: "file:///home/user/document.txt",
974
+ name: "My Document",
975
+ mimeType: "text/plain",
976
+ },
977
+ {
978
+ uri: "file:///home/user/image.png",
979
+ name: "My Image",
980
+ mimeType: "image/png",
981
+ },
982
+ {
983
+ uri: "file:///home/user/notes.txt",
984
+ name: "Notes",
985
+ mimeType: "text/plain",
986
+ },
987
+ ],
988
+ };
989
+ const mockClientA = {
990
+ listTools: jest.fn().mockResolvedValue([]),
991
+ listPrompts: jest.fn().mockResolvedValue({ prompts: [] }),
992
+ listResources: jest.fn().mockResolvedValue(serverAResources),
993
+ close: jest.fn(),
994
+ };
995
+ const clientA = {
996
+ client: mockClientA,
997
+ listTools: jest.fn().mockResolvedValue([]),
998
+ close: jest.fn(),
999
+ };
1000
+ createImpl.mockImplementation(async () => clientA);
1001
+ let capturedResources = [];
1002
+ const Capture = ({ search }) => {
1003
+ const { data: resources } = (0, mcp_hooks_1.useTamboMcpResourceList)(search);
1004
+ (0, react_2.useEffect)(() => {
1005
+ if (resources) {
1006
+ capturedResources = resources;
1007
+ }
1008
+ }, [resources]);
1009
+ return null;
1010
+ };
1011
+ const { rerender } = (0, react_1.render)(react_2.default.createElement(tambo_client_provider_1.TamboClientContext.Provider, { value: {
1012
+ client: { baseURL: "https://api.tambo.co" },
1013
+ queryClient,
1014
+ isUpdatingToken: false,
1015
+ } },
1016
+ react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { mcpServers: [
1017
+ {
1018
+ url: "https://server-a.example",
1019
+ transport: mcp_client_1.MCPTransport.SSE,
1020
+ },
1021
+ ] },
1022
+ react_2.default.createElement(tambo_mcp_token_provider_1.TamboMcpTokenProvider, null,
1023
+ react_2.default.createElement(tambo_mcp_provider_1.TamboMcpProvider, null,
1024
+ react_2.default.createElement(Capture, null))))));
1025
+ // Wait for all resources to be loaded (no search)
1026
+ await (0, react_1.waitFor)(() => {
1027
+ expect(capturedResources.length).toBe(3);
1028
+ });
1029
+ // Now search for "document"
1030
+ rerender(react_2.default.createElement(tambo_client_provider_1.TamboClientContext.Provider, { value: {
1031
+ client: { baseURL: "https://api.tambo.co" },
1032
+ queryClient,
1033
+ isUpdatingToken: false,
1034
+ } },
1035
+ react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { mcpServers: [
1036
+ {
1037
+ url: "https://server-a.example",
1038
+ transport: mcp_client_1.MCPTransport.SSE,
1039
+ },
1040
+ ] },
1041
+ react_2.default.createElement(tambo_mcp_token_provider_1.TamboMcpTokenProvider, null,
1042
+ react_2.default.createElement(tambo_mcp_provider_1.TamboMcpProvider, null,
1043
+ react_2.default.createElement(Capture, { search: "document" }))))));
1044
+ // Should only have the document resource
1045
+ await (0, react_1.waitFor)(() => {
1046
+ expect(capturedResources.length).toBe(1);
1047
+ });
1048
+ expect(capturedResources[0].resource.name).toBe("My Document");
1049
+ // MCP listResources should only be called once (not re-fetched on search change)
1050
+ expect(mockClientA.listResources).toHaveBeenCalledTimes(1);
1051
+ });
1052
+ it("should pass search string to registry listResources for dynamic generation", async () => {
1053
+ const listResources = jest
1054
+ .fn()
1055
+ .mockImplementation(async (search) => {
1056
+ // Dynamically generate resources based on search
1057
+ if (!search)
1058
+ return [];
1059
+ return [
1060
+ {
1061
+ uri: `dynamic://${search}`,
1062
+ name: `Dynamic Resource for ${search}`,
1063
+ mimeType: "text/plain",
1064
+ },
1065
+ ];
1066
+ });
1067
+ const getResource = jest.fn().mockResolvedValue({
1068
+ contents: [{ uri: "test", text: "test content", mimeType: "text/plain" }],
1069
+ });
1070
+ let capturedResources = [];
1071
+ const Capture = ({ search }) => {
1072
+ const { data: resources } = (0, mcp_hooks_1.useTamboMcpResourceList)(search);
1073
+ (0, react_2.useEffect)(() => {
1074
+ if (resources) {
1075
+ capturedResources = resources;
1076
+ }
1077
+ }, [resources]);
1078
+ return null;
1079
+ };
1080
+ const { rerender } = (0, react_1.render)(react_2.default.createElement(tambo_client_provider_1.TamboClientContext.Provider, { value: {
1081
+ client: { baseURL: "https://api.tambo.co" },
1082
+ queryClient,
1083
+ isUpdatingToken: false,
1084
+ } },
1085
+ react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { listResources: listResources, getResource: getResource },
1086
+ react_2.default.createElement(tambo_mcp_token_provider_1.TamboMcpTokenProvider, null,
1087
+ react_2.default.createElement(tambo_mcp_provider_1.TamboMcpProvider, null,
1088
+ react_2.default.createElement(Capture, { search: "foo" }))))));
1089
+ // Wait for dynamic resource to be generated
1090
+ await (0, react_1.waitFor)(() => {
1091
+ expect(capturedResources.length).toBe(1);
1092
+ });
1093
+ // Verify listResources was called with the search string
1094
+ expect(listResources).toHaveBeenCalledWith("foo");
1095
+ expect(capturedResources[0].resource.name).toBe("Dynamic Resource for foo");
1096
+ // Registry resources get the "registry:" prefix
1097
+ expect(capturedResources[0].resource.uri).toBe("registry:dynamic://foo");
1098
+ // Now search for "bar"
1099
+ rerender(react_2.default.createElement(tambo_client_provider_1.TamboClientContext.Provider, { value: {
1100
+ client: { baseURL: "https://api.tambo.co" },
1101
+ queryClient,
1102
+ isUpdatingToken: false,
1103
+ } },
1104
+ react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { listResources: listResources, getResource: getResource },
1105
+ react_2.default.createElement(tambo_mcp_token_provider_1.TamboMcpTokenProvider, null,
1106
+ react_2.default.createElement(tambo_mcp_provider_1.TamboMcpProvider, null,
1107
+ react_2.default.createElement(Capture, { search: "bar" }))))));
1108
+ // Wait for new dynamic resource
1109
+ await (0, react_1.waitFor)(() => {
1110
+ expect(capturedResources[0].resource.uri).toBe("registry:dynamic://bar");
1111
+ });
1112
+ // listResources should be called again with new search
1113
+ expect(listResources).toHaveBeenCalledWith("bar");
1114
+ expect(capturedResources[0].resource.name).toBe("Dynamic Resource for bar");
1115
+ });
1116
+ it("should not locally substring-filter dynamic registry resources", async () => {
1117
+ const listResources = jest
1118
+ .fn()
1119
+ .mockImplementation(async (search) => {
1120
+ if (!search)
1121
+ return [];
1122
+ // Simulate a provider that matches resources using non-substring logic.
1123
+ return [
1124
+ {
1125
+ uri: "dynamic://matched-by-provider",
1126
+ name: "Smart Match",
1127
+ mimeType: "text/plain",
1128
+ },
1129
+ ];
1130
+ });
1131
+ const getResource = jest.fn().mockResolvedValue({
1132
+ contents: [{ uri: "test", text: "test content", mimeType: "text/plain" }],
1133
+ });
1134
+ let capturedResources = [];
1135
+ const Capture = ({ search }) => {
1136
+ const { data: resources } = (0, mcp_hooks_1.useTamboMcpResourceList)(search);
1137
+ (0, react_2.useEffect)(() => {
1138
+ if (resources) {
1139
+ capturedResources = resources;
1140
+ }
1141
+ }, [resources]);
1142
+ return null;
1143
+ };
1144
+ (0, react_1.render)(react_2.default.createElement(tambo_client_provider_1.TamboClientContext.Provider, { value: {
1145
+ client: { baseURL: "https://api.tambo.co" },
1146
+ queryClient,
1147
+ isUpdatingToken: false,
1148
+ } },
1149
+ react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { listResources: listResources, getResource: getResource },
1150
+ react_2.default.createElement(tambo_mcp_token_provider_1.TamboMcpTokenProvider, null,
1151
+ react_2.default.createElement(tambo_mcp_provider_1.TamboMcpProvider, null,
1152
+ react_2.default.createElement(Capture, { search: "foo" }))))));
1153
+ await (0, react_1.waitFor)(() => {
1154
+ expect(capturedResources.length).toBe(1);
1155
+ });
1156
+ expect(listResources).toHaveBeenCalledWith("foo");
1157
+ expect(capturedResources[0].server).toBeNull();
1158
+ expect(capturedResources[0].resource.name).toBe("Smart Match");
1159
+ expect(capturedResources[0].resource.uri).toBe("registry:dynamic://matched-by-provider");
1160
+ });
1161
+ it("should combine MCP filtered resources with dynamically generated registry resources", async () => {
1162
+ const serverAResources = {
1163
+ resources: [
1164
+ {
1165
+ uri: "file:///apple.txt",
1166
+ name: "Apple",
1167
+ mimeType: "text/plain",
1168
+ },
1169
+ {
1170
+ uri: "file:///banana.txt",
1171
+ name: "Banana",
1172
+ mimeType: "text/plain",
1173
+ },
1174
+ ],
1175
+ };
1176
+ const mockClientA = {
1177
+ listTools: jest.fn().mockResolvedValue([]),
1178
+ listPrompts: jest.fn().mockResolvedValue({ prompts: [] }),
1179
+ listResources: jest.fn().mockResolvedValue(serverAResources),
1180
+ close: jest.fn(),
1181
+ };
1182
+ const clientA = {
1183
+ client: mockClientA,
1184
+ listTools: jest.fn().mockResolvedValue([]),
1185
+ close: jest.fn(),
1186
+ };
1187
+ createImpl.mockImplementation(async () => clientA);
1188
+ const listResources = jest
1189
+ .fn()
1190
+ .mockImplementation(async (search) => {
1191
+ // Always return a resource that includes the search term
1192
+ return [
1193
+ {
1194
+ uri: `registry://${search ?? "all"}`,
1195
+ name: `Registry ${search ?? "all"}`,
1196
+ mimeType: "text/plain",
1197
+ },
1198
+ ];
1199
+ });
1200
+ const getResource = jest.fn().mockResolvedValue({
1201
+ contents: [{ uri: "test", text: "test", mimeType: "text/plain" }],
1202
+ });
1203
+ let capturedResources = [];
1204
+ const Capture = ({ search }) => {
1205
+ const { data: resources } = (0, mcp_hooks_1.useTamboMcpResourceList)(search);
1206
+ (0, react_2.useEffect)(() => {
1207
+ if (resources) {
1208
+ capturedResources = resources;
1209
+ }
1210
+ }, [resources]);
1211
+ return null;
1212
+ };
1213
+ (0, react_1.render)(react_2.default.createElement(tambo_client_provider_1.TamboClientContext.Provider, { value: {
1214
+ client: { baseURL: "https://api.tambo.co" },
1215
+ queryClient,
1216
+ isUpdatingToken: false,
1217
+ } },
1218
+ react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { mcpServers: [
1219
+ {
1220
+ url: "https://server-a.example",
1221
+ transport: mcp_client_1.MCPTransport.SSE,
1222
+ },
1223
+ ], listResources: listResources, getResource: getResource },
1224
+ react_2.default.createElement(tambo_mcp_token_provider_1.TamboMcpTokenProvider, null,
1225
+ react_2.default.createElement(tambo_mcp_provider_1.TamboMcpProvider, null,
1226
+ react_2.default.createElement(Capture, { search: "apple" }))))));
1227
+ // Wait for resources
1228
+ await (0, react_1.waitFor)(() => {
1229
+ // Should have: 1 MCP resource (Apple filtered) + 1 registry resource (dynamic)
1230
+ expect(capturedResources.length).toBe(2);
1231
+ });
1232
+ const uris = capturedResources.map((r) => r.resource.uri);
1233
+ // MCP "Apple" should match (filtered locally)
1234
+ expect(uris).toContain("server-a:file:///apple.txt");
1235
+ // Registry dynamic resource
1236
+ expect(uris).toContain("registry:registry://apple");
1237
+ // MCP "Banana" should NOT be included (filtered out)
1238
+ expect(uris).not.toContain("server-a:file:///banana.txt");
1239
+ });
1240
+ });
818
1241
  describe("useTamboMcpResource - read individual resource", () => {
819
1242
  let queryClient;
820
1243
  beforeEach(() => {