@tambo-ai/react 0.74.0 → 0.75.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 (314) hide show
  1. package/README.md +46 -449
  2. package/dist/hoc/with-tambo-interactable.d.ts +8 -0
  3. package/dist/hoc/with-tambo-interactable.d.ts.map +1 -1
  4. package/dist/hoc/with-tambo-interactable.js +5 -2
  5. package/dist/hoc/with-tambo-interactable.js.map +1 -1
  6. package/dist/hoc/with-tambo-interactable.test.js +12 -0
  7. package/dist/hoc/with-tambo-interactable.test.js.map +1 -1
  8. package/dist/hooks/use-tambo-voice.test.js +3 -0
  9. package/dist/hooks/use-tambo-voice.test.js.map +1 -1
  10. package/dist/mcp/mcp-hooks.d.ts.map +1 -1
  11. package/dist/mcp/mcp-hooks.js +70 -16
  12. package/dist/mcp/mcp-hooks.js.map +1 -1
  13. package/dist/mcp/mcp-hooks.test.js +69 -0
  14. package/dist/mcp/mcp-hooks.test.js.map +1 -1
  15. package/dist/mcp/tambo-mcp-provider.test.js +24 -0
  16. package/dist/mcp/tambo-mcp-provider.test.js.map +1 -1
  17. package/dist/mcp/use-mcp-servers.test.js +9 -0
  18. package/dist/mcp/use-mcp-servers.test.js.map +1 -1
  19. package/dist/model/component-metadata.d.ts +4 -4
  20. package/dist/model/component-metadata.js.map +1 -1
  21. package/dist/providers/__tests__/thread-input-resource-resolution.test.js +2 -2
  22. package/dist/providers/__tests__/thread-input-resource-resolution.test.js.map +1 -1
  23. package/dist/providers/tambo-client-provider.d.ts +6 -0
  24. package/dist/providers/tambo-client-provider.d.ts.map +1 -1
  25. package/dist/providers/tambo-client-provider.js +4 -1
  26. package/dist/providers/tambo-client-provider.js.map +1 -1
  27. package/dist/providers/tambo-interactable-provider.d.ts.map +1 -1
  28. package/dist/providers/tambo-interactable-provider.js +8 -0
  29. package/dist/providers/tambo-interactable-provider.js.map +1 -1
  30. package/dist/providers/tambo-interactable-provider.test.js +47 -0
  31. package/dist/providers/tambo-interactable-provider.test.js.map +1 -1
  32. package/dist/providers/tambo-provider.d.ts.map +1 -1
  33. package/dist/providers/tambo-provider.js +4 -1
  34. package/dist/providers/tambo-provider.js.map +1 -1
  35. package/dist/providers/tambo-stubs.d.ts.map +1 -1
  36. package/dist/providers/tambo-stubs.js +3 -0
  37. package/dist/providers/tambo-stubs.js.map +1 -1
  38. package/dist/providers/tambo-thread-provider-initial-messages.test.js +3 -0
  39. package/dist/providers/tambo-thread-provider-initial-messages.test.js.map +1 -1
  40. package/dist/providers/tambo-thread-provider.test.js +3 -0
  41. package/dist/providers/tambo-thread-provider.test.js.map +1 -1
  42. package/dist/util/registry-validators.js +1 -1
  43. package/dist/util/registry-validators.js.map +1 -1
  44. package/dist/util/resource-content-resolver.test.js +1 -1
  45. package/dist/util/resource-content-resolver.test.js.map +1 -1
  46. package/dist/v1/hooks/use-tambo-v1-auth-state.d.ts +11 -0
  47. package/dist/v1/hooks/use-tambo-v1-auth-state.d.ts.map +1 -0
  48. package/dist/v1/hooks/use-tambo-v1-auth-state.js +48 -0
  49. package/dist/v1/hooks/use-tambo-v1-auth-state.js.map +1 -0
  50. package/dist/v1/hooks/use-tambo-v1-auth-state.test.d.ts +2 -0
  51. package/dist/v1/hooks/use-tambo-v1-auth-state.test.d.ts.map +1 -0
  52. package/dist/v1/hooks/use-tambo-v1-auth-state.test.js +105 -0
  53. package/dist/v1/hooks/use-tambo-v1-auth-state.test.js.map +1 -0
  54. package/dist/v1/hooks/use-tambo-v1-component-state.d.ts.map +1 -1
  55. package/dist/v1/hooks/use-tambo-v1-component-state.js +68 -21
  56. package/dist/v1/hooks/use-tambo-v1-component-state.js.map +1 -1
  57. package/dist/v1/hooks/use-tambo-v1-component-state.test.js +100 -0
  58. package/dist/v1/hooks/use-tambo-v1-component-state.test.js.map +1 -1
  59. package/dist/v1/hooks/use-tambo-v1-messages.test.js +8 -0
  60. package/dist/v1/hooks/use-tambo-v1-messages.test.js.map +1 -1
  61. package/dist/v1/hooks/use-tambo-v1-send-message.d.ts +19 -1
  62. package/dist/v1/hooks/use-tambo-v1-send-message.d.ts.map +1 -1
  63. package/dist/v1/hooks/use-tambo-v1-send-message.js +86 -9
  64. package/dist/v1/hooks/use-tambo-v1-send-message.js.map +1 -1
  65. package/dist/v1/hooks/use-tambo-v1-send-message.test.js +273 -0
  66. package/dist/v1/hooks/use-tambo-v1-send-message.test.js.map +1 -1
  67. package/dist/v1/hooks/use-tambo-v1-stream-status.d.ts +2 -2
  68. package/dist/v1/hooks/use-tambo-v1-stream-status.d.ts.map +1 -1
  69. package/dist/v1/hooks/use-tambo-v1-stream-status.js +2 -2
  70. package/dist/v1/hooks/use-tambo-v1-stream-status.js.map +1 -1
  71. package/dist/v1/hooks/use-tambo-v1-stream-status.test.js +11 -11
  72. package/dist/v1/hooks/use-tambo-v1-stream-status.test.js.map +1 -1
  73. package/dist/v1/hooks/use-tambo-v1-thread-input.test.js +13 -0
  74. package/dist/v1/hooks/use-tambo-v1-thread-input.test.js.map +1 -1
  75. package/dist/v1/hooks/use-tambo-v1-thread-list.d.ts.map +1 -1
  76. package/dist/v1/hooks/use-tambo-v1-thread-list.js +4 -0
  77. package/dist/v1/hooks/use-tambo-v1-thread-list.js.map +1 -1
  78. package/dist/v1/hooks/use-tambo-v1-thread-list.test.js +6 -0
  79. package/dist/v1/hooks/use-tambo-v1-thread-list.test.js.map +1 -1
  80. package/dist/v1/hooks/use-tambo-v1-thread.d.ts.map +1 -1
  81. package/dist/v1/hooks/use-tambo-v1-thread.js +4 -0
  82. package/dist/v1/hooks/use-tambo-v1-thread.js.map +1 -1
  83. package/dist/v1/hooks/use-tambo-v1-thread.test.js +6 -0
  84. package/dist/v1/hooks/use-tambo-v1-thread.test.js.map +1 -1
  85. package/dist/v1/hooks/use-tambo-v1.d.ts +11 -0
  86. package/dist/v1/hooks/use-tambo-v1.d.ts.map +1 -1
  87. package/dist/v1/hooks/use-tambo-v1.js +5 -0
  88. package/dist/v1/hooks/use-tambo-v1.js.map +1 -1
  89. package/dist/v1/hooks/use-tambo-v1.test.js +13 -0
  90. package/dist/v1/hooks/use-tambo-v1.test.js.map +1 -1
  91. package/dist/v1/index.d.ts +4 -1
  92. package/dist/v1/index.d.ts.map +1 -1
  93. package/dist/v1/index.js +5 -2
  94. package/dist/v1/index.js.map +1 -1
  95. package/dist/v1/providers/tambo-v1-provider.d.ts +16 -1
  96. package/dist/v1/providers/tambo-v1-provider.d.ts.map +1 -1
  97. package/dist/v1/providers/tambo-v1-provider.js +42 -5
  98. package/dist/v1/providers/tambo-v1-provider.js.map +1 -1
  99. package/dist/v1/providers/tambo-v1-provider.test.js +19 -2
  100. package/dist/v1/providers/tambo-v1-provider.test.js.map +1 -1
  101. package/dist/v1/providers/tambo-v1-stream-context.d.ts +6 -0
  102. package/dist/v1/providers/tambo-v1-stream-context.d.ts.map +1 -1
  103. package/dist/v1/providers/tambo-v1-stream-context.js +50 -11
  104. package/dist/v1/providers/tambo-v1-stream-context.js.map +1 -1
  105. package/dist/v1/providers/tambo-v1-stream-context.test.js +9 -0
  106. package/dist/v1/providers/tambo-v1-stream-context.test.js.map +1 -1
  107. package/dist/v1/providers/tambo-v1-stub-provider.d.ts.map +1 -1
  108. package/dist/v1/providers/tambo-v1-stub-provider.js +4 -0
  109. package/dist/v1/providers/tambo-v1-stub-provider.js.map +1 -1
  110. package/dist/v1/providers/tambo-v1-thread-input-provider.d.ts +11 -0
  111. package/dist/v1/providers/tambo-v1-thread-input-provider.d.ts.map +1 -1
  112. package/dist/v1/providers/tambo-v1-thread-input-provider.js +10 -1
  113. package/dist/v1/providers/tambo-v1-thread-input-provider.js.map +1 -1
  114. package/dist/v1/types/auth.d.ts +24 -0
  115. package/dist/v1/types/auth.d.ts.map +1 -0
  116. package/dist/v1/types/auth.js +3 -0
  117. package/dist/v1/types/auth.js.map +1 -0
  118. package/dist/v1/types/message.d.ts +12 -0
  119. package/dist/v1/types/message.d.ts.map +1 -1
  120. package/dist/v1/types/message.js.map +1 -1
  121. package/dist/v1/types/tool-choice.d.ts +8 -0
  122. package/dist/v1/types/tool-choice.d.ts.map +1 -0
  123. package/dist/v1/types/tool-choice.js +3 -0
  124. package/dist/v1/types/tool-choice.js.map +1 -0
  125. package/dist/v1/utils/event-accumulator.d.ts +28 -2
  126. package/dist/v1/utils/event-accumulator.d.ts.map +1 -1
  127. package/dist/v1/utils/event-accumulator.js +67 -15
  128. package/dist/v1/utils/event-accumulator.js.map +1 -1
  129. package/dist/v1/utils/event-accumulator.test.js +106 -0
  130. package/dist/v1/utils/event-accumulator.test.js.map +1 -1
  131. package/dist/v1/utils/keyed-throttle.d.ts +42 -0
  132. package/dist/v1/utils/keyed-throttle.d.ts.map +1 -0
  133. package/dist/v1/utils/keyed-throttle.js +86 -0
  134. package/dist/v1/utils/keyed-throttle.js.map +1 -0
  135. package/dist/v1/utils/keyed-throttle.test.d.ts +2 -0
  136. package/dist/v1/utils/keyed-throttle.test.d.ts.map +1 -0
  137. package/dist/v1/utils/keyed-throttle.test.js +147 -0
  138. package/dist/v1/utils/keyed-throttle.test.js.map +1 -0
  139. package/dist/v1/utils/registry-conversion.d.ts.map +1 -1
  140. package/dist/v1/utils/registry-conversion.js +2 -0
  141. package/dist/v1/utils/registry-conversion.js.map +1 -1
  142. package/dist/v1/utils/registry-conversion.test.js +23 -0
  143. package/dist/v1/utils/registry-conversion.test.js.map +1 -1
  144. package/dist/v1/utils/tool-call-tracker.d.ts +10 -0
  145. package/dist/v1/utils/tool-call-tracker.d.ts.map +1 -1
  146. package/dist/v1/utils/tool-call-tracker.js +13 -0
  147. package/dist/v1/utils/tool-call-tracker.js.map +1 -1
  148. package/dist/v1/utils/tool-call-tracker.test.d.ts +2 -0
  149. package/dist/v1/utils/tool-call-tracker.test.d.ts.map +1 -0
  150. package/dist/v1/utils/tool-call-tracker.test.js +67 -0
  151. package/dist/v1/utils/tool-call-tracker.test.js.map +1 -0
  152. package/dist/v1/utils/tool-executor.d.ts +34 -0
  153. package/dist/v1/utils/tool-executor.d.ts.map +1 -1
  154. package/dist/v1/utils/tool-executor.js +55 -0
  155. package/dist/v1/utils/tool-executor.js.map +1 -1
  156. package/dist/v1/utils/tool-executor.test.js +211 -0
  157. package/dist/v1/utils/tool-executor.test.js.map +1 -1
  158. package/esm/hoc/with-tambo-interactable.d.ts +8 -0
  159. package/esm/hoc/with-tambo-interactable.d.ts.map +1 -1
  160. package/esm/hoc/with-tambo-interactable.js +5 -2
  161. package/esm/hoc/with-tambo-interactable.js.map +1 -1
  162. package/esm/hoc/with-tambo-interactable.test.js +12 -0
  163. package/esm/hoc/with-tambo-interactable.test.js.map +1 -1
  164. package/esm/hooks/use-tambo-voice.test.js +3 -0
  165. package/esm/hooks/use-tambo-voice.test.js.map +1 -1
  166. package/esm/mcp/mcp-hooks.d.ts.map +1 -1
  167. package/esm/mcp/mcp-hooks.js +70 -16
  168. package/esm/mcp/mcp-hooks.js.map +1 -1
  169. package/esm/mcp/mcp-hooks.test.js +69 -0
  170. package/esm/mcp/mcp-hooks.test.js.map +1 -1
  171. package/esm/mcp/tambo-mcp-provider.test.js +24 -0
  172. package/esm/mcp/tambo-mcp-provider.test.js.map +1 -1
  173. package/esm/mcp/use-mcp-servers.test.js +9 -0
  174. package/esm/mcp/use-mcp-servers.test.js.map +1 -1
  175. package/esm/model/component-metadata.d.ts +4 -4
  176. package/esm/model/component-metadata.js.map +1 -1
  177. package/esm/providers/__tests__/thread-input-resource-resolution.test.js +2 -2
  178. package/esm/providers/__tests__/thread-input-resource-resolution.test.js.map +1 -1
  179. package/esm/providers/tambo-client-provider.d.ts +6 -0
  180. package/esm/providers/tambo-client-provider.d.ts.map +1 -1
  181. package/esm/providers/tambo-client-provider.js +4 -1
  182. package/esm/providers/tambo-client-provider.js.map +1 -1
  183. package/esm/providers/tambo-interactable-provider.d.ts.map +1 -1
  184. package/esm/providers/tambo-interactable-provider.js +8 -0
  185. package/esm/providers/tambo-interactable-provider.js.map +1 -1
  186. package/esm/providers/tambo-interactable-provider.test.js +47 -0
  187. package/esm/providers/tambo-interactable-provider.test.js.map +1 -1
  188. package/esm/providers/tambo-provider.d.ts.map +1 -1
  189. package/esm/providers/tambo-provider.js +4 -1
  190. package/esm/providers/tambo-provider.js.map +1 -1
  191. package/esm/providers/tambo-stubs.d.ts.map +1 -1
  192. package/esm/providers/tambo-stubs.js +3 -0
  193. package/esm/providers/tambo-stubs.js.map +1 -1
  194. package/esm/providers/tambo-thread-provider-initial-messages.test.js +3 -0
  195. package/esm/providers/tambo-thread-provider-initial-messages.test.js.map +1 -1
  196. package/esm/providers/tambo-thread-provider.test.js +3 -0
  197. package/esm/providers/tambo-thread-provider.test.js.map +1 -1
  198. package/esm/util/registry-validators.js +1 -1
  199. package/esm/util/registry-validators.js.map +1 -1
  200. package/esm/util/resource-content-resolver.test.js +1 -1
  201. package/esm/util/resource-content-resolver.test.js.map +1 -1
  202. package/esm/v1/hooks/use-tambo-v1-auth-state.d.ts +11 -0
  203. package/esm/v1/hooks/use-tambo-v1-auth-state.d.ts.map +1 -0
  204. package/esm/v1/hooks/use-tambo-v1-auth-state.js +45 -0
  205. package/esm/v1/hooks/use-tambo-v1-auth-state.js.map +1 -0
  206. package/esm/v1/hooks/use-tambo-v1-auth-state.test.d.ts +2 -0
  207. package/esm/v1/hooks/use-tambo-v1-auth-state.test.d.ts.map +1 -0
  208. package/esm/v1/hooks/use-tambo-v1-auth-state.test.js +100 -0
  209. package/esm/v1/hooks/use-tambo-v1-auth-state.test.js.map +1 -0
  210. package/esm/v1/hooks/use-tambo-v1-component-state.d.ts.map +1 -1
  211. package/esm/v1/hooks/use-tambo-v1-component-state.js +68 -21
  212. package/esm/v1/hooks/use-tambo-v1-component-state.js.map +1 -1
  213. package/esm/v1/hooks/use-tambo-v1-component-state.test.js +100 -0
  214. package/esm/v1/hooks/use-tambo-v1-component-state.test.js.map +1 -1
  215. package/esm/v1/hooks/use-tambo-v1-messages.test.js +8 -0
  216. package/esm/v1/hooks/use-tambo-v1-messages.test.js.map +1 -1
  217. package/esm/v1/hooks/use-tambo-v1-send-message.d.ts +19 -1
  218. package/esm/v1/hooks/use-tambo-v1-send-message.d.ts.map +1 -1
  219. package/esm/v1/hooks/use-tambo-v1-send-message.js +87 -10
  220. package/esm/v1/hooks/use-tambo-v1-send-message.js.map +1 -1
  221. package/esm/v1/hooks/use-tambo-v1-send-message.test.js +273 -0
  222. package/esm/v1/hooks/use-tambo-v1-send-message.test.js.map +1 -1
  223. package/esm/v1/hooks/use-tambo-v1-stream-status.d.ts +2 -2
  224. package/esm/v1/hooks/use-tambo-v1-stream-status.d.ts.map +1 -1
  225. package/esm/v1/hooks/use-tambo-v1-stream-status.js +2 -2
  226. package/esm/v1/hooks/use-tambo-v1-stream-status.js.map +1 -1
  227. package/esm/v1/hooks/use-tambo-v1-stream-status.test.js +11 -11
  228. package/esm/v1/hooks/use-tambo-v1-stream-status.test.js.map +1 -1
  229. package/esm/v1/hooks/use-tambo-v1-thread-input.test.js +13 -0
  230. package/esm/v1/hooks/use-tambo-v1-thread-input.test.js.map +1 -1
  231. package/esm/v1/hooks/use-tambo-v1-thread-list.d.ts.map +1 -1
  232. package/esm/v1/hooks/use-tambo-v1-thread-list.js +4 -0
  233. package/esm/v1/hooks/use-tambo-v1-thread-list.js.map +1 -1
  234. package/esm/v1/hooks/use-tambo-v1-thread-list.test.js +6 -0
  235. package/esm/v1/hooks/use-tambo-v1-thread-list.test.js.map +1 -1
  236. package/esm/v1/hooks/use-tambo-v1-thread.d.ts.map +1 -1
  237. package/esm/v1/hooks/use-tambo-v1-thread.js +4 -0
  238. package/esm/v1/hooks/use-tambo-v1-thread.js.map +1 -1
  239. package/esm/v1/hooks/use-tambo-v1-thread.test.js +6 -0
  240. package/esm/v1/hooks/use-tambo-v1-thread.test.js.map +1 -1
  241. package/esm/v1/hooks/use-tambo-v1.d.ts +11 -0
  242. package/esm/v1/hooks/use-tambo-v1.d.ts.map +1 -1
  243. package/esm/v1/hooks/use-tambo-v1.js +5 -0
  244. package/esm/v1/hooks/use-tambo-v1.js.map +1 -1
  245. package/esm/v1/hooks/use-tambo-v1.test.js +13 -0
  246. package/esm/v1/hooks/use-tambo-v1.test.js.map +1 -1
  247. package/esm/v1/index.d.ts +4 -1
  248. package/esm/v1/index.d.ts.map +1 -1
  249. package/esm/v1/index.js +3 -1
  250. package/esm/v1/index.js.map +1 -1
  251. package/esm/v1/providers/tambo-v1-provider.d.ts +16 -1
  252. package/esm/v1/providers/tambo-v1-provider.d.ts.map +1 -1
  253. package/esm/v1/providers/tambo-v1-provider.js +43 -6
  254. package/esm/v1/providers/tambo-v1-provider.js.map +1 -1
  255. package/esm/v1/providers/tambo-v1-provider.test.js +19 -2
  256. package/esm/v1/providers/tambo-v1-provider.test.js.map +1 -1
  257. package/esm/v1/providers/tambo-v1-stream-context.d.ts +6 -0
  258. package/esm/v1/providers/tambo-v1-stream-context.d.ts.map +1 -1
  259. package/esm/v1/providers/tambo-v1-stream-context.js +51 -12
  260. package/esm/v1/providers/tambo-v1-stream-context.js.map +1 -1
  261. package/esm/v1/providers/tambo-v1-stream-context.test.js +9 -0
  262. package/esm/v1/providers/tambo-v1-stream-context.test.js.map +1 -1
  263. package/esm/v1/providers/tambo-v1-stub-provider.d.ts.map +1 -1
  264. package/esm/v1/providers/tambo-v1-stub-provider.js +4 -0
  265. package/esm/v1/providers/tambo-v1-stub-provider.js.map +1 -1
  266. package/esm/v1/providers/tambo-v1-thread-input-provider.d.ts +11 -0
  267. package/esm/v1/providers/tambo-v1-thread-input-provider.d.ts.map +1 -1
  268. package/esm/v1/providers/tambo-v1-thread-input-provider.js +10 -1
  269. package/esm/v1/providers/tambo-v1-thread-input-provider.js.map +1 -1
  270. package/esm/v1/types/auth.d.ts +24 -0
  271. package/esm/v1/types/auth.d.ts.map +1 -0
  272. package/esm/v1/types/auth.js +2 -0
  273. package/esm/v1/types/auth.js.map +1 -0
  274. package/esm/v1/types/message.d.ts +12 -0
  275. package/esm/v1/types/message.d.ts.map +1 -1
  276. package/esm/v1/types/message.js.map +1 -1
  277. package/esm/v1/types/tool-choice.d.ts +8 -0
  278. package/esm/v1/types/tool-choice.d.ts.map +1 -0
  279. package/esm/v1/types/tool-choice.js +2 -0
  280. package/esm/v1/types/tool-choice.js.map +1 -0
  281. package/esm/v1/utils/event-accumulator.d.ts +28 -2
  282. package/esm/v1/utils/event-accumulator.d.ts.map +1 -1
  283. package/esm/v1/utils/event-accumulator.js +66 -15
  284. package/esm/v1/utils/event-accumulator.js.map +1 -1
  285. package/esm/v1/utils/event-accumulator.test.js +106 -0
  286. package/esm/v1/utils/event-accumulator.test.js.map +1 -1
  287. package/esm/v1/utils/keyed-throttle.d.ts +42 -0
  288. package/esm/v1/utils/keyed-throttle.d.ts.map +1 -0
  289. package/esm/v1/utils/keyed-throttle.js +83 -0
  290. package/esm/v1/utils/keyed-throttle.js.map +1 -0
  291. package/esm/v1/utils/keyed-throttle.test.d.ts +2 -0
  292. package/esm/v1/utils/keyed-throttle.test.d.ts.map +1 -0
  293. package/esm/v1/utils/keyed-throttle.test.js +145 -0
  294. package/esm/v1/utils/keyed-throttle.test.js.map +1 -0
  295. package/esm/v1/utils/registry-conversion.d.ts.map +1 -1
  296. package/esm/v1/utils/registry-conversion.js +2 -0
  297. package/esm/v1/utils/registry-conversion.js.map +1 -1
  298. package/esm/v1/utils/registry-conversion.test.js +23 -0
  299. package/esm/v1/utils/registry-conversion.test.js.map +1 -1
  300. package/esm/v1/utils/tool-call-tracker.d.ts +10 -0
  301. package/esm/v1/utils/tool-call-tracker.d.ts.map +1 -1
  302. package/esm/v1/utils/tool-call-tracker.js +13 -0
  303. package/esm/v1/utils/tool-call-tracker.js.map +1 -1
  304. package/esm/v1/utils/tool-call-tracker.test.d.ts +2 -0
  305. package/esm/v1/utils/tool-call-tracker.test.d.ts.map +1 -0
  306. package/esm/v1/utils/tool-call-tracker.test.js +65 -0
  307. package/esm/v1/utils/tool-call-tracker.test.js.map +1 -0
  308. package/esm/v1/utils/tool-executor.d.ts +34 -0
  309. package/esm/v1/utils/tool-executor.d.ts.map +1 -1
  310. package/esm/v1/utils/tool-executor.js +53 -0
  311. package/esm/v1/utils/tool-executor.js.map +1 -1
  312. package/esm/v1/utils/tool-executor.test.js +212 -1
  313. package/esm/v1/utils/tool-executor.test.js.map +1 -1
  314. package/package.json +4 -4
@@ -5,6 +5,9 @@
5
5
  * - TamboClientProvider: API client and authentication
6
6
  * - TamboRegistryProvider: Component and tool registration
7
7
  * - TamboContextHelpersProvider: Context helper functions
8
+ * - TamboMcpTokenProvider: MCP access token management
9
+ * - TamboMcpProvider: MCP server connections and tool discovery
10
+ * - TamboContextAttachmentProvider: Single-message context attachments
8
11
  * - TamboInteractableProvider: Interactive component tracking
9
12
  * - TamboV1StreamProvider: Streaming state management
10
13
  *
@@ -17,6 +20,7 @@ import { type TamboRegistryProviderProps } from "../../providers/tambo-registry-
17
20
  import type { ContextHelpers } from "../../context-helpers/index.js";
18
21
  import type { McpServerInfo } from "../../model/mcp-server-info.js";
19
22
  import type { ListResourceItem, ResourceSource } from "../../model/resource-info.js";
23
+ import type { InitialInputMessage } from "../types/message.js";
20
24
  /**
21
25
  * Configuration values for v1 SDK.
22
26
  * These are static values that don't change during the session.
@@ -28,6 +32,11 @@ export interface TamboV1Config {
28
32
  autoGenerateThreadName?: boolean;
29
33
  /** The message count threshold at which the thread name will be auto-generated. Defaults to 3. */
30
34
  autoGenerateNameThreshold?: number;
35
+ /**
36
+ * Initial messages to seed new threads with.
37
+ * These are displayed in the UI immediately and sent to the API on first message.
38
+ */
39
+ initialMessages?: InitialInputMessage[];
31
40
  }
32
41
  /**
33
42
  * Context for v1 SDK configuration.
@@ -107,6 +116,12 @@ export interface TamboV1ProviderProps extends Pick<TamboClientProviderProps, "ap
107
116
  * Defaults to 3.
108
117
  */
109
118
  autoGenerateNameThreshold?: number;
119
+ /**
120
+ * Initial messages to seed new threads with.
121
+ * These are displayed in the UI immediately (before the first API call)
122
+ * and sent to the API when the first message is sent to create the thread.
123
+ */
124
+ initialMessages?: InitialInputMessage[];
110
125
  /**
111
126
  * Children components
112
127
  */
@@ -157,5 +172,5 @@ export interface TamboV1ProviderProps extends Pick<TamboClientProviderProps, "ap
157
172
  * }
158
173
  * ```
159
174
  */
160
- export declare function TamboV1Provider({ apiKey, tamboUrl, environment, userToken, components, tools, mcpServers, onCallUnregisteredTool, resources, listResources, getResource, contextHelpers, userKey, autoGenerateThreadName, autoGenerateNameThreshold, children, }: PropsWithChildren<TamboV1ProviderProps>): React.JSX.Element;
175
+ export declare function TamboV1Provider({ apiKey, tamboUrl, environment, userToken, components, tools, mcpServers, onCallUnregisteredTool, resources, listResources, getResource, contextHelpers, userKey, autoGenerateThreadName, autoGenerateNameThreshold, initialMessages, children, }: PropsWithChildren<TamboV1ProviderProps>): React.JSX.Element;
161
176
  //# sourceMappingURL=tambo-v1-provider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tambo-v1-provider.d.ts","sourceRoot":"","sources":["../../../src/v1/providers/tambo-v1-provider.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,EAGZ,KAAK,iBAAiB,EACvB,MAAM,OAAO,CAAC;AACf,OAAO,EAEL,KAAK,wBAAwB,EAC9B,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAEL,KAAK,0BAA0B,EAChC,MAAM,yCAAyC,CAAC;AAGjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,KAAK,EACV,gBAAgB,EAChB,cAAc,EACf,MAAM,2BAA2B,CAAC;AAInC;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,gDAAgD;IAChD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sGAAsG;IACtG,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,kGAAkG;IAClG,yBAAyB,CAAC,EAAE,MAAM,CAAC;CACpC;AAED;;;GAGG;AACH,eAAO,MAAM,oBAAoB,qCAA4C,CAAC;AAE9E;;;;GAIG;AACH,wBAAgB,gBAAgB,IAAI,aAAa,CAMhD;AAED;;GAEG;AACH,MAAM,WAAW,oBAAqB,SAAQ,IAAI,CAChD,wBAAwB,EACxB,QAAQ,GAAG,UAAU,GAAG,aAAa,GAAG,WAAW,CACpD;IACC;;;OAGG;IACH,UAAU,CAAC,EAAE,0BAA0B,CAAC,YAAY,CAAC,CAAC;IAEtD;;;OAGG;IACH,KAAK,CAAC,EAAE,0BAA0B,CAAC,OAAO,CAAC,CAAC;IAE5C;;;OAGG;IACH,UAAU,CAAC,EAAE,CAAC,aAAa,GAAG,MAAM,CAAC,EAAE,CAAC;IAExC;;;OAGG;IACH,sBAAsB,CAAC,EAAE,0BAA0B,CAAC,wBAAwB,CAAC,CAAC;IAE9E;;;OAGG;IACH,SAAS,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAE/B;;;;OAIG;IACH,aAAa,CAAC,EAAE,cAAc,CAAC,eAAe,CAAC,CAAC;IAEhD;;;;OAIG;IACH,WAAW,CAAC,EAAE,cAAc,CAAC,aAAa,CAAC,CAAC;IAE5C;;;;OAIG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;IAEhC;;;;;;;;OAQG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAEjC;;;OAGG;IACH,yBAAyB,CAAC,EAAE,MAAM,CAAC;IAEnC;;OAEG;IACH,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,wBAAgB,eAAe,CAAC,EAC9B,MAAM,EACN,QAAQ,EACR,WAAW,EACX,SAAS,EACT,UAAU,EACV,KAAK,EACL,UAAU,EACV,sBAAsB,EACtB,SAAS,EACT,aAAa,EACb,WAAW,EACX,cAAc,EACd,OAAO,EACP,sBAAsB,EACtB,yBAAyB,EACzB,QAAQ,GACT,EAAE,iBAAiB,CAAC,oBAAoB,CAAC,qBAsCzC"}
1
+ {"version":3,"file":"tambo-v1-provider.d.ts","sourceRoot":"","sources":["../../../src/v1/providers/tambo-v1-provider.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,EAIZ,KAAK,iBAAiB,EACvB,MAAM,OAAO,CAAC;AAEf,OAAO,EAEL,KAAK,wBAAwB,EAC9B,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAEL,KAAK,0BAA0B,EAChC,MAAM,yCAAyC,CAAC;AAMjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,KAAK,EACV,gBAAgB,EAChB,cAAc,EACf,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAI5D;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,gDAAgD;IAChD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sGAAsG;IACtG,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,kGAAkG;IAClG,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC;;;OAGG;IACH,eAAe,CAAC,EAAE,mBAAmB,EAAE,CAAC;CACzC;AAED;;;GAGG;AACH,eAAO,MAAM,oBAAoB,qCAA4C,CAAC;AAE9E;;;;GAIG;AACH,wBAAgB,gBAAgB,IAAI,aAAa,CAMhD;AAED;;GAEG;AACH,MAAM,WAAW,oBAAqB,SAAQ,IAAI,CAChD,wBAAwB,EACxB,QAAQ,GAAG,UAAU,GAAG,aAAa,GAAG,WAAW,CACpD;IACC;;;OAGG;IACH,UAAU,CAAC,EAAE,0BAA0B,CAAC,YAAY,CAAC,CAAC;IAEtD;;;OAGG;IACH,KAAK,CAAC,EAAE,0BAA0B,CAAC,OAAO,CAAC,CAAC;IAE5C;;;OAGG;IACH,UAAU,CAAC,EAAE,CAAC,aAAa,GAAG,MAAM,CAAC,EAAE,CAAC;IAExC;;;OAGG;IACH,sBAAsB,CAAC,EAAE,0BAA0B,CAAC,wBAAwB,CAAC,CAAC;IAE9E;;;OAGG;IACH,SAAS,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAE/B;;;;OAIG;IACH,aAAa,CAAC,EAAE,cAAc,CAAC,eAAe,CAAC,CAAC;IAEhD;;;;OAIG;IACH,WAAW,CAAC,EAAE,cAAc,CAAC,aAAa,CAAC,CAAC;IAE5C;;;;OAIG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;IAEhC;;;;;;;;OAQG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAEjC;;;OAGG;IACH,yBAAyB,CAAC,EAAE,MAAM,CAAC;IAEnC;;;;OAIG;IACH,eAAe,CAAC,EAAE,mBAAmB,EAAE,CAAC;IAExC;;OAEG;IACH,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAkCD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,wBAAgB,eAAe,CAAC,EAC9B,MAAM,EACN,QAAQ,EACR,WAAW,EACX,SAAS,EACT,UAAU,EACV,KAAK,EACL,UAAU,EACV,sBAAsB,EACtB,SAAS,EACT,aAAa,EACb,WAAW,EACX,cAAc,EACd,OAAO,EACP,sBAAsB,EACtB,yBAAyB,EACzB,eAAe,EACf,QAAQ,GACT,EAAE,iBAAiB,CAAC,oBAAoB,CAAC,qBA8CzC"}
@@ -6,17 +6,24 @@
6
6
  * - TamboClientProvider: API client and authentication
7
7
  * - TamboRegistryProvider: Component and tool registration
8
8
  * - TamboContextHelpersProvider: Context helper functions
9
+ * - TamboMcpTokenProvider: MCP access token management
10
+ * - TamboMcpProvider: MCP server connections and tool discovery
11
+ * - TamboContextAttachmentProvider: Single-message context attachments
9
12
  * - TamboInteractableProvider: Interactive component tracking
10
13
  * - TamboV1StreamProvider: Streaming state management
11
14
  *
12
15
  * This provider should wrap your entire application or the portion
13
16
  * that needs access to Tambo v1 functionality.
14
17
  */
15
- import React, { createContext, useContext, } from "react";
18
+ import React, { createContext, useContext, useEffect, } from "react";
19
+ import { useTamboV1AuthState } from "../hooks/use-tambo-v1-auth-state.js";
16
20
  import { TamboClientProvider, } from "../../providers/tambo-client-provider.js";
17
21
  import { TamboRegistryProvider, } from "../../providers/tambo-registry-provider.js";
22
+ import { TamboContextAttachmentProvider } from "../../providers/tambo-context-attachment-provider.js";
18
23
  import { TamboContextHelpersProvider } from "../../providers/tambo-context-helpers-provider.js";
19
24
  import { TamboInteractableProvider } from "../../providers/tambo-interactable-provider.js";
25
+ import { TamboMcpTokenProvider } from "../../providers/tambo-mcp-token-provider.js";
26
+ import { TamboMcpProvider } from "../../mcp/tambo-mcp-provider.js";
20
27
  import { TamboV1StreamProvider } from "./tambo-v1-stream-context.js";
21
28
  import { TamboV1ThreadInputProvider } from "./tambo-v1-thread-input-provider.js";
22
29
  /**
@@ -36,6 +43,31 @@ export function useTamboV1Config() {
36
43
  }
37
44
  return config;
38
45
  }
46
+ /**
47
+ * Internal component that emits console warnings for auth misconfiguration.
48
+ * Rendered inside the provider tree so both TamboClientContext and
49
+ * TamboV1ConfigContext are available.
50
+ */
51
+ function TamboV1AuthWarnings() {
52
+ const authState = useTamboV1AuthState();
53
+ const authError = authState.status === "error" ? authState.error : null;
54
+ useEffect(() => {
55
+ switch (authState.status) {
56
+ case "unauthenticated":
57
+ console.warn("[TamboV1Provider] Neither userKey nor userToken provided. " +
58
+ "API requests will be blocked until authentication is configured.");
59
+ break;
60
+ case "invalid":
61
+ console.warn("[TamboV1Provider] Both userKey and userToken were provided. " +
62
+ "You must provide one or the other, not both.");
63
+ break;
64
+ case "error":
65
+ console.warn("[TamboV1Provider] Token exchange failed:", authError);
66
+ break;
67
+ }
68
+ }, [authState.status, authError]);
69
+ return null;
70
+ }
39
71
  /**
40
72
  * Main provider for the Tambo v1 SDK.
41
73
  *
@@ -81,19 +113,24 @@ export function useTamboV1Config() {
81
113
  * }
82
114
  * ```
83
115
  */
84
- export function TamboV1Provider({ apiKey, tamboUrl, environment, userToken, components, tools, mcpServers, onCallUnregisteredTool, resources, listResources, getResource, contextHelpers, userKey, autoGenerateThreadName, autoGenerateNameThreshold, children, }) {
116
+ export function TamboV1Provider({ apiKey, tamboUrl, environment, userToken, components, tools, mcpServers, onCallUnregisteredTool, resources, listResources, getResource, contextHelpers, userKey, autoGenerateThreadName, autoGenerateNameThreshold, initialMessages, children, }) {
85
117
  // Config is static - created once and never changes
86
118
  const config = {
87
119
  userKey,
88
120
  autoGenerateThreadName,
89
121
  autoGenerateNameThreshold,
122
+ initialMessages,
90
123
  };
91
124
  return (React.createElement(TamboClientProvider, { apiKey: apiKey, tamboUrl: tamboUrl, environment: environment, userToken: userToken },
92
125
  React.createElement(TamboRegistryProvider, { components: components, tools: tools, mcpServers: mcpServers, onCallUnregisteredTool: onCallUnregisteredTool, resources: resources, listResources: listResources, getResource: getResource },
93
126
  React.createElement(TamboContextHelpersProvider, { contextHelpers: contextHelpers },
94
- React.createElement(TamboInteractableProvider, null,
95
- React.createElement(TamboV1ConfigContext.Provider, { value: config },
96
- React.createElement(TamboV1StreamProvider, null,
97
- React.createElement(TamboV1ThreadInputProvider, null, children))))))));
127
+ React.createElement(TamboMcpTokenProvider, null,
128
+ React.createElement(TamboMcpProvider, null,
129
+ React.createElement(TamboContextAttachmentProvider, null,
130
+ React.createElement(TamboInteractableProvider, null,
131
+ React.createElement(TamboV1ConfigContext.Provider, { value: config },
132
+ React.createElement(TamboV1AuthWarnings, null),
133
+ React.createElement(TamboV1StreamProvider, { initialMessages: initialMessages },
134
+ React.createElement(TamboV1ThreadInputProvider, null, children)))))))))));
98
135
  }
99
136
  //# sourceMappingURL=tambo-v1-provider.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tambo-v1-provider.js","sourceRoot":"","sources":["../../../src/v1/providers/tambo-v1-provider.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,EACZ,aAAa,EACb,UAAU,GAEX,MAAM,OAAO,CAAC;AACf,OAAO,EACL,mBAAmB,GAEpB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EACL,qBAAqB,GAEtB,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,2BAA2B,EAAE,MAAM,gDAAgD,CAAC;AAC7F,OAAO,EAAE,yBAAyB,EAAE,MAAM,6CAA6C,CAAC;AAOxF,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,0BAA0B,EAAE,MAAM,kCAAkC,CAAC;AAe9E;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,aAAa,CAAuB,IAAI,CAAC,CAAC;AAE9E;;;;GAIG;AACH,MAAM,UAAU,gBAAgB;IAC9B,MAAM,MAAM,GAAG,UAAU,CAAC,oBAAoB,CAAC,CAAC;IAChD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;IAC1E,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAyFD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,MAAM,UAAU,eAAe,CAAC,EAC9B,MAAM,EACN,QAAQ,EACR,WAAW,EACX,SAAS,EACT,UAAU,EACV,KAAK,EACL,UAAU,EACV,sBAAsB,EACtB,SAAS,EACT,aAAa,EACb,WAAW,EACX,cAAc,EACd,OAAO,EACP,sBAAsB,EACtB,yBAAyB,EACzB,QAAQ,GACgC;IACxC,oDAAoD;IACpD,MAAM,MAAM,GAAkB;QAC5B,OAAO;QACP,sBAAsB;QACtB,yBAAyB;KAC1B,CAAC;IAEF,OAAO,CACL,oBAAC,mBAAmB,IAClB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,QAAQ,EAClB,WAAW,EAAE,WAAW,EACxB,SAAS,EAAE,SAAS;QAEpB,oBAAC,qBAAqB,IACpB,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,KAAK,EACZ,UAAU,EAAE,UAAU,EACtB,sBAAsB,EAAE,sBAAsB,EAC9C,SAAS,EAAE,SAAS,EACpB,aAAa,EAAE,aAAa,EAC5B,WAAW,EAAE,WAAW;YAExB,oBAAC,2BAA2B,IAAC,cAAc,EAAE,cAAc;gBACzD,oBAAC,yBAAyB;oBACxB,oBAAC,oBAAoB,CAAC,QAAQ,IAAC,KAAK,EAAE,MAAM;wBAC1C,oBAAC,qBAAqB;4BACpB,oBAAC,0BAA0B,QACxB,QAAQ,CACkB,CACP,CACM,CACN,CACA,CACR,CACJ,CACvB,CAAC;AACJ,CAAC","sourcesContent":["\"use client\";\n\n/**\n * TamboV1Provider - Main Provider for v1 API\n *\n * Composes the necessary providers for the v1 SDK:\n * - TamboClientProvider: API client and authentication\n * - TamboRegistryProvider: Component and tool registration\n * - TamboContextHelpersProvider: Context helper functions\n * - TamboInteractableProvider: Interactive component tracking\n * - TamboV1StreamProvider: Streaming state management\n *\n * This provider should wrap your entire application or the portion\n * that needs access to Tambo v1 functionality.\n */\n\nimport React, {\n createContext,\n useContext,\n type PropsWithChildren,\n} from \"react\";\nimport {\n TamboClientProvider,\n type TamboClientProviderProps,\n} from \"../../providers/tambo-client-provider\";\nimport {\n TamboRegistryProvider,\n type TamboRegistryProviderProps,\n} from \"../../providers/tambo-registry-provider\";\nimport { TamboContextHelpersProvider } from \"../../providers/tambo-context-helpers-provider\";\nimport { TamboInteractableProvider } from \"../../providers/tambo-interactable-provider\";\nimport type { ContextHelpers } from \"../../context-helpers\";\nimport type { McpServerInfo } from \"../../model/mcp-server-info\";\nimport type {\n ListResourceItem,\n ResourceSource,\n} from \"../../model/resource-info\";\nimport { TamboV1StreamProvider } from \"./tambo-v1-stream-context\";\nimport { TamboV1ThreadInputProvider } from \"./tambo-v1-thread-input-provider\";\n\n/**\n * Configuration values for v1 SDK.\n * These are static values that don't change during the session.\n */\nexport interface TamboV1Config {\n /** User key for thread ownership and scoping */\n userKey?: string;\n /** Whether to automatically generate thread names after a threshold of messages. Defaults to true. */\n autoGenerateThreadName?: boolean;\n /** The message count threshold at which the thread name will be auto-generated. Defaults to 3. */\n autoGenerateNameThreshold?: number;\n}\n\n/**\n * Context for v1 SDK configuration.\n * @internal\n */\nexport const TamboV1ConfigContext = createContext<TamboV1Config | null>(null);\n\n/**\n * Hook to access v1 SDK configuration.\n * @returns Configuration values including userKey\n * @throws {Error} If used outside TamboV1Provider\n */\nexport function useTamboV1Config(): TamboV1Config {\n const config = useContext(TamboV1ConfigContext);\n if (!config) {\n throw new Error(\"useTamboV1Config must be used within TamboV1Provider\");\n }\n return config;\n}\n\n/**\n * Props for TamboV1Provider\n */\nexport interface TamboV1ProviderProps extends Pick<\n TamboClientProviderProps,\n \"apiKey\" | \"tamboUrl\" | \"environment\" | \"userToken\"\n> {\n /**\n * Components to register with the registry.\n * These will be available for the AI to use in responses.\n */\n components?: TamboRegistryProviderProps[\"components\"];\n\n /**\n * Tools to register with the registry.\n * These will be executed client-side when requested by the AI.\n */\n tools?: TamboRegistryProviderProps[\"tools\"];\n\n /**\n * MCP servers to register with the registry.\n * These provide additional tools and resources from MCP-compatible servers.\n */\n mcpServers?: (McpServerInfo | string)[];\n\n /**\n * Callback function called when an unregistered tool is called.\n * If not provided, an error will be thrown for unknown tools.\n */\n onCallUnregisteredTool?: TamboRegistryProviderProps[\"onCallUnregisteredTool\"];\n\n /**\n * Static resources to register with the registry.\n * These will be available for the AI to access.\n */\n resources?: ListResourceItem[];\n\n /**\n * Dynamic resource search function.\n * Must be paired with getResource.\n * Called when searching for resources dynamically.\n */\n listResources?: ResourceSource[\"listResources\"];\n\n /**\n * Dynamic resource fetch function.\n * Must be paired with listResources.\n * Called when fetching a specific resource by URI.\n */\n getResource?: ResourceSource[\"getResource\"];\n\n /**\n * Configuration for context helpers.\n * A dictionary of functions that provide additional context to the AI.\n * Each key becomes the context name, and the function returns the value.\n */\n contextHelpers?: ContextHelpers;\n\n /**\n * User key for thread ownership and scoping.\n *\n * **Required**: You must provide either `userKey` OR `userToken` (which contains a userKey).\n * All thread operations (create, list, fetch) only return threads owned by this userKey.\n *\n * - Use `userKey` for server-side or trusted environments where you control the user identity\n * - Use `userToken` (OAuth bearer token) for client-side apps where the token contains the userKey\n */\n userKey?: string;\n\n /**\n * Whether to automatically generate thread names after a threshold of messages.\n * Defaults to true.\n */\n autoGenerateThreadName?: boolean;\n\n /**\n * The message count threshold at which the thread name will be auto-generated.\n * Defaults to 3.\n */\n autoGenerateNameThreshold?: number;\n\n /**\n * Children components\n */\n children: React.ReactNode;\n}\n\n/**\n * Main provider for the Tambo v1 SDK.\n *\n * Composes TamboClientProvider, TamboRegistryProvider, and TamboV1StreamProvider\n * to provide a complete context for building AI-powered applications.\n *\n * Threads are managed dynamically through useTamboV1() hook functions:\n * - startNewThread() - Begin a new conversation\n * - switchThread(threadId) - Switch to an existing thread\n * - initThread(threadId) - Initialize a thread for receiving events\n * @param props - Provider configuration\n * @param props.apiKey - Tambo API key for authentication\n * @param props.tamboUrl - Optional custom Tambo API URL\n * @param props.environment - Optional environment configuration\n * @param props.userToken - Optional OAuth token for user authentication\n * @param props.components - Components to register with the AI\n * @param props.tools - Tools to register for client-side execution\n * @param props.mcpServers - MCP servers to register for additional tools/resources\n * @param props.onCallUnregisteredTool - Callback for handling unknown tool calls\n * @param props.resources - Static resources to register with the AI\n * @param props.listResources - Dynamic resource search function (must be paired with getResource)\n * @param props.getResource - Dynamic resource fetch function (must be paired with listResources)\n * @param props.contextHelpers - Configuration for context helper functions\n * @param props.userKey - User key for thread ownership (required if not using userToken)\n * @param props.autoGenerateThreadName - Whether to automatically generate thread names. Defaults to true.\n * @param props.autoGenerateNameThreshold - The message count threshold at which the thread name will be auto-generated. Defaults to 3.\n * @param props.children - Child components\n * @returns Provider component tree\n * @example\n * ```tsx\n * import { TamboV1Provider } from '@tambo-ai/react/v1';\n *\n * function App() {\n * return (\n * <TamboV1Provider\n * apiKey={process.env.NEXT_PUBLIC_TAMBO_API_KEY!}\n * components={[WeatherCard, StockChart]}\n * tools={[searchTool, calculatorTool]}\n * >\n * <ChatInterface />\n * </TamboV1Provider>\n * );\n * }\n * ```\n */\nexport function TamboV1Provider({\n apiKey,\n tamboUrl,\n environment,\n userToken,\n components,\n tools,\n mcpServers,\n onCallUnregisteredTool,\n resources,\n listResources,\n getResource,\n contextHelpers,\n userKey,\n autoGenerateThreadName,\n autoGenerateNameThreshold,\n children,\n}: PropsWithChildren<TamboV1ProviderProps>) {\n // Config is static - created once and never changes\n const config: TamboV1Config = {\n userKey,\n autoGenerateThreadName,\n autoGenerateNameThreshold,\n };\n\n return (\n <TamboClientProvider\n apiKey={apiKey}\n tamboUrl={tamboUrl}\n environment={environment}\n userToken={userToken}\n >\n <TamboRegistryProvider\n components={components}\n tools={tools}\n mcpServers={mcpServers}\n onCallUnregisteredTool={onCallUnregisteredTool}\n resources={resources}\n listResources={listResources}\n getResource={getResource}\n >\n <TamboContextHelpersProvider contextHelpers={contextHelpers}>\n <TamboInteractableProvider>\n <TamboV1ConfigContext.Provider value={config}>\n <TamboV1StreamProvider>\n <TamboV1ThreadInputProvider>\n {children}\n </TamboV1ThreadInputProvider>\n </TamboV1StreamProvider>\n </TamboV1ConfigContext.Provider>\n </TamboInteractableProvider>\n </TamboContextHelpersProvider>\n </TamboRegistryProvider>\n </TamboClientProvider>\n );\n}\n"]}
1
+ {"version":3,"file":"tambo-v1-provider.js","sourceRoot":"","sources":["../../../src/v1/providers/tambo-v1-provider.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\n\n/**\n * TamboV1Provider - Main Provider for v1 API\n *\n * Composes the necessary providers for the v1 SDK:\n * - TamboClientProvider: API client and authentication\n * - TamboRegistryProvider: Component and tool registration\n * - TamboContextHelpersProvider: Context helper functions\n * - TamboMcpTokenProvider: MCP access token management\n * - TamboMcpProvider: MCP server connections and tool discovery\n * - TamboContextAttachmentProvider: Single-message context attachments\n * - TamboInteractableProvider: Interactive component tracking\n * - TamboV1StreamProvider: Streaming state management\n *\n * This provider should wrap your entire application or the portion\n * that needs access to Tambo v1 functionality.\n */\n\nimport React, {\n createContext,\n useContext,\n useEffect,\n type PropsWithChildren,\n} from \"react\";\nimport { useTamboV1AuthState } from \"../hooks/use-tambo-v1-auth-state\";\nimport {\n TamboClientProvider,\n type TamboClientProviderProps,\n} from \"../../providers/tambo-client-provider\";\nimport {\n TamboRegistryProvider,\n type TamboRegistryProviderProps,\n} from \"../../providers/tambo-registry-provider\";\nimport { TamboContextAttachmentProvider } from \"../../providers/tambo-context-attachment-provider\";\nimport { TamboContextHelpersProvider } from \"../../providers/tambo-context-helpers-provider\";\nimport { TamboInteractableProvider } from \"../../providers/tambo-interactable-provider\";\nimport { TamboMcpTokenProvider } from \"../../providers/tambo-mcp-token-provider\";\nimport { TamboMcpProvider } from \"../../mcp/tambo-mcp-provider\";\nimport type { ContextHelpers } from \"../../context-helpers\";\nimport type { McpServerInfo } from \"../../model/mcp-server-info\";\nimport type {\n ListResourceItem,\n ResourceSource,\n} from \"../../model/resource-info\";\nimport type { InitialInputMessage } from \"../types/message\";\nimport { TamboV1StreamProvider } from \"./tambo-v1-stream-context\";\nimport { TamboV1ThreadInputProvider } from \"./tambo-v1-thread-input-provider\";\n\n/**\n * Configuration values for v1 SDK.\n * These are static values that don't change during the session.\n */\nexport interface TamboV1Config {\n /** User key for thread ownership and scoping */\n userKey?: string;\n /** Whether to automatically generate thread names after a threshold of messages. Defaults to true. */\n autoGenerateThreadName?: boolean;\n /** The message count threshold at which the thread name will be auto-generated. Defaults to 3. */\n autoGenerateNameThreshold?: number;\n /**\n * Initial messages to seed new threads with.\n * These are displayed in the UI immediately and sent to the API on first message.\n */\n initialMessages?: InitialInputMessage[];\n}\n\n/**\n * Context for v1 SDK configuration.\n * @internal\n */\nexport const TamboV1ConfigContext = createContext<TamboV1Config | null>(null);\n\n/**\n * Hook to access v1 SDK configuration.\n * @returns Configuration values including userKey\n * @throws {Error} If used outside TamboV1Provider\n */\nexport function useTamboV1Config(): TamboV1Config {\n const config = useContext(TamboV1ConfigContext);\n if (!config) {\n throw new Error(\"useTamboV1Config must be used within TamboV1Provider\");\n }\n return config;\n}\n\n/**\n * Props for TamboV1Provider\n */\nexport interface TamboV1ProviderProps extends Pick<\n TamboClientProviderProps,\n \"apiKey\" | \"tamboUrl\" | \"environment\" | \"userToken\"\n> {\n /**\n * Components to register with the registry.\n * These will be available for the AI to use in responses.\n */\n components?: TamboRegistryProviderProps[\"components\"];\n\n /**\n * Tools to register with the registry.\n * These will be executed client-side when requested by the AI.\n */\n tools?: TamboRegistryProviderProps[\"tools\"];\n\n /**\n * MCP servers to register with the registry.\n * These provide additional tools and resources from MCP-compatible servers.\n */\n mcpServers?: (McpServerInfo | string)[];\n\n /**\n * Callback function called when an unregistered tool is called.\n * If not provided, an error will be thrown for unknown tools.\n */\n onCallUnregisteredTool?: TamboRegistryProviderProps[\"onCallUnregisteredTool\"];\n\n /**\n * Static resources to register with the registry.\n * These will be available for the AI to access.\n */\n resources?: ListResourceItem[];\n\n /**\n * Dynamic resource search function.\n * Must be paired with getResource.\n * Called when searching for resources dynamically.\n */\n listResources?: ResourceSource[\"listResources\"];\n\n /**\n * Dynamic resource fetch function.\n * Must be paired with listResources.\n * Called when fetching a specific resource by URI.\n */\n getResource?: ResourceSource[\"getResource\"];\n\n /**\n * Configuration for context helpers.\n * A dictionary of functions that provide additional context to the AI.\n * Each key becomes the context name, and the function returns the value.\n */\n contextHelpers?: ContextHelpers;\n\n /**\n * User key for thread ownership and scoping.\n *\n * **Required**: You must provide either `userKey` OR `userToken` (which contains a userKey).\n * All thread operations (create, list, fetch) only return threads owned by this userKey.\n *\n * - Use `userKey` for server-side or trusted environments where you control the user identity\n * - Use `userToken` (OAuth bearer token) for client-side apps where the token contains the userKey\n */\n userKey?: string;\n\n /**\n * Whether to automatically generate thread names after a threshold of messages.\n * Defaults to true.\n */\n autoGenerateThreadName?: boolean;\n\n /**\n * The message count threshold at which the thread name will be auto-generated.\n * Defaults to 3.\n */\n autoGenerateNameThreshold?: number;\n\n /**\n * Initial messages to seed new threads with.\n * These are displayed in the UI immediately (before the first API call)\n * and sent to the API when the first message is sent to create the thread.\n */\n initialMessages?: InitialInputMessage[];\n\n /**\n * Children components\n */\n children: React.ReactNode;\n}\n\n/**\n * Internal component that emits console warnings for auth misconfiguration.\n * Rendered inside the provider tree so both TamboClientContext and\n * TamboV1ConfigContext are available.\n */\nfunction TamboV1AuthWarnings(): null {\n const authState = useTamboV1AuthState();\n const authError = authState.status === \"error\" ? authState.error : null;\n\n useEffect(() => {\n switch (authState.status) {\n case \"unauthenticated\":\n console.warn(\n \"[TamboV1Provider] Neither userKey nor userToken provided. \" +\n \"API requests will be blocked until authentication is configured.\",\n );\n break;\n case \"invalid\":\n console.warn(\n \"[TamboV1Provider] Both userKey and userToken were provided. \" +\n \"You must provide one or the other, not both.\",\n );\n break;\n case \"error\":\n console.warn(\"[TamboV1Provider] Token exchange failed:\", authError);\n break;\n }\n }, [authState.status, authError]);\n\n return null;\n}\n\n/**\n * Main provider for the Tambo v1 SDK.\n *\n * Composes TamboClientProvider, TamboRegistryProvider, and TamboV1StreamProvider\n * to provide a complete context for building AI-powered applications.\n *\n * Threads are managed dynamically through useTamboV1() hook functions:\n * - startNewThread() - Begin a new conversation\n * - switchThread(threadId) - Switch to an existing thread\n * - initThread(threadId) - Initialize a thread for receiving events\n * @param props - Provider configuration\n * @param props.apiKey - Tambo API key for authentication\n * @param props.tamboUrl - Optional custom Tambo API URL\n * @param props.environment - Optional environment configuration\n * @param props.userToken - Optional OAuth token for user authentication\n * @param props.components - Components to register with the AI\n * @param props.tools - Tools to register for client-side execution\n * @param props.mcpServers - MCP servers to register for additional tools/resources\n * @param props.onCallUnregisteredTool - Callback for handling unknown tool calls\n * @param props.resources - Static resources to register with the AI\n * @param props.listResources - Dynamic resource search function (must be paired with getResource)\n * @param props.getResource - Dynamic resource fetch function (must be paired with listResources)\n * @param props.contextHelpers - Configuration for context helper functions\n * @param props.userKey - User key for thread ownership (required if not using userToken)\n * @param props.autoGenerateThreadName - Whether to automatically generate thread names. Defaults to true.\n * @param props.autoGenerateNameThreshold - The message count threshold at which the thread name will be auto-generated. Defaults to 3.\n * @param props.children - Child components\n * @returns Provider component tree\n * @example\n * ```tsx\n * import { TamboV1Provider } from '@tambo-ai/react/v1';\n *\n * function App() {\n * return (\n * <TamboV1Provider\n * apiKey={process.env.NEXT_PUBLIC_TAMBO_API_KEY!}\n * components={[WeatherCard, StockChart]}\n * tools={[searchTool, calculatorTool]}\n * >\n * <ChatInterface />\n * </TamboV1Provider>\n * );\n * }\n * ```\n */\nexport function TamboV1Provider({\n apiKey,\n tamboUrl,\n environment,\n userToken,\n components,\n tools,\n mcpServers,\n onCallUnregisteredTool,\n resources,\n listResources,\n getResource,\n contextHelpers,\n userKey,\n autoGenerateThreadName,\n autoGenerateNameThreshold,\n initialMessages,\n children,\n}: PropsWithChildren<TamboV1ProviderProps>) {\n // Config is static - created once and never changes\n const config: TamboV1Config = {\n userKey,\n autoGenerateThreadName,\n autoGenerateNameThreshold,\n initialMessages,\n };\n\n return (\n <TamboClientProvider\n apiKey={apiKey}\n tamboUrl={tamboUrl}\n environment={environment}\n userToken={userToken}\n >\n <TamboRegistryProvider\n components={components}\n tools={tools}\n mcpServers={mcpServers}\n onCallUnregisteredTool={onCallUnregisteredTool}\n resources={resources}\n listResources={listResources}\n getResource={getResource}\n >\n <TamboContextHelpersProvider contextHelpers={contextHelpers}>\n <TamboMcpTokenProvider>\n <TamboMcpProvider>\n <TamboContextAttachmentProvider>\n <TamboInteractableProvider>\n <TamboV1ConfigContext.Provider value={config}>\n <TamboV1AuthWarnings />\n <TamboV1StreamProvider initialMessages={initialMessages}>\n <TamboV1ThreadInputProvider>\n {children}\n </TamboV1ThreadInputProvider>\n </TamboV1StreamProvider>\n </TamboV1ConfigContext.Provider>\n </TamboInteractableProvider>\n </TamboContextAttachmentProvider>\n </TamboMcpProvider>\n </TamboMcpTokenProvider>\n </TamboContextHelpersProvider>\n </TamboRegistryProvider>\n </TamboClientProvider>\n );\n}\n"]}
@@ -18,6 +18,20 @@ jest.mock("../../providers/tambo-client-provider", () => {
18
18
  TamboClientProvider: jest.fn(({ children }) => children),
19
19
  };
20
20
  });
21
+ // Mock MCP providers to avoid TamboClientContext dependency
22
+ jest.mock("../../providers/tambo-mcp-token-provider", () => ({
23
+ TamboMcpTokenProvider: ({ children }) => children,
24
+ }));
25
+ jest.mock("../../mcp/tambo-mcp-provider", () => ({
26
+ TamboMcpProvider: ({ children }) => children,
27
+ }));
28
+ // Mock auth state to avoid TamboClientContext dependency
29
+ jest.mock("../hooks/use-tambo-v1-auth-state", () => ({
30
+ useTamboV1AuthState: () => ({
31
+ status: "identified",
32
+ source: "userKey",
33
+ }),
34
+ }));
21
35
  // Mock useTamboV1SendMessage to avoid complex dependencies
22
36
  jest.mock("../hooks/use-tambo-v1-send-message", () => ({
23
37
  useTamboV1SendMessage: jest.fn(() => ({
@@ -200,8 +214,11 @@ describe("TamboV1Provider", () => {
200
214
  const wrapper = ({ children }) => (React.createElement(TamboV1Provider, { apiKey: "test-api-key" }, children));
201
215
  const { result } = renderHook(() => useTamboContextHelpers(), { wrapper });
202
216
  const helpers = result.current.getContextHelpers();
203
- // TamboInteractableProvider registers an "interactables" context helper
204
- expect(Object.keys(helpers)).toEqual(["interactables"]);
217
+ // TamboInteractableProvider registers "interactables" and TamboContextAttachmentProvider registers "contextAttachments"
218
+ expect(Object.keys(helpers)).toEqual([
219
+ "interactables",
220
+ "contextAttachments",
221
+ ]);
205
222
  });
206
223
  });
207
224
  //# sourceMappingURL=tambo-v1-provider.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tambo-v1-provider.test.js","sourceRoot":"","sources":["../../../src/v1/providers/tambo-v1-provider.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import TamboAI from \"@tambo-ai/typescript-sdk\";\nimport { QueryClient, QueryClientProvider } from \"@tanstack/react-query\";\nimport { renderHook, act } from \"@testing-library/react\";\nimport React from \"react\";\nimport { z } from \"zod\";\nimport {\n useTamboClient,\n useTamboQueryClient,\n} from \"../../providers/tambo-client-provider\";\nimport { useTamboRegistry } from \"../../providers/tambo-registry-provider\";\nimport { useTamboContextHelpers } from \"../../providers/tambo-context-helpers-provider\";\nimport { useStreamState, useThreadManagement } from \"./tambo-v1-stream-context\";\nimport { TamboV1Provider, useTamboV1Config } from \"./tambo-v1-provider\";\n\n// Module-level QueryClient for tests - created lazily\nlet testQueryClient: QueryClient | null = null;\n\n// Mock the client provider to capture the apiKey\njest.mock(\"../../providers/tambo-client-provider\", () => {\n return {\n useTamboClient: jest.fn(),\n useTamboQueryClient: jest.fn(),\n TamboClientProvider: jest.fn(\n ({ children }: { children: React.ReactNode }) => children,\n ),\n };\n});\n\n// Mock useTamboV1SendMessage to avoid complex dependencies\njest.mock(\"../hooks/use-tambo-v1-send-message\", () => ({\n useTamboV1SendMessage: jest.fn(() => ({\n mutateAsync: jest.fn(),\n mutate: jest.fn(),\n isPending: false,\n isError: false,\n error: null,\n isSuccess: false,\n reset: jest.fn(),\n })),\n}));\n\ndescribe(\"TamboV1Provider\", () => {\n const mockFetch: typeof fetch = async (..._args) => {\n throw new Error(\"fetch not implemented\");\n };\n\n const mockClient = new TamboAI({\n apiKey: \"test-api-key\",\n fetch: mockFetch,\n });\n\n beforeEach(() => {\n // Create a fresh QueryClient for each test\n testQueryClient = new QueryClient({\n defaultOptions: {\n queries: { retry: false },\n mutations: { retry: false },\n },\n });\n\n jest.mocked(useTamboClient).mockReturnValue(mockClient);\n jest.mocked(useTamboQueryClient).mockReturnValue(testQueryClient);\n\n // Mock TamboClientProvider to wrap children with QueryClientProvider\n const { TamboClientProvider } = jest.requireMock(\n \"../../providers/tambo-client-provider\",\n );\n jest\n .mocked(TamboClientProvider)\n .mockImplementation(({ children }: { children: React.ReactNode }) => (\n <QueryClientProvider client={testQueryClient!}>\n {children}\n </QueryClientProvider>\n ));\n });\n\n it(\"provides access to registry context\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\">{children}</TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.componentList).toBeDefined();\n expect(result.current.toolRegistry).toBeDefined();\n expect(typeof result.current.registerComponent).toBe(\"function\");\n expect(typeof result.current.registerTool).toBe(\"function\");\n });\n\n it(\"provides access to stream context with placeholder thread ready\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\">{children}</TamboV1Provider>\n );\n\n const { result } = renderHook(() => useStreamState(), { wrapper });\n\n expect(result.current.threadMap).toBeDefined();\n // Initial state has placeholder thread for optimistic UI\n expect(result.current.currentThreadId).toBe(\"placeholder\");\n expect(result.current.threadMap.placeholder).toBeDefined();\n });\n\n it(\"manages threads via useThreadManagement\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\">{children}</TamboV1Provider>\n );\n\n const { result } = renderHook(\n () => ({\n state: useStreamState(),\n management: useThreadManagement(),\n }),\n { wrapper },\n );\n\n // Initially has placeholder thread for optimistic UI\n expect(result.current.state.currentThreadId).toBe(\"placeholder\");\n\n // Initialize and switch to a different thread\n act(() => {\n result.current.management.initThread(\"thread_123\");\n result.current.management.switchThread(\"thread_123\");\n });\n\n expect(result.current.state.currentThreadId).toBe(\"thread_123\");\n expect(result.current.state.threadMap.thread_123).toBeDefined();\n });\n\n it(\"provides access to query client via useTamboQueryClient\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\">{children}</TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboQueryClient(), { wrapper });\n\n expect(result.current).toBeInstanceOf(QueryClient);\n });\n\n it(\"registers components when provided\", () => {\n const TestComponent = () => <div>Test</div>;\n const propsSchema = z.object({\n title: z.string().describe(\"The title\"),\n });\n const components = [\n {\n name: \"TestComponent\",\n description: \"A test component\",\n component: TestComponent,\n propsSchema,\n },\n ];\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\" components={components}>\n {children}\n </TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.componentList.TestComponent).toBeDefined();\n expect(result.current.componentList.TestComponent.name).toBe(\n \"TestComponent\",\n );\n });\n\n it(\"registers tools when provided\", () => {\n const inputSchema = z.object({\n query: z.string().describe(\"Search query\"),\n });\n const outputSchema = z.string().describe(\"Result string\");\n const tools = [\n {\n name: \"testTool\",\n description: \"A test tool\",\n tool: async () => \"result\",\n inputSchema,\n outputSchema,\n },\n ];\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\" tools={tools}>\n {children}\n </TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.toolRegistry.testTool).toBeDefined();\n expect(result.current.toolRegistry.testTool.name).toBe(\"testTool\");\n });\n\n it(\"registers MCP servers when provided\", () => {\n const mcpServers = [\n { url: \"https://mcp.example.com\", name: \"Example MCP\" },\n ];\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\" mcpServers={mcpServers}>\n {children}\n </TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.mcpServerInfos).toHaveLength(1);\n expect(result.current.mcpServerInfos[0].url).toBe(\n \"https://mcp.example.com\",\n );\n });\n\n it(\"provides onCallUnregisteredTool to registry\", () => {\n const onCallUnregisteredTool = jest\n .fn()\n .mockResolvedValue(\"fallback result\");\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider\n apiKey=\"test-api-key\"\n onCallUnregisteredTool={onCallUnregisteredTool}\n >\n {children}\n </TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.onCallUnregisteredTool).toBe(onCallUnregisteredTool);\n });\n\n it(\"registers static resources when provided\", () => {\n const resources = [\n {\n uri: \"resource://test/example\",\n name: \"Test Resource\",\n description: \"A test resource\",\n mimeType: \"text/plain\",\n },\n ];\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\" resources={resources}>\n {children}\n </TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.resources).toHaveLength(1);\n expect(result.current.resources[0].uri).toBe(\"resource://test/example\");\n expect(result.current.resources[0].name).toBe(\"Test Resource\");\n });\n\n it(\"registers resource source when listResources and getResource provided\", () => {\n const listResources = jest.fn().mockResolvedValue({ resources: [] });\n const getResource = jest.fn().mockResolvedValue({ contents: [] });\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider\n apiKey=\"test-api-key\"\n listResources={listResources}\n getResource={getResource}\n >\n {children}\n </TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.resourceSource).toBeDefined();\n expect(result.current.resourceSource?.listResources).toBe(listResources);\n expect(result.current.resourceSource?.getResource).toBe(getResource);\n });\n\n it(\"provides userKey via useTamboV1Config\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\" userKey=\"my-user-key\">\n {children}\n </TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboV1Config(), { wrapper });\n\n expect(result.current.userKey).toBe(\"my-user-key\");\n });\n\n it(\"returns undefined userKey from useTamboV1Config when no userKey provided\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\">{children}</TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboV1Config(), { wrapper });\n\n expect(result.current.userKey).toBeUndefined();\n });\n\n it(\"provides context helpers via useTamboContextHelpers hook\", async () => {\n const contextHelpers = {\n getUserName: () => \"Test User\",\n getCurrentTime: () => new Date().toISOString(),\n };\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\" contextHelpers={contextHelpers}>\n {children}\n </TamboV1Provider>\n );\n\n const { result, rerender } = renderHook(() => useTamboContextHelpers(), {\n wrapper,\n });\n\n // Helpers are registered via useEffect, so we need to trigger a rerender\n await act(async () => {\n rerender();\n });\n\n const helpers = result.current.getContextHelpers();\n expect(helpers.getUserName).toBe(contextHelpers.getUserName);\n expect(helpers.getCurrentTime).toBe(contextHelpers.getCurrentTime);\n });\n\n it(\"returns only interactables contextHelper when none explicitly provided\", async () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\">{children}</TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboContextHelpers(), { wrapper });\n\n const helpers = result.current.getContextHelpers();\n // TamboInteractableProvider registers an \"interactables\" context helper\n expect(Object.keys(helpers)).toEqual([\"interactables\"]);\n });\n});\n"]}
1
+ {"version":3,"file":"tambo-v1-provider.test.js","sourceRoot":"","sources":["../../../src/v1/providers/tambo-v1-provider.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import TamboAI from \"@tambo-ai/typescript-sdk\";\nimport { QueryClient, QueryClientProvider } from \"@tanstack/react-query\";\nimport { renderHook, act } from \"@testing-library/react\";\nimport React from \"react\";\nimport { z } from \"zod\";\nimport {\n useTamboClient,\n useTamboQueryClient,\n} from \"../../providers/tambo-client-provider\";\nimport { useTamboRegistry } from \"../../providers/tambo-registry-provider\";\nimport { useTamboContextHelpers } from \"../../providers/tambo-context-helpers-provider\";\nimport { useStreamState, useThreadManagement } from \"./tambo-v1-stream-context\";\nimport { TamboV1Provider, useTamboV1Config } from \"./tambo-v1-provider\";\n\n// Module-level QueryClient for tests - created lazily\nlet testQueryClient: QueryClient | null = null;\n\n// Mock the client provider to capture the apiKey\njest.mock(\"../../providers/tambo-client-provider\", () => {\n return {\n useTamboClient: jest.fn(),\n useTamboQueryClient: jest.fn(),\n TamboClientProvider: jest.fn(\n ({ children }: { children: React.ReactNode }) => children,\n ),\n };\n});\n\n// Mock MCP providers to avoid TamboClientContext dependency\njest.mock(\"../../providers/tambo-mcp-token-provider\", () => ({\n TamboMcpTokenProvider: ({ children }: { children: React.ReactNode }) =>\n children,\n}));\n\njest.mock(\"../../mcp/tambo-mcp-provider\", () => ({\n TamboMcpProvider: ({ children }: { children: React.ReactNode }) => children,\n}));\n\n// Mock auth state to avoid TamboClientContext dependency\njest.mock(\"../hooks/use-tambo-v1-auth-state\", () => ({\n useTamboV1AuthState: () => ({\n status: \"identified\",\n source: \"userKey\",\n }),\n}));\n\n// Mock useTamboV1SendMessage to avoid complex dependencies\njest.mock(\"../hooks/use-tambo-v1-send-message\", () => ({\n useTamboV1SendMessage: jest.fn(() => ({\n mutateAsync: jest.fn(),\n mutate: jest.fn(),\n isPending: false,\n isError: false,\n error: null,\n isSuccess: false,\n reset: jest.fn(),\n })),\n}));\n\ndescribe(\"TamboV1Provider\", () => {\n const mockFetch: typeof fetch = async (..._args) => {\n throw new Error(\"fetch not implemented\");\n };\n\n const mockClient = new TamboAI({\n apiKey: \"test-api-key\",\n fetch: mockFetch,\n });\n\n beforeEach(() => {\n // Create a fresh QueryClient for each test\n testQueryClient = new QueryClient({\n defaultOptions: {\n queries: { retry: false },\n mutations: { retry: false },\n },\n });\n\n jest.mocked(useTamboClient).mockReturnValue(mockClient);\n jest.mocked(useTamboQueryClient).mockReturnValue(testQueryClient);\n\n // Mock TamboClientProvider to wrap children with QueryClientProvider\n const { TamboClientProvider } = jest.requireMock(\n \"../../providers/tambo-client-provider\",\n );\n jest\n .mocked(TamboClientProvider)\n .mockImplementation(({ children }: { children: React.ReactNode }) => (\n <QueryClientProvider client={testQueryClient!}>\n {children}\n </QueryClientProvider>\n ));\n });\n\n it(\"provides access to registry context\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\">{children}</TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.componentList).toBeDefined();\n expect(result.current.toolRegistry).toBeDefined();\n expect(typeof result.current.registerComponent).toBe(\"function\");\n expect(typeof result.current.registerTool).toBe(\"function\");\n });\n\n it(\"provides access to stream context with placeholder thread ready\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\">{children}</TamboV1Provider>\n );\n\n const { result } = renderHook(() => useStreamState(), { wrapper });\n\n expect(result.current.threadMap).toBeDefined();\n // Initial state has placeholder thread for optimistic UI\n expect(result.current.currentThreadId).toBe(\"placeholder\");\n expect(result.current.threadMap.placeholder).toBeDefined();\n });\n\n it(\"manages threads via useThreadManagement\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\">{children}</TamboV1Provider>\n );\n\n const { result } = renderHook(\n () => ({\n state: useStreamState(),\n management: useThreadManagement(),\n }),\n { wrapper },\n );\n\n // Initially has placeholder thread for optimistic UI\n expect(result.current.state.currentThreadId).toBe(\"placeholder\");\n\n // Initialize and switch to a different thread\n act(() => {\n result.current.management.initThread(\"thread_123\");\n result.current.management.switchThread(\"thread_123\");\n });\n\n expect(result.current.state.currentThreadId).toBe(\"thread_123\");\n expect(result.current.state.threadMap.thread_123).toBeDefined();\n });\n\n it(\"provides access to query client via useTamboQueryClient\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\">{children}</TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboQueryClient(), { wrapper });\n\n expect(result.current).toBeInstanceOf(QueryClient);\n });\n\n it(\"registers components when provided\", () => {\n const TestComponent = () => <div>Test</div>;\n const propsSchema = z.object({\n title: z.string().describe(\"The title\"),\n });\n const components = [\n {\n name: \"TestComponent\",\n description: \"A test component\",\n component: TestComponent,\n propsSchema,\n },\n ];\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\" components={components}>\n {children}\n </TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.componentList.TestComponent).toBeDefined();\n expect(result.current.componentList.TestComponent.name).toBe(\n \"TestComponent\",\n );\n });\n\n it(\"registers tools when provided\", () => {\n const inputSchema = z.object({\n query: z.string().describe(\"Search query\"),\n });\n const outputSchema = z.string().describe(\"Result string\");\n const tools = [\n {\n name: \"testTool\",\n description: \"A test tool\",\n tool: async () => \"result\",\n inputSchema,\n outputSchema,\n },\n ];\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\" tools={tools}>\n {children}\n </TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.toolRegistry.testTool).toBeDefined();\n expect(result.current.toolRegistry.testTool.name).toBe(\"testTool\");\n });\n\n it(\"registers MCP servers when provided\", () => {\n const mcpServers = [\n { url: \"https://mcp.example.com\", name: \"Example MCP\" },\n ];\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\" mcpServers={mcpServers}>\n {children}\n </TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.mcpServerInfos).toHaveLength(1);\n expect(result.current.mcpServerInfos[0].url).toBe(\n \"https://mcp.example.com\",\n );\n });\n\n it(\"provides onCallUnregisteredTool to registry\", () => {\n const onCallUnregisteredTool = jest\n .fn()\n .mockResolvedValue(\"fallback result\");\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider\n apiKey=\"test-api-key\"\n onCallUnregisteredTool={onCallUnregisteredTool}\n >\n {children}\n </TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.onCallUnregisteredTool).toBe(onCallUnregisteredTool);\n });\n\n it(\"registers static resources when provided\", () => {\n const resources = [\n {\n uri: \"resource://test/example\",\n name: \"Test Resource\",\n description: \"A test resource\",\n mimeType: \"text/plain\",\n },\n ];\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\" resources={resources}>\n {children}\n </TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.resources).toHaveLength(1);\n expect(result.current.resources[0].uri).toBe(\"resource://test/example\");\n expect(result.current.resources[0].name).toBe(\"Test Resource\");\n });\n\n it(\"registers resource source when listResources and getResource provided\", () => {\n const listResources = jest.fn().mockResolvedValue({ resources: [] });\n const getResource = jest.fn().mockResolvedValue({ contents: [] });\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider\n apiKey=\"test-api-key\"\n listResources={listResources}\n getResource={getResource}\n >\n {children}\n </TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.resourceSource).toBeDefined();\n expect(result.current.resourceSource?.listResources).toBe(listResources);\n expect(result.current.resourceSource?.getResource).toBe(getResource);\n });\n\n it(\"provides userKey via useTamboV1Config\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\" userKey=\"my-user-key\">\n {children}\n </TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboV1Config(), { wrapper });\n\n expect(result.current.userKey).toBe(\"my-user-key\");\n });\n\n it(\"returns undefined userKey from useTamboV1Config when no userKey provided\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\">{children}</TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboV1Config(), { wrapper });\n\n expect(result.current.userKey).toBeUndefined();\n });\n\n it(\"provides context helpers via useTamboContextHelpers hook\", async () => {\n const contextHelpers = {\n getUserName: () => \"Test User\",\n getCurrentTime: () => new Date().toISOString(),\n };\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\" contextHelpers={contextHelpers}>\n {children}\n </TamboV1Provider>\n );\n\n const { result, rerender } = renderHook(() => useTamboContextHelpers(), {\n wrapper,\n });\n\n // Helpers are registered via useEffect, so we need to trigger a rerender\n await act(async () => {\n rerender();\n });\n\n const helpers = result.current.getContextHelpers();\n expect(helpers.getUserName).toBe(contextHelpers.getUserName);\n expect(helpers.getCurrentTime).toBe(contextHelpers.getCurrentTime);\n });\n\n it(\"returns only interactables contextHelper when none explicitly provided\", async () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\">{children}</TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboContextHelpers(), { wrapper });\n\n const helpers = result.current.getContextHelpers();\n // TamboInteractableProvider registers \"interactables\" and TamboContextAttachmentProvider registers \"contextAttachments\"\n expect(Object.keys(helpers)).toEqual([\n \"interactables\",\n \"contextAttachments\",\n ]);\n });\n});\n"]}
@@ -6,6 +6,7 @@
6
6
  * following the split-context pattern for optimal re-render performance.
7
7
  */
8
8
  import React from "react";
9
+ import type { InitialInputMessage } from "../types/message.js";
9
10
  import type { TamboV1Thread } from "../types/thread.js";
10
11
  import { type StreamAction, type StreamState } from "../utils/event-accumulator.js";
11
12
  /**
@@ -37,6 +38,11 @@ export interface ThreadManagement {
37
38
  */
38
39
  export interface TamboV1StreamProviderProps {
39
40
  children: React.ReactNode;
41
+ /**
42
+ * Initial messages to populate the placeholder thread with.
43
+ * These render in the UI before any API call is made.
44
+ */
45
+ initialMessages?: InitialInputMessage[];
40
46
  /**
41
47
  * Optional override for stream state (primarily for tests).
42
48
  * If provided, you must also provide `dispatch`.
@@ -1 +1 @@
1
- {"version":3,"file":"tambo-v1-stream-context.d.ts","sourceRoot":"","sources":["../../../src/v1/providers/tambo-v1-stream-context.tsx"],"names":[],"mappings":"AAEA;;;;;;GAMG;AAEH,OAAO,KAQN,MAAM,OAAO,CAAC;AAIf,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAML,KAAK,YAAY,EACjB,KAAK,WAAW,EACjB,MAAM,4BAA4B,CAAC;AAEpC;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;;OAKG;IACH,UAAU,EAAE,CACV,QAAQ,EAAE,MAAM,EAChB,aAAa,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,KACnC,IAAI,CAAC;IAEV;;;;OAIG;IACH,YAAY,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAEzC;;;;OAIG;IACH,cAAc,EAAE,MAAM,MAAM,CAAC;CAC9B;AAqBD;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAE1B;;;OAGG;IACH,KAAK,CAAC,EAAE,WAAW,CAAC;IAEpB;;;OAGG;IACH,QAAQ,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;IAExC;;OAEG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;CACrC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,0BAA0B,qBAkFtE;AAsDD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,cAAc,IAAI,WAAW,CAQ5C;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,iBAAiB,IAAI,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC,CAUhE;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,mBAAmB,IAAI,gBAAgB,CAUtD"}
1
+ {"version":3,"file":"tambo-v1-stream-context.d.ts","sourceRoot":"","sources":["../../../src/v1/providers/tambo-v1-stream-context.tsx"],"names":[],"mappings":"AAEA;;;;;;GAMG;AAEH,OAAO,KAQN,MAAM,OAAO,CAAC;AAGf,OAAO,KAAK,EAAE,mBAAmB,EAAkB,MAAM,kBAAkB,CAAC;AAC5E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAOL,KAAK,YAAY,EACjB,KAAK,WAAW,EACjB,MAAM,4BAA4B,CAAC;AAGpC;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;;OAKG;IACH,UAAU,EAAE,CACV,QAAQ,EAAE,MAAM,EAChB,aAAa,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,KACnC,IAAI,CAAC;IAEV;;;;OAIG;IACH,YAAY,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAEzC;;;;OAIG;IACH,cAAc,EAAE,MAAM,MAAM,CAAC;CAC9B;AAqBD;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAE1B;;;OAGG;IACH,eAAe,CAAC,EAAE,mBAAmB,EAAE,CAAC;IAExC;;;OAGG;IACH,KAAK,CAAC,EAAE,WAAW,CAAC;IAEpB;;;OAGG;IACH,QAAQ,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;IAExC;;OAEG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;CACrC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,0BAA0B,qBA8GtE;AAyED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,cAAc,IAAI,WAAW,CAQ5C;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,iBAAiB,IAAI,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC,CAUhE;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,mBAAmB,IAAI,gBAAgB,CAUtD"}
@@ -7,9 +7,10 @@
7
7
  * following the split-context pattern for optimal re-render performance.
8
8
  */
9
9
  import React, { createContext, useCallback, useContext, useEffect, useMemo, useReducer, useRef, } from "react";
10
- import { useTamboClient } from "../../providers/tambo-client-provider.js";
11
10
  import { useTamboQuery } from "../../hooks/react-query-hooks.js";
12
- import { createInitialState, createInitialThreadState, isPlaceholderThreadId, PLACEHOLDER_THREAD_ID, streamReducer, } from "../utils/event-accumulator.js";
11
+ import { useTamboClient } from "../../providers/tambo-client-provider.js";
12
+ import { createInitialState, createInitialStateWithMessages, createInitialThreadState, isPlaceholderThreadId, PLACEHOLDER_THREAD_ID, streamReducer, } from "../utils/event-accumulator.js";
13
+ import { useTamboV1Config } from "./tambo-v1-provider.js";
13
14
  /**
14
15
  * Context for accessing stream state (read-only).
15
16
  * Separated from dispatch context to prevent unnecessary re-renders.
@@ -44,7 +45,7 @@ const ThreadManagementContext = createContext(null);
44
45
  * ```
45
46
  */
46
47
  export function TamboV1StreamProvider(props) {
47
- const { children, state: providedState, dispatch: providedDispatch } = props;
48
+ const { children, initialMessages, state: providedState, dispatch: providedDispatch, } = props;
48
49
  if ((providedState && !providedDispatch) ||
49
50
  (!providedState && providedDispatch)) {
50
51
  throw new Error("TamboV1StreamProvider requires both state and dispatch when overriding");
@@ -59,7 +60,10 @@ export function TamboV1StreamProvider(props) {
59
60
  }
60
61
  // Create stable initial state - only computed once on mount
61
62
  // Uses createInitialState which sets up placeholder thread for optimistic UI
62
- const [state, dispatch] = useReducer(streamReducer, undefined, createInitialState);
63
+ // If initialMessages are provided, the placeholder thread is seeded with them
64
+ const [state, dispatch] = useReducer(streamReducer, initialMessages, (msgs) => msgs?.length
65
+ ? createInitialStateWithMessages(msgs)
66
+ : createInitialState());
63
67
  const activeState = providedState ?? state;
64
68
  const activeDispatch = providedDispatch ?? dispatch;
65
69
  // Thread management functions
@@ -70,15 +74,32 @@ export function TamboV1StreamProvider(props) {
70
74
  activeDispatch({ type: "SET_CURRENT_THREAD", threadId });
71
75
  }, [activeDispatch]);
72
76
  const startNewThread = useCallback(() => {
73
- // Reset placeholder thread to empty state and switch to it
74
- // This prepares for a new conversation while preserving existing threads
77
+ // Reset placeholder thread and switch to it
78
+ // This prepares for a new conversation while preserving existing threads.
79
+ // If initialMessages were provided, re-seed the placeholder with them.
80
+ const baseThread = createInitialThreadState(PLACEHOLDER_THREAD_ID).thread;
81
+ const threadWithMessages = initialMessages?.length
82
+ ? {
83
+ ...baseThread,
84
+ messages: initialMessages.map((msg) => ({
85
+ id: `initial_${crypto.randomUUID()}`,
86
+ role: msg.role,
87
+ content: msg.content.map((c) => {
88
+ if (c.type === "text") {
89
+ return { type: "text", text: c.text };
90
+ }
91
+ return c;
92
+ }),
93
+ })),
94
+ }
95
+ : baseThread;
75
96
  activeDispatch({
76
97
  type: "START_NEW_THREAD",
77
98
  threadId: PLACEHOLDER_THREAD_ID,
78
- initialThread: createInitialThreadState(PLACEHOLDER_THREAD_ID).thread,
99
+ initialThread: threadWithMessages,
79
100
  });
80
101
  return PLACEHOLDER_THREAD_ID;
81
- }, [activeDispatch]);
102
+ }, [activeDispatch, initialMessages]);
82
103
  const threadManagement = useMemo(() => {
83
104
  return (props.threadManagement ?? {
84
105
  initThread,
@@ -101,6 +122,7 @@ export function TamboV1StreamProvider(props) {
101
122
  */
102
123
  function ThreadSyncManager() {
103
124
  const client = useTamboClient();
125
+ const { userKey } = useTamboV1Config();
104
126
  const state = useContext(StreamStateContext);
105
127
  const dispatch = useContext(StreamDispatchContext);
106
128
  // Track which threads have been synced to avoid redundant fetches
@@ -113,17 +135,34 @@ function ThreadSyncManager() {
113
135
  const isNotSynced = currentThreadId !== lastSyncedThreadRef.current;
114
136
  const hasNoMessages = !threadState || threadState.thread.messages.length === 0;
115
137
  const shouldFetch = isNotPlaceholder && isNotSynced && hasNoMessages;
116
- // Fetch messages from the messages endpoint (not the thread endpoint)
117
- const { data: messagesData, isSuccess } = useTamboQuery({
138
+ // Fetch messages and thread metadata in parallel
139
+ const { data: messagesData, isSuccess: messagesSuccess } = useTamboQuery({
118
140
  queryKey: ["v1-thread-messages", currentThreadId],
119
141
  queryFn: async () => await client.threads.messages.list(currentThreadId),
120
142
  enabled: shouldFetch,
121
143
  staleTime: 1000,
122
144
  refetchOnWindowFocus: false,
123
145
  });
146
+ useTamboQuery({
147
+ queryKey: ["v1-thread-metadata", currentThreadId],
148
+ queryFn: async () => {
149
+ const data = await client.threads.retrieve(currentThreadId, { userKey });
150
+ if (data.lastCompletedRunId && dispatch) {
151
+ dispatch({
152
+ type: "SET_LAST_COMPLETED_RUN_ID",
153
+ threadId: currentThreadId,
154
+ lastCompletedRunId: data.lastCompletedRunId,
155
+ });
156
+ }
157
+ return data;
158
+ },
159
+ enabled: shouldFetch,
160
+ staleTime: 1000,
161
+ refetchOnWindowFocus: false,
162
+ });
124
163
  // Sync fetched messages to stream state
125
164
  useEffect(() => {
126
- if (!isSuccess || !messagesData || !dispatch)
165
+ if (!messagesSuccess || !messagesData || !dispatch)
127
166
  return;
128
167
  if (lastSyncedThreadRef.current === currentThreadId)
129
168
  return;
@@ -134,7 +173,7 @@ function ThreadSyncManager() {
134
173
  skipIfStreaming: true,
135
174
  });
136
175
  lastSyncedThreadRef.current = currentThreadId;
137
- }, [isSuccess, messagesData, currentThreadId, dispatch]);
176
+ }, [messagesSuccess, messagesData, currentThreadId, dispatch]);
138
177
  return null;
139
178
  }
140
179
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"tambo-v1-stream-context.js","sourceRoot":"","sources":["../../../src/v1/providers/tambo-v1-stream-context.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\n\n/**\n * Stream Context Provider for v1 API\n *\n * Manages streaming state using React Context and useReducer.\n * Provides state and dispatch to child components via separate contexts\n * following the split-context pattern for optimal re-render performance.\n */\n\nimport React, {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useReducer,\n useRef,\n} from \"react\";\nimport { useTamboClient } from \"../../providers/tambo-client-provider\";\nimport { useTamboQuery } from \"../../hooks/react-query-hooks\";\nimport type { TamboV1Message } from \"../types/message\";\nimport type { TamboV1Thread } from \"../types/thread\";\nimport {\n createInitialState,\n createInitialThreadState,\n isPlaceholderThreadId,\n PLACEHOLDER_THREAD_ID,\n streamReducer,\n type StreamAction,\n type StreamState,\n} from \"../utils/event-accumulator\";\n\n/**\n * Thread management functions exposed by the stream context.\n */\nexport interface ThreadManagement {\n /**\n * Initialize a new thread in the stream context.\n * Use this before sending messages to a new thread.\n * @param threadId - The thread ID to initialize\n * @param initialThread - Optional initial thread data\n */\n initThread: (\n threadId: string,\n initialThread?: Partial<TamboV1Thread>,\n ) => void;\n\n /**\n * Switch the current active thread.\n * Does not fetch thread data - use useTamboV1Thread for that.\n * @param threadId - The thread ID to switch to\n */\n switchThread: (threadId: string) => void;\n\n /**\n * Start a new thread (generates a temporary ID).\n * The actual thread ID will be assigned when the first message is sent.\n * @returns The temporary thread ID\n */\n startNewThread: () => string;\n}\n\n/**\n * Context for accessing stream state (read-only).\n * Separated from dispatch context to prevent unnecessary re-renders.\n */\nconst StreamStateContext = createContext<StreamState | null>(null);\n\n/**\n * Context for dispatching events to the stream reducer.\n * Separated from state context to prevent unnecessary re-renders.\n */\nconst StreamDispatchContext =\n createContext<React.Dispatch<StreamAction> | null>(null);\n\n/**\n * Context for thread management functions.\n * Separated from state to prevent unnecessary re-renders.\n */\nconst ThreadManagementContext = createContext<ThreadManagement | null>(null);\n\n/**\n * Props for TamboV1StreamProvider\n */\nexport interface TamboV1StreamProviderProps {\n children: React.ReactNode;\n\n /**\n * Optional override for stream state (primarily for tests).\n * If provided, you must also provide `dispatch`.\n */\n state?: StreamState;\n\n /**\n * Optional override for stream dispatch (primarily for tests).\n * If provided, you must also provide `state`.\n */\n dispatch?: React.Dispatch<StreamAction>;\n\n /**\n * Optional override for thread management functions (primarily for tests).\n */\n threadManagement?: ThreadManagement;\n}\n\n/**\n * Provider component for stream state management.\n *\n * Uses useReducer with streamReducer to accumulate AG-UI events into\n * thread state. Provides state, dispatch, and thread management via separate contexts.\n *\n * Thread management is done programmatically via the hooks:\n * - startNewThread() - Start a new conversation\n * - switchThread(threadId) - Switch to an existing thread\n * - initThread(threadId) - Initialize a thread for receiving events\n * @returns JSX element wrapping children with stream contexts\n * @example\n * ```tsx\n * <TamboV1StreamProvider>\n * <ChatInterface />\n * </TamboV1StreamProvider>\n * ```\n */\nexport function TamboV1StreamProvider(props: TamboV1StreamProviderProps) {\n const { children, state: providedState, dispatch: providedDispatch } = props;\n\n if (\n (providedState && !providedDispatch) ||\n (!providedState && providedDispatch)\n ) {\n throw new Error(\n \"TamboV1StreamProvider requires both state and dispatch when overriding\",\n );\n }\n\n if (props.threadManagement) {\n const { initThread, switchThread, startNewThread } = props.threadManagement;\n if (\n typeof initThread !== \"function\" ||\n typeof switchThread !== \"function\" ||\n typeof startNewThread !== \"function\"\n ) {\n throw new Error(\n \"TamboV1StreamProvider: threadManagement override is missing required methods\",\n );\n }\n }\n\n // Create stable initial state - only computed once on mount\n // Uses createInitialState which sets up placeholder thread for optimistic UI\n const [state, dispatch] = useReducer(\n streamReducer,\n undefined,\n createInitialState,\n );\n\n const activeState = providedState ?? state;\n const activeDispatch = providedDispatch ?? dispatch;\n\n // Thread management functions\n const initThread = useCallback(\n (threadId: string, initialThread?: Partial<TamboV1Thread>) => {\n activeDispatch({ type: \"INIT_THREAD\", threadId, initialThread });\n },\n [activeDispatch],\n );\n\n const switchThread = useCallback(\n (threadId: string) => {\n activeDispatch({ type: \"SET_CURRENT_THREAD\", threadId });\n },\n [activeDispatch],\n );\n\n const startNewThread = useCallback(() => {\n // Reset placeholder thread to empty state and switch to it\n // This prepares for a new conversation while preserving existing threads\n activeDispatch({\n type: \"START_NEW_THREAD\",\n threadId: PLACEHOLDER_THREAD_ID,\n initialThread: createInitialThreadState(PLACEHOLDER_THREAD_ID).thread,\n });\n return PLACEHOLDER_THREAD_ID;\n }, [activeDispatch]);\n\n const threadManagement = useMemo<ThreadManagement>(() => {\n return (\n props.threadManagement ?? {\n initThread,\n switchThread,\n startNewThread,\n }\n );\n }, [props.threadManagement, initThread, switchThread, startNewThread]);\n\n return (\n <StreamStateContext.Provider value={activeState}>\n <StreamDispatchContext.Provider value={activeDispatch}>\n <ThreadManagementContext.Provider value={threadManagement}>\n <ThreadSyncManager />\n {children}\n </ThreadManagementContext.Provider>\n </StreamDispatchContext.Provider>\n </StreamStateContext.Provider>\n );\n}\n\n/**\n * Internal component that handles automatic thread message syncing.\n * Fetches thread messages when switching to a non-placeholder thread.\n * Must be used within StreamStateContext, StreamDispatchContext, and TamboClientProvider.\n * @internal\n * @returns null - this component renders nothing\n */\nfunction ThreadSyncManager(): null {\n const client = useTamboClient();\n const state = useContext(StreamStateContext);\n const dispatch = useContext(StreamDispatchContext);\n\n // Track which threads have been synced to avoid redundant fetches\n const lastSyncedThreadRef = useRef<string | null>(null);\n const currentThreadId = state?.currentThreadId ?? PLACEHOLDER_THREAD_ID;\n const threadState = state?.threadMap[currentThreadId];\n\n // Determine if we need to fetch thread messages\n // Only fetch for non-placeholder threads that haven't been synced and have no messages\n const isNotPlaceholder = !isPlaceholderThreadId(currentThreadId);\n const isNotSynced = currentThreadId !== lastSyncedThreadRef.current;\n const hasNoMessages =\n !threadState || threadState.thread.messages.length === 0;\n const shouldFetch = isNotPlaceholder && isNotSynced && hasNoMessages;\n\n // Fetch messages from the messages endpoint (not the thread endpoint)\n const { data: messagesData, isSuccess } = useTamboQuery({\n queryKey: [\"v1-thread-messages\", currentThreadId],\n queryFn: async () => await client.threads.messages.list(currentThreadId),\n enabled: shouldFetch,\n staleTime: 1000,\n refetchOnWindowFocus: false,\n });\n\n // Sync fetched messages to stream state\n useEffect(() => {\n if (!isSuccess || !messagesData || !dispatch) return;\n if (lastSyncedThreadRef.current === currentThreadId) return;\n\n dispatch({\n type: \"LOAD_THREAD_MESSAGES\",\n threadId: currentThreadId,\n messages: messagesData.messages as TamboV1Message[],\n skipIfStreaming: true,\n });\n\n lastSyncedThreadRef.current = currentThreadId;\n }, [isSuccess, messagesData, currentThreadId, dispatch]);\n\n return null;\n}\n\n/**\n * Hook to access stream state.\n *\n * Must be used within TamboV1StreamProvider.\n * @returns Current stream state\n * @throws {Error} if used outside TamboV1StreamProvider\n * @example\n * ```tsx\n * function ChatMessages() {\n * const { thread, streaming } = useStreamState();\n *\n * return (\n * <div>\n * {thread.messages.map(msg => <Message key={msg.id} message={msg} />)}\n * {streaming.status === 'streaming' && <LoadingIndicator />}\n * </div>\n * );\n * }\n * ```\n */\nexport function useStreamState(): StreamState {\n const context = useContext(StreamStateContext);\n\n if (!context) {\n throw new Error(\"useStreamState must be used within TamboV1StreamProvider\");\n }\n\n return context;\n}\n\n/**\n * Hook to access stream dispatch function.\n *\n * Must be used within TamboV1StreamProvider.\n * @returns Dispatch function for sending events to reducer\n * @throws {Error} if used outside TamboV1StreamProvider\n * @example\n * ```tsx\n * function StreamHandler() {\n * const dispatch = useStreamDispatch();\n *\n * useEffect(() => {\n * async function handleStream() {\n * for await (const event of streamEvents) {\n * dispatch({ type: 'EVENT', event });\n * }\n * }\n * handleStream();\n * }, [dispatch]);\n *\n * return null;\n * }\n * ```\n */\nexport function useStreamDispatch(): React.Dispatch<StreamAction> {\n const context = useContext(StreamDispatchContext);\n\n if (!context) {\n throw new Error(\n \"useStreamDispatch must be used within TamboV1StreamProvider\",\n );\n }\n\n return context;\n}\n\n/**\n * Hook to access thread management functions.\n *\n * Must be used within TamboV1StreamProvider.\n * @returns Thread management functions\n * @throws {Error} if used outside TamboV1StreamProvider\n * @example\n * ```tsx\n * function ThreadSwitcher() {\n * const { switchThread, startNewThread } = useThreadManagement();\n *\n * return (\n * <div>\n * <button onClick={() => switchThread('thread_123')}>\n * Load Thread\n * </button>\n * <button onClick={startNewThread}>\n * New Chat\n * </button>\n * </div>\n * );\n * }\n * ```\n */\nexport function useThreadManagement(): ThreadManagement {\n const context = useContext(ThreadManagementContext);\n\n if (!context) {\n throw new Error(\n \"useThreadManagement must be used within TamboV1StreamProvider\",\n );\n }\n\n return context;\n}\n"]}
1
+ {"version":3,"file":"tambo-v1-stream-context.js","sourceRoot":"","sources":["../../../src/v1/providers/tambo-v1-stream-context.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\n\n/**\n * Stream Context Provider for v1 API\n *\n * Manages streaming state using React Context and useReducer.\n * Provides state and dispatch to child components via separate contexts\n * following the split-context pattern for optimal re-render performance.\n */\n\nimport React, {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useReducer,\n useRef,\n} from \"react\";\nimport { useTamboQuery } from \"../../hooks/react-query-hooks\";\nimport { useTamboClient } from \"../../providers/tambo-client-provider\";\nimport type { InitialInputMessage, TamboV1Message } from \"../types/message\";\nimport type { TamboV1Thread } from \"../types/thread\";\nimport {\n createInitialState,\n createInitialStateWithMessages,\n createInitialThreadState,\n isPlaceholderThreadId,\n PLACEHOLDER_THREAD_ID,\n streamReducer,\n type StreamAction,\n type StreamState,\n} from \"../utils/event-accumulator\";\nimport { useTamboV1Config } from \"./tambo-v1-provider\";\n\n/**\n * Thread management functions exposed by the stream context.\n */\nexport interface ThreadManagement {\n /**\n * Initialize a new thread in the stream context.\n * Use this before sending messages to a new thread.\n * @param threadId - The thread ID to initialize\n * @param initialThread - Optional initial thread data\n */\n initThread: (\n threadId: string,\n initialThread?: Partial<TamboV1Thread>,\n ) => void;\n\n /**\n * Switch the current active thread.\n * Does not fetch thread data - use useTamboV1Thread for that.\n * @param threadId - The thread ID to switch to\n */\n switchThread: (threadId: string) => void;\n\n /**\n * Start a new thread (generates a temporary ID).\n * The actual thread ID will be assigned when the first message is sent.\n * @returns The temporary thread ID\n */\n startNewThread: () => string;\n}\n\n/**\n * Context for accessing stream state (read-only).\n * Separated from dispatch context to prevent unnecessary re-renders.\n */\nconst StreamStateContext = createContext<StreamState | null>(null);\n\n/**\n * Context for dispatching events to the stream reducer.\n * Separated from state context to prevent unnecessary re-renders.\n */\nconst StreamDispatchContext =\n createContext<React.Dispatch<StreamAction> | null>(null);\n\n/**\n * Context for thread management functions.\n * Separated from state to prevent unnecessary re-renders.\n */\nconst ThreadManagementContext = createContext<ThreadManagement | null>(null);\n\n/**\n * Props for TamboV1StreamProvider\n */\nexport interface TamboV1StreamProviderProps {\n children: React.ReactNode;\n\n /**\n * Initial messages to populate the placeholder thread with.\n * These render in the UI before any API call is made.\n */\n initialMessages?: InitialInputMessage[];\n\n /**\n * Optional override for stream state (primarily for tests).\n * If provided, you must also provide `dispatch`.\n */\n state?: StreamState;\n\n /**\n * Optional override for stream dispatch (primarily for tests).\n * If provided, you must also provide `state`.\n */\n dispatch?: React.Dispatch<StreamAction>;\n\n /**\n * Optional override for thread management functions (primarily for tests).\n */\n threadManagement?: ThreadManagement;\n}\n\n/**\n * Provider component for stream state management.\n *\n * Uses useReducer with streamReducer to accumulate AG-UI events into\n * thread state. Provides state, dispatch, and thread management via separate contexts.\n *\n * Thread management is done programmatically via the hooks:\n * - startNewThread() - Start a new conversation\n * - switchThread(threadId) - Switch to an existing thread\n * - initThread(threadId) - Initialize a thread for receiving events\n * @returns JSX element wrapping children with stream contexts\n * @example\n * ```tsx\n * <TamboV1StreamProvider>\n * <ChatInterface />\n * </TamboV1StreamProvider>\n * ```\n */\nexport function TamboV1StreamProvider(props: TamboV1StreamProviderProps) {\n const {\n children,\n initialMessages,\n state: providedState,\n dispatch: providedDispatch,\n } = props;\n\n if (\n (providedState && !providedDispatch) ||\n (!providedState && providedDispatch)\n ) {\n throw new Error(\n \"TamboV1StreamProvider requires both state and dispatch when overriding\",\n );\n }\n\n if (props.threadManagement) {\n const { initThread, switchThread, startNewThread } = props.threadManagement;\n if (\n typeof initThread !== \"function\" ||\n typeof switchThread !== \"function\" ||\n typeof startNewThread !== \"function\"\n ) {\n throw new Error(\n \"TamboV1StreamProvider: threadManagement override is missing required methods\",\n );\n }\n }\n\n // Create stable initial state - only computed once on mount\n // Uses createInitialState which sets up placeholder thread for optimistic UI\n // If initialMessages are provided, the placeholder thread is seeded with them\n const [state, dispatch] = useReducer(\n streamReducer,\n initialMessages,\n (msgs) =>\n msgs?.length\n ? createInitialStateWithMessages(msgs)\n : createInitialState(),\n );\n\n const activeState = providedState ?? state;\n const activeDispatch = providedDispatch ?? dispatch;\n\n // Thread management functions\n const initThread = useCallback(\n (threadId: string, initialThread?: Partial<TamboV1Thread>) => {\n activeDispatch({ type: \"INIT_THREAD\", threadId, initialThread });\n },\n [activeDispatch],\n );\n\n const switchThread = useCallback(\n (threadId: string) => {\n activeDispatch({ type: \"SET_CURRENT_THREAD\", threadId });\n },\n [activeDispatch],\n );\n\n const startNewThread = useCallback(() => {\n // Reset placeholder thread and switch to it\n // This prepares for a new conversation while preserving existing threads.\n // If initialMessages were provided, re-seed the placeholder with them.\n const baseThread = createInitialThreadState(PLACEHOLDER_THREAD_ID).thread;\n const threadWithMessages = initialMessages?.length\n ? {\n ...baseThread,\n messages: initialMessages.map(\n (msg): TamboV1Message => ({\n id: `initial_${crypto.randomUUID()}`,\n role: msg.role,\n content: msg.content.map((c) => {\n if (c.type === \"text\") {\n return { type: \"text\" as const, text: c.text };\n }\n return c;\n }),\n }),\n ),\n }\n : baseThread;\n activeDispatch({\n type: \"START_NEW_THREAD\",\n threadId: PLACEHOLDER_THREAD_ID,\n initialThread: threadWithMessages,\n });\n return PLACEHOLDER_THREAD_ID;\n }, [activeDispatch, initialMessages]);\n\n const threadManagement = useMemo<ThreadManagement>(() => {\n return (\n props.threadManagement ?? {\n initThread,\n switchThread,\n startNewThread,\n }\n );\n }, [props.threadManagement, initThread, switchThread, startNewThread]);\n\n return (\n <StreamStateContext.Provider value={activeState}>\n <StreamDispatchContext.Provider value={activeDispatch}>\n <ThreadManagementContext.Provider value={threadManagement}>\n <ThreadSyncManager />\n {children}\n </ThreadManagementContext.Provider>\n </StreamDispatchContext.Provider>\n </StreamStateContext.Provider>\n );\n}\n\n/**\n * Internal component that handles automatic thread message syncing.\n * Fetches thread messages when switching to a non-placeholder thread.\n * Must be used within StreamStateContext, StreamDispatchContext, and TamboClientProvider.\n * @internal\n * @returns null - this component renders nothing\n */\nfunction ThreadSyncManager(): null {\n const client = useTamboClient();\n const { userKey } = useTamboV1Config();\n const state = useContext(StreamStateContext);\n const dispatch = useContext(StreamDispatchContext);\n\n // Track which threads have been synced to avoid redundant fetches\n const lastSyncedThreadRef = useRef<string | null>(null);\n const currentThreadId = state?.currentThreadId ?? PLACEHOLDER_THREAD_ID;\n const threadState = state?.threadMap[currentThreadId];\n\n // Determine if we need to fetch thread messages\n // Only fetch for non-placeholder threads that haven't been synced and have no messages\n const isNotPlaceholder = !isPlaceholderThreadId(currentThreadId);\n const isNotSynced = currentThreadId !== lastSyncedThreadRef.current;\n const hasNoMessages =\n !threadState || threadState.thread.messages.length === 0;\n const shouldFetch = isNotPlaceholder && isNotSynced && hasNoMessages;\n\n // Fetch messages and thread metadata in parallel\n const { data: messagesData, isSuccess: messagesSuccess } = useTamboQuery({\n queryKey: [\"v1-thread-messages\", currentThreadId],\n queryFn: async () => await client.threads.messages.list(currentThreadId),\n enabled: shouldFetch,\n staleTime: 1000,\n refetchOnWindowFocus: false,\n });\n\n useTamboQuery({\n queryKey: [\"v1-thread-metadata\", currentThreadId],\n queryFn: async () => {\n const data = await client.threads.retrieve(currentThreadId, { userKey });\n if (data.lastCompletedRunId && dispatch) {\n dispatch({\n type: \"SET_LAST_COMPLETED_RUN_ID\",\n threadId: currentThreadId,\n lastCompletedRunId: data.lastCompletedRunId,\n });\n }\n return data;\n },\n enabled: shouldFetch,\n staleTime: 1000,\n refetchOnWindowFocus: false,\n });\n\n // Sync fetched messages to stream state\n useEffect(() => {\n if (!messagesSuccess || !messagesData || !dispatch) return;\n if (lastSyncedThreadRef.current === currentThreadId) return;\n\n dispatch({\n type: \"LOAD_THREAD_MESSAGES\",\n threadId: currentThreadId,\n messages: messagesData.messages as TamboV1Message[],\n skipIfStreaming: true,\n });\n\n lastSyncedThreadRef.current = currentThreadId;\n }, [messagesSuccess, messagesData, currentThreadId, dispatch]);\n\n return null;\n}\n\n/**\n * Hook to access stream state.\n *\n * Must be used within TamboV1StreamProvider.\n * @returns Current stream state\n * @throws {Error} if used outside TamboV1StreamProvider\n * @example\n * ```tsx\n * function ChatMessages() {\n * const { thread, streaming } = useStreamState();\n *\n * return (\n * <div>\n * {thread.messages.map(msg => <Message key={msg.id} message={msg} />)}\n * {streaming.status === 'streaming' && <LoadingIndicator />}\n * </div>\n * );\n * }\n * ```\n */\nexport function useStreamState(): StreamState {\n const context = useContext(StreamStateContext);\n\n if (!context) {\n throw new Error(\"useStreamState must be used within TamboV1StreamProvider\");\n }\n\n return context;\n}\n\n/**\n * Hook to access stream dispatch function.\n *\n * Must be used within TamboV1StreamProvider.\n * @returns Dispatch function for sending events to reducer\n * @throws {Error} if used outside TamboV1StreamProvider\n * @example\n * ```tsx\n * function StreamHandler() {\n * const dispatch = useStreamDispatch();\n *\n * useEffect(() => {\n * async function handleStream() {\n * for await (const event of streamEvents) {\n * dispatch({ type: 'EVENT', event });\n * }\n * }\n * handleStream();\n * }, [dispatch]);\n *\n * return null;\n * }\n * ```\n */\nexport function useStreamDispatch(): React.Dispatch<StreamAction> {\n const context = useContext(StreamDispatchContext);\n\n if (!context) {\n throw new Error(\n \"useStreamDispatch must be used within TamboV1StreamProvider\",\n );\n }\n\n return context;\n}\n\n/**\n * Hook to access thread management functions.\n *\n * Must be used within TamboV1StreamProvider.\n * @returns Thread management functions\n * @throws {Error} if used outside TamboV1StreamProvider\n * @example\n * ```tsx\n * function ThreadSwitcher() {\n * const { switchThread, startNewThread } = useThreadManagement();\n *\n * return (\n * <div>\n * <button onClick={() => switchThread('thread_123')}>\n * Load Thread\n * </button>\n * <button onClick={startNewThread}>\n * New Chat\n * </button>\n * </div>\n * );\n * }\n * ```\n */\nexport function useThreadManagement(): ThreadManagement {\n const context = useContext(ThreadManagementContext);\n\n if (!context) {\n throw new Error(\n \"useThreadManagement must be used within TamboV1StreamProvider\",\n );\n }\n\n return context;\n}\n"]}