@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,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const mcp_server_info_1 = require("../model/mcp-server-info");
3
+ const client_1 = require("@tambo-ai/client");
4
4
  const mcp_server_utils_1 = require("./mcp-server-utils");
5
5
  describe("deriveServerKey", () => {
6
6
  it("should extract key from simple domain", () => {
@@ -65,7 +65,7 @@ describe("normalizeServerInfo", () => {
65
65
  const result = (0, mcp_server_utils_1.normalizeServerInfo)("https://example.com/mcp");
66
66
  expect(result).toEqual({
67
67
  url: "https://example.com/mcp",
68
- transport: mcp_server_info_1.MCPTransport.HTTP,
68
+ transport: client_1.MCPTransport.HTTP,
69
69
  serverKey: "example",
70
70
  });
71
71
  });
@@ -76,7 +76,7 @@ describe("normalizeServerInfo", () => {
76
76
  };
77
77
  const result = (0, mcp_server_utils_1.normalizeServerInfo)(server);
78
78
  expect(result.serverKey).toBe("custom-key");
79
- expect(result.transport).toBe(mcp_server_info_1.MCPTransport.HTTP);
79
+ expect(result.transport).toBe(client_1.MCPTransport.HTTP);
80
80
  });
81
81
  it("should derive serverKey when not provided", () => {
82
82
  const server = {
@@ -88,17 +88,17 @@ describe("normalizeServerInfo", () => {
88
88
  it("should preserve existing transport", () => {
89
89
  const server = {
90
90
  url: "https://example.com/mcp",
91
- transport: mcp_server_info_1.MCPTransport.SSE,
91
+ transport: client_1.MCPTransport.SSE,
92
92
  };
93
93
  const result = (0, mcp_server_utils_1.normalizeServerInfo)(server);
94
- expect(result.transport).toBe(mcp_server_info_1.MCPTransport.SSE);
94
+ expect(result.transport).toBe(client_1.MCPTransport.SSE);
95
95
  });
96
96
  it("should default transport to HTTP when not provided", () => {
97
97
  const server = {
98
98
  url: "https://example.com/mcp",
99
99
  };
100
100
  const result = (0, mcp_server_utils_1.normalizeServerInfo)(server);
101
- expect(result.transport).toBe(mcp_server_info_1.MCPTransport.HTTP);
101
+ expect(result.transport).toBe(client_1.MCPTransport.HTTP);
102
102
  });
103
103
  it("should preserve all other properties", () => {
104
104
  const server = {
@@ -119,7 +119,7 @@ describe("normalizeServerInfo", () => {
119
119
  url: "https://example.com/mcp",
120
120
  name: "My Server",
121
121
  description: "Description",
122
- transport: mcp_server_info_1.MCPTransport.SSE,
122
+ transport: client_1.MCPTransport.SSE,
123
123
  serverKey: "my-server",
124
124
  customHeaders: { Authorization: "Bearer token" },
125
125
  };
@@ -128,7 +128,7 @@ describe("normalizeServerInfo", () => {
128
128
  url: "https://example.com/mcp",
129
129
  name: "My Server",
130
130
  description: "Description",
131
- transport: mcp_server_info_1.MCPTransport.SSE,
131
+ transport: client_1.MCPTransport.SSE,
132
132
  serverKey: "my-server",
133
133
  customHeaders: { Authorization: "Bearer token" },
134
134
  });
@@ -141,7 +141,7 @@ describe("deduplicateMcpServers", () => {
141
141
  it("should return single server unchanged", () => {
142
142
  const server = {
143
143
  url: "https://example.com/mcp",
144
- transport: mcp_server_info_1.MCPTransport.HTTP,
144
+ transport: client_1.MCPTransport.HTTP,
145
145
  serverKey: "example",
146
146
  };
147
147
  expect((0, mcp_server_utils_1.deduplicateMcpServers)([server])).toEqual([server]);
@@ -149,12 +149,12 @@ describe("deduplicateMcpServers", () => {
149
149
  it("should deduplicate servers with same URL and transport", () => {
150
150
  const server1 = {
151
151
  url: "https://example.com/mcp",
152
- transport: mcp_server_info_1.MCPTransport.HTTP,
152
+ transport: client_1.MCPTransport.HTTP,
153
153
  serverKey: "example",
154
154
  };
155
155
  const server2 = {
156
156
  url: "https://example.com/mcp",
157
- transport: mcp_server_info_1.MCPTransport.HTTP,
157
+ transport: client_1.MCPTransport.HTTP,
158
158
  serverKey: "example",
159
159
  };
160
160
  const result = (0, mcp_server_utils_1.deduplicateMcpServers)([server1, server2]);
@@ -164,12 +164,12 @@ describe("deduplicateMcpServers", () => {
164
164
  it("should keep servers with different URLs", () => {
165
165
  const server1 = {
166
166
  url: "https://example.com/mcp",
167
- transport: mcp_server_info_1.MCPTransport.HTTP,
167
+ transport: client_1.MCPTransport.HTTP,
168
168
  serverKey: "example",
169
169
  };
170
170
  const server2 = {
171
171
  url: "https://other.com/mcp",
172
- transport: mcp_server_info_1.MCPTransport.HTTP,
172
+ transport: client_1.MCPTransport.HTTP,
173
173
  serverKey: "other",
174
174
  };
175
175
  const result = (0, mcp_server_utils_1.deduplicateMcpServers)([server1, server2]);
@@ -178,12 +178,12 @@ describe("deduplicateMcpServers", () => {
178
178
  it("should keep servers with same URL but different transport", () => {
179
179
  const server1 = {
180
180
  url: "https://example.com/mcp",
181
- transport: mcp_server_info_1.MCPTransport.HTTP,
181
+ transport: client_1.MCPTransport.HTTP,
182
182
  serverKey: "example",
183
183
  };
184
184
  const server2 = {
185
185
  url: "https://example.com/mcp",
186
- transport: mcp_server_info_1.MCPTransport.SSE,
186
+ transport: client_1.MCPTransport.SSE,
187
187
  serverKey: "example",
188
188
  };
189
189
  const result = (0, mcp_server_utils_1.deduplicateMcpServers)([server1, server2]);
@@ -192,17 +192,17 @@ describe("deduplicateMcpServers", () => {
192
192
  it("should ensure unique serverKeys by appending suffixes", () => {
193
193
  const server1 = {
194
194
  url: "https://example1.com/mcp",
195
- transport: mcp_server_info_1.MCPTransport.HTTP,
195
+ transport: client_1.MCPTransport.HTTP,
196
196
  serverKey: "linear",
197
197
  };
198
198
  const server2 = {
199
199
  url: "https://example2.com/mcp",
200
- transport: mcp_server_info_1.MCPTransport.HTTP,
200
+ transport: client_1.MCPTransport.HTTP,
201
201
  serverKey: "linear",
202
202
  };
203
203
  const server3 = {
204
204
  url: "https://example3.com/mcp",
205
- transport: mcp_server_info_1.MCPTransport.HTTP,
205
+ transport: client_1.MCPTransport.HTTP,
206
206
  serverKey: "linear",
207
207
  };
208
208
  const result = (0, mcp_server_utils_1.deduplicateMcpServers)([server1, server2, server3]);
@@ -214,17 +214,17 @@ describe("deduplicateMcpServers", () => {
214
214
  it("should handle mixed unique and duplicate serverKeys", () => {
215
215
  const server1 = {
216
216
  url: "https://example1.com/mcp",
217
- transport: mcp_server_info_1.MCPTransport.HTTP,
217
+ transport: client_1.MCPTransport.HTTP,
218
218
  serverKey: "linear",
219
219
  };
220
220
  const server2 = {
221
221
  url: "https://example2.com/mcp",
222
- transport: mcp_server_info_1.MCPTransport.HTTP,
222
+ transport: client_1.MCPTransport.HTTP,
223
223
  serverKey: "notion",
224
224
  };
225
225
  const server3 = {
226
226
  url: "https://example3.com/mcp",
227
- transport: mcp_server_info_1.MCPTransport.HTTP,
227
+ transport: client_1.MCPTransport.HTTP,
228
228
  serverKey: "linear",
229
229
  };
230
230
  const result = (0, mcp_server_utils_1.deduplicateMcpServers)([server1, server2, server3]);
@@ -237,12 +237,12 @@ describe("deduplicateMcpServers", () => {
237
237
  // Same connection, different serverKeys (shouldn't happen in practice but test the logic)
238
238
  const server1 = {
239
239
  url: "https://example.com/mcp",
240
- transport: mcp_server_info_1.MCPTransport.HTTP,
240
+ transport: client_1.MCPTransport.HTTP,
241
241
  serverKey: "linear",
242
242
  };
243
243
  const server2 = {
244
244
  url: "https://example.com/mcp",
245
- transport: mcp_server_info_1.MCPTransport.HTTP,
245
+ transport: client_1.MCPTransport.HTTP,
246
246
  serverKey: "notion",
247
247
  };
248
248
  const result = (0, mcp_server_utils_1.deduplicateMcpServers)([server1, server2]);
@@ -252,13 +252,13 @@ describe("deduplicateMcpServers", () => {
252
252
  it("should preserve server properties when deduplicating", () => {
253
253
  const server1 = {
254
254
  url: "https://example.com/mcp",
255
- transport: mcp_server_info_1.MCPTransport.HTTP,
255
+ transport: client_1.MCPTransport.HTTP,
256
256
  serverKey: "example",
257
257
  name: "First Server",
258
258
  };
259
259
  const server2 = {
260
260
  url: "https://example.com/mcp",
261
- transport: mcp_server_info_1.MCPTransport.HTTP,
261
+ transport: client_1.MCPTransport.HTTP,
262
262
  serverKey: "example",
263
263
  name: "Second Server",
264
264
  };
@@ -270,13 +270,13 @@ describe("deduplicateMcpServers", () => {
270
270
  it("should handle servers with different customHeaders as different connections", () => {
271
271
  const server1 = {
272
272
  url: "https://example.com/mcp",
273
- transport: mcp_server_info_1.MCPTransport.HTTP,
273
+ transport: client_1.MCPTransport.HTTP,
274
274
  serverKey: "example",
275
275
  customHeaders: { Authorization: "Bearer token1" },
276
276
  };
277
277
  const server2 = {
278
278
  url: "https://example.com/mcp",
279
- transport: mcp_server_info_1.MCPTransport.HTTP,
279
+ transport: client_1.MCPTransport.HTTP,
280
280
  serverKey: "example",
281
281
  customHeaders: { Authorization: "Bearer token2" },
282
282
  };
@@ -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"]}
@@ -12,7 +12,7 @@ const schema_1 = require("../schema");
12
12
  const getAvailableComponents = (componentRegistry, toolRegistry, toolAssociations) => {
13
13
  const availableComponents = [];
14
14
  for (const [name, componentEntry] of Object.entries(componentRegistry)) {
15
- const associatedToolNames = toolAssociations[name] || [];
15
+ const associatedToolNames = toolAssociations[name] ?? [];
16
16
  const contextTools = associatedToolNames
17
17
  .map((toolName) => {
18
18
  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"]}
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.resolveResourceContents = resolveResourceContents;
4
4
  exports.extractResourceUris = extractResourceUris;
5
- const mcp_constants_1 = require("../mcp/mcp-constants");
5
+ const client_1 = require("@tambo-ai/client");
6
6
  /**
7
7
  * Type guard for narrowing McpServer to a connected server.
8
8
  * A connected server has a non-null client.
@@ -34,7 +34,7 @@ async function resolveResourceContents(resourceUris, mcpServers, resourceSource)
34
34
  try {
35
35
  // Handle registry resources directly - no server lookup needed
36
36
  // Registry resources are local to the browser and resolved via resourceSource
37
- if (serverKey === mcp_constants_1.REGISTRY_SERVER_KEY) {
37
+ if (serverKey === client_1.REGISTRY_SERVER_KEY) {
38
38
  if (!resourceSource) {
39
39
  console.warn(`No resource source available to resolve registry resource: ${prefixedUri}`);
40
40
  return;
@@ -52,13 +52,13 @@ async function resolveResourceContents(resourceUris, mcpServers, resourceSource)
52
52
  return;
53
53
  }
54
54
  switch (server.serverType) {
55
- case mcp_constants_1.ServerType.TAMBO_INTERNAL:
55
+ case client_1.ServerType.TAMBO_INTERNAL:
56
56
  // Skip internal server resources - backend can resolve these
57
57
  return;
58
- case mcp_constants_1.ServerType.TAMBO_REGISTRY:
58
+ case client_1.ServerType.TAMBO_REGISTRY:
59
59
  // Should not reach here since we handle registry above, but keep for safety
60
60
  return;
61
- case mcp_constants_1.ServerType.BROWSER_SIDE: {
61
+ case client_1.ServerType.BROWSER_SIDE: {
62
62
  // Client-side MCP resource
63
63
  if (!isConnectedMcpServer(server)) {
64
64
  console.warn(`MCP server not connected for resource: ${prefixedUri}`);
@@ -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,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const mcp_constants_1 = require("../mcp/mcp-constants");
4
- const mcp_client_1 = require("../mcp/mcp-client");
3
+ const client_1 = require("@tambo-ai/client");
4
+ const client_2 = require("@tambo-ai/client");
5
5
  const resource_content_resolver_1 = require("./resource-content-resolver");
6
6
  describe("extractResourceUris", () => {
7
7
  it("should extract a single resource URI", () => {
@@ -44,12 +44,12 @@ describe("extractResourceUris", () => {
44
44
  });
45
45
  });
46
46
  describe("resolveResourceContents", () => {
47
- const createMockConnectedServer = (serverKey, readResource, serverType = mcp_constants_1.ServerType.BROWSER_SIDE) => ({
47
+ const createMockConnectedServer = (serverKey, readResource, serverType = client_1.ServerType.BROWSER_SIDE) => ({
48
48
  key: `mcp-${serverKey}`,
49
49
  serverKey,
50
50
  url: `https://${serverKey}.example.com`,
51
51
  name: `MCP Server ${serverKey}`,
52
- transport: mcp_client_1.MCPTransport.HTTP,
52
+ transport: client_2.MCPTransport.HTTP,
53
53
  serverType,
54
54
  client: {
55
55
  client: {
@@ -68,8 +68,8 @@ describe("resolveResourceContents", () => {
68
68
  serverKey,
69
69
  url: "https://api.tambo.co/mcp",
70
70
  name: "__tambo_internal_mcp_server__",
71
- transport: mcp_client_1.MCPTransport.HTTP,
72
- serverType: mcp_constants_1.ServerType.TAMBO_INTERNAL,
71
+ transport: client_2.MCPTransport.HTTP,
72
+ serverType: client_1.ServerType.TAMBO_INTERNAL,
73
73
  connectionError: undefined, // No client for internal servers
74
74
  });
75
75
  const createMockResourceSource = (getResource) => ({
@@ -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":""}