@tambo-ai/react 0.73.1 → 0.74.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 (402) hide show
  1. package/README.md +12 -12
  2. package/dist/hooks/use-component-state.d.ts +1 -1
  3. package/dist/hooks/use-component-state.js.map +1 -1
  4. package/dist/hooks/use-streaming-props.d.ts +1 -1
  5. package/dist/hooks/use-streaming-props.js +1 -1
  6. package/dist/hooks/use-streaming-props.js.map +1 -1
  7. package/dist/hooks/use-tambo-stream-status.d.ts +1 -1
  8. package/dist/hooks/use-tambo-stream-status.js +1 -1
  9. package/dist/hooks/use-tambo-stream-status.js.map +1 -1
  10. package/dist/providers/tambo-interactable-provider-partial-updates.test.js +3 -3
  11. package/dist/providers/tambo-interactable-provider-partial-updates.test.js.map +1 -1
  12. package/dist/providers/tambo-interactable-provider.js +2 -2
  13. package/dist/providers/tambo-interactable-provider.js.map +1 -1
  14. package/dist/providers/tambo-interactable-provider.test.js +3 -3
  15. package/dist/providers/tambo-interactable-provider.test.js.map +1 -1
  16. package/dist/providers/tambo-thread-input-provider.d.ts.map +1 -1
  17. package/dist/providers/tambo-thread-input-provider.js +1 -0
  18. package/dist/providers/tambo-thread-input-provider.js.map +1 -1
  19. package/dist/v1/__tests__/v1-interactables.test.d.ts +2 -0
  20. package/dist/v1/__tests__/v1-interactables.test.d.ts.map +1 -0
  21. package/dist/v1/__tests__/v1-interactables.test.js +135 -0
  22. package/dist/v1/__tests__/v1-interactables.test.js.map +1 -0
  23. package/dist/v1/components/v1-component-renderer.d.ts +48 -0
  24. package/dist/v1/components/v1-component-renderer.d.ts.map +1 -0
  25. package/dist/v1/components/v1-component-renderer.js +137 -0
  26. package/dist/v1/components/v1-component-renderer.js.map +1 -0
  27. package/dist/v1/components/v1-component-renderer.test.d.ts +2 -0
  28. package/dist/v1/components/v1-component-renderer.test.d.ts.map +1 -0
  29. package/dist/v1/components/v1-component-renderer.test.js +270 -0
  30. package/dist/v1/components/v1-component-renderer.test.js.map +1 -0
  31. package/dist/v1/hooks/use-tambo-v1-component-state.d.ts.map +1 -1
  32. package/dist/v1/hooks/use-tambo-v1-component-state.js +2 -25
  33. package/dist/v1/hooks/use-tambo-v1-component-state.js.map +1 -1
  34. package/dist/v1/hooks/use-tambo-v1-component-state.test.js +2 -1
  35. package/dist/v1/hooks/use-tambo-v1-component-state.test.js.map +1 -1
  36. package/dist/v1/hooks/use-tambo-v1-messages.test.js +25 -1
  37. package/dist/v1/hooks/use-tambo-v1-messages.test.js.map +1 -1
  38. package/dist/v1/hooks/use-tambo-v1-send-message.d.ts +18 -0
  39. package/dist/v1/hooks/use-tambo-v1-send-message.d.ts.map +1 -1
  40. package/dist/v1/hooks/use-tambo-v1-send-message.js +204 -17
  41. package/dist/v1/hooks/use-tambo-v1-send-message.js.map +1 -1
  42. package/dist/v1/hooks/use-tambo-v1-send-message.test.js +261 -7
  43. package/dist/v1/hooks/use-tambo-v1-send-message.test.js.map +1 -1
  44. package/dist/v1/hooks/use-tambo-v1-stream-status.d.ts +90 -0
  45. package/dist/v1/hooks/use-tambo-v1-stream-status.d.ts.map +1 -0
  46. package/dist/v1/hooks/use-tambo-v1-stream-status.js +179 -0
  47. package/dist/v1/hooks/use-tambo-v1-stream-status.js.map +1 -0
  48. package/dist/v1/hooks/use-tambo-v1-stream-status.test.d.ts +2 -0
  49. package/dist/v1/hooks/use-tambo-v1-stream-status.test.d.ts.map +1 -0
  50. package/dist/v1/hooks/use-tambo-v1-stream-status.test.js +371 -0
  51. package/dist/v1/hooks/use-tambo-v1-stream-status.test.js.map +1 -0
  52. package/dist/v1/hooks/use-tambo-v1-suggestions.d.ts +78 -54
  53. package/dist/v1/hooks/use-tambo-v1-suggestions.d.ts.map +1 -1
  54. package/dist/v1/hooks/use-tambo-v1-suggestions.js +153 -87
  55. package/dist/v1/hooks/use-tambo-v1-suggestions.js.map +1 -1
  56. package/dist/v1/hooks/use-tambo-v1-suggestions.test.js +213 -134
  57. package/dist/v1/hooks/use-tambo-v1-suggestions.test.js.map +1 -1
  58. package/dist/v1/hooks/use-tambo-v1-thread-input.test.js +148 -13
  59. package/dist/v1/hooks/use-tambo-v1-thread-input.test.js.map +1 -1
  60. package/dist/v1/hooks/use-tambo-v1-thread-list.d.ts +8 -21
  61. package/dist/v1/hooks/use-tambo-v1-thread-list.d.ts.map +1 -1
  62. package/dist/v1/hooks/use-tambo-v1-thread-list.js +11 -10
  63. package/dist/v1/hooks/use-tambo-v1-thread-list.js.map +1 -1
  64. package/dist/v1/hooks/use-tambo-v1-thread-list.test.js +37 -2
  65. package/dist/v1/hooks/use-tambo-v1-thread-list.test.js.map +1 -1
  66. package/dist/v1/hooks/use-tambo-v1-thread.d.ts +1 -1
  67. package/dist/v1/hooks/use-tambo-v1-thread.d.ts.map +1 -1
  68. package/dist/v1/hooks/use-tambo-v1-thread.js +2 -7
  69. package/dist/v1/hooks/use-tambo-v1-thread.js.map +1 -1
  70. package/dist/v1/hooks/use-tambo-v1-thread.test.js +2 -0
  71. package/dist/v1/hooks/use-tambo-v1-thread.test.js.map +1 -1
  72. package/dist/v1/hooks/use-tambo-v1.d.ts +12 -28
  73. package/dist/v1/hooks/use-tambo-v1.d.ts.map +1 -1
  74. package/dist/v1/hooks/use-tambo-v1.js +164 -31
  75. package/dist/v1/hooks/use-tambo-v1.js.map +1 -1
  76. package/dist/v1/hooks/use-tambo-v1.test.js +891 -18
  77. package/dist/v1/hooks/use-tambo-v1.test.js.map +1 -1
  78. package/dist/v1/index.d.ts +7 -1
  79. package/dist/v1/index.d.ts.map +1 -1
  80. package/dist/v1/index.js +18 -1
  81. package/dist/v1/index.js.map +1 -1
  82. package/dist/v1/providers/tambo-v1-provider.d.ts +16 -6
  83. package/dist/v1/providers/tambo-v1-provider.d.ts.map +1 -1
  84. package/dist/v1/providers/tambo-v1-provider.js +14 -19
  85. package/dist/v1/providers/tambo-v1-provider.js.map +1 -1
  86. package/dist/v1/providers/tambo-v1-provider.test.js +34 -20
  87. package/dist/v1/providers/tambo-v1-provider.test.js.map +1 -1
  88. package/dist/v1/providers/tambo-v1-stream-context.d.ts +3 -3
  89. package/dist/v1/providers/tambo-v1-stream-context.d.ts.map +1 -1
  90. package/dist/v1/providers/tambo-v1-stream-context.js +60 -12
  91. package/dist/v1/providers/tambo-v1-stream-context.js.map +1 -1
  92. package/dist/v1/providers/tambo-v1-stream-context.test.js +49 -20
  93. package/dist/v1/providers/tambo-v1-stream-context.test.js.map +1 -1
  94. package/dist/v1/providers/tambo-v1-stub-provider.d.ts.map +1 -1
  95. package/dist/v1/providers/tambo-v1-stub-provider.js +2 -0
  96. package/dist/v1/providers/tambo-v1-stub-provider.js.map +1 -1
  97. package/dist/v1/providers/tambo-v1-stub-provider.test.js +7 -6
  98. package/dist/v1/providers/tambo-v1-stub-provider.test.js.map +1 -1
  99. package/dist/v1/providers/tambo-v1-thread-input-provider.d.ts +1 -6
  100. package/dist/v1/providers/tambo-v1-thread-input-provider.d.ts.map +1 -1
  101. package/dist/v1/providers/tambo-v1-thread-input-provider.js +14 -12
  102. package/dist/v1/providers/tambo-v1-thread-input-provider.js.map +1 -1
  103. package/dist/v1/types/event.d.ts +9 -1
  104. package/dist/v1/types/event.d.ts.map +1 -1
  105. package/dist/v1/types/event.js.map +1 -1
  106. package/dist/v1/types/event.test.js +5 -1
  107. package/dist/v1/types/event.test.js.map +1 -1
  108. package/dist/v1/types/message.d.ts +65 -7
  109. package/dist/v1/types/message.d.ts.map +1 -1
  110. package/dist/v1/types/message.js.map +1 -1
  111. package/dist/v1/types/thread.d.ts +4 -0
  112. package/dist/v1/types/thread.d.ts.map +1 -1
  113. package/dist/v1/types/thread.js.map +1 -1
  114. package/dist/v1/utils/event-accumulator.d.ts +40 -4
  115. package/dist/v1/utils/event-accumulator.d.ts.map +1 -1
  116. package/dist/v1/utils/event-accumulator.js +444 -35
  117. package/dist/v1/utils/event-accumulator.js.map +1 -1
  118. package/dist/v1/utils/event-accumulator.test.js +1041 -28
  119. package/dist/v1/utils/event-accumulator.test.js.map +1 -1
  120. package/dist/v1/utils/registry-conversion.d.ts +9 -9
  121. package/dist/v1/utils/registry-conversion.d.ts.map +1 -1
  122. package/dist/v1/utils/registry-conversion.js +10 -11
  123. package/dist/v1/utils/registry-conversion.js.map +1 -1
  124. package/dist/v1/utils/registry-conversion.test.js +39 -11
  125. package/dist/v1/utils/registry-conversion.test.js.map +1 -1
  126. package/dist/v1/utils/thread-utils.d.ts +16 -0
  127. package/dist/v1/utils/thread-utils.d.ts.map +1 -0
  128. package/dist/v1/utils/thread-utils.js +34 -0
  129. package/dist/v1/utils/thread-utils.js.map +1 -0
  130. package/dist/v1/utils/tool-executor.d.ts.map +1 -1
  131. package/dist/v1/utils/tool-executor.js +2 -0
  132. package/dist/v1/utils/tool-executor.js.map +1 -1
  133. package/dist/v1/utils/tool-executor.test.js +5 -0
  134. package/dist/v1/utils/tool-executor.test.js.map +1 -1
  135. package/esm/context-helpers/context-helpers-provider.test.js +2 -2
  136. package/esm/context-helpers/context-helpers.test.js +1 -1
  137. package/esm/context-helpers/current-interactables-context-helper.d.ts +1 -1
  138. package/esm/context-helpers/current-page-context-helper.d.ts +1 -1
  139. package/esm/context-helpers/current-time-context-helper.d.ts +1 -1
  140. package/esm/context-helpers/index.d.ts +4 -4
  141. package/esm/context-helpers/index.js +4 -4
  142. package/esm/hoc/with-tambo-interactable.d.ts +1 -1
  143. package/esm/hoc/with-tambo-interactable.js +2 -2
  144. package/esm/hoc/with-tambo-interactable.test.js +3 -3
  145. package/esm/hooks/index.d.ts +8 -8
  146. package/esm/hooks/index.js +8 -8
  147. package/esm/hooks/react-query-hooks.js +1 -1
  148. package/esm/hooks/use-component-state.d.ts +1 -1
  149. package/esm/hooks/use-component-state.js +3 -3
  150. package/esm/hooks/use-component-state.js.map +1 -1
  151. package/esm/hooks/use-component-state.test.js +5 -5
  152. package/esm/hooks/use-current-message.d.ts +1 -1
  153. package/esm/hooks/use-current-message.test.js +1 -1
  154. package/esm/hooks/use-message-images.test.js +1 -1
  155. package/esm/hooks/use-streaming-props.d.ts +1 -1
  156. package/esm/hooks/use-streaming-props.js +1 -1
  157. package/esm/hooks/use-streaming-props.js.map +1 -1
  158. package/esm/hooks/use-suggestions.d.ts +2 -2
  159. package/esm/hooks/use-suggestions.js +10 -10
  160. package/esm/hooks/use-suggestions.test.js +7 -7
  161. package/esm/hooks/use-tambo-stream-status.d.ts +1 -1
  162. package/esm/hooks/use-tambo-stream-status.js +4 -4
  163. package/esm/hooks/use-tambo-stream-status.js.map +1 -1
  164. package/esm/hooks/use-tambo-stream-status.test.js +4 -4
  165. package/esm/hooks/use-tambo-threads.js +3 -3
  166. package/esm/hooks/use-tambo-threads.test.js +3 -3
  167. package/esm/hooks/use-tambo-voice.js +2 -2
  168. package/esm/hooks/use-tambo-voice.test.js +3 -3
  169. package/esm/index.d.ts +22 -22
  170. package/esm/index.js +15 -15
  171. package/esm/mcp/elicitation.d.ts +1 -1
  172. package/esm/mcp/elicitation.test.js +1 -1
  173. package/esm/mcp/index.d.ts +7 -7
  174. package/esm/mcp/index.js +3 -3
  175. package/esm/mcp/mcp-client.d.ts +1 -1
  176. package/esm/mcp/mcp-client.js +1 -1
  177. package/esm/mcp/mcp-client.test.js +1 -1
  178. package/esm/mcp/mcp-hooks.d.ts +1 -1
  179. package/esm/mcp/mcp-hooks.js +4 -4
  180. package/esm/mcp/mcp-hooks.test.js +6 -6
  181. package/esm/mcp/tambo-mcp-provider.d.ts +4 -4
  182. package/esm/mcp/tambo-mcp-provider.js +7 -7
  183. package/esm/mcp/tambo-mcp-provider.test.js +5 -5
  184. package/esm/mcp/use-mcp-servers.test.js +4 -4
  185. package/esm/model/generate-component-response.d.ts +1 -1
  186. package/esm/model/tambo-interactable.d.ts +1 -1
  187. package/esm/model/tambo-thread.d.ts +1 -1
  188. package/esm/providers/__tests__/thread-input-resource-resolution.test.js +3 -3
  189. package/esm/providers/hooks/use-tambo-session-token.test.js +1 -1
  190. package/esm/providers/index.d.ts +12 -12
  191. package/esm/providers/index.js +10 -10
  192. package/esm/providers/tambo-client-provider.js +1 -1
  193. package/esm/providers/tambo-client-provider.test.js +2 -2
  194. package/esm/providers/tambo-component-provider.d.ts +1 -1
  195. package/esm/providers/tambo-component-provider.js +2 -2
  196. package/esm/providers/tambo-context-attachment-provider.js +1 -1
  197. package/esm/providers/tambo-context-attachment-provider.test.js +2 -2
  198. package/esm/providers/tambo-context-helpers-provider.d.ts +1 -1
  199. package/esm/providers/tambo-context-helpers-provider.js +1 -1
  200. package/esm/providers/tambo-context-helpers-provider.test.js +2 -2
  201. package/esm/providers/tambo-interactable-provider-partial-updates.test.js +4 -4
  202. package/esm/providers/tambo-interactable-provider-partial-updates.test.js.map +1 -1
  203. package/esm/providers/tambo-interactable-provider.d.ts +5 -5
  204. package/esm/providers/tambo-interactable-provider.js +6 -6
  205. package/esm/providers/tambo-interactable-provider.js.map +1 -1
  206. package/esm/providers/tambo-interactable-provider.test.js +4 -4
  207. package/esm/providers/tambo-interactable-provider.test.js.map +1 -1
  208. package/esm/providers/tambo-interactables-additional-context-edge-cases.test.js +4 -4
  209. package/esm/providers/tambo-interactables-additional-context.test.js +4 -4
  210. package/esm/providers/tambo-mcp-token-provider.js +2 -2
  211. package/esm/providers/tambo-prop-stream-provider/index.d.ts +8 -8
  212. package/esm/providers/tambo-prop-stream-provider/index.js +9 -9
  213. package/esm/providers/tambo-prop-stream-provider/pending.d.ts +1 -1
  214. package/esm/providers/tambo-prop-stream-provider/pending.js +2 -2
  215. package/esm/providers/tambo-prop-stream-provider/provider.d.ts +1 -1
  216. package/esm/providers/tambo-prop-stream-provider/provider.js +2 -2
  217. package/esm/providers/tambo-prop-stream-provider/streaming.d.ts +1 -1
  218. package/esm/providers/tambo-prop-stream-provider/streaming.js +2 -2
  219. package/esm/providers/tambo-prop-stream-provider/success.d.ts +1 -1
  220. package/esm/providers/tambo-prop-stream-provider/success.js +2 -2
  221. package/esm/providers/tambo-prop-stream-provider/types.d.ts +1 -1
  222. package/esm/providers/tambo-prop-stream-provider.test.js +4 -4
  223. package/esm/providers/tambo-provider.d.ts +7 -7
  224. package/esm/providers/tambo-provider.js +10 -10
  225. package/esm/providers/tambo-registry-provider.d.ts +3 -3
  226. package/esm/providers/tambo-registry-provider.js +3 -3
  227. package/esm/providers/tambo-registry-provider.test.js +2 -2
  228. package/esm/providers/tambo-registry-schema-compat.test.js +2 -2
  229. package/esm/providers/tambo-stubs.d.ts +4 -4
  230. package/esm/providers/tambo-stubs.js +9 -9
  231. package/esm/providers/tambo-stubs.test.js +2 -2
  232. package/esm/providers/tambo-thread-input-provider.d.ts +2 -2
  233. package/esm/providers/tambo-thread-input-provider.d.ts.map +1 -1
  234. package/esm/providers/tambo-thread-input-provider.js +11 -10
  235. package/esm/providers/tambo-thread-input-provider.js.map +1 -1
  236. package/esm/providers/tambo-thread-provider-initial-messages.test.js +6 -6
  237. package/esm/providers/tambo-thread-provider.d.ts +2 -2
  238. package/esm/providers/tambo-thread-provider.js +8 -8
  239. package/esm/providers/tambo-thread-provider.test.js +7 -7
  240. package/esm/schema/index.d.ts +4 -4
  241. package/esm/schema/index.js +4 -4
  242. package/esm/schema/json-schema.test.js +1 -1
  243. package/esm/schema/schema.d.ts +1 -1
  244. package/esm/schema/schema.js +2 -2
  245. package/esm/schema/schema.test.js +3 -3
  246. package/esm/schema/standard-schema.test.js +1 -1
  247. package/esm/schema/validate.js +2 -2
  248. package/esm/schema/validate.test.js +1 -1
  249. package/esm/testing/tools.d.ts +3 -3
  250. package/esm/testing/tools.js +2 -2
  251. package/esm/util/content-parts.test.js +1 -1
  252. package/esm/util/generate-component.d.ts +2 -2
  253. package/esm/util/generate-component.js +4 -4
  254. package/esm/util/generate-component.test.js +2 -2
  255. package/esm/util/is-promise.test.js +1 -1
  256. package/esm/util/mcp-server-utils.d.ts +1 -1
  257. package/esm/util/mcp-server-utils.js +1 -1
  258. package/esm/util/mcp-server-utils.test.js +2 -2
  259. package/esm/util/message-builder.d.ts +1 -1
  260. package/esm/util/message-builder.test.js +1 -1
  261. package/esm/util/query-utils.test.js +1 -1
  262. package/esm/util/registry-validators.d.ts +1 -1
  263. package/esm/util/registry-validators.js +2 -2
  264. package/esm/util/registry-validators.test.js +1 -1
  265. package/esm/util/registry.d.ts +1 -1
  266. package/esm/util/registry.js +1 -1
  267. package/esm/util/registry.test.js +2 -2
  268. package/esm/util/resource-content-resolver.d.ts +2 -2
  269. package/esm/util/resource-content-resolver.js +1 -1
  270. package/esm/util/resource-content-resolver.test.js +3 -3
  271. package/esm/util/resource-validators.d.ts +1 -1
  272. package/esm/util/resource-validators.test.js +1 -1
  273. package/esm/util/tool-caller.d.ts +1 -1
  274. package/esm/util/tool-caller.js +1 -1
  275. package/esm/util/validate-component-name.test.js +1 -1
  276. package/esm/v1/__tests__/v1-interactables.test.d.ts +2 -0
  277. package/esm/v1/__tests__/v1-interactables.test.d.ts.map +1 -0
  278. package/esm/v1/__tests__/v1-interactables.test.js +130 -0
  279. package/esm/v1/__tests__/v1-interactables.test.js.map +1 -0
  280. package/esm/v1/components/v1-component-renderer.d.ts +48 -0
  281. package/esm/v1/components/v1-component-renderer.d.ts.map +1 -0
  282. package/esm/v1/components/v1-component-renderer.js +100 -0
  283. package/esm/v1/components/v1-component-renderer.js.map +1 -0
  284. package/esm/v1/components/v1-component-renderer.test.d.ts +2 -0
  285. package/esm/v1/components/v1-component-renderer.test.d.ts.map +1 -0
  286. package/esm/v1/components/v1-component-renderer.test.js +265 -0
  287. package/esm/v1/components/v1-component-renderer.test.js.map +1 -0
  288. package/esm/v1/hooks/use-tambo-v1-component-state.d.ts.map +1 -1
  289. package/esm/v1/hooks/use-tambo-v1-component-state.js +4 -27
  290. package/esm/v1/hooks/use-tambo-v1-component-state.js.map +1 -1
  291. package/esm/v1/hooks/use-tambo-v1-component-state.test.js +6 -5
  292. package/esm/v1/hooks/use-tambo-v1-component-state.test.js.map +1 -1
  293. package/esm/v1/hooks/use-tambo-v1-messages.d.ts +1 -1
  294. package/esm/v1/hooks/use-tambo-v1-messages.js +1 -1
  295. package/esm/v1/hooks/use-tambo-v1-messages.test.js +27 -3
  296. package/esm/v1/hooks/use-tambo-v1-messages.test.js.map +1 -1
  297. package/esm/v1/hooks/use-tambo-v1-send-message.d.ts +20 -2
  298. package/esm/v1/hooks/use-tambo-v1-send-message.d.ts.map +1 -1
  299. package/esm/v1/hooks/use-tambo-v1-send-message.js +213 -26
  300. package/esm/v1/hooks/use-tambo-v1-send-message.js.map +1 -1
  301. package/esm/v1/hooks/use-tambo-v1-send-message.test.js +266 -12
  302. package/esm/v1/hooks/use-tambo-v1-send-message.test.js.map +1 -1
  303. package/esm/v1/hooks/use-tambo-v1-stream-status.d.ts +90 -0
  304. package/esm/v1/hooks/use-tambo-v1-stream-status.d.ts.map +1 -0
  305. package/esm/v1/hooks/use-tambo-v1-stream-status.js +176 -0
  306. package/esm/v1/hooks/use-tambo-v1-stream-status.js.map +1 -0
  307. package/esm/v1/hooks/use-tambo-v1-stream-status.test.d.ts +2 -0
  308. package/esm/v1/hooks/use-tambo-v1-stream-status.test.d.ts.map +1 -0
  309. package/esm/v1/hooks/use-tambo-v1-stream-status.test.js +369 -0
  310. package/esm/v1/hooks/use-tambo-v1-stream-status.test.js.map +1 -0
  311. package/esm/v1/hooks/use-tambo-v1-suggestions.d.ts +78 -54
  312. package/esm/v1/hooks/use-tambo-v1-suggestions.d.ts.map +1 -1
  313. package/esm/v1/hooks/use-tambo-v1-suggestions.js +157 -91
  314. package/esm/v1/hooks/use-tambo-v1-suggestions.js.map +1 -1
  315. package/esm/v1/hooks/use-tambo-v1-suggestions.test.js +218 -139
  316. package/esm/v1/hooks/use-tambo-v1-suggestions.test.js.map +1 -1
  317. package/esm/v1/hooks/use-tambo-v1-thread-input.d.ts +1 -1
  318. package/esm/v1/hooks/use-tambo-v1-thread-input.js +1 -1
  319. package/esm/v1/hooks/use-tambo-v1-thread-input.test.js +151 -16
  320. package/esm/v1/hooks/use-tambo-v1-thread-input.test.js.map +1 -1
  321. package/esm/v1/hooks/use-tambo-v1-thread-list.d.ts +8 -21
  322. package/esm/v1/hooks/use-tambo-v1-thread-list.d.ts.map +1 -1
  323. package/esm/v1/hooks/use-tambo-v1-thread-list.js +12 -11
  324. package/esm/v1/hooks/use-tambo-v1-thread-list.js.map +1 -1
  325. package/esm/v1/hooks/use-tambo-v1-thread-list.test.js +39 -4
  326. package/esm/v1/hooks/use-tambo-v1-thread-list.test.js.map +1 -1
  327. package/esm/v1/hooks/use-tambo-v1-thread.d.ts +1 -1
  328. package/esm/v1/hooks/use-tambo-v1-thread.d.ts.map +1 -1
  329. package/esm/v1/hooks/use-tambo-v1-thread.js +3 -8
  330. package/esm/v1/hooks/use-tambo-v1-thread.js.map +1 -1
  331. package/esm/v1/hooks/use-tambo-v1-thread.test.js +4 -2
  332. package/esm/v1/hooks/use-tambo-v1-thread.test.js.map +1 -1
  333. package/esm/v1/hooks/use-tambo-v1.d.ts +15 -31
  334. package/esm/v1/hooks/use-tambo-v1.d.ts.map +1 -1
  335. package/esm/v1/hooks/use-tambo-v1.js +134 -34
  336. package/esm/v1/hooks/use-tambo-v1.js.map +1 -1
  337. package/esm/v1/hooks/use-tambo-v1.test.js +862 -19
  338. package/esm/v1/hooks/use-tambo-v1.test.js.map +1 -1
  339. package/esm/v1/index.d.ts +28 -22
  340. package/esm/v1/index.d.ts.map +1 -1
  341. package/esm/v1/index.js +30 -18
  342. package/esm/v1/index.js.map +1 -1
  343. package/esm/v1/providers/tambo-v1-provider.d.ts +21 -11
  344. package/esm/v1/providers/tambo-v1-provider.d.ts.map +1 -1
  345. package/esm/v1/providers/tambo-v1-provider.js +20 -25
  346. package/esm/v1/providers/tambo-v1-provider.js.map +1 -1
  347. package/esm/v1/providers/tambo-v1-provider.test.js +40 -26
  348. package/esm/v1/providers/tambo-v1-provider.test.js.map +1 -1
  349. package/esm/v1/providers/tambo-v1-stream-context.d.ts +4 -4
  350. package/esm/v1/providers/tambo-v1-stream-context.d.ts.map +1 -1
  351. package/esm/v1/providers/tambo-v1-stream-context.js +62 -14
  352. package/esm/v1/providers/tambo-v1-stream-context.js.map +1 -1
  353. package/esm/v1/providers/tambo-v1-stream-context.test.js +50 -21
  354. package/esm/v1/providers/tambo-v1-stream-context.test.js.map +1 -1
  355. package/esm/v1/providers/tambo-v1-stub-provider.d.ts +3 -3
  356. package/esm/v1/providers/tambo-v1-stub-provider.d.ts.map +1 -1
  357. package/esm/v1/providers/tambo-v1-stub-provider.js +7 -5
  358. package/esm/v1/providers/tambo-v1-stub-provider.js.map +1 -1
  359. package/esm/v1/providers/tambo-v1-stub-provider.test.js +12 -11
  360. package/esm/v1/providers/tambo-v1-stub-provider.test.js.map +1 -1
  361. package/esm/v1/providers/tambo-v1-thread-input-provider.d.ts +3 -8
  362. package/esm/v1/providers/tambo-v1-thread-input-provider.d.ts.map +1 -1
  363. package/esm/v1/providers/tambo-v1-thread-input-provider.js +18 -16
  364. package/esm/v1/providers/tambo-v1-thread-input-provider.js.map +1 -1
  365. package/esm/v1/types/event.d.ts +9 -1
  366. package/esm/v1/types/event.d.ts.map +1 -1
  367. package/esm/v1/types/event.js.map +1 -1
  368. package/esm/v1/types/event.test.js +6 -2
  369. package/esm/v1/types/event.test.js.map +1 -1
  370. package/esm/v1/types/message.d.ts +65 -7
  371. package/esm/v1/types/message.d.ts.map +1 -1
  372. package/esm/v1/types/message.js.map +1 -1
  373. package/esm/v1/types/thread.d.ts +5 -1
  374. package/esm/v1/types/thread.d.ts.map +1 -1
  375. package/esm/v1/types/thread.js.map +1 -1
  376. package/esm/v1/utils/component-renderer.test.js +1 -1
  377. package/esm/v1/utils/event-accumulator.d.ts +41 -5
  378. package/esm/v1/utils/event-accumulator.d.ts.map +1 -1
  379. package/esm/v1/utils/event-accumulator.js +444 -36
  380. package/esm/v1/utils/event-accumulator.js.map +1 -1
  381. package/esm/v1/utils/event-accumulator.test.js +1042 -29
  382. package/esm/v1/utils/event-accumulator.test.js.map +1 -1
  383. package/esm/v1/utils/json-patch.test.js +1 -1
  384. package/esm/v1/utils/registry-conversion.d.ts +9 -9
  385. package/esm/v1/utils/registry-conversion.d.ts.map +1 -1
  386. package/esm/v1/utils/registry-conversion.js +11 -12
  387. package/esm/v1/utils/registry-conversion.js.map +1 -1
  388. package/esm/v1/utils/registry-conversion.test.js +40 -12
  389. package/esm/v1/utils/registry-conversion.test.js.map +1 -1
  390. package/esm/v1/utils/stream-handler.test.js +1 -1
  391. package/esm/v1/utils/thread-utils.d.ts +16 -0
  392. package/esm/v1/utils/thread-utils.d.ts.map +1 -0
  393. package/esm/v1/utils/thread-utils.js +31 -0
  394. package/esm/v1/utils/thread-utils.js.map +1 -0
  395. package/esm/v1/utils/tool-call-tracker.d.ts +1 -1
  396. package/esm/v1/utils/tool-executor.d.ts +1 -1
  397. package/esm/v1/utils/tool-executor.d.ts.map +1 -1
  398. package/esm/v1/utils/tool-executor.js +2 -0
  399. package/esm/v1/utils/tool-executor.js.map +1 -1
  400. package/esm/v1/utils/tool-executor.test.js +6 -1
  401. package/esm/v1/utils/tool-executor.test.js.map +1 -1
  402. package/package.json +11 -10
@@ -1,8 +1,8 @@
1
1
  import * as z3 from "zod/v3";
2
2
  import * as z4 from "zod/v4";
3
- import { looksLikeJSONSchema } from "./json-schema";
4
- import { getParametersFromToolSchema, safeSchemaToJsonSchema, schemaToJsonSchema, } from "./schema";
5
- import { isStandardSchema } from "./standard-schema";
3
+ import { looksLikeJSONSchema } from "./json-schema.js";
4
+ import { getParametersFromToolSchema, safeSchemaToJsonSchema, schemaToJsonSchema, } from "./schema.js";
5
+ import { isStandardSchema } from "./standard-schema.js";
6
6
  describe("schema utilities", () => {
7
7
  describe("looksLikeJSONSchema", () => {
8
8
  it("returns true for a basic JSON Schema object", () => {
@@ -1,6 +1,6 @@
1
1
  import * as z3 from "zod/v3";
2
2
  import * as z4 from "zod/v4";
3
- import { isStandardSchema } from "./standard-schema";
3
+ import { isStandardSchema } from "./standard-schema.js";
4
4
  describe("isStandardSchema", () => {
5
5
  describe("returns true for valid Standard Schema implementations", () => {
6
6
  it("recognizes Zod 4 object schema", () => {
@@ -1,5 +1,5 @@
1
- import { schemaToJsonSchema } from "./schema";
2
- import { isStandardSchema } from "./standard-schema";
1
+ import { schemaToJsonSchema } from "./schema.js";
2
+ import { isStandardSchema } from "./standard-schema.js";
3
3
  /*
4
4
  * Check if a JSON Schema represents a record type (map with dynamic keys).
5
5
  *
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod/v4";
2
- import { assertNoRecordSchema } from "./validate";
2
+ import { assertNoRecordSchema } from "./validate.js";
3
3
  describe("assertNoRecordSchema", () => {
4
4
  describe("falsy inputs", () => {
5
5
  it("should return early for null", () => {
@@ -1,4 +1,4 @@
1
- import { TamboComponent, TamboTool } from "../providers";
1
+ import { TamboComponent, TamboTool } from "../providers/index.js";
2
2
  /**
3
3
  * Serializes the registry for testing purposes.
4
4
  * Converts Standard Schema validators to JSON Schema format.
@@ -8,12 +8,12 @@ import { TamboComponent, TamboTool } from "../providers";
8
8
  */
9
9
  export declare function serializeRegistry(mockRegistry: TamboComponent[]): {
10
10
  props: import("json-schema").JSONSchema7 | undefined;
11
- contextTools: import("..").ComponentContextToolMetadata[] | undefined;
11
+ contextTools: import("../index.js").ComponentContextToolMetadata[] | undefined;
12
12
  name: string;
13
13
  description: string;
14
14
  propsDefinition?: any;
15
15
  loadingComponent?: import("react").ComponentType<any>;
16
- annotations?: import("..").ToolAnnotations;
16
+ annotations?: import("../index.js").ToolAnnotations;
17
17
  }[];
18
18
  interface CreateMockToolOptions {
19
19
  inputSchema: TamboTool["inputSchema"];
@@ -1,5 +1,5 @@
1
- import { isStandardSchema, safeSchemaToJsonSchema } from "../schema";
2
- import { mapTamboToolToContextTool } from "../util/registry";
1
+ import { isStandardSchema, safeSchemaToJsonSchema } from "../schema/index.js";
2
+ import { mapTamboToolToContextTool } from "../util/registry.js";
3
3
  /**
4
4
  * Serializes the registry for testing purposes.
5
5
  * Converts Standard Schema validators to JSON Schema format.
@@ -1,4 +1,4 @@
1
- import { isContentPartArray, isContentPart, toText } from "./content-parts";
1
+ import { isContentPartArray, isContentPart, toText } from "./content-parts.js";
2
2
  describe("content-parts type guards", () => {
3
3
  it("returns true for a valid text content part array", () => {
4
4
  const parts = [{ type: "text", text: "hello" }];
@@ -1,6 +1,6 @@
1
1
  import TamboAI from "@tambo-ai/typescript-sdk";
2
- import { ComponentRegistry } from "../model/component-metadata";
3
- import { TamboThreadMessage } from "../model/generate-component-response";
2
+ import { ComponentRegistry } from "../model/component-metadata.js";
3
+ import { TamboThreadMessage } from "../model/generate-component-response.js";
4
4
  /**
5
5
  * Generate a message that has a component rendered into it, if the message
6
6
  * came with one.
@@ -1,9 +1,9 @@
1
1
  import { parse } from "partial-json";
2
2
  import React from "react";
3
- import { wrapWithTamboMessageProvider } from "../hooks/use-current-message";
4
- import { isStandardSchema } from "../schema";
5
- import { isPromise } from "../util/is-promise";
6
- import { getComponentFromRegistry } from "../util/registry";
3
+ import { wrapWithTamboMessageProvider } from "../hooks/use-current-message.js";
4
+ import { isStandardSchema } from "../schema/index.js";
5
+ import { isPromise } from "../util/is-promise.js";
6
+ import { getComponentFromRegistry } from "../util/registry.js";
7
7
  /**
8
8
  * Generate a message that has a component rendered into it, if the message
9
9
  * came with one.
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
- import * as useCurrentMessage from "../hooks/use-current-message";
3
- import { renderComponentIntoMessage } from "./generate-component";
2
+ import * as useCurrentMessage from "../hooks/use-current-message.js";
3
+ import { renderComponentIntoMessage } from "./generate-component.js";
4
4
  // Track calls to wrapWithTamboMessageProvider
5
5
  let wrapWithTamboMessageProviderSpy;
6
6
  beforeEach(() => {
@@ -1,4 +1,4 @@
1
- import { isPromise } from "../util/is-promise";
1
+ import { isPromise } from "../util/is-promise.js";
2
2
  describe("isPromise", () => {
3
3
  it("should return true for real Promise instances", () => {
4
4
  expect(isPromise(Promise.resolve(1))).toBe(true);
@@ -1,4 +1,4 @@
1
- import type { McpServerInfo, NormalizedMcpServerInfo } from "../model/mcp-server-info";
1
+ import type { McpServerInfo, NormalizedMcpServerInfo } from "../model/mcp-server-info.js";
2
2
  /**
3
3
  * Derives a short, meaningful key from a server URL.
4
4
  * Strips TLDs and common prefixes to get a human-readable identifier.
@@ -1,4 +1,4 @@
1
- import { getMcpServerUniqueKey, MCPTransport } from "../model/mcp-server-info";
1
+ import { getMcpServerUniqueKey, MCPTransport } from "../model/mcp-server-info.js";
2
2
  /**
3
3
  * Derives a short, meaningful key from a server URL.
4
4
  * Strips TLDs and common prefixes to get a human-readable identifier.
@@ -1,5 +1,5 @@
1
- import { MCPTransport } from "../model/mcp-server-info";
2
- import { deduplicateMcpServers, deriveServerKey, normalizeServerInfo, } from "./mcp-server-utils";
1
+ import { MCPTransport } from "../model/mcp-server-info.js";
2
+ import { deduplicateMcpServers, deriveServerKey, normalizeServerInfo, } from "./mcp-server-utils.js";
3
3
  describe("deriveServerKey", () => {
4
4
  it("should extract key from simple domain", () => {
5
5
  expect(deriveServerKey("https://linear.app/mcp")).toBe("linear");
@@ -1,6 +1,6 @@
1
1
  import type { ReadResourceResult } from "@modelcontextprotocol/sdk/types.js";
2
2
  import type TamboAI from "@tambo-ai/typescript-sdk";
3
- import { StagedImage } from "../hooks/use-message-images";
3
+ import { StagedImage } from "../hooks/use-message-images.js";
4
4
  /**
5
5
  * Builds message content with text, MCP resource references, and images
6
6
  * @param text - The text content, may include \@serverKey:uri resource references
@@ -1,4 +1,4 @@
1
- import { buildMessageContent } from "./message-builder";
1
+ import { buildMessageContent } from "./message-builder.js";
2
2
  describe("buildMessageContent", () => {
3
3
  const createMockStagedImage = (overrides = {}) => ({
4
4
  id: "test-id",
@@ -1,4 +1,4 @@
1
- import { combineMutationResults, combineQueryResults } from "./query-utils";
1
+ import { combineMutationResults, combineQueryResults } from "./query-utils.js";
2
2
  function createMutationResult(status, overrides = {}) {
3
3
  const base = {
4
4
  data: undefined,
@@ -1,4 +1,4 @@
1
- import type { TamboComponent, TamboTool } from "../model/component-metadata";
1
+ import type { TamboComponent, TamboTool } from "../model/component-metadata.js";
2
2
  /**
3
3
  * Validates a tool before registration.
4
4
  * Throws an error if the tool is invalid.
@@ -1,5 +1,5 @@
1
- import { assertNoRecordSchema, isStandardSchema, looksLikeJSONSchema, schemaToJsonSchema, } from "../schema";
2
- import { assertValidName } from "./validate-component-name";
1
+ import { assertNoRecordSchema, isStandardSchema, looksLikeJSONSchema, schemaToJsonSchema, } from "../schema/index.js";
2
+ import { assertValidName } from "./validate-component-name.js";
3
3
  /**
4
4
  * Checks if a JSON Schema represents an object type.
5
5
  * @param schema - The JSON Schema to check
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod/v3";
2
- import { validateAndPrepareComponent, validateTool, validateToolAssociation, } from "./registry-validators";
2
+ import { validateAndPrepareComponent, validateTool, validateToolAssociation, } from "./registry-validators.js";
3
3
  describe("validateTool", () => {
4
4
  it("should validate tool with valid name", () => {
5
5
  const tool = {
@@ -1,5 +1,5 @@
1
1
  import TamboAI from "@tambo-ai/typescript-sdk";
2
- import { ComponentContextToolMetadata, ComponentRegistry, DefineToolFn, RegisteredComponent, TamboTool, TamboToolAssociations, TamboToolRegistry } from "../model/component-metadata";
2
+ import { ComponentContextToolMetadata, ComponentRegistry, DefineToolFn, RegisteredComponent, TamboTool, TamboToolAssociations, TamboToolRegistry } from "../model/component-metadata.js";
3
3
  /**
4
4
  * Get all the available components from the component registry
5
5
  * @param componentRegistry - The component registry
@@ -1,4 +1,4 @@
1
- import { getParametersFromToolSchema, isStandardSchema, schemaToJsonSchema, } from "../schema";
1
+ import { getParametersFromToolSchema, isStandardSchema, schemaToJsonSchema, } from "../schema/index.js";
2
2
  /**
3
3
  * Get all the available components from the component registry
4
4
  * @param componentRegistry - The component registry
@@ -1,7 +1,7 @@
1
1
  import * as z3 from "zod/v3";
2
2
  import * as z4 from "zod/v4";
3
- import { createMockTool } from "../testing/tools";
4
- import { convertPropsToJsonSchema, getAvailableComponents, getComponentFromRegistry, getUnassociatedTools, mapTamboToolToContextTool, } from "./registry";
3
+ import { createMockTool } from "../testing/tools.js";
4
+ import { convertPropsToJsonSchema, getAvailableComponents, getComponentFromRegistry, getUnassociatedTools, mapTamboToolToContextTool, } from "./registry.js";
5
5
  describe("getParametersFromToolSchema (via mapTamboToolToContextTool)", () => {
6
6
  describe("inputSchema interface (object schemas)", () => {
7
7
  describe("Zod 4 object schemas", () => {
@@ -1,6 +1,6 @@
1
1
  import type { ReadResourceResult } from "@modelcontextprotocol/sdk/types.js";
2
- import type { McpServer } from "../mcp/tambo-mcp-provider";
3
- import type { ResourceSource } from "../model/resource-info";
2
+ import type { McpServer } from "../mcp/tambo-mcp-provider.js";
3
+ import type { ResourceSource } from "../model/resource-info.js";
4
4
  /**
5
5
  * Resolves content for client-side resources (MCP and registry).
6
6
  * Server-side (internal Tambo) resources are skipped - the backend can resolve them.
@@ -1,4 +1,4 @@
1
- import { REGISTRY_SERVER_KEY, ServerType } from "../mcp/mcp-constants";
1
+ import { REGISTRY_SERVER_KEY, ServerType } from "../mcp/mcp-constants.js";
2
2
  /**
3
3
  * Type guard for narrowing McpServer to a connected server.
4
4
  * A connected server has a non-null client.
@@ -1,6 +1,6 @@
1
- import { ServerType } from "../mcp/mcp-constants";
2
- import { MCPTransport } from "../mcp/mcp-client";
3
- import { resolveResourceContents, extractResourceUris, } from "./resource-content-resolver";
1
+ import { ServerType } from "../mcp/mcp-constants.js";
2
+ import { MCPTransport } from "../mcp/mcp-client.js";
3
+ import { resolveResourceContents, extractResourceUris, } from "./resource-content-resolver.js";
4
4
  describe("extractResourceUris", () => {
5
5
  it("should extract a single resource URI", () => {
6
6
  const text = "Check @registry:file:///path/to/doc.txt";
@@ -1,4 +1,4 @@
1
- import type { ListResourceItem, ResourceSource } from "../model/resource-info";
1
+ import type { ListResourceItem, ResourceSource } from "../model/resource-info.js";
2
2
  /**
3
3
  * Validates that a ResourceSource has both listResources and getResource defined,
4
4
  * or neither defined. You cannot provide one without the other.
@@ -1,4 +1,4 @@
1
- import { validateResource, validateResourceSource, } from "./resource-validators";
1
+ import { validateResource, validateResourceSource, } from "./resource-validators.js";
2
2
  describe("validateResourceSource", () => {
3
3
  it("should throw when has listResources but not getResource", () => {
4
4
  const listResources = async () => [];
@@ -1,5 +1,5 @@
1
1
  import TamboAI from "@tambo-ai/typescript-sdk";
2
- import { TamboTool, TamboToolRegistry } from "../model/component-metadata";
2
+ import { TamboTool, TamboToolRegistry } from "../model/component-metadata.js";
3
3
  /**
4
4
  * Process a message from the thread, invoking the appropriate tool and returning the result.
5
5
  * @param toolCallRequest - The message to handle
@@ -1,4 +1,4 @@
1
- import { mapTamboToolToContextTool } from "./registry";
1
+ import { mapTamboToolToContextTool } from "./registry.js";
2
2
  /**
3
3
  * Process a message from the thread, invoking the appropriate tool and returning the result.
4
4
  * @param toolCallRequest - The message to handle
@@ -1,4 +1,4 @@
1
- import { assertValidName } from "./validate-component-name";
1
+ import { assertValidName } from "./validate-component-name.js";
2
2
  describe("assertValidName", () => {
3
3
  // Valid names
4
4
  it("should not throw an error for a valid name with letters only", () => {
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=v1-interactables.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"v1-interactables.test.d.ts","sourceRoot":"","sources":["../../../src/v1/__tests__/v1-interactables.test.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,130 @@
1
+ import { act, render, renderHook, screen } from "@testing-library/react";
2
+ import React from "react";
3
+ import { z } from "zod/v3";
4
+ import { withTamboInteractable } from "../../hoc/with-tambo-interactable.js";
5
+ import { useTamboInteractable } from "../../providers/tambo-interactable-provider.js";
6
+ import { useTamboContextHelpers } from "../../providers/tambo-context-helpers-provider.js";
7
+ import { TamboRegistryContext, } from "../../providers/tambo-registry-provider.js";
8
+ import { TamboContextHelpersProvider } from "../../providers/tambo-context-helpers-provider.js";
9
+ import { TamboInteractableProvider } from "../../providers/tambo-interactable-provider.js";
10
+ // Minimal registry mock that captures registered tools
11
+ function createMockRegistry() {
12
+ const toolRegistry = {};
13
+ return {
14
+ value: {
15
+ componentList: {},
16
+ toolRegistry,
17
+ componentToolAssociations: {},
18
+ mcpServerInfos: [],
19
+ resources: [],
20
+ resourceSource: null,
21
+ onCallUnregisteredTool: undefined,
22
+ registerComponent: jest.fn(),
23
+ registerTool: jest.fn((tool) => {
24
+ toolRegistry[tool.name] = tool;
25
+ }),
26
+ registerTools: jest.fn(),
27
+ addToolAssociation: jest.fn(),
28
+ registerMcpServer: jest.fn(),
29
+ registerMcpServers: jest.fn(),
30
+ registerResource: jest.fn(),
31
+ registerResources: jest.fn(),
32
+ registerResourceSource: jest.fn(),
33
+ },
34
+ getRegisteredToolNames: () => Object.keys(toolRegistry),
35
+ };
36
+ }
37
+ /**
38
+ * Wrapper that provides the minimal V1-compatible provider tree for interactables:
39
+ * TamboRegistryContext > TamboContextHelpersProvider > TamboInteractableProvider
40
+ */
41
+ function V1InteractableWrapper({ children, registry, }) {
42
+ return (React.createElement(TamboRegistryContext.Provider, { value: registry },
43
+ React.createElement(TamboContextHelpersProvider, null,
44
+ React.createElement(TamboInteractableProvider, null, children))));
45
+ }
46
+ describe("V1 Interactables Integration", () => {
47
+ it("registers update_component_props and update_component_state tools when an interactable is added", () => {
48
+ const mockRegistry = createMockRegistry();
49
+ const { result } = renderHook(() => useTamboInteractable(), {
50
+ wrapper: ({ children }) => (React.createElement(V1InteractableWrapper, { registry: mockRegistry.value }, children)),
51
+ });
52
+ act(() => {
53
+ result.current.addInteractableComponent({
54
+ name: "TestWidget",
55
+ description: "A test widget",
56
+ component: () => React.createElement("div", null, "widget"),
57
+ props: { label: "hello" },
58
+ propsSchema: z.object({ label: z.string() }),
59
+ });
60
+ });
61
+ const toolNames = mockRegistry.getRegisteredToolNames();
62
+ expect(toolNames.some((n) => n.startsWith("update_component_props_TestWidget"))).toBe(true);
63
+ expect(toolNames.some((n) => n.startsWith("update_component_state_TestWidget"))).toBe(true);
64
+ });
65
+ it("registers interactables context helper that includes component info", async () => {
66
+ const mockRegistry = createMockRegistry();
67
+ const { result } = renderHook(() => ({
68
+ interactable: useTamboInteractable(),
69
+ helpers: useTamboContextHelpers(),
70
+ }), {
71
+ wrapper: ({ children }) => (React.createElement(V1InteractableWrapper, { registry: mockRegistry.value }, children)),
72
+ });
73
+ // Add an interactable component
74
+ act(() => {
75
+ result.current.interactable.addInteractableComponent({
76
+ name: "InfoCard",
77
+ description: "An info card",
78
+ component: () => React.createElement("div", null, "card"),
79
+ props: { title: "Test" },
80
+ });
81
+ });
82
+ // Get additional context - should include interactable info
83
+ const contexts = await act(async () => {
84
+ return await result.current.helpers.getAdditionalContext();
85
+ });
86
+ const interactablesContext = contexts.find((c) => c.name === "interactables");
87
+ expect(interactablesContext).toBeDefined();
88
+ expect(interactablesContext?.context).toBeDefined();
89
+ });
90
+ it("renders an interactable component via withTamboInteractable HOC", () => {
91
+ const mockRegistry = createMockRegistry();
92
+ const Card = ({ title }) => (React.createElement("div", { "data-testid": "card-title" }, title));
93
+ const InteractableCard = withTamboInteractable(Card, {
94
+ componentName: "Card",
95
+ description: "A card component",
96
+ propsSchema: z.object({ title: z.string() }),
97
+ });
98
+ render(React.createElement(V1InteractableWrapper, { registry: mockRegistry.value },
99
+ React.createElement(InteractableCard, { title: "Hello V1" })));
100
+ expect(screen.getByTestId("card-title")).toHaveTextContent("Hello V1");
101
+ });
102
+ it("updates component props via the interactable provider", () => {
103
+ const mockRegistry = createMockRegistry();
104
+ const Counter = ({ count }) => (React.createElement("div", { "data-testid": "count" }, count));
105
+ const InteractableCounter = withTamboInteractable(Counter, {
106
+ componentName: "Counter",
107
+ description: "A counter",
108
+ propsSchema: z.object({ count: z.number() }),
109
+ });
110
+ // Inner component that triggers prop updates
111
+ function TestHarness() {
112
+ const { interactableComponents, updateInteractableComponentProps } = useTamboInteractable();
113
+ const component = interactableComponents[0];
114
+ return (React.createElement("div", null,
115
+ React.createElement(InteractableCounter, { count: 0 }),
116
+ component && (React.createElement("button", { "data-testid": "update-btn", onClick: () => updateInteractableComponentProps(component.id, { count: 42 }) }, "Update"))));
117
+ }
118
+ render(React.createElement(V1InteractableWrapper, { registry: mockRegistry.value },
119
+ React.createElement(TestHarness, null)));
120
+ // Initial render
121
+ expect(screen.getByTestId("count")).toHaveTextContent("0");
122
+ // Update props via the interactable provider
123
+ act(() => {
124
+ screen.getByTestId("update-btn").click();
125
+ });
126
+ // The interactable should reflect updated props
127
+ expect(screen.getByTestId("count")).toHaveTextContent("42");
128
+ });
129
+ });
130
+ //# sourceMappingURL=v1-interactables.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"v1-interactables.test.js","sourceRoot":"","sources":["../../../src/v1/__tests__/v1-interactables.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import { act, render, renderHook, screen } from \"@testing-library/react\";\nimport React from \"react\";\nimport { z } from \"zod/v3\";\nimport { withTamboInteractable } from \"../../hoc/with-tambo-interactable\";\nimport { useTamboInteractable } from \"../../providers/tambo-interactable-provider\";\nimport { useTamboContextHelpers } from \"../../providers/tambo-context-helpers-provider\";\nimport {\n TamboRegistryContext,\n type TamboRegistryContext as TamboRegistryContextType,\n} from \"../../providers/tambo-registry-provider\";\nimport { TamboContextHelpersProvider } from \"../../providers/tambo-context-helpers-provider\";\nimport { TamboInteractableProvider } from \"../../providers/tambo-interactable-provider\";\n\n// Minimal registry mock that captures registered tools\nfunction createMockRegistry() {\n const toolRegistry: Record<string, unknown> = {};\n return {\n value: {\n componentList: {},\n toolRegistry,\n componentToolAssociations: {},\n mcpServerInfos: [],\n resources: [],\n resourceSource: null,\n onCallUnregisteredTool: undefined,\n registerComponent: jest.fn(),\n registerTool: jest.fn((tool: { name: string }) => {\n toolRegistry[tool.name] = tool;\n }),\n registerTools: jest.fn(),\n addToolAssociation: jest.fn(),\n registerMcpServer: jest.fn(),\n registerMcpServers: jest.fn(),\n registerResource: jest.fn(),\n registerResources: jest.fn(),\n registerResourceSource: jest.fn(),\n } as unknown as TamboRegistryContextType,\n getRegisteredToolNames: () => Object.keys(toolRegistry),\n };\n}\n\n/**\n * Wrapper that provides the minimal V1-compatible provider tree for interactables:\n * TamboRegistryContext > TamboContextHelpersProvider > TamboInteractableProvider\n */\nfunction V1InteractableWrapper({\n children,\n registry,\n}: {\n children: React.ReactNode;\n registry: TamboRegistryContextType;\n}) {\n return (\n <TamboRegistryContext.Provider value={registry}>\n <TamboContextHelpersProvider>\n <TamboInteractableProvider>{children}</TamboInteractableProvider>\n </TamboContextHelpersProvider>\n </TamboRegistryContext.Provider>\n );\n}\n\ndescribe(\"V1 Interactables Integration\", () => {\n it(\"registers update_component_props and update_component_state tools when an interactable is added\", () => {\n const mockRegistry = createMockRegistry();\n\n const { result } = renderHook(() => useTamboInteractable(), {\n wrapper: ({ children }) => (\n <V1InteractableWrapper registry={mockRegistry.value}>\n {children}\n </V1InteractableWrapper>\n ),\n });\n\n act(() => {\n result.current.addInteractableComponent({\n name: \"TestWidget\",\n description: \"A test widget\",\n component: () => <div>widget</div>,\n props: { label: \"hello\" },\n propsSchema: z.object({ label: z.string() }),\n });\n });\n\n const toolNames = mockRegistry.getRegisteredToolNames();\n expect(\n toolNames.some((n) => n.startsWith(\"update_component_props_TestWidget\")),\n ).toBe(true);\n expect(\n toolNames.some((n) => n.startsWith(\"update_component_state_TestWidget\")),\n ).toBe(true);\n });\n\n it(\"registers interactables context helper that includes component info\", async () => {\n const mockRegistry = createMockRegistry();\n\n const { result } = renderHook(\n () => ({\n interactable: useTamboInteractable(),\n helpers: useTamboContextHelpers(),\n }),\n {\n wrapper: ({ children }) => (\n <V1InteractableWrapper registry={mockRegistry.value}>\n {children}\n </V1InteractableWrapper>\n ),\n },\n );\n\n // Add an interactable component\n act(() => {\n result.current.interactable.addInteractableComponent({\n name: \"InfoCard\",\n description: \"An info card\",\n component: () => <div>card</div>,\n props: { title: \"Test\" },\n });\n });\n\n // Get additional context - should include interactable info\n const contexts = await act(async () => {\n return await result.current.helpers.getAdditionalContext();\n });\n\n const interactablesContext = contexts.find(\n (c) => c.name === \"interactables\",\n );\n expect(interactablesContext).toBeDefined();\n expect(interactablesContext?.context).toBeDefined();\n });\n\n it(\"renders an interactable component via withTamboInteractable HOC\", () => {\n const mockRegistry = createMockRegistry();\n\n interface CardProps {\n title: string;\n }\n\n const Card: React.FC<CardProps> = ({ title }) => (\n <div data-testid=\"card-title\">{title}</div>\n );\n\n const InteractableCard = withTamboInteractable(Card, {\n componentName: \"Card\",\n description: \"A card component\",\n propsSchema: z.object({ title: z.string() }),\n });\n\n render(\n <V1InteractableWrapper registry={mockRegistry.value}>\n <InteractableCard title=\"Hello V1\" />\n </V1InteractableWrapper>,\n );\n\n expect(screen.getByTestId(\"card-title\")).toHaveTextContent(\"Hello V1\");\n });\n\n it(\"updates component props via the interactable provider\", () => {\n const mockRegistry = createMockRegistry();\n\n interface CounterProps {\n count: number;\n }\n\n const Counter: React.FC<CounterProps> = ({ count }) => (\n <div data-testid=\"count\">{count}</div>\n );\n\n const InteractableCounter = withTamboInteractable(Counter, {\n componentName: \"Counter\",\n description: \"A counter\",\n propsSchema: z.object({ count: z.number() }),\n });\n\n // Inner component that triggers prop updates\n function TestHarness() {\n const { interactableComponents, updateInteractableComponentProps } =\n useTamboInteractable();\n const component = interactableComponents[0];\n\n return (\n <div>\n <InteractableCounter count={0} />\n {component && (\n <button\n data-testid=\"update-btn\"\n onClick={() =>\n updateInteractableComponentProps(component.id, { count: 42 })\n }\n >\n Update\n </button>\n )}\n </div>\n );\n }\n\n render(\n <V1InteractableWrapper registry={mockRegistry.value}>\n <TestHarness />\n </V1InteractableWrapper>,\n );\n\n // Initial render\n expect(screen.getByTestId(\"count\")).toHaveTextContent(\"0\");\n\n // Update props via the interactable provider\n act(() => {\n screen.getByTestId(\"update-btn\").click();\n });\n\n // The interactable should reflect updated props\n expect(screen.getByTestId(\"count\")).toHaveTextContent(\"42\");\n });\n});\n"]}
@@ -0,0 +1,48 @@
1
+ import React, { type FC } from "react";
2
+ import type { V1ComponentContent } from "../types/message.js";
3
+ export interface V1ComponentRendererProps {
4
+ /**
5
+ * The component content block from a v1 message
6
+ */
7
+ content: V1ComponentContent;
8
+ /**
9
+ * The thread ID the component belongs to
10
+ */
11
+ threadId: string;
12
+ /**
13
+ * The message ID the component belongs to
14
+ */
15
+ messageId: string;
16
+ /**
17
+ * Optional fallback to render if component is not found in registry
18
+ */
19
+ fallback?: React.ReactNode;
20
+ }
21
+ /**
22
+ * Renders a component from the registry based on component content block data.
23
+ *
24
+ * Use this component in your message renderer to display AI-generated components.
25
+ * The component instance is preserved across re-renders as long as React's
26
+ * reconciliation keeps this wrapper mounted (use content.id as key).
27
+ *
28
+ * Wraps the rendered component with V1ComponentContentProvider so that hooks
29
+ * like useTamboV1ComponentState can access component context.
30
+ * @returns The rendered component wrapped in V1ComponentContentProvider, or fallback if not found
31
+ * @example
32
+ * ```tsx
33
+ * function MessageContent({ content }: { content: Content }) {
34
+ * if (content.type === 'component') {
35
+ * return (
36
+ * <V1ComponentRenderer
37
+ * key={content.id}
38
+ * content={content}
39
+ * fallback={<div>Unknown component: {content.name}</div>}
40
+ * />
41
+ * );
42
+ * }
43
+ * // ... handle other content types
44
+ * }
45
+ * ```
46
+ */
47
+ export declare const V1ComponentRenderer: FC<V1ComponentRendererProps>;
48
+ //# sourceMappingURL=v1-component-renderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"v1-component-renderer.d.ts","sourceRoot":"","sources":["../../../src/v1/components/v1-component-renderer.tsx"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,EAAE,KAAK,EAAE,EAAuB,MAAM,OAAO,CAAC;AAK5D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAG3D,MAAM,WAAW,wBAAwB;IACvC;;OAEG;IACH,OAAO,EAAE,kBAAkB,CAAC;IAE5B;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,mBAAmB,EAAE,EAAE,CAAC,wBAAwB,CAoF5D,CAAC"}
@@ -0,0 +1,100 @@
1
+ "use client";
2
+ /**
3
+ * V1 Component Renderer
4
+ *
5
+ * A wrapper component that renders a component from the registry based on
6
+ * component content block data. Uses React's normal reconciliation to maintain
7
+ * component identity - as long as the key stays stable, the component instance
8
+ * is preserved.
9
+ *
10
+ * Wraps the component with V1ComponentContentProvider so that hooks like
11
+ * useTamboV1ComponentState can access component context.
12
+ */
13
+ import { parse } from "partial-json";
14
+ import React, { useMemo, useContext } from "react";
15
+ import { TamboRegistryContext } from "../../providers/tambo-registry-provider.js";
16
+ import { isStandardSchema } from "../../schema/index.js";
17
+ import { isPromise } from "../../util/is-promise.js";
18
+ import { getComponentFromRegistry } from "../../util/registry.js";
19
+ import { V1ComponentContentProvider } from "../utils/component-renderer.js";
20
+ /**
21
+ * Renders a component from the registry based on component content block data.
22
+ *
23
+ * Use this component in your message renderer to display AI-generated components.
24
+ * The component instance is preserved across re-renders as long as React's
25
+ * reconciliation keeps this wrapper mounted (use content.id as key).
26
+ *
27
+ * Wraps the rendered component with V1ComponentContentProvider so that hooks
28
+ * like useTamboV1ComponentState can access component context.
29
+ * @returns The rendered component wrapped in V1ComponentContentProvider, or fallback if not found
30
+ * @example
31
+ * ```tsx
32
+ * function MessageContent({ content }: { content: Content }) {
33
+ * if (content.type === 'component') {
34
+ * return (
35
+ * <V1ComponentRenderer
36
+ * key={content.id}
37
+ * content={content}
38
+ * fallback={<div>Unknown component: {content.name}</div>}
39
+ * />
40
+ * );
41
+ * }
42
+ * // ... handle other content types
43
+ * }
44
+ * ```
45
+ */
46
+ export const V1ComponentRenderer = ({ content, threadId, messageId, fallback = null, }) => {
47
+ const registry = useContext(TamboRegistryContext);
48
+ // Memoize the rendered element - only recreates when props change
49
+ const element = useMemo(() => {
50
+ try {
51
+ const registeredComponent = getComponentFromRegistry(content.name, registry.componentList);
52
+ // Parse props (handles partial JSON during streaming)
53
+ const propsJson = JSON.stringify(content.props ?? {});
54
+ const parsedProps = parse(propsJson);
55
+ let validatedProps = parsedProps;
56
+ // Validate props if schema is present
57
+ if (isStandardSchema(registeredComponent.props)) {
58
+ const result = registeredComponent.props["~standard"].validate(parsedProps);
59
+ if (isPromise(result)) {
60
+ // Async validation not supported - skip validation
61
+ console.warn(`Async schema validation not supported for component ${content.name}`);
62
+ }
63
+ else if ("value" in result) {
64
+ validatedProps = result.value;
65
+ }
66
+ else {
67
+ // Validation failed - log warning but still render with raw props
68
+ console.warn(`Props validation failed for component ${content.name}:`, result.issues?.[0]?.message);
69
+ }
70
+ }
71
+ return React.createElement(registeredComponent.component, validatedProps);
72
+ }
73
+ catch (error) {
74
+ console.error("[V1ComponentRenderer] Failed to render component", {
75
+ threadId,
76
+ messageId,
77
+ componentId: content.id,
78
+ componentName: content.name,
79
+ streamingState: content.streamingState,
80
+ props: content.props,
81
+ error,
82
+ });
83
+ return null;
84
+ }
85
+ }, [
86
+ content.id,
87
+ content.name,
88
+ content.props,
89
+ content.streamingState,
90
+ messageId,
91
+ threadId,
92
+ registry.componentList,
93
+ ]);
94
+ if (element === null) {
95
+ return React.createElement(React.Fragment, null, fallback);
96
+ }
97
+ // Wrap with provider so hooks like useTamboV1ComponentState work
98
+ return (React.createElement(V1ComponentContentProvider, { componentId: content.id, threadId: threadId, messageId: messageId, componentName: content.name }, element));
99
+ };
100
+ //# sourceMappingURL=v1-component-renderer.js.map