@tambo-ai/react 0.65.3 → 0.66.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 (346) hide show
  1. package/README.md +120 -20
  2. package/dist/{providers/hoc → hoc}/with-tambo-interactable.d.ts +2 -2
  3. package/dist/hoc/with-tambo-interactable.d.ts.map +1 -0
  4. package/dist/{providers/hoc → hoc}/with-tambo-interactable.js +29 -2
  5. package/dist/hoc/with-tambo-interactable.js.map +1 -0
  6. package/dist/hoc/with-tambo-interactable.test.d.ts +2 -0
  7. package/dist/hoc/with-tambo-interactable.test.d.ts.map +1 -0
  8. package/dist/hoc/with-tambo-interactable.test.js +192 -0
  9. package/dist/hoc/with-tambo-interactable.test.js.map +1 -0
  10. package/dist/hooks/index.d.ts +1 -1
  11. package/dist/hooks/index.d.ts.map +1 -1
  12. package/dist/hooks/index.js +2 -1
  13. package/dist/hooks/index.js.map +1 -1
  14. package/dist/hooks/use-current-message.d.ts +51 -7
  15. package/dist/hooks/use-current-message.d.ts.map +1 -1
  16. package/dist/hooks/use-current-message.js +50 -6
  17. package/dist/hooks/use-current-message.js.map +1 -1
  18. package/dist/hooks/use-current-message.test.d.ts +2 -0
  19. package/dist/hooks/use-current-message.test.d.ts.map +1 -0
  20. package/dist/hooks/use-current-message.test.js +264 -0
  21. package/dist/hooks/use-current-message.test.js.map +1 -0
  22. package/dist/index.d.ts +10 -8
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +7 -3
  25. package/dist/index.js.map +1 -1
  26. package/dist/mcp/index.d.ts +1 -1
  27. package/dist/mcp/index.d.ts.map +1 -1
  28. package/dist/mcp/index.js +2 -1
  29. package/dist/mcp/index.js.map +1 -1
  30. package/dist/mcp/mcp-hooks.d.ts +77 -6
  31. package/dist/mcp/mcp-hooks.d.ts.map +1 -1
  32. package/dist/mcp/mcp-hooks.js +104 -40
  33. package/dist/mcp/mcp-hooks.js.map +1 -1
  34. package/dist/mcp/mcp-hooks.test.js +83 -18
  35. package/dist/mcp/mcp-hooks.test.js.map +1 -1
  36. package/dist/mcp/tambo-mcp-provider.d.ts.map +1 -1
  37. package/dist/mcp/tambo-mcp-provider.js +2 -1
  38. package/dist/mcp/tambo-mcp-provider.js.map +1 -1
  39. package/dist/model/component-metadata.d.ts +444 -14
  40. package/dist/model/component-metadata.d.ts.map +1 -1
  41. package/dist/model/component-metadata.js.map +1 -1
  42. package/dist/model/generate-component-response.d.ts +12 -1
  43. package/dist/model/generate-component-response.d.ts.map +1 -1
  44. package/dist/model/generate-component-response.js.map +1 -1
  45. package/dist/model/resource-info.d.ts +55 -0
  46. package/dist/model/resource-info.d.ts.map +1 -0
  47. package/dist/model/resource-info.js +3 -0
  48. package/dist/model/resource-info.js.map +1 -0
  49. package/dist/providers/index.d.ts +1 -1
  50. package/dist/providers/index.d.ts.map +1 -1
  51. package/dist/providers/index.js.map +1 -1
  52. package/dist/providers/tambo-component-provider.d.ts +4 -4
  53. package/dist/providers/tambo-component-provider.d.ts.map +1 -1
  54. package/dist/providers/tambo-component-provider.js.map +1 -1
  55. package/dist/providers/tambo-interactable-provider-partial-updates.test.js +87 -87
  56. package/dist/providers/tambo-interactable-provider-partial-updates.test.js.map +1 -1
  57. package/dist/providers/tambo-interactable-provider.d.ts +2 -3
  58. package/dist/providers/tambo-interactable-provider.d.ts.map +1 -1
  59. package/dist/providers/tambo-interactable-provider.js +47 -41
  60. package/dist/providers/tambo-interactable-provider.js.map +1 -1
  61. package/dist/providers/tambo-interactables-additional-context-edge-cases.test.js +9 -9
  62. package/dist/providers/tambo-interactables-additional-context-edge-cases.test.js.map +1 -1
  63. package/dist/providers/tambo-interactables-additional-context.test.js +11 -11
  64. package/dist/providers/tambo-interactables-additional-context.test.js.map +1 -1
  65. package/dist/providers/tambo-registry-provider.d.ts +28 -7
  66. package/dist/providers/tambo-registry-provider.d.ts.map +1 -1
  67. package/dist/providers/tambo-registry-provider.js +70 -181
  68. package/dist/providers/tambo-registry-provider.js.map +1 -1
  69. package/dist/providers/tambo-registry-provider.test.js +152 -30
  70. package/dist/providers/tambo-registry-provider.test.js.map +1 -1
  71. package/dist/providers/tambo-registry-schema-compat.test.d.ts +2 -0
  72. package/dist/providers/tambo-registry-schema-compat.test.d.ts.map +1 -0
  73. package/dist/providers/tambo-registry-schema-compat.test.js +616 -0
  74. package/dist/providers/tambo-registry-schema-compat.test.js.map +1 -0
  75. package/dist/providers/tambo-stubs.d.ts +2 -2
  76. package/dist/providers/tambo-stubs.d.ts.map +1 -1
  77. package/dist/providers/tambo-stubs.js +5 -0
  78. package/dist/providers/tambo-stubs.js.map +1 -1
  79. package/dist/providers/tambo-thread-input-provider.d.ts +1 -0
  80. package/dist/providers/tambo-thread-input-provider.d.ts.map +1 -1
  81. package/dist/providers/tambo-thread-input-provider.js +3 -3
  82. package/dist/providers/tambo-thread-input-provider.js.map +1 -1
  83. package/dist/providers/tambo-thread-provider.d.ts.map +1 -1
  84. package/dist/providers/tambo-thread-provider.js.map +1 -1
  85. package/dist/providers/tambo-thread-provider.test.js +32 -36
  86. package/dist/providers/tambo-thread-provider.test.js.map +1 -1
  87. package/dist/schema/index.d.ts +6 -0
  88. package/dist/schema/index.d.ts.map +1 -0
  89. package/dist/schema/index.js +18 -0
  90. package/dist/schema/index.js.map +1 -0
  91. package/dist/schema/json-schema.d.ts +35 -0
  92. package/dist/schema/json-schema.d.ts.map +1 -0
  93. package/dist/schema/json-schema.js +103 -0
  94. package/dist/schema/json-schema.js.map +1 -0
  95. package/dist/schema/schema.d.ts +66 -0
  96. package/dist/schema/schema.d.ts.map +1 -0
  97. package/dist/schema/schema.js +192 -0
  98. package/dist/schema/schema.js.map +1 -0
  99. package/dist/schema/schema.test.d.ts +2 -0
  100. package/dist/schema/schema.test.d.ts.map +1 -0
  101. package/dist/schema/schema.test.js +41 -0
  102. package/dist/schema/schema.test.js.map +1 -0
  103. package/dist/schema/standard-schema.d.ts +21 -0
  104. package/dist/schema/standard-schema.d.ts.map +1 -0
  105. package/dist/schema/standard-schema.js +37 -0
  106. package/dist/schema/standard-schema.js.map +1 -0
  107. package/dist/schema/validate.d.ts +14 -0
  108. package/dist/schema/validate.d.ts.map +1 -0
  109. package/dist/schema/validate.js +148 -0
  110. package/dist/schema/validate.js.map +1 -0
  111. package/dist/schema/validate.test.d.ts +2 -0
  112. package/dist/schema/validate.test.d.ts.map +1 -0
  113. package/dist/schema/validate.test.js +128 -0
  114. package/dist/schema/validate.test.js.map +1 -0
  115. package/dist/schema/zod.d.ts +54 -0
  116. package/dist/schema/zod.d.ts.map +1 -0
  117. package/dist/schema/zod.js +135 -0
  118. package/dist/schema/zod.js.map +1 -0
  119. package/dist/testing/tools.d.ts +29 -15
  120. package/dist/testing/tools.d.ts.map +1 -1
  121. package/dist/testing/tools.js +64 -19
  122. package/dist/testing/tools.js.map +1 -1
  123. package/dist/util/generate-component.d.ts.map +1 -1
  124. package/dist/util/generate-component.js +3 -3
  125. package/dist/util/generate-component.js.map +1 -1
  126. package/dist/util/mcp-server-utils.d.ts +23 -0
  127. package/dist/util/mcp-server-utils.d.ts.map +1 -0
  128. package/dist/util/mcp-server-utils.js +107 -0
  129. package/dist/util/mcp-server-utils.js.map +1 -0
  130. package/dist/util/mcp-server-utils.test.d.ts +2 -0
  131. package/dist/util/mcp-server-utils.test.d.ts.map +1 -0
  132. package/dist/util/mcp-server-utils.test.js +287 -0
  133. package/dist/util/mcp-server-utils.test.js.map +1 -0
  134. package/dist/util/message-builder.d.ts +2 -1
  135. package/dist/util/message-builder.d.ts.map +1 -1
  136. package/dist/util/message-builder.js +54 -36
  137. package/dist/util/message-builder.js.map +1 -1
  138. package/dist/util/message-builder.test.js +500 -13
  139. package/dist/util/message-builder.test.js.map +1 -1
  140. package/dist/util/registry-validators.d.ts +26 -0
  141. package/dist/util/registry-validators.d.ts.map +1 -0
  142. package/dist/util/registry-validators.js +105 -0
  143. package/dist/util/registry-validators.js.map +1 -0
  144. package/dist/util/registry-validators.test.d.ts +2 -0
  145. package/dist/util/registry-validators.test.d.ts.map +1 -0
  146. package/dist/util/registry-validators.test.js +235 -0
  147. package/dist/util/registry-validators.test.js.map +1 -0
  148. package/dist/util/registry.d.ts +35 -7
  149. package/dist/util/registry.d.ts.map +1 -1
  150. package/dist/util/registry.js +60 -77
  151. package/dist/util/registry.js.map +1 -1
  152. package/dist/util/registry.test.d.ts +2 -0
  153. package/dist/util/registry.test.d.ts.map +1 -0
  154. package/dist/util/registry.test.js +204 -0
  155. package/dist/util/registry.test.js.map +1 -0
  156. package/dist/util/resource-validators.d.ts +16 -0
  157. package/dist/util/resource-validators.d.ts.map +1 -0
  158. package/dist/util/resource-validators.js +34 -0
  159. package/dist/util/resource-validators.js.map +1 -0
  160. package/dist/util/tool-caller.d.ts +2 -2
  161. package/dist/util/tool-caller.d.ts.map +1 -1
  162. package/dist/util/tool-caller.js +12 -4
  163. package/dist/util/tool-caller.js.map +1 -1
  164. package/esm/{providers/hoc → hoc}/with-tambo-interactable.d.ts +2 -2
  165. package/esm/hoc/with-tambo-interactable.d.ts.map +1 -0
  166. package/esm/{providers/hoc → hoc}/with-tambo-interactable.js +29 -2
  167. package/esm/hoc/with-tambo-interactable.js.map +1 -0
  168. package/esm/hoc/with-tambo-interactable.test.d.ts +2 -0
  169. package/esm/hoc/with-tambo-interactable.test.d.ts.map +1 -0
  170. package/esm/hoc/with-tambo-interactable.test.js +187 -0
  171. package/esm/hoc/with-tambo-interactable.test.js.map +1 -0
  172. package/esm/hooks/index.d.ts +1 -1
  173. package/esm/hooks/index.d.ts.map +1 -1
  174. package/esm/hooks/index.js +1 -1
  175. package/esm/hooks/index.js.map +1 -1
  176. package/esm/hooks/use-current-message.d.ts +51 -7
  177. package/esm/hooks/use-current-message.d.ts.map +1 -1
  178. package/esm/hooks/use-current-message.js +48 -5
  179. package/esm/hooks/use-current-message.js.map +1 -1
  180. package/esm/hooks/use-current-message.test.d.ts +2 -0
  181. package/esm/hooks/use-current-message.test.d.ts.map +1 -0
  182. package/esm/hooks/use-current-message.test.js +259 -0
  183. package/esm/hooks/use-current-message.test.js.map +1 -0
  184. package/esm/index.d.ts +10 -8
  185. package/esm/index.d.ts.map +1 -1
  186. package/esm/index.js +4 -2
  187. package/esm/index.js.map +1 -1
  188. package/esm/mcp/index.d.ts +1 -1
  189. package/esm/mcp/index.d.ts.map +1 -1
  190. package/esm/mcp/index.js +1 -1
  191. package/esm/mcp/index.js.map +1 -1
  192. package/esm/mcp/mcp-hooks.d.ts +77 -6
  193. package/esm/mcp/mcp-hooks.d.ts.map +1 -1
  194. package/esm/mcp/mcp-hooks.js +103 -40
  195. package/esm/mcp/mcp-hooks.js.map +1 -1
  196. package/esm/mcp/mcp-hooks.test.js +84 -19
  197. package/esm/mcp/mcp-hooks.test.js.map +1 -1
  198. package/esm/mcp/tambo-mcp-provider.d.ts.map +1 -1
  199. package/esm/mcp/tambo-mcp-provider.js +2 -1
  200. package/esm/mcp/tambo-mcp-provider.js.map +1 -1
  201. package/esm/model/component-metadata.d.ts +444 -14
  202. package/esm/model/component-metadata.d.ts.map +1 -1
  203. package/esm/model/component-metadata.js.map +1 -1
  204. package/esm/model/generate-component-response.d.ts +12 -1
  205. package/esm/model/generate-component-response.d.ts.map +1 -1
  206. package/esm/model/generate-component-response.js.map +1 -1
  207. package/esm/model/resource-info.d.ts +55 -0
  208. package/esm/model/resource-info.d.ts.map +1 -0
  209. package/esm/model/resource-info.js +2 -0
  210. package/esm/model/resource-info.js.map +1 -0
  211. package/esm/providers/index.d.ts +1 -1
  212. package/esm/providers/index.d.ts.map +1 -1
  213. package/esm/providers/index.js.map +1 -1
  214. package/esm/providers/tambo-component-provider.d.ts +4 -4
  215. package/esm/providers/tambo-component-provider.d.ts.map +1 -1
  216. package/esm/providers/tambo-component-provider.js.map +1 -1
  217. package/esm/providers/tambo-interactable-provider-partial-updates.test.js +1 -1
  218. package/esm/providers/tambo-interactable-provider-partial-updates.test.js.map +1 -1
  219. package/esm/providers/tambo-interactable-provider.d.ts +2 -3
  220. package/esm/providers/tambo-interactable-provider.d.ts.map +1 -1
  221. package/esm/providers/tambo-interactable-provider.js +44 -38
  222. package/esm/providers/tambo-interactable-provider.js.map +1 -1
  223. package/esm/providers/tambo-interactables-additional-context-edge-cases.test.js +3 -3
  224. package/esm/providers/tambo-interactables-additional-context-edge-cases.test.js.map +1 -1
  225. package/esm/providers/tambo-interactables-additional-context.test.js +3 -3
  226. package/esm/providers/tambo-interactables-additional-context.test.js.map +1 -1
  227. package/esm/providers/tambo-registry-provider.d.ts +28 -7
  228. package/esm/providers/tambo-registry-provider.d.ts.map +1 -1
  229. package/esm/providers/tambo-registry-provider.js +67 -175
  230. package/esm/providers/tambo-registry-provider.js.map +1 -1
  231. package/esm/providers/tambo-registry-provider.test.js +148 -26
  232. package/esm/providers/tambo-registry-provider.test.js.map +1 -1
  233. package/esm/providers/tambo-registry-schema-compat.test.d.ts +2 -0
  234. package/esm/providers/tambo-registry-schema-compat.test.d.ts.map +1 -0
  235. package/esm/providers/tambo-registry-schema-compat.test.js +578 -0
  236. package/esm/providers/tambo-registry-schema-compat.test.js.map +1 -0
  237. package/esm/providers/tambo-stubs.d.ts +2 -2
  238. package/esm/providers/tambo-stubs.d.ts.map +1 -1
  239. package/esm/providers/tambo-stubs.js +5 -0
  240. package/esm/providers/tambo-stubs.js.map +1 -1
  241. package/esm/providers/tambo-thread-input-provider.d.ts +1 -0
  242. package/esm/providers/tambo-thread-input-provider.d.ts.map +1 -1
  243. package/esm/providers/tambo-thread-input-provider.js +3 -3
  244. package/esm/providers/tambo-thread-input-provider.js.map +1 -1
  245. package/esm/providers/tambo-thread-provider.d.ts.map +1 -1
  246. package/esm/providers/tambo-thread-provider.js.map +1 -1
  247. package/esm/providers/tambo-thread-provider.test.js +24 -28
  248. package/esm/providers/tambo-thread-provider.test.js.map +1 -1
  249. package/esm/schema/index.d.ts +6 -0
  250. package/esm/schema/index.d.ts.map +1 -0
  251. package/esm/schema/index.js +6 -0
  252. package/esm/schema/index.js.map +1 -0
  253. package/esm/schema/json-schema.d.ts +35 -0
  254. package/esm/schema/json-schema.d.ts.map +1 -0
  255. package/esm/schema/json-schema.js +98 -0
  256. package/esm/schema/json-schema.js.map +1 -0
  257. package/esm/schema/schema.d.ts +66 -0
  258. package/esm/schema/schema.d.ts.map +1 -0
  259. package/esm/schema/schema.js +185 -0
  260. package/esm/schema/schema.js.map +1 -0
  261. package/esm/schema/schema.test.d.ts +2 -0
  262. package/esm/schema/schema.test.d.ts.map +1 -0
  263. package/esm/schema/schema.test.js +39 -0
  264. package/esm/schema/schema.test.js.map +1 -0
  265. package/esm/schema/standard-schema.d.ts +21 -0
  266. package/esm/schema/standard-schema.d.ts.map +1 -0
  267. package/esm/schema/standard-schema.js +34 -0
  268. package/esm/schema/standard-schema.js.map +1 -0
  269. package/esm/schema/validate.d.ts +14 -0
  270. package/esm/schema/validate.d.ts.map +1 -0
  271. package/esm/schema/validate.js +145 -0
  272. package/esm/schema/validate.js.map +1 -0
  273. package/esm/schema/validate.test.d.ts +2 -0
  274. package/esm/schema/validate.test.d.ts.map +1 -0
  275. package/esm/schema/validate.test.js +126 -0
  276. package/esm/schema/validate.test.js.map +1 -0
  277. package/esm/schema/zod.d.ts +54 -0
  278. package/esm/schema/zod.d.ts.map +1 -0
  279. package/esm/schema/zod.js +124 -0
  280. package/esm/schema/zod.js.map +1 -0
  281. package/esm/testing/tools.d.ts +29 -15
  282. package/esm/testing/tools.d.ts.map +1 -1
  283. package/esm/testing/tools.js +62 -16
  284. package/esm/testing/tools.js.map +1 -1
  285. package/esm/util/generate-component.d.ts.map +1 -1
  286. package/esm/util/generate-component.js +3 -3
  287. package/esm/util/generate-component.js.map +1 -1
  288. package/esm/util/mcp-server-utils.d.ts +23 -0
  289. package/esm/util/mcp-server-utils.d.ts.map +1 -0
  290. package/esm/util/mcp-server-utils.js +102 -0
  291. package/esm/util/mcp-server-utils.js.map +1 -0
  292. package/esm/util/mcp-server-utils.test.d.ts +2 -0
  293. package/esm/util/mcp-server-utils.test.d.ts.map +1 -0
  294. package/esm/util/mcp-server-utils.test.js +285 -0
  295. package/esm/util/mcp-server-utils.test.js.map +1 -0
  296. package/esm/util/message-builder.d.ts +2 -1
  297. package/esm/util/message-builder.d.ts.map +1 -1
  298. package/esm/util/message-builder.js +54 -36
  299. package/esm/util/message-builder.js.map +1 -1
  300. package/esm/util/message-builder.test.js +500 -13
  301. package/esm/util/message-builder.test.js.map +1 -1
  302. package/esm/util/registry-validators.d.ts +26 -0
  303. package/esm/util/registry-validators.d.ts.map +1 -0
  304. package/esm/util/registry-validators.js +100 -0
  305. package/esm/util/registry-validators.js.map +1 -0
  306. package/esm/util/registry-validators.test.d.ts +2 -0
  307. package/esm/util/registry-validators.test.d.ts.map +1 -0
  308. package/esm/util/registry-validators.test.js +233 -0
  309. package/esm/util/registry-validators.test.js.map +1 -0
  310. package/esm/util/registry.d.ts +35 -7
  311. package/esm/util/registry.d.ts.map +1 -1
  312. package/esm/util/registry.js +57 -73
  313. package/esm/util/registry.js.map +1 -1
  314. package/esm/util/registry.test.d.ts +2 -0
  315. package/esm/util/registry.test.d.ts.map +1 -0
  316. package/esm/util/registry.test.js +169 -0
  317. package/esm/util/registry.test.js.map +1 -0
  318. package/esm/util/resource-validators.d.ts +16 -0
  319. package/esm/util/resource-validators.d.ts.map +1 -0
  320. package/esm/util/resource-validators.js +30 -0
  321. package/esm/util/resource-validators.js.map +1 -0
  322. package/esm/util/tool-caller.d.ts +2 -2
  323. package/esm/util/tool-caller.d.ts.map +1 -1
  324. package/esm/util/tool-caller.js +12 -4
  325. package/esm/util/tool-caller.js.map +1 -1
  326. package/package.json +13 -8
  327. package/dist/providers/hoc/with-tambo-interactable.d.ts.map +0 -1
  328. package/dist/providers/hoc/with-tambo-interactable.js.map +0 -1
  329. package/dist/util/validate-zod-schema.d.ts +0 -10
  330. package/dist/util/validate-zod-schema.d.ts.map +0 -1
  331. package/dist/util/validate-zod-schema.js +0 -100
  332. package/dist/util/validate-zod-schema.js.map +0 -1
  333. package/dist/util/validate-zod-schema.test.d.ts +0 -2
  334. package/dist/util/validate-zod-schema.test.d.ts.map +0 -1
  335. package/dist/util/validate-zod-schema.test.js +0 -96
  336. package/dist/util/validate-zod-schema.test.js.map +0 -1
  337. package/esm/providers/hoc/with-tambo-interactable.d.ts.map +0 -1
  338. package/esm/providers/hoc/with-tambo-interactable.js.map +0 -1
  339. package/esm/util/validate-zod-schema.d.ts +0 -10
  340. package/esm/util/validate-zod-schema.d.ts.map +0 -1
  341. package/esm/util/validate-zod-schema.js +0 -97
  342. package/esm/util/validate-zod-schema.js.map +0 -1
  343. package/esm/util/validate-zod-schema.test.d.ts +0 -2
  344. package/esm/util/validate-zod-schema.test.d.ts.map +0 -1
  345. package/esm/util/validate-zod-schema.test.js +0 -94
  346. package/esm/util/validate-zod-schema.test.js.map +0 -1
package/README.md CHANGED
@@ -79,7 +79,7 @@ import {
79
79
  useTamboThread,
80
80
  useTamboThreadInput,
81
81
  } from "@tambo-ai/react";
82
- import { z } from "zod";
82
+ import { z } from "zod/v4";
83
83
 
84
84
  // 1. Register your components
85
85
  const components = [
@@ -275,25 +275,24 @@ const mcpServers = [
275
275
  Sometimes you need functions that run in the browser. DOM manipulation, authenticated fetches, accessing React state. Define them as tools and the AI can call them.
276
276
 
277
277
  ```tsx
278
- import { type TamboTool } from "@tambo-ai/react";
278
+ import { z } from "zod/v4";
279
+ import { defineTool } from "@tambo-ai/react";
279
280
 
280
- const tools: TamboTool[] = [
281
- {
281
+ const tools = [
282
+ defineTool({
282
283
  name: "getWeather",
283
284
  description: "Fetches weather data for a location",
284
- tool: async (location: string) =>
285
+ tool: async ({ location }) =>
285
286
  fetch(`/api/weather?q=${location}`).then((r) => r.json()),
286
- toolSchema: z
287
- .function()
288
- .args(z.string())
289
- .returns(
290
- z.object({
291
- temperature: z.number(),
292
- condition: z.string(),
293
- location: z.string(),
294
- }),
295
- ),
296
- },
287
+ inputSchema: z.object({
288
+ location: z.string(),
289
+ }),
290
+ outputSchema: z.object({
291
+ temperature: z.number(),
292
+ condition: z.string(),
293
+ location: z.string(),
294
+ }),
295
+ }),
297
296
  ];
298
297
 
299
298
  <TamboProvider tools={tools} components={components}>
@@ -316,10 +315,10 @@ const tools: TamboTool[] = [
316
315
  const data = await fetchImageData(imageId);
317
316
  return { url: data.imageUrl, description: data.description };
318
317
  },
319
- toolSchema: z
320
- .function()
321
- .args(z.string())
322
- .returns(z.object({ url: z.string(), description: z.string() })),
318
+ toolSchema: z.function({
319
+ input: z.string(),
320
+ output: z.object({ url: z.string(), description: z.string() }),
321
+ }),
323
322
  transformToContent: (result) => [
324
323
  { type: "text", text: result.description },
325
324
  { type: "image_url", image_url: { url: result.url } },
@@ -330,6 +329,107 @@ const tools: TamboTool[] = [
330
329
 
331
330
  The MCP integration automatically uses `transformToContent` to pass through rich content.
332
331
 
332
+ ### Local Resources
333
+
334
+ Resources provide context to the AI by making content accessible without requiring a full MCP server. You can register static resources, dynamic resource functions, or both.
335
+
336
+ #### Static Resources
337
+
338
+ Register individual resources directly in your provider:
339
+
340
+ ```tsx
341
+ import { type ListResourceItem } from "@tambo-ai/react";
342
+
343
+ const resources: ListResourceItem[] = [
344
+ {
345
+ uri: "file:///config/app-settings.json",
346
+ name: "App Settings",
347
+ description: "Current application configuration",
348
+ mimeType: "application/json",
349
+ },
350
+ {
351
+ uri: "file:///docs/user-guide.md",
352
+ name: "User Guide",
353
+ description: "Getting started documentation",
354
+ mimeType: "text/markdown",
355
+ },
356
+ ];
357
+
358
+ <TamboProvider resources={resources}>
359
+ <App />
360
+ </TamboProvider>;
361
+ ```
362
+
363
+ #### Dynamic Resources
364
+
365
+ For resources that need to be fetched or computed at runtime, provide `listResources` and `getResource` functions:
366
+
367
+ ```tsx
368
+ import { type ResourceSource, type ReadResourceResult } from "@tambo-ai/react";
369
+
370
+ const listResources = async (search?: string) => {
371
+ const allDocs = await fetchUserDocuments();
372
+ return allDocs
373
+ .filter((doc) => !search || doc.name.includes(search))
374
+ .map((doc) => ({
375
+ uri: `file:///docs/${doc.id}`,
376
+ name: doc.name,
377
+ description: doc.summary,
378
+ mimeType: "text/markdown",
379
+ }));
380
+ };
381
+
382
+ const getResource = async (uri: string): Promise<ReadResourceResult> => {
383
+ const docId = uri.split("/").pop();
384
+ const content = await fetchDocumentContent(docId);
385
+ return {
386
+ contents: [
387
+ {
388
+ uri,
389
+ mimeType: "text/markdown",
390
+ text: content,
391
+ },
392
+ ],
393
+ };
394
+ };
395
+
396
+ <TamboProvider listResources={listResources} getResource={getResource}>
397
+ <App />
398
+ </TamboProvider>;
399
+ ```
400
+
401
+ **Important:** Both `listResources` and `getResource` must be provided together - you cannot provide one without the other.
402
+
403
+ #### Programmatic Registration
404
+
405
+ You can also register resources programmatically:
406
+
407
+ ```tsx
408
+ const { registerResource, registerResourceSource } = useTamboRegistry();
409
+
410
+ // Register a single resource
411
+ registerResource({
412
+ uri: "file:///runtime/state.json",
413
+ name: "Application State",
414
+ mimeType: "application/json",
415
+ });
416
+
417
+ // Register a dynamic source
418
+ registerResourceSource({
419
+ listResources: async () => [...],
420
+ getResource: async (uri) => ({ contents: [...] }),
421
+ });
422
+ ```
423
+
424
+ #### Resource vs MCP Server
425
+
426
+ - **Local resources**: Fast, simple, runs in the browser. Great for app state, config, cached data.
427
+ - **MCP servers**: Full protocol support, server-side execution. Use for databases, APIs, external services.
428
+
429
+ Local resources appear in `useTamboMcpResourceList()` alongside MCP resources, with MCP resources always prefixed by their serverKey.
430
+
431
+ [→ Learn more about resources](https://docs.tambo.co/concepts/resources)
432
+
333
433
  ### Streaming Status
334
434
 
335
435
  Monitor streaming status for progressive loading:
@@ -1,9 +1,9 @@
1
1
  import React from "react";
2
- import { z } from "zod/v3";
2
+ import { SupportedSchema } from "../schema";
3
3
  export interface InteractableConfig {
4
4
  componentName: string;
5
5
  description: string;
6
- propsSchema?: z.ZodTypeAny;
6
+ propsSchema?: SupportedSchema;
7
7
  }
8
8
  export interface WithTamboInteractableProps {
9
9
  interactableId?: string;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"with-tambo-interactable.d.ts","sourceRoot":"","sources":["../../src/hoc/with-tambo-interactable.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAIxE,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAE5C,MAAM,WAAW,kBAAkB;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,eAAe,CAAC;CAC/B;AAED,MAAM,WAAW,0BAA0B;IACzC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,mBAAmB,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,aAAa,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,IAAI,CAAC;CACzD;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,SAAS,MAAM,EACpD,gBAAgB,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,EACxC,MAAM,EAAE,kBAAkB,4CAgH3B"}
@@ -37,7 +37,8 @@ var __importStar = (this && this.__importStar) || (function () {
37
37
  Object.defineProperty(exports, "__esModule", { value: true });
38
38
  exports.withTamboInteractable = withTamboInteractable;
39
39
  const react_1 = __importStar(require("react"));
40
- const tambo_interactable_provider_1 = require("../tambo-interactable-provider");
40
+ const use_current_message_1 = require("../hooks/use-current-message");
41
+ const tambo_interactable_provider_1 = require("../providers/tambo-interactable-provider");
41
42
  /**
42
43
  * Higher-Order Component that makes any component interactable by tambo.
43
44
  * @param WrappedComponent - The component to make interactable
@@ -111,7 +112,33 @@ function withTamboInteractable(WrappedComponent, config) {
111
112
  updateInteractableComponentProps,
112
113
  onPropsUpdate,
113
114
  ]);
114
- return react_1.default.createElement(WrappedComponent, { ...effectiveProps });
115
+ // If the interactable ID is not yet set, render the component without provider
116
+ if (!interactableId) {
117
+ return react_1.default.createElement(WrappedComponent, { ...effectiveProps });
118
+ }
119
+ // Create a minimal message with interactable metadata
120
+ // This allows useTamboCurrentComponent to work with standalone interactable components
121
+ const minimalMessage = {
122
+ id: interactableId,
123
+ role: "assistant",
124
+ content: [],
125
+ threadId: "",
126
+ createdAt: new Date().toISOString(),
127
+ component: {
128
+ componentName: config.componentName,
129
+ componentState: {},
130
+ message: "",
131
+ props: effectiveProps,
132
+ },
133
+ componentState: {},
134
+ };
135
+ // Wrap with TamboMessageProvider including interactable metadata
136
+ return (react_1.default.createElement(use_current_message_1.TamboMessageProvider, { message: minimalMessage, interactableMetadata: {
137
+ id: interactableId,
138
+ componentName: config.componentName,
139
+ description: config.description,
140
+ } },
141
+ react_1.default.createElement(WrappedComponent, { ...effectiveProps })));
115
142
  };
116
143
  TamboInteractableWrapper.displayName = `withTamboInteractable(${displayName})`;
117
144
  return TamboInteractableWrapper;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"with-tambo-interactable.js","sourceRoot":"","sources":["../../src/hoc/with-tambo-interactable.tsx"],"names":[],"mappings":"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","sourcesContent":["// react-sdk/src/providers/with-interactable.tsx\n\"use client\";\nimport React, { useCallback, useEffect, useRef, useState } from \"react\";\nimport { TamboMessageProvider } from \"../hooks/use-current-message\";\nimport { TamboThreadMessage } from \"../model/generate-component-response\";\nimport { useTamboInteractable } from \"../providers/tambo-interactable-provider\";\nimport { SupportedSchema } from \"../schema\";\n\nexport interface InteractableConfig {\n componentName: string;\n description: string;\n propsSchema?: SupportedSchema;\n}\n\nexport interface WithTamboInteractableProps {\n interactableId?: string;\n onInteractableReady?: (id: string) => void;\n onPropsUpdate?: (newProps: Record<string, any>) => void;\n}\n\n/**\n * Higher-Order Component that makes any component interactable by tambo.\n * @param WrappedComponent - The component to make interactable\n * @param config - Configuration for the interactable component\n * @returns A new component that is automatically registered as interactable\n * @example\n * ```tsx\n * const MyInteractableNote = withTamboInteractable(MyNote, {\n * componentName: \"MyNote\",\n * description: \"A note component\",\n * propsSchema: z.object({\n * title: z.string(),\n * content: z.string(),\n * }),\n * });\n *\n * // Usage\n * <MyInteractableNote title=\"My Note\" content=\"This is my note\" />\n * ```\n */\nexport function withTamboInteractable<P extends object>(\n WrappedComponent: React.ComponentType<P>,\n config: InteractableConfig,\n) {\n const displayName =\n WrappedComponent.displayName ?? WrappedComponent.name ?? \"Component\";\n\n const TamboInteractableWrapper: React.FC<P & WithTamboInteractableProps> = (\n props,\n ) => {\n const {\n addInteractableComponent,\n updateInteractableComponentProps,\n getInteractableComponent,\n } = useTamboInteractable();\n\n const [interactableId, setInteractableId] = useState<string | null>(null);\n const isInitialized = useRef(false);\n const lastParentProps = useRef<Record<string, any>>({});\n\n // Extract interactable-specific props\n const { onInteractableReady, onPropsUpdate, ...componentProps } = props;\n\n // Get the current interactable component to track prop updates\n const currentInteractable = interactableId\n ? getInteractableComponent(interactableId)\n : null;\n\n // Use the props from the interactable component if available, otherwise use the passed props\n // We need to be careful not to create a loop, so we only use stored props if they're different from passed props\n const effectiveProps = currentInteractable?.props ?? componentProps;\n\n // Memoize the registration function\n const registerComponent = useCallback(() => {\n if (!isInitialized.current) {\n const id = addInteractableComponent({\n name: config.componentName,\n description: config.description,\n component: WrappedComponent,\n props: componentProps,\n propsSchema: config.propsSchema,\n });\n\n setInteractableId(id);\n onInteractableReady?.(id);\n isInitialized.current = true;\n }\n }, [addInteractableComponent, componentProps, onInteractableReady]);\n\n // Register the component as interactable on mount (only once)\n useEffect(() => {\n registerComponent();\n }, [registerComponent]);\n\n // Update the interactable component when props change from parent\n useEffect(() => {\n if (interactableId && isInitialized.current) {\n // Only update if the props are different from what we last sent\n const lastPropsString = JSON.stringify(lastParentProps.current);\n const currentPropsString = JSON.stringify(componentProps);\n\n if (lastPropsString !== currentPropsString) {\n updateInteractableComponentProps(interactableId, componentProps);\n onPropsUpdate?.(componentProps);\n lastParentProps.current = componentProps;\n }\n }\n }, [\n interactableId,\n componentProps,\n updateInteractableComponentProps,\n onPropsUpdate,\n ]);\n\n // If the interactable ID is not yet set, render the component without provider\n if (!interactableId) {\n return <WrappedComponent {...(effectiveProps as P)} />;\n }\n\n // Create a minimal message with interactable metadata\n // This allows useTamboCurrentComponent to work with standalone interactable components\n const minimalMessage: TamboThreadMessage = {\n id: interactableId,\n role: \"assistant\" as const,\n content: [],\n threadId: \"\",\n createdAt: new Date().toISOString(),\n component: {\n componentName: config.componentName,\n componentState: {},\n message: \"\",\n props: effectiveProps,\n },\n componentState: {},\n };\n\n // Wrap with TamboMessageProvider including interactable metadata\n return (\n <TamboMessageProvider\n message={minimalMessage}\n interactableMetadata={{\n id: interactableId,\n componentName: config.componentName,\n description: config.description,\n }}\n >\n <WrappedComponent {...(effectiveProps as P)} />\n </TamboMessageProvider>\n );\n };\n\n TamboInteractableWrapper.displayName = `withTamboInteractable(${displayName})`;\n\n return TamboInteractableWrapper;\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=with-tambo-interactable.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"with-tambo-interactable.test.d.ts","sourceRoot":"","sources":["../../src/hoc/with-tambo-interactable.test.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,192 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const react_1 = require("@testing-library/react");
7
+ const react_2 = __importDefault(require("react"));
8
+ const v3_1 = require("zod/v3");
9
+ const use_current_message_1 = require("../hooks/use-current-message");
10
+ const tambo_interactable_provider_1 = require("../providers/tambo-interactable-provider");
11
+ const with_tambo_interactable_1 = require("./with-tambo-interactable");
12
+ // Create a consistent mock implementation
13
+ const mockAddInteractableComponent = jest.fn(() => "mock-id-123");
14
+ const mockUpdateInteractableComponentProps = jest.fn();
15
+ const mockGetInteractableComponent = jest.fn(() => null);
16
+ const mockRemoveInteractableComponent = jest.fn();
17
+ const mockGetInteractableComponentsByName = jest.fn(() => []);
18
+ const mockClearAllInteractableComponents = jest.fn();
19
+ // Mock the interactable provider
20
+ jest.mock("../providers/tambo-interactable-provider", () => ({
21
+ TamboInteractableProvider: ({ children }) => (react_2.default.createElement("div", { "data-testid": "interactable-provider" }, children)),
22
+ useTamboInteractable: () => ({
23
+ addInteractableComponent: mockAddInteractableComponent,
24
+ updateInteractableComponentProps: mockUpdateInteractableComponentProps,
25
+ getInteractableComponent: mockGetInteractableComponent,
26
+ removeInteractableComponent: mockRemoveInteractableComponent,
27
+ getInteractableComponentsByName: mockGetInteractableComponentsByName,
28
+ clearAllInteractableComponents: mockClearAllInteractableComponents,
29
+ interactableComponents: [],
30
+ }),
31
+ }));
32
+ describe("withTamboInteractable", () => {
33
+ const TestComponent = ({ title, count }) => (react_2.default.createElement("div", null,
34
+ react_2.default.createElement("h1", { "data-testid": "title" }, title),
35
+ count !== undefined && react_2.default.createElement("span", { "data-testid": "count" }, count)));
36
+ const testSchema = v3_1.z.object({
37
+ title: v3_1.z.string(),
38
+ count: v3_1.z.number().optional(),
39
+ });
40
+ beforeEach(() => {
41
+ jest.clearAllMocks();
42
+ // Reset mock implementations
43
+ mockAddInteractableComponent.mockReturnValue("mock-id-123");
44
+ mockGetInteractableComponent.mockReturnValue(null);
45
+ mockGetInteractableComponentsByName.mockReturnValue([]);
46
+ });
47
+ it("should render the wrapped component with provided props", () => {
48
+ const InteractableComponent = (0, with_tambo_interactable_1.withTamboInteractable)(TestComponent, {
49
+ componentName: "TestComponent",
50
+ description: "A test component",
51
+ propsSchema: testSchema,
52
+ });
53
+ (0, react_1.render)(react_2.default.createElement(tambo_interactable_provider_1.TamboInteractableProvider, null,
54
+ react_2.default.createElement(InteractableComponent, { title: "Hello", count: 42 })));
55
+ expect(react_1.screen.getByTestId("title")).toHaveTextContent("Hello");
56
+ expect(react_1.screen.getByTestId("count")).toHaveTextContent("42");
57
+ });
58
+ it("should set displayName correctly", () => {
59
+ const InteractableComponent = (0, with_tambo_interactable_1.withTamboInteractable)(TestComponent, {
60
+ componentName: "TestComponent",
61
+ description: "A test component",
62
+ });
63
+ expect(InteractableComponent.displayName).toBe("withTamboInteractable(TestComponent)");
64
+ });
65
+ it("should handle components without displayName", () => {
66
+ const AnonymousComponent = () => react_2.default.createElement("div", null, "Anonymous");
67
+ const InteractableComponent = (0, with_tambo_interactable_1.withTamboInteractable)(AnonymousComponent, {
68
+ componentName: "AnonymousComponent",
69
+ description: "An anonymous component",
70
+ });
71
+ // Anonymous components get their name from the function name
72
+ expect(InteractableComponent.displayName).toBe("withTamboInteractable(AnonymousComponent)");
73
+ });
74
+ it("should provide TamboMessageProvider with interactable metadata", async () => {
75
+ // Child component that uses the context
76
+ const ContextConsumer = () => {
77
+ const component = (0, use_current_message_1.useTamboCurrentComponent)();
78
+ return (react_2.default.createElement("div", null,
79
+ react_2.default.createElement("span", { "data-testid": "interactable-id" }, component?.interactableId),
80
+ react_2.default.createElement("span", { "data-testid": "component-name" }, component?.componentName),
81
+ react_2.default.createElement("span", { "data-testid": "description" }, component?.description)));
82
+ };
83
+ // Wrap TestComponent to include ContextConsumer
84
+ const TestComponentWithConsumer = (props) => (react_2.default.createElement("div", null,
85
+ react_2.default.createElement(TestComponent, { ...props }),
86
+ react_2.default.createElement(ContextConsumer, null)));
87
+ const InteractableWithConsumer = (0, with_tambo_interactable_1.withTamboInteractable)(TestComponentWithConsumer, {
88
+ componentName: "TestComponent",
89
+ description: "A test component",
90
+ propsSchema: testSchema,
91
+ });
92
+ (0, react_1.render)(react_2.default.createElement(tambo_interactable_provider_1.TamboInteractableProvider, null,
93
+ react_2.default.createElement(InteractableWithConsumer, { title: "Hello" })));
94
+ // Wait for the component to register and render
95
+ await (0, react_1.waitFor)(() => {
96
+ expect(react_1.screen.getByTestId("interactable-id")).toHaveTextContent("mock-id-123");
97
+ });
98
+ expect(react_1.screen.getByTestId("component-name")).toHaveTextContent("TestComponent");
99
+ expect(react_1.screen.getByTestId("description")).toHaveTextContent("A test component");
100
+ });
101
+ it("should create minimal message with correct structure", async () => {
102
+ // Child component that checks the message structure
103
+ const MessageChecker = () => {
104
+ const component = (0, use_current_message_1.useTamboCurrentComponent)();
105
+ return (react_2.default.createElement("div", null,
106
+ react_2.default.createElement("span", { "data-testid": "has-component-name" }, component?.componentName ? "yes" : "no"),
107
+ react_2.default.createElement("span", { "data-testid": "has-props" }, component?.props ? "yes" : "no"),
108
+ react_2.default.createElement("span", { "data-testid": "has-interactable-id" }, component?.interactableId ? "yes" : "no"),
109
+ react_2.default.createElement("span", { "data-testid": "has-description" }, component?.description ? "yes" : "no")));
110
+ };
111
+ const TestComponentWithChecker = (props) => (react_2.default.createElement("div", null,
112
+ react_2.default.createElement(TestComponent, { ...props }),
113
+ react_2.default.createElement(MessageChecker, null)));
114
+ const InteractableWithChecker = (0, with_tambo_interactable_1.withTamboInteractable)(TestComponentWithChecker, {
115
+ componentName: "TestComponent",
116
+ description: "A test component",
117
+ propsSchema: testSchema,
118
+ });
119
+ (0, react_1.render)(react_2.default.createElement(tambo_interactable_provider_1.TamboInteractableProvider, null,
120
+ react_2.default.createElement(InteractableWithChecker, { title: "Hello", count: 42 })));
121
+ await (0, react_1.waitFor)(() => {
122
+ expect(react_1.screen.getByTestId("has-component-name")).toHaveTextContent("yes");
123
+ });
124
+ expect(react_1.screen.getByTestId("has-props")).toHaveTextContent("yes");
125
+ expect(react_1.screen.getByTestId("has-interactable-id")).toHaveTextContent("yes");
126
+ expect(react_1.screen.getByTestId("has-description")).toHaveTextContent("yes");
127
+ });
128
+ it("should pass through all component props correctly", () => {
129
+ const InteractableComponent = (0, with_tambo_interactable_1.withTamboInteractable)(TestComponent, {
130
+ componentName: "TestComponent",
131
+ description: "A test component",
132
+ propsSchema: testSchema,
133
+ });
134
+ (0, react_1.render)(react_2.default.createElement(tambo_interactable_provider_1.TamboInteractableProvider, null,
135
+ react_2.default.createElement(InteractableComponent, { title: "Test Title", count: 100 })));
136
+ expect(react_1.screen.getByTestId("title")).toHaveTextContent("Test Title");
137
+ expect(react_1.screen.getByTestId("count")).toHaveTextContent("100");
138
+ });
139
+ it("should filter out interactable-specific props from component props", () => {
140
+ const ExtendedComponent = ({ title, onInteractableReady, onPropsUpdate, }) => (react_2.default.createElement("div", null,
141
+ react_2.default.createElement("span", { "data-testid": "title" }, title),
142
+ react_2.default.createElement("span", { "data-testid": "has-ready" }, onInteractableReady ? "yes" : "no"),
143
+ react_2.default.createElement("span", { "data-testid": "has-update" }, onPropsUpdate ? "yes" : "no")));
144
+ const InteractableComponent = (0, with_tambo_interactable_1.withTamboInteractable)(ExtendedComponent, {
145
+ componentName: "ExtendedComponent",
146
+ description: "An extended component",
147
+ });
148
+ const mockReady = jest.fn();
149
+ const mockUpdate = jest.fn();
150
+ (0, react_1.render)(react_2.default.createElement(tambo_interactable_provider_1.TamboInteractableProvider, null,
151
+ react_2.default.createElement(InteractableComponent, { title: "Test", onInteractableReady: mockReady, onPropsUpdate: mockUpdate })));
152
+ expect(react_1.screen.getByTestId("title")).toHaveTextContent("Test");
153
+ // These props should be filtered out
154
+ expect(react_1.screen.getByTestId("has-ready")).toHaveTextContent("no");
155
+ expect(react_1.screen.getByTestId("has-update")).toHaveTextContent("no");
156
+ });
157
+ it("should work without propsSchema", () => {
158
+ const InteractableComponent = (0, with_tambo_interactable_1.withTamboInteractable)(TestComponent, {
159
+ componentName: "TestComponent",
160
+ description: "A test component",
161
+ });
162
+ (0, react_1.render)(react_2.default.createElement(tambo_interactable_provider_1.TamboInteractableProvider, null,
163
+ react_2.default.createElement(InteractableComponent, { title: "No Schema" })));
164
+ expect(react_1.screen.getByTestId("title")).toHaveTextContent("No Schema");
165
+ });
166
+ it("should render before interactable ID is set", () => {
167
+ const InteractableComponent = (0, with_tambo_interactable_1.withTamboInteractable)(TestComponent, {
168
+ componentName: "TestComponent",
169
+ description: "A test component",
170
+ });
171
+ const { container } = (0, react_1.render)(react_2.default.createElement(tambo_interactable_provider_1.TamboInteractableProvider, null,
172
+ react_2.default.createElement(InteractableComponent, { title: "Early Render" })));
173
+ // Component should render even before ID is available
174
+ expect(container.querySelector('[data-testid="title"]')).toBeInTheDocument();
175
+ });
176
+ it("should handle null/undefined values in props", () => {
177
+ const NullableComponent = ({ title, optional, nullable, }) => (react_2.default.createElement("div", null,
178
+ react_2.default.createElement("span", { "data-testid": "title" }, title),
179
+ react_2.default.createElement("span", { "data-testid": "optional" }, optional ?? "undefined"),
180
+ react_2.default.createElement("span", { "data-testid": "nullable" }, nullable ?? "null")));
181
+ const InteractableComponent = (0, with_tambo_interactable_1.withTamboInteractable)(NullableComponent, {
182
+ componentName: "NullableComponent",
183
+ description: "A component with nullable props",
184
+ });
185
+ (0, react_1.render)(react_2.default.createElement(tambo_interactable_provider_1.TamboInteractableProvider, null,
186
+ react_2.default.createElement(InteractableComponent, { title: "Test", nullable: null })));
187
+ expect(react_1.screen.getByTestId("title")).toHaveTextContent("Test");
188
+ expect(react_1.screen.getByTestId("optional")).toHaveTextContent("undefined");
189
+ expect(react_1.screen.getByTestId("nullable")).toHaveTextContent("null");
190
+ });
191
+ });
192
+ //# sourceMappingURL=with-tambo-interactable.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"with-tambo-interactable.test.js","sourceRoot":"","sources":["../../src/hoc/with-tambo-interactable.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import { render, screen, waitFor } from \"@testing-library/react\";\nimport React from \"react\";\nimport { z } from \"zod/v3\";\nimport { useTamboCurrentComponent } from \"../hooks/use-current-message\";\nimport { TamboInteractableProvider } from \"../providers/tambo-interactable-provider\";\nimport { withTamboInteractable } from \"./with-tambo-interactable\";\n\n// Create a consistent mock implementation\nconst mockAddInteractableComponent = jest.fn(() => \"mock-id-123\");\nconst mockUpdateInteractableComponentProps = jest.fn();\nconst mockGetInteractableComponent = jest.fn(() => null);\nconst mockRemoveInteractableComponent = jest.fn();\nconst mockGetInteractableComponentsByName = jest.fn(() => []);\nconst mockClearAllInteractableComponents = jest.fn();\n\n// Mock the interactable provider\njest.mock(\"../providers/tambo-interactable-provider\", () => ({\n TamboInteractableProvider: ({ children }: { children: React.ReactNode }) => (\n <div data-testid=\"interactable-provider\">{children}</div>\n ),\n useTamboInteractable: () => ({\n addInteractableComponent: mockAddInteractableComponent,\n updateInteractableComponentProps: mockUpdateInteractableComponentProps,\n getInteractableComponent: mockGetInteractableComponent,\n removeInteractableComponent: mockRemoveInteractableComponent,\n getInteractableComponentsByName: mockGetInteractableComponentsByName,\n clearAllInteractableComponents: mockClearAllInteractableComponents,\n interactableComponents: [],\n }),\n}));\n\ndescribe(\"withTamboInteractable\", () => {\n // Simple test component\n interface TestComponentProps {\n title: string;\n count?: number;\n }\n\n const TestComponent: React.FC<TestComponentProps> = ({ title, count }) => (\n <div>\n <h1 data-testid=\"title\">{title}</h1>\n {count !== undefined && <span data-testid=\"count\">{count}</span>}\n </div>\n );\n\n const testSchema = z.object({\n title: z.string(),\n count: z.number().optional(),\n });\n\n beforeEach(() => {\n jest.clearAllMocks();\n // Reset mock implementations\n mockAddInteractableComponent.mockReturnValue(\"mock-id-123\");\n mockGetInteractableComponent.mockReturnValue(null);\n mockGetInteractableComponentsByName.mockReturnValue([]);\n });\n\n it(\"should render the wrapped component with provided props\", () => {\n const InteractableComponent = withTamboInteractable(TestComponent, {\n componentName: \"TestComponent\",\n description: \"A test component\",\n propsSchema: testSchema,\n });\n\n render(\n <TamboInteractableProvider>\n <InteractableComponent title=\"Hello\" count={42} />\n </TamboInteractableProvider>,\n );\n\n expect(screen.getByTestId(\"title\")).toHaveTextContent(\"Hello\");\n expect(screen.getByTestId(\"count\")).toHaveTextContent(\"42\");\n });\n\n it(\"should set displayName correctly\", () => {\n const InteractableComponent = withTamboInteractable(TestComponent, {\n componentName: \"TestComponent\",\n description: \"A test component\",\n });\n\n expect(InteractableComponent.displayName).toBe(\n \"withTamboInteractable(TestComponent)\",\n );\n });\n\n it(\"should handle components without displayName\", () => {\n const AnonymousComponent = () => <div>Anonymous</div>;\n\n const InteractableComponent = withTamboInteractable(AnonymousComponent, {\n componentName: \"AnonymousComponent\",\n description: \"An anonymous component\",\n });\n\n // Anonymous components get their name from the function name\n expect(InteractableComponent.displayName).toBe(\n \"withTamboInteractable(AnonymousComponent)\",\n );\n });\n\n it(\"should provide TamboMessageProvider with interactable metadata\", async () => {\n // Child component that uses the context\n const ContextConsumer = () => {\n const component = useTamboCurrentComponent();\n return (\n <div>\n <span data-testid=\"interactable-id\">{component?.interactableId}</span>\n <span data-testid=\"component-name\">{component?.componentName}</span>\n <span data-testid=\"description\">{component?.description}</span>\n </div>\n );\n };\n\n // Wrap TestComponent to include ContextConsumer\n const TestComponentWithConsumer: React.FC<TestComponentProps> = (props) => (\n <div>\n <TestComponent {...props} />\n <ContextConsumer />\n </div>\n );\n\n const InteractableWithConsumer = withTamboInteractable(\n TestComponentWithConsumer,\n {\n componentName: \"TestComponent\",\n description: \"A test component\",\n propsSchema: testSchema,\n },\n );\n\n render(\n <TamboInteractableProvider>\n <InteractableWithConsumer title=\"Hello\" />\n </TamboInteractableProvider>,\n );\n\n // Wait for the component to register and render\n await waitFor(() => {\n expect(screen.getByTestId(\"interactable-id\")).toHaveTextContent(\n \"mock-id-123\",\n );\n });\n\n expect(screen.getByTestId(\"component-name\")).toHaveTextContent(\n \"TestComponent\",\n );\n expect(screen.getByTestId(\"description\")).toHaveTextContent(\n \"A test component\",\n );\n });\n\n it(\"should create minimal message with correct structure\", async () => {\n // Child component that checks the message structure\n const MessageChecker = () => {\n const component = useTamboCurrentComponent();\n return (\n <div>\n <span data-testid=\"has-component-name\">\n {component?.componentName ? \"yes\" : \"no\"}\n </span>\n <span data-testid=\"has-props\">{component?.props ? \"yes\" : \"no\"}</span>\n <span data-testid=\"has-interactable-id\">\n {component?.interactableId ? \"yes\" : \"no\"}\n </span>\n <span data-testid=\"has-description\">\n {component?.description ? \"yes\" : \"no\"}\n </span>\n </div>\n );\n };\n\n const TestComponentWithChecker: React.FC<TestComponentProps> = (props) => (\n <div>\n <TestComponent {...props} />\n <MessageChecker />\n </div>\n );\n\n const InteractableWithChecker = withTamboInteractable(\n TestComponentWithChecker,\n {\n componentName: \"TestComponent\",\n description: \"A test component\",\n propsSchema: testSchema,\n },\n );\n\n render(\n <TamboInteractableProvider>\n <InteractableWithChecker title=\"Hello\" count={42} />\n </TamboInteractableProvider>,\n );\n\n await waitFor(() => {\n expect(screen.getByTestId(\"has-component-name\")).toHaveTextContent(\"yes\");\n });\n\n expect(screen.getByTestId(\"has-props\")).toHaveTextContent(\"yes\");\n expect(screen.getByTestId(\"has-interactable-id\")).toHaveTextContent(\"yes\");\n expect(screen.getByTestId(\"has-description\")).toHaveTextContent(\"yes\");\n });\n\n it(\"should pass through all component props correctly\", () => {\n const InteractableComponent = withTamboInteractable(TestComponent, {\n componentName: \"TestComponent\",\n description: \"A test component\",\n propsSchema: testSchema,\n });\n\n render(\n <TamboInteractableProvider>\n <InteractableComponent title=\"Test Title\" count={100} />\n </TamboInteractableProvider>,\n );\n\n expect(screen.getByTestId(\"title\")).toHaveTextContent(\"Test Title\");\n expect(screen.getByTestId(\"count\")).toHaveTextContent(\"100\");\n });\n\n it(\"should filter out interactable-specific props from component props\", () => {\n interface ExtendedProps extends TestComponentProps {\n onInteractableReady?: (id: string) => void;\n onPropsUpdate?: (props: Record<string, any>) => void;\n }\n\n const ExtendedComponent: React.FC<ExtendedProps> = ({\n title,\n onInteractableReady,\n onPropsUpdate,\n }) => (\n <div>\n <span data-testid=\"title\">{title}</span>\n <span data-testid=\"has-ready\">\n {onInteractableReady ? \"yes\" : \"no\"}\n </span>\n <span data-testid=\"has-update\">{onPropsUpdate ? \"yes\" : \"no\"}</span>\n </div>\n );\n\n const InteractableComponent = withTamboInteractable(ExtendedComponent, {\n componentName: \"ExtendedComponent\",\n description: \"An extended component\",\n });\n\n const mockReady = jest.fn();\n const mockUpdate = jest.fn();\n\n render(\n <TamboInteractableProvider>\n <InteractableComponent\n title=\"Test\"\n onInteractableReady={mockReady}\n onPropsUpdate={mockUpdate}\n />\n </TamboInteractableProvider>,\n );\n\n expect(screen.getByTestId(\"title\")).toHaveTextContent(\"Test\");\n // These props should be filtered out\n expect(screen.getByTestId(\"has-ready\")).toHaveTextContent(\"no\");\n expect(screen.getByTestId(\"has-update\")).toHaveTextContent(\"no\");\n });\n\n it(\"should work without propsSchema\", () => {\n const InteractableComponent = withTamboInteractable(TestComponent, {\n componentName: \"TestComponent\",\n description: \"A test component\",\n });\n\n render(\n <TamboInteractableProvider>\n <InteractableComponent title=\"No Schema\" />\n </TamboInteractableProvider>,\n );\n\n expect(screen.getByTestId(\"title\")).toHaveTextContent(\"No Schema\");\n });\n\n it(\"should render before interactable ID is set\", () => {\n const InteractableComponent = withTamboInteractable(TestComponent, {\n componentName: \"TestComponent\",\n description: \"A test component\",\n });\n\n const { container } = render(\n <TamboInteractableProvider>\n <InteractableComponent title=\"Early Render\" />\n </TamboInteractableProvider>,\n );\n\n // Component should render even before ID is available\n expect(\n container.querySelector('[data-testid=\"title\"]'),\n ).toBeInTheDocument();\n });\n\n it(\"should handle null/undefined values in props\", () => {\n interface NullableProps {\n title: string;\n optional?: string;\n nullable: string | null;\n }\n\n const NullableComponent: React.FC<NullableProps> = ({\n title,\n optional,\n nullable,\n }) => (\n <div>\n <span data-testid=\"title\">{title}</span>\n <span data-testid=\"optional\">{optional ?? \"undefined\"}</span>\n <span data-testid=\"nullable\">{nullable ?? \"null\"}</span>\n </div>\n );\n\n const InteractableComponent = withTamboInteractable(NullableComponent, {\n componentName: \"NullableComponent\",\n description: \"A component with nullable props\",\n });\n\n render(\n <TamboInteractableProvider>\n <InteractableComponent title=\"Test\" nullable={null} />\n </TamboInteractableProvider>,\n );\n\n expect(screen.getByTestId(\"title\")).toHaveTextContent(\"Test\");\n expect(screen.getByTestId(\"optional\")).toHaveTextContent(\"undefined\");\n expect(screen.getByTestId(\"nullable\")).toHaveTextContent(\"null\");\n });\n});\n"]}
@@ -1,6 +1,6 @@
1
1
  export * from "./react-query-hooks";
2
2
  export { useTamboComponentState } from "./use-component-state";
3
- export { useTamboCurrentMessage } from "./use-current-message";
3
+ export { useTamboCurrentComponent, useTamboCurrentMessage, type TamboCurrentComponent, } from "./use-current-message";
4
4
  export { useTamboStreamingProps } from "./use-streaming-props";
5
5
  export * from "./use-suggestions";
6
6
  export { useTamboStreamStatus, type PropStatus, type StreamStatus, } from "./use-tambo-stream-status";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AACA,cAAc,qBAAqB,CAAC;AACpC,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,cAAc,mBAAmB,CAAC;AAClC,OAAO,EACL,oBAAoB,EACpB,KAAK,UAAU,EACf,KAAK,YAAY,GAClB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AACA,cAAc,qBAAqB,CAAC;AACpC,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EACL,wBAAwB,EACxB,sBAAsB,EACtB,KAAK,qBAAqB,GAC3B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,cAAc,mBAAmB,CAAC;AAClC,OAAO,EACL,oBAAoB,EACpB,KAAK,UAAU,EACf,KAAK,YAAY,GAClB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC"}
@@ -14,12 +14,13 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.useTamboVoice = exports.useTamboThreadList = exports.useTamboStreamStatus = exports.useTamboStreamingProps = exports.useTamboCurrentMessage = exports.useTamboComponentState = void 0;
17
+ exports.useTamboVoice = exports.useTamboThreadList = exports.useTamboStreamStatus = exports.useTamboStreamingProps = exports.useTamboCurrentMessage = exports.useTamboCurrentComponent = exports.useTamboComponentState = void 0;
18
18
  // Export all hooks from this directory
19
19
  __exportStar(require("./react-query-hooks"), exports);
20
20
  var use_component_state_1 = require("./use-component-state");
21
21
  Object.defineProperty(exports, "useTamboComponentState", { enumerable: true, get: function () { return use_component_state_1.useTamboComponentState; } });
22
22
  var use_current_message_1 = require("./use-current-message");
23
+ Object.defineProperty(exports, "useTamboCurrentComponent", { enumerable: true, get: function () { return use_current_message_1.useTamboCurrentComponent; } });
23
24
  Object.defineProperty(exports, "useTamboCurrentMessage", { enumerable: true, get: function () { return use_current_message_1.useTamboCurrentMessage; } });
24
25
  var use_streaming_props_1 = require("./use-streaming-props");
25
26
  Object.defineProperty(exports, "useTamboStreamingProps", { enumerable: true, get: function () { return use_streaming_props_1.useTamboStreamingProps; } });
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,uCAAuC;AACvC,sDAAoC;AACpC,6DAA+D;AAAtD,6HAAA,sBAAsB,OAAA;AAC/B,6DAA+D;AAAtD,6HAAA,sBAAsB,OAAA;AAC/B,6DAA+D;AAAtD,6HAAA,sBAAsB,OAAA;AAC/B,oDAAkC;AAClC,qEAImC;AAHjC,+HAAA,oBAAoB,OAAA;AAItB,yDAAyD;AAAhD,uHAAA,kBAAkB,OAAA;AAC3B,qDAAkD;AAAzC,gHAAA,aAAa,OAAA","sourcesContent":["// Export all hooks from this directory\nexport * from \"./react-query-hooks\";\nexport { useTamboComponentState } from \"./use-component-state\";\nexport { useTamboCurrentMessage } from \"./use-current-message\";\nexport { useTamboStreamingProps } from \"./use-streaming-props\";\nexport * from \"./use-suggestions\";\nexport {\n useTamboStreamStatus,\n type PropStatus,\n type StreamStatus,\n} from \"./use-tambo-stream-status\";\nexport { useTamboThreadList } from \"./use-tambo-threads\";\nexport { useTamboVoice } from \"./use-tambo-voice\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,uCAAuC;AACvC,sDAAoC;AACpC,6DAA+D;AAAtD,6HAAA,sBAAsB,OAAA;AAC/B,6DAI+B;AAH7B,+HAAA,wBAAwB,OAAA;AACxB,6HAAA,sBAAsB,OAAA;AAGxB,6DAA+D;AAAtD,6HAAA,sBAAsB,OAAA;AAC/B,oDAAkC;AAClC,qEAImC;AAHjC,+HAAA,oBAAoB,OAAA;AAItB,yDAAyD;AAAhD,uHAAA,kBAAkB,OAAA;AAC3B,qDAAkD;AAAzC,gHAAA,aAAa,OAAA","sourcesContent":["// Export all hooks from this directory\nexport * from \"./react-query-hooks\";\nexport { useTamboComponentState } from \"./use-component-state\";\nexport {\n useTamboCurrentComponent,\n useTamboCurrentMessage,\n type TamboCurrentComponent,\n} from \"./use-current-message\";\nexport { useTamboStreamingProps } from \"./use-streaming-props\";\nexport * from \"./use-suggestions\";\nexport {\n useTamboStreamStatus,\n type PropStatus,\n type StreamStatus,\n} from \"./use-tambo-stream-status\";\nexport { useTamboThreadList } from \"./use-tambo-threads\";\nexport { useTamboVoice } from \"./use-tambo-voice\";\n"]}
@@ -1,27 +1,71 @@
1
- import React, { PropsWithChildren } from "react";
2
- import { TamboThreadMessage } from "../model/generate-component-response";
1
+ import React from "react";
2
+ import { InteractableMetadata, TamboThreadMessage } from "../model/generate-component-response";
3
+ export interface TamboMessageProviderProps {
4
+ children: React.ReactNode;
5
+ message: TamboThreadMessage;
6
+ /** Optional interactable metadata for components wrapped with withInteractable */
7
+ interactableMetadata?: InteractableMetadata;
8
+ }
3
9
  /**
4
- * Wraps all components, so that they can find what message they are in
10
+ * Wraps all components, so that they can find what message they are in.
11
+ * Also supports optional interactable metadata for components wrapped with withInteractable.
5
12
  * @param props - props for the TamboMessageProvider
6
13
  * @param props.children - The children to wrap
7
14
  * @param props.message - The message object
15
+ * @param props.interactableMetadata - Optional interactable component metadata
8
16
  * @returns The wrapped component
9
17
  */
10
- export declare const TamboMessageProvider: React.FC<PropsWithChildren<{
11
- message: TamboThreadMessage;
12
- }>>;
18
+ export declare const TamboMessageProvider: React.FC<TamboMessageProviderProps>;
13
19
  /**
14
20
  * Wraps a component with a TamboMessageProvider - this allows the provider
15
21
  * to be used outside of a TSX file
16
22
  * @param children - The children to wrap
17
23
  * @param message - The message object
24
+ * @param interactableMetadata - Optional interactable metadata
18
25
  * @returns The wrapped component
19
26
  */
20
- export declare function wrapWithTamboMessageProvider(children: React.ReactNode, message: TamboThreadMessage): React.JSX.Element;
27
+ export declare function wrapWithTamboMessageProvider(children: React.ReactNode, message: TamboThreadMessage, interactableMetadata?: InteractableMetadata): React.JSX.Element;
21
28
  /**
22
29
  * Hook used inside a component wrapped with TamboMessageProvider, to get
23
30
  * the current message.
24
31
  * @returns The current message that is used to render the component
25
32
  */
26
33
  export declare const useTamboCurrentMessage: () => TamboThreadMessage;
34
+ /**
35
+ * Component info extracted from the current message and interactable context.
36
+ * Provides a unified interface for accessing component metadata.
37
+ */
38
+ export interface TamboCurrentComponent {
39
+ /** Component name from the message */
40
+ componentName?: string;
41
+ /** Component props from the message */
42
+ props?: Record<string, any>;
43
+ /** Interactable ID (only present for components wrapped with withInteractable) */
44
+ interactableId?: string;
45
+ /** Description (only present for components wrapped with withInteractable) */
46
+ description?: string;
47
+ }
48
+ /**
49
+ * Hook to access the current component information from the message context.
50
+ * Provides a unified interface for both AI-generated and interactable components.
51
+ *
52
+ * **Use this hook when you need component metadata regardless of the context.**
53
+ * @returns Component info including name, props, and interactable metadata if available, or null if used outside TamboMessageProvider
54
+ * @example
55
+ * ```tsx
56
+ * function MyInlineEditor() {
57
+ * const component = useTamboCurrentComponent();
58
+ *
59
+ * if (!component) return null; // Not inside a component
60
+ *
61
+ * return (
62
+ * <div>
63
+ * Editing: {component.componentName}
64
+ * {component.interactableId && <span>ID: {component.interactableId}</span>}
65
+ * </div>
66
+ * );
67
+ * }
68
+ * ```
69
+ */
70
+ export declare const useTamboCurrentComponent: () => TamboCurrentComponent | null;
27
71
  //# sourceMappingURL=use-current-message.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-current-message.d.ts","sourceRoot":"","sources":["../../src/hooks/use-current-message.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAiB,iBAAiB,EAAc,MAAM,OAAO,CAAC;AAC5E,OAAO,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AAI1E;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,EAAE,KAAK,CAAC,EAAE,CACzC,iBAAiB,CAAC;IAAE,OAAO,EAAE,kBAAkB,CAAA;CAAE,CAAC,CAUnD,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,KAAK,CAAC,SAAS,EACzB,OAAO,EAAE,kBAAkB,qBAK5B;AAED;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,0BAQlC,CAAC"}
1
+ {"version":3,"file":"use-current-message.d.ts","sourceRoot":"","sources":["../../src/hooks/use-current-message.tsx"],"names":[],"mappings":"AACA,OAAO,KAAoC,MAAM,OAAO,CAAC;AACzD,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EACnB,MAAM,sCAAsC,CAAC;AAI9C,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,OAAO,EAAE,kBAAkB,CAAC;IAC5B,kFAAkF;IAClF,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;CAC7C;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,EAAE,KAAK,CAAC,EAAE,CAAC,yBAAyB,CAkBpE,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,KAAK,CAAC,SAAS,EACzB,OAAO,EAAE,kBAAkB,EAC3B,oBAAoB,CAAC,EAAE,oBAAoB,qBAU5C;AAED;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,0BAQlC,CAAC;AAEF;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,sCAAsC;IACtC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,uCAAuC;IACvC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,kFAAkF;IAClF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,8EAA8E;IAC9E,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,wBAAwB,QAAO,qBAAqB,GAAG,IAgBnE,CAAC"}