@tambo-ai/react 1.0.3 → 1.2.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 (458) hide show
  1. package/README.md +1 -1
  2. package/dist/context-helpers/current-interactables-context-helper.d.ts +16 -2
  3. package/dist/context-helpers/current-interactables-context-helper.d.ts.map +1 -1
  4. package/dist/context-helpers/current-interactables-context-helper.js.map +1 -1
  5. package/dist/context-helpers/current-interactables-context-helper.test.d.ts +2 -0
  6. package/dist/context-helpers/current-interactables-context-helper.test.d.ts.map +1 -0
  7. package/dist/context-helpers/current-interactables-context-helper.test.js +70 -0
  8. package/dist/context-helpers/current-interactables-context-helper.test.js.map +1 -0
  9. package/dist/mcp/elicitation.d.ts +3 -37
  10. package/dist/mcp/elicitation.d.ts.map +1 -1
  11. package/dist/mcp/elicitation.js +7 -24
  12. package/dist/mcp/elicitation.js.map +1 -1
  13. package/dist/mcp/index.d.ts +4 -4
  14. package/dist/mcp/index.d.ts.map +1 -1
  15. package/dist/mcp/index.js +2 -2
  16. package/dist/mcp/index.js.map +1 -1
  17. package/dist/mcp/mcp-client.test.js +17 -17
  18. package/dist/mcp/mcp-client.test.js.map +1 -1
  19. package/dist/mcp/mcp-hooks.d.ts.map +1 -1
  20. package/dist/mcp/mcp-hooks.js +8 -5
  21. package/dist/mcp/mcp-hooks.js.map +1 -1
  22. package/dist/mcp/mcp-hooks.test.js +30 -29
  23. package/dist/mcp/mcp-hooks.test.js.map +1 -1
  24. package/dist/mcp/tambo-mcp-provider.d.ts +6 -9
  25. package/dist/mcp/tambo-mcp-provider.d.ts.map +1 -1
  26. package/dist/mcp/tambo-mcp-provider.js +9 -13
  27. package/dist/mcp/tambo-mcp-provider.js.map +1 -1
  28. package/dist/mcp/tambo-mcp-provider.test.js +26 -25
  29. package/dist/mcp/tambo-mcp-provider.test.js.map +1 -1
  30. package/dist/mcp/use-mcp-servers.test.js +2 -1
  31. package/dist/mcp/use-mcp-servers.test.js.map +1 -1
  32. package/dist/model/component-metadata.d.ts +7 -372
  33. package/dist/model/component-metadata.d.ts.map +1 -1
  34. package/dist/model/component-metadata.js.map +1 -1
  35. package/dist/model/validate-input.test.d.ts +2 -0
  36. package/dist/model/validate-input.test.d.ts.map +1 -0
  37. package/dist/model/validate-input.test.js +38 -0
  38. package/dist/model/validate-input.test.js.map +1 -0
  39. package/dist/providers/tambo-interactable-provider.d.ts +7 -7
  40. package/dist/providers/tambo-registry-provider.d.ts +1 -1
  41. package/dist/providers/tambo-registry-provider.d.ts.map +1 -1
  42. package/dist/providers/tambo-registry-provider.js.map +1 -1
  43. package/dist/providers/tambo-registry-schema-compat.test.js +4 -4
  44. package/dist/providers/tambo-registry-schema-compat.test.js.map +1 -1
  45. package/dist/schema/index.d.ts +2 -4
  46. package/dist/schema/index.d.ts.map +1 -1
  47. package/dist/schema/index.js +9 -11
  48. package/dist/schema/index.js.map +1 -1
  49. package/dist/schema/json-schema.d.ts +1 -17
  50. package/dist/schema/json-schema.d.ts.map +1 -1
  51. package/dist/schema/json-schema.js +5 -69
  52. package/dist/schema/json-schema.js.map +1 -1
  53. package/dist/schema/schema.test.js +24 -25
  54. package/dist/schema/schema.test.js.map +1 -1
  55. package/dist/schema/standard-schema.test.js +25 -25
  56. package/dist/schema/standard-schema.test.js.map +1 -1
  57. package/dist/schema/validate.test.js +33 -33
  58. package/dist/schema/validate.test.js.map +1 -1
  59. package/dist/testing/tools.d.ts +4 -4
  60. package/dist/testing/tools.test.d.ts +2 -0
  61. package/dist/testing/tools.test.d.ts.map +1 -0
  62. package/dist/testing/tools.test.js +60 -0
  63. package/dist/testing/tools.test.js.map +1 -0
  64. package/dist/util/mcp-server-utils.d.ts +1 -1
  65. package/dist/util/mcp-server-utils.d.ts.map +1 -1
  66. package/dist/util/mcp-server-utils.js +4 -4
  67. package/dist/util/mcp-server-utils.js.map +1 -1
  68. package/dist/util/mcp-server-utils.test.js +27 -27
  69. package/dist/util/mcp-server-utils.test.js.map +1 -1
  70. package/dist/util/registry.js +1 -1
  71. package/dist/util/registry.js.map +1 -1
  72. package/dist/util/resource-content-resolver.js +5 -5
  73. package/dist/util/resource-content-resolver.js.map +1 -1
  74. package/dist/util/resource-content-resolver.test.js +6 -6
  75. package/dist/util/resource-content-resolver.test.js.map +1 -1
  76. package/dist/util/tool-caller.test.d.ts +2 -0
  77. package/dist/util/tool-caller.test.d.ts.map +1 -0
  78. package/dist/util/tool-caller.test.js +71 -0
  79. package/dist/util/tool-caller.test.js.map +1 -0
  80. package/dist/v1/__tests__/v1-interactables.test.js +1 -0
  81. package/dist/v1/__tests__/v1-interactables.test.js.map +1 -1
  82. package/dist/v1/hooks/use-tambo-v1-auth-state.d.ts +1 -1
  83. package/dist/v1/hooks/use-tambo-v1-auth-state.d.ts.map +1 -1
  84. package/dist/v1/hooks/use-tambo-v1-auth-state.js.map +1 -1
  85. package/dist/v1/hooks/use-tambo-v1-component-state.js +2 -2
  86. package/dist/v1/hooks/use-tambo-v1-component-state.js.map +1 -1
  87. package/dist/v1/hooks/use-tambo-v1-component-state.test.js +1 -1
  88. package/dist/v1/hooks/use-tambo-v1-component-state.test.js.map +1 -1
  89. package/dist/v1/hooks/use-tambo-v1-send-message.d.ts +1 -1
  90. package/dist/v1/hooks/use-tambo-v1-send-message.d.ts.map +1 -1
  91. package/dist/v1/hooks/use-tambo-v1-send-message.js +17 -17
  92. package/dist/v1/hooks/use-tambo-v1-send-message.js.map +1 -1
  93. package/dist/v1/hooks/use-tambo-v1-send-message.test.js +1 -1
  94. package/dist/v1/hooks/use-tambo-v1-send-message.test.js.map +1 -1
  95. package/dist/v1/hooks/use-tambo-v1-stream-status.js +2 -2
  96. package/dist/v1/hooks/use-tambo-v1-stream-status.js.map +1 -1
  97. package/dist/v1/hooks/use-tambo-v1-stream-status.test.js +9 -5
  98. package/dist/v1/hooks/use-tambo-v1-stream-status.test.js.map +1 -1
  99. package/dist/v1/hooks/use-tambo-v1-suggestions.js +2 -2
  100. package/dist/v1/hooks/use-tambo-v1-suggestions.js.map +1 -1
  101. package/dist/v1/hooks/use-tambo-v1-thread-input.test.js +104 -0
  102. package/dist/v1/hooks/use-tambo-v1-thread-input.test.js.map +1 -1
  103. package/dist/v1/hooks/use-tambo-v1.d.ts +7 -6
  104. package/dist/v1/hooks/use-tambo-v1.d.ts.map +1 -1
  105. package/dist/v1/hooks/use-tambo-v1.js +2 -2
  106. package/dist/v1/hooks/use-tambo-v1.js.map +1 -1
  107. package/dist/v1/hooks/use-tambo-v1.test.js +23 -23
  108. package/dist/v1/hooks/use-tambo-v1.test.js.map +1 -1
  109. package/dist/v1/index.d.ts +6 -6
  110. package/dist/v1/index.d.ts.map +1 -1
  111. package/dist/v1/index.js +2 -2
  112. package/dist/v1/index.js.map +1 -1
  113. package/dist/v1/providers/tambo-v1-provider.d.ts +2 -1
  114. package/dist/v1/providers/tambo-v1-provider.d.ts.map +1 -1
  115. package/dist/v1/providers/tambo-v1-provider.js +2 -0
  116. package/dist/v1/providers/tambo-v1-provider.js.map +1 -1
  117. package/dist/v1/providers/tambo-v1-stream-context.d.ts +2 -2
  118. package/dist/v1/providers/tambo-v1-stream-context.d.ts.map +1 -1
  119. package/dist/v1/providers/tambo-v1-stream-context.js +9 -9
  120. package/dist/v1/providers/tambo-v1-stream-context.js.map +1 -1
  121. package/dist/v1/providers/tambo-v1-stream-context.test.js +35 -0
  122. package/dist/v1/providers/tambo-v1-stream-context.test.js.map +1 -1
  123. package/dist/v1/providers/tambo-v1-stub-provider.d.ts +1 -1
  124. package/dist/v1/providers/tambo-v1-stub-provider.d.ts.map +1 -1
  125. package/dist/v1/providers/tambo-v1-stub-provider.js +1 -1
  126. package/dist/v1/providers/tambo-v1-stub-provider.js.map +1 -1
  127. package/dist/v1/providers/tambo-v1-stub-provider.test.js.map +1 -1
  128. package/dist/v1/providers/tambo-v1-thread-input-provider.d.ts +1 -1
  129. package/dist/v1/providers/tambo-v1-thread-input-provider.d.ts.map +1 -1
  130. package/dist/v1/providers/tambo-v1-thread-input-provider.js +33 -17
  131. package/dist/v1/providers/tambo-v1-thread-input-provider.js.map +1 -1
  132. package/dist/v1/types/event.test.js +13 -13
  133. package/dist/v1/types/event.test.js.map +1 -1
  134. package/dist/v1/types/message.d.ts +12 -109
  135. package/dist/v1/types/message.d.ts.map +1 -1
  136. package/dist/v1/types/message.js +0 -7
  137. package/dist/v1/types/message.js.map +1 -1
  138. package/dist/v1/utils/event-accumulator.test.js +183 -184
  139. package/dist/v1/utils/event-accumulator.test.js.map +1 -1
  140. package/dist/v1/utils/json-patch.test.js +4 -4
  141. package/dist/v1/utils/json-patch.test.js.map +1 -1
  142. package/dist/v1/utils/keyed-throttle.test.js +12 -12
  143. package/dist/v1/utils/keyed-throttle.test.js.map +1 -1
  144. package/dist/v1/utils/registry-conversion.test.js +13 -13
  145. package/dist/v1/utils/registry-conversion.test.js.map +1 -1
  146. package/dist/v1/utils/stream-handler.test.js +5 -5
  147. package/dist/v1/utils/stream-handler.test.js.map +1 -1
  148. package/dist/v1/utils/tool-call-tracker.test.js +15 -9
  149. package/dist/v1/utils/tool-call-tracker.test.js.map +1 -1
  150. package/dist/v1/utils/tool-executor.test.js +25 -26
  151. package/dist/v1/utils/tool-executor.test.js.map +1 -1
  152. package/dist/v1/utils/unstrictify.test.js +16 -16
  153. package/dist/v1/utils/unstrictify.test.js.map +1 -1
  154. package/esm/context-helpers/current-interactables-context-helper.d.ts +16 -2
  155. package/esm/context-helpers/current-interactables-context-helper.d.ts.map +1 -1
  156. package/esm/context-helpers/current-interactables-context-helper.js.map +1 -1
  157. package/esm/context-helpers/current-interactables-context-helper.test.d.ts +2 -0
  158. package/esm/context-helpers/current-interactables-context-helper.test.d.ts.map +1 -0
  159. package/esm/context-helpers/current-interactables-context-helper.test.js +68 -0
  160. package/esm/context-helpers/current-interactables-context-helper.test.js.map +1 -0
  161. package/esm/mcp/elicitation.d.ts +3 -37
  162. package/esm/mcp/elicitation.d.ts.map +1 -1
  163. package/esm/mcp/elicitation.js +4 -24
  164. package/esm/mcp/elicitation.js.map +1 -1
  165. package/esm/mcp/index.d.ts +4 -4
  166. package/esm/mcp/index.d.ts.map +1 -1
  167. package/esm/mcp/index.js +1 -1
  168. package/esm/mcp/index.js.map +1 -1
  169. package/esm/mcp/mcp-client.test.js +1 -1
  170. package/esm/mcp/mcp-client.test.js.map +1 -1
  171. package/esm/mcp/mcp-hooks.d.ts.map +1 -1
  172. package/esm/mcp/mcp-hooks.js +4 -1
  173. package/esm/mcp/mcp-hooks.js.map +1 -1
  174. package/esm/mcp/mcp-hooks.test.js +3 -2
  175. package/esm/mcp/mcp-hooks.test.js.map +1 -1
  176. package/esm/mcp/tambo-mcp-provider.d.ts +6 -9
  177. package/esm/mcp/tambo-mcp-provider.d.ts.map +1 -1
  178. package/esm/mcp/tambo-mcp-provider.js +4 -8
  179. package/esm/mcp/tambo-mcp-provider.js.map +1 -1
  180. package/esm/mcp/tambo-mcp-provider.test.js +3 -2
  181. package/esm/mcp/tambo-mcp-provider.test.js.map +1 -1
  182. package/esm/mcp/use-mcp-servers.test.js +2 -1
  183. package/esm/mcp/use-mcp-servers.test.js.map +1 -1
  184. package/esm/model/component-metadata.d.ts +7 -372
  185. package/esm/model/component-metadata.d.ts.map +1 -1
  186. package/esm/model/component-metadata.js.map +1 -1
  187. package/esm/model/validate-input.test.d.ts +2 -0
  188. package/esm/model/validate-input.test.d.ts.map +1 -0
  189. package/esm/model/validate-input.test.js +36 -0
  190. package/esm/model/validate-input.test.js.map +1 -0
  191. package/esm/providers/tambo-interactable-provider.d.ts +7 -7
  192. package/esm/providers/tambo-registry-provider.d.ts +1 -1
  193. package/esm/providers/tambo-registry-provider.d.ts.map +1 -1
  194. package/esm/providers/tambo-registry-provider.js.map +1 -1
  195. package/esm/providers/tambo-registry-schema-compat.test.js +4 -4
  196. package/esm/providers/tambo-registry-schema-compat.test.js.map +1 -1
  197. package/esm/schema/index.d.ts +2 -4
  198. package/esm/schema/index.d.ts.map +1 -1
  199. package/esm/schema/index.js +2 -4
  200. package/esm/schema/index.js.map +1 -1
  201. package/esm/schema/json-schema.d.ts +1 -17
  202. package/esm/schema/json-schema.d.ts.map +1 -1
  203. package/esm/schema/json-schema.js +2 -67
  204. package/esm/schema/json-schema.js.map +1 -1
  205. package/esm/schema/schema.test.js +1 -2
  206. package/esm/schema/schema.test.js.map +1 -1
  207. package/esm/schema/standard-schema.test.js +1 -1
  208. package/esm/schema/standard-schema.test.js.map +1 -1
  209. package/esm/schema/validate.test.js +1 -1
  210. package/esm/schema/validate.test.js.map +1 -1
  211. package/esm/testing/tools.d.ts +4 -4
  212. package/esm/testing/tools.test.d.ts +2 -0
  213. package/esm/testing/tools.test.d.ts.map +1 -0
  214. package/esm/testing/tools.test.js +58 -0
  215. package/esm/testing/tools.test.js.map +1 -0
  216. package/esm/util/mcp-server-utils.d.ts +1 -1
  217. package/esm/util/mcp-server-utils.d.ts.map +1 -1
  218. package/esm/util/mcp-server-utils.js +1 -1
  219. package/esm/util/mcp-server-utils.js.map +1 -1
  220. package/esm/util/mcp-server-utils.test.js +1 -1
  221. package/esm/util/mcp-server-utils.test.js.map +1 -1
  222. package/esm/util/registry.js +1 -1
  223. package/esm/util/registry.js.map +1 -1
  224. package/esm/util/resource-content-resolver.js +1 -1
  225. package/esm/util/resource-content-resolver.js.map +1 -1
  226. package/esm/util/resource-content-resolver.test.js +2 -2
  227. package/esm/util/resource-content-resolver.test.js.map +1 -1
  228. package/esm/util/tool-caller.test.d.ts +2 -0
  229. package/esm/util/tool-caller.test.d.ts.map +1 -0
  230. package/esm/util/tool-caller.test.js +69 -0
  231. package/esm/util/tool-caller.test.js.map +1 -0
  232. package/esm/v1/__tests__/v1-interactables.test.js +1 -0
  233. package/esm/v1/__tests__/v1-interactables.test.js.map +1 -1
  234. package/esm/v1/hooks/use-tambo-v1-auth-state.d.ts +1 -1
  235. package/esm/v1/hooks/use-tambo-v1-auth-state.d.ts.map +1 -1
  236. package/esm/v1/hooks/use-tambo-v1-auth-state.js.map +1 -1
  237. package/esm/v1/hooks/use-tambo-v1-component-state.js +1 -1
  238. package/esm/v1/hooks/use-tambo-v1-component-state.js.map +1 -1
  239. package/esm/v1/hooks/use-tambo-v1-component-state.test.js +1 -1
  240. package/esm/v1/hooks/use-tambo-v1-component-state.test.js.map +1 -1
  241. package/esm/v1/hooks/use-tambo-v1-send-message.d.ts +1 -1
  242. package/esm/v1/hooks/use-tambo-v1-send-message.d.ts.map +1 -1
  243. package/esm/v1/hooks/use-tambo-v1-send-message.js +6 -6
  244. package/esm/v1/hooks/use-tambo-v1-send-message.js.map +1 -1
  245. package/esm/v1/hooks/use-tambo-v1-send-message.test.js +1 -1
  246. package/esm/v1/hooks/use-tambo-v1-send-message.test.js.map +1 -1
  247. package/esm/v1/hooks/use-tambo-v1-stream-status.js +1 -1
  248. package/esm/v1/hooks/use-tambo-v1-stream-status.js.map +1 -1
  249. package/esm/v1/hooks/use-tambo-v1-stream-status.test.js +9 -5
  250. package/esm/v1/hooks/use-tambo-v1-stream-status.test.js.map +1 -1
  251. package/esm/v1/hooks/use-tambo-v1-suggestions.js +1 -1
  252. package/esm/v1/hooks/use-tambo-v1-suggestions.js.map +1 -1
  253. package/esm/v1/hooks/use-tambo-v1-thread-input.test.js +104 -0
  254. package/esm/v1/hooks/use-tambo-v1-thread-input.test.js.map +1 -1
  255. package/esm/v1/hooks/use-tambo-v1.d.ts +7 -6
  256. package/esm/v1/hooks/use-tambo-v1.d.ts.map +1 -1
  257. package/esm/v1/hooks/use-tambo-v1.js +1 -1
  258. package/esm/v1/hooks/use-tambo-v1.js.map +1 -1
  259. package/esm/v1/hooks/use-tambo-v1.test.js +22 -22
  260. package/esm/v1/hooks/use-tambo-v1.test.js.map +1 -1
  261. package/esm/v1/index.d.ts +6 -6
  262. package/esm/v1/index.d.ts.map +1 -1
  263. package/esm/v1/index.js +1 -1
  264. package/esm/v1/index.js.map +1 -1
  265. package/esm/v1/providers/tambo-v1-provider.d.ts +2 -1
  266. package/esm/v1/providers/tambo-v1-provider.d.ts.map +1 -1
  267. package/esm/v1/providers/tambo-v1-provider.js +2 -0
  268. package/esm/v1/providers/tambo-v1-provider.js.map +1 -1
  269. package/esm/v1/providers/tambo-v1-stream-context.d.ts +2 -2
  270. package/esm/v1/providers/tambo-v1-stream-context.d.ts.map +1 -1
  271. package/esm/v1/providers/tambo-v1-stream-context.js +1 -1
  272. package/esm/v1/providers/tambo-v1-stream-context.js.map +1 -1
  273. package/esm/v1/providers/tambo-v1-stream-context.test.js +35 -0
  274. package/esm/v1/providers/tambo-v1-stream-context.test.js.map +1 -1
  275. package/esm/v1/providers/tambo-v1-stub-provider.d.ts +1 -1
  276. package/esm/v1/providers/tambo-v1-stub-provider.d.ts.map +1 -1
  277. package/esm/v1/providers/tambo-v1-stub-provider.js +1 -1
  278. package/esm/v1/providers/tambo-v1-stub-provider.js.map +1 -1
  279. package/esm/v1/providers/tambo-v1-stub-provider.test.js.map +1 -1
  280. package/esm/v1/providers/tambo-v1-thread-input-provider.d.ts +1 -1
  281. package/esm/v1/providers/tambo-v1-thread-input-provider.d.ts.map +1 -1
  282. package/esm/v1/providers/tambo-v1-thread-input-provider.js +32 -16
  283. package/esm/v1/providers/tambo-v1-thread-input-provider.js.map +1 -1
  284. package/esm/v1/types/event.test.js +1 -1
  285. package/esm/v1/types/event.test.js.map +1 -1
  286. package/esm/v1/types/message.d.ts +12 -109
  287. package/esm/v1/types/message.d.ts.map +1 -1
  288. package/esm/v1/types/message.js +0 -7
  289. package/esm/v1/types/message.js.map +1 -1
  290. package/esm/v1/utils/event-accumulator.test.js +2 -3
  291. package/esm/v1/utils/event-accumulator.test.js.map +1 -1
  292. package/esm/v1/utils/json-patch.test.js +1 -1
  293. package/esm/v1/utils/json-patch.test.js.map +1 -1
  294. package/esm/v1/utils/keyed-throttle.test.js +1 -1
  295. package/esm/v1/utils/keyed-throttle.test.js.map +1 -1
  296. package/esm/v1/utils/registry-conversion.test.js +1 -1
  297. package/esm/v1/utils/registry-conversion.test.js.map +1 -1
  298. package/esm/v1/utils/stream-handler.test.js +1 -1
  299. package/esm/v1/utils/stream-handler.test.js.map +1 -1
  300. package/esm/v1/utils/tool-call-tracker.test.js +9 -3
  301. package/esm/v1/utils/tool-call-tracker.test.js.map +1 -1
  302. package/esm/v1/utils/tool-executor.test.js +1 -2
  303. package/esm/v1/utils/tool-executor.test.js.map +1 -1
  304. package/esm/v1/utils/unstrictify.test.js +1 -1
  305. package/esm/v1/utils/unstrictify.test.js.map +1 -1
  306. package/package.json +12 -15
  307. package/dist/mcp/mcp-client.d.ts +0 -185
  308. package/dist/mcp/mcp-client.d.ts.map +0 -1
  309. package/dist/mcp/mcp-client.js +0 -219
  310. package/dist/mcp/mcp-client.js.map +0 -1
  311. package/dist/mcp/mcp-constants.d.ts +0 -19
  312. package/dist/mcp/mcp-constants.d.ts.map +0 -1
  313. package/dist/mcp/mcp-constants.js +0 -21
  314. package/dist/mcp/mcp-constants.js.map +0 -1
  315. package/dist/model/mcp-server-info.d.ts +0 -76
  316. package/dist/model/mcp-server-info.d.ts.map +0 -1
  317. package/dist/model/mcp-server-info.js +0 -29
  318. package/dist/model/mcp-server-info.js.map +0 -1
  319. package/dist/schema/schema.d.ts +0 -49
  320. package/dist/schema/schema.d.ts.map +0 -1
  321. package/dist/schema/schema.js +0 -129
  322. package/dist/schema/schema.js.map +0 -1
  323. package/dist/schema/standard-schema.d.ts +0 -22
  324. package/dist/schema/standard-schema.d.ts.map +0 -1
  325. package/dist/schema/standard-schema.js +0 -42
  326. package/dist/schema/standard-schema.js.map +0 -1
  327. package/dist/schema/validate.d.ts +0 -14
  328. package/dist/schema/validate.d.ts.map +0 -1
  329. package/dist/schema/validate.js +0 -148
  330. package/dist/schema/validate.js.map +0 -1
  331. package/dist/v1/types/auth.d.ts +0 -24
  332. package/dist/v1/types/auth.d.ts.map +0 -1
  333. package/dist/v1/types/auth.js +0 -3
  334. package/dist/v1/types/auth.js.map +0 -1
  335. package/dist/v1/types/event.d.ts +0 -89
  336. package/dist/v1/types/event.d.ts.map +0 -1
  337. package/dist/v1/types/event.js +0 -57
  338. package/dist/v1/types/event.js.map +0 -1
  339. package/dist/v1/types/thread.d.ts +0 -58
  340. package/dist/v1/types/thread.d.ts.map +0 -1
  341. package/dist/v1/types/thread.js +0 -9
  342. package/dist/v1/types/thread.js.map +0 -1
  343. package/dist/v1/types/tool-choice.d.ts +0 -8
  344. package/dist/v1/types/tool-choice.d.ts.map +0 -1
  345. package/dist/v1/types/tool-choice.js +0 -3
  346. package/dist/v1/types/tool-choice.js.map +0 -1
  347. package/dist/v1/utils/event-accumulator.d.ts +0 -165
  348. package/dist/v1/utils/event-accumulator.d.ts.map +0 -1
  349. package/dist/v1/utils/event-accumulator.js +0 -1277
  350. package/dist/v1/utils/event-accumulator.js.map +0 -1
  351. package/dist/v1/utils/json-patch.d.ts +0 -18
  352. package/dist/v1/utils/json-patch.d.ts.map +0 -1
  353. package/dist/v1/utils/json-patch.js +0 -35
  354. package/dist/v1/utils/json-patch.js.map +0 -1
  355. package/dist/v1/utils/keyed-throttle.d.ts +0 -42
  356. package/dist/v1/utils/keyed-throttle.d.ts.map +0 -1
  357. package/dist/v1/utils/keyed-throttle.js +0 -86
  358. package/dist/v1/utils/keyed-throttle.js.map +0 -1
  359. package/dist/v1/utils/registry-conversion.d.ts +0 -53
  360. package/dist/v1/utils/registry-conversion.d.ts.map +0 -1
  361. package/dist/v1/utils/registry-conversion.js +0 -115
  362. package/dist/v1/utils/registry-conversion.js.map +0 -1
  363. package/dist/v1/utils/stream-handler.d.ts +0 -45
  364. package/dist/v1/utils/stream-handler.d.ts.map +0 -1
  365. package/dist/v1/utils/stream-handler.js +0 -47
  366. package/dist/v1/utils/stream-handler.js.map +0 -1
  367. package/dist/v1/utils/thread-utils.d.ts +0 -16
  368. package/dist/v1/utils/thread-utils.d.ts.map +0 -1
  369. package/dist/v1/utils/thread-utils.js +0 -34
  370. package/dist/v1/utils/thread-utils.js.map +0 -1
  371. package/dist/v1/utils/tool-call-tracker.d.ts +0 -73
  372. package/dist/v1/utils/tool-call-tracker.d.ts.map +0 -1
  373. package/dist/v1/utils/tool-call-tracker.js +0 -180
  374. package/dist/v1/utils/tool-call-tracker.js.map +0 -1
  375. package/dist/v1/utils/tool-executor.d.ts +0 -67
  376. package/dist/v1/utils/tool-executor.d.ts.map +0 -1
  377. package/dist/v1/utils/tool-executor.js +0 -160
  378. package/dist/v1/utils/tool-executor.js.map +0 -1
  379. package/dist/v1/utils/unstrictify.d.ts +0 -32
  380. package/dist/v1/utils/unstrictify.d.ts.map +0 -1
  381. package/dist/v1/utils/unstrictify.js +0 -159
  382. package/dist/v1/utils/unstrictify.js.map +0 -1
  383. package/esm/mcp/mcp-client.d.ts +0 -185
  384. package/esm/mcp/mcp-client.d.ts.map +0 -1
  385. package/esm/mcp/mcp-client.js +0 -216
  386. package/esm/mcp/mcp-client.js.map +0 -1
  387. package/esm/mcp/mcp-constants.d.ts +0 -19
  388. package/esm/mcp/mcp-constants.d.ts.map +0 -1
  389. package/esm/mcp/mcp-constants.js +0 -18
  390. package/esm/mcp/mcp-constants.js.map +0 -1
  391. package/esm/model/mcp-server-info.d.ts +0 -76
  392. package/esm/model/mcp-server-info.d.ts.map +0 -1
  393. package/esm/model/mcp-server-info.js +0 -25
  394. package/esm/model/mcp-server-info.js.map +0 -1
  395. package/esm/schema/schema.d.ts +0 -49
  396. package/esm/schema/schema.d.ts.map +0 -1
  397. package/esm/schema/schema.js +0 -124
  398. package/esm/schema/schema.js.map +0 -1
  399. package/esm/schema/standard-schema.d.ts +0 -22
  400. package/esm/schema/standard-schema.d.ts.map +0 -1
  401. package/esm/schema/standard-schema.js +0 -39
  402. package/esm/schema/standard-schema.js.map +0 -1
  403. package/esm/schema/validate.d.ts +0 -14
  404. package/esm/schema/validate.d.ts.map +0 -1
  405. package/esm/schema/validate.js +0 -145
  406. package/esm/schema/validate.js.map +0 -1
  407. package/esm/v1/types/auth.d.ts +0 -24
  408. package/esm/v1/types/auth.d.ts.map +0 -1
  409. package/esm/v1/types/auth.js +0 -2
  410. package/esm/v1/types/auth.js.map +0 -1
  411. package/esm/v1/types/event.d.ts +0 -89
  412. package/esm/v1/types/event.d.ts.map +0 -1
  413. package/esm/v1/types/event.js +0 -53
  414. package/esm/v1/types/event.js.map +0 -1
  415. package/esm/v1/types/thread.d.ts +0 -58
  416. package/esm/v1/types/thread.d.ts.map +0 -1
  417. package/esm/v1/types/thread.js +0 -8
  418. package/esm/v1/types/thread.js.map +0 -1
  419. package/esm/v1/types/tool-choice.d.ts +0 -8
  420. package/esm/v1/types/tool-choice.d.ts.map +0 -1
  421. package/esm/v1/types/tool-choice.js +0 -2
  422. package/esm/v1/types/tool-choice.js.map +0 -1
  423. package/esm/v1/utils/event-accumulator.d.ts +0 -165
  424. package/esm/v1/utils/event-accumulator.d.ts.map +0 -1
  425. package/esm/v1/utils/event-accumulator.js +0 -1268
  426. package/esm/v1/utils/event-accumulator.js.map +0 -1
  427. package/esm/v1/utils/json-patch.d.ts +0 -18
  428. package/esm/v1/utils/json-patch.d.ts.map +0 -1
  429. package/esm/v1/utils/json-patch.js +0 -32
  430. package/esm/v1/utils/json-patch.js.map +0 -1
  431. package/esm/v1/utils/keyed-throttle.d.ts +0 -42
  432. package/esm/v1/utils/keyed-throttle.d.ts.map +0 -1
  433. package/esm/v1/utils/keyed-throttle.js +0 -83
  434. package/esm/v1/utils/keyed-throttle.js.map +0 -1
  435. package/esm/v1/utils/registry-conversion.d.ts +0 -53
  436. package/esm/v1/utils/registry-conversion.d.ts.map +0 -1
  437. package/esm/v1/utils/registry-conversion.js +0 -109
  438. package/esm/v1/utils/registry-conversion.js.map +0 -1
  439. package/esm/v1/utils/stream-handler.d.ts +0 -45
  440. package/esm/v1/utils/stream-handler.d.ts.map +0 -1
  441. package/esm/v1/utils/stream-handler.js +0 -44
  442. package/esm/v1/utils/stream-handler.js.map +0 -1
  443. package/esm/v1/utils/thread-utils.d.ts +0 -16
  444. package/esm/v1/utils/thread-utils.d.ts.map +0 -1
  445. package/esm/v1/utils/thread-utils.js +0 -31
  446. package/esm/v1/utils/thread-utils.js.map +0 -1
  447. package/esm/v1/utils/tool-call-tracker.d.ts +0 -73
  448. package/esm/v1/utils/tool-call-tracker.d.ts.map +0 -1
  449. package/esm/v1/utils/tool-call-tracker.js +0 -176
  450. package/esm/v1/utils/tool-call-tracker.js.map +0 -1
  451. package/esm/v1/utils/tool-executor.d.ts +0 -67
  452. package/esm/v1/utils/tool-executor.d.ts.map +0 -1
  453. package/esm/v1/utils/tool-executor.js +0 -154
  454. package/esm/v1/utils/tool-executor.js.map +0 -1
  455. package/esm/v1/utils/unstrictify.d.ts +0 -32
  456. package/esm/v1/utils/unstrictify.d.ts.map +0 -1
  457. package/esm/v1/utils/unstrictify.js +0 -155
  458. package/esm/v1/utils/unstrictify.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-server-utils.test.js","sourceRoot":"","sources":["../../src/util/mcp-server-utils.test.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n McpServerInfo,\n NormalizedMcpServerInfo,\n} from \"../model/mcp-server-info\";\nimport { MCPTransport } from \"../model/mcp-server-info\";\nimport {\n deduplicateMcpServers,\n deriveServerKey,\n normalizeServerInfo,\n} from \"./mcp-server-utils\";\n\ndescribe(\"deriveServerKey\", () => {\n it(\"should extract key from simple domain\", () => {\n expect(deriveServerKey(\"https://linear.app/mcp\")).toBe(\"linear\");\n });\n\n it(\"should extract key from subdomain\", () => {\n expect(deriveServerKey(\"https://mcp.linear.app/mcp\")).toBe(\"linear\");\n });\n\n it(\"should extract key from www subdomain\", () => {\n expect(deriveServerKey(\"https://www.example.com/mcp\")).toBe(\"example\");\n });\n\n it(\"should extract key from api subdomain\", () => {\n expect(deriveServerKey(\"https://api.service.com/mcp\")).toBe(\"service\");\n });\n\n it(\"should extract key from app subdomain\", () => {\n expect(deriveServerKey(\"https://app.tool.com/mcp\")).toBe(\"tool\");\n });\n\n it(\"should handle multi-part TLDs like .co.uk\", () => {\n expect(deriveServerKey(\"https://example.co.uk/mcp\")).toBe(\"example\");\n });\n\n it(\"should handle .com.au TLDs\", () => {\n expect(deriveServerKey(\"https://service.com.au/mcp\")).toBe(\"service\");\n });\n\n it(\"should prefer meaningful part over common prefixes\", () => {\n // mcp.staging.app.com -> after removing TLD: [\"mcp\", \"staging\", \"app\"]\n // Working backwards: checks \"app\" (index 2) - common prefix, continue\n // Checks \"staging\" (index 1) - common prefix, continue\n // Checks \"mcp\" (index 0) - common prefix, continue\n // Falls back - actual behavior returns \"staging\"\n expect(deriveServerKey(\"https://mcp.staging.app.com/mcp\")).toBe(\"staging\");\n });\n\n it(\"should fallback to last part if all are common prefixes\", () => {\n // www.api.mcp.com -> after removing TLD: [\"www\", \"api\", \"mcp\"]\n // All are common prefixes, so falls back to last relevant part\n // The actual implementation returns \"api\" (the middle part)\n // This appears to be the behavior, so we test for it\n expect(deriveServerKey(\"https://www.api.mcp.com/mcp\")).toBe(\"api\");\n });\n\n it(\"should handle single-part hostname\", () => {\n expect(deriveServerKey(\"https://localhost:3000/mcp\")).toBe(\"localhost\");\n });\n\n it(\"should handle invalid URL by sanitizing\", () => {\n const result = deriveServerKey(\"not-a-url!!!\");\n expect(result).toBe(\"not_a_url___\");\n expect(result).toMatch(/^[a-z0-9_]+$/);\n });\n\n it(\"should lowercase the result\", () => {\n expect(deriveServerKey(\"https://EXAMPLE.COM/mcp\")).toBe(\"example\");\n });\n\n it(\"should handle staging subdomain\", () => {\n expect(deriveServerKey(\"https://staging.service.com/mcp\")).toBe(\"service\");\n });\n\n it(\"should handle dev subdomain\", () => {\n expect(deriveServerKey(\"https://dev.tool.com/mcp\")).toBe(\"tool\");\n });\n\n it(\"should handle prod subdomain\", () => {\n expect(deriveServerKey(\"https://prod.service.com/mcp\")).toBe(\"service\");\n });\n});\n\ndescribe(\"normalizeServerInfo\", () => {\n it(\"should normalize string URL to server info\", () => {\n const result = normalizeServerInfo(\"https://example.com/mcp\");\n\n expect(result).toEqual({\n url: \"https://example.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"example\",\n });\n });\n\n it(\"should preserve existing serverKey\", () => {\n const server: McpServerInfo = {\n url: \"https://example.com/mcp\",\n serverKey: \"custom-key\",\n };\n\n const result = normalizeServerInfo(server);\n\n expect(result.serverKey).toBe(\"custom-key\");\n expect(result.transport).toBe(MCPTransport.HTTP);\n });\n\n it(\"should derive serverKey when not provided\", () => {\n const server: McpServerInfo = {\n url: \"https://mcp.linear.app/mcp\",\n };\n\n const result = normalizeServerInfo(server);\n\n expect(result.serverKey).toBe(\"linear\");\n });\n\n it(\"should preserve existing transport\", () => {\n const server: McpServerInfo = {\n url: \"https://example.com/mcp\",\n transport: MCPTransport.SSE,\n };\n\n const result = normalizeServerInfo(server);\n\n expect(result.transport).toBe(MCPTransport.SSE);\n });\n\n it(\"should default transport to HTTP when not provided\", () => {\n const server: McpServerInfo = {\n url: \"https://example.com/mcp\",\n };\n\n const result = normalizeServerInfo(server);\n\n expect(result.transport).toBe(MCPTransport.HTTP);\n });\n\n it(\"should preserve all other properties\", () => {\n const server: McpServerInfo = {\n url: \"https://example.com/mcp\",\n name: \"Test Server\",\n description: \"A test server\",\n customHeaders: { \"X-API-Key\": \"secret\" },\n handlers: {},\n };\n\n const result = normalizeServerInfo(server);\n\n expect(result.name).toBe(\"Test Server\");\n expect(result.description).toBe(\"A test server\");\n expect(result.customHeaders).toEqual({ \"X-API-Key\": \"secret\" });\n expect(result.handlers).toEqual({});\n });\n\n it(\"should handle server with all optional fields\", () => {\n const server: McpServerInfo = {\n url: \"https://example.com/mcp\",\n name: \"My Server\",\n description: \"Description\",\n transport: MCPTransport.SSE,\n serverKey: \"my-server\",\n customHeaders: { Authorization: \"Bearer token\" },\n };\n\n const result = normalizeServerInfo(server);\n\n expect(result).toEqual({\n url: \"https://example.com/mcp\",\n name: \"My Server\",\n description: \"Description\",\n transport: MCPTransport.SSE,\n serverKey: \"my-server\",\n customHeaders: { Authorization: \"Bearer token\" },\n });\n });\n});\n\ndescribe(\"deduplicateMcpServers\", () => {\n it(\"should return empty array for empty input\", () => {\n expect(deduplicateMcpServers([])).toEqual([]);\n });\n\n it(\"should return single server unchanged\", () => {\n const server: NormalizedMcpServerInfo = {\n url: \"https://example.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"example\",\n };\n\n expect(deduplicateMcpServers([server])).toEqual([server]);\n });\n\n it(\"should deduplicate servers with same URL and transport\", () => {\n const server1: NormalizedMcpServerInfo = {\n url: \"https://example.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"example\",\n };\n const server2: NormalizedMcpServerInfo = {\n url: \"https://example.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"example\",\n };\n\n const result = deduplicateMcpServers([server1, server2]);\n\n expect(result).toHaveLength(1);\n expect(result[0].url).toBe(\"https://example.com/mcp\");\n });\n\n it(\"should keep servers with different URLs\", () => {\n const server1: NormalizedMcpServerInfo = {\n url: \"https://example.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"example\",\n };\n const server2: NormalizedMcpServerInfo = {\n url: \"https://other.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"other\",\n };\n\n const result = deduplicateMcpServers([server1, server2]);\n\n expect(result).toHaveLength(2);\n });\n\n it(\"should keep servers with same URL but different transport\", () => {\n const server1: NormalizedMcpServerInfo = {\n url: \"https://example.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"example\",\n };\n const server2: NormalizedMcpServerInfo = {\n url: \"https://example.com/mcp\",\n transport: MCPTransport.SSE,\n serverKey: \"example\",\n };\n\n const result = deduplicateMcpServers([server1, server2]);\n\n expect(result).toHaveLength(2);\n });\n\n it(\"should ensure unique serverKeys by appending suffixes\", () => {\n const server1: NormalizedMcpServerInfo = {\n url: \"https://example1.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"linear\",\n };\n const server2: NormalizedMcpServerInfo = {\n url: \"https://example2.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"linear\",\n };\n const server3: NormalizedMcpServerInfo = {\n url: \"https://example3.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"linear\",\n };\n\n const result = deduplicateMcpServers([server1, server2, server3]);\n\n expect(result).toHaveLength(3);\n expect(result[0].serverKey).toBe(\"linear\");\n expect(result[1].serverKey).toBe(\"linear-2\");\n expect(result[2].serverKey).toBe(\"linear-3\");\n });\n\n it(\"should handle mixed unique and duplicate serverKeys\", () => {\n const server1: NormalizedMcpServerInfo = {\n url: \"https://example1.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"linear\",\n };\n const server2: NormalizedMcpServerInfo = {\n url: \"https://example2.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"notion\",\n };\n const server3: NormalizedMcpServerInfo = {\n url: \"https://example3.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"linear\",\n };\n\n const result = deduplicateMcpServers([server1, server2, server3]);\n\n expect(result).toHaveLength(3);\n expect(result[0].serverKey).toBe(\"linear\");\n expect(result[1].serverKey).toBe(\"notion\");\n expect(result[2].serverKey).toBe(\"linear-2\");\n });\n\n it(\"should deduplicate by connection first, then ensure serverKey uniqueness\", () => {\n // Same connection, different serverKeys (shouldn't happen in practice but test the logic)\n const server1: NormalizedMcpServerInfo = {\n url: \"https://example.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"linear\",\n };\n const server2: NormalizedMcpServerInfo = {\n url: \"https://example.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"notion\",\n };\n\n const result = deduplicateMcpServers([server1, server2]);\n\n // Should deduplicate by connection, keeping only one\n expect(result).toHaveLength(1);\n });\n\n it(\"should preserve server properties when deduplicating\", () => {\n const server1: NormalizedMcpServerInfo = {\n url: \"https://example.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"example\",\n name: \"First Server\",\n };\n const server2: NormalizedMcpServerInfo = {\n url: \"https://example.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"example\",\n name: \"Second Server\",\n };\n\n const result = deduplicateMcpServers([server1, server2]);\n\n expect(result).toHaveLength(1);\n // Should keep the last one encountered\n expect(result[0].name).toBe(\"Second Server\");\n });\n\n it(\"should handle servers with different customHeaders as different connections\", () => {\n const server1: NormalizedMcpServerInfo = {\n url: \"https://example.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"example\",\n customHeaders: { Authorization: \"Bearer token1\" },\n };\n const server2: NormalizedMcpServerInfo = {\n url: \"https://example.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"example\",\n customHeaders: { Authorization: \"Bearer token2\" },\n };\n\n const result = deduplicateMcpServers([server1, server2]);\n\n expect(result).toHaveLength(2);\n });\n});\n"]}
1
+ {"version":3,"file":"mcp-server-utils.test.js","sourceRoot":"","sources":["../../src/util/mcp-server-utils.test.ts"],"names":[],"mappings":"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","sourcesContent":["import type { McpServerInfo, NormalizedMcpServerInfo } from \"@tambo-ai/client\";\nimport { MCPTransport } from \"@tambo-ai/client\";\nimport {\n deduplicateMcpServers,\n deriveServerKey,\n normalizeServerInfo,\n} from \"./mcp-server-utils\";\n\ndescribe(\"deriveServerKey\", () => {\n it(\"should extract key from simple domain\", () => {\n expect(deriveServerKey(\"https://linear.app/mcp\")).toBe(\"linear\");\n });\n\n it(\"should extract key from subdomain\", () => {\n expect(deriveServerKey(\"https://mcp.linear.app/mcp\")).toBe(\"linear\");\n });\n\n it(\"should extract key from www subdomain\", () => {\n expect(deriveServerKey(\"https://www.example.com/mcp\")).toBe(\"example\");\n });\n\n it(\"should extract key from api subdomain\", () => {\n expect(deriveServerKey(\"https://api.service.com/mcp\")).toBe(\"service\");\n });\n\n it(\"should extract key from app subdomain\", () => {\n expect(deriveServerKey(\"https://app.tool.com/mcp\")).toBe(\"tool\");\n });\n\n it(\"should handle multi-part TLDs like .co.uk\", () => {\n expect(deriveServerKey(\"https://example.co.uk/mcp\")).toBe(\"example\");\n });\n\n it(\"should handle .com.au TLDs\", () => {\n expect(deriveServerKey(\"https://service.com.au/mcp\")).toBe(\"service\");\n });\n\n it(\"should prefer meaningful part over common prefixes\", () => {\n // mcp.staging.app.com -> after removing TLD: [\"mcp\", \"staging\", \"app\"]\n // Working backwards: checks \"app\" (index 2) - common prefix, continue\n // Checks \"staging\" (index 1) - common prefix, continue\n // Checks \"mcp\" (index 0) - common prefix, continue\n // Falls back - actual behavior returns \"staging\"\n expect(deriveServerKey(\"https://mcp.staging.app.com/mcp\")).toBe(\"staging\");\n });\n\n it(\"should fallback to last part if all are common prefixes\", () => {\n // www.api.mcp.com -> after removing TLD: [\"www\", \"api\", \"mcp\"]\n // All are common prefixes, so falls back to last relevant part\n // The actual implementation returns \"api\" (the middle part)\n // This appears to be the behavior, so we test for it\n expect(deriveServerKey(\"https://www.api.mcp.com/mcp\")).toBe(\"api\");\n });\n\n it(\"should handle single-part hostname\", () => {\n expect(deriveServerKey(\"https://localhost:3000/mcp\")).toBe(\"localhost\");\n });\n\n it(\"should handle invalid URL by sanitizing\", () => {\n const result = deriveServerKey(\"not-a-url!!!\");\n expect(result).toBe(\"not_a_url___\");\n expect(result).toMatch(/^[a-z0-9_]+$/);\n });\n\n it(\"should lowercase the result\", () => {\n expect(deriveServerKey(\"https://EXAMPLE.COM/mcp\")).toBe(\"example\");\n });\n\n it(\"should handle staging subdomain\", () => {\n expect(deriveServerKey(\"https://staging.service.com/mcp\")).toBe(\"service\");\n });\n\n it(\"should handle dev subdomain\", () => {\n expect(deriveServerKey(\"https://dev.tool.com/mcp\")).toBe(\"tool\");\n });\n\n it(\"should handle prod subdomain\", () => {\n expect(deriveServerKey(\"https://prod.service.com/mcp\")).toBe(\"service\");\n });\n});\n\ndescribe(\"normalizeServerInfo\", () => {\n it(\"should normalize string URL to server info\", () => {\n const result = normalizeServerInfo(\"https://example.com/mcp\");\n\n expect(result).toEqual({\n url: \"https://example.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"example\",\n });\n });\n\n it(\"should preserve existing serverKey\", () => {\n const server: McpServerInfo = {\n url: \"https://example.com/mcp\",\n serverKey: \"custom-key\",\n };\n\n const result = normalizeServerInfo(server);\n\n expect(result.serverKey).toBe(\"custom-key\");\n expect(result.transport).toBe(MCPTransport.HTTP);\n });\n\n it(\"should derive serverKey when not provided\", () => {\n const server: McpServerInfo = {\n url: \"https://mcp.linear.app/mcp\",\n };\n\n const result = normalizeServerInfo(server);\n\n expect(result.serverKey).toBe(\"linear\");\n });\n\n it(\"should preserve existing transport\", () => {\n const server: McpServerInfo = {\n url: \"https://example.com/mcp\",\n transport: MCPTransport.SSE,\n };\n\n const result = normalizeServerInfo(server);\n\n expect(result.transport).toBe(MCPTransport.SSE);\n });\n\n it(\"should default transport to HTTP when not provided\", () => {\n const server: McpServerInfo = {\n url: \"https://example.com/mcp\",\n };\n\n const result = normalizeServerInfo(server);\n\n expect(result.transport).toBe(MCPTransport.HTTP);\n });\n\n it(\"should preserve all other properties\", () => {\n const server: McpServerInfo = {\n url: \"https://example.com/mcp\",\n name: \"Test Server\",\n description: \"A test server\",\n customHeaders: { \"X-API-Key\": \"secret\" },\n handlers: {},\n };\n\n const result = normalizeServerInfo(server);\n\n expect(result.name).toBe(\"Test Server\");\n expect(result.description).toBe(\"A test server\");\n expect(result.customHeaders).toEqual({ \"X-API-Key\": \"secret\" });\n expect(result.handlers).toEqual({});\n });\n\n it(\"should handle server with all optional fields\", () => {\n const server: McpServerInfo = {\n url: \"https://example.com/mcp\",\n name: \"My Server\",\n description: \"Description\",\n transport: MCPTransport.SSE,\n serverKey: \"my-server\",\n customHeaders: { Authorization: \"Bearer token\" },\n };\n\n const result = normalizeServerInfo(server);\n\n expect(result).toEqual({\n url: \"https://example.com/mcp\",\n name: \"My Server\",\n description: \"Description\",\n transport: MCPTransport.SSE,\n serverKey: \"my-server\",\n customHeaders: { Authorization: \"Bearer token\" },\n });\n });\n});\n\ndescribe(\"deduplicateMcpServers\", () => {\n it(\"should return empty array for empty input\", () => {\n expect(deduplicateMcpServers([])).toEqual([]);\n });\n\n it(\"should return single server unchanged\", () => {\n const server: NormalizedMcpServerInfo = {\n url: \"https://example.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"example\",\n };\n\n expect(deduplicateMcpServers([server])).toEqual([server]);\n });\n\n it(\"should deduplicate servers with same URL and transport\", () => {\n const server1: NormalizedMcpServerInfo = {\n url: \"https://example.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"example\",\n };\n const server2: NormalizedMcpServerInfo = {\n url: \"https://example.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"example\",\n };\n\n const result = deduplicateMcpServers([server1, server2]);\n\n expect(result).toHaveLength(1);\n expect(result[0].url).toBe(\"https://example.com/mcp\");\n });\n\n it(\"should keep servers with different URLs\", () => {\n const server1: NormalizedMcpServerInfo = {\n url: \"https://example.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"example\",\n };\n const server2: NormalizedMcpServerInfo = {\n url: \"https://other.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"other\",\n };\n\n const result = deduplicateMcpServers([server1, server2]);\n\n expect(result).toHaveLength(2);\n });\n\n it(\"should keep servers with same URL but different transport\", () => {\n const server1: NormalizedMcpServerInfo = {\n url: \"https://example.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"example\",\n };\n const server2: NormalizedMcpServerInfo = {\n url: \"https://example.com/mcp\",\n transport: MCPTransport.SSE,\n serverKey: \"example\",\n };\n\n const result = deduplicateMcpServers([server1, server2]);\n\n expect(result).toHaveLength(2);\n });\n\n it(\"should ensure unique serverKeys by appending suffixes\", () => {\n const server1: NormalizedMcpServerInfo = {\n url: \"https://example1.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"linear\",\n };\n const server2: NormalizedMcpServerInfo = {\n url: \"https://example2.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"linear\",\n };\n const server3: NormalizedMcpServerInfo = {\n url: \"https://example3.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"linear\",\n };\n\n const result = deduplicateMcpServers([server1, server2, server3]);\n\n expect(result).toHaveLength(3);\n expect(result[0].serverKey).toBe(\"linear\");\n expect(result[1].serverKey).toBe(\"linear-2\");\n expect(result[2].serverKey).toBe(\"linear-3\");\n });\n\n it(\"should handle mixed unique and duplicate serverKeys\", () => {\n const server1: NormalizedMcpServerInfo = {\n url: \"https://example1.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"linear\",\n };\n const server2: NormalizedMcpServerInfo = {\n url: \"https://example2.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"notion\",\n };\n const server3: NormalizedMcpServerInfo = {\n url: \"https://example3.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"linear\",\n };\n\n const result = deduplicateMcpServers([server1, server2, server3]);\n\n expect(result).toHaveLength(3);\n expect(result[0].serverKey).toBe(\"linear\");\n expect(result[1].serverKey).toBe(\"notion\");\n expect(result[2].serverKey).toBe(\"linear-2\");\n });\n\n it(\"should deduplicate by connection first, then ensure serverKey uniqueness\", () => {\n // Same connection, different serverKeys (shouldn't happen in practice but test the logic)\n const server1: NormalizedMcpServerInfo = {\n url: \"https://example.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"linear\",\n };\n const server2: NormalizedMcpServerInfo = {\n url: \"https://example.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"notion\",\n };\n\n const result = deduplicateMcpServers([server1, server2]);\n\n // Should deduplicate by connection, keeping only one\n expect(result).toHaveLength(1);\n });\n\n it(\"should preserve server properties when deduplicating\", () => {\n const server1: NormalizedMcpServerInfo = {\n url: \"https://example.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"example\",\n name: \"First Server\",\n };\n const server2: NormalizedMcpServerInfo = {\n url: \"https://example.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"example\",\n name: \"Second Server\",\n };\n\n const result = deduplicateMcpServers([server1, server2]);\n\n expect(result).toHaveLength(1);\n // Should keep the last one encountered\n expect(result[0].name).toBe(\"Second Server\");\n });\n\n it(\"should handle servers with different customHeaders as different connections\", () => {\n const server1: NormalizedMcpServerInfo = {\n url: \"https://example.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"example\",\n customHeaders: { Authorization: \"Bearer token1\" },\n };\n const server2: NormalizedMcpServerInfo = {\n url: \"https://example.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"example\",\n customHeaders: { Authorization: \"Bearer token2\" },\n };\n\n const result = deduplicateMcpServers([server1, server2]);\n\n expect(result).toHaveLength(2);\n });\n});\n"]}
@@ -9,7 +9,7 @@ import { getParametersFromToolSchema, isStandardSchema, schemaToJsonSchema, } fr
9
9
  export const getAvailableComponents = (componentRegistry, toolRegistry, toolAssociations) => {
10
10
  const availableComponents = [];
11
11
  for (const [name, componentEntry] of Object.entries(componentRegistry)) {
12
- const associatedToolNames = toolAssociations[name] || [];
12
+ const associatedToolNames = toolAssociations[name] ?? [];
13
13
  const contextTools = associatedToolNames
14
14
  .map((toolName) => {
15
15
  const tool = toolRegistry[toolName];
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/util/registry.ts"],"names":[],"mappings":"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","sourcesContent":["import TamboAI from \"@tambo-ai/typescript-sdk\";\nimport {\n ComponentContextToolMetadata,\n ComponentRegistry,\n DefineToolFn,\n RegisteredComponent,\n TamboTool,\n TamboToolAssociations,\n TamboToolRegistry,\n} from \"../model/component-metadata\";\nimport {\n getParametersFromToolSchema,\n isStandardSchema,\n schemaToJsonSchema,\n} from \"../schema\";\n\n/**\n * Get all the available components from the component registry\n * @param componentRegistry - The component registry\n * @param toolRegistry - The tool registry\n * @param toolAssociations - The tool associations\n * @returns The available components\n */\nexport const getAvailableComponents = (\n componentRegistry: ComponentRegistry,\n toolRegistry: TamboToolRegistry,\n toolAssociations: TamboToolAssociations,\n): TamboAI.AvailableComponent[] => {\n const availableComponents: TamboAI.AvailableComponent[] = [];\n\n for (const [name, componentEntry] of Object.entries(componentRegistry)) {\n const associatedToolNames = toolAssociations[name] || [];\n\n const contextTools = associatedToolNames\n .map((toolName) => {\n const tool = toolRegistry[toolName];\n if (!tool) return null;\n return mapTamboToolToContextTool(tool);\n })\n .filter((tool): tool is ComponentContextToolMetadata => tool !== null);\n\n availableComponents.push({\n name: componentEntry.name,\n description: componentEntry.description,\n props: componentEntry.props,\n contextTools,\n });\n }\n\n return availableComponents;\n};\n\n/**\n * Get tools from tool registry that are not associated with any component\n * @param toolRegistry - The tool registry\n * @param toolAssociations - The tool associations\n * @returns The tools that are not associated with any component\n */\nexport const getUnassociatedTools = (\n toolRegistry: TamboToolRegistry,\n toolAssociations: TamboToolAssociations,\n): TamboTool[] => {\n return Object.values(toolRegistry).filter((tool) => {\n // Check if the tool's name appears in any of the tool association arrays\n return !Object.values(toolAssociations).flat().includes(tool.name);\n });\n};\n\n/**\n * Helper function to convert component props from Standard Schema or JSON Schema\n * @param component - The component to convert\n * @returns The converted props as JSON Schema\n */\nexport const convertPropsToJsonSchema = (\n component: RegisteredComponent,\n): unknown => {\n if (!component.props) {\n return component.props;\n }\n\n // Check if props is a Standard Schema (Zod, Valibot, ArkType, etc.)\n if (isStandardSchema(component.props)) {\n return schemaToJsonSchema(component.props);\n }\n\n // Already JSON Schema or unknown format - return as-is\n return component.props;\n};\n\n/**\n * Get a component by name from the component registry\n * @param componentName - The name of the component to get\n * @param componentRegistry - The component registry\n * @returns The component registration information\n */\nexport const getComponentFromRegistry = (\n componentName: string,\n componentRegistry: ComponentRegistry,\n): RegisteredComponent => {\n const componentEntry = componentRegistry[componentName];\n\n if (!componentEntry) {\n throw new Error(\n `Tambo tried to use Component ${componentName}, but it was not found.`,\n );\n }\n\n return componentEntry;\n};\n\n/**\n * Map a Tambo tool to a context tool\n * @param tool - The tool to map\n * @returns The context tool\n */\nexport const mapTamboToolToContextTool = (\n tool: TamboTool,\n): ComponentContextToolMetadata => {\n const parameters = getParametersFromToolSchema(tool);\n\n return {\n name: tool.name,\n description: tool.description,\n parameters,\n ...(\"maxCalls\" in tool && tool.maxCalls !== undefined\n ? { maxCalls: tool.maxCalls }\n : {}),\n ...(\"annotations\" in tool && tool.annotations !== undefined\n ? { annotations: tool.annotations }\n : {}),\n };\n};\n\n/**\n * Provides type safety for defining a Tambo Tool.\n *\n * Tambo uses the [standard-schema.dev](https://standard-schema.dev) spec which means you can use any Standard Schema\n * compliant validator (Zod, Valibot, ArkType, etc.). This ensures the tool function args and output types are correctly\n * inferred from the provided schemas.\n * @example\n * ```typescript\n * import { z } from \"zod/v4\";\n *\n * const myTool = defineTamboTool({\n * // ...\n * });\n * ```\n * @param tool The tool definition to register\n * @returns The registered tool definition\n */\nexport const defineTool: DefineToolFn = (tool: any) => {\n if (\"toolSchema\" in tool) {\n return tool;\n }\n tool.inputSchema ??= { type: \"object\", properties: {}, required: [] };\n tool.outputSchema ??= { type: \"object\", properties: {}, required: [] };\n return tool;\n};\n"]}
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/util/registry.ts"],"names":[],"mappings":"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","sourcesContent":["import TamboAI from \"@tambo-ai/typescript-sdk\";\nimport {\n ComponentContextToolMetadata,\n ComponentRegistry,\n DefineToolFn,\n RegisteredComponent,\n TamboTool,\n TamboToolAssociations,\n TamboToolRegistry,\n} from \"../model/component-metadata\";\nimport {\n getParametersFromToolSchema,\n isStandardSchema,\n schemaToJsonSchema,\n} from \"../schema\";\n\n/**\n * Get all the available components from the component registry\n * @param componentRegistry - The component registry\n * @param toolRegistry - The tool registry\n * @param toolAssociations - The tool associations\n * @returns The available components\n */\nexport const getAvailableComponents = (\n componentRegistry: ComponentRegistry,\n toolRegistry: TamboToolRegistry,\n toolAssociations: TamboToolAssociations,\n): TamboAI.AvailableComponent[] => {\n const availableComponents: TamboAI.AvailableComponent[] = [];\n\n for (const [name, componentEntry] of Object.entries(componentRegistry)) {\n const associatedToolNames = toolAssociations[name] ?? [];\n\n const contextTools = associatedToolNames\n .map((toolName) => {\n const tool = toolRegistry[toolName];\n if (!tool) return null;\n return mapTamboToolToContextTool(tool);\n })\n .filter((tool): tool is ComponentContextToolMetadata => tool !== null);\n\n availableComponents.push({\n name: componentEntry.name,\n description: componentEntry.description,\n props: componentEntry.props,\n contextTools,\n });\n }\n\n return availableComponents;\n};\n\n/**\n * Get tools from tool registry that are not associated with any component\n * @param toolRegistry - The tool registry\n * @param toolAssociations - The tool associations\n * @returns The tools that are not associated with any component\n */\nexport const getUnassociatedTools = (\n toolRegistry: TamboToolRegistry,\n toolAssociations: TamboToolAssociations,\n): TamboTool[] => {\n return Object.values(toolRegistry).filter((tool) => {\n // Check if the tool's name appears in any of the tool association arrays\n return !Object.values(toolAssociations).flat().includes(tool.name);\n });\n};\n\n/**\n * Helper function to convert component props from Standard Schema or JSON Schema\n * @param component - The component to convert\n * @returns The converted props as JSON Schema\n */\nexport const convertPropsToJsonSchema = (\n component: RegisteredComponent,\n): unknown => {\n if (!component.props) {\n return component.props;\n }\n\n // Check if props is a Standard Schema (Zod, Valibot, ArkType, etc.)\n if (isStandardSchema(component.props)) {\n return schemaToJsonSchema(component.props);\n }\n\n // Already JSON Schema or unknown format - return as-is\n return component.props;\n};\n\n/**\n * Get a component by name from the component registry\n * @param componentName - The name of the component to get\n * @param componentRegistry - The component registry\n * @returns The component registration information\n */\nexport const getComponentFromRegistry = (\n componentName: string,\n componentRegistry: ComponentRegistry,\n): RegisteredComponent => {\n const componentEntry = componentRegistry[componentName];\n\n if (!componentEntry) {\n throw new Error(\n `Tambo tried to use Component ${componentName}, but it was not found.`,\n );\n }\n\n return componentEntry;\n};\n\n/**\n * Map a Tambo tool to a context tool\n * @param tool - The tool to map\n * @returns The context tool\n */\nexport const mapTamboToolToContextTool = (\n tool: TamboTool,\n): ComponentContextToolMetadata => {\n const parameters = getParametersFromToolSchema(tool);\n\n return {\n name: tool.name,\n description: tool.description,\n parameters,\n ...(\"maxCalls\" in tool && tool.maxCalls !== undefined\n ? { maxCalls: tool.maxCalls }\n : {}),\n ...(\"annotations\" in tool && tool.annotations !== undefined\n ? { annotations: tool.annotations }\n : {}),\n };\n};\n\n/**\n * Provides type safety for defining a Tambo Tool.\n *\n * Tambo uses the [standard-schema.dev](https://standard-schema.dev) spec which means you can use any Standard Schema\n * compliant validator (Zod, Valibot, ArkType, etc.). This ensures the tool function args and output types are correctly\n * inferred from the provided schemas.\n * @example\n * ```typescript\n * import { z } from \"zod/v4\";\n *\n * const myTool = defineTamboTool({\n * // ...\n * });\n * ```\n * @param tool The tool definition to register\n * @returns The registered tool definition\n */\nexport const defineTool: DefineToolFn = (tool: any) => {\n if (\"toolSchema\" in tool) {\n return tool;\n }\n tool.inputSchema ??= { type: \"object\", properties: {}, required: [] };\n tool.outputSchema ??= { type: \"object\", properties: {}, required: [] };\n return tool;\n};\n"]}
@@ -1,4 +1,4 @@
1
- import { REGISTRY_SERVER_KEY, ServerType } from "../mcp/mcp-constants.js";
1
+ import { REGISTRY_SERVER_KEY, ServerType } from "@tambo-ai/client";
2
2
  /**
3
3
  * Type guard for narrowing McpServer to a connected server.
4
4
  * A connected server has a non-null client.
@@ -1 +1 @@
1
- {"version":3,"file":"resource-content-resolver.js","sourceRoot":"","sources":["../../src/util/resource-content-resolver.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ReadResourceResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport { REGISTRY_SERVER_KEY, ServerType } from \"../mcp/mcp-constants\";\nimport type { ConnectedMcpServer, McpServer } from \"../mcp/tambo-mcp-provider\";\nimport type { ResourceSource } from \"../model/resource-info\";\n\n/**\n * Type guard for narrowing McpServer to a connected server.\n * A connected server has a non-null client.\n * @param server - The MCP server to check\n * @returns True if the server is connected, false otherwise\n */\nfunction isConnectedMcpServer(server: McpServer): server is ConnectedMcpServer {\n return \"client\" in server && server.client != null;\n}\n\n/**\n * Resolves content for client-side resources (MCP and registry).\n * Server-side (internal Tambo) resources are skipped - the backend can resolve them.\n * @param resourceUris - Prefixed URIs (e.g., \"linear:file://foo\", \"registry:file://bar\", \"tambo-abc:test://resource\")\n * @param mcpServers - Active MCP servers including virtual registry server\n * @param resourceSource - Registry resource source (listResources/getResource)\n * @returns Map of prefixedUri -> ReadResourceResult for resolved resources.\n * Resources that failed to fetch or are internal server resources won't be in the map.\n */\nexport async function resolveResourceContents(\n resourceUris: string[],\n mcpServers: McpServer[],\n resourceSource: ResourceSource | undefined,\n): Promise<Map<string, ReadResourceResult>> {\n const results = new Map<string, ReadResourceResult>();\n\n const fetchPromises = resourceUris.map(async (prefixedUri) => {\n // Parse serverKey and original URI\n // Format: serverKey:originalUri (e.g., \"linear:file://foo\", \"registry:docs://readme\")\n const colonIndex = prefixedUri.indexOf(\":\");\n if (colonIndex === -1) return;\n\n const serverKey = prefixedUri.slice(0, colonIndex);\n const originalUri = prefixedUri.slice(colonIndex + 1);\n\n try {\n // Handle registry resources directly - no server lookup needed\n // Registry resources are local to the browser and resolved via resourceSource\n if (serverKey === REGISTRY_SERVER_KEY) {\n if (!resourceSource) {\n console.warn(\n `No resource source available to resolve registry resource: ${prefixedUri}`,\n );\n return;\n }\n const registryContent = await resourceSource.getResource(originalUri);\n if (registryContent) {\n results.set(prefixedUri, registryContent);\n }\n return;\n }\n\n // For non-registry resources, find the server by serverKey\n const server = mcpServers.find((s) => s.serverKey === serverKey);\n if (!server) {\n console.warn(`No server found for resource: ${prefixedUri}`);\n return;\n }\n\n switch (server.serverType) {\n case ServerType.TAMBO_INTERNAL:\n // Skip internal server resources - backend can resolve these\n return;\n\n case ServerType.TAMBO_REGISTRY:\n // Should not reach here since we handle registry above, but keep for safety\n return;\n\n case ServerType.BROWSER_SIDE: {\n // Client-side MCP resource\n if (!isConnectedMcpServer(server)) {\n console.warn(\n `MCP server not connected for resource: ${prefixedUri}`,\n );\n return;\n }\n const mcpContent = (await server.client.client.readResource({\n uri: originalUri,\n })) as ReadResourceResult | null;\n if (mcpContent) {\n results.set(prefixedUri, mcpContent);\n }\n return;\n }\n }\n } catch (error) {\n // Graceful fallback - log warning and continue without content\n console.warn(\n `Failed to fetch resource content for ${prefixedUri}:`,\n error,\n );\n }\n });\n\n await Promise.all(fetchPromises);\n return results;\n}\n\n/**\n * Extracts resource URIs from text using the `@serverKey:uri` pattern.\n * @param text - Text potentially containing resource references\n * @returns Array of prefixed resource URIs (e.g., [\"linear:file://foo\", \"registry:file://bar\"])\n */\nexport function extractResourceUris(text: string): string[] {\n const pattern = /@([a-zA-Z0-9-]+):(\\S+)/g;\n const matches = Array.from(text.matchAll(pattern));\n return matches.map(([, serverKey, uri]) => `${serverKey}:${uri}`);\n}\n"]}
1
+ {"version":3,"file":"resource-content-resolver.js","sourceRoot":"","sources":["../../src/util/resource-content-resolver.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ReadResourceResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport { REGISTRY_SERVER_KEY, ServerType } from \"@tambo-ai/client\";\nimport type { ConnectedMcpServer, McpServer } from \"../mcp/tambo-mcp-provider\";\nimport type { ResourceSource } from \"../model/resource-info\";\n\n/**\n * Type guard for narrowing McpServer to a connected server.\n * A connected server has a non-null client.\n * @param server - The MCP server to check\n * @returns True if the server is connected, false otherwise\n */\nfunction isConnectedMcpServer(server: McpServer): server is ConnectedMcpServer {\n return \"client\" in server && server.client != null;\n}\n\n/**\n * Resolves content for client-side resources (MCP and registry).\n * Server-side (internal Tambo) resources are skipped - the backend can resolve them.\n * @param resourceUris - Prefixed URIs (e.g., \"linear:file://foo\", \"registry:file://bar\", \"tambo-abc:test://resource\")\n * @param mcpServers - Active MCP servers including virtual registry server\n * @param resourceSource - Registry resource source (listResources/getResource)\n * @returns Map of prefixedUri -> ReadResourceResult for resolved resources.\n * Resources that failed to fetch or are internal server resources won't be in the map.\n */\nexport async function resolveResourceContents(\n resourceUris: string[],\n mcpServers: McpServer[],\n resourceSource: ResourceSource | undefined,\n): Promise<Map<string, ReadResourceResult>> {\n const results = new Map<string, ReadResourceResult>();\n\n const fetchPromises = resourceUris.map(async (prefixedUri) => {\n // Parse serverKey and original URI\n // Format: serverKey:originalUri (e.g., \"linear:file://foo\", \"registry:docs://readme\")\n const colonIndex = prefixedUri.indexOf(\":\");\n if (colonIndex === -1) return;\n\n const serverKey = prefixedUri.slice(0, colonIndex);\n const originalUri = prefixedUri.slice(colonIndex + 1);\n\n try {\n // Handle registry resources directly - no server lookup needed\n // Registry resources are local to the browser and resolved via resourceSource\n if (serverKey === REGISTRY_SERVER_KEY) {\n if (!resourceSource) {\n console.warn(\n `No resource source available to resolve registry resource: ${prefixedUri}`,\n );\n return;\n }\n const registryContent = await resourceSource.getResource(originalUri);\n if (registryContent) {\n results.set(prefixedUri, registryContent);\n }\n return;\n }\n\n // For non-registry resources, find the server by serverKey\n const server = mcpServers.find((s) => s.serverKey === serverKey);\n if (!server) {\n console.warn(`No server found for resource: ${prefixedUri}`);\n return;\n }\n\n switch (server.serverType) {\n case ServerType.TAMBO_INTERNAL:\n // Skip internal server resources - backend can resolve these\n return;\n\n case ServerType.TAMBO_REGISTRY:\n // Should not reach here since we handle registry above, but keep for safety\n return;\n\n case ServerType.BROWSER_SIDE: {\n // Client-side MCP resource\n if (!isConnectedMcpServer(server)) {\n console.warn(\n `MCP server not connected for resource: ${prefixedUri}`,\n );\n return;\n }\n const mcpContent = (await server.client.client.readResource({\n uri: originalUri,\n })) as ReadResourceResult | null;\n if (mcpContent) {\n results.set(prefixedUri, mcpContent);\n }\n return;\n }\n }\n } catch (error) {\n // Graceful fallback - log warning and continue without content\n console.warn(\n `Failed to fetch resource content for ${prefixedUri}:`,\n error,\n );\n }\n });\n\n await Promise.all(fetchPromises);\n return results;\n}\n\n/**\n * Extracts resource URIs from text using the `@serverKey:uri` pattern.\n * @param text - Text potentially containing resource references\n * @returns Array of prefixed resource URIs (e.g., [\"linear:file://foo\", \"registry:file://bar\"])\n */\nexport function extractResourceUris(text: string): string[] {\n const pattern = /@([a-zA-Z0-9-]+):(\\S+)/g;\n const matches = Array.from(text.matchAll(pattern));\n return matches.map(([, serverKey, uri]) => `${serverKey}:${uri}`);\n}\n"]}
@@ -1,5 +1,5 @@
1
- import { ServerType } from "../mcp/mcp-constants.js";
2
- import { MCPTransport } from "../mcp/mcp-client.js";
1
+ import { ServerType } from "@tambo-ai/client";
2
+ import { MCPTransport } from "@tambo-ai/client";
3
3
  import { resolveResourceContents, extractResourceUris, } from "./resource-content-resolver.js";
4
4
  describe("extractResourceUris", () => {
5
5
  it("should extract a single resource URI", () => {
@@ -1 +1 @@
1
- {"version":3,"file":"resource-content-resolver.test.js","sourceRoot":"","sources":["../../src/util/resource-content-resolver.test.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ReadResourceResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport { ServerType } from \"../mcp/mcp-constants\";\nimport type { McpServer } from \"../mcp/tambo-mcp-provider\";\nimport type { ResourceSource } from \"../model/resource-info\";\nimport { MCPTransport } from \"../mcp/mcp-client\";\n\nimport {\n resolveResourceContents,\n extractResourceUris,\n} from \"./resource-content-resolver\";\n\ndescribe(\"extractResourceUris\", () => {\n it(\"should extract a single resource URI\", () => {\n const text = \"Check @registry:file:///path/to/doc.txt\";\n const result = extractResourceUris(text);\n expect(result).toEqual([\"registry:file:///path/to/doc.txt\"]);\n });\n\n it(\"should extract multiple resource URIs\", () => {\n const text =\n \"Check @registry:file:///doc1.txt and @server-a:file:///doc2.txt\";\n const result = extractResourceUris(text);\n expect(result).toEqual([\n \"registry:file:///doc1.txt\",\n \"server-a:file:///doc2.txt\",\n ]);\n });\n\n it(\"should extract resource URIs with internal server prefix\", () => {\n const text = \"Check @tambo-abc123:tambo:test://resource/1\";\n const result = extractResourceUris(text);\n expect(result).toEqual([\"tambo-abc123:tambo:test://resource/1\"]);\n });\n\n it(\"should extract resource URIs with hyphens in server key\", () => {\n const text = \"@my-mcp-server:file:///path/file.txt\";\n const result = extractResourceUris(text);\n expect(result).toEqual([\"my-mcp-server:file:///path/file.txt\"]);\n });\n\n it(\"should return empty array for text without resource references\", () => {\n const text = \"Just some regular text without @mentions\";\n const result = extractResourceUris(text);\n expect(result).toEqual([]);\n });\n\n it(\"should not extract malformed references without colon\", () => {\n const text = \"@server-without-colon is not a resource\";\n const result = extractResourceUris(text);\n expect(result).toEqual([]);\n });\n\n it(\"should handle URIs with multiple colons\", () => {\n const text = \"@server:http://example.com:8080/path\";\n const result = extractResourceUris(text);\n expect(result).toEqual([\"server:http://example.com:8080/path\"]);\n });\n});\n\ndescribe(\"resolveResourceContents\", () => {\n const createMockConnectedServer = (\n serverKey: string,\n readResource: jest.Mock,\n serverType: ServerType = ServerType.BROWSER_SIDE,\n ): McpServer =>\n ({\n key: `mcp-${serverKey}`,\n serverKey,\n url: `https://${serverKey}.example.com`,\n name: `MCP Server ${serverKey}`,\n transport: MCPTransport.HTTP,\n serverType,\n client: {\n client: {\n readResource,\n listResources: jest.fn().mockResolvedValue({ resources: [] }),\n listTools: jest.fn().mockResolvedValue({ tools: [] }),\n listPrompts: jest.fn().mockResolvedValue({ prompts: [] }),\n getPrompt: jest.fn().mockResolvedValue(null),\n callTool: jest.fn().mockResolvedValue(null),\n },\n close: jest.fn().mockResolvedValue(undefined),\n } as unknown as McpServer[\"client\"],\n }) as McpServer;\n\n const createMockInternalServer = (serverKey: string): McpServer =>\n ({\n key: serverKey,\n serverKey,\n url: \"https://api.tambo.co/mcp\",\n name: \"__tambo_internal_mcp_server__\",\n transport: MCPTransport.HTTP,\n serverType: ServerType.TAMBO_INTERNAL,\n connectionError: undefined, // No client for internal servers\n }) as unknown as McpServer;\n\n const createMockResourceSource = (\n getResource: jest.Mock,\n ): ResourceSource => ({\n listResources: jest.fn().mockResolvedValue([]),\n getResource,\n });\n\n it(\"should resolve registry resources via resourceSource\", async () => {\n const mockGetResource = jest.fn().mockResolvedValue({\n contents: [\n {\n uri: \"file:///local/doc.txt\",\n mimeType: \"text/plain\",\n text: \"Registry document content\",\n },\n ],\n } satisfies ReadResourceResult);\n\n const resourceSource = createMockResourceSource(mockGetResource);\n\n const result = await resolveResourceContents(\n [\"registry:file:///local/doc.txt\"],\n [], // Registry resources don't need a server - they're handled directly\n resourceSource,\n );\n\n expect(mockGetResource).toHaveBeenCalledWith(\"file:///local/doc.txt\");\n expect(result.size).toBe(1);\n expect(result.get(\"registry:file:///local/doc.txt\")).toEqual({\n contents: [\n {\n uri: \"file:///local/doc.txt\",\n mimeType: \"text/plain\",\n text: \"Registry document content\",\n },\n ],\n });\n });\n\n it(\"should resolve client-side MCP resources via mcpServer\", async () => {\n const mockReadResource = jest.fn().mockResolvedValue({\n contents: [\n {\n uri: \"file:///mcp/file.txt\",\n mimeType: \"text/plain\",\n text: \"MCP server content\",\n },\n ],\n } satisfies ReadResourceResult);\n\n const mcpServer = createMockConnectedServer(\"linear\", mockReadResource);\n\n const result = await resolveResourceContents(\n [\"linear:file:///mcp/file.txt\"],\n [mcpServer],\n undefined,\n );\n\n expect(mockReadResource).toHaveBeenCalledWith({\n uri: \"file:///mcp/file.txt\",\n });\n expect(result.size).toBe(1);\n expect(result.get(\"linear:file:///mcp/file.txt\")).toEqual({\n contents: [\n {\n uri: \"file:///mcp/file.txt\",\n mimeType: \"text/plain\",\n text: \"MCP server content\",\n },\n ],\n });\n });\n\n it(\"should skip internal server resources (serverType: TAMBO_INTERNAL)\", async () => {\n const mockGetResource = jest.fn();\n const resourceSource = createMockResourceSource(mockGetResource);\n const internalServer = createMockInternalServer(\"tambo-abc123\");\n\n const result = await resolveResourceContents(\n [\"tambo-abc123:tambo:test://resource/1\"],\n [internalServer],\n resourceSource,\n );\n\n // Should not call getResource for internal server resources\n expect(mockGetResource).not.toHaveBeenCalled();\n // Should return empty map since internal resources are skipped\n expect(result.size).toBe(0);\n });\n\n it(\"should resolve multiple resources in parallel\", async () => {\n const mockGetResource = jest.fn().mockResolvedValue({\n contents: [{ uri: \"file:///doc.txt\", text: \"registry content\" }],\n });\n const mockReadResource = jest.fn().mockResolvedValue({\n contents: [{ uri: \"file:///mcp.txt\", text: \"mcp content\" }],\n });\n\n const resourceSource = createMockResourceSource(mockGetResource);\n const mcpServer = createMockConnectedServer(\"mcp-server\", mockReadResource);\n\n const result = await resolveResourceContents(\n [\"registry:file:///doc.txt\", \"mcp-server:file:///mcp.txt\"],\n [mcpServer], // Only MCP server needed - registry handled directly\n resourceSource,\n );\n\n expect(result.size).toBe(2);\n expect(result.has(\"registry:file:///doc.txt\")).toBe(true);\n expect(result.has(\"mcp-server:file:///mcp.txt\")).toBe(true);\n });\n\n it(\"should handle mixed internal and client-side resources\", async () => {\n const mockGetResource = jest.fn().mockResolvedValue({\n contents: [{ uri: \"file:///doc.txt\", text: \"registry content\" }],\n });\n const resourceSource = createMockResourceSource(mockGetResource);\n const internalServer = createMockInternalServer(\"tambo-abc123\");\n\n const result = await resolveResourceContents(\n [\n \"registry:file:///doc.txt\", // client-side registry\n \"tambo-abc123:tambo:test://resource/1\", // internal - should skip\n ],\n [internalServer], // Only internal server needed - registry handled directly\n resourceSource,\n );\n\n // Only the registry resource should be resolved\n expect(mockGetResource).toHaveBeenCalledTimes(1);\n expect(result.size).toBe(1);\n expect(result.has(\"registry:file:///doc.txt\")).toBe(true);\n expect(result.has(\"tambo-abc123:tambo:test://resource/1\")).toBe(false);\n });\n\n it(\"should gracefully handle registry resource fetch failure\", async () => {\n const consoleSpy = jest.spyOn(console, \"warn\").mockImplementation();\n const mockGetResource = jest\n .fn()\n .mockRejectedValue(new Error(\"Resource not found\"));\n const resourceSource = createMockResourceSource(mockGetResource);\n\n const result = await resolveResourceContents(\n [\"registry:file:///missing.txt\"],\n [], // Registry resources don't need a server\n resourceSource,\n );\n\n expect(consoleSpy).toHaveBeenCalledWith(\n \"Failed to fetch resource content for registry:file:///missing.txt:\",\n expect.any(Error),\n );\n expect(result.size).toBe(0);\n\n consoleSpy.mockRestore();\n });\n\n it(\"should gracefully handle MCP resource fetch failure\", async () => {\n const consoleSpy = jest.spyOn(console, \"warn\").mockImplementation();\n const mockReadResource = jest\n .fn()\n .mockRejectedValue(new Error(\"MCP server error\"));\n const mcpServer = createMockConnectedServer(\"linear\", mockReadResource);\n\n const result = await resolveResourceContents(\n [\"linear:file:///missing.txt\"],\n [mcpServer],\n undefined,\n );\n\n expect(consoleSpy).toHaveBeenCalledWith(\n \"Failed to fetch resource content for linear:file:///missing.txt:\",\n expect.any(Error),\n );\n expect(result.size).toBe(0);\n\n consoleSpy.mockRestore();\n });\n\n it(\"should warn when no resourceSource available for registry resource\", async () => {\n const consoleSpy = jest.spyOn(console, \"warn\").mockImplementation();\n\n const result = await resolveResourceContents(\n [\"registry:file:///doc.txt\"],\n [], // Registry resources don't need a server\n undefined, // no resourceSource\n );\n\n expect(consoleSpy).toHaveBeenCalledWith(\n \"No resource source available to resolve registry resource: registry:file:///doc.txt\",\n );\n expect(result.size).toBe(0);\n\n consoleSpy.mockRestore();\n });\n\n it(\"should warn when no server found for resource\", async () => {\n const consoleSpy = jest.spyOn(console, \"warn\").mockImplementation();\n\n const result = await resolveResourceContents(\n [\"unknown-server:file:///doc.txt\"],\n [], // no servers\n undefined,\n );\n\n expect(consoleSpy).toHaveBeenCalledWith(\n \"No server found for resource: unknown-server:file:///doc.txt\",\n );\n expect(result.size).toBe(0);\n\n consoleSpy.mockRestore();\n });\n\n it(\"should handle resource content with blob data\", async () => {\n const mockGetResource = jest.fn().mockResolvedValue({\n contents: [\n {\n uri: \"file:///image.png\",\n mimeType: \"image/png\",\n blob: \"base64encodeddata\",\n },\n ],\n } satisfies ReadResourceResult);\n\n const resourceSource = createMockResourceSource(mockGetResource);\n\n const result = await resolveResourceContents(\n [\"registry:file:///image.png\"],\n [], // Registry resources don't need a server\n resourceSource,\n );\n\n expect(result.get(\"registry:file:///image.png\")).toEqual({\n contents: [\n {\n uri: \"file:///image.png\",\n mimeType: \"image/png\",\n blob: \"base64encodeddata\",\n },\n ],\n });\n });\n\n it(\"should handle URIs with no colon (invalid format)\", async () => {\n const result = await resolveResourceContents(\n [\"invalid-uri-no-colon\"],\n [],\n undefined,\n );\n\n expect(result.size).toBe(0);\n });\n\n it(\"should handle null content from getResource\", async () => {\n const mockGetResource = jest.fn().mockResolvedValue(null);\n const resourceSource = createMockResourceSource(mockGetResource);\n\n const result = await resolveResourceContents(\n [\"registry:file:///doc.txt\"],\n [], // Registry resources don't need a server\n resourceSource,\n );\n\n expect(mockGetResource).toHaveBeenCalled();\n expect(result.size).toBe(0);\n });\n\n it(\"should handle null content from readResource\", async () => {\n const mockReadResource = jest.fn().mockResolvedValue(null);\n const mcpServer = createMockConnectedServer(\"linear\", mockReadResource);\n\n const result = await resolveResourceContents(\n [\"linear:file:///doc.txt\"],\n [mcpServer],\n undefined,\n );\n\n expect(mockReadResource).toHaveBeenCalled();\n expect(result.size).toBe(0);\n });\n});\n"]}
1
+ {"version":3,"file":"resource-content-resolver.test.js","sourceRoot":"","sources":["../../src/util/resource-content-resolver.test.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ReadResourceResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport { ServerType } from \"@tambo-ai/client\";\nimport type { McpServer } from \"../mcp/tambo-mcp-provider\";\nimport type { ResourceSource } from \"../model/resource-info\";\nimport { MCPTransport } from \"@tambo-ai/client\";\n\nimport {\n resolveResourceContents,\n extractResourceUris,\n} from \"./resource-content-resolver\";\n\ndescribe(\"extractResourceUris\", () => {\n it(\"should extract a single resource URI\", () => {\n const text = \"Check @registry:file:///path/to/doc.txt\";\n const result = extractResourceUris(text);\n expect(result).toEqual([\"registry:file:///path/to/doc.txt\"]);\n });\n\n it(\"should extract multiple resource URIs\", () => {\n const text =\n \"Check @registry:file:///doc1.txt and @server-a:file:///doc2.txt\";\n const result = extractResourceUris(text);\n expect(result).toEqual([\n \"registry:file:///doc1.txt\",\n \"server-a:file:///doc2.txt\",\n ]);\n });\n\n it(\"should extract resource URIs with internal server prefix\", () => {\n const text = \"Check @tambo-abc123:tambo:test://resource/1\";\n const result = extractResourceUris(text);\n expect(result).toEqual([\"tambo-abc123:tambo:test://resource/1\"]);\n });\n\n it(\"should extract resource URIs with hyphens in server key\", () => {\n const text = \"@my-mcp-server:file:///path/file.txt\";\n const result = extractResourceUris(text);\n expect(result).toEqual([\"my-mcp-server:file:///path/file.txt\"]);\n });\n\n it(\"should return empty array for text without resource references\", () => {\n const text = \"Just some regular text without @mentions\";\n const result = extractResourceUris(text);\n expect(result).toEqual([]);\n });\n\n it(\"should not extract malformed references without colon\", () => {\n const text = \"@server-without-colon is not a resource\";\n const result = extractResourceUris(text);\n expect(result).toEqual([]);\n });\n\n it(\"should handle URIs with multiple colons\", () => {\n const text = \"@server:http://example.com:8080/path\";\n const result = extractResourceUris(text);\n expect(result).toEqual([\"server:http://example.com:8080/path\"]);\n });\n});\n\ndescribe(\"resolveResourceContents\", () => {\n const createMockConnectedServer = (\n serverKey: string,\n readResource: jest.Mock,\n serverType: ServerType = ServerType.BROWSER_SIDE,\n ): McpServer =>\n ({\n key: `mcp-${serverKey}`,\n serverKey,\n url: `https://${serverKey}.example.com`,\n name: `MCP Server ${serverKey}`,\n transport: MCPTransport.HTTP,\n serverType,\n client: {\n client: {\n readResource,\n listResources: jest.fn().mockResolvedValue({ resources: [] }),\n listTools: jest.fn().mockResolvedValue({ tools: [] }),\n listPrompts: jest.fn().mockResolvedValue({ prompts: [] }),\n getPrompt: jest.fn().mockResolvedValue(null),\n callTool: jest.fn().mockResolvedValue(null),\n },\n close: jest.fn().mockResolvedValue(undefined),\n } as unknown as McpServer[\"client\"],\n }) as McpServer;\n\n const createMockInternalServer = (serverKey: string): McpServer =>\n ({\n key: serverKey,\n serverKey,\n url: \"https://api.tambo.co/mcp\",\n name: \"__tambo_internal_mcp_server__\",\n transport: MCPTransport.HTTP,\n serverType: ServerType.TAMBO_INTERNAL,\n connectionError: undefined, // No client for internal servers\n }) as unknown as McpServer;\n\n const createMockResourceSource = (\n getResource: jest.Mock,\n ): ResourceSource => ({\n listResources: jest.fn().mockResolvedValue([]),\n getResource,\n });\n\n it(\"should resolve registry resources via resourceSource\", async () => {\n const mockGetResource = jest.fn().mockResolvedValue({\n contents: [\n {\n uri: \"file:///local/doc.txt\",\n mimeType: \"text/plain\",\n text: \"Registry document content\",\n },\n ],\n } satisfies ReadResourceResult);\n\n const resourceSource = createMockResourceSource(mockGetResource);\n\n const result = await resolveResourceContents(\n [\"registry:file:///local/doc.txt\"],\n [], // Registry resources don't need a server - they're handled directly\n resourceSource,\n );\n\n expect(mockGetResource).toHaveBeenCalledWith(\"file:///local/doc.txt\");\n expect(result.size).toBe(1);\n expect(result.get(\"registry:file:///local/doc.txt\")).toEqual({\n contents: [\n {\n uri: \"file:///local/doc.txt\",\n mimeType: \"text/plain\",\n text: \"Registry document content\",\n },\n ],\n });\n });\n\n it(\"should resolve client-side MCP resources via mcpServer\", async () => {\n const mockReadResource = jest.fn().mockResolvedValue({\n contents: [\n {\n uri: \"file:///mcp/file.txt\",\n mimeType: \"text/plain\",\n text: \"MCP server content\",\n },\n ],\n } satisfies ReadResourceResult);\n\n const mcpServer = createMockConnectedServer(\"linear\", mockReadResource);\n\n const result = await resolveResourceContents(\n [\"linear:file:///mcp/file.txt\"],\n [mcpServer],\n undefined,\n );\n\n expect(mockReadResource).toHaveBeenCalledWith({\n uri: \"file:///mcp/file.txt\",\n });\n expect(result.size).toBe(1);\n expect(result.get(\"linear:file:///mcp/file.txt\")).toEqual({\n contents: [\n {\n uri: \"file:///mcp/file.txt\",\n mimeType: \"text/plain\",\n text: \"MCP server content\",\n },\n ],\n });\n });\n\n it(\"should skip internal server resources (serverType: TAMBO_INTERNAL)\", async () => {\n const mockGetResource = jest.fn();\n const resourceSource = createMockResourceSource(mockGetResource);\n const internalServer = createMockInternalServer(\"tambo-abc123\");\n\n const result = await resolveResourceContents(\n [\"tambo-abc123:tambo:test://resource/1\"],\n [internalServer],\n resourceSource,\n );\n\n // Should not call getResource for internal server resources\n expect(mockGetResource).not.toHaveBeenCalled();\n // Should return empty map since internal resources are skipped\n expect(result.size).toBe(0);\n });\n\n it(\"should resolve multiple resources in parallel\", async () => {\n const mockGetResource = jest.fn().mockResolvedValue({\n contents: [{ uri: \"file:///doc.txt\", text: \"registry content\" }],\n });\n const mockReadResource = jest.fn().mockResolvedValue({\n contents: [{ uri: \"file:///mcp.txt\", text: \"mcp content\" }],\n });\n\n const resourceSource = createMockResourceSource(mockGetResource);\n const mcpServer = createMockConnectedServer(\"mcp-server\", mockReadResource);\n\n const result = await resolveResourceContents(\n [\"registry:file:///doc.txt\", \"mcp-server:file:///mcp.txt\"],\n [mcpServer], // Only MCP server needed - registry handled directly\n resourceSource,\n );\n\n expect(result.size).toBe(2);\n expect(result.has(\"registry:file:///doc.txt\")).toBe(true);\n expect(result.has(\"mcp-server:file:///mcp.txt\")).toBe(true);\n });\n\n it(\"should handle mixed internal and client-side resources\", async () => {\n const mockGetResource = jest.fn().mockResolvedValue({\n contents: [{ uri: \"file:///doc.txt\", text: \"registry content\" }],\n });\n const resourceSource = createMockResourceSource(mockGetResource);\n const internalServer = createMockInternalServer(\"tambo-abc123\");\n\n const result = await resolveResourceContents(\n [\n \"registry:file:///doc.txt\", // client-side registry\n \"tambo-abc123:tambo:test://resource/1\", // internal - should skip\n ],\n [internalServer], // Only internal server needed - registry handled directly\n resourceSource,\n );\n\n // Only the registry resource should be resolved\n expect(mockGetResource).toHaveBeenCalledTimes(1);\n expect(result.size).toBe(1);\n expect(result.has(\"registry:file:///doc.txt\")).toBe(true);\n expect(result.has(\"tambo-abc123:tambo:test://resource/1\")).toBe(false);\n });\n\n it(\"should gracefully handle registry resource fetch failure\", async () => {\n const consoleSpy = jest.spyOn(console, \"warn\").mockImplementation();\n const mockGetResource = jest\n .fn()\n .mockRejectedValue(new Error(\"Resource not found\"));\n const resourceSource = createMockResourceSource(mockGetResource);\n\n const result = await resolveResourceContents(\n [\"registry:file:///missing.txt\"],\n [], // Registry resources don't need a server\n resourceSource,\n );\n\n expect(consoleSpy).toHaveBeenCalledWith(\n \"Failed to fetch resource content for registry:file:///missing.txt:\",\n expect.any(Error),\n );\n expect(result.size).toBe(0);\n\n consoleSpy.mockRestore();\n });\n\n it(\"should gracefully handle MCP resource fetch failure\", async () => {\n const consoleSpy = jest.spyOn(console, \"warn\").mockImplementation();\n const mockReadResource = jest\n .fn()\n .mockRejectedValue(new Error(\"MCP server error\"));\n const mcpServer = createMockConnectedServer(\"linear\", mockReadResource);\n\n const result = await resolveResourceContents(\n [\"linear:file:///missing.txt\"],\n [mcpServer],\n undefined,\n );\n\n expect(consoleSpy).toHaveBeenCalledWith(\n \"Failed to fetch resource content for linear:file:///missing.txt:\",\n expect.any(Error),\n );\n expect(result.size).toBe(0);\n\n consoleSpy.mockRestore();\n });\n\n it(\"should warn when no resourceSource available for registry resource\", async () => {\n const consoleSpy = jest.spyOn(console, \"warn\").mockImplementation();\n\n const result = await resolveResourceContents(\n [\"registry:file:///doc.txt\"],\n [], // Registry resources don't need a server\n undefined, // no resourceSource\n );\n\n expect(consoleSpy).toHaveBeenCalledWith(\n \"No resource source available to resolve registry resource: registry:file:///doc.txt\",\n );\n expect(result.size).toBe(0);\n\n consoleSpy.mockRestore();\n });\n\n it(\"should warn when no server found for resource\", async () => {\n const consoleSpy = jest.spyOn(console, \"warn\").mockImplementation();\n\n const result = await resolveResourceContents(\n [\"unknown-server:file:///doc.txt\"],\n [], // no servers\n undefined,\n );\n\n expect(consoleSpy).toHaveBeenCalledWith(\n \"No server found for resource: unknown-server:file:///doc.txt\",\n );\n expect(result.size).toBe(0);\n\n consoleSpy.mockRestore();\n });\n\n it(\"should handle resource content with blob data\", async () => {\n const mockGetResource = jest.fn().mockResolvedValue({\n contents: [\n {\n uri: \"file:///image.png\",\n mimeType: \"image/png\",\n blob: \"base64encodeddata\",\n },\n ],\n } satisfies ReadResourceResult);\n\n const resourceSource = createMockResourceSource(mockGetResource);\n\n const result = await resolveResourceContents(\n [\"registry:file:///image.png\"],\n [], // Registry resources don't need a server\n resourceSource,\n );\n\n expect(result.get(\"registry:file:///image.png\")).toEqual({\n contents: [\n {\n uri: \"file:///image.png\",\n mimeType: \"image/png\",\n blob: \"base64encodeddata\",\n },\n ],\n });\n });\n\n it(\"should handle URIs with no colon (invalid format)\", async () => {\n const result = await resolveResourceContents(\n [\"invalid-uri-no-colon\"],\n [],\n undefined,\n );\n\n expect(result.size).toBe(0);\n });\n\n it(\"should handle null content from getResource\", async () => {\n const mockGetResource = jest.fn().mockResolvedValue(null);\n const resourceSource = createMockResourceSource(mockGetResource);\n\n const result = await resolveResourceContents(\n [\"registry:file:///doc.txt\"],\n [], // Registry resources don't need a server\n resourceSource,\n );\n\n expect(mockGetResource).toHaveBeenCalled();\n expect(result.size).toBe(0);\n });\n\n it(\"should handle null content from readResource\", async () => {\n const mockReadResource = jest.fn().mockResolvedValue(null);\n const mcpServer = createMockConnectedServer(\"linear\", mockReadResource);\n\n const result = await resolveResourceContents(\n [\"linear:file:///doc.txt\"],\n [mcpServer],\n undefined,\n );\n\n expect(mockReadResource).toHaveBeenCalled();\n expect(result.size).toBe(0);\n });\n});\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=tool-caller.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-caller.test.d.ts","sourceRoot":"","sources":["../../src/util/tool-caller.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,69 @@
1
+ import { handleToolCall } from "./tool-caller.js";
2
+ function makeRegistry(toolName, impl) {
3
+ return {
4
+ [toolName]: {
5
+ name: toolName,
6
+ description: `Test tool ${toolName}`,
7
+ tool: impl,
8
+ inputSchema: { type: "object", properties: {} },
9
+ outputSchema: { type: "object" },
10
+ },
11
+ };
12
+ }
13
+ describe("handleToolCall", () => {
14
+ it("calls the registered tool with reconstructed parameters", async () => {
15
+ const registry = makeRegistry("myTool", (input) => `got ${input.name}`);
16
+ const request = {
17
+ toolName: "myTool",
18
+ parameters: [{ parameterName: "name", parameterValue: "Alice" }],
19
+ };
20
+ const { result, error } = await handleToolCall(request, registry);
21
+ expect(result).toBe("got Alice");
22
+ expect(error).toBeUndefined();
23
+ });
24
+ it("throws when toolName is missing", async () => {
25
+ await expect(handleToolCall({ toolName: "", parameters: [] }, {})).rejects.toThrow("Tool name is required");
26
+ });
27
+ it("returns error message when tool is not found and no fallback", async () => {
28
+ const request = {
29
+ toolName: "missing",
30
+ parameters: [],
31
+ };
32
+ const { result, error } = await handleToolCall(request, {});
33
+ expect(error).toBe("Tool missing not found in registry");
34
+ expect(result).toContain("missing");
35
+ });
36
+ it("calls onCallUnregisteredTool fallback when tool not in registry", async () => {
37
+ const fallback = jest.fn().mockResolvedValue("fallback result");
38
+ const request = {
39
+ toolName: "unregistered",
40
+ parameters: [{ parameterName: "x", parameterValue: "1" }],
41
+ };
42
+ const { result, error } = await handleToolCall(request, {}, fallback);
43
+ expect(result).toBe("fallback result");
44
+ expect(error).toBeUndefined();
45
+ expect(fallback).toHaveBeenCalledWith("unregistered", request.parameters);
46
+ });
47
+ it("returns error info when tool execution throws", async () => {
48
+ const registry = makeRegistry("boom", () => {
49
+ throw new Error("kaboom");
50
+ });
51
+ const request = {
52
+ toolName: "boom",
53
+ parameters: [],
54
+ };
55
+ const { result, error } = await handleToolCall(request, registry);
56
+ expect(error).toBe("kaboom");
57
+ expect(result).toContain("kaboom");
58
+ });
59
+ it("handles null parameters", async () => {
60
+ const registry = makeRegistry("noArgs", () => "ok");
61
+ const request = {
62
+ toolName: "noArgs",
63
+ parameters: null,
64
+ };
65
+ const { result } = await handleToolCall(request, registry);
66
+ expect(result).toBe("ok");
67
+ });
68
+ });
69
+ //# sourceMappingURL=tool-caller.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-caller.test.js","sourceRoot":"","sources":["../../src/util/tool-caller.test.ts"],"names":[],"mappings":"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","sourcesContent":["import type TamboAI from \"@tambo-ai/typescript-sdk\";\nimport type { TamboToolRegistry } from \"../model/component-metadata\";\nimport { handleToolCall } from \"./tool-caller\";\n\nfunction makeRegistry(\n toolName: string,\n impl: (input: Record<string, unknown>) => unknown,\n): TamboToolRegistry {\n return {\n [toolName]: {\n name: toolName,\n description: `Test tool ${toolName}`,\n tool: impl,\n inputSchema: { type: \"object\", properties: {} },\n outputSchema: { type: \"object\" },\n },\n };\n}\n\ndescribe(\"handleToolCall\", () => {\n it(\"calls the registered tool with reconstructed parameters\", async () => {\n const registry = makeRegistry(\"myTool\", (input) => `got ${input.name}`);\n const request: TamboAI.ToolCallRequest = {\n toolName: \"myTool\",\n parameters: [{ parameterName: \"name\", parameterValue: \"Alice\" }],\n };\n\n const { result, error } = await handleToolCall(request, registry);\n expect(result).toBe(\"got Alice\");\n expect(error).toBeUndefined();\n });\n\n it(\"throws when toolName is missing\", async () => {\n await expect(\n handleToolCall(\n { toolName: \"\", parameters: [] } as TamboAI.ToolCallRequest,\n {},\n ),\n ).rejects.toThrow(\"Tool name is required\");\n });\n\n it(\"returns error message when tool is not found and no fallback\", async () => {\n const request: TamboAI.ToolCallRequest = {\n toolName: \"missing\",\n parameters: [],\n };\n\n const { result, error } = await handleToolCall(request, {});\n expect(error).toBe(\"Tool missing not found in registry\");\n expect(result).toContain(\"missing\");\n });\n\n it(\"calls onCallUnregisteredTool fallback when tool not in registry\", async () => {\n const fallback = jest.fn().mockResolvedValue(\"fallback result\");\n const request: TamboAI.ToolCallRequest = {\n toolName: \"unregistered\",\n parameters: [{ parameterName: \"x\", parameterValue: \"1\" }],\n };\n\n const { result, error } = await handleToolCall(request, {}, fallback);\n expect(result).toBe(\"fallback result\");\n expect(error).toBeUndefined();\n expect(fallback).toHaveBeenCalledWith(\"unregistered\", request.parameters);\n });\n\n it(\"returns error info when tool execution throws\", async () => {\n const registry = makeRegistry(\"boom\", () => {\n throw new Error(\"kaboom\");\n });\n const request: TamboAI.ToolCallRequest = {\n toolName: \"boom\",\n parameters: [],\n };\n\n const { result, error } = await handleToolCall(request, registry);\n expect(error).toBe(\"kaboom\");\n expect(result).toContain(\"kaboom\");\n });\n\n it(\"handles null parameters\", async () => {\n const registry = makeRegistry(\"noArgs\", () => \"ok\");\n const request = {\n toolName: \"noArgs\",\n parameters: null,\n } as unknown as TamboAI.ToolCallRequest;\n\n const { result } = await handleToolCall(request, registry);\n expect(result).toBe(\"ok\");\n });\n});\n"]}
@@ -37,6 +37,7 @@ function createMockRegistry() {
37
37
  /**
38
38
  * Wrapper that provides the minimal provider tree for interactables:
39
39
  * TamboRegistryContext > TamboContextHelpersProvider > TamboInteractableProvider
40
+ * @returns The wrapper component.
40
41
  */
41
42
  function V1InteractableWrapper({ children, registry, }) {
42
43
  return (React.createElement(TamboRegistryContext.Provider, { value: registry },
@@ -1 +1 @@
1
- {"version":3,"file":"v1-interactables.test.js","sourceRoot":"","sources":["../../../src/v1/__tests__/v1-interactables.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import { act, render, renderHook, screen } from \"@testing-library/react\";\nimport React from \"react\";\nimport { z } from \"zod/v3\";\nimport { withTamboInteractable } from \"../../hoc/with-tambo-interactable\";\nimport { useTamboInteractable } from \"../../providers/tambo-interactable-provider\";\nimport { useTamboContextHelpers } from \"../../providers/tambo-context-helpers-provider\";\nimport {\n TamboRegistryContext,\n type TamboRegistryContext as TamboRegistryContextType,\n} from \"../../providers/tambo-registry-provider\";\nimport { TamboContextHelpersProvider } from \"../../providers/tambo-context-helpers-provider\";\nimport { TamboInteractableProvider } from \"../../providers/tambo-interactable-provider\";\n\n// Minimal registry mock that captures registered tools\nfunction createMockRegistry() {\n const toolRegistry: Record<string, unknown> = {};\n return {\n value: {\n componentList: {},\n toolRegistry,\n componentToolAssociations: {},\n mcpServerInfos: [],\n resources: [],\n resourceSource: null,\n onCallUnregisteredTool: undefined,\n registerComponent: jest.fn(),\n registerTool: jest.fn((tool: { name: string }) => {\n toolRegistry[tool.name] = tool;\n }),\n registerTools: jest.fn(),\n addToolAssociation: jest.fn(),\n registerMcpServer: jest.fn(),\n registerMcpServers: jest.fn(),\n registerResource: jest.fn(),\n registerResources: jest.fn(),\n registerResourceSource: jest.fn(),\n } as unknown as TamboRegistryContextType,\n getRegisteredToolNames: () => Object.keys(toolRegistry),\n };\n}\n\n/**\n * Wrapper that provides the minimal provider tree for interactables:\n * TamboRegistryContext > TamboContextHelpersProvider > TamboInteractableProvider\n */\nfunction V1InteractableWrapper({\n children,\n registry,\n}: {\n children: React.ReactNode;\n registry: TamboRegistryContextType;\n}) {\n return (\n <TamboRegistryContext.Provider value={registry}>\n <TamboContextHelpersProvider>\n <TamboInteractableProvider>{children}</TamboInteractableProvider>\n </TamboContextHelpersProvider>\n </TamboRegistryContext.Provider>\n );\n}\n\ndescribe(\"V1 Interactables Integration\", () => {\n it(\"registers update_component_props and update_component_state tools when an interactable is added\", () => {\n const mockRegistry = createMockRegistry();\n\n const { result } = renderHook(() => useTamboInteractable(), {\n wrapper: ({ children }) => (\n <V1InteractableWrapper registry={mockRegistry.value}>\n {children}\n </V1InteractableWrapper>\n ),\n });\n\n act(() => {\n result.current.addInteractableComponent({\n name: \"TestWidget\",\n description: \"A test widget\",\n component: () => <div>widget</div>,\n props: { label: \"hello\" },\n propsSchema: z.object({ label: z.string() }),\n });\n });\n\n const toolNames = mockRegistry.getRegisteredToolNames();\n expect(\n toolNames.some((n) => n.startsWith(\"update_component_props_TestWidget\")),\n ).toBe(true);\n expect(\n toolNames.some((n) => n.startsWith(\"update_component_state_TestWidget\")),\n ).toBe(true);\n });\n\n it(\"registers interactables context helper that includes component info\", async () => {\n const mockRegistry = createMockRegistry();\n\n const { result } = renderHook(\n () => ({\n interactable: useTamboInteractable(),\n helpers: useTamboContextHelpers(),\n }),\n {\n wrapper: ({ children }) => (\n <V1InteractableWrapper registry={mockRegistry.value}>\n {children}\n </V1InteractableWrapper>\n ),\n },\n );\n\n // Add an interactable component\n act(() => {\n result.current.interactable.addInteractableComponent({\n name: \"InfoCard\",\n description: \"An info card\",\n component: () => <div>card</div>,\n props: { title: \"Test\" },\n });\n });\n\n // Get additional context - should include interactable info\n const contexts = await act(async () => {\n return await result.current.helpers.getAdditionalContext();\n });\n\n const interactablesContext = contexts.find(\n (c) => c.name === \"interactables\",\n );\n expect(interactablesContext).toBeDefined();\n expect(interactablesContext?.context).toBeDefined();\n });\n\n it(\"renders an interactable component via withTamboInteractable HOC\", () => {\n const mockRegistry = createMockRegistry();\n\n interface CardProps {\n title: string;\n }\n\n const Card: React.FC<CardProps> = ({ title }) => (\n <div data-testid=\"card-title\">{title}</div>\n );\n\n const InteractableCard = withTamboInteractable(Card, {\n componentName: \"Card\",\n description: \"A card component\",\n propsSchema: z.object({ title: z.string() }),\n });\n\n render(\n <V1InteractableWrapper registry={mockRegistry.value}>\n <InteractableCard title=\"Hello V1\" />\n </V1InteractableWrapper>,\n );\n\n expect(screen.getByTestId(\"card-title\")).toHaveTextContent(\"Hello V1\");\n });\n\n it(\"updates component props via the interactable provider\", () => {\n const mockRegistry = createMockRegistry();\n\n interface CounterProps {\n count: number;\n }\n\n const Counter: React.FC<CounterProps> = ({ count }) => (\n <div data-testid=\"count\">{count}</div>\n );\n\n const InteractableCounter = withTamboInteractable(Counter, {\n componentName: \"Counter\",\n description: \"A counter\",\n propsSchema: z.object({ count: z.number() }),\n });\n\n // Inner component that triggers prop updates\n function TestHarness() {\n const { interactableComponents, updateInteractableComponentProps } =\n useTamboInteractable();\n const component = interactableComponents[0];\n\n return (\n <div>\n <InteractableCounter count={0} />\n {component && (\n <button\n data-testid=\"update-btn\"\n onClick={() =>\n updateInteractableComponentProps(component.id, { count: 42 })\n }\n >\n Update\n </button>\n )}\n </div>\n );\n }\n\n render(\n <V1InteractableWrapper registry={mockRegistry.value}>\n <TestHarness />\n </V1InteractableWrapper>,\n );\n\n // Initial render\n expect(screen.getByTestId(\"count\")).toHaveTextContent(\"0\");\n\n // Update props via the interactable provider\n act(() => {\n screen.getByTestId(\"update-btn\").click();\n });\n\n // The interactable should reflect updated props\n expect(screen.getByTestId(\"count\")).toHaveTextContent(\"42\");\n });\n});\n"]}
1
+ {"version":3,"file":"v1-interactables.test.js","sourceRoot":"","sources":["../../../src/v1/__tests__/v1-interactables.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import { act, render, renderHook, screen } from \"@testing-library/react\";\nimport React from \"react\";\nimport { z } from \"zod/v3\";\nimport { withTamboInteractable } from \"../../hoc/with-tambo-interactable\";\nimport { useTamboInteractable } from \"../../providers/tambo-interactable-provider\";\nimport { useTamboContextHelpers } from \"../../providers/tambo-context-helpers-provider\";\nimport {\n TamboRegistryContext,\n type TamboRegistryContext as TamboRegistryContextType,\n} from \"../../providers/tambo-registry-provider\";\nimport { TamboContextHelpersProvider } from \"../../providers/tambo-context-helpers-provider\";\nimport { TamboInteractableProvider } from \"../../providers/tambo-interactable-provider\";\n\n// Minimal registry mock that captures registered tools\nfunction createMockRegistry() {\n const toolRegistry: Record<string, unknown> = {};\n return {\n value: {\n componentList: {},\n toolRegistry,\n componentToolAssociations: {},\n mcpServerInfos: [],\n resources: [],\n resourceSource: null,\n onCallUnregisteredTool: undefined,\n registerComponent: jest.fn(),\n registerTool: jest.fn((tool: { name: string }) => {\n toolRegistry[tool.name] = tool;\n }),\n registerTools: jest.fn(),\n addToolAssociation: jest.fn(),\n registerMcpServer: jest.fn(),\n registerMcpServers: jest.fn(),\n registerResource: jest.fn(),\n registerResources: jest.fn(),\n registerResourceSource: jest.fn(),\n } as unknown as TamboRegistryContextType,\n getRegisteredToolNames: () => Object.keys(toolRegistry),\n };\n}\n\n/**\n * Wrapper that provides the minimal provider tree for interactables:\n * TamboRegistryContext > TamboContextHelpersProvider > TamboInteractableProvider\n * @returns The wrapper component.\n */\nfunction V1InteractableWrapper({\n children,\n registry,\n}: {\n children: React.ReactNode;\n registry: TamboRegistryContextType;\n}) {\n return (\n <TamboRegistryContext.Provider value={registry}>\n <TamboContextHelpersProvider>\n <TamboInteractableProvider>{children}</TamboInteractableProvider>\n </TamboContextHelpersProvider>\n </TamboRegistryContext.Provider>\n );\n}\n\ndescribe(\"V1 Interactables Integration\", () => {\n it(\"registers update_component_props and update_component_state tools when an interactable is added\", () => {\n const mockRegistry = createMockRegistry();\n\n const { result } = renderHook(() => useTamboInteractable(), {\n wrapper: ({ children }) => (\n <V1InteractableWrapper registry={mockRegistry.value}>\n {children}\n </V1InteractableWrapper>\n ),\n });\n\n act(() => {\n result.current.addInteractableComponent({\n name: \"TestWidget\",\n description: \"A test widget\",\n component: () => <div>widget</div>,\n props: { label: \"hello\" },\n propsSchema: z.object({ label: z.string() }),\n });\n });\n\n const toolNames = mockRegistry.getRegisteredToolNames();\n expect(\n toolNames.some((n) => n.startsWith(\"update_component_props_TestWidget\")),\n ).toBe(true);\n expect(\n toolNames.some((n) => n.startsWith(\"update_component_state_TestWidget\")),\n ).toBe(true);\n });\n\n it(\"registers interactables context helper that includes component info\", async () => {\n const mockRegistry = createMockRegistry();\n\n const { result } = renderHook(\n () => ({\n interactable: useTamboInteractable(),\n helpers: useTamboContextHelpers(),\n }),\n {\n wrapper: ({ children }) => (\n <V1InteractableWrapper registry={mockRegistry.value}>\n {children}\n </V1InteractableWrapper>\n ),\n },\n );\n\n // Add an interactable component\n act(() => {\n result.current.interactable.addInteractableComponent({\n name: \"InfoCard\",\n description: \"An info card\",\n component: () => <div>card</div>,\n props: { title: \"Test\" },\n });\n });\n\n // Get additional context - should include interactable info\n const contexts = await act(async () => {\n return await result.current.helpers.getAdditionalContext();\n });\n\n const interactablesContext = contexts.find(\n (c) => c.name === \"interactables\",\n );\n expect(interactablesContext).toBeDefined();\n expect(interactablesContext?.context).toBeDefined();\n });\n\n it(\"renders an interactable component via withTamboInteractable HOC\", () => {\n const mockRegistry = createMockRegistry();\n\n interface CardProps {\n title: string;\n }\n\n const Card: React.FC<CardProps> = ({ title }) => (\n <div data-testid=\"card-title\">{title}</div>\n );\n\n const InteractableCard = withTamboInteractable(Card, {\n componentName: \"Card\",\n description: \"A card component\",\n propsSchema: z.object({ title: z.string() }),\n });\n\n render(\n <V1InteractableWrapper registry={mockRegistry.value}>\n <InteractableCard title=\"Hello V1\" />\n </V1InteractableWrapper>,\n );\n\n expect(screen.getByTestId(\"card-title\")).toHaveTextContent(\"Hello V1\");\n });\n\n it(\"updates component props via the interactable provider\", () => {\n const mockRegistry = createMockRegistry();\n\n interface CounterProps {\n count: number;\n }\n\n const Counter: React.FC<CounterProps> = ({ count }) => (\n <div data-testid=\"count\">{count}</div>\n );\n\n const InteractableCounter = withTamboInteractable(Counter, {\n componentName: \"Counter\",\n description: \"A counter\",\n propsSchema: z.object({ count: z.number() }),\n });\n\n // Inner component that triggers prop updates\n function TestHarness() {\n const { interactableComponents, updateInteractableComponentProps } =\n useTamboInteractable();\n const component = interactableComponents[0];\n\n return (\n <div>\n <InteractableCounter count={0} />\n {component && (\n <button\n data-testid=\"update-btn\"\n onClick={() =>\n updateInteractableComponentProps(component.id, { count: 42 })\n }\n >\n Update\n </button>\n )}\n </div>\n );\n }\n\n render(\n <V1InteractableWrapper registry={mockRegistry.value}>\n <TestHarness />\n </V1InteractableWrapper>,\n );\n\n // Initial render\n expect(screen.getByTestId(\"count\")).toHaveTextContent(\"0\");\n\n // Update props via the interactable provider\n act(() => {\n screen.getByTestId(\"update-btn\").click();\n });\n\n // The interactable should reflect updated props\n expect(screen.getByTestId(\"count\")).toHaveTextContent(\"42\");\n });\n});\n"]}
@@ -1,4 +1,4 @@
1
- import type { TamboAuthState } from "../types/auth.js";
1
+ import type { TamboAuthState } from "@tambo-ai/client";
2
2
  /**
3
3
  * Hook to compute the current authentication state for the SDK.
4
4
  *
@@ -1 +1 @@
1
- {"version":3,"file":"use-tambo-v1-auth-state.d.ts","sourceRoot":"","sources":["../../../src/v1/hooks/use-tambo-v1-auth-state.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,IAAI,cAAc,CAqClD"}
1
+ {"version":3,"file":"use-tambo-v1-auth-state.d.ts","sourceRoot":"","sources":["../../../src/v1/hooks/use-tambo-v1-auth-state.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEvD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,IAAI,cAAc,CAqClD"}
@@ -1 +1 @@
1
- {"version":3,"file":"use-tambo-v1-auth-state.js","sourceRoot":"","sources":["../../../src/v1/hooks/use-tambo-v1-auth-state.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AACnC,OAAO,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAGpE;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB;IAC/B,MAAM,aAAa,GAAG,UAAU,CAAC,kBAAkB,CAAC,CAAC;IACrD,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;IACzE,CAAC;IAED,MAAM,MAAM,GAAG,UAAU,CAAC,kBAAkB,CAAC,CAAC;IAC9C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;IACzE,CAAC;IAED,MAAM,EAAE,kBAAkB,EAAE,SAAS,EAAE,aAAa,EAAE,GAAG,aAAa,CAAC;IACvE,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;IAE3B,+CAA+C;IAC/C,IAAI,OAAO,IAAI,SAAS,EAAE,CAAC;QACzB,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IAC/B,CAAC;IAED,yBAAyB;IACzB,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IACrD,CAAC;IAED,2BAA2B;IAC3B,IAAI,SAAS,EAAE,CAAC;QACd,IAAI,kBAAkB,EAAE,CAAC;YACvB,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,kBAAkB,EAAE,CAAC;QACxD,CAAC;QACD,IAAI,aAAa,EAAE,CAAC;YAClB,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;QAC3D,CAAC;QACD,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC;IAClC,CAAC;IAED,mBAAmB;IACnB,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAAC;AACvC,CAAC","sourcesContent":["\"use client\";\n\nimport { useContext } from \"react\";\nimport { TamboClientContext } from \"../../providers/tambo-client-provider\";\nimport { TamboConfigContext } from \"../providers/tambo-v1-provider\";\nimport type { TamboAuthState } from \"../types/auth\";\n\n/**\n * Hook to compute the current authentication state for the SDK.\n *\n * Reads from TamboClientContext and TamboConfigContext to determine\n * whether the SDK is ready to make API calls.\n * @returns The current auth state as a discriminated union\n * @throws {Error} If used outside TamboProvider\n */\nexport function useTamboAuthState(): TamboAuthState {\n const clientContext = useContext(TamboClientContext);\n if (!clientContext) {\n throw new Error(\"useTamboAuthState must be used within TamboProvider\");\n }\n\n const config = useContext(TamboConfigContext);\n if (!config) {\n throw new Error(\"useTamboAuthState must be used within TamboProvider\");\n }\n\n const { tokenExchangeError, userToken, hasValidToken } = clientContext;\n const { userKey } = config;\n\n // Invalid: both userKey AND userToken provided\n if (userKey && userToken) {\n return { status: \"invalid\" };\n }\n\n // Identified via userKey\n if (userKey) {\n return { status: \"identified\", source: \"userKey\" };\n }\n\n // Token exchange scenarios\n if (userToken) {\n if (tokenExchangeError) {\n return { status: \"error\", error: tokenExchangeError };\n }\n if (hasValidToken) {\n return { status: \"identified\", source: \"tokenExchange\" };\n }\n return { status: \"exchanging\" };\n }\n\n // Neither provided\n return { status: \"unauthenticated\" };\n}\n"]}
1
+ {"version":3,"file":"use-tambo-v1-auth-state.js","sourceRoot":"","sources":["../../../src/v1/hooks/use-tambo-v1-auth-state.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AACnC,OAAO,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAGpE;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB;IAC/B,MAAM,aAAa,GAAG,UAAU,CAAC,kBAAkB,CAAC,CAAC;IACrD,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;IACzE,CAAC;IAED,MAAM,MAAM,GAAG,UAAU,CAAC,kBAAkB,CAAC,CAAC;IAC9C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;IACzE,CAAC;IAED,MAAM,EAAE,kBAAkB,EAAE,SAAS,EAAE,aAAa,EAAE,GAAG,aAAa,CAAC;IACvE,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;IAE3B,+CAA+C;IAC/C,IAAI,OAAO,IAAI,SAAS,EAAE,CAAC;QACzB,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IAC/B,CAAC;IAED,yBAAyB;IACzB,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IACrD,CAAC;IAED,2BAA2B;IAC3B,IAAI,SAAS,EAAE,CAAC;QACd,IAAI,kBAAkB,EAAE,CAAC;YACvB,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,kBAAkB,EAAE,CAAC;QACxD,CAAC;QACD,IAAI,aAAa,EAAE,CAAC;YAClB,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;QAC3D,CAAC;QACD,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC;IAClC,CAAC;IAED,mBAAmB;IACnB,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAAC;AACvC,CAAC","sourcesContent":["\"use client\";\n\nimport { useContext } from \"react\";\nimport { TamboClientContext } from \"../../providers/tambo-client-provider\";\nimport { TamboConfigContext } from \"../providers/tambo-v1-provider\";\nimport type { TamboAuthState } from \"@tambo-ai/client\";\n\n/**\n * Hook to compute the current authentication state for the SDK.\n *\n * Reads from TamboClientContext and TamboConfigContext to determine\n * whether the SDK is ready to make API calls.\n * @returns The current auth state as a discriminated union\n * @throws {Error} If used outside TamboProvider\n */\nexport function useTamboAuthState(): TamboAuthState {\n const clientContext = useContext(TamboClientContext);\n if (!clientContext) {\n throw new Error(\"useTamboAuthState must be used within TamboProvider\");\n }\n\n const config = useContext(TamboConfigContext);\n if (!config) {\n throw new Error(\"useTamboAuthState must be used within TamboProvider\");\n }\n\n const { tokenExchangeError, userToken, hasValidToken } = clientContext;\n const { userKey } = config;\n\n // Invalid: both userKey AND userToken provided\n if (userKey && userToken) {\n return { status: \"invalid\" };\n }\n\n // Identified via userKey\n if (userKey) {\n return { status: \"identified\", source: \"userKey\" };\n }\n\n // Token exchange scenarios\n if (userToken) {\n if (tokenExchangeError) {\n return { status: \"error\", error: tokenExchangeError };\n }\n if (hasValidToken) {\n return { status: \"identified\", source: \"tokenExchange\" };\n }\n return { status: \"exchanging\" };\n }\n\n // Neither provided\n return { status: \"unauthenticated\" };\n}\n"]}
@@ -20,7 +20,7 @@ import { useTamboInteractable } from "../../providers/tambo-interactable-provide
20
20
  import { useComponentContentOptional } from "../utils/component-renderer.js";
21
21
  import { useTamboConfig } from "../providers/tambo-v1-provider.js";
22
22
  import { useStreamState } from "../providers/tambo-v1-stream-context.js";
23
- import { findComponentContent } from "../utils/thread-utils.js";
23
+ import { findComponentContent } from "@tambo-ai/client";
24
24
  export function useTamboComponentState(keyName, initialValue, debounceTime = 500) {
25
25
  const client = useTamboClient();
26
26
  const { userKey } = useTamboConfig();