@tambo-ai/react 0.75.0 → 1.0.0-rc.4

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 (613) hide show
  1. package/dist/hoc/with-tambo-interactable.d.ts.map +1 -1
  2. package/dist/hoc/with-tambo-interactable.js +13 -13
  3. package/dist/hoc/with-tambo-interactable.js.map +1 -1
  4. package/dist/hoc/with-tambo-interactable.test.js +3 -3
  5. package/dist/hoc/with-tambo-interactable.test.js.map +1 -1
  6. package/dist/index.d.ts +7 -25
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +7 -59
  9. package/dist/index.js.map +1 -1
  10. package/dist/mcp/mcp-hooks.js +5 -5
  11. package/dist/mcp/mcp-hooks.js.map +1 -1
  12. package/dist/model/component-metadata.d.ts +4 -4
  13. package/dist/model/component-metadata.js.map +1 -1
  14. package/dist/providers/tambo-client-provider.d.ts +6 -0
  15. package/dist/providers/tambo-client-provider.d.ts.map +1 -1
  16. package/dist/providers/tambo-client-provider.js +4 -2
  17. package/dist/providers/tambo-client-provider.js.map +1 -1
  18. package/dist/providers/tambo-interactable-provider.d.ts +1 -1
  19. package/dist/providers/tambo-interactables-additional-context-edge-cases.test.js +2 -10
  20. package/dist/providers/tambo-interactables-additional-context-edge-cases.test.js.map +1 -1
  21. package/dist/providers/tambo-interactables-additional-context.test.js +3 -19
  22. package/dist/providers/tambo-interactables-additional-context.test.js.map +1 -1
  23. package/dist/providers/tambo-mcp-token-provider.d.ts +8 -17
  24. package/dist/providers/tambo-mcp-token-provider.d.ts.map +1 -1
  25. package/dist/providers/tambo-mcp-token-provider.js +20 -97
  26. package/dist/providers/tambo-mcp-token-provider.js.map +1 -1
  27. package/dist/testing/tools.d.ts +3 -3
  28. package/dist/testing/tools.d.ts.map +1 -1
  29. package/dist/testing/tools.js.map +1 -1
  30. package/dist/util/registry-validators.js +1 -1
  31. package/dist/util/registry-validators.js.map +1 -1
  32. package/dist/v1/__tests__/v1-interactables.test.js +1 -1
  33. package/dist/v1/__tests__/v1-interactables.test.js.map +1 -1
  34. package/dist/v1/components/v1-component-renderer.d.ts +9 -9
  35. package/dist/v1/components/v1-component-renderer.d.ts.map +1 -1
  36. package/dist/v1/components/v1-component-renderer.js +13 -13
  37. package/dist/v1/components/v1-component-renderer.js.map +1 -1
  38. package/dist/v1/components/v1-component-renderer.test.js +15 -15
  39. package/dist/v1/components/v1-component-renderer.test.js.map +1 -1
  40. package/{esm/hooks/use-current-message.d.ts → dist/v1/hooks/use-tambo-current-message.d.ts} +30 -9
  41. package/dist/v1/hooks/use-tambo-current-message.d.ts.map +1 -0
  42. package/dist/{hooks/use-current-message.js → v1/hooks/use-tambo-current-message.js} +13 -8
  43. package/dist/v1/hooks/use-tambo-current-message.js.map +1 -0
  44. package/dist/v1/hooks/use-tambo-v1-auth-state.d.ts +5 -5
  45. package/dist/v1/hooks/use-tambo-v1-auth-state.d.ts.map +1 -1
  46. package/dist/v1/hooks/use-tambo-v1-auth-state.js +8 -8
  47. package/dist/v1/hooks/use-tambo-v1-auth-state.js.map +1 -1
  48. package/dist/v1/hooks/use-tambo-v1-auth-state.test.js +12 -12
  49. package/dist/v1/hooks/use-tambo-v1-auth-state.test.js.map +1 -1
  50. package/dist/v1/hooks/use-tambo-v1-component-state.d.ts +7 -6
  51. package/dist/v1/hooks/use-tambo-v1-component-state.d.ts.map +1 -1
  52. package/dist/v1/hooks/use-tambo-v1-component-state.js +50 -24
  53. package/dist/v1/hooks/use-tambo-v1-component-state.js.map +1 -1
  54. package/dist/v1/hooks/use-tambo-v1-component-state.test.js +60 -35
  55. package/dist/v1/hooks/use-tambo-v1-component-state.test.js.map +1 -1
  56. package/dist/v1/hooks/use-tambo-v1-messages.d.ts +9 -9
  57. package/dist/v1/hooks/use-tambo-v1-messages.d.ts.map +1 -1
  58. package/dist/v1/hooks/use-tambo-v1-messages.js +4 -4
  59. package/dist/v1/hooks/use-tambo-v1-messages.js.map +1 -1
  60. package/dist/v1/hooks/use-tambo-v1-messages.test.js +7 -7
  61. package/dist/v1/hooks/use-tambo-v1-messages.test.js.map +1 -1
  62. package/dist/v1/hooks/use-tambo-v1-send-message.d.ts +3 -3
  63. package/dist/v1/hooks/use-tambo-v1-send-message.d.ts.map +1 -1
  64. package/dist/v1/hooks/use-tambo-v1-send-message.js +20 -22
  65. package/dist/v1/hooks/use-tambo-v1-send-message.js.map +1 -1
  66. package/dist/v1/hooks/use-tambo-v1-send-message.test.js +51 -51
  67. package/dist/v1/hooks/use-tambo-v1-send-message.test.js.map +1 -1
  68. package/dist/v1/hooks/use-tambo-v1-stream-status.d.ts +5 -5
  69. package/dist/v1/hooks/use-tambo-v1-stream-status.d.ts.map +1 -1
  70. package/dist/v1/hooks/use-tambo-v1-stream-status.js +12 -14
  71. package/dist/v1/hooks/use-tambo-v1-stream-status.js.map +1 -1
  72. package/dist/v1/hooks/use-tambo-v1-stream-status.test.js +19 -19
  73. package/dist/v1/hooks/use-tambo-v1-stream-status.test.js.map +1 -1
  74. package/dist/v1/hooks/use-tambo-v1-suggestions.d.ts +7 -7
  75. package/dist/v1/hooks/use-tambo-v1-suggestions.d.ts.map +1 -1
  76. package/dist/v1/hooks/use-tambo-v1-suggestions.js +9 -9
  77. package/dist/v1/hooks/use-tambo-v1-suggestions.js.map +1 -1
  78. package/dist/v1/hooks/use-tambo-v1-suggestions.test.js +44 -44
  79. package/dist/v1/hooks/use-tambo-v1-suggestions.test.js.map +1 -1
  80. package/dist/v1/hooks/use-tambo-v1-thread-input.d.ts +3 -3
  81. package/dist/v1/hooks/use-tambo-v1-thread-input.d.ts.map +1 -1
  82. package/dist/v1/hooks/use-tambo-v1-thread-input.js +4 -4
  83. package/dist/v1/hooks/use-tambo-v1-thread-input.js.map +1 -1
  84. package/dist/v1/hooks/use-tambo-v1-thread-input.test.js +29 -29
  85. package/dist/v1/hooks/use-tambo-v1-thread-input.test.js.map +1 -1
  86. package/dist/v1/hooks/use-tambo-v1-thread-list.d.ts +4 -4
  87. package/dist/v1/hooks/use-tambo-v1-thread-list.d.ts.map +1 -1
  88. package/dist/v1/hooks/use-tambo-v1-thread-list.js +5 -5
  89. package/dist/v1/hooks/use-tambo-v1-thread-list.js.map +1 -1
  90. package/dist/v1/hooks/use-tambo-v1-thread-list.test.js +13 -17
  91. package/dist/v1/hooks/use-tambo-v1-thread-list.test.js.map +1 -1
  92. package/dist/v1/hooks/use-tambo-v1-thread.d.ts +3 -3
  93. package/dist/v1/hooks/use-tambo-v1-thread.d.ts.map +1 -1
  94. package/dist/v1/hooks/use-tambo-v1-thread.js +4 -4
  95. package/dist/v1/hooks/use-tambo-v1-thread.js.map +1 -1
  96. package/dist/v1/hooks/use-tambo-v1-thread.test.js +5 -5
  97. package/dist/v1/hooks/use-tambo-v1-thread.test.js.map +1 -1
  98. package/dist/v1/hooks/use-tambo-v1.d.ts +16 -7
  99. package/dist/v1/hooks/use-tambo-v1.d.ts.map +1 -1
  100. package/dist/v1/hooks/use-tambo-v1.js +41 -10
  101. package/dist/v1/hooks/use-tambo-v1.js.map +1 -1
  102. package/dist/v1/hooks/use-tambo-v1.test.js +176 -48
  103. package/dist/v1/hooks/use-tambo-v1.test.js.map +1 -1
  104. package/dist/v1/index.d.ts +31 -27
  105. package/dist/v1/index.d.ts.map +1 -1
  106. package/dist/v1/index.js +45 -35
  107. package/dist/v1/index.js.map +1 -1
  108. package/dist/v1/providers/tambo-v1-provider.d.ts +20 -20
  109. package/dist/v1/providers/tambo-v1-provider.d.ts.map +1 -1
  110. package/dist/v1/providers/tambo-v1-provider.js +32 -32
  111. package/dist/v1/providers/tambo-v1-provider.js.map +1 -1
  112. package/dist/v1/providers/tambo-v1-provider.test.js +22 -22
  113. package/dist/v1/providers/tambo-v1-provider.test.js.map +1 -1
  114. package/dist/v1/providers/tambo-v1-stream-context.d.ts +15 -15
  115. package/dist/v1/providers/tambo-v1-stream-context.d.ts.map +1 -1
  116. package/dist/v1/providers/tambo-v1-stream-context.js +17 -17
  117. package/dist/v1/providers/tambo-v1-stream-context.js.map +1 -1
  118. package/dist/v1/providers/tambo-v1-stream-context.test.js +9 -9
  119. package/dist/v1/providers/tambo-v1-stream-context.test.js.map +1 -1
  120. package/dist/v1/providers/tambo-v1-stub-provider.d.ts +9 -9
  121. package/dist/v1/providers/tambo-v1-stub-provider.d.ts.map +1 -1
  122. package/dist/v1/providers/tambo-v1-stub-provider.js +7 -7
  123. package/dist/v1/providers/tambo-v1-stub-provider.js.map +1 -1
  124. package/dist/v1/providers/tambo-v1-stub-provider.test.js +25 -25
  125. package/dist/v1/providers/tambo-v1-stub-provider.test.js.map +1 -1
  126. package/dist/v1/providers/tambo-v1-thread-input-provider.d.ts +9 -9
  127. package/dist/v1/providers/tambo-v1-thread-input-provider.d.ts.map +1 -1
  128. package/dist/v1/providers/tambo-v1-thread-input-provider.js +16 -16
  129. package/dist/v1/providers/tambo-v1-thread-input-provider.js.map +1 -1
  130. package/dist/v1/types/auth.d.ts +2 -2
  131. package/dist/v1/types/auth.d.ts.map +1 -1
  132. package/dist/v1/types/auth.js.map +1 -1
  133. package/dist/v1/types/component.d.ts +3 -3
  134. package/dist/v1/types/component.d.ts.map +1 -1
  135. package/dist/v1/types/component.js +2 -2
  136. package/dist/v1/types/component.js.map +1 -1
  137. package/dist/v1/types/event.d.ts +1 -1
  138. package/dist/v1/types/event.js +1 -1
  139. package/dist/v1/types/event.js.map +1 -1
  140. package/dist/v1/types/message.d.ts +17 -24
  141. package/dist/v1/types/message.d.ts.map +1 -1
  142. package/dist/v1/types/message.js +1 -1
  143. package/dist/v1/types/message.js.map +1 -1
  144. package/dist/v1/types/thread.d.ts +10 -8
  145. package/dist/v1/types/thread.d.ts.map +1 -1
  146. package/dist/v1/types/thread.js +1 -1
  147. package/dist/v1/types/thread.js.map +1 -1
  148. package/dist/v1/types/tool-choice.d.ts +1 -1
  149. package/dist/v1/types/tool-choice.js.map +1 -1
  150. package/dist/v1/utils/component-renderer.d.ts +11 -5
  151. package/dist/v1/utils/component-renderer.d.ts.map +1 -1
  152. package/dist/v1/utils/component-renderer.js +16 -7
  153. package/dist/v1/utils/component-renderer.js.map +1 -1
  154. package/dist/v1/utils/component-renderer.test.js +7 -7
  155. package/dist/v1/utils/component-renderer.test.js.map +1 -1
  156. package/dist/v1/utils/event-accumulator.d.ts +13 -13
  157. package/dist/v1/utils/event-accumulator.d.ts.map +1 -1
  158. package/dist/v1/utils/event-accumulator.js +26 -15
  159. package/dist/v1/utils/event-accumulator.js.map +1 -1
  160. package/dist/v1/utils/event-accumulator.test.js +54 -19
  161. package/dist/v1/utils/event-accumulator.test.js.map +1 -1
  162. package/dist/v1/utils/registry-conversion.d.ts +18 -18
  163. package/dist/v1/utils/registry-conversion.js +23 -23
  164. package/dist/v1/utils/registry-conversion.js.map +1 -1
  165. package/dist/v1/utils/stream-handler.d.ts +1 -1
  166. package/dist/v1/utils/stream-handler.js +1 -1
  167. package/dist/v1/utils/stream-handler.js.map +1 -1
  168. package/dist/v1/utils/thread-utils.d.ts +2 -2
  169. package/dist/v1/utils/thread-utils.d.ts.map +1 -1
  170. package/dist/v1/utils/thread-utils.js.map +1 -1
  171. package/dist/v1/utils/tool-call-tracker.d.ts +1 -1
  172. package/dist/v1/utils/tool-call-tracker.js +1 -1
  173. package/dist/v1/utils/tool-call-tracker.js.map +1 -1
  174. package/dist/v1/utils/tool-executor.d.ts +1 -1
  175. package/dist/v1/utils/tool-executor.js +2 -2
  176. package/dist/v1/utils/tool-executor.js.map +1 -1
  177. package/esm/hoc/with-tambo-interactable.d.ts.map +1 -1
  178. package/esm/hoc/with-tambo-interactable.js +13 -13
  179. package/esm/hoc/with-tambo-interactable.js.map +1 -1
  180. package/esm/hoc/with-tambo-interactable.test.js +1 -1
  181. package/esm/hoc/with-tambo-interactable.test.js.map +1 -1
  182. package/esm/index.d.ts +7 -25
  183. package/esm/index.d.ts.map +1 -1
  184. package/esm/index.js +7 -21
  185. package/esm/index.js.map +1 -1
  186. package/esm/mcp/mcp-hooks.js +1 -1
  187. package/esm/mcp/mcp-hooks.js.map +1 -1
  188. package/esm/model/component-metadata.d.ts +4 -4
  189. package/esm/model/component-metadata.js.map +1 -1
  190. package/esm/providers/tambo-client-provider.d.ts +6 -0
  191. package/esm/providers/tambo-client-provider.d.ts.map +1 -1
  192. package/esm/providers/tambo-client-provider.js +4 -2
  193. package/esm/providers/tambo-client-provider.js.map +1 -1
  194. package/esm/providers/tambo-interactable-provider.d.ts +1 -1
  195. package/esm/providers/tambo-interactables-additional-context-edge-cases.test.js +2 -10
  196. package/esm/providers/tambo-interactables-additional-context-edge-cases.test.js.map +1 -1
  197. package/esm/providers/tambo-interactables-additional-context.test.js +3 -19
  198. package/esm/providers/tambo-interactables-additional-context.test.js.map +1 -1
  199. package/esm/providers/tambo-mcp-token-provider.d.ts +8 -17
  200. package/esm/providers/tambo-mcp-token-provider.d.ts.map +1 -1
  201. package/esm/providers/tambo-mcp-token-provider.js +20 -97
  202. package/esm/providers/tambo-mcp-token-provider.js.map +1 -1
  203. package/esm/testing/tools.d.ts +3 -3
  204. package/esm/testing/tools.d.ts.map +1 -1
  205. package/esm/testing/tools.js.map +1 -1
  206. package/esm/util/registry-validators.js +1 -1
  207. package/esm/util/registry-validators.js.map +1 -1
  208. package/esm/v1/__tests__/v1-interactables.test.js +1 -1
  209. package/esm/v1/__tests__/v1-interactables.test.js.map +1 -1
  210. package/esm/v1/components/v1-component-renderer.d.ts +9 -9
  211. package/esm/v1/components/v1-component-renderer.d.ts.map +1 -1
  212. package/esm/v1/components/v1-component-renderer.js +12 -12
  213. package/esm/v1/components/v1-component-renderer.js.map +1 -1
  214. package/esm/v1/components/v1-component-renderer.test.js +16 -16
  215. package/esm/v1/components/v1-component-renderer.test.js.map +1 -1
  216. package/{dist/hooks/use-current-message.d.ts → esm/v1/hooks/use-tambo-current-message.d.ts} +30 -9
  217. package/esm/v1/hooks/use-tambo-current-message.d.ts.map +1 -0
  218. package/esm/{hooks/use-current-message.js → v1/hooks/use-tambo-current-message.js} +13 -8
  219. package/esm/v1/hooks/use-tambo-current-message.js.map +1 -0
  220. package/esm/v1/hooks/use-tambo-v1-auth-state.d.ts +5 -5
  221. package/esm/v1/hooks/use-tambo-v1-auth-state.d.ts.map +1 -1
  222. package/esm/v1/hooks/use-tambo-v1-auth-state.js +8 -8
  223. package/esm/v1/hooks/use-tambo-v1-auth-state.js.map +1 -1
  224. package/esm/v1/hooks/use-tambo-v1-auth-state.test.js +14 -14
  225. package/esm/v1/hooks/use-tambo-v1-auth-state.test.js.map +1 -1
  226. package/esm/v1/hooks/use-tambo-v1-component-state.d.ts +7 -6
  227. package/esm/v1/hooks/use-tambo-v1-component-state.d.ts.map +1 -1
  228. package/esm/v1/hooks/use-tambo-v1-component-state.js +50 -24
  229. package/esm/v1/hooks/use-tambo-v1-component-state.js.map +1 -1
  230. package/esm/v1/hooks/use-tambo-v1-component-state.test.js +62 -37
  231. package/esm/v1/hooks/use-tambo-v1-component-state.test.js.map +1 -1
  232. package/esm/v1/hooks/use-tambo-v1-messages.d.ts +9 -9
  233. package/esm/v1/hooks/use-tambo-v1-messages.d.ts.map +1 -1
  234. package/esm/v1/hooks/use-tambo-v1-messages.js +3 -3
  235. package/esm/v1/hooks/use-tambo-v1-messages.js.map +1 -1
  236. package/esm/v1/hooks/use-tambo-v1-messages.test.js +9 -9
  237. package/esm/v1/hooks/use-tambo-v1-messages.test.js.map +1 -1
  238. package/esm/v1/hooks/use-tambo-v1-send-message.d.ts +3 -3
  239. package/esm/v1/hooks/use-tambo-v1-send-message.d.ts.map +1 -1
  240. package/esm/v1/hooks/use-tambo-v1-send-message.js +21 -23
  241. package/esm/v1/hooks/use-tambo-v1-send-message.js.map +1 -1
  242. package/esm/v1/hooks/use-tambo-v1-send-message.test.js +54 -54
  243. package/esm/v1/hooks/use-tambo-v1-send-message.test.js.map +1 -1
  244. package/esm/v1/hooks/use-tambo-v1-stream-status.d.ts +5 -5
  245. package/esm/v1/hooks/use-tambo-v1-stream-status.d.ts.map +1 -1
  246. package/esm/v1/hooks/use-tambo-v1-stream-status.js +12 -14
  247. package/esm/v1/hooks/use-tambo-v1-stream-status.js.map +1 -1
  248. package/esm/v1/hooks/use-tambo-v1-stream-status.test.js +21 -21
  249. package/esm/v1/hooks/use-tambo-v1-stream-status.test.js.map +1 -1
  250. package/esm/v1/hooks/use-tambo-v1-suggestions.d.ts +7 -7
  251. package/esm/v1/hooks/use-tambo-v1-suggestions.d.ts.map +1 -1
  252. package/esm/v1/hooks/use-tambo-v1-suggestions.js +11 -11
  253. package/esm/v1/hooks/use-tambo-v1-suggestions.js.map +1 -1
  254. package/esm/v1/hooks/use-tambo-v1-suggestions.test.js +48 -48
  255. package/esm/v1/hooks/use-tambo-v1-suggestions.test.js.map +1 -1
  256. package/esm/v1/hooks/use-tambo-v1-thread-input.d.ts +3 -3
  257. package/esm/v1/hooks/use-tambo-v1-thread-input.d.ts.map +1 -1
  258. package/esm/v1/hooks/use-tambo-v1-thread-input.js +3 -3
  259. package/esm/v1/hooks/use-tambo-v1-thread-input.js.map +1 -1
  260. package/esm/v1/hooks/use-tambo-v1-thread-input.test.js +32 -32
  261. package/esm/v1/hooks/use-tambo-v1-thread-input.test.js.map +1 -1
  262. package/esm/v1/hooks/use-tambo-v1-thread-list.d.ts +4 -4
  263. package/esm/v1/hooks/use-tambo-v1-thread-list.d.ts.map +1 -1
  264. package/esm/v1/hooks/use-tambo-v1-thread-list.js +6 -6
  265. package/esm/v1/hooks/use-tambo-v1-thread-list.js.map +1 -1
  266. package/esm/v1/hooks/use-tambo-v1-thread-list.test.js +15 -19
  267. package/esm/v1/hooks/use-tambo-v1-thread-list.test.js.map +1 -1
  268. package/esm/v1/hooks/use-tambo-v1-thread.d.ts +3 -3
  269. package/esm/v1/hooks/use-tambo-v1-thread.d.ts.map +1 -1
  270. package/esm/v1/hooks/use-tambo-v1-thread.js +4 -4
  271. package/esm/v1/hooks/use-tambo-v1-thread.js.map +1 -1
  272. package/esm/v1/hooks/use-tambo-v1-thread.test.js +6 -6
  273. package/esm/v1/hooks/use-tambo-v1-thread.test.js.map +1 -1
  274. package/esm/v1/hooks/use-tambo-v1.d.ts +16 -7
  275. package/esm/v1/hooks/use-tambo-v1.d.ts.map +1 -1
  276. package/esm/v1/hooks/use-tambo-v1.js +43 -12
  277. package/esm/v1/hooks/use-tambo-v1.js.map +1 -1
  278. package/esm/v1/hooks/use-tambo-v1.test.js +178 -50
  279. package/esm/v1/hooks/use-tambo-v1.test.js.map +1 -1
  280. package/esm/v1/index.d.ts +31 -27
  281. package/esm/v1/index.d.ts.map +1 -1
  282. package/esm/v1/index.js +38 -33
  283. package/esm/v1/index.js.map +1 -1
  284. package/esm/v1/providers/tambo-v1-provider.d.ts +20 -20
  285. package/esm/v1/providers/tambo-v1-provider.d.ts.map +1 -1
  286. package/esm/v1/providers/tambo-v1-provider.js +32 -32
  287. package/esm/v1/providers/tambo-v1-provider.js.map +1 -1
  288. package/esm/v1/providers/tambo-v1-provider.test.js +23 -23
  289. package/esm/v1/providers/tambo-v1-provider.test.js.map +1 -1
  290. package/esm/v1/providers/tambo-v1-stream-context.d.ts +15 -15
  291. package/esm/v1/providers/tambo-v1-stream-context.d.ts.map +1 -1
  292. package/esm/v1/providers/tambo-v1-stream-context.js +17 -17
  293. package/esm/v1/providers/tambo-v1-stream-context.js.map +1 -1
  294. package/esm/v1/providers/tambo-v1-stream-context.test.js +10 -10
  295. package/esm/v1/providers/tambo-v1-stream-context.test.js.map +1 -1
  296. package/esm/v1/providers/tambo-v1-stub-provider.d.ts +9 -9
  297. package/esm/v1/providers/tambo-v1-stub-provider.d.ts.map +1 -1
  298. package/esm/v1/providers/tambo-v1-stub-provider.js +9 -9
  299. package/esm/v1/providers/tambo-v1-stub-provider.js.map +1 -1
  300. package/esm/v1/providers/tambo-v1-stub-provider.test.js +28 -28
  301. package/esm/v1/providers/tambo-v1-stub-provider.test.js.map +1 -1
  302. package/esm/v1/providers/tambo-v1-thread-input-provider.d.ts +9 -9
  303. package/esm/v1/providers/tambo-v1-thread-input-provider.d.ts.map +1 -1
  304. package/esm/v1/providers/tambo-v1-thread-input-provider.js +15 -15
  305. package/esm/v1/providers/tambo-v1-thread-input-provider.js.map +1 -1
  306. package/esm/v1/types/auth.d.ts +2 -2
  307. package/esm/v1/types/auth.d.ts.map +1 -1
  308. package/esm/v1/types/auth.js.map +1 -1
  309. package/esm/v1/types/component.d.ts +3 -3
  310. package/esm/v1/types/component.d.ts.map +1 -1
  311. package/esm/v1/types/component.js +2 -2
  312. package/esm/v1/types/component.js.map +1 -1
  313. package/esm/v1/types/event.d.ts +1 -1
  314. package/esm/v1/types/event.js +1 -1
  315. package/esm/v1/types/event.js.map +1 -1
  316. package/esm/v1/types/message.d.ts +17 -24
  317. package/esm/v1/types/message.d.ts.map +1 -1
  318. package/esm/v1/types/message.js +1 -1
  319. package/esm/v1/types/message.js.map +1 -1
  320. package/esm/v1/types/thread.d.ts +10 -8
  321. package/esm/v1/types/thread.d.ts.map +1 -1
  322. package/esm/v1/types/thread.js +1 -1
  323. package/esm/v1/types/thread.js.map +1 -1
  324. package/esm/v1/types/tool-choice.d.ts +1 -1
  325. package/esm/v1/types/tool-choice.js.map +1 -1
  326. package/esm/v1/utils/component-renderer.d.ts +11 -5
  327. package/esm/v1/utils/component-renderer.d.ts.map +1 -1
  328. package/esm/v1/utils/component-renderer.js +13 -5
  329. package/esm/v1/utils/component-renderer.js.map +1 -1
  330. package/esm/v1/utils/component-renderer.test.js +8 -8
  331. package/esm/v1/utils/component-renderer.test.js.map +1 -1
  332. package/esm/v1/utils/event-accumulator.d.ts +13 -13
  333. package/esm/v1/utils/event-accumulator.d.ts.map +1 -1
  334. package/esm/v1/utils/event-accumulator.js +26 -15
  335. package/esm/v1/utils/event-accumulator.js.map +1 -1
  336. package/esm/v1/utils/event-accumulator.test.js +54 -19
  337. package/esm/v1/utils/event-accumulator.test.js.map +1 -1
  338. package/esm/v1/utils/registry-conversion.d.ts +18 -18
  339. package/esm/v1/utils/registry-conversion.js +23 -23
  340. package/esm/v1/utils/registry-conversion.js.map +1 -1
  341. package/esm/v1/utils/stream-handler.d.ts +1 -1
  342. package/esm/v1/utils/stream-handler.js +1 -1
  343. package/esm/v1/utils/stream-handler.js.map +1 -1
  344. package/esm/v1/utils/thread-utils.d.ts +2 -2
  345. package/esm/v1/utils/thread-utils.d.ts.map +1 -1
  346. package/esm/v1/utils/thread-utils.js.map +1 -1
  347. package/esm/v1/utils/tool-call-tracker.d.ts +1 -1
  348. package/esm/v1/utils/tool-call-tracker.js +1 -1
  349. package/esm/v1/utils/tool-call-tracker.js.map +1 -1
  350. package/esm/v1/utils/tool-executor.d.ts +1 -1
  351. package/esm/v1/utils/tool-executor.js +2 -2
  352. package/esm/v1/utils/tool-executor.js.map +1 -1
  353. package/package.json +4 -9
  354. package/dist/hooks/index.d.ts +0 -9
  355. package/dist/hooks/index.d.ts.map +0 -1
  356. package/dist/hooks/index.js +0 -34
  357. package/dist/hooks/index.js.map +0 -1
  358. package/dist/hooks/use-component-state.d.ts +0 -30
  359. package/dist/hooks/use-component-state.d.ts.map +0 -1
  360. package/dist/hooks/use-component-state.js +0 -139
  361. package/dist/hooks/use-component-state.js.map +0 -1
  362. package/dist/hooks/use-component-state.test.d.ts +0 -2
  363. package/dist/hooks/use-component-state.test.d.ts.map +0 -1
  364. package/dist/hooks/use-component-state.test.js +0 -406
  365. package/dist/hooks/use-component-state.test.js.map +0 -1
  366. package/dist/hooks/use-current-message.d.ts.map +0 -1
  367. package/dist/hooks/use-current-message.js.map +0 -1
  368. package/dist/hooks/use-current-message.test.d.ts +0 -2
  369. package/dist/hooks/use-current-message.test.d.ts.map +0 -1
  370. package/dist/hooks/use-current-message.test.js +0 -269
  371. package/dist/hooks/use-current-message.test.js.map +0 -1
  372. package/dist/hooks/use-streaming-props.d.ts +0 -11
  373. package/dist/hooks/use-streaming-props.d.ts.map +0 -1
  374. package/dist/hooks/use-streaming-props.js +0 -37
  375. package/dist/hooks/use-streaming-props.js.map +0 -1
  376. package/dist/hooks/use-suggestions.d.ts +0 -46
  377. package/dist/hooks/use-suggestions.d.ts.map +0 -1
  378. package/dist/hooks/use-suggestions.js +0 -118
  379. package/dist/hooks/use-suggestions.js.map +0 -1
  380. package/dist/hooks/use-suggestions.test.d.ts +0 -2
  381. package/dist/hooks/use-suggestions.test.d.ts.map +0 -1
  382. package/dist/hooks/use-suggestions.test.js +0 -247
  383. package/dist/hooks/use-suggestions.test.js.map +0 -1
  384. package/dist/hooks/use-tambo-stream-status.d.ts +0 -90
  385. package/dist/hooks/use-tambo-stream-status.d.ts.map +0 -1
  386. package/dist/hooks/use-tambo-stream-status.js +0 -213
  387. package/dist/hooks/use-tambo-stream-status.js.map +0 -1
  388. package/dist/hooks/use-tambo-stream-status.test.d.ts +0 -2
  389. package/dist/hooks/use-tambo-stream-status.test.d.ts.map +0 -1
  390. package/dist/hooks/use-tambo-stream-status.test.js +0 -378
  391. package/dist/hooks/use-tambo-stream-status.test.js.map +0 -1
  392. package/dist/hooks/use-tambo-threads.d.ts +0 -158
  393. package/dist/hooks/use-tambo-threads.d.ts.map +0 -1
  394. package/dist/hooks/use-tambo-threads.js +0 -45
  395. package/dist/hooks/use-tambo-threads.js.map +0 -1
  396. package/dist/hooks/use-tambo-threads.test.d.ts +0 -2
  397. package/dist/hooks/use-tambo-threads.test.d.ts.map +0 -1
  398. package/dist/hooks/use-tambo-threads.test.js +0 -214
  399. package/dist/hooks/use-tambo-threads.test.js.map +0 -1
  400. package/dist/model/generate-component-response.d.ts +0 -37
  401. package/dist/model/generate-component-response.d.ts.map +0 -1
  402. package/dist/model/generate-component-response.js +0 -29
  403. package/dist/model/generate-component-response.js.map +0 -1
  404. package/dist/model/tambo-thread.d.ts +0 -15
  405. package/dist/model/tambo-thread.d.ts.map +0 -1
  406. package/dist/model/tambo-thread.js +0 -3
  407. package/dist/model/tambo-thread.js.map +0 -1
  408. package/dist/providers/__tests__/thread-input-resource-resolution.test.d.ts +0 -2
  409. package/dist/providers/__tests__/thread-input-resource-resolution.test.d.ts.map +0 -1
  410. package/dist/providers/__tests__/thread-input-resource-resolution.test.js +0 -592
  411. package/dist/providers/__tests__/thread-input-resource-resolution.test.js.map +0 -1
  412. package/dist/providers/index.d.ts +0 -13
  413. package/dist/providers/index.d.ts.map +0 -1
  414. package/dist/providers/index.js +0 -41
  415. package/dist/providers/index.js.map +0 -1
  416. package/dist/providers/tambo-component-provider.d.ts +0 -23
  417. package/dist/providers/tambo-component-provider.d.ts.map +0 -1
  418. package/dist/providers/tambo-component-provider.js +0 -88
  419. package/dist/providers/tambo-component-provider.js.map +0 -1
  420. package/dist/providers/tambo-prop-stream-provider/index.d.ts +0 -19
  421. package/dist/providers/tambo-prop-stream-provider/index.d.ts.map +0 -1
  422. package/dist/providers/tambo-prop-stream-provider/index.js +0 -43
  423. package/dist/providers/tambo-prop-stream-provider/index.js.map +0 -1
  424. package/dist/providers/tambo-prop-stream-provider/pending.d.ts +0 -12
  425. package/dist/providers/tambo-prop-stream-provider/pending.d.ts.map +0 -1
  426. package/dist/providers/tambo-prop-stream-provider/pending.js +0 -31
  427. package/dist/providers/tambo-prop-stream-provider/pending.js.map +0 -1
  428. package/dist/providers/tambo-prop-stream-provider/provider.d.ts +0 -17
  429. package/dist/providers/tambo-prop-stream-provider/provider.d.ts.map +0 -1
  430. package/dist/providers/tambo-prop-stream-provider/provider.js +0 -107
  431. package/dist/providers/tambo-prop-stream-provider/provider.js.map +0 -1
  432. package/dist/providers/tambo-prop-stream-provider/streaming.d.ts +0 -12
  433. package/dist/providers/tambo-prop-stream-provider/streaming.d.ts.map +0 -1
  434. package/dist/providers/tambo-prop-stream-provider/streaming.js +0 -28
  435. package/dist/providers/tambo-prop-stream-provider/streaming.js.map +0 -1
  436. package/dist/providers/tambo-prop-stream-provider/success.d.ts +0 -12
  437. package/dist/providers/tambo-prop-stream-provider/success.d.ts.map +0 -1
  438. package/dist/providers/tambo-prop-stream-provider/success.js +0 -28
  439. package/dist/providers/tambo-prop-stream-provider/success.js.map +0 -1
  440. package/dist/providers/tambo-prop-stream-provider/types.d.ts +0 -25
  441. package/dist/providers/tambo-prop-stream-provider/types.d.ts.map +0 -1
  442. package/dist/providers/tambo-prop-stream-provider/types.js +0 -6
  443. package/dist/providers/tambo-prop-stream-provider/types.js.map +0 -1
  444. package/dist/providers/tambo-prop-stream-provider.test.d.ts +0 -2
  445. package/dist/providers/tambo-prop-stream-provider.test.d.ts.map +0 -1
  446. package/dist/providers/tambo-prop-stream-provider.test.js +0 -275
  447. package/dist/providers/tambo-prop-stream-provider.test.js.map +0 -1
  448. package/dist/providers/tambo-provider.d.ts +0 -53
  449. package/dist/providers/tambo-provider.d.ts.map +0 -1
  450. package/dist/providers/tambo-provider.js +0 -133
  451. package/dist/providers/tambo-provider.js.map +0 -1
  452. package/dist/providers/tambo-stubs.d.ts +0 -89
  453. package/dist/providers/tambo-stubs.d.ts.map +0 -1
  454. package/dist/providers/tambo-stubs.js +0 -279
  455. package/dist/providers/tambo-stubs.js.map +0 -1
  456. package/dist/providers/tambo-stubs.test.d.ts +0 -2
  457. package/dist/providers/tambo-stubs.test.d.ts.map +0 -1
  458. package/dist/providers/tambo-stubs.test.js +0 -97
  459. package/dist/providers/tambo-stubs.test.js.map +0 -1
  460. package/dist/providers/tambo-thread-input-provider.d.ts +0 -65
  461. package/dist/providers/tambo-thread-input-provider.d.ts.map +0 -1
  462. package/dist/providers/tambo-thread-input-provider.js +0 -179
  463. package/dist/providers/tambo-thread-input-provider.js.map +0 -1
  464. package/dist/providers/tambo-thread-provider-initial-messages.test.d.ts +0 -2
  465. package/dist/providers/tambo-thread-provider-initial-messages.test.d.ts.map +0 -1
  466. package/dist/providers/tambo-thread-provider-initial-messages.test.js +0 -278
  467. package/dist/providers/tambo-thread-provider-initial-messages.test.js.map +0 -1
  468. package/dist/providers/tambo-thread-provider.d.ts +0 -126
  469. package/dist/providers/tambo-thread-provider.d.ts.map +0 -1
  470. package/dist/providers/tambo-thread-provider.js +0 -931
  471. package/dist/providers/tambo-thread-provider.js.map +0 -1
  472. package/dist/providers/tambo-thread-provider.test.d.ts +0 -2
  473. package/dist/providers/tambo-thread-provider.test.d.ts.map +0 -1
  474. package/dist/providers/tambo-thread-provider.test.js +0 -1591
  475. package/dist/providers/tambo-thread-provider.test.js.map +0 -1
  476. package/dist/util/generate-component.d.ts +0 -12
  477. package/dist/util/generate-component.d.ts.map +0 -1
  478. package/dist/util/generate-component.js +0 -58
  479. package/dist/util/generate-component.js.map +0 -1
  480. package/dist/util/generate-component.test.d.ts +0 -2
  481. package/dist/util/generate-component.test.d.ts.map +0 -1
  482. package/dist/util/generate-component.test.js +0 -340
  483. package/dist/util/generate-component.test.js.map +0 -1
  484. package/esm/hooks/index.d.ts +0 -9
  485. package/esm/hooks/index.d.ts.map +0 -1
  486. package/esm/hooks/index.js +0 -10
  487. package/esm/hooks/index.js.map +0 -1
  488. package/esm/hooks/use-component-state.d.ts +0 -30
  489. package/esm/hooks/use-component-state.d.ts.map +0 -1
  490. package/esm/hooks/use-component-state.js +0 -136
  491. package/esm/hooks/use-component-state.js.map +0 -1
  492. package/esm/hooks/use-component-state.test.d.ts +0 -2
  493. package/esm/hooks/use-component-state.test.d.ts.map +0 -1
  494. package/esm/hooks/use-component-state.test.js +0 -401
  495. package/esm/hooks/use-component-state.test.js.map +0 -1
  496. package/esm/hooks/use-current-message.d.ts.map +0 -1
  497. package/esm/hooks/use-current-message.js.map +0 -1
  498. package/esm/hooks/use-current-message.test.d.ts +0 -2
  499. package/esm/hooks/use-current-message.test.d.ts.map +0 -1
  500. package/esm/hooks/use-current-message.test.js +0 -264
  501. package/esm/hooks/use-current-message.test.js.map +0 -1
  502. package/esm/hooks/use-streaming-props.d.ts +0 -11
  503. package/esm/hooks/use-streaming-props.d.ts.map +0 -1
  504. package/esm/hooks/use-streaming-props.js +0 -34
  505. package/esm/hooks/use-streaming-props.js.map +0 -1
  506. package/esm/hooks/use-suggestions.d.ts +0 -46
  507. package/esm/hooks/use-suggestions.d.ts.map +0 -1
  508. package/esm/hooks/use-suggestions.js +0 -115
  509. package/esm/hooks/use-suggestions.js.map +0 -1
  510. package/esm/hooks/use-suggestions.test.d.ts +0 -2
  511. package/esm/hooks/use-suggestions.test.d.ts.map +0 -1
  512. package/esm/hooks/use-suggestions.test.js +0 -245
  513. package/esm/hooks/use-suggestions.test.js.map +0 -1
  514. package/esm/hooks/use-tambo-stream-status.d.ts +0 -90
  515. package/esm/hooks/use-tambo-stream-status.d.ts.map +0 -1
  516. package/esm/hooks/use-tambo-stream-status.js +0 -210
  517. package/esm/hooks/use-tambo-stream-status.js.map +0 -1
  518. package/esm/hooks/use-tambo-stream-status.test.d.ts +0 -2
  519. package/esm/hooks/use-tambo-stream-status.test.d.ts.map +0 -1
  520. package/esm/hooks/use-tambo-stream-status.test.js +0 -376
  521. package/esm/hooks/use-tambo-stream-status.test.js.map +0 -1
  522. package/esm/hooks/use-tambo-threads.d.ts +0 -158
  523. package/esm/hooks/use-tambo-threads.d.ts.map +0 -1
  524. package/esm/hooks/use-tambo-threads.js +0 -42
  525. package/esm/hooks/use-tambo-threads.js.map +0 -1
  526. package/esm/hooks/use-tambo-threads.test.d.ts +0 -2
  527. package/esm/hooks/use-tambo-threads.test.d.ts.map +0 -1
  528. package/esm/hooks/use-tambo-threads.test.js +0 -212
  529. package/esm/hooks/use-tambo-threads.test.js.map +0 -1
  530. package/esm/model/generate-component-response.d.ts +0 -37
  531. package/esm/model/generate-component-response.d.ts.map +0 -1
  532. package/esm/model/generate-component-response.js +0 -25
  533. package/esm/model/generate-component-response.js.map +0 -1
  534. package/esm/model/tambo-thread.d.ts +0 -15
  535. package/esm/model/tambo-thread.d.ts.map +0 -1
  536. package/esm/model/tambo-thread.js +0 -2
  537. package/esm/model/tambo-thread.js.map +0 -1
  538. package/esm/providers/__tests__/thread-input-resource-resolution.test.d.ts +0 -2
  539. package/esm/providers/__tests__/thread-input-resource-resolution.test.d.ts.map +0 -1
  540. package/esm/providers/__tests__/thread-input-resource-resolution.test.js +0 -587
  541. package/esm/providers/__tests__/thread-input-resource-resolution.test.js.map +0 -1
  542. package/esm/providers/index.d.ts +0 -13
  543. package/esm/providers/index.d.ts.map +0 -1
  544. package/esm/providers/index.js +0 -11
  545. package/esm/providers/index.js.map +0 -1
  546. package/esm/providers/tambo-component-provider.d.ts +0 -23
  547. package/esm/providers/tambo-component-provider.d.ts.map +0 -1
  548. package/esm/providers/tambo-component-provider.js +0 -50
  549. package/esm/providers/tambo-component-provider.js.map +0 -1
  550. package/esm/providers/tambo-prop-stream-provider/index.d.ts +0 -19
  551. package/esm/providers/tambo-prop-stream-provider/index.d.ts.map +0 -1
  552. package/esm/providers/tambo-prop-stream-provider/index.js +0 -22
  553. package/esm/providers/tambo-prop-stream-provider/index.js.map +0 -1
  554. package/esm/providers/tambo-prop-stream-provider/pending.d.ts +0 -12
  555. package/esm/providers/tambo-prop-stream-provider/pending.d.ts.map +0 -1
  556. package/esm/providers/tambo-prop-stream-provider/pending.js +0 -24
  557. package/esm/providers/tambo-prop-stream-provider/pending.js.map +0 -1
  558. package/esm/providers/tambo-prop-stream-provider/provider.d.ts +0 -17
  559. package/esm/providers/tambo-prop-stream-provider/provider.d.ts.map +0 -1
  560. package/esm/providers/tambo-prop-stream-provider/provider.js +0 -70
  561. package/esm/providers/tambo-prop-stream-provider/provider.js.map +0 -1
  562. package/esm/providers/tambo-prop-stream-provider/streaming.d.ts +0 -12
  563. package/esm/providers/tambo-prop-stream-provider/streaming.d.ts.map +0 -1
  564. package/esm/providers/tambo-prop-stream-provider/streaming.js +0 -21
  565. package/esm/providers/tambo-prop-stream-provider/streaming.js.map +0 -1
  566. package/esm/providers/tambo-prop-stream-provider/success.d.ts +0 -12
  567. package/esm/providers/tambo-prop-stream-provider/success.d.ts.map +0 -1
  568. package/esm/providers/tambo-prop-stream-provider/success.js +0 -21
  569. package/esm/providers/tambo-prop-stream-provider/success.js.map +0 -1
  570. package/esm/providers/tambo-prop-stream-provider/types.d.ts +0 -25
  571. package/esm/providers/tambo-prop-stream-provider/types.d.ts.map +0 -1
  572. package/esm/providers/tambo-prop-stream-provider/types.js +0 -3
  573. package/esm/providers/tambo-prop-stream-provider/types.js.map +0 -1
  574. package/esm/providers/tambo-prop-stream-provider.test.d.ts +0 -2
  575. package/esm/providers/tambo-prop-stream-provider.test.d.ts.map +0 -1
  576. package/esm/providers/tambo-prop-stream-provider.test.js +0 -270
  577. package/esm/providers/tambo-prop-stream-provider.test.js.map +0 -1
  578. package/esm/providers/tambo-provider.d.ts +0 -53
  579. package/esm/providers/tambo-provider.d.ts.map +0 -1
  580. package/esm/providers/tambo-provider.js +0 -94
  581. package/esm/providers/tambo-provider.js.map +0 -1
  582. package/esm/providers/tambo-stubs.d.ts +0 -89
  583. package/esm/providers/tambo-stubs.d.ts.map +0 -1
  584. package/esm/providers/tambo-stubs.js +0 -242
  585. package/esm/providers/tambo-stubs.js.map +0 -1
  586. package/esm/providers/tambo-stubs.test.d.ts +0 -2
  587. package/esm/providers/tambo-stubs.test.d.ts.map +0 -1
  588. package/esm/providers/tambo-stubs.test.js +0 -62
  589. package/esm/providers/tambo-stubs.test.js.map +0 -1
  590. package/esm/providers/tambo-thread-input-provider.d.ts +0 -65
  591. package/esm/providers/tambo-thread-input-provider.d.ts.map +0 -1
  592. package/esm/providers/tambo-thread-input-provider.js +0 -141
  593. package/esm/providers/tambo-thread-input-provider.js.map +0 -1
  594. package/esm/providers/tambo-thread-provider-initial-messages.test.d.ts +0 -2
  595. package/esm/providers/tambo-thread-provider-initial-messages.test.d.ts.map +0 -1
  596. package/esm/providers/tambo-thread-provider-initial-messages.test.js +0 -273
  597. package/esm/providers/tambo-thread-provider-initial-messages.test.js.map +0 -1
  598. package/esm/providers/tambo-thread-provider.d.ts +0 -126
  599. package/esm/providers/tambo-thread-provider.d.ts.map +0 -1
  600. package/esm/providers/tambo-thread-provider.js +0 -891
  601. package/esm/providers/tambo-thread-provider.js.map +0 -1
  602. package/esm/providers/tambo-thread-provider.test.d.ts +0 -2
  603. package/esm/providers/tambo-thread-provider.test.d.ts.map +0 -1
  604. package/esm/providers/tambo-thread-provider.test.js +0 -1553
  605. package/esm/providers/tambo-thread-provider.test.js.map +0 -1
  606. package/esm/util/generate-component.d.ts +0 -12
  607. package/esm/util/generate-component.d.ts.map +0 -1
  608. package/esm/util/generate-component.js +0 -52
  609. package/esm/util/generate-component.js.map +0 -1
  610. package/esm/util/generate-component.test.d.ts +0 -2
  611. package/esm/util/generate-component.test.d.ts.map +0 -1
  612. package/esm/util/generate-component.test.js +0 -302
  613. package/esm/util/generate-component.test.js.map +0 -1
@@ -1,1591 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- var __importDefault = (this && this.__importDefault) || function (mod) {
36
- return (mod && mod.__esModule) ? mod : { "default": mod };
37
- };
38
- Object.defineProperty(exports, "__esModule", { value: true });
39
- const typescript_sdk_1 = __importStar(require("@tambo-ai/typescript-sdk"));
40
- const react_1 = require("@testing-library/react");
41
- const react_2 = __importDefault(require("react"));
42
- const v4_1 = require("zod/v4");
43
- const generate_component_response_1 = require("../model/generate-component-response");
44
- const tools_1 = require("../testing/tools");
45
- const tambo_client_provider_1 = require("./tambo-client-provider");
46
- const tambo_context_helpers_provider_1 = require("./tambo-context-helpers-provider");
47
- const tambo_mcp_token_provider_1 = require("./tambo-mcp-token-provider");
48
- const tambo_registry_provider_1 = require("./tambo-registry-provider");
49
- const tambo_thread_provider_1 = require("./tambo-thread-provider");
50
- // Mock crypto.randomUUID
51
- Object.defineProperty(global, "crypto", {
52
- value: {
53
- randomUUID: jest.fn().mockReturnValue("test-uuid"),
54
- },
55
- });
56
- // Mock the required providers
57
- jest.mock("./tambo-client-provider", () => {
58
- return {
59
- useTamboClient: jest.fn(),
60
- useTamboQueryClient: jest.fn(),
61
- TamboClientContext: react_2.default.createContext(undefined),
62
- };
63
- });
64
- jest.mock("@tambo-ai/typescript-sdk", () => {
65
- const actual = jest.requireActual("@tambo-ai/typescript-sdk");
66
- return {
67
- __esModule: true,
68
- ...actual,
69
- advanceStream: jest.fn(),
70
- };
71
- });
72
- // Mock the getCustomContext
73
- jest.mock("../util/registry", () => ({
74
- ...jest.requireActual("../util/registry"),
75
- getCustomContext: () => ({
76
- message: "additional instructions",
77
- }),
78
- }));
79
- // Test utilities
80
- const createMockMessage = (overrides = {}) => ({
81
- id: "test-message-1",
82
- content: [{ type: "text", text: "Hello" }],
83
- role: "user",
84
- threadId: "test-thread-1",
85
- createdAt: new Date().toISOString(),
86
- componentState: {},
87
- ...overrides,
88
- });
89
- const createMockThread = (overrides = {}) => ({
90
- id: "test-thread-1",
91
- messages: [],
92
- createdAt: "2024-01-01T00:00:00Z",
93
- projectId: "test-project",
94
- updatedAt: "2024-01-01T00:00:00Z",
95
- metadata: {},
96
- ...overrides,
97
- });
98
- const createMockAdvanceResponse = (overrides = {}) => ({
99
- responseMessageDto: {
100
- id: "test-uuid",
101
- content: [{ type: "text", text: "Default response" }],
102
- role: "assistant",
103
- threadId: "test-thread-1",
104
- component: undefined,
105
- componentState: {},
106
- createdAt: new Date().toISOString(),
107
- },
108
- generationStage: generate_component_response_1.GenerationStage.COMPLETE,
109
- mcpAccessToken: "test-mcp-access-token",
110
- ...overrides,
111
- });
112
- describe("TamboThreadProvider", () => {
113
- const mockThread = createMockThread();
114
- let mockTamboAI;
115
- let mockThreadsApi;
116
- let mockProjectsApi;
117
- let mockQueryClient;
118
- const mockRegistry = [
119
- {
120
- name: "TestOnly",
121
- component: () => react_2.default.createElement("div", null, "TestOnly"),
122
- description: "TestOnly",
123
- propsSchema: v4_1.z.object({
124
- test: v4_1.z.string(),
125
- }),
126
- associatedTools: [
127
- {
128
- name: "test-tool",
129
- tool: jest.fn().mockResolvedValue("test-tool"),
130
- description: "test-tool",
131
- inputSchema: v4_1.z.object({
132
- param: v4_1.z.string().describe("test-param-description"),
133
- }),
134
- outputSchema: v4_1.z.string(),
135
- },
136
- ],
137
- },
138
- ];
139
- /**
140
- * Creates a test wrapper component with configurable options.
141
- * Reduces duplication across tests by centralizing provider setup.
142
- * @param options - Configuration options for the wrapper
143
- * @param options.components - The Tambo components to register
144
- * @param options.streaming - Whether to enable streaming responses
145
- * @param options.onCallUnregisteredTool - Handler for unregistered tool calls
146
- * @param options.autoGenerateThreadName - Whether to auto-generate thread names
147
- * @param options.autoGenerateNameThreshold - Token threshold for auto-generating names
148
- * @returns A React component that wraps children with the necessary providers
149
- */
150
- const createWrapper = ({ components = mockRegistry, streaming = false, onCallUnregisteredTool, autoGenerateThreadName, autoGenerateNameThreshold, } = {}) => function TestWrapper({ children }) {
151
- const client = (0, tambo_client_provider_1.useTamboClient)();
152
- const queryClient = (0, tambo_client_provider_1.useTamboQueryClient)();
153
- return (react_2.default.createElement(tambo_client_provider_1.TamboClientContext.Provider, { value: {
154
- client,
155
- queryClient,
156
- isUpdatingToken: false,
157
- tokenExchangeError: null,
158
- userToken: undefined,
159
- hasValidToken: false,
160
- } },
161
- react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { components: components, onCallUnregisteredTool: onCallUnregisteredTool },
162
- react_2.default.createElement(tambo_context_helpers_provider_1.TamboContextHelpersProvider, { contextHelpers: {
163
- currentTimeContextHelper: () => null,
164
- currentPageContextHelper: () => null,
165
- } },
166
- react_2.default.createElement(tambo_mcp_token_provider_1.TamboMcpTokenProvider, null,
167
- react_2.default.createElement(tambo_thread_provider_1.TamboThreadProvider, { streaming: streaming, autoGenerateThreadName: autoGenerateThreadName, autoGenerateNameThreshold: autoGenerateNameThreshold }, children))))));
168
- };
169
- // Default wrapper for most tests
170
- const Wrapper = createWrapper();
171
- afterEach(() => {
172
- jest.restoreAllMocks();
173
- });
174
- beforeEach(() => {
175
- jest.clearAllMocks();
176
- mockTamboAI = new typescript_sdk_1.default({
177
- apiKey: "",
178
- fetch: () => {
179
- throw new Error("Unexpected network call in test");
180
- },
181
- });
182
- mockThreadsApi = mockTamboAI.beta.threads;
183
- mockProjectsApi = mockTamboAI.beta.projects;
184
- // Setup mock query client
185
- mockQueryClient = {
186
- invalidateQueries: jest.fn().mockResolvedValue(undefined),
187
- setQueryData: jest.fn(),
188
- };
189
- jest
190
- .mocked(tambo_client_provider_1.useTamboQueryClient)
191
- .mockReturnValue(mockQueryClient);
192
- jest.spyOn(mockThreadsApi, "retrieve").mockResolvedValue(mockThread);
193
- jest
194
- .spyOn(mockThreadsApi.messages, "create")
195
- .mockResolvedValue(createMockMessage());
196
- jest
197
- .spyOn(mockThreadsApi, "advance")
198
- .mockResolvedValue(createMockAdvanceResponse());
199
- jest
200
- .spyOn(mockThreadsApi, "advanceByID")
201
- .mockResolvedValue(createMockAdvanceResponse());
202
- jest.spyOn(mockThreadsApi, "generateName").mockResolvedValue({
203
- ...mockThread,
204
- name: "Generated Thread Name",
205
- });
206
- jest.spyOn(mockThreadsApi, "update").mockResolvedValue({});
207
- jest.spyOn(mockProjectsApi, "getCurrent").mockResolvedValue({
208
- id: "test-project-id",
209
- name: "Test Project",
210
- isTokenRequired: false,
211
- providerType: "llm",
212
- userId: "test-user-id",
213
- });
214
- jest.mocked(tambo_client_provider_1.useTamboClient).mockReturnValue(mockTamboAI);
215
- });
216
- it("should initialize with placeholder thread", () => {
217
- const { result } = (0, react_1.renderHook)(() => (0, tambo_thread_provider_1.useTamboThread)(), { wrapper: Wrapper });
218
- expect(result.current.thread.id).toBe("placeholder");
219
- expect(result.current.isIdle).toBe(true);
220
- expect(result.current.generationStage).toBe(generate_component_response_1.GenerationStage.IDLE);
221
- });
222
- it("should switch to a new thread", async () => {
223
- const { result } = (0, react_1.renderHook)(() => (0, tambo_thread_provider_1.useTamboThread)(), { wrapper: Wrapper });
224
- await (0, react_1.act)(async () => {
225
- await result.current.switchCurrentThread("test-thread-1");
226
- });
227
- expect(mockThreadsApi.retrieve).toHaveBeenCalledWith("test-thread-1");
228
- expect(result.current.thread.id).toBe("test-thread-1");
229
- });
230
- it("should start a new thread", async () => {
231
- const { result } = (0, react_1.renderHook)(() => (0, tambo_thread_provider_1.useTamboThread)(), { wrapper: Wrapper });
232
- await (0, react_1.act)(async () => {
233
- result.current.startNewThread();
234
- });
235
- expect(result.current.thread.id).toBe("placeholder");
236
- expect(result.current.isIdle).toBe(true);
237
- });
238
- it("should add a message to the thread", async () => {
239
- const { result } = (0, react_1.renderHook)(() => (0, tambo_thread_provider_1.useTamboThread)(), { wrapper: Wrapper });
240
- const testMessage = {
241
- id: "test-message-1",
242
- content: [{ type: "text", text: "Hello" }],
243
- role: "user",
244
- threadId: "test-thread-1",
245
- createdAt: new Date().toISOString(),
246
- componentState: {},
247
- };
248
- await (0, react_1.act)(async () => {
249
- await result.current.addThreadMessage(testMessage, true);
250
- });
251
- expect(mockThreadsApi.messages.create).toHaveBeenCalledWith("test-thread-1", {
252
- content: testMessage.content,
253
- role: testMessage.role,
254
- });
255
- });
256
- it("should update a message in the thread", async () => {
257
- const { result } = (0, react_1.renderHook)(() => (0, tambo_thread_provider_1.useTamboThread)(), { wrapper: Wrapper });
258
- const testMessage = {
259
- id: "test-message-1",
260
- content: [{ type: "text", text: "Updated message" }],
261
- role: "user",
262
- threadId: "test-thread-1",
263
- createdAt: new Date().toISOString(),
264
- componentState: {},
265
- };
266
- await (0, react_1.act)(async () => {
267
- await result.current.updateThreadMessage("test-message-1", testMessage, true);
268
- });
269
- expect(mockThreadsApi.messages.create).toHaveBeenCalledWith("test-thread-1", {
270
- content: testMessage.content,
271
- role: testMessage.role,
272
- });
273
- });
274
- it("should send a message and update thread state", async () => {
275
- const mockStreamResponse = {
276
- responseMessageDto: {
277
- id: "response-1",
278
- content: [{ type: "text", text: "Response" }],
279
- role: "assistant",
280
- threadId: "test-thread-1",
281
- component: undefined,
282
- componentState: {},
283
- createdAt: new Date().toISOString(),
284
- },
285
- generationStage: generate_component_response_1.GenerationStage.COMPLETE,
286
- mcpAccessToken: "test-mcp-access-token",
287
- };
288
- const mockAsyncIterator = {
289
- [Symbol.asyncIterator]: async function* () {
290
- yield mockStreamResponse;
291
- },
292
- };
293
- jest.mocked(typescript_sdk_1.advanceStream).mockResolvedValue(mockAsyncIterator);
294
- const { result } = (0, react_1.renderHook)(() => (0, tambo_thread_provider_1.useTamboThread)(), { wrapper: Wrapper });
295
- await (0, react_1.act)(async () => {
296
- await result.current.sendThreadMessage("Hello", {
297
- threadId: "test-thread-1",
298
- streamResponse: true,
299
- additionalContext: {
300
- custom: {
301
- message: "additional instructions",
302
- },
303
- },
304
- });
305
- });
306
- expect(typescript_sdk_1.advanceStream).toHaveBeenCalledWith(expect.anything(), {
307
- messageToAppend: {
308
- content: [{ type: "text", text: "Hello" }],
309
- role: "user",
310
- additionalContext: {
311
- custom: {
312
- message: "additional instructions",
313
- },
314
- },
315
- },
316
- availableComponents: (0, tools_1.serializeRegistry)(mockRegistry),
317
- contextKey: undefined,
318
- clientTools: [],
319
- toolCallCounts: {},
320
- }, "test-thread-1");
321
- expect(result.current.generationStage).toBe(generate_component_response_1.GenerationStage.COMPLETE);
322
- });
323
- it("should handle streaming responses", async () => {
324
- const mockStreamResponse = {
325
- responseMessageDto: {
326
- id: "stream-1",
327
- content: [{ type: "text", text: "Streaming response" }],
328
- role: "assistant",
329
- threadId: "test-thread-1",
330
- component: undefined,
331
- componentState: {},
332
- createdAt: new Date().toISOString(),
333
- },
334
- generationStage: generate_component_response_1.GenerationStage.COMPLETE,
335
- mcpAccessToken: "test-mcp-access-token",
336
- };
337
- // Create an async iterator mock
338
- const mockAsyncIterator = {
339
- [Symbol.asyncIterator]: async function* () {
340
- yield mockStreamResponse;
341
- },
342
- };
343
- // Mock advanceStream to return our async iterator
344
- jest.mocked(typescript_sdk_1.advanceStream).mockResolvedValue(mockAsyncIterator);
345
- const { result } = (0, react_1.renderHook)(() => (0, tambo_thread_provider_1.useTamboThread)(), { wrapper: Wrapper });
346
- await (0, react_1.act)(async () => {
347
- await result.current.sendThreadMessage("Hello", {
348
- threadId: "test-thread-1",
349
- streamResponse: true,
350
- });
351
- });
352
- expect(result.current.generationStage).toBe(generate_component_response_1.GenerationStage.COMPLETE);
353
- });
354
- it("should handle tool calls during message processing.", async () => {
355
- const mockToolCallChunk = {
356
- responseMessageDto: {
357
- id: "tool-call-1",
358
- content: [{ type: "text", text: "Tool response" }],
359
- role: "tool",
360
- threadId: "test-thread-1",
361
- toolCallRequest: {
362
- toolName: "test-tool",
363
- parameters: [{ parameterName: "test", parameterValue: "test" }],
364
- },
365
- componentState: {},
366
- createdAt: new Date().toISOString(),
367
- },
368
- generationStage: generate_component_response_1.GenerationStage.COMPLETE,
369
- mcpAccessToken: "test-mcp-access-token",
370
- };
371
- const mockFinalChunk = {
372
- responseMessageDto: {
373
- id: "advance-response2",
374
- content: [{ type: "text", text: "response 2" }],
375
- role: "user",
376
- threadId: "test-thread-1",
377
- componentState: {},
378
- createdAt: new Date().toISOString(),
379
- },
380
- generationStage: generate_component_response_1.GenerationStage.COMPLETE,
381
- mcpAccessToken: "test-mcp-access-token",
382
- };
383
- const mockAsyncIterator = {
384
- [Symbol.asyncIterator]: async function* () {
385
- yield mockToolCallChunk;
386
- },
387
- };
388
- const mockAsyncIterator2 = {
389
- [Symbol.asyncIterator]: async function* () {
390
- yield mockFinalChunk;
391
- },
392
- };
393
- jest
394
- .mocked(typescript_sdk_1.advanceStream)
395
- .mockResolvedValueOnce(mockAsyncIterator)
396
- .mockResolvedValueOnce(mockAsyncIterator2);
397
- const { result } = (0, react_1.renderHook)(() => (0, tambo_thread_provider_1.useTamboThread)(), { wrapper: Wrapper });
398
- await (0, react_1.act)(async () => {
399
- await result.current.sendThreadMessage("Use tool", {
400
- threadId: "test-thread-1",
401
- streamResponse: true,
402
- });
403
- });
404
- expect(result.current.generationStage).toBe(generate_component_response_1.GenerationStage.COMPLETE);
405
- // New inputSchema interface: tool receives single object arg
406
- expect(mockRegistry[0]?.associatedTools?.[0]?.tool).toHaveBeenCalledWith({
407
- test: "test",
408
- });
409
- });
410
- it("should handle unregistered tool calls with onCallUnregisteredTool", async () => {
411
- const mockOnCallUnregisteredTool = jest
412
- .fn()
413
- .mockResolvedValue("unregistered-tool-result");
414
- const mockUnregisteredToolCallChunk = {
415
- responseMessageDto: {
416
- id: "unregistered-tool-call-1",
417
- content: [{ type: "text", text: "Unregistered tool response" }],
418
- role: "tool",
419
- threadId: "test-thread-1",
420
- toolCallRequest: {
421
- toolName: "unregistered-tool",
422
- parameters: [
423
- { parameterName: "input", parameterValue: "test-input" },
424
- ],
425
- },
426
- componentState: {},
427
- createdAt: new Date().toISOString(),
428
- },
429
- generationStage: generate_component_response_1.GenerationStage.COMPLETE,
430
- mcpAccessToken: "test-mcp-access-token",
431
- };
432
- const mockFinalChunk = {
433
- responseMessageDto: {
434
- id: "advance-response2",
435
- content: [{ type: "text", text: "response 2" }],
436
- role: "user",
437
- threadId: "test-thread-1",
438
- componentState: {},
439
- createdAt: new Date().toISOString(),
440
- },
441
- generationStage: generate_component_response_1.GenerationStage.COMPLETE,
442
- mcpAccessToken: "test-mcp-access-token",
443
- };
444
- const mockAsyncIterator = {
445
- [Symbol.asyncIterator]: async function* () {
446
- yield mockUnregisteredToolCallChunk;
447
- },
448
- };
449
- const mockAsyncIterator2 = {
450
- [Symbol.asyncIterator]: async function* () {
451
- yield mockFinalChunk;
452
- },
453
- };
454
- jest
455
- .mocked(typescript_sdk_1.advanceStream)
456
- .mockResolvedValueOnce(mockAsyncIterator)
457
- .mockResolvedValueOnce(mockAsyncIterator2);
458
- const { result } = (0, react_1.renderHook)(() => (0, tambo_thread_provider_1.useTamboThread)(), {
459
- wrapper: createWrapper({
460
- onCallUnregisteredTool: mockOnCallUnregisteredTool,
461
- }),
462
- });
463
- await (0, react_1.act)(async () => {
464
- await result.current.sendThreadMessage("Use unregistered tool", {
465
- threadId: "test-thread-1",
466
- streamResponse: true,
467
- });
468
- });
469
- expect(result.current.generationStage).toBe(generate_component_response_1.GenerationStage.COMPLETE);
470
- expect(mockOnCallUnregisteredTool).toHaveBeenCalledWith("unregistered-tool", [{ parameterName: "input", parameterValue: "test-input" }]);
471
- });
472
- it("should handle unregistered tool calls without onCallUnregisteredTool", async () => {
473
- const mockUnregisteredToolCallChunk = {
474
- responseMessageDto: {
475
- id: "unregistered-tool-call-1",
476
- content: [{ type: "text", text: "Unregistered tool response" }],
477
- role: "tool",
478
- threadId: "test-thread-1",
479
- toolCallRequest: {
480
- toolName: "unregistered-tool",
481
- parameters: [
482
- { parameterName: "input", parameterValue: "test-input" },
483
- ],
484
- },
485
- componentState: {},
486
- createdAt: new Date().toISOString(),
487
- },
488
- generationStage: generate_component_response_1.GenerationStage.COMPLETE,
489
- mcpAccessToken: "test-mcp-access-token",
490
- };
491
- const mockFinalChunk = {
492
- responseMessageDto: {
493
- id: "advance-response2",
494
- content: [{ type: "text", text: "response 2" }],
495
- role: "user",
496
- threadId: "test-thread-1",
497
- componentState: {},
498
- createdAt: new Date().toISOString(),
499
- },
500
- generationStage: generate_component_response_1.GenerationStage.COMPLETE,
501
- mcpAccessToken: "test-mcp-access-token",
502
- };
503
- const mockAsyncIterator = {
504
- [Symbol.asyncIterator]: async function* () {
505
- yield mockUnregisteredToolCallChunk;
506
- },
507
- };
508
- const mockAsyncIterator2 = {
509
- [Symbol.asyncIterator]: async function* () {
510
- yield mockFinalChunk;
511
- },
512
- };
513
- jest
514
- .mocked(typescript_sdk_1.advanceStream)
515
- .mockResolvedValueOnce(mockAsyncIterator)
516
- .mockResolvedValueOnce(mockAsyncIterator2);
517
- const { result } = (0, react_1.renderHook)(() => (0, tambo_thread_provider_1.useTamboThread)(), { wrapper: Wrapper });
518
- await (0, react_1.act)(async () => {
519
- await result.current.sendThreadMessage("Use unregistered tool", {
520
- threadId: "test-thread-1",
521
- streamResponse: true,
522
- });
523
- });
524
- expect(result.current.generationStage).toBe(generate_component_response_1.GenerationStage.COMPLETE);
525
- // Should not throw an error, but the tool call should fail gracefully
526
- });
527
- describe("streaming behavior", () => {
528
- it("should call advanceStream when streamResponse=true", async () => {
529
- const mockStreamResponse = {
530
- responseMessageDto: {
531
- id: "stream-response",
532
- content: [{ type: "text", text: "Streaming response" }],
533
- role: "assistant",
534
- threadId: "test-thread-1",
535
- component: undefined,
536
- componentState: {},
537
- createdAt: new Date().toISOString(),
538
- },
539
- generationStage: generate_component_response_1.GenerationStage.COMPLETE,
540
- mcpAccessToken: "test-mcp-access-token",
541
- };
542
- const mockAsyncIterator = {
543
- [Symbol.asyncIterator]: async function* () {
544
- yield mockStreamResponse;
545
- },
546
- };
547
- jest.mocked(typescript_sdk_1.advanceStream).mockResolvedValue(mockAsyncIterator);
548
- const { result } = (0, react_1.renderHook)(() => (0, tambo_thread_provider_1.useTamboThread)(), {
549
- wrapper: createWrapper({ streaming: true }),
550
- });
551
- await (0, react_1.act)(async () => {
552
- await result.current.sendThreadMessage("Hello streaming", {
553
- threadId: "test-thread-1",
554
- streamResponse: true,
555
- additionalContext: {
556
- custom: {
557
- message: "additional instructions",
558
- },
559
- },
560
- });
561
- });
562
- expect(typescript_sdk_1.advanceStream).toHaveBeenCalledWith(mockTamboAI, {
563
- messageToAppend: {
564
- content: [{ type: "text", text: "Hello streaming" }],
565
- role: "user",
566
- additionalContext: {
567
- custom: {
568
- message: "additional instructions",
569
- },
570
- },
571
- },
572
- availableComponents: (0, tools_1.serializeRegistry)(mockRegistry),
573
- contextKey: undefined,
574
- clientTools: [],
575
- forceToolChoice: undefined,
576
- toolCallCounts: {},
577
- }, "test-thread-1");
578
- // Should not call advance or advanceById
579
- expect(mockThreadsApi.advance).not.toHaveBeenCalled();
580
- expect(mockThreadsApi.advanceByID).not.toHaveBeenCalled();
581
- });
582
- it("should throw error when streamResponse=false (non-streaming not supported)", async () => {
583
- const { result } = (0, react_1.renderHook)(() => (0, tambo_thread_provider_1.useTamboThread)(), {
584
- wrapper: createWrapper({ streaming: true }),
585
- });
586
- await (0, react_1.act)(async () => {
587
- await expect(result.current.sendThreadMessage("Hello non-streaming", {
588
- threadId: "test-thread-1",
589
- streamResponse: false,
590
- })).rejects.toThrow();
591
- });
592
- });
593
- it("should call advanceStream when streamResponse is undefined and provider streaming=true (default)", async () => {
594
- const mockStreamResponse = {
595
- responseMessageDto: {
596
- id: "stream-response",
597
- content: [{ type: "text", text: "Streaming response" }],
598
- role: "assistant",
599
- threadId: "test-thread-1",
600
- component: undefined,
601
- componentState: {},
602
- createdAt: new Date().toISOString(),
603
- },
604
- generationStage: generate_component_response_1.GenerationStage.COMPLETE,
605
- mcpAccessToken: "test-mcp-access-token",
606
- };
607
- const mockAsyncIterator = {
608
- [Symbol.asyncIterator]: async function* () {
609
- yield mockStreamResponse;
610
- },
611
- };
612
- jest.mocked(typescript_sdk_1.advanceStream).mockResolvedValue(mockAsyncIterator);
613
- const { result } = (0, react_1.renderHook)(() => (0, tambo_thread_provider_1.useTamboThread)(), {
614
- wrapper: createWrapper({ streaming: true }),
615
- });
616
- await (0, react_1.act)(async () => {
617
- await result.current.sendThreadMessage("Hello default streaming", {
618
- threadId: "test-thread-1",
619
- // streamResponse is undefined, should use provider's streaming=true (default)
620
- additionalContext: {
621
- custom: {
622
- message: "additional instructions",
623
- },
624
- },
625
- });
626
- });
627
- expect(typescript_sdk_1.advanceStream).toHaveBeenCalledWith(mockTamboAI, {
628
- messageToAppend: {
629
- content: [{ type: "text", text: "Hello default streaming" }],
630
- role: "user",
631
- additionalContext: {
632
- custom: {
633
- message: "additional instructions",
634
- },
635
- },
636
- },
637
- availableComponents: (0, tools_1.serializeRegistry)(mockRegistry),
638
- contextKey: undefined,
639
- clientTools: [],
640
- forceToolChoice: undefined,
641
- toolCallCounts: {},
642
- }, "test-thread-1");
643
- // Should not call advance or advanceById
644
- expect(mockThreadsApi.advance).not.toHaveBeenCalled();
645
- expect(mockThreadsApi.advanceByID).not.toHaveBeenCalled();
646
- });
647
- it("should call advanceStream when streamResponse=true for placeholder thread", async () => {
648
- const mockStreamResponse = {
649
- responseMessageDto: {
650
- id: "stream-response",
651
- content: [{ type: "text", text: "Streaming response" }],
652
- role: "assistant",
653
- threadId: "new-thread-1",
654
- component: undefined,
655
- componentState: {},
656
- createdAt: new Date().toISOString(),
657
- },
658
- generationStage: generate_component_response_1.GenerationStage.COMPLETE,
659
- mcpAccessToken: "test-mcp-access-token",
660
- };
661
- const mockAsyncIterator = {
662
- [Symbol.asyncIterator]: async function* () {
663
- yield mockStreamResponse;
664
- },
665
- };
666
- jest.mocked(typescript_sdk_1.advanceStream).mockResolvedValue(mockAsyncIterator);
667
- const { result } = (0, react_1.renderHook)(() => (0, tambo_thread_provider_1.useTamboThread)(), {
668
- wrapper: createWrapper({ streaming: false }),
669
- });
670
- // Start with placeholder thread (which is the default state)
671
- expect(result.current.thread.id).toBe("placeholder");
672
- await (0, react_1.act)(async () => {
673
- await result.current.sendThreadMessage("Hello streaming new thread", {
674
- threadId: "placeholder",
675
- streamResponse: true,
676
- additionalContext: {
677
- custom: {
678
- message: "additional instructions",
679
- },
680
- },
681
- });
682
- });
683
- expect(typescript_sdk_1.advanceStream).toHaveBeenCalledWith(mockTamboAI, {
684
- messageToAppend: {
685
- content: [{ type: "text", text: "Hello streaming new thread" }],
686
- role: "user",
687
- additionalContext: {
688
- custom: {
689
- message: "additional instructions",
690
- },
691
- },
692
- },
693
- availableComponents: (0, tools_1.serializeRegistry)(mockRegistry),
694
- contextKey: undefined,
695
- clientTools: [],
696
- forceToolChoice: undefined,
697
- toolCallCounts: {},
698
- }, undefined);
699
- // Should not call advance or advanceById
700
- expect(mockThreadsApi.advance).not.toHaveBeenCalled();
701
- expect(mockThreadsApi.advanceByID).not.toHaveBeenCalled();
702
- });
703
- it("should handle multiple sequential messages during streaming (server tool scenario)", async () => {
704
- // This test verifies the fix for the bug where the second message doesn't render
705
- // during server tool response streaming. The scenario:
706
- // 1. First message: "I will call the tool..." with statusMessage
707
- // 2. Second message: The tool result response streaming in
708
- // First message - tool announcement (server tools don't have componentName set during streaming)
709
- const mockFirstMessage = {
710
- responseMessageDto: {
711
- id: "msg-first",
712
- content: [{ type: "text", text: "I will search the docs..." }],
713
- role: "assistant",
714
- threadId: "test-thread-1",
715
- component: {
716
- componentName: "",
717
- componentState: {},
718
- message: "",
719
- props: {},
720
- statusMessage: "searching the Tambo docs...",
721
- },
722
- componentState: {},
723
- createdAt: new Date().toISOString(),
724
- },
725
- generationStage: generate_component_response_1.GenerationStage.STREAMING_RESPONSE,
726
- mcpAccessToken: "test-mcp-access-token",
727
- };
728
- // Second message - tool result (different ID!)
729
- const mockSecondMessageChunk1 = {
730
- responseMessageDto: {
731
- id: "msg-second",
732
- content: [{ type: "text", text: "Here's what I found..." }],
733
- role: "assistant",
734
- threadId: "test-thread-1",
735
- componentState: {},
736
- createdAt: new Date().toISOString(),
737
- },
738
- generationStage: generate_component_response_1.GenerationStage.STREAMING_RESPONSE,
739
- mcpAccessToken: "test-mcp-access-token",
740
- };
741
- const mockSecondMessageChunk2 = {
742
- responseMessageDto: {
743
- id: "msg-second",
744
- content: [
745
- {
746
- type: "text",
747
- text: "Here's what I found in the documentation about that topic.",
748
- },
749
- ],
750
- role: "assistant",
751
- threadId: "test-thread-1",
752
- componentState: {},
753
- createdAt: new Date().toISOString(),
754
- },
755
- generationStage: generate_component_response_1.GenerationStage.COMPLETE,
756
- mcpAccessToken: "test-mcp-access-token",
757
- };
758
- const mockAsyncIterator = {
759
- [Symbol.asyncIterator]: async function* () {
760
- yield mockFirstMessage;
761
- yield mockSecondMessageChunk1;
762
- yield mockSecondMessageChunk2;
763
- },
764
- };
765
- jest.mocked(typescript_sdk_1.advanceStream).mockResolvedValue(mockAsyncIterator);
766
- const { result } = (0, react_1.renderHook)(() => (0, tambo_thread_provider_1.useTamboThread)(), {
767
- wrapper: createWrapper({ streaming: true }),
768
- });
769
- await (0, react_1.act)(async () => {
770
- await result.current.sendThreadMessage("Search the docs", {
771
- threadId: "test-thread-1",
772
- streamResponse: true,
773
- });
774
- });
775
- // Thread should have 3 messages: user message + 2 assistant messages
776
- expect(result.current.thread.messages).toHaveLength(3);
777
- // Filter to assistant messages only
778
- const assistantMessages = result.current.thread.messages.filter((m) => m.role === "assistant");
779
- expect(assistantMessages).toHaveLength(2);
780
- // First assistant message should have the tool status
781
- const firstMsg = result.current.thread.messages.find((m) => m.id === "msg-first");
782
- expect(firstMsg).toBeDefined();
783
- expect(firstMsg?.content[0]?.text).toContain("search the docs");
784
- // Second assistant message should have the final content
785
- const secondMsg = result.current.thread.messages.find((m) => m.id === "msg-second");
786
- expect(secondMsg).toBeDefined();
787
- expect(secondMsg?.content[0]?.text).toContain("what I found in the documentation");
788
- // Generation should be complete
789
- expect(result.current.generationStage).toBe(generate_component_response_1.GenerationStage.COMPLETE);
790
- });
791
- });
792
- describe("error handling", () => {
793
- it("should set generation stage to ERROR when streaming sendThreadMessage fails", async () => {
794
- const testError = new Error("Streaming API call failed");
795
- // Mock advanceStream to throw an error
796
- jest.mocked(typescript_sdk_1.advanceStream).mockRejectedValue(testError);
797
- const { result } = (0, react_1.renderHook)(() => (0, tambo_thread_provider_1.useTamboThread)(), {
798
- wrapper: Wrapper,
799
- });
800
- // Expect the error to be thrown
801
- await (0, react_1.act)(async () => {
802
- await result.current.switchCurrentThread("test-thread-1");
803
- await expect(result.current.sendThreadMessage("Hello", {
804
- threadId: "test-thread-1",
805
- streamResponse: true,
806
- })).rejects.toThrow("Streaming API call failed");
807
- });
808
- // Verify generation stage is set to ERROR
809
- expect(result.current.generationStage).toBe(generate_component_response_1.GenerationStage.ERROR);
810
- });
811
- it("should rollback optimistic user message when sendThreadMessage fails", async () => {
812
- const testError = new Error("API call failed");
813
- jest.mocked(typescript_sdk_1.advanceStream).mockRejectedValue(testError);
814
- const { result } = (0, react_1.renderHook)(() => (0, tambo_thread_provider_1.useTamboThread)(), {
815
- wrapper: Wrapper,
816
- });
817
- await (0, react_1.act)(async () => {
818
- await result.current.switchCurrentThread("test-thread-1");
819
- });
820
- const initialMessageCount = result.current.thread.messages.length;
821
- await (0, react_1.act)(async () => {
822
- await expect(result.current.sendThreadMessage("Hello", {
823
- threadId: "test-thread-1",
824
- streamResponse: true,
825
- })).rejects.toThrow("API call failed");
826
- });
827
- // Verify user message was rolled back
828
- expect(result.current.thread.messages.length).toBe(initialMessageCount);
829
- });
830
- it("should rollback optimistic message when addThreadMessage fails", async () => {
831
- const testError = new Error("Create message failed");
832
- jest.mocked(mockThreadsApi.messages.create).mockRejectedValue(testError);
833
- const { result } = (0, react_1.renderHook)(() => (0, tambo_thread_provider_1.useTamboThread)(), {
834
- wrapper: Wrapper,
835
- });
836
- await (0, react_1.act)(async () => {
837
- await result.current.switchCurrentThread("test-thread-1");
838
- });
839
- const initialMessageCount = result.current.thread.messages.length;
840
- const newMessage = createMockMessage({ threadId: "test-thread-1" });
841
- await (0, react_1.act)(async () => {
842
- await expect(result.current.addThreadMessage(newMessage, true)).rejects.toThrow("Create message failed");
843
- });
844
- // Verify message was rolled back
845
- expect(result.current.thread.messages.length).toBe(initialMessageCount);
846
- });
847
- it("should rollback optimistic update when updateThreadMessage fails", async () => {
848
- const testError = new Error("Update message failed");
849
- jest.mocked(mockThreadsApi.messages.create).mockRejectedValue(testError);
850
- const { result } = (0, react_1.renderHook)(() => (0, tambo_thread_provider_1.useTamboThread)(), {
851
- wrapper: Wrapper,
852
- });
853
- await (0, react_1.act)(async () => {
854
- await result.current.switchCurrentThread("test-thread-1");
855
- });
856
- const existingMessage = createMockMessage({
857
- id: "existing-msg",
858
- threadId: "test-thread-1",
859
- content: [{ type: "text", text: "Old content" }],
860
- });
861
- await (0, react_1.act)(async () => {
862
- await result.current.addThreadMessage(existingMessage, false);
863
- });
864
- const initialMessageCount = result.current.thread.messages.length;
865
- await (0, react_1.act)(async () => {
866
- await expect(result.current.updateThreadMessage("existing-msg", {
867
- threadId: "test-thread-1",
868
- content: [{ type: "text", text: "New content" }],
869
- role: "assistant",
870
- }, true)).rejects.toThrow("Update message failed");
871
- });
872
- // Verify message was rolled back
873
- expect(result.current.thread.messages.length).toBe(initialMessageCount - 1);
874
- });
875
- it("should rollback optimistic name update when updateThreadName fails", async () => {
876
- const testError = new Error("Update name failed");
877
- jest.mocked(mockThreadsApi.update).mockRejectedValue(testError);
878
- const { result } = (0, react_1.renderHook)(() => (0, tambo_thread_provider_1.useTamboThread)(), {
879
- wrapper: Wrapper,
880
- });
881
- await (0, react_1.act)(async () => {
882
- await result.current.switchCurrentThread("test-thread-1");
883
- });
884
- const initialName = result.current.thread.name;
885
- await (0, react_1.act)(async () => {
886
- await expect(result.current.updateThreadName("New Name", "test-thread-1")).rejects.toThrow("Update name failed");
887
- });
888
- // Verify name was rolled back
889
- expect(result.current.thread.name).toBe(initialName);
890
- });
891
- });
892
- describe("refetch threads list behavior", () => {
893
- it("should refetch threads list when creating a new thread via sendThreadMessage", async () => {
894
- const { result } = (0, react_1.renderHook)(() => (0, tambo_thread_provider_1.useTamboThread)(), {
895
- wrapper: Wrapper,
896
- });
897
- // Mock the stream response to return a new thread ID
898
- const mockStreamResponse = {
899
- responseMessageDto: {
900
- id: "response-1",
901
- content: [{ type: "text", text: "Response" }],
902
- role: "assistant",
903
- threadId: "new-thread-123",
904
- component: undefined,
905
- componentState: {},
906
- createdAt: new Date().toISOString(),
907
- },
908
- generationStage: generate_component_response_1.GenerationStage.COMPLETE,
909
- mcpAccessToken: "test-mcp-access-token",
910
- };
911
- const mockAsyncIterator = {
912
- [Symbol.asyncIterator]: async function* () {
913
- yield mockStreamResponse;
914
- },
915
- };
916
- jest.mocked(typescript_sdk_1.advanceStream).mockResolvedValue(mockAsyncIterator);
917
- // Start with placeholder thread
918
- expect(result.current.thread.id).toBe("placeholder");
919
- // Send a message which will create a new thread with contextKey
920
- await (0, react_1.act)(async () => {
921
- await result.current.sendThreadMessage("Hello", {
922
- threadId: "placeholder",
923
- streamResponse: true,
924
- contextKey: "test-context-key",
925
- });
926
- });
927
- // Verify that setQueryData was called first (optimistic update)
928
- expect(mockQueryClient.setQueryData).toHaveBeenCalledWith(["threads", "test-project-id", "test-context-key"], expect.any(Function));
929
- // Verify that refetchQueries was called when the new thread was created
930
- expect(mockQueryClient.invalidateQueries).toHaveBeenCalledWith({
931
- queryKey: ["threads"],
932
- });
933
- });
934
- it("should not refetch threads list when switching between existing threads", async () => {
935
- const { result } = (0, react_1.renderHook)(() => (0, tambo_thread_provider_1.useTamboThread)(), {
936
- wrapper: Wrapper,
937
- });
938
- // Start with placeholder thread
939
- expect(result.current.thread.id).toBe("placeholder");
940
- // Clear any previous mock calls
941
- jest.clearAllMocks();
942
- // Mock the retrieve call to return the expected thread
943
- const existingThread = createMockThread({ id: "existing-thread-123" });
944
- jest
945
- .mocked(mockThreadsApi.retrieve)
946
- .mockResolvedValueOnce(existingThread);
947
- // Switch to an existing thread (this should not trigger refetch)
948
- await (0, react_1.act)(async () => {
949
- await result.current.switchCurrentThread("existing-thread-123");
950
- });
951
- // Verify that the thread retrieval was called
952
- expect(mockThreadsApi.retrieve).toHaveBeenCalledWith("existing-thread-123");
953
- // Verify that neither setQueryData nor refetchQueries were called
954
- expect(mockQueryClient.setQueryData).not.toHaveBeenCalled();
955
- expect(mockQueryClient.invalidateQueries).not.toHaveBeenCalled();
956
- // Verify the thread was switched correctly
957
- expect(result.current.thread.id).toBe("existing-thread-123");
958
- });
959
- });
960
- describe("transformToContent", () => {
961
- it("should use custom async transformToContent when provided (streaming)", async () => {
962
- const mockTransformToContent = jest
963
- .fn()
964
- .mockResolvedValue([
965
- { type: "text", text: "Async transformed content" },
966
- ]);
967
- const customToolRegistry = [
968
- {
969
- name: "TestComponent",
970
- component: () => react_2.default.createElement("div", null, "Test"),
971
- description: "Test",
972
- propsSchema: v4_1.z.object({ test: v4_1.z.string() }),
973
- associatedTools: [
974
- {
975
- name: "async-tool",
976
- tool: jest.fn().mockResolvedValue({ data: "async tool result" }),
977
- description: "Tool with async transform",
978
- inputSchema: v4_1.z.object({ input: v4_1.z.string() }),
979
- outputSchema: v4_1.z.object({ data: v4_1.z.string() }),
980
- transformToContent: mockTransformToContent,
981
- },
982
- ],
983
- },
984
- ];
985
- const mockToolCallChunk = {
986
- responseMessageDto: {
987
- id: "tool-call-chunk",
988
- content: [{ type: "text", text: "Tool call" }],
989
- role: "tool",
990
- threadId: "test-thread-1",
991
- toolCallRequest: {
992
- toolName: "async-tool",
993
- parameters: [
994
- { parameterName: "input", parameterValue: "async-test" },
995
- ],
996
- },
997
- componentState: {},
998
- createdAt: new Date().toISOString(),
999
- },
1000
- generationStage: generate_component_response_1.GenerationStage.COMPLETE,
1001
- mcpAccessToken: "test-mcp-access-token",
1002
- };
1003
- const mockFinalChunk = {
1004
- responseMessageDto: {
1005
- id: "final-chunk",
1006
- content: [{ type: "text", text: "Final streaming response" }],
1007
- role: "assistant",
1008
- threadId: "test-thread-1",
1009
- componentState: {},
1010
- createdAt: new Date().toISOString(),
1011
- },
1012
- generationStage: generate_component_response_1.GenerationStage.COMPLETE,
1013
- mcpAccessToken: "test-mcp-access-token",
1014
- };
1015
- const mockAsyncIterator = {
1016
- [Symbol.asyncIterator]: async function* () {
1017
- yield mockToolCallChunk;
1018
- yield mockFinalChunk;
1019
- },
1020
- };
1021
- jest
1022
- .mocked(typescript_sdk_1.advanceStream)
1023
- .mockResolvedValueOnce(mockAsyncIterator)
1024
- .mockResolvedValueOnce({
1025
- [Symbol.asyncIterator]: async function* () {
1026
- yield mockFinalChunk;
1027
- },
1028
- });
1029
- const { result } = (0, react_1.renderHook)(() => (0, tambo_thread_provider_1.useTamboThread)(), {
1030
- wrapper: createWrapper({
1031
- components: customToolRegistry,
1032
- streaming: true,
1033
- }),
1034
- });
1035
- await (0, react_1.act)(async () => {
1036
- await result.current.sendThreadMessage("Use async tool", {
1037
- threadId: "test-thread-1",
1038
- streamResponse: true,
1039
- });
1040
- });
1041
- // Verify the tool was called with single object arg (new inputSchema interface)
1042
- expect(customToolRegistry[0]?.associatedTools?.[0]?.tool).toHaveBeenCalledWith({ input: "async-test" });
1043
- // Verify transformToContent was called
1044
- expect(mockTransformToContent).toHaveBeenCalledWith({
1045
- data: "async tool result",
1046
- });
1047
- // Verify advanceStream was called twice (initial request and tool response)
1048
- expect(typescript_sdk_1.advanceStream).toHaveBeenCalledTimes(2);
1049
- // Verify the second advanceStream call included the transformed content
1050
- expect(typescript_sdk_1.advanceStream).toHaveBeenLastCalledWith(mockTamboAI, expect.objectContaining({
1051
- messageToAppend: expect.objectContaining({
1052
- content: [{ type: "text", text: "Async transformed content" }],
1053
- role: "tool",
1054
- }),
1055
- }), "test-thread-1");
1056
- });
1057
- });
1058
- describe("tamboStreamableHint streaming behavior", () => {
1059
- it("should call streamable tool during streaming when tamboStreamableHint is true", async () => {
1060
- const streamableToolFn = jest
1061
- .fn()
1062
- .mockResolvedValue({ data: "streamed" });
1063
- const customToolRegistry = [
1064
- {
1065
- name: "TestComponent",
1066
- component: () => react_2.default.createElement("div", null, "Test"),
1067
- description: "Test",
1068
- propsSchema: v4_1.z.object({ test: v4_1.z.string() }),
1069
- associatedTools: [
1070
- {
1071
- name: "streamable-tool",
1072
- tool: streamableToolFn,
1073
- description: "Tool safe for streaming",
1074
- inputSchema: v4_1.z.object({ input: v4_1.z.string() }),
1075
- outputSchema: v4_1.z.object({ data: v4_1.z.string() }),
1076
- annotations: { tamboStreamableHint: true },
1077
- },
1078
- ],
1079
- },
1080
- ];
1081
- // First chunk initializes finalMessage
1082
- const mockInitialChunk = {
1083
- responseMessageDto: {
1084
- id: "initial-chunk",
1085
- content: [{ type: "text", text: "Starting..." }],
1086
- role: "assistant",
1087
- threadId: "test-thread-1",
1088
- componentState: {},
1089
- createdAt: new Date().toISOString(),
1090
- },
1091
- generationStage: generate_component_response_1.GenerationStage.STREAMING_RESPONSE,
1092
- mcpAccessToken: "test-mcp-access-token",
1093
- };
1094
- // Second chunk has the tool call - this triggers streaming tool handling
1095
- const mockToolCallChunk = {
1096
- responseMessageDto: {
1097
- id: "initial-chunk", // Same ID as initial - it's an update
1098
- content: [{ type: "text", text: "Streaming..." }],
1099
- role: "assistant",
1100
- threadId: "test-thread-1",
1101
- component: {
1102
- componentName: "",
1103
- componentState: {},
1104
- message: "",
1105
- props: {},
1106
- toolCallRequest: {
1107
- toolName: "streamable-tool",
1108
- parameters: [
1109
- { parameterName: "input", parameterValue: "stream-test" },
1110
- ],
1111
- },
1112
- },
1113
- componentState: {},
1114
- createdAt: new Date().toISOString(),
1115
- },
1116
- generationStage: generate_component_response_1.GenerationStage.STREAMING_RESPONSE,
1117
- mcpAccessToken: "test-mcp-access-token",
1118
- };
1119
- const mockFinalChunk = {
1120
- responseMessageDto: {
1121
- id: "initial-chunk",
1122
- content: [{ type: "text", text: "Complete" }],
1123
- role: "assistant",
1124
- threadId: "test-thread-1",
1125
- componentState: {},
1126
- createdAt: new Date().toISOString(),
1127
- },
1128
- generationStage: generate_component_response_1.GenerationStage.COMPLETE,
1129
- mcpAccessToken: "test-mcp-access-token",
1130
- };
1131
- const mockAsyncIterator = {
1132
- [Symbol.asyncIterator]: async function* () {
1133
- yield mockInitialChunk;
1134
- yield mockToolCallChunk;
1135
- yield mockFinalChunk;
1136
- },
1137
- };
1138
- jest.mocked(typescript_sdk_1.advanceStream).mockResolvedValueOnce(mockAsyncIterator);
1139
- const { result } = (0, react_1.renderHook)(() => (0, tambo_thread_provider_1.useTamboThread)(), {
1140
- wrapper: createWrapper({
1141
- components: customToolRegistry,
1142
- streaming: true,
1143
- }),
1144
- });
1145
- await (0, react_1.act)(async () => {
1146
- await result.current.sendThreadMessage("Test streamable tool", {
1147
- threadId: "test-thread-1",
1148
- streamResponse: true,
1149
- });
1150
- });
1151
- // Streamable tool should be called during streaming
1152
- expect(streamableToolFn).toHaveBeenCalledWith({ input: "stream-test" });
1153
- });
1154
- it("should NOT call non-streamable tool during streaming", async () => {
1155
- const nonStreamableToolFn = jest
1156
- .fn()
1157
- .mockResolvedValue({ data: "result" });
1158
- const customToolRegistry = [
1159
- {
1160
- name: "TestComponent",
1161
- component: () => react_2.default.createElement("div", null, "Test"),
1162
- description: "Test",
1163
- propsSchema: v4_1.z.object({ test: v4_1.z.string() }),
1164
- associatedTools: [
1165
- {
1166
- name: "non-streamable-tool",
1167
- tool: nonStreamableToolFn,
1168
- description: "Tool not safe for streaming",
1169
- inputSchema: v4_1.z.object({ input: v4_1.z.string() }),
1170
- outputSchema: v4_1.z.object({ data: v4_1.z.string() }),
1171
- // No tamboStreamableHint - defaults to false
1172
- },
1173
- ],
1174
- },
1175
- ];
1176
- // First chunk initializes finalMessage
1177
- const mockInitialChunk = {
1178
- responseMessageDto: {
1179
- id: "streaming-chunk",
1180
- content: [{ type: "text", text: "Starting..." }],
1181
- role: "assistant",
1182
- threadId: "test-thread-1",
1183
- componentState: {},
1184
- createdAt: new Date().toISOString(),
1185
- },
1186
- generationStage: generate_component_response_1.GenerationStage.STREAMING_RESPONSE,
1187
- mcpAccessToken: "test-mcp-access-token",
1188
- };
1189
- // Second chunk has the tool call - but tool is NOT streamable
1190
- const mockToolCallChunk = {
1191
- responseMessageDto: {
1192
- id: "streaming-chunk",
1193
- content: [{ type: "text", text: "Streaming..." }],
1194
- role: "assistant",
1195
- threadId: "test-thread-1",
1196
- component: {
1197
- componentName: "",
1198
- componentState: {},
1199
- message: "",
1200
- props: {},
1201
- toolCallRequest: {
1202
- toolName: "non-streamable-tool",
1203
- parameters: [{ parameterName: "input", parameterValue: "test" }],
1204
- },
1205
- },
1206
- componentState: {},
1207
- createdAt: new Date().toISOString(),
1208
- },
1209
- generationStage: generate_component_response_1.GenerationStage.STREAMING_RESPONSE,
1210
- mcpAccessToken: "test-mcp-access-token",
1211
- };
1212
- const mockFinalChunk = {
1213
- responseMessageDto: {
1214
- id: "streaming-chunk",
1215
- content: [{ type: "text", text: "Complete" }],
1216
- role: "assistant",
1217
- threadId: "test-thread-1",
1218
- componentState: {},
1219
- createdAt: new Date().toISOString(),
1220
- },
1221
- generationStage: generate_component_response_1.GenerationStage.COMPLETE,
1222
- mcpAccessToken: "test-mcp-access-token",
1223
- };
1224
- const mockAsyncIterator = {
1225
- [Symbol.asyncIterator]: async function* () {
1226
- yield mockInitialChunk;
1227
- yield mockToolCallChunk;
1228
- yield mockFinalChunk;
1229
- },
1230
- };
1231
- jest.mocked(typescript_sdk_1.advanceStream).mockResolvedValueOnce(mockAsyncIterator);
1232
- const { result } = (0, react_1.renderHook)(() => (0, tambo_thread_provider_1.useTamboThread)(), {
1233
- wrapper: createWrapper({
1234
- components: customToolRegistry,
1235
- streaming: true,
1236
- }),
1237
- });
1238
- await (0, react_1.act)(async () => {
1239
- await result.current.sendThreadMessage("Test non-streamable tool", {
1240
- threadId: "test-thread-1",
1241
- streamResponse: true,
1242
- });
1243
- });
1244
- // Non-streamable tool should NOT be called during the streaming chunk phase
1245
- // (it would only be called when generationStage is COMPLETE with a toolCallRequest)
1246
- expect(nonStreamableToolFn).not.toHaveBeenCalled();
1247
- });
1248
- it("should only call streamable tools during streaming when mixed", async () => {
1249
- const streamableToolFn = jest
1250
- .fn()
1251
- .mockResolvedValue({ data: "streamed" });
1252
- const nonStreamableToolFn = jest
1253
- .fn()
1254
- .mockResolvedValue({ data: "not-streamed" });
1255
- const customToolRegistry = [
1256
- {
1257
- name: "TestComponent",
1258
- component: () => react_2.default.createElement("div", null, "Test"),
1259
- description: "Test",
1260
- propsSchema: v4_1.z.object({ test: v4_1.z.string() }),
1261
- associatedTools: [
1262
- {
1263
- name: "streamable-tool",
1264
- tool: streamableToolFn,
1265
- description: "Tool safe for streaming",
1266
- inputSchema: v4_1.z.object({ input: v4_1.z.string() }),
1267
- outputSchema: v4_1.z.object({ data: v4_1.z.string() }),
1268
- annotations: { tamboStreamableHint: true },
1269
- },
1270
- {
1271
- name: "non-streamable-tool",
1272
- tool: nonStreamableToolFn,
1273
- description: "Tool not safe for streaming",
1274
- inputSchema: v4_1.z.object({ input: v4_1.z.string() }),
1275
- outputSchema: v4_1.z.object({ data: v4_1.z.string() }),
1276
- annotations: { tamboStreamableHint: false },
1277
- },
1278
- ],
1279
- },
1280
- ];
1281
- // First chunk initializes finalMessage
1282
- const mockInitialChunk = {
1283
- responseMessageDto: {
1284
- id: "streaming-chunk",
1285
- content: [{ type: "text", text: "Starting..." }],
1286
- role: "assistant",
1287
- threadId: "test-thread-1",
1288
- componentState: {},
1289
- createdAt: new Date().toISOString(),
1290
- },
1291
- generationStage: generate_component_response_1.GenerationStage.STREAMING_RESPONSE,
1292
- mcpAccessToken: "test-mcp-access-token",
1293
- };
1294
- // Second chunk calls the streamable tool
1295
- const mockStreamableToolChunk = {
1296
- responseMessageDto: {
1297
- id: "streaming-chunk",
1298
- content: [{ type: "text", text: "Calling streamable..." }],
1299
- role: "assistant",
1300
- threadId: "test-thread-1",
1301
- component: {
1302
- componentName: "",
1303
- componentState: {},
1304
- message: "",
1305
- props: {},
1306
- toolCallRequest: {
1307
- toolName: "streamable-tool",
1308
- parameters: [
1309
- { parameterName: "input", parameterValue: "streamed-input" },
1310
- ],
1311
- },
1312
- },
1313
- componentState: {},
1314
- createdAt: new Date().toISOString(),
1315
- },
1316
- generationStage: generate_component_response_1.GenerationStage.STREAMING_RESPONSE,
1317
- mcpAccessToken: "test-mcp-access-token",
1318
- };
1319
- // Third chunk calls the non-streamable tool
1320
- const mockNonStreamableToolChunk = {
1321
- responseMessageDto: {
1322
- id: "streaming-chunk",
1323
- content: [{ type: "text", text: "Calling non-streamable..." }],
1324
- role: "assistant",
1325
- threadId: "test-thread-1",
1326
- component: {
1327
- componentName: "",
1328
- componentState: {},
1329
- message: "",
1330
- props: {},
1331
- toolCallRequest: {
1332
- toolName: "non-streamable-tool",
1333
- parameters: [
1334
- {
1335
- parameterName: "input",
1336
- parameterValue: "non-streamed-input",
1337
- },
1338
- ],
1339
- },
1340
- },
1341
- componentState: {},
1342
- createdAt: new Date().toISOString(),
1343
- },
1344
- generationStage: generate_component_response_1.GenerationStage.STREAMING_RESPONSE,
1345
- mcpAccessToken: "test-mcp-access-token",
1346
- };
1347
- const mockFinalChunk = {
1348
- responseMessageDto: {
1349
- id: "streaming-chunk",
1350
- content: [{ type: "text", text: "Complete" }],
1351
- role: "assistant",
1352
- threadId: "test-thread-1",
1353
- componentState: {},
1354
- createdAt: new Date().toISOString(),
1355
- },
1356
- generationStage: generate_component_response_1.GenerationStage.COMPLETE,
1357
- mcpAccessToken: "test-mcp-access-token",
1358
- };
1359
- const mockAsyncIterator = {
1360
- [Symbol.asyncIterator]: async function* () {
1361
- yield mockInitialChunk;
1362
- yield mockStreamableToolChunk;
1363
- yield mockNonStreamableToolChunk;
1364
- yield mockFinalChunk;
1365
- },
1366
- };
1367
- jest.mocked(typescript_sdk_1.advanceStream).mockResolvedValueOnce(mockAsyncIterator);
1368
- const { result } = (0, react_1.renderHook)(() => (0, tambo_thread_provider_1.useTamboThread)(), {
1369
- wrapper: createWrapper({
1370
- components: customToolRegistry,
1371
- streaming: true,
1372
- }),
1373
- });
1374
- await (0, react_1.act)(async () => {
1375
- await result.current.sendThreadMessage("Test mixed tools", {
1376
- threadId: "test-thread-1",
1377
- streamResponse: true,
1378
- });
1379
- });
1380
- // Only the streamable tool should be called during streaming
1381
- expect(streamableToolFn).toHaveBeenCalledWith({
1382
- input: "streamed-input",
1383
- });
1384
- expect(nonStreamableToolFn).not.toHaveBeenCalled();
1385
- });
1386
- });
1387
- describe("auto-generate thread name", () => {
1388
- it("should auto-generate thread name after reaching threshold", async () => {
1389
- const mockStreamResponse = {
1390
- responseMessageDto: {
1391
- id: "response-1",
1392
- content: [{ type: "text", text: "Response" }],
1393
- role: "assistant",
1394
- threadId: "test-thread-1",
1395
- component: undefined,
1396
- componentState: {},
1397
- createdAt: new Date().toISOString(),
1398
- },
1399
- generationStage: generate_component_response_1.GenerationStage.COMPLETE,
1400
- mcpAccessToken: "test-mcp-access-token",
1401
- };
1402
- const mockAsyncIterator = {
1403
- [Symbol.asyncIterator]: async function* () {
1404
- yield mockStreamResponse;
1405
- },
1406
- };
1407
- jest.mocked(typescript_sdk_1.advanceStream).mockResolvedValue(mockAsyncIterator);
1408
- const { result } = (0, react_1.renderHook)(() => (0, tambo_thread_provider_1.useTamboThread)(), {
1409
- wrapper: createWrapper({ autoGenerateNameThreshold: 2 }),
1410
- });
1411
- const existingThread = createMockThread({
1412
- id: "test-thread-1",
1413
- name: undefined,
1414
- });
1415
- jest
1416
- .mocked(mockThreadsApi.retrieve)
1417
- .mockResolvedValueOnce(existingThread);
1418
- await (0, react_1.act)(async () => {
1419
- await result.current.switchCurrentThread("test-thread-1");
1420
- });
1421
- // Add first message
1422
- await (0, react_1.act)(async () => {
1423
- await result.current.addThreadMessage(createMockMessage({
1424
- id: "msg-1",
1425
- role: "user",
1426
- threadId: "test-thread-1",
1427
- }), false);
1428
- });
1429
- expect(mockThreadsApi.generateName).not.toHaveBeenCalled();
1430
- // Add second message and send to reach threshold
1431
- await (0, react_1.act)(async () => {
1432
- await result.current.addThreadMessage(createMockMessage({
1433
- id: "msg-2",
1434
- role: "assistant",
1435
- threadId: "test-thread-1",
1436
- }), false);
1437
- });
1438
- await (0, react_1.act)(async () => {
1439
- await result.current.sendThreadMessage("Test message", {
1440
- streamResponse: true,
1441
- });
1442
- });
1443
- expect(mockThreadsApi.generateName).toHaveBeenCalledWith("test-thread-1");
1444
- expect(result.current.thread.name).toBe("Generated Thread Name");
1445
- expect(mockQueryClient.setQueryData).toHaveBeenCalledWith(["threads", "test-project-id", undefined], expect.any(Function));
1446
- });
1447
- it("should NOT auto-generate when autoGenerateThreadName is false", async () => {
1448
- const mockStreamResponse = {
1449
- responseMessageDto: {
1450
- id: "response-1",
1451
- content: [{ type: "text", text: "Response" }],
1452
- role: "assistant",
1453
- threadId: "test-thread-1",
1454
- component: undefined,
1455
- componentState: {},
1456
- createdAt: new Date().toISOString(),
1457
- },
1458
- generationStage: generate_component_response_1.GenerationStage.COMPLETE,
1459
- mcpAccessToken: "test-mcp-access-token",
1460
- };
1461
- const mockAsyncIterator = {
1462
- [Symbol.asyncIterator]: async function* () {
1463
- yield mockStreamResponse;
1464
- },
1465
- };
1466
- jest.mocked(typescript_sdk_1.advanceStream).mockResolvedValue(mockAsyncIterator);
1467
- const { result } = (0, react_1.renderHook)(() => (0, tambo_thread_provider_1.useTamboThread)(), {
1468
- wrapper: createWrapper({
1469
- autoGenerateThreadName: false,
1470
- autoGenerateNameThreshold: 2,
1471
- }),
1472
- });
1473
- const existingThread = createMockThread({
1474
- id: "test-thread-1",
1475
- name: undefined,
1476
- });
1477
- jest
1478
- .mocked(mockThreadsApi.retrieve)
1479
- .mockResolvedValueOnce(existingThread);
1480
- await (0, react_1.act)(async () => {
1481
- await result.current.switchCurrentThread("test-thread-1");
1482
- });
1483
- await (0, react_1.act)(async () => {
1484
- await result.current.addThreadMessage(createMockMessage({
1485
- id: "msg-1",
1486
- role: "user",
1487
- threadId: "test-thread-1",
1488
- }), false);
1489
- });
1490
- await (0, react_1.act)(async () => {
1491
- await result.current.addThreadMessage(createMockMessage({
1492
- id: "msg-2",
1493
- role: "assistant",
1494
- threadId: "test-thread-1",
1495
- }), false);
1496
- });
1497
- await (0, react_1.act)(async () => {
1498
- await result.current.sendThreadMessage("Test message", {
1499
- streamResponse: true,
1500
- });
1501
- });
1502
- // Should NOT generate name because feature is disabled
1503
- expect(mockThreadsApi.generateName).not.toHaveBeenCalled();
1504
- });
1505
- it("should NOT auto-generate when thread already has a name", async () => {
1506
- const mockStreamResponse = {
1507
- responseMessageDto: {
1508
- id: "response-1",
1509
- content: [{ type: "text", text: "Response" }],
1510
- role: "assistant",
1511
- threadId: "test-thread-1",
1512
- component: undefined,
1513
- componentState: {},
1514
- createdAt: new Date().toISOString(),
1515
- },
1516
- generationStage: generate_component_response_1.GenerationStage.COMPLETE,
1517
- mcpAccessToken: "test-mcp-access-token",
1518
- };
1519
- const mockAsyncIterator = {
1520
- [Symbol.asyncIterator]: async function* () {
1521
- yield mockStreamResponse;
1522
- },
1523
- };
1524
- jest.mocked(typescript_sdk_1.advanceStream).mockResolvedValue(mockAsyncIterator);
1525
- const { result } = (0, react_1.renderHook)(() => (0, tambo_thread_provider_1.useTamboThread)(), {
1526
- wrapper: createWrapper({ autoGenerateNameThreshold: 2 }),
1527
- });
1528
- const threadWithName = createMockThread({
1529
- id: "test-thread-1",
1530
- name: "Existing Thread Name",
1531
- });
1532
- jest
1533
- .mocked(mockThreadsApi.retrieve)
1534
- .mockResolvedValueOnce(threadWithName);
1535
- await (0, react_1.act)(async () => {
1536
- await result.current.switchCurrentThread("test-thread-1");
1537
- });
1538
- // Verify thread has existing name
1539
- expect(result.current.thread.name).toBe("Existing Thread Name");
1540
- // Add messages to build up state
1541
- await (0, react_1.act)(async () => {
1542
- await result.current.addThreadMessage(createMockMessage({
1543
- id: "msg-1",
1544
- role: "user",
1545
- threadId: "test-thread-1",
1546
- }), false);
1547
- });
1548
- await (0, react_1.act)(async () => {
1549
- await result.current.addThreadMessage(createMockMessage({
1550
- id: "msg-2",
1551
- role: "assistant",
1552
- threadId: "test-thread-1",
1553
- }), false);
1554
- });
1555
- expect(result.current.thread.messages).toHaveLength(2);
1556
- // Send another message to reach threshold (3 messages total)
1557
- await (0, react_1.act)(async () => {
1558
- await result.current.sendThreadMessage("Test message", {
1559
- streamResponse: true,
1560
- });
1561
- });
1562
- // Should NOT generate name because thread already has one
1563
- expect(mockThreadsApi.generateName).not.toHaveBeenCalled();
1564
- });
1565
- it("should NOT auto-generate for placeholder thread", async () => {
1566
- const { result } = (0, react_1.renderHook)(() => (0, tambo_thread_provider_1.useTamboThread)(), {
1567
- wrapper: createWrapper({ autoGenerateNameThreshold: 2 }),
1568
- });
1569
- // Stay on placeholder thread
1570
- expect(result.current.thread.id).toBe("placeholder");
1571
- // Add messages to placeholder thread
1572
- await (0, react_1.act)(async () => {
1573
- await result.current.addThreadMessage(createMockMessage({
1574
- id: "msg-1",
1575
- role: "user",
1576
- threadId: "placeholder",
1577
- }), false);
1578
- });
1579
- await (0, react_1.act)(async () => {
1580
- await result.current.addThreadMessage(createMockMessage({
1581
- id: "msg-2",
1582
- role: "assistant",
1583
- threadId: "placeholder",
1584
- }), false);
1585
- });
1586
- // Should NOT generate name for placeholder thread
1587
- expect(mockThreadsApi.generateName).not.toHaveBeenCalled();
1588
- });
1589
- });
1590
- });
1591
- //# sourceMappingURL=tambo-thread-provider.test.js.map