@tambo-ai/react 0.70.0 → 0.72.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 (305) hide show
  1. package/dist/v1/hooks/use-tambo-v1-component-state.d.ts +44 -0
  2. package/dist/v1/hooks/use-tambo-v1-component-state.d.ts.map +1 -0
  3. package/dist/v1/hooks/use-tambo-v1-component-state.js +134 -0
  4. package/dist/v1/hooks/use-tambo-v1-component-state.js.map +1 -0
  5. package/dist/v1/hooks/use-tambo-v1-component-state.test.d.ts +2 -0
  6. package/dist/v1/hooks/use-tambo-v1-component-state.test.d.ts.map +1 -0
  7. package/dist/v1/hooks/use-tambo-v1-component-state.test.js +292 -0
  8. package/dist/v1/hooks/use-tambo-v1-component-state.test.js.map +1 -0
  9. package/dist/v1/hooks/use-tambo-v1-messages.d.ts +58 -0
  10. package/dist/v1/hooks/use-tambo-v1-messages.d.ts.map +1 -0
  11. package/dist/v1/hooks/use-tambo-v1-messages.js +54 -0
  12. package/dist/v1/hooks/use-tambo-v1-messages.js.map +1 -0
  13. package/dist/v1/hooks/use-tambo-v1-messages.test.d.ts +2 -0
  14. package/dist/v1/hooks/use-tambo-v1-messages.test.d.ts.map +1 -0
  15. package/dist/v1/hooks/use-tambo-v1-messages.test.js +137 -0
  16. package/dist/v1/hooks/use-tambo-v1-messages.test.js.map +1 -0
  17. package/dist/v1/hooks/use-tambo-v1-send-message.d.ts +96 -0
  18. package/dist/v1/hooks/use-tambo-v1-send-message.d.ts.map +1 -0
  19. package/dist/v1/hooks/use-tambo-v1-send-message.js +227 -0
  20. package/dist/v1/hooks/use-tambo-v1-send-message.js.map +1 -0
  21. package/dist/v1/hooks/use-tambo-v1-send-message.test.d.ts +2 -0
  22. package/dist/v1/hooks/use-tambo-v1-send-message.test.d.ts.map +1 -0
  23. package/dist/v1/hooks/use-tambo-v1-send-message.test.js +827 -0
  24. package/dist/v1/hooks/use-tambo-v1-send-message.test.js.map +1 -0
  25. package/dist/v1/hooks/use-tambo-v1-thread-input.d.ts +62 -0
  26. package/dist/v1/hooks/use-tambo-v1-thread-input.d.ts.map +1 -0
  27. package/dist/v1/hooks/use-tambo-v1-thread-input.js +76 -0
  28. package/dist/v1/hooks/use-tambo-v1-thread-input.js.map +1 -0
  29. package/dist/v1/hooks/use-tambo-v1-thread-input.test.d.ts +2 -0
  30. package/dist/v1/hooks/use-tambo-v1-thread-input.test.d.ts.map +1 -0
  31. package/dist/v1/hooks/use-tambo-v1-thread-input.test.js +168 -0
  32. package/dist/v1/hooks/use-tambo-v1-thread-input.test.js.map +1 -0
  33. package/dist/v1/hooks/use-tambo-v1-thread-list.d.ts +61 -0
  34. package/dist/v1/hooks/use-tambo-v1-thread-list.d.ts.map +1 -0
  35. package/dist/v1/hooks/use-tambo-v1-thread-list.js +56 -0
  36. package/dist/v1/hooks/use-tambo-v1-thread-list.js.map +1 -0
  37. package/dist/v1/hooks/use-tambo-v1-thread-list.test.d.ts +2 -0
  38. package/dist/v1/hooks/use-tambo-v1-thread-list.test.d.ts.map +1 -0
  39. package/dist/v1/hooks/use-tambo-v1-thread-list.test.js +98 -0
  40. package/dist/v1/hooks/use-tambo-v1-thread-list.test.js.map +1 -0
  41. package/dist/v1/hooks/use-tambo-v1-thread.d.ts +37 -0
  42. package/dist/v1/hooks/use-tambo-v1-thread.d.ts.map +1 -0
  43. package/dist/v1/hooks/use-tambo-v1-thread.js +49 -0
  44. package/dist/v1/hooks/use-tambo-v1-thread.js.map +1 -0
  45. package/dist/v1/hooks/use-tambo-v1-thread.test.d.ts +2 -0
  46. package/dist/v1/hooks/use-tambo-v1-thread.test.d.ts.map +1 -0
  47. package/dist/v1/hooks/use-tambo-v1-thread.test.js +83 -0
  48. package/dist/v1/hooks/use-tambo-v1-thread.test.js.map +1 -0
  49. package/dist/v1/hooks/use-tambo-v1.d.ts +107 -0
  50. package/dist/v1/hooks/use-tambo-v1.d.ts.map +1 -0
  51. package/dist/v1/hooks/use-tambo-v1.js +87 -0
  52. package/dist/v1/hooks/use-tambo-v1.js.map +1 -0
  53. package/dist/v1/hooks/use-tambo-v1.test.d.ts +2 -0
  54. package/dist/v1/hooks/use-tambo-v1.test.d.ts.map +1 -0
  55. package/dist/v1/hooks/use-tambo-v1.test.js +150 -0
  56. package/dist/v1/hooks/use-tambo-v1.test.js.map +1 -0
  57. package/dist/v1/index.d.ts +65 -16
  58. package/dist/v1/index.d.ts.map +1 -1
  59. package/dist/v1/index.js +119 -26
  60. package/dist/v1/index.js.map +1 -1
  61. package/dist/v1/providers/tambo-v1-provider.d.ts +133 -0
  62. package/dist/v1/providers/tambo-v1-provider.d.ts.map +1 -0
  63. package/dist/v1/providers/tambo-v1-provider.js +131 -0
  64. package/dist/v1/providers/tambo-v1-provider.js.map +1 -0
  65. package/dist/v1/providers/tambo-v1-provider.test.d.ts +2 -0
  66. package/dist/v1/providers/tambo-v1-provider.test.d.ts.map +1 -0
  67. package/dist/v1/providers/tambo-v1-provider.test.js +181 -0
  68. package/dist/v1/providers/tambo-v1-provider.test.js.map +1 -0
  69. package/dist/v1/providers/tambo-v1-stream-context.d.ts +136 -0
  70. package/dist/v1/providers/tambo-v1-stream-context.d.ts.map +1 -0
  71. package/dist/v1/providers/tambo-v1-stream-context.js +230 -0
  72. package/dist/v1/providers/tambo-v1-stream-context.js.map +1 -0
  73. package/dist/v1/providers/tambo-v1-stream-context.test.d.ts +2 -0
  74. package/dist/v1/providers/tambo-v1-stream-context.test.d.ts.map +1 -0
  75. package/dist/v1/providers/tambo-v1-stream-context.test.js +85 -0
  76. package/dist/v1/providers/tambo-v1-stream-context.test.js.map +1 -0
  77. package/dist/v1/types/component.d.ts +5 -2
  78. package/dist/v1/types/component.d.ts.map +1 -1
  79. package/dist/v1/types/component.js +5 -2
  80. package/dist/v1/types/component.js.map +1 -1
  81. package/dist/v1/types/event.d.ts +21 -12
  82. package/dist/v1/types/event.d.ts.map +1 -1
  83. package/dist/v1/types/event.js +46 -1
  84. package/dist/v1/types/event.js.map +1 -1
  85. package/dist/v1/types/event.test.d.ts +2 -0
  86. package/dist/v1/types/event.test.d.ts.map +1 -0
  87. package/dist/v1/types/event.test.js +70 -0
  88. package/dist/v1/types/event.test.js.map +1 -0
  89. package/dist/v1/types/message.d.ts +30 -9
  90. package/dist/v1/types/message.d.ts.map +1 -1
  91. package/dist/v1/types/message.js +1 -1
  92. package/dist/v1/types/message.js.map +1 -1
  93. package/dist/v1/types/thread.d.ts +1 -3
  94. package/dist/v1/types/thread.d.ts.map +1 -1
  95. package/dist/v1/types/thread.js +1 -1
  96. package/dist/v1/types/thread.js.map +1 -1
  97. package/dist/v1/utils/component-renderer.d.ts +89 -0
  98. package/dist/v1/utils/component-renderer.d.ts.map +1 -0
  99. package/dist/v1/utils/component-renderer.js +216 -0
  100. package/dist/v1/utils/component-renderer.js.map +1 -0
  101. package/dist/v1/utils/component-renderer.test.d.ts +2 -0
  102. package/dist/v1/utils/component-renderer.test.d.ts.map +1 -0
  103. package/dist/v1/utils/component-renderer.test.js +380 -0
  104. package/dist/v1/utils/component-renderer.test.js.map +1 -0
  105. package/dist/v1/utils/event-accumulator.d.ts +100 -0
  106. package/dist/v1/utils/event-accumulator.d.ts.map +1 -0
  107. package/dist/v1/utils/event-accumulator.js +735 -0
  108. package/dist/v1/utils/event-accumulator.js.map +1 -0
  109. package/dist/v1/utils/event-accumulator.test.d.ts +2 -0
  110. package/dist/v1/utils/event-accumulator.test.d.ts.map +1 -0
  111. package/dist/v1/utils/event-accumulator.test.js +1205 -0
  112. package/dist/v1/utils/event-accumulator.test.js.map +1 -0
  113. package/dist/v1/utils/json-patch.d.ts +18 -0
  114. package/dist/v1/utils/json-patch.d.ts.map +1 -0
  115. package/dist/v1/utils/json-patch.js +35 -0
  116. package/dist/v1/utils/json-patch.js.map +1 -0
  117. package/dist/v1/utils/json-patch.test.d.ts +2 -0
  118. package/dist/v1/utils/json-patch.test.d.ts.map +1 -0
  119. package/dist/v1/utils/json-patch.test.js +28 -0
  120. package/dist/v1/utils/json-patch.test.js.map +1 -0
  121. package/dist/v1/utils/registry-conversion.d.ts +53 -0
  122. package/dist/v1/utils/registry-conversion.d.ts.map +1 -0
  123. package/dist/v1/utils/registry-conversion.js +114 -0
  124. package/dist/v1/utils/registry-conversion.js.map +1 -0
  125. package/dist/v1/utils/registry-conversion.test.d.ts +2 -0
  126. package/dist/v1/utils/registry-conversion.test.d.ts.map +1 -0
  127. package/dist/v1/utils/registry-conversion.test.js +179 -0
  128. package/dist/v1/utils/registry-conversion.test.js.map +1 -0
  129. package/dist/v1/utils/stream-handler.d.ts +45 -0
  130. package/dist/v1/utils/stream-handler.d.ts.map +1 -0
  131. package/dist/v1/utils/stream-handler.js +47 -0
  132. package/dist/v1/utils/stream-handler.js.map +1 -0
  133. package/dist/v1/utils/stream-handler.test.d.ts +2 -0
  134. package/dist/v1/utils/stream-handler.test.d.ts.map +1 -0
  135. package/dist/v1/utils/stream-handler.test.js +74 -0
  136. package/dist/v1/utils/stream-handler.test.js.map +1 -0
  137. package/dist/v1/utils/tool-call-tracker.d.ts +41 -0
  138. package/dist/v1/utils/tool-call-tracker.d.ts.map +1 -0
  139. package/dist/v1/utils/tool-call-tracker.js +90 -0
  140. package/dist/v1/utils/tool-call-tracker.js.map +1 -0
  141. package/dist/v1/utils/tool-executor.d.ts +33 -0
  142. package/dist/v1/utils/tool-executor.d.ts.map +1 -0
  143. package/dist/v1/utils/tool-executor.js +103 -0
  144. package/dist/v1/utils/tool-executor.js.map +1 -0
  145. package/dist/v1/utils/tool-executor.test.d.ts +2 -0
  146. package/dist/v1/utils/tool-executor.test.d.ts.map +1 -0
  147. package/dist/v1/utils/tool-executor.test.js +222 -0
  148. package/dist/v1/utils/tool-executor.test.js.map +1 -0
  149. package/esm/v1/hooks/use-tambo-v1-component-state.d.ts +44 -0
  150. package/esm/v1/hooks/use-tambo-v1-component-state.d.ts.map +1 -0
  151. package/esm/v1/hooks/use-tambo-v1-component-state.js +131 -0
  152. package/esm/v1/hooks/use-tambo-v1-component-state.js.map +1 -0
  153. package/esm/v1/hooks/use-tambo-v1-component-state.test.d.ts +2 -0
  154. package/esm/v1/hooks/use-tambo-v1-component-state.test.d.ts.map +1 -0
  155. package/esm/v1/hooks/use-tambo-v1-component-state.test.js +290 -0
  156. package/esm/v1/hooks/use-tambo-v1-component-state.test.js.map +1 -0
  157. package/esm/v1/hooks/use-tambo-v1-messages.d.ts +58 -0
  158. package/esm/v1/hooks/use-tambo-v1-messages.d.ts.map +1 -0
  159. package/esm/v1/hooks/use-tambo-v1-messages.js +51 -0
  160. package/esm/v1/hooks/use-tambo-v1-messages.js.map +1 -0
  161. package/esm/v1/hooks/use-tambo-v1-messages.test.d.ts +2 -0
  162. package/esm/v1/hooks/use-tambo-v1-messages.test.d.ts.map +1 -0
  163. package/esm/v1/hooks/use-tambo-v1-messages.test.js +132 -0
  164. package/esm/v1/hooks/use-tambo-v1-messages.test.js.map +1 -0
  165. package/esm/v1/hooks/use-tambo-v1-send-message.d.ts +96 -0
  166. package/esm/v1/hooks/use-tambo-v1-send-message.d.ts.map +1 -0
  167. package/esm/v1/hooks/use-tambo-v1-send-message.js +223 -0
  168. package/esm/v1/hooks/use-tambo-v1-send-message.js.map +1 -0
  169. package/esm/v1/hooks/use-tambo-v1-send-message.test.d.ts +2 -0
  170. package/esm/v1/hooks/use-tambo-v1-send-message.test.d.ts.map +1 -0
  171. package/esm/v1/hooks/use-tambo-v1-send-message.test.js +822 -0
  172. package/esm/v1/hooks/use-tambo-v1-send-message.test.js.map +1 -0
  173. package/esm/v1/hooks/use-tambo-v1-thread-input.d.ts +62 -0
  174. package/esm/v1/hooks/use-tambo-v1-thread-input.d.ts.map +1 -0
  175. package/esm/v1/hooks/use-tambo-v1-thread-input.js +73 -0
  176. package/esm/v1/hooks/use-tambo-v1-thread-input.js.map +1 -0
  177. package/esm/v1/hooks/use-tambo-v1-thread-input.test.d.ts +2 -0
  178. package/esm/v1/hooks/use-tambo-v1-thread-input.test.d.ts.map +1 -0
  179. package/esm/v1/hooks/use-tambo-v1-thread-input.test.js +166 -0
  180. package/esm/v1/hooks/use-tambo-v1-thread-input.test.js.map +1 -0
  181. package/esm/v1/hooks/use-tambo-v1-thread-list.d.ts +61 -0
  182. package/esm/v1/hooks/use-tambo-v1-thread-list.d.ts.map +1 -0
  183. package/esm/v1/hooks/use-tambo-v1-thread-list.js +53 -0
  184. package/esm/v1/hooks/use-tambo-v1-thread-list.js.map +1 -0
  185. package/esm/v1/hooks/use-tambo-v1-thread-list.test.d.ts +2 -0
  186. package/esm/v1/hooks/use-tambo-v1-thread-list.test.d.ts.map +1 -0
  187. package/esm/v1/hooks/use-tambo-v1-thread-list.test.js +93 -0
  188. package/esm/v1/hooks/use-tambo-v1-thread-list.test.js.map +1 -0
  189. package/esm/v1/hooks/use-tambo-v1-thread.d.ts +37 -0
  190. package/esm/v1/hooks/use-tambo-v1-thread.d.ts.map +1 -0
  191. package/esm/v1/hooks/use-tambo-v1-thread.js +46 -0
  192. package/esm/v1/hooks/use-tambo-v1-thread.js.map +1 -0
  193. package/esm/v1/hooks/use-tambo-v1-thread.test.d.ts +2 -0
  194. package/esm/v1/hooks/use-tambo-v1-thread.test.d.ts.map +1 -0
  195. package/esm/v1/hooks/use-tambo-v1-thread.test.js +78 -0
  196. package/esm/v1/hooks/use-tambo-v1-thread.test.js.map +1 -0
  197. package/esm/v1/hooks/use-tambo-v1.d.ts +107 -0
  198. package/esm/v1/hooks/use-tambo-v1.d.ts.map +1 -0
  199. package/esm/v1/hooks/use-tambo-v1.js +84 -0
  200. package/esm/v1/hooks/use-tambo-v1.js.map +1 -0
  201. package/esm/v1/hooks/use-tambo-v1.test.d.ts +2 -0
  202. package/esm/v1/hooks/use-tambo-v1.test.d.ts.map +1 -0
  203. package/esm/v1/hooks/use-tambo-v1.test.js +145 -0
  204. package/esm/v1/hooks/use-tambo-v1.test.js.map +1 -0
  205. package/esm/v1/index.d.ts +65 -16
  206. package/esm/v1/index.d.ts.map +1 -1
  207. package/esm/v1/index.js +83 -27
  208. package/esm/v1/index.js.map +1 -1
  209. package/esm/v1/providers/tambo-v1-provider.d.ts +133 -0
  210. package/esm/v1/providers/tambo-v1-provider.d.ts.map +1 -0
  211. package/esm/v1/providers/tambo-v1-provider.js +94 -0
  212. package/esm/v1/providers/tambo-v1-provider.js.map +1 -0
  213. package/esm/v1/providers/tambo-v1-provider.test.d.ts +2 -0
  214. package/esm/v1/providers/tambo-v1-provider.test.d.ts.map +1 -0
  215. package/esm/v1/providers/tambo-v1-provider.test.js +176 -0
  216. package/esm/v1/providers/tambo-v1-provider.test.js.map +1 -0
  217. package/esm/v1/providers/tambo-v1-stream-context.d.ts +136 -0
  218. package/esm/v1/providers/tambo-v1-stream-context.d.ts.map +1 -0
  219. package/esm/v1/providers/tambo-v1-stream-context.js +191 -0
  220. package/esm/v1/providers/tambo-v1-stream-context.js.map +1 -0
  221. package/esm/v1/providers/tambo-v1-stream-context.test.d.ts +2 -0
  222. package/esm/v1/providers/tambo-v1-stream-context.test.d.ts.map +1 -0
  223. package/esm/v1/providers/tambo-v1-stream-context.test.js +80 -0
  224. package/esm/v1/providers/tambo-v1-stream-context.test.js.map +1 -0
  225. package/esm/v1/types/component.d.ts +5 -2
  226. package/esm/v1/types/component.d.ts.map +1 -1
  227. package/esm/v1/types/component.js +5 -2
  228. package/esm/v1/types/component.js.map +1 -1
  229. package/esm/v1/types/event.d.ts +21 -12
  230. package/esm/v1/types/event.d.ts.map +1 -1
  231. package/esm/v1/types/event.js +44 -2
  232. package/esm/v1/types/event.js.map +1 -1
  233. package/esm/v1/types/event.test.d.ts +2 -0
  234. package/esm/v1/types/event.test.d.ts.map +1 -0
  235. package/esm/v1/types/event.test.js +68 -0
  236. package/esm/v1/types/event.test.js.map +1 -0
  237. package/esm/v1/types/message.d.ts +30 -9
  238. package/esm/v1/types/message.d.ts.map +1 -1
  239. package/esm/v1/types/message.js +1 -1
  240. package/esm/v1/types/message.js.map +1 -1
  241. package/esm/v1/types/thread.d.ts +1 -3
  242. package/esm/v1/types/thread.d.ts.map +1 -1
  243. package/esm/v1/types/thread.js +1 -1
  244. package/esm/v1/types/thread.js.map +1 -1
  245. package/esm/v1/utils/component-renderer.d.ts +89 -0
  246. package/esm/v1/utils/component-renderer.d.ts.map +1 -0
  247. package/esm/v1/utils/component-renderer.js +175 -0
  248. package/esm/v1/utils/component-renderer.js.map +1 -0
  249. package/esm/v1/utils/component-renderer.test.d.ts +2 -0
  250. package/esm/v1/utils/component-renderer.test.d.ts.map +1 -0
  251. package/esm/v1/utils/component-renderer.test.js +375 -0
  252. package/esm/v1/utils/component-renderer.test.js.map +1 -0
  253. package/esm/v1/utils/event-accumulator.d.ts +100 -0
  254. package/esm/v1/utils/event-accumulator.d.ts.map +1 -0
  255. package/esm/v1/utils/event-accumulator.js +728 -0
  256. package/esm/v1/utils/event-accumulator.js.map +1 -0
  257. package/esm/v1/utils/event-accumulator.test.d.ts +2 -0
  258. package/esm/v1/utils/event-accumulator.test.d.ts.map +1 -0
  259. package/esm/v1/utils/event-accumulator.test.js +1203 -0
  260. package/esm/v1/utils/event-accumulator.test.js.map +1 -0
  261. package/esm/v1/utils/json-patch.d.ts +18 -0
  262. package/esm/v1/utils/json-patch.d.ts.map +1 -0
  263. package/esm/v1/utils/json-patch.js +32 -0
  264. package/esm/v1/utils/json-patch.js.map +1 -0
  265. package/esm/v1/utils/json-patch.test.d.ts +2 -0
  266. package/esm/v1/utils/json-patch.test.d.ts.map +1 -0
  267. package/esm/v1/utils/json-patch.test.js +26 -0
  268. package/esm/v1/utils/json-patch.test.js.map +1 -0
  269. package/esm/v1/utils/registry-conversion.d.ts +53 -0
  270. package/esm/v1/utils/registry-conversion.d.ts.map +1 -0
  271. package/esm/v1/utils/registry-conversion.js +108 -0
  272. package/esm/v1/utils/registry-conversion.js.map +1 -0
  273. package/esm/v1/utils/registry-conversion.test.d.ts +2 -0
  274. package/esm/v1/utils/registry-conversion.test.d.ts.map +1 -0
  275. package/esm/v1/utils/registry-conversion.test.js +177 -0
  276. package/esm/v1/utils/registry-conversion.test.js.map +1 -0
  277. package/esm/v1/utils/stream-handler.d.ts +45 -0
  278. package/esm/v1/utils/stream-handler.d.ts.map +1 -0
  279. package/esm/v1/utils/stream-handler.js +44 -0
  280. package/esm/v1/utils/stream-handler.js.map +1 -0
  281. package/esm/v1/utils/stream-handler.test.d.ts +2 -0
  282. package/esm/v1/utils/stream-handler.test.d.ts.map +1 -0
  283. package/esm/v1/utils/stream-handler.test.js +72 -0
  284. package/esm/v1/utils/stream-handler.test.js.map +1 -0
  285. package/esm/v1/utils/tool-call-tracker.d.ts +41 -0
  286. package/esm/v1/utils/tool-call-tracker.d.ts.map +1 -0
  287. package/esm/v1/utils/tool-call-tracker.js +86 -0
  288. package/esm/v1/utils/tool-call-tracker.js.map +1 -0
  289. package/esm/v1/utils/tool-executor.d.ts +33 -0
  290. package/esm/v1/utils/tool-executor.d.ts.map +1 -0
  291. package/esm/v1/utils/tool-executor.js +99 -0
  292. package/esm/v1/utils/tool-executor.js.map +1 -0
  293. package/esm/v1/utils/tool-executor.test.d.ts +2 -0
  294. package/esm/v1/utils/tool-executor.test.d.ts.map +1 -0
  295. package/esm/v1/utils/tool-executor.test.js +220 -0
  296. package/esm/v1/utils/tool-executor.test.js.map +1 -0
  297. package/package.json +7 -6
  298. package/dist/v1/types/tool.d.ts +0 -52
  299. package/dist/v1/types/tool.d.ts.map +0 -1
  300. package/dist/v1/types/tool.js +0 -11
  301. package/dist/v1/types/tool.js.map +0 -1
  302. package/esm/v1/types/tool.d.ts +0 -52
  303. package/esm/v1/types/tool.d.ts.map +0 -1
  304. package/esm/v1/types/tool.js +0 -10
  305. package/esm/v1/types/tool.js.map +0 -1
@@ -0,0 +1,191 @@
1
+ "use client";
2
+ /**
3
+ * Stream Context Provider for v1 API
4
+ *
5
+ * Manages streaming state using React Context and useReducer.
6
+ * Provides state and dispatch to child components via separate contexts
7
+ * following the split-context pattern for optimal re-render performance.
8
+ */
9
+ // React is used implicitly for JSX transformation (jsx: "react" in tsconfig)
10
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
11
+ import React, { createContext, useReducer, useContext, useMemo, useCallback, } from "react";
12
+ import { streamReducer, createInitialThreadState, } from "../utils/event-accumulator";
13
+ /**
14
+ * Context for accessing stream state (read-only).
15
+ * Separated from dispatch context to prevent unnecessary re-renders.
16
+ */
17
+ const StreamStateContext = createContext(null);
18
+ /**
19
+ * Context for dispatching events to the stream reducer.
20
+ * Separated from state context to prevent unnecessary re-renders.
21
+ */
22
+ const StreamDispatchContext = createContext(null);
23
+ /**
24
+ * Context for thread management functions.
25
+ * Separated from state to prevent unnecessary re-renders.
26
+ */
27
+ const ThreadManagementContext = createContext(null);
28
+ /**
29
+ * Creates initial stream state from props.
30
+ * @param props - Provider props
31
+ * @returns Initial stream state
32
+ */
33
+ function createInitialState(props) {
34
+ const { initialThread, threadId } = props;
35
+ // Initialize with empty threadMap
36
+ const threadMap = {};
37
+ // If threadId is provided, initialize that thread
38
+ if (threadId) {
39
+ // Create initial thread state (immutably)
40
+ const baseState = createInitialThreadState(threadId);
41
+ // If initial thread data provided, merge it immutably
42
+ const threadState = initialThread
43
+ ? {
44
+ ...baseState,
45
+ thread: {
46
+ ...baseState.thread,
47
+ ...initialThread,
48
+ id: threadId, // Always use the provided threadId
49
+ },
50
+ }
51
+ : baseState;
52
+ threadMap[threadId] = threadState;
53
+ }
54
+ return {
55
+ threadMap,
56
+ currentThreadId: threadId ?? null,
57
+ };
58
+ }
59
+ /**
60
+ * Provider component for stream state management.
61
+ *
62
+ * Uses useReducer with streamReducer to accumulate AG-UI events into
63
+ * thread state. Provides state, dispatch, and thread management via separate contexts.
64
+ * @returns JSX element wrapping children with stream contexts
65
+ * @example
66
+ * ```tsx
67
+ * <TamboV1StreamProvider threadId="thread_123">
68
+ * <ChatInterface />
69
+ * </TamboV1StreamProvider>
70
+ * ```
71
+ */
72
+ export function TamboV1StreamProvider(props) {
73
+ const { children } = props;
74
+ const initialState = useMemo(() => createInitialState(props),
75
+ // Only recompute if threadId changes
76
+ // eslint-disable-next-line react-hooks/exhaustive-deps
77
+ [props.threadId]);
78
+ const [state, dispatch] = useReducer(streamReducer, initialState);
79
+ // Thread management functions
80
+ const initThread = useCallback((threadId, initialThread) => {
81
+ dispatch({ type: "INIT_THREAD", threadId, initialThread });
82
+ }, []);
83
+ const switchThread = useCallback((threadId) => {
84
+ dispatch({ type: "SET_CURRENT_THREAD", threadId });
85
+ }, []);
86
+ const startNewThread = useCallback(() => {
87
+ const tempId = `temp_${crypto.randomUUID()}`;
88
+ // Use atomic START_NEW_THREAD action to prevent race conditions
89
+ // when multiple calls happen concurrently (e.g., double-click)
90
+ dispatch({ type: "START_NEW_THREAD", threadId: tempId });
91
+ return tempId;
92
+ }, []);
93
+ const threadManagement = useMemo(() => ({
94
+ initThread,
95
+ switchThread,
96
+ startNewThread,
97
+ }), [initThread, switchThread, startNewThread]);
98
+ return (React.createElement(StreamStateContext.Provider, { value: state },
99
+ React.createElement(StreamDispatchContext.Provider, { value: dispatch },
100
+ React.createElement(ThreadManagementContext.Provider, { value: threadManagement }, children))));
101
+ }
102
+ /**
103
+ * Hook to access stream state.
104
+ *
105
+ * Must be used within TamboV1StreamProvider.
106
+ * @returns Current stream state
107
+ * @throws {Error} if used outside TamboV1StreamProvider
108
+ * @example
109
+ * ```tsx
110
+ * function ChatMessages() {
111
+ * const { thread, streaming } = useStreamState();
112
+ *
113
+ * return (
114
+ * <div>
115
+ * {thread.messages.map(msg => <Message key={msg.id} message={msg} />)}
116
+ * {streaming.status === 'streaming' && <LoadingIndicator />}
117
+ * </div>
118
+ * );
119
+ * }
120
+ * ```
121
+ */
122
+ export function useStreamState() {
123
+ const context = useContext(StreamStateContext);
124
+ if (!context) {
125
+ throw new Error("useStreamState must be used within TamboV1StreamProvider");
126
+ }
127
+ return context;
128
+ }
129
+ /**
130
+ * Hook to access stream dispatch function.
131
+ *
132
+ * Must be used within TamboV1StreamProvider.
133
+ * @returns Dispatch function for sending events to reducer
134
+ * @throws {Error} if used outside TamboV1StreamProvider
135
+ * @example
136
+ * ```tsx
137
+ * function StreamHandler() {
138
+ * const dispatch = useStreamDispatch();
139
+ *
140
+ * useEffect(() => {
141
+ * async function handleStream() {
142
+ * for await (const event of streamEvents) {
143
+ * dispatch({ type: 'EVENT', event });
144
+ * }
145
+ * }
146
+ * handleStream();
147
+ * }, [dispatch]);
148
+ *
149
+ * return null;
150
+ * }
151
+ * ```
152
+ */
153
+ export function useStreamDispatch() {
154
+ const context = useContext(StreamDispatchContext);
155
+ if (!context) {
156
+ throw new Error("useStreamDispatch must be used within TamboV1StreamProvider");
157
+ }
158
+ return context;
159
+ }
160
+ /**
161
+ * Hook to access thread management functions.
162
+ *
163
+ * Must be used within TamboV1StreamProvider.
164
+ * @returns Thread management functions
165
+ * @throws {Error} if used outside TamboV1StreamProvider
166
+ * @example
167
+ * ```tsx
168
+ * function ThreadSwitcher() {
169
+ * const { switchThread, startNewThread } = useThreadManagement();
170
+ *
171
+ * return (
172
+ * <div>
173
+ * <button onClick={() => switchThread('thread_123')}>
174
+ * Load Thread
175
+ * </button>
176
+ * <button onClick={startNewThread}>
177
+ * New Chat
178
+ * </button>
179
+ * </div>
180
+ * );
181
+ * }
182
+ * ```
183
+ */
184
+ export function useThreadManagement() {
185
+ const context = useContext(ThreadManagementContext);
186
+ if (!context) {
187
+ throw new Error("useThreadManagement must be used within TamboV1StreamProvider");
188
+ }
189
+ return context;
190
+ }
191
+ //# sourceMappingURL=tambo-v1-stream-context.js.map
@@ -0,0 +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\n// React is used implicitly for JSX transformation (jsx: \"react\" in tsconfig)\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport React, {\n createContext,\n useReducer,\n useContext,\n useMemo,\n useCallback,\n type ReactNode,\n type Dispatch,\n} from \"react\";\nimport {\n streamReducer,\n createInitialThreadState,\n type StreamState,\n type StreamAction,\n} from \"../utils/event-accumulator\";\nimport type { TamboV1Thread } from \"../types/thread\";\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, or null to clear\n */\n switchThread: (threadId: string | null) => 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 = createContext<Dispatch<StreamAction> | null>(\n null,\n);\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: ReactNode;\n\n /**\n * Initial thread state (optional).\n * If not provided, an empty thread will be created.\n */\n initialThread?: Partial<TamboV1Thread>;\n\n /**\n * Thread ID for the stream context.\n * Used to initialize the thread if initialThread is not provided.\n */\n threadId?: string;\n}\n\n/**\n * Creates initial stream state from props.\n * @param props - Provider props\n * @returns Initial stream state\n */\nfunction createInitialState(props: TamboV1StreamProviderProps): StreamState {\n const { initialThread, threadId } = props;\n\n // Initialize with empty threadMap\n const threadMap: Record<\n string,\n ReturnType<typeof createInitialThreadState>\n > = {};\n\n // If threadId is provided, initialize that thread\n if (threadId) {\n // Create initial thread state (immutably)\n const baseState = createInitialThreadState(threadId);\n\n // If initial thread data provided, merge it immutably\n const threadState = initialThread\n ? {\n ...baseState,\n thread: {\n ...baseState.thread,\n ...initialThread,\n id: threadId, // Always use the provided threadId\n },\n }\n : baseState;\n\n threadMap[threadId] = threadState;\n }\n\n return {\n threadMap,\n currentThreadId: threadId ?? null,\n };\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 * @returns JSX element wrapping children with stream contexts\n * @example\n * ```tsx\n * <TamboV1StreamProvider threadId=\"thread_123\">\n * <ChatInterface />\n * </TamboV1StreamProvider>\n * ```\n */\nexport function TamboV1StreamProvider(props: TamboV1StreamProviderProps) {\n const { children } = props;\n\n const initialState = useMemo(\n () => createInitialState(props),\n // Only recompute if threadId changes\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [props.threadId],\n );\n\n const [state, dispatch] = useReducer(streamReducer, initialState);\n\n // Thread management functions\n const initThread = useCallback(\n (threadId: string, initialThread?: Partial<TamboV1Thread>) => {\n dispatch({ type: \"INIT_THREAD\", threadId, initialThread });\n },\n [],\n );\n\n const switchThread = useCallback((threadId: string | null) => {\n dispatch({ type: \"SET_CURRENT_THREAD\", threadId });\n }, []);\n\n const startNewThread = useCallback(() => {\n const tempId = `temp_${crypto.randomUUID()}`;\n // Use atomic START_NEW_THREAD action to prevent race conditions\n // when multiple calls happen concurrently (e.g., double-click)\n dispatch({ type: \"START_NEW_THREAD\", threadId: tempId });\n return tempId;\n }, []);\n\n const threadManagement = useMemo<ThreadManagement>(\n () => ({\n initThread,\n switchThread,\n startNewThread,\n }),\n [initThread, switchThread, startNewThread],\n );\n\n return (\n <StreamStateContext.Provider value={state}>\n <StreamDispatchContext.Provider value={dispatch}>\n <ThreadManagementContext.Provider value={threadManagement}>\n {children}\n </ThreadManagementContext.Provider>\n </StreamDispatchContext.Provider>\n </StreamStateContext.Provider>\n );\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(): 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"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=tambo-v1-stream-context.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tambo-v1-stream-context.test.d.ts","sourceRoot":"","sources":["../../../src/v1/providers/tambo-v1-stream-context.test.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,80 @@
1
+ import { EventType } from "@ag-ui/core";
2
+ import { renderHook, act } from "@testing-library/react";
3
+ import React from "react";
4
+ import { TamboV1StreamProvider, useStreamState, useStreamDispatch, } from "./tambo-v1-stream-context";
5
+ describe("TamboV1StreamProvider", () => {
6
+ describe("useStreamState", () => {
7
+ it("throws when used outside provider", () => {
8
+ // Suppress console.error for expected error
9
+ const consoleSpy = jest
10
+ .spyOn(console, "error")
11
+ .mockImplementation(() => { });
12
+ expect(() => {
13
+ renderHook(() => useStreamState());
14
+ }).toThrow("useStreamState must be used within TamboV1StreamProvider");
15
+ consoleSpy.mockRestore();
16
+ });
17
+ it("returns initial state with empty threadMap when no threadId", () => {
18
+ const wrapper = ({ children }) => (React.createElement(TamboV1StreamProvider, null, children));
19
+ const { result } = renderHook(() => useStreamState(), { wrapper });
20
+ expect(result.current.threadMap).toEqual({});
21
+ expect(result.current.currentThreadId).toBeNull();
22
+ });
23
+ it("initializes thread when threadId is provided", () => {
24
+ const wrapper = ({ children }) => (React.createElement(TamboV1StreamProvider, { threadId: "thread_123" }, children));
25
+ const { result } = renderHook(() => useStreamState(), { wrapper });
26
+ expect(result.current.currentThreadId).toBe("thread_123");
27
+ expect(result.current.threadMap.thread_123).toBeDefined();
28
+ expect(result.current.threadMap.thread_123.thread.id).toBe("thread_123");
29
+ expect(result.current.threadMap.thread_123.thread.status).toBe("idle");
30
+ expect(result.current.threadMap.thread_123.thread.messages).toEqual([]);
31
+ });
32
+ it("merges initialThread with default state", () => {
33
+ const wrapper = ({ children }) => (React.createElement(TamboV1StreamProvider, { threadId: "thread_123", initialThread: {
34
+ title: "Test Thread",
35
+ metadata: { key: "value" },
36
+ } }, children));
37
+ const { result } = renderHook(() => useStreamState(), { wrapper });
38
+ expect(result.current.threadMap.thread_123.thread.title).toBe("Test Thread");
39
+ expect(result.current.threadMap.thread_123.thread.metadata).toEqual({
40
+ key: "value",
41
+ });
42
+ // Default values should still be set
43
+ expect(result.current.threadMap.thread_123.thread.status).toBe("idle");
44
+ });
45
+ });
46
+ describe("useStreamDispatch", () => {
47
+ it("throws when used outside provider", () => {
48
+ const consoleSpy = jest
49
+ .spyOn(console, "error")
50
+ .mockImplementation(() => { });
51
+ expect(() => {
52
+ renderHook(() => useStreamDispatch());
53
+ }).toThrow("useStreamDispatch must be used within TamboV1StreamProvider");
54
+ consoleSpy.mockRestore();
55
+ });
56
+ it("dispatches events to update state", () => {
57
+ const wrapper = ({ children }) => (React.createElement(TamboV1StreamProvider, { threadId: "thread_123" }, children));
58
+ const { result } = renderHook(() => ({
59
+ state: useStreamState(),
60
+ dispatch: useStreamDispatch(),
61
+ }), { wrapper });
62
+ const runStartedEvent = {
63
+ type: EventType.RUN_STARTED,
64
+ runId: "run_1",
65
+ threadId: "thread_123",
66
+ };
67
+ act(() => {
68
+ result.current.dispatch({
69
+ type: "EVENT",
70
+ event: runStartedEvent,
71
+ threadId: "thread_123",
72
+ });
73
+ });
74
+ expect(result.current.state.threadMap.thread_123.thread.status).toBe("streaming");
75
+ expect(result.current.state.threadMap.thread_123.streaming.status).toBe("streaming");
76
+ expect(result.current.state.threadMap.thread_123.streaming.runId).toBe("run_1");
77
+ });
78
+ });
79
+ });
80
+ //# sourceMappingURL=tambo-v1-stream-context.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tambo-v1-stream-context.test.js","sourceRoot":"","sources":["../../../src/v1/providers/tambo-v1-stream-context.test.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAwB,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EACL,qBAAqB,EACrB,cAAc,EACd,iBAAiB,GAClB,MAAM,2BAA2B,CAAC;AAEnC,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;IACrC,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;QAC9B,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;YAC3C,4CAA4C;YAC5C,MAAM,UAAU,GAAG,IAAI;iBACpB,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC;iBACvB,kBAAkB,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YAEhC,MAAM,CAAC,GAAG,EAAE;gBACV,UAAU,CAAC,GAAG,EAAE,CAAC,cAAc,EAAE,CAAC,CAAC;YACrC,CAAC,CAAC,CAAC,OAAO,CAAC,0DAA0D,CAAC,CAAC;YAEvE,UAAU,CAAC,WAAW,EAAE,CAAC;QAC3B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6DAA6D,EAAE,GAAG,EAAE;YACrE,MAAM,OAAO,GAAG,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE,CAAC,CAC/D,oBAAC,qBAAqB,QAAE,QAAQ,CAAyB,CAC1D,CAAC;YAEF,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,cAAc,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;YAEnE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YAC7C,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,QAAQ,EAAE,CAAC;QACpD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;YACtD,MAAM,OAAO,GAAG,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE,CAAC,CAC/D,oBAAC,qBAAqB,IAAC,QAAQ,EAAC,YAAY,IACzC,QAAQ,CACa,CACzB,CAAC;YAEF,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,cAAc,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;YAEnE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAC1D,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE,CAAC;YAC1D,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YACzE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACvE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAC1E,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;YACjD,MAAM,OAAO,GAAG,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE,CAAC,CAC/D,oBAAC,qBAAqB,IACpB,QAAQ,EAAC,YAAY,EACrB,aAAa,EAAE;oBACb,KAAK,EAAE,aAAa;oBACpB,QAAQ,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE;iBAC3B,IAEA,QAAQ,CACa,CACzB,CAAC;YAEF,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,cAAc,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;YAEnE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAC3D,aAAa,CACd,CAAC;YACF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC;gBAClE,GAAG,EAAE,OAAO;aACb,CAAC,CAAC;YACH,qCAAqC;YACrC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACzE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;QACjC,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;YAC3C,MAAM,UAAU,GAAG,IAAI;iBACpB,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC;iBACvB,kBAAkB,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YAEhC,MAAM,CAAC,GAAG,EAAE;gBACV,UAAU,CAAC,GAAG,EAAE,CAAC,iBAAiB,EAAE,CAAC,CAAC;YACxC,CAAC,CAAC,CAAC,OAAO,CAAC,6DAA6D,CAAC,CAAC;YAE1E,UAAU,CAAC,WAAW,EAAE,CAAC;QAC3B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;YAC3C,MAAM,OAAO,GAAG,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE,CAAC,CAC/D,oBAAC,qBAAqB,IAAC,QAAQ,EAAC,YAAY,IACzC,QAAQ,CACa,CACzB,CAAC;YAEF,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAC3B,GAAG,EAAE,CAAC,CAAC;gBACL,KAAK,EAAE,cAAc,EAAE;gBACvB,QAAQ,EAAE,iBAAiB,EAAE;aAC9B,CAAC,EACF,EAAE,OAAO,EAAE,CACZ,CAAC;YAEF,MAAM,eAAe,GAAoB;gBACvC,IAAI,EAAE,SAAS,CAAC,WAAW;gBAC3B,KAAK,EAAE,OAAO;gBACd,QAAQ,EAAE,YAAY;aACvB,CAAC;YAEF,GAAG,CAAC,GAAG,EAAE;gBACP,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC;oBACtB,IAAI,EAAE,OAAO;oBACb,KAAK,EAAE,eAAe;oBACtB,QAAQ,EAAE,YAAY;iBACvB,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;YAEH,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAClE,WAAW,CACZ,CAAC;YACF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,UAAU,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,CACrE,WAAW,CACZ,CAAC;YACF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,UAAU,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,IAAI,CACpE,OAAO,CACR,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { EventType, type RunStartedEvent } from \"@ag-ui/core\";\nimport { renderHook, act } from \"@testing-library/react\";\nimport React from \"react\";\nimport {\n TamboV1StreamProvider,\n useStreamState,\n useStreamDispatch,\n} from \"./tambo-v1-stream-context\";\n\ndescribe(\"TamboV1StreamProvider\", () => {\n describe(\"useStreamState\", () => {\n it(\"throws when used outside provider\", () => {\n // Suppress console.error for expected error\n const consoleSpy = jest\n .spyOn(console, \"error\")\n .mockImplementation(() => {});\n\n expect(() => {\n renderHook(() => useStreamState());\n }).toThrow(\"useStreamState must be used within TamboV1StreamProvider\");\n\n consoleSpy.mockRestore();\n });\n\n it(\"returns initial state with empty threadMap when no threadId\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1StreamProvider>{children}</TamboV1StreamProvider>\n );\n\n const { result } = renderHook(() => useStreamState(), { wrapper });\n\n expect(result.current.threadMap).toEqual({});\n expect(result.current.currentThreadId).toBeNull();\n });\n\n it(\"initializes thread when threadId is provided\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1StreamProvider threadId=\"thread_123\">\n {children}\n </TamboV1StreamProvider>\n );\n\n const { result } = renderHook(() => useStreamState(), { wrapper });\n\n expect(result.current.currentThreadId).toBe(\"thread_123\");\n expect(result.current.threadMap.thread_123).toBeDefined();\n expect(result.current.threadMap.thread_123.thread.id).toBe(\"thread_123\");\n expect(result.current.threadMap.thread_123.thread.status).toBe(\"idle\");\n expect(result.current.threadMap.thread_123.thread.messages).toEqual([]);\n });\n\n it(\"merges initialThread with default state\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1StreamProvider\n threadId=\"thread_123\"\n initialThread={{\n title: \"Test Thread\",\n metadata: { key: \"value\" },\n }}\n >\n {children}\n </TamboV1StreamProvider>\n );\n\n const { result } = renderHook(() => useStreamState(), { wrapper });\n\n expect(result.current.threadMap.thread_123.thread.title).toBe(\n \"Test Thread\",\n );\n expect(result.current.threadMap.thread_123.thread.metadata).toEqual({\n key: \"value\",\n });\n // Default values should still be set\n expect(result.current.threadMap.thread_123.thread.status).toBe(\"idle\");\n });\n });\n\n describe(\"useStreamDispatch\", () => {\n it(\"throws when used outside provider\", () => {\n const consoleSpy = jest\n .spyOn(console, \"error\")\n .mockImplementation(() => {});\n\n expect(() => {\n renderHook(() => useStreamDispatch());\n }).toThrow(\"useStreamDispatch must be used within TamboV1StreamProvider\");\n\n consoleSpy.mockRestore();\n });\n\n it(\"dispatches events to update state\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1StreamProvider threadId=\"thread_123\">\n {children}\n </TamboV1StreamProvider>\n );\n\n const { result } = renderHook(\n () => ({\n state: useStreamState(),\n dispatch: useStreamDispatch(),\n }),\n { wrapper },\n );\n\n const runStartedEvent: RunStartedEvent = {\n type: EventType.RUN_STARTED,\n runId: \"run_1\",\n threadId: \"thread_123\",\n };\n\n act(() => {\n result.current.dispatch({\n type: \"EVENT\",\n event: runStartedEvent,\n threadId: \"thread_123\",\n });\n });\n\n expect(result.current.state.threadMap.thread_123.thread.status).toBe(\n \"streaming\",\n );\n expect(result.current.state.threadMap.thread_123.streaming.status).toBe(\n \"streaming\",\n );\n expect(result.current.state.threadMap.thread_123.streaming.runId).toBe(\n \"run_1\",\n );\n });\n });\n});\n"]}
@@ -3,8 +3,11 @@
3
3
  *
4
4
  * Defines how React components are registered and made available to the AI.
5
5
  *
6
- * TODO: Once @tambo-ai/typescript-sdk/v1 is released, import AvailableComponent
7
- * from the SDK package.
6
+ * Note: AvailableComponent is defined locally to match RunCreateParams.AvailableComponent
7
+ * from the SDK. The SDK exports two different AvailableComponent types:
8
+ * - `shared.AvailableComponent` has `props` and `contextTools` fields
9
+ * - `RunCreateParams.AvailableComponent` has `propsSchema` and `stateSchema` fields
10
+ * We need the latter for v1 API calls, so we define it locally to avoid confusion.
8
11
  */
9
12
  import type { ComponentType } from "react";
10
13
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../../../src/v1/types/component.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAE3C;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;IAEb,4CAA4C;IAC5C,WAAW,EAAE,MAAM,CAAC;IAEpB,6CAA6C;IAC7C,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAErC,wDAAwD;IACxD,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACvC;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAiB,SAAQ,kBAAkB;IAC1D,oCAAoC;IACpC,SAAS,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC;IAE9B,uCAAuC;IACvC,YAAY,CAAC,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC9C;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB,CAClC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChE,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAEhE,8BAA8B;IAC9B,KAAK,EAAE,MAAM,CAAC;IAEd,uDAAuD;IACvD,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,mCAAmC;IACnC,WAAW,EAAE,MAAM,CAAC;IAEpB,oDAAoD;IACpD,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB"}
1
+ {"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../../../src/v1/types/component.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAE3C;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;IAEb,4CAA4C;IAC5C,WAAW,EAAE,MAAM,CAAC;IAEpB,6CAA6C;IAC7C,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAErC,wDAAwD;IACxD,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACvC;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAiB,SAAQ,kBAAkB;IAC1D,oCAAoC;IACpC,SAAS,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC;IAE9B,uCAAuC;IACvC,YAAY,CAAC,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC9C;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB,CAClC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChE,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAEhE,8BAA8B;IAC9B,KAAK,EAAE,MAAM,CAAC;IAEd,uDAAuD;IACvD,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,mCAAmC;IACnC,WAAW,EAAE,MAAM,CAAC;IAEpB,oDAAoD;IACpD,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB"}
@@ -3,8 +3,11 @@
3
3
  *
4
4
  * Defines how React components are registered and made available to the AI.
5
5
  *
6
- * TODO: Once @tambo-ai/typescript-sdk/v1 is released, import AvailableComponent
7
- * from the SDK package.
6
+ * Note: AvailableComponent is defined locally to match RunCreateParams.AvailableComponent
7
+ * from the SDK. The SDK exports two different AvailableComponent types:
8
+ * - `shared.AvailableComponent` has `props` and `contextTools` fields
9
+ * - `RunCreateParams.AvailableComponent` has `propsSchema` and `stateSchema` fields
10
+ * We need the latter for v1 API calls, so we define it locally to avoid confusion.
8
11
  */
9
12
  export {};
10
13
  //# sourceMappingURL=component.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"component.js","sourceRoot":"","sources":["../../../src/v1/types/component.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG","sourcesContent":["/**\n * Component Types for v1 API\n *\n * Defines how React components are registered and made available to the AI.\n *\n * TODO: Once @tambo-ai/typescript-sdk/v1 is released, import AvailableComponent\n * from the SDK package.\n */\n\nimport type { ComponentType } from \"react\";\n\n/**\n * Component registration metadata for the AI\n * This is what gets sent to the API in the `available_components` field\n */\nexport interface AvailableComponent {\n /** Component name (must be unique) */\n name: string;\n\n /** Human-readable description for the AI */\n description: string;\n\n /** JSON Schema describing component props */\n propsSchema: Record<string, unknown>;\n\n /** JSON Schema describing component state (optional) */\n stateSchema?: Record<string, unknown>;\n}\n\n/**\n * Component registration for React SDK\n * Extends AvailableComponent with the actual React component\n */\nexport interface TamboV1Component extends AvailableComponent {\n /** The React component to render */\n component: ComponentType<any>;\n\n /** Initial state factory (optional) */\n initialState?: () => Record<string, unknown>;\n}\n\n/**\n * Props passed to components when rendered\n */\nexport interface TamboComponentProps<\n TProps extends Record<string, unknown> = Record<string, unknown>,\n TState extends Record<string, unknown> = Record<string, unknown>,\n> {\n /** Component props from AI */\n props: TProps;\n\n /** Component state (can be updated by AI or client) */\n state?: TState;\n\n /** Unique component instance ID */\n componentId: string;\n\n /** Whether this component is currently streaming */\n isStreaming?: boolean;\n}\n"]}
1
+ {"version":3,"file":"component.js","sourceRoot":"","sources":["../../../src/v1/types/component.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG","sourcesContent":["/**\n * Component Types for v1 API\n *\n * Defines how React components are registered and made available to the AI.\n *\n * Note: AvailableComponent is defined locally to match RunCreateParams.AvailableComponent\n * from the SDK. The SDK exports two different AvailableComponent types:\n * - `shared.AvailableComponent` has `props` and `contextTools` fields\n * - `RunCreateParams.AvailableComponent` has `propsSchema` and `stateSchema` fields\n * We need the latter for v1 API calls, so we define it locally to avoid confusion.\n */\n\nimport type { ComponentType } from \"react\";\n\n/**\n * Component registration metadata for the AI\n * This is what gets sent to the API in the `available_components` field\n */\nexport interface AvailableComponent {\n /** Component name (must be unique) */\n name: string;\n\n /** Human-readable description for the AI */\n description: string;\n\n /** JSON Schema describing component props */\n propsSchema: Record<string, unknown>;\n\n /** JSON Schema describing component state (optional) */\n stateSchema?: Record<string, unknown>;\n}\n\n/**\n * Component registration for React SDK\n * Extends AvailableComponent with the actual React component\n */\nexport interface TamboV1Component extends AvailableComponent {\n /** The React component to render */\n component: ComponentType<any>;\n\n /** Initial state factory (optional) */\n initialState?: () => Record<string, unknown>;\n}\n\n/**\n * Props passed to components when rendered\n */\nexport interface TamboComponentProps<\n TProps extends Record<string, unknown> = Record<string, unknown>,\n TState extends Record<string, unknown> = Record<string, unknown>,\n> {\n /** Component props from AI */\n props: TProps;\n\n /** Component state (can be updated by AI or client) */\n state?: TState;\n\n /** Unique component instance ID */\n componentId: string;\n\n /** Whether this component is currently streaming */\n isStreaming?: boolean;\n}\n"]}
@@ -2,9 +2,10 @@
2
2
  * Tambo-specific Custom Event Types for v1 Streaming API
3
3
  *
4
4
  * Defines custom events specific to Tambo functionality.
5
- * For standard AG-UI events, import directly from @ag-ui/core.
5
+ * For standard AG-UI events, import directly from `@ag-ui/core`.
6
6
  */
7
7
  import type { CustomEvent } from "@ag-ui/core";
8
+ import type { Operation } from "fast-json-patch";
8
9
  type TamboCustomEventEnvelope<TName extends string, TValue> = Omit<CustomEvent, "name" | "value"> & {
9
10
  name: TName;
10
11
  value: TValue;
@@ -23,7 +24,7 @@ export type ComponentStartEvent = TamboCustomEventEnvelope<"tambo.component.star
23
24
  */
24
25
  export type ComponentPropsDeltaEvent = TamboCustomEventEnvelope<"tambo.component.props_delta", {
25
26
  componentId: string;
26
- operations: JsonPatchOperation[];
27
+ operations: Operation[];
27
28
  }>;
28
29
  /**
29
30
  * Component state delta event (custom: tambo.component.state_delta)
@@ -31,7 +32,7 @@ export type ComponentPropsDeltaEvent = TamboCustomEventEnvelope<"tambo.component
31
32
  */
32
33
  export type ComponentStateDeltaEvent = TamboCustomEventEnvelope<"tambo.component.state_delta", {
33
34
  componentId: string;
34
- operations: JsonPatchOperation[];
35
+ operations: Operation[];
35
36
  }>;
36
37
  /**
37
38
  * Component end event (custom: tambo.component.end)
@@ -46,18 +47,26 @@ export type ComponentEndEvent = TamboCustomEventEnvelope<"tambo.component.end",
46
47
  export type RunAwaitingInputEvent = TamboCustomEventEnvelope<"tambo.run.awaiting_input", {
47
48
  pendingToolCallIds: string[];
48
49
  }>;
49
- /**
50
- * JSON Patch operation (RFC 6902)
51
- */
52
- export interface JsonPatchOperation {
53
- op: "add" | "remove" | "replace" | "move" | "copy" | "test";
54
- path: string;
55
- value?: unknown;
56
- from?: string;
57
- }
58
50
  /**
59
51
  * Union type of Tambo-specific custom events
60
52
  */
61
53
  export type TamboCustomEvent = ComponentStartEvent | ComponentPropsDeltaEvent | ComponentStateDeltaEvent | ComponentEndEvent | RunAwaitingInputEvent;
54
+ /**
55
+ * Type guard to check if an event is a Tambo custom event.
56
+ * Validates that the event has a name matching known Tambo custom event types.
57
+ * @param event - Event object to check
58
+ * @param event.name - Event name to match against known Tambo event types
59
+ * @returns True if event is a TamboCustomEvent
60
+ */
61
+ export declare function isTamboCustomEvent(event: {
62
+ name?: string;
63
+ }): event is TamboCustomEvent;
64
+ /**
65
+ * Casts a CustomEvent to the specific TamboCustomEvent type based on its name.
66
+ * Uses exhaustive type checking to ensure all event types are handled.
67
+ * @param event - The CustomEvent to cast
68
+ * @returns The properly typed TamboCustomEvent, or undefined if not a known Tambo event
69
+ */
70
+ export declare function asTamboCustomEvent(event: CustomEvent): TamboCustomEvent | undefined;
62
71
  export {};
63
72
  //# sourceMappingURL=event.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"event.d.ts","sourceRoot":"","sources":["../../../src/v1/types/event.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,KAAK,wBAAwB,CAAC,KAAK,SAAS,MAAM,EAAE,MAAM,IAAI,IAAI,CAChE,WAAW,EACX,MAAM,GAAG,OAAO,CACjB,GAAG;IACF,IAAI,EAAE,KAAK,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,wBAAwB,CACxD,uBAAuB,EACvB;IACE,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;CACvB,CACF,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,wBAAwB,GAAG,wBAAwB,CAC7D,6BAA6B,EAC7B;IACE,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,kBAAkB,EAAE,CAAC;CAClC,CACF,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,wBAAwB,GAAG,wBAAwB,CAC7D,6BAA6B,EAC7B;IACE,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,kBAAkB,EAAE,CAAC;CAClC,CACF,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,wBAAwB,CACtD,qBAAqB,EACrB;IACE,WAAW,EAAE,MAAM,CAAC;CACrB,CACF,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,qBAAqB,GAAG,wBAAwB,CAC1D,0BAA0B,EAC1B;IACE,kBAAkB,EAAE,MAAM,EAAE,CAAC;CAC9B,CACF,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,KAAK,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IAC5D,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,MAAM,gBAAgB,GACxB,mBAAmB,GACnB,wBAAwB,GACxB,wBAAwB,GACxB,iBAAiB,GACjB,qBAAqB,CAAC"}
1
+ {"version":3,"file":"event.d.ts","sourceRoot":"","sources":["../../../src/v1/types/event.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,KAAK,wBAAwB,CAAC,KAAK,SAAS,MAAM,EAAE,MAAM,IAAI,IAAI,CAChE,WAAW,EACX,MAAM,GAAG,OAAO,CACjB,GAAG;IACF,IAAI,EAAE,KAAK,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,wBAAwB,CACxD,uBAAuB,EACvB;IACE,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;CACvB,CACF,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,wBAAwB,GAAG,wBAAwB,CAC7D,6BAA6B,EAC7B;IACE,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,SAAS,EAAE,CAAC;CACzB,CACF,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,wBAAwB,GAAG,wBAAwB,CAC7D,6BAA6B,EAC7B;IACE,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,SAAS,EAAE,CAAC;CACzB,CACF,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,wBAAwB,CACtD,qBAAqB,EACrB;IACE,WAAW,EAAE,MAAM,CAAC;CACrB,CACF,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,qBAAqB,GAAG,wBAAwB,CAC1D,0BAA0B,EAC1B;IACE,kBAAkB,EAAE,MAAM,EAAE,CAAC;CAC9B,CACF,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,gBAAgB,GACxB,mBAAmB,GACnB,wBAAwB,GACxB,wBAAwB,GACxB,iBAAiB,GACjB,qBAAqB,CAAC;AAa1B;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,GAAG,KAAK,IAAI,gBAAgB,CAK5B;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,WAAW,GACjB,gBAAgB,GAAG,SAAS,CAe9B"}
@@ -2,7 +2,49 @@
2
2
  * Tambo-specific Custom Event Types for v1 Streaming API
3
3
  *
4
4
  * Defines custom events specific to Tambo functionality.
5
- * For standard AG-UI events, import directly from @ag-ui/core.
5
+ * For standard AG-UI events, import directly from `@ag-ui/core`.
6
6
  */
7
- export {};
7
+ /**
8
+ * Known Tambo custom event names for type narrowing
9
+ */
10
+ const TAMBO_CUSTOM_EVENT_NAMES = [
11
+ "tambo.component.start",
12
+ "tambo.component.props_delta",
13
+ "tambo.component.state_delta",
14
+ "tambo.component.end",
15
+ "tambo.run.awaiting_input",
16
+ ];
17
+ /**
18
+ * Type guard to check if an event is a Tambo custom event.
19
+ * Validates that the event has a name matching known Tambo custom event types.
20
+ * @param event - Event object to check
21
+ * @param event.name - Event name to match against known Tambo event types
22
+ * @returns True if event is a TamboCustomEvent
23
+ */
24
+ export function isTamboCustomEvent(event) {
25
+ return (typeof event.name === "string" &&
26
+ TAMBO_CUSTOM_EVENT_NAMES.includes(event.name));
27
+ }
28
+ /**
29
+ * Casts a CustomEvent to the specific TamboCustomEvent type based on its name.
30
+ * Uses exhaustive type checking to ensure all event types are handled.
31
+ * @param event - The CustomEvent to cast
32
+ * @returns The properly typed TamboCustomEvent, or undefined if not a known Tambo event
33
+ */
34
+ export function asTamboCustomEvent(event) {
35
+ switch (event.name) {
36
+ case "tambo.component.start":
37
+ return event;
38
+ case "tambo.component.props_delta":
39
+ return event;
40
+ case "tambo.component.state_delta":
41
+ return event;
42
+ case "tambo.component.end":
43
+ return event;
44
+ case "tambo.run.awaiting_input":
45
+ return event;
46
+ default:
47
+ return undefined;
48
+ }
49
+ }
8
50
  //# sourceMappingURL=event.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"event.js","sourceRoot":"","sources":["../../../src/v1/types/event.ts"],"names":[],"mappings":"AAAA;;;;;GAKG","sourcesContent":["/**\n * Tambo-specific Custom Event Types for v1 Streaming API\n *\n * Defines custom events specific to Tambo functionality.\n * For standard AG-UI events, import directly from @ag-ui/core.\n */\n\nimport type { CustomEvent } from \"@ag-ui/core\";\n\ntype TamboCustomEventEnvelope<TName extends string, TValue> = Omit<\n CustomEvent,\n \"name\" | \"value\"\n> & {\n name: TName;\n value: TValue;\n};\n\n/**\n * Component start event (custom: tambo.component.start)\n */\nexport type ComponentStartEvent = TamboCustomEventEnvelope<\n \"tambo.component.start\",\n {\n messageId: string;\n componentId: string;\n componentName: string;\n }\n>;\n\n/**\n * Component props delta event (custom: tambo.component.props_delta)\n * Uses JSON Patch (RFC 6902) to update component props\n */\nexport type ComponentPropsDeltaEvent = TamboCustomEventEnvelope<\n \"tambo.component.props_delta\",\n {\n componentId: string;\n operations: JsonPatchOperation[];\n }\n>;\n\n/**\n * Component state delta event (custom: tambo.component.state_delta)\n * Uses JSON Patch (RFC 6902) to update component state\n */\nexport type ComponentStateDeltaEvent = TamboCustomEventEnvelope<\n \"tambo.component.state_delta\",\n {\n componentId: string;\n operations: JsonPatchOperation[];\n }\n>;\n\n/**\n * Component end event (custom: tambo.component.end)\n */\nexport type ComponentEndEvent = TamboCustomEventEnvelope<\n \"tambo.component.end\",\n {\n componentId: string;\n }\n>;\n\n/**\n * Run awaiting input event (custom: tambo.run.awaiting_input)\n * Signals that the run is paused waiting for client-side tool execution\n */\nexport type RunAwaitingInputEvent = TamboCustomEventEnvelope<\n \"tambo.run.awaiting_input\",\n {\n pendingToolCallIds: string[];\n }\n>;\n\n/**\n * JSON Patch operation (RFC 6902)\n */\nexport interface JsonPatchOperation {\n op: \"add\" | \"remove\" | \"replace\" | \"move\" | \"copy\" | \"test\";\n path: string;\n value?: unknown;\n from?: string; // For 'move' and 'copy' operations\n}\n\n/**\n * Union type of Tambo-specific custom events\n */\nexport type TamboCustomEvent =\n | ComponentStartEvent\n | ComponentPropsDeltaEvent\n | ComponentStateDeltaEvent\n | ComponentEndEvent\n | RunAwaitingInputEvent;\n"]}
1
+ {"version":3,"file":"event.js","sourceRoot":"","sources":["../../../src/v1/types/event.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAgFH;;GAEG;AACH,MAAM,wBAAwB,GAAG;IAC/B,uBAAuB;IACvB,6BAA6B;IAC7B,6BAA6B;IAC7B,qBAAqB;IACrB,0BAA0B;CAClB,CAAC;AAEX;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAElC;IACC,OAAO,CACL,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ;QAC7B,wBAA8C,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CACrE,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAChC,KAAkB;IAElB,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,uBAAuB;YAC1B,OAAO,KAA4B,CAAC;QACtC,KAAK,6BAA6B;YAChC,OAAO,KAAiC,CAAC;QAC3C,KAAK,6BAA6B;YAChC,OAAO,KAAiC,CAAC;QAC3C,KAAK,qBAAqB;YACxB,OAAO,KAA0B,CAAC;QACpC,KAAK,0BAA0B;YAC7B,OAAO,KAA8B,CAAC;QACxC;YACE,OAAO,SAAS,CAAC;IACrB,CAAC;AACH,CAAC","sourcesContent":["/**\n * Tambo-specific Custom Event Types for v1 Streaming API\n *\n * Defines custom events specific to Tambo functionality.\n * For standard AG-UI events, import directly from `@ag-ui/core`.\n */\n\nimport type { CustomEvent } from \"@ag-ui/core\";\nimport type { Operation } from \"fast-json-patch\";\n\ntype TamboCustomEventEnvelope<TName extends string, TValue> = Omit<\n CustomEvent,\n \"name\" | \"value\"\n> & {\n name: TName;\n value: TValue;\n};\n\n/**\n * Component start event (custom: tambo.component.start)\n */\nexport type ComponentStartEvent = TamboCustomEventEnvelope<\n \"tambo.component.start\",\n {\n messageId: string;\n componentId: string;\n componentName: string;\n }\n>;\n\n/**\n * Component props delta event (custom: tambo.component.props_delta)\n * Uses JSON Patch (RFC 6902) to update component props\n */\nexport type ComponentPropsDeltaEvent = TamboCustomEventEnvelope<\n \"tambo.component.props_delta\",\n {\n componentId: string;\n operations: Operation[];\n }\n>;\n\n/**\n * Component state delta event (custom: tambo.component.state_delta)\n * Uses JSON Patch (RFC 6902) to update component state\n */\nexport type ComponentStateDeltaEvent = TamboCustomEventEnvelope<\n \"tambo.component.state_delta\",\n {\n componentId: string;\n operations: Operation[];\n }\n>;\n\n/**\n * Component end event (custom: tambo.component.end)\n */\nexport type ComponentEndEvent = TamboCustomEventEnvelope<\n \"tambo.component.end\",\n {\n componentId: string;\n }\n>;\n\n/**\n * Run awaiting input event (custom: tambo.run.awaiting_input)\n * Signals that the run is paused waiting for client-side tool execution\n */\nexport type RunAwaitingInputEvent = TamboCustomEventEnvelope<\n \"tambo.run.awaiting_input\",\n {\n pendingToolCallIds: string[];\n }\n>;\n\n/**\n * Union type of Tambo-specific custom events\n */\nexport type TamboCustomEvent =\n | ComponentStartEvent\n | ComponentPropsDeltaEvent\n | ComponentStateDeltaEvent\n | ComponentEndEvent\n | RunAwaitingInputEvent;\n\n/**\n * Known Tambo custom event names for type narrowing\n */\nconst TAMBO_CUSTOM_EVENT_NAMES = [\n \"tambo.component.start\",\n \"tambo.component.props_delta\",\n \"tambo.component.state_delta\",\n \"tambo.component.end\",\n \"tambo.run.awaiting_input\",\n] as const;\n\n/**\n * Type guard to check if an event is a Tambo custom event.\n * Validates that the event has a name matching known Tambo custom event types.\n * @param event - Event object to check\n * @param event.name - Event name to match against known Tambo event types\n * @returns True if event is a TamboCustomEvent\n */\nexport function isTamboCustomEvent(event: {\n name?: string;\n}): event is TamboCustomEvent {\n return (\n typeof event.name === \"string\" &&\n (TAMBO_CUSTOM_EVENT_NAMES as readonly string[]).includes(event.name)\n );\n}\n\n/**\n * Casts a CustomEvent to the specific TamboCustomEvent type based on its name.\n * Uses exhaustive type checking to ensure all event types are handled.\n * @param event - The CustomEvent to cast\n * @returns The properly typed TamboCustomEvent, or undefined if not a known Tambo event\n */\nexport function asTamboCustomEvent(\n event: CustomEvent,\n): TamboCustomEvent | undefined {\n switch (event.name) {\n case \"tambo.component.start\":\n return event as ComponentStartEvent;\n case \"tambo.component.props_delta\":\n return event as ComponentPropsDeltaEvent;\n case \"tambo.component.state_delta\":\n return event as ComponentStateDeltaEvent;\n case \"tambo.component.end\":\n return event as ComponentEndEvent;\n case \"tambo.run.awaiting_input\":\n return event as RunAwaitingInputEvent;\n default:\n return undefined;\n }\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=event.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event.test.d.ts","sourceRoot":"","sources":["../../../src/v1/types/event.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,68 @@
1
+ import { EventType } from "@ag-ui/core";
2
+ import { isTamboCustomEvent } from "./event";
3
+ describe("isTamboCustomEvent", () => {
4
+ it("returns true for tambo.component.start event", () => {
5
+ const event = {
6
+ type: EventType.CUSTOM,
7
+ name: "tambo.component.start",
8
+ value: { messageId: "msg1", componentId: "comp1", componentName: "Test" },
9
+ };
10
+ expect(isTamboCustomEvent(event)).toBe(true);
11
+ });
12
+ it("returns true for tambo.component.props_delta event", () => {
13
+ const event = {
14
+ type: EventType.CUSTOM,
15
+ name: "tambo.component.props_delta",
16
+ value: { componentId: "comp1", operations: [] },
17
+ };
18
+ expect(isTamboCustomEvent(event)).toBe(true);
19
+ });
20
+ it("returns true for tambo.component.state_delta event", () => {
21
+ const event = {
22
+ type: EventType.CUSTOM,
23
+ name: "tambo.component.state_delta",
24
+ value: { componentId: "comp1", operations: [] },
25
+ };
26
+ expect(isTamboCustomEvent(event)).toBe(true);
27
+ });
28
+ it("returns true for tambo.component.end event", () => {
29
+ const event = {
30
+ type: EventType.CUSTOM,
31
+ name: "tambo.component.end",
32
+ value: { componentId: "comp1" },
33
+ };
34
+ expect(isTamboCustomEvent(event)).toBe(true);
35
+ });
36
+ it("returns true for tambo.run.awaiting_input event", () => {
37
+ const event = {
38
+ type: EventType.CUSTOM,
39
+ name: "tambo.run.awaiting_input",
40
+ value: { pendingToolCallIds: ["tool1"] },
41
+ };
42
+ expect(isTamboCustomEvent(event)).toBe(true);
43
+ });
44
+ it("returns false for unknown custom event name", () => {
45
+ const event = {
46
+ type: EventType.CUSTOM,
47
+ name: "unknown.event",
48
+ value: {},
49
+ };
50
+ expect(isTamboCustomEvent(event)).toBe(false);
51
+ });
52
+ it("returns false when name is undefined", () => {
53
+ const event = {};
54
+ expect(isTamboCustomEvent(event)).toBe(false);
55
+ });
56
+ it("returns false when name is not a string", () => {
57
+ const event = {
58
+ type: EventType.CUSTOM,
59
+ name: 123,
60
+ value: {},
61
+ };
62
+ expect(isTamboCustomEvent(event)).toBe(false);
63
+ });
64
+ it("returns false for empty object", () => {
65
+ expect(isTamboCustomEvent({})).toBe(false);
66
+ });
67
+ });
68
+ //# sourceMappingURL=event.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event.test.js","sourceRoot":"","sources":["../../../src/v1/types/event.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { EventType } from \"@ag-ui/core\";\nimport { isTamboCustomEvent } from \"./event\";\n\ndescribe(\"isTamboCustomEvent\", () => {\n it(\"returns true for tambo.component.start event\", () => {\n const event = {\n type: EventType.CUSTOM,\n name: \"tambo.component.start\",\n value: { messageId: \"msg1\", componentId: \"comp1\", componentName: \"Test\" },\n };\n expect(isTamboCustomEvent(event)).toBe(true);\n });\n\n it(\"returns true for tambo.component.props_delta event\", () => {\n const event = {\n type: EventType.CUSTOM,\n name: \"tambo.component.props_delta\",\n value: { componentId: \"comp1\", operations: [] },\n };\n expect(isTamboCustomEvent(event)).toBe(true);\n });\n\n it(\"returns true for tambo.component.state_delta event\", () => {\n const event = {\n type: EventType.CUSTOM,\n name: \"tambo.component.state_delta\",\n value: { componentId: \"comp1\", operations: [] },\n };\n expect(isTamboCustomEvent(event)).toBe(true);\n });\n\n it(\"returns true for tambo.component.end event\", () => {\n const event = {\n type: EventType.CUSTOM,\n name: \"tambo.component.end\",\n value: { componentId: \"comp1\" },\n };\n expect(isTamboCustomEvent(event)).toBe(true);\n });\n\n it(\"returns true for tambo.run.awaiting_input event\", () => {\n const event = {\n type: EventType.CUSTOM,\n name: \"tambo.run.awaiting_input\",\n value: { pendingToolCallIds: [\"tool1\"] },\n };\n expect(isTamboCustomEvent(event)).toBe(true);\n });\n\n it(\"returns false for unknown custom event name\", () => {\n const event = {\n type: EventType.CUSTOM,\n name: \"unknown.event\",\n value: {},\n };\n expect(isTamboCustomEvent(event)).toBe(false);\n });\n\n it(\"returns false when name is undefined\", () => {\n const event: { name?: string } = {};\n expect(isTamboCustomEvent(event)).toBe(false);\n });\n\n it(\"returns false when name is not a string\", () => {\n const event = {\n type: EventType.CUSTOM,\n name: 123,\n value: {},\n };\n expect(isTamboCustomEvent(event as unknown as { name?: string })).toBe(\n false,\n );\n });\n\n it(\"returns false for empty object\", () => {\n expect(isTamboCustomEvent({})).toBe(false);\n });\n});\n"]}