@tambo-ai/react 0.69.1 → 0.71.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (402) hide show
  1. package/README.md +7 -7
  2. package/dist/hooks/use-tambo-threads.test.js.map +1 -1
  3. package/dist/index.d.ts +1 -1
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js.map +1 -1
  6. package/dist/mcp/index.d.ts +4 -5
  7. package/dist/mcp/index.d.ts.map +1 -1
  8. package/dist/mcp/index.js +4 -5
  9. package/dist/mcp/index.js.map +1 -1
  10. package/dist/model/component-metadata.d.ts +88 -241
  11. package/dist/model/component-metadata.d.ts.map +1 -1
  12. package/dist/model/component-metadata.js.map +1 -1
  13. package/dist/model/mcp-server-info.d.ts +3 -3
  14. package/dist/model/mcp-server-info.js.map +1 -1
  15. package/dist/providers/hooks/use-tambo-session-token.test.js.map +1 -1
  16. package/dist/providers/tambo-component-provider.d.ts +2 -2
  17. package/dist/providers/tambo-component-provider.d.ts.map +1 -1
  18. package/dist/providers/tambo-component-provider.js.map +1 -1
  19. package/dist/providers/tambo-interactable-provider.d.ts +1 -1
  20. package/dist/providers/tambo-registry-provider.d.ts +4 -4
  21. package/dist/providers/tambo-registry-provider.d.ts.map +1 -1
  22. package/dist/providers/tambo-registry-provider.js +11 -8
  23. package/dist/providers/tambo-registry-provider.js.map +1 -1
  24. package/dist/providers/tambo-registry-provider.test.js +31 -0
  25. package/dist/providers/tambo-registry-provider.test.js.map +1 -1
  26. package/dist/providers/tambo-registry-schema-compat.test.js +42 -52
  27. package/dist/providers/tambo-registry-schema-compat.test.js.map +1 -1
  28. package/dist/providers/tambo-stubs.d.ts +2 -2
  29. package/dist/providers/tambo-stubs.d.ts.map +1 -1
  30. package/dist/providers/tambo-stubs.js.map +1 -1
  31. package/dist/providers/tambo-thread-provider-initial-messages.test.js.map +1 -1
  32. package/dist/providers/tambo-thread-provider.d.ts.map +1 -1
  33. package/dist/providers/tambo-thread-provider.js +107 -141
  34. package/dist/providers/tambo-thread-provider.js.map +1 -1
  35. package/dist/providers/tambo-thread-provider.test.js +274 -445
  36. package/dist/providers/tambo-thread-provider.test.js.map +1 -1
  37. package/dist/schema/index.d.ts +1 -2
  38. package/dist/schema/index.d.ts.map +1 -1
  39. package/dist/schema/index.js +1 -5
  40. package/dist/schema/index.js.map +1 -1
  41. package/dist/schema/schema.d.ts +7 -24
  42. package/dist/schema/schema.d.ts.map +1 -1
  43. package/dist/schema/schema.js +34 -105
  44. package/dist/schema/schema.js.map +1 -1
  45. package/dist/schema/schema.test.js +26 -124
  46. package/dist/schema/schema.test.js.map +1 -1
  47. package/dist/testing/tools.d.ts +2 -12
  48. package/dist/testing/tools.d.ts.map +1 -1
  49. package/dist/testing/tools.js +1 -20
  50. package/dist/testing/tools.js.map +1 -1
  51. package/dist/testing/types.d.ts +2 -2
  52. package/dist/testing/types.d.ts.map +1 -1
  53. package/dist/testing/types.js.map +1 -1
  54. package/dist/util/registry-validators.d.ts +2 -2
  55. package/dist/util/registry-validators.d.ts.map +1 -1
  56. package/dist/util/registry-validators.js +37 -17
  57. package/dist/util/registry-validators.js.map +1 -1
  58. package/dist/util/registry-validators.test.js +64 -25
  59. package/dist/util/registry-validators.test.js.map +1 -1
  60. package/dist/util/registry.d.ts +4 -10
  61. package/dist/util/registry.d.ts.map +1 -1
  62. package/dist/util/registry.js +6 -22
  63. package/dist/util/registry.js.map +1 -1
  64. package/dist/util/registry.test.js +1 -47
  65. package/dist/util/registry.test.js.map +1 -1
  66. package/dist/util/tool-caller.d.ts +2 -2
  67. package/dist/util/tool-caller.d.ts.map +1 -1
  68. package/dist/util/tool-caller.js +5 -12
  69. package/dist/util/tool-caller.js.map +1 -1
  70. package/dist/v1/hooks/use-tambo-v1-messages.d.ts +58 -0
  71. package/dist/v1/hooks/use-tambo-v1-messages.d.ts.map +1 -0
  72. package/dist/v1/hooks/use-tambo-v1-messages.js +54 -0
  73. package/dist/v1/hooks/use-tambo-v1-messages.js.map +1 -0
  74. package/dist/v1/hooks/use-tambo-v1-messages.test.d.ts +2 -0
  75. package/dist/v1/hooks/use-tambo-v1-messages.test.d.ts.map +1 -0
  76. package/dist/v1/hooks/use-tambo-v1-messages.test.js +137 -0
  77. package/dist/v1/hooks/use-tambo-v1-messages.test.js.map +1 -0
  78. package/dist/v1/hooks/use-tambo-v1-send-message.d.ts +96 -0
  79. package/dist/v1/hooks/use-tambo-v1-send-message.d.ts.map +1 -0
  80. package/dist/v1/hooks/use-tambo-v1-send-message.js +227 -0
  81. package/dist/v1/hooks/use-tambo-v1-send-message.js.map +1 -0
  82. package/dist/v1/hooks/use-tambo-v1-send-message.test.d.ts +2 -0
  83. package/dist/v1/hooks/use-tambo-v1-send-message.test.d.ts.map +1 -0
  84. package/dist/v1/hooks/use-tambo-v1-send-message.test.js +827 -0
  85. package/dist/v1/hooks/use-tambo-v1-send-message.test.js.map +1 -0
  86. package/dist/v1/hooks/use-tambo-v1-thread-list.d.ts +61 -0
  87. package/dist/v1/hooks/use-tambo-v1-thread-list.d.ts.map +1 -0
  88. package/dist/v1/hooks/use-tambo-v1-thread-list.js +56 -0
  89. package/dist/v1/hooks/use-tambo-v1-thread-list.js.map +1 -0
  90. package/dist/v1/hooks/use-tambo-v1-thread-list.test.d.ts +2 -0
  91. package/dist/v1/hooks/use-tambo-v1-thread-list.test.d.ts.map +1 -0
  92. package/dist/v1/hooks/use-tambo-v1-thread-list.test.js +98 -0
  93. package/dist/v1/hooks/use-tambo-v1-thread-list.test.js.map +1 -0
  94. package/dist/v1/hooks/use-tambo-v1-thread.d.ts +37 -0
  95. package/dist/v1/hooks/use-tambo-v1-thread.d.ts.map +1 -0
  96. package/dist/v1/hooks/use-tambo-v1-thread.js +49 -0
  97. package/dist/v1/hooks/use-tambo-v1-thread.js.map +1 -0
  98. package/dist/v1/hooks/use-tambo-v1-thread.test.d.ts +2 -0
  99. package/dist/v1/hooks/use-tambo-v1-thread.test.d.ts.map +1 -0
  100. package/dist/v1/hooks/use-tambo-v1-thread.test.js +83 -0
  101. package/dist/v1/hooks/use-tambo-v1-thread.test.js.map +1 -0
  102. package/dist/v1/hooks/use-tambo-v1.d.ts +107 -0
  103. package/dist/v1/hooks/use-tambo-v1.d.ts.map +1 -0
  104. package/dist/v1/hooks/use-tambo-v1.js +87 -0
  105. package/dist/v1/hooks/use-tambo-v1.js.map +1 -0
  106. package/dist/v1/hooks/use-tambo-v1.test.d.ts +2 -0
  107. package/dist/v1/hooks/use-tambo-v1.test.d.ts.map +1 -0
  108. package/dist/v1/hooks/use-tambo-v1.test.js +150 -0
  109. package/dist/v1/hooks/use-tambo-v1.test.js.map +1 -0
  110. package/dist/v1/index.d.ts +73 -0
  111. package/dist/v1/index.d.ts.map +1 -0
  112. package/dist/v1/index.js +106 -0
  113. package/dist/v1/index.js.map +1 -0
  114. package/dist/v1/providers/tambo-v1-provider.d.ts +91 -0
  115. package/dist/v1/providers/tambo-v1-provider.d.ts.map +1 -0
  116. package/dist/v1/providers/tambo-v1-provider.js +110 -0
  117. package/dist/v1/providers/tambo-v1-provider.js.map +1 -0
  118. package/dist/v1/providers/tambo-v1-provider.test.d.ts +2 -0
  119. package/dist/v1/providers/tambo-v1-provider.test.d.ts.map +1 -0
  120. package/dist/v1/providers/tambo-v1-provider.test.js +123 -0
  121. package/dist/v1/providers/tambo-v1-provider.test.js.map +1 -0
  122. package/dist/v1/providers/tambo-v1-stream-context.d.ts +136 -0
  123. package/dist/v1/providers/tambo-v1-stream-context.d.ts.map +1 -0
  124. package/dist/v1/providers/tambo-v1-stream-context.js +230 -0
  125. package/dist/v1/providers/tambo-v1-stream-context.js.map +1 -0
  126. package/dist/v1/providers/tambo-v1-stream-context.test.d.ts +2 -0
  127. package/dist/v1/providers/tambo-v1-stream-context.test.d.ts.map +1 -0
  128. package/dist/v1/providers/tambo-v1-stream-context.test.js +85 -0
  129. package/dist/v1/providers/tambo-v1-stream-context.test.js.map +1 -0
  130. package/dist/v1/types/component.d.ts +50 -0
  131. package/dist/v1/types/component.d.ts.map +1 -0
  132. package/dist/v1/types/component.js +14 -0
  133. package/dist/v1/types/component.js.map +1 -0
  134. package/dist/v1/types/event.d.ts +72 -0
  135. package/dist/v1/types/event.d.ts.map +1 -0
  136. package/dist/v1/types/event.js +54 -0
  137. package/dist/v1/types/event.js.map +1 -0
  138. package/dist/v1/types/event.test.d.ts +2 -0
  139. package/dist/v1/types/event.test.d.ts.map +1 -0
  140. package/dist/v1/types/event.test.js +70 -0
  141. package/dist/v1/types/event.test.js.map +1 -0
  142. package/dist/v1/types/message.d.ts +35 -0
  143. package/dist/v1/types/message.d.ts.map +1 -0
  144. package/dist/v1/types/message.js +10 -0
  145. package/dist/v1/types/message.js.map +1 -0
  146. package/dist/v1/types/thread.d.ts +52 -0
  147. package/dist/v1/types/thread.d.ts.map +1 -0
  148. package/dist/v1/types/thread.js +9 -0
  149. package/dist/v1/types/thread.js.map +1 -0
  150. package/dist/v1/utils/event-accumulator.d.ts +100 -0
  151. package/dist/v1/utils/event-accumulator.d.ts.map +1 -0
  152. package/dist/v1/utils/event-accumulator.js +715 -0
  153. package/dist/v1/utils/event-accumulator.js.map +1 -0
  154. package/dist/v1/utils/event-accumulator.test.d.ts +2 -0
  155. package/dist/v1/utils/event-accumulator.test.d.ts.map +1 -0
  156. package/dist/v1/utils/event-accumulator.test.js +1010 -0
  157. package/dist/v1/utils/event-accumulator.test.js.map +1 -0
  158. package/dist/v1/utils/json-patch.d.ts +18 -0
  159. package/dist/v1/utils/json-patch.d.ts.map +1 -0
  160. package/dist/v1/utils/json-patch.js +35 -0
  161. package/dist/v1/utils/json-patch.js.map +1 -0
  162. package/dist/v1/utils/json-patch.test.d.ts +2 -0
  163. package/dist/v1/utils/json-patch.test.d.ts.map +1 -0
  164. package/dist/v1/utils/json-patch.test.js +28 -0
  165. package/dist/v1/utils/json-patch.test.js.map +1 -0
  166. package/dist/v1/utils/registry-conversion.d.ts +53 -0
  167. package/dist/v1/utils/registry-conversion.d.ts.map +1 -0
  168. package/dist/v1/utils/registry-conversion.js +114 -0
  169. package/dist/v1/utils/registry-conversion.js.map +1 -0
  170. package/dist/v1/utils/registry-conversion.test.d.ts +2 -0
  171. package/dist/v1/utils/registry-conversion.test.d.ts.map +1 -0
  172. package/dist/v1/utils/registry-conversion.test.js +179 -0
  173. package/dist/v1/utils/registry-conversion.test.js.map +1 -0
  174. package/dist/v1/utils/stream-handler.d.ts +45 -0
  175. package/dist/v1/utils/stream-handler.d.ts.map +1 -0
  176. package/dist/v1/utils/stream-handler.js +47 -0
  177. package/dist/v1/utils/stream-handler.js.map +1 -0
  178. package/dist/v1/utils/stream-handler.test.d.ts +2 -0
  179. package/dist/v1/utils/stream-handler.test.d.ts.map +1 -0
  180. package/dist/v1/utils/stream-handler.test.js +74 -0
  181. package/dist/v1/utils/stream-handler.test.js.map +1 -0
  182. package/dist/v1/utils/tool-call-tracker.d.ts +41 -0
  183. package/dist/v1/utils/tool-call-tracker.d.ts.map +1 -0
  184. package/dist/v1/utils/tool-call-tracker.js +90 -0
  185. package/dist/v1/utils/tool-call-tracker.js.map +1 -0
  186. package/dist/v1/utils/tool-executor.d.ts +33 -0
  187. package/dist/v1/utils/tool-executor.d.ts.map +1 -0
  188. package/dist/v1/utils/tool-executor.js +103 -0
  189. package/dist/v1/utils/tool-executor.js.map +1 -0
  190. package/dist/v1/utils/tool-executor.test.d.ts +2 -0
  191. package/dist/v1/utils/tool-executor.test.d.ts.map +1 -0
  192. package/dist/v1/utils/tool-executor.test.js +222 -0
  193. package/dist/v1/utils/tool-executor.test.js.map +1 -0
  194. package/esm/hooks/use-tambo-threads.test.js.map +1 -1
  195. package/esm/index.d.ts +1 -1
  196. package/esm/index.d.ts.map +1 -1
  197. package/esm/index.js.map +1 -1
  198. package/esm/mcp/index.d.ts +4 -5
  199. package/esm/mcp/index.d.ts.map +1 -1
  200. package/esm/mcp/index.js +4 -5
  201. package/esm/mcp/index.js.map +1 -1
  202. package/esm/model/component-metadata.d.ts +88 -241
  203. package/esm/model/component-metadata.d.ts.map +1 -1
  204. package/esm/model/component-metadata.js.map +1 -1
  205. package/esm/model/mcp-server-info.d.ts +3 -3
  206. package/esm/model/mcp-server-info.js.map +1 -1
  207. package/esm/providers/hooks/use-tambo-session-token.test.js.map +1 -1
  208. package/esm/providers/tambo-component-provider.d.ts +2 -2
  209. package/esm/providers/tambo-component-provider.d.ts.map +1 -1
  210. package/esm/providers/tambo-component-provider.js.map +1 -1
  211. package/esm/providers/tambo-interactable-provider.d.ts +1 -1
  212. package/esm/providers/tambo-registry-provider.d.ts +4 -4
  213. package/esm/providers/tambo-registry-provider.d.ts.map +1 -1
  214. package/esm/providers/tambo-registry-provider.js +11 -8
  215. package/esm/providers/tambo-registry-provider.js.map +1 -1
  216. package/esm/providers/tambo-registry-provider.test.js +31 -0
  217. package/esm/providers/tambo-registry-provider.test.js.map +1 -1
  218. package/esm/providers/tambo-registry-schema-compat.test.js +42 -52
  219. package/esm/providers/tambo-registry-schema-compat.test.js.map +1 -1
  220. package/esm/providers/tambo-stubs.d.ts +2 -2
  221. package/esm/providers/tambo-stubs.d.ts.map +1 -1
  222. package/esm/providers/tambo-stubs.js.map +1 -1
  223. package/esm/providers/tambo-thread-provider-initial-messages.test.js.map +1 -1
  224. package/esm/providers/tambo-thread-provider.d.ts.map +1 -1
  225. package/esm/providers/tambo-thread-provider.js +107 -141
  226. package/esm/providers/tambo-thread-provider.js.map +1 -1
  227. package/esm/providers/tambo-thread-provider.test.js +241 -445
  228. package/esm/providers/tambo-thread-provider.test.js.map +1 -1
  229. package/esm/schema/index.d.ts +1 -2
  230. package/esm/schema/index.d.ts.map +1 -1
  231. package/esm/schema/index.js +1 -2
  232. package/esm/schema/index.js.map +1 -1
  233. package/esm/schema/schema.d.ts +7 -24
  234. package/esm/schema/schema.d.ts.map +1 -1
  235. package/esm/schema/schema.js +34 -103
  236. package/esm/schema/schema.js.map +1 -1
  237. package/esm/schema/schema.test.js +27 -125
  238. package/esm/schema/schema.test.js.map +1 -1
  239. package/esm/testing/tools.d.ts +2 -12
  240. package/esm/testing/tools.d.ts.map +1 -1
  241. package/esm/testing/tools.js +2 -20
  242. package/esm/testing/tools.js.map +1 -1
  243. package/esm/testing/types.d.ts +2 -2
  244. package/esm/testing/types.d.ts.map +1 -1
  245. package/esm/testing/types.js.map +1 -1
  246. package/esm/util/registry-validators.d.ts +2 -2
  247. package/esm/util/registry-validators.d.ts.map +1 -1
  248. package/esm/util/registry-validators.js +38 -18
  249. package/esm/util/registry-validators.js.map +1 -1
  250. package/esm/util/registry-validators.test.js +64 -25
  251. package/esm/util/registry-validators.test.js.map +1 -1
  252. package/esm/util/registry.d.ts +4 -10
  253. package/esm/util/registry.d.ts.map +1 -1
  254. package/esm/util/registry.js +7 -22
  255. package/esm/util/registry.js.map +1 -1
  256. package/esm/util/registry.test.js +3 -49
  257. package/esm/util/registry.test.js.map +1 -1
  258. package/esm/util/tool-caller.d.ts +2 -2
  259. package/esm/util/tool-caller.d.ts.map +1 -1
  260. package/esm/util/tool-caller.js +5 -12
  261. package/esm/util/tool-caller.js.map +1 -1
  262. package/esm/v1/hooks/use-tambo-v1-messages.d.ts +58 -0
  263. package/esm/v1/hooks/use-tambo-v1-messages.d.ts.map +1 -0
  264. package/esm/v1/hooks/use-tambo-v1-messages.js +51 -0
  265. package/esm/v1/hooks/use-tambo-v1-messages.js.map +1 -0
  266. package/esm/v1/hooks/use-tambo-v1-messages.test.d.ts +2 -0
  267. package/esm/v1/hooks/use-tambo-v1-messages.test.d.ts.map +1 -0
  268. package/esm/v1/hooks/use-tambo-v1-messages.test.js +132 -0
  269. package/esm/v1/hooks/use-tambo-v1-messages.test.js.map +1 -0
  270. package/esm/v1/hooks/use-tambo-v1-send-message.d.ts +96 -0
  271. package/esm/v1/hooks/use-tambo-v1-send-message.d.ts.map +1 -0
  272. package/esm/v1/hooks/use-tambo-v1-send-message.js +223 -0
  273. package/esm/v1/hooks/use-tambo-v1-send-message.js.map +1 -0
  274. package/esm/v1/hooks/use-tambo-v1-send-message.test.d.ts +2 -0
  275. package/esm/v1/hooks/use-tambo-v1-send-message.test.d.ts.map +1 -0
  276. package/esm/v1/hooks/use-tambo-v1-send-message.test.js +822 -0
  277. package/esm/v1/hooks/use-tambo-v1-send-message.test.js.map +1 -0
  278. package/esm/v1/hooks/use-tambo-v1-thread-list.d.ts +61 -0
  279. package/esm/v1/hooks/use-tambo-v1-thread-list.d.ts.map +1 -0
  280. package/esm/v1/hooks/use-tambo-v1-thread-list.js +53 -0
  281. package/esm/v1/hooks/use-tambo-v1-thread-list.js.map +1 -0
  282. package/esm/v1/hooks/use-tambo-v1-thread-list.test.d.ts +2 -0
  283. package/esm/v1/hooks/use-tambo-v1-thread-list.test.d.ts.map +1 -0
  284. package/esm/v1/hooks/use-tambo-v1-thread-list.test.js +93 -0
  285. package/esm/v1/hooks/use-tambo-v1-thread-list.test.js.map +1 -0
  286. package/esm/v1/hooks/use-tambo-v1-thread.d.ts +37 -0
  287. package/esm/v1/hooks/use-tambo-v1-thread.d.ts.map +1 -0
  288. package/esm/v1/hooks/use-tambo-v1-thread.js +46 -0
  289. package/esm/v1/hooks/use-tambo-v1-thread.js.map +1 -0
  290. package/esm/v1/hooks/use-tambo-v1-thread.test.d.ts +2 -0
  291. package/esm/v1/hooks/use-tambo-v1-thread.test.d.ts.map +1 -0
  292. package/esm/v1/hooks/use-tambo-v1-thread.test.js +78 -0
  293. package/esm/v1/hooks/use-tambo-v1-thread.test.js.map +1 -0
  294. package/esm/v1/hooks/use-tambo-v1.d.ts +107 -0
  295. package/esm/v1/hooks/use-tambo-v1.d.ts.map +1 -0
  296. package/esm/v1/hooks/use-tambo-v1.js +84 -0
  297. package/esm/v1/hooks/use-tambo-v1.js.map +1 -0
  298. package/esm/v1/hooks/use-tambo-v1.test.d.ts +2 -0
  299. package/esm/v1/hooks/use-tambo-v1.test.d.ts.map +1 -0
  300. package/esm/v1/hooks/use-tambo-v1.test.js +145 -0
  301. package/esm/v1/hooks/use-tambo-v1.test.js.map +1 -0
  302. package/esm/v1/index.d.ts +73 -0
  303. package/esm/v1/index.d.ts.map +1 -0
  304. package/esm/v1/index.js +83 -0
  305. package/esm/v1/index.js.map +1 -0
  306. package/esm/v1/providers/tambo-v1-provider.d.ts +91 -0
  307. package/esm/v1/providers/tambo-v1-provider.d.ts.map +1 -0
  308. package/esm/v1/providers/tambo-v1-provider.js +74 -0
  309. package/esm/v1/providers/tambo-v1-provider.js.map +1 -0
  310. package/esm/v1/providers/tambo-v1-provider.test.d.ts +2 -0
  311. package/esm/v1/providers/tambo-v1-provider.test.d.ts.map +1 -0
  312. package/esm/v1/providers/tambo-v1-provider.test.js +118 -0
  313. package/esm/v1/providers/tambo-v1-provider.test.js.map +1 -0
  314. package/esm/v1/providers/tambo-v1-stream-context.d.ts +136 -0
  315. package/esm/v1/providers/tambo-v1-stream-context.d.ts.map +1 -0
  316. package/esm/v1/providers/tambo-v1-stream-context.js +191 -0
  317. package/esm/v1/providers/tambo-v1-stream-context.js.map +1 -0
  318. package/esm/v1/providers/tambo-v1-stream-context.test.d.ts +2 -0
  319. package/esm/v1/providers/tambo-v1-stream-context.test.d.ts.map +1 -0
  320. package/esm/v1/providers/tambo-v1-stream-context.test.js +80 -0
  321. package/esm/v1/providers/tambo-v1-stream-context.test.js.map +1 -0
  322. package/esm/v1/types/component.d.ts +50 -0
  323. package/esm/v1/types/component.d.ts.map +1 -0
  324. package/esm/v1/types/component.js +13 -0
  325. package/esm/v1/types/component.js.map +1 -0
  326. package/esm/v1/types/event.d.ts +72 -0
  327. package/esm/v1/types/event.d.ts.map +1 -0
  328. package/esm/v1/types/event.js +50 -0
  329. package/esm/v1/types/event.js.map +1 -0
  330. package/esm/v1/types/event.test.d.ts +2 -0
  331. package/esm/v1/types/event.test.d.ts.map +1 -0
  332. package/esm/v1/types/event.test.js +68 -0
  333. package/esm/v1/types/event.test.js.map +1 -0
  334. package/esm/v1/types/message.d.ts +35 -0
  335. package/esm/v1/types/message.d.ts.map +1 -0
  336. package/esm/v1/types/message.js +9 -0
  337. package/esm/v1/types/message.js.map +1 -0
  338. package/esm/v1/types/thread.d.ts +52 -0
  339. package/esm/v1/types/thread.d.ts.map +1 -0
  340. package/esm/v1/types/thread.js +8 -0
  341. package/esm/v1/types/thread.js.map +1 -0
  342. package/esm/v1/utils/event-accumulator.d.ts +100 -0
  343. package/esm/v1/utils/event-accumulator.d.ts.map +1 -0
  344. package/esm/v1/utils/event-accumulator.js +708 -0
  345. package/esm/v1/utils/event-accumulator.js.map +1 -0
  346. package/esm/v1/utils/event-accumulator.test.d.ts +2 -0
  347. package/esm/v1/utils/event-accumulator.test.d.ts.map +1 -0
  348. package/esm/v1/utils/event-accumulator.test.js +1008 -0
  349. package/esm/v1/utils/event-accumulator.test.js.map +1 -0
  350. package/esm/v1/utils/json-patch.d.ts +18 -0
  351. package/esm/v1/utils/json-patch.d.ts.map +1 -0
  352. package/esm/v1/utils/json-patch.js +32 -0
  353. package/esm/v1/utils/json-patch.js.map +1 -0
  354. package/esm/v1/utils/json-patch.test.d.ts +2 -0
  355. package/esm/v1/utils/json-patch.test.d.ts.map +1 -0
  356. package/esm/v1/utils/json-patch.test.js +26 -0
  357. package/esm/v1/utils/json-patch.test.js.map +1 -0
  358. package/esm/v1/utils/registry-conversion.d.ts +53 -0
  359. package/esm/v1/utils/registry-conversion.d.ts.map +1 -0
  360. package/esm/v1/utils/registry-conversion.js +108 -0
  361. package/esm/v1/utils/registry-conversion.js.map +1 -0
  362. package/esm/v1/utils/registry-conversion.test.d.ts +2 -0
  363. package/esm/v1/utils/registry-conversion.test.d.ts.map +1 -0
  364. package/esm/v1/utils/registry-conversion.test.js +177 -0
  365. package/esm/v1/utils/registry-conversion.test.js.map +1 -0
  366. package/esm/v1/utils/stream-handler.d.ts +45 -0
  367. package/esm/v1/utils/stream-handler.d.ts.map +1 -0
  368. package/esm/v1/utils/stream-handler.js +44 -0
  369. package/esm/v1/utils/stream-handler.js.map +1 -0
  370. package/esm/v1/utils/stream-handler.test.d.ts +2 -0
  371. package/esm/v1/utils/stream-handler.test.d.ts.map +1 -0
  372. package/esm/v1/utils/stream-handler.test.js +72 -0
  373. package/esm/v1/utils/stream-handler.test.js.map +1 -0
  374. package/esm/v1/utils/tool-call-tracker.d.ts +41 -0
  375. package/esm/v1/utils/tool-call-tracker.d.ts.map +1 -0
  376. package/esm/v1/utils/tool-call-tracker.js +86 -0
  377. package/esm/v1/utils/tool-call-tracker.js.map +1 -0
  378. package/esm/v1/utils/tool-executor.d.ts +33 -0
  379. package/esm/v1/utils/tool-executor.d.ts.map +1 -0
  380. package/esm/v1/utils/tool-executor.js +99 -0
  381. package/esm/v1/utils/tool-executor.js.map +1 -0
  382. package/esm/v1/utils/tool-executor.test.d.ts +2 -0
  383. package/esm/v1/utils/tool-executor.test.d.ts.map +1 -0
  384. package/esm/v1/utils/tool-executor.test.js +220 -0
  385. package/esm/v1/utils/tool-executor.test.js.map +1 -0
  386. package/package.json +20 -9
  387. package/dist/schema/zod.d.ts +0 -57
  388. package/dist/schema/zod.d.ts.map +0 -1
  389. package/dist/schema/zod.js +0 -191
  390. package/dist/schema/zod.js.map +0 -1
  391. package/dist/schema/zod.test.d.ts +0 -2
  392. package/dist/schema/zod.test.d.ts.map +0 -1
  393. package/dist/schema/zod.test.js +0 -663
  394. package/dist/schema/zod.test.js.map +0 -1
  395. package/esm/schema/zod.d.ts +0 -57
  396. package/esm/schema/zod.d.ts.map +0 -1
  397. package/esm/schema/zod.js +0 -180
  398. package/esm/schema/zod.js.map +0 -1
  399. package/esm/schema/zod.test.d.ts +0 -2
  400. package/esm/schema/zod.test.d.ts.map +0 -1
  401. package/esm/schema/zod.test.js +0 -628
  402. package/esm/schema/zod.test.js.map +0 -1
@@ -0,0 +1,1008 @@
1
+ import { EventType, } from "@ag-ui/core";
2
+ import { createInitialState, createInitialThreadState, streamReducer, } from "./event-accumulator";
3
+ /**
4
+ * Helper to extract a ToolUseContent from a message content array.
5
+ * @param content - Content array from a message
6
+ * @param index - Index of the content item
7
+ * @returns The content as ToolUseContent
8
+ */
9
+ function asToolUseContent(content, index) {
10
+ return content[index];
11
+ }
12
+ /**
13
+ * Helper to extract a ComponentContent from a message content array.
14
+ * @param content - Content array from a message
15
+ * @param index - Index of the content item
16
+ * @returns The content as ComponentContent
17
+ */
18
+ function asComponentContent(content, index) {
19
+ return content[index];
20
+ }
21
+ // Helper to create a base thread state for testing
22
+ function createTestThreadState(threadId) {
23
+ return {
24
+ ...createInitialThreadState(threadId),
25
+ thread: {
26
+ ...createInitialThreadState(threadId).thread,
27
+ // Use fixed timestamps for snapshot stability
28
+ createdAt: "2024-01-01T00:00:00.000Z",
29
+ updatedAt: "2024-01-01T00:00:00.000Z",
30
+ },
31
+ };
32
+ }
33
+ // Helper to create stream state with a thread
34
+ function createTestStreamState(threadId) {
35
+ return {
36
+ threadMap: {
37
+ [threadId]: createTestThreadState(threadId),
38
+ },
39
+ currentThreadId: threadId,
40
+ };
41
+ }
42
+ describe("createInitialThreadState", () => {
43
+ it("creates thread state with correct structure", () => {
44
+ const state = createInitialThreadState("thread_123");
45
+ expect(state.thread.id).toBe("thread_123");
46
+ expect(state.thread.messages).toEqual([]);
47
+ expect(state.thread.status).toBe("idle");
48
+ expect(state.streaming.status).toBe("idle");
49
+ expect(state.accumulatingToolArgs).toBeInstanceOf(Map);
50
+ expect(state.accumulatingToolArgs.size).toBe(0);
51
+ });
52
+ });
53
+ describe("createInitialState", () => {
54
+ it("creates empty stream state", () => {
55
+ const state = createInitialState();
56
+ expect(state.threadMap).toEqual({});
57
+ expect(state.currentThreadId).toBeNull();
58
+ });
59
+ });
60
+ describe("streamReducer", () => {
61
+ // Mock console.warn for tests that check logging
62
+ let consoleWarnSpy;
63
+ beforeEach(() => {
64
+ consoleWarnSpy = jest.spyOn(console, "warn").mockImplementation(() => { });
65
+ });
66
+ afterEach(() => {
67
+ consoleWarnSpy.mockRestore();
68
+ });
69
+ describe("unknown thread handling", () => {
70
+ it("auto-initializes unknown thread when receiving events", () => {
71
+ const state = createInitialState();
72
+ const event = {
73
+ type: EventType.RUN_STARTED,
74
+ runId: "run_1",
75
+ threadId: "unknown_thread",
76
+ };
77
+ const result = streamReducer(state, {
78
+ type: "EVENT",
79
+ event,
80
+ threadId: "unknown_thread",
81
+ });
82
+ // Should auto-initialize the thread rather than dropping the event
83
+ expect(result.threadMap.unknown_thread).toBeDefined();
84
+ expect(result.threadMap.unknown_thread.thread.id).toBe("unknown_thread");
85
+ expect(result.threadMap.unknown_thread.streaming.status).toBe("streaming");
86
+ expect(result.threadMap.unknown_thread.streaming.runId).toBe("run_1");
87
+ // No warning should be logged for auto-initialization
88
+ expect(consoleWarnSpy).not.toHaveBeenCalled();
89
+ });
90
+ });
91
+ describe("unsupported event types", () => {
92
+ it("logs warning for unsupported AG-UI events", () => {
93
+ const state = createTestStreamState("thread_1");
94
+ const event = {
95
+ type: EventType.STATE_SNAPSHOT,
96
+ snapshot: {},
97
+ };
98
+ const result = streamReducer(state, {
99
+ type: "EVENT",
100
+ event,
101
+ threadId: "thread_1",
102
+ });
103
+ expect(result).toBe(state);
104
+ expect(consoleWarnSpy).toHaveBeenCalledWith(expect.stringContaining("unsupported event type"));
105
+ });
106
+ it("throws for completely unknown event types (fail-fast)", () => {
107
+ const state = createTestStreamState("thread_1");
108
+ // Create an event with an unknown type (not in EventType enum)
109
+ // This tests fail-fast behavior when SDK returns unexpected event types
110
+ const event = {
111
+ type: "TOTALLY_UNKNOWN_EVENT_TYPE",
112
+ };
113
+ expect(() => streamReducer(state, {
114
+ type: "EVENT",
115
+ event: event,
116
+ threadId: "thread_1",
117
+ })).toThrow("Unreachable case");
118
+ });
119
+ it("logs warning for unknown custom event names", () => {
120
+ const state = createTestStreamState("thread_1");
121
+ const event = {
122
+ type: EventType.CUSTOM,
123
+ name: "unknown.custom.event",
124
+ value: {},
125
+ };
126
+ const result = streamReducer(state, {
127
+ type: "EVENT",
128
+ event,
129
+ threadId: "thread_1",
130
+ });
131
+ expect(result.threadMap.thread_1).toBe(state.threadMap.thread_1);
132
+ expect(consoleWarnSpy).toHaveBeenCalledWith(expect.stringContaining("Unknown custom event name"));
133
+ });
134
+ });
135
+ describe("RUN_STARTED event", () => {
136
+ it("updates thread status to streaming", () => {
137
+ const state = createTestStreamState("thread_1");
138
+ const event = {
139
+ type: EventType.RUN_STARTED,
140
+ runId: "run_123",
141
+ threadId: "thread_1",
142
+ timestamp: 1704067200000,
143
+ };
144
+ const result = streamReducer(state, {
145
+ type: "EVENT",
146
+ event,
147
+ threadId: "thread_1",
148
+ });
149
+ expect(result.threadMap.thread_1.thread.status).toBe("streaming");
150
+ expect(result.threadMap.thread_1.streaming.status).toBe("streaming");
151
+ expect(result.threadMap.thread_1.streaming.runId).toBe("run_123");
152
+ });
153
+ it("uses provided timestamp for startTime", () => {
154
+ const state = createTestStreamState("thread_1");
155
+ const event = {
156
+ type: EventType.RUN_STARTED,
157
+ runId: "run_123",
158
+ threadId: "thread_1",
159
+ timestamp: 1704067200000,
160
+ };
161
+ const result = streamReducer(state, {
162
+ type: "EVENT",
163
+ event,
164
+ threadId: "thread_1",
165
+ });
166
+ expect(result.threadMap.thread_1.streaming.startTime).toBe(1704067200000);
167
+ });
168
+ });
169
+ describe("RUN_FINISHED event", () => {
170
+ it("updates thread status to complete", () => {
171
+ const state = createTestStreamState("thread_1");
172
+ state.threadMap.thread_1.thread.status = "streaming";
173
+ state.threadMap.thread_1.streaming.status = "streaming";
174
+ const event = {
175
+ type: EventType.RUN_FINISHED,
176
+ runId: "run_123",
177
+ threadId: "thread_1",
178
+ };
179
+ const result = streamReducer(state, {
180
+ type: "EVENT",
181
+ event,
182
+ threadId: "thread_1",
183
+ });
184
+ expect(result.threadMap.thread_1.thread.status).toBe("complete");
185
+ expect(result.threadMap.thread_1.streaming.status).toBe("complete");
186
+ });
187
+ });
188
+ describe("RUN_ERROR event", () => {
189
+ it("updates thread status to error with details", () => {
190
+ const state = createTestStreamState("thread_1");
191
+ const event = {
192
+ type: EventType.RUN_ERROR,
193
+ message: "Something went wrong",
194
+ code: "ERR_001",
195
+ };
196
+ const result = streamReducer(state, {
197
+ type: "EVENT",
198
+ event,
199
+ threadId: "thread_1",
200
+ });
201
+ expect(result.threadMap.thread_1.thread.status).toBe("error");
202
+ expect(result.threadMap.thread_1.streaming.status).toBe("error");
203
+ expect(result.threadMap.thread_1.streaming.error).toEqual({
204
+ message: "Something went wrong",
205
+ code: "ERR_001",
206
+ });
207
+ });
208
+ });
209
+ describe("TEXT_MESSAGE_START event", () => {
210
+ it("creates new message in thread", () => {
211
+ const state = createTestStreamState("thread_1");
212
+ const event = {
213
+ type: EventType.TEXT_MESSAGE_START,
214
+ messageId: "msg_1",
215
+ role: "assistant",
216
+ };
217
+ const result = streamReducer(state, {
218
+ type: "EVENT",
219
+ event,
220
+ threadId: "thread_1",
221
+ });
222
+ const messages = result.threadMap.thread_1.thread.messages;
223
+ expect(messages).toHaveLength(1);
224
+ expect(messages[0].id).toBe("msg_1");
225
+ expect(messages[0].role).toBe("assistant");
226
+ expect(messages[0].content).toEqual([]);
227
+ });
228
+ it("creates user message when role is user", () => {
229
+ const state = createTestStreamState("thread_1");
230
+ const event = {
231
+ type: EventType.TEXT_MESSAGE_START,
232
+ messageId: "msg_1",
233
+ role: "user",
234
+ };
235
+ const result = streamReducer(state, {
236
+ type: "EVENT",
237
+ event,
238
+ threadId: "thread_1",
239
+ });
240
+ const messages = result.threadMap.thread_1.thread.messages;
241
+ expect(messages).toHaveLength(1);
242
+ expect(messages[0].role).toBe("user");
243
+ });
244
+ });
245
+ describe("TEXT_MESSAGE_CONTENT event", () => {
246
+ it("appends text content to message", () => {
247
+ const state = createTestStreamState("thread_1");
248
+ // Add a message first
249
+ state.threadMap.thread_1.thread.messages = [
250
+ {
251
+ id: "msg_1",
252
+ role: "assistant",
253
+ content: [],
254
+ createdAt: "2024-01-01T00:00:00.000Z",
255
+ },
256
+ ];
257
+ const event = {
258
+ type: EventType.TEXT_MESSAGE_CONTENT,
259
+ messageId: "msg_1",
260
+ delta: "Hello ",
261
+ };
262
+ const result = streamReducer(state, {
263
+ type: "EVENT",
264
+ event,
265
+ threadId: "thread_1",
266
+ });
267
+ const content = result.threadMap.thread_1.thread.messages[0].content;
268
+ expect(content).toHaveLength(1);
269
+ expect(content[0]).toEqual({ type: "text", text: "Hello " });
270
+ });
271
+ it("creates new text block after non-text content", () => {
272
+ const state = createTestStreamState("thread_1");
273
+ state.threadMap.thread_1.thread.messages = [
274
+ {
275
+ id: "msg_1",
276
+ role: "assistant",
277
+ content: [
278
+ { type: "tool_use", id: "tool_1", name: "test", input: {} },
279
+ ],
280
+ createdAt: "2024-01-01T00:00:00.000Z",
281
+ },
282
+ ];
283
+ const event = {
284
+ type: EventType.TEXT_MESSAGE_CONTENT,
285
+ messageId: "msg_1",
286
+ delta: "After tool call",
287
+ };
288
+ const result = streamReducer(state, {
289
+ type: "EVENT",
290
+ event,
291
+ threadId: "thread_1",
292
+ });
293
+ const content = result.threadMap.thread_1.thread.messages[0].content;
294
+ expect(content).toHaveLength(2);
295
+ expect(content[0]).toEqual({
296
+ type: "tool_use",
297
+ id: "tool_1",
298
+ name: "test",
299
+ input: {},
300
+ });
301
+ expect(content[1]).toEqual({ type: "text", text: "After tool call" });
302
+ });
303
+ it("accumulates text content deltas", () => {
304
+ const state = createTestStreamState("thread_1");
305
+ state.threadMap.thread_1.thread.messages = [
306
+ {
307
+ id: "msg_1",
308
+ role: "assistant",
309
+ content: [{ type: "text", text: "Hello " }],
310
+ createdAt: "2024-01-01T00:00:00.000Z",
311
+ },
312
+ ];
313
+ const event = {
314
+ type: EventType.TEXT_MESSAGE_CONTENT,
315
+ messageId: "msg_1",
316
+ delta: "world!",
317
+ };
318
+ const result = streamReducer(state, {
319
+ type: "EVENT",
320
+ event,
321
+ threadId: "thread_1",
322
+ });
323
+ const content = result.threadMap.thread_1.thread.messages[0].content;
324
+ expect(content).toHaveLength(1);
325
+ expect(content[0]).toEqual({ type: "text", text: "Hello world!" });
326
+ });
327
+ it("throws when message not found", () => {
328
+ const state = createTestStreamState("thread_1");
329
+ state.threadMap.thread_1.thread.messages = [
330
+ {
331
+ id: "msg_1",
332
+ role: "assistant",
333
+ content: [],
334
+ createdAt: "2024-01-01T00:00:00.000Z",
335
+ },
336
+ ];
337
+ const event = {
338
+ type: EventType.TEXT_MESSAGE_CONTENT,
339
+ messageId: "unknown_msg",
340
+ delta: "Hello",
341
+ };
342
+ expect(() => {
343
+ streamReducer(state, {
344
+ type: "EVENT",
345
+ event,
346
+ threadId: "thread_1",
347
+ });
348
+ }).toThrow("Message unknown_msg not found");
349
+ });
350
+ });
351
+ describe("TEXT_MESSAGE_END event", () => {
352
+ it("throws when messageId doesn't match active message", () => {
353
+ const state = createTestStreamState("thread_1");
354
+ // Set up an active message in streaming state
355
+ state.threadMap.thread_1.streaming.messageId = "msg_1";
356
+ state.threadMap.thread_1.thread.messages = [
357
+ {
358
+ id: "msg_1",
359
+ role: "assistant",
360
+ content: [{ type: "text", text: "Hello" }],
361
+ createdAt: "2024-01-01T00:00:00.000Z",
362
+ },
363
+ ];
364
+ const event = {
365
+ type: EventType.TEXT_MESSAGE_END,
366
+ messageId: "wrong_msg_id",
367
+ };
368
+ expect(() => {
369
+ streamReducer(state, {
370
+ type: "EVENT",
371
+ event,
372
+ threadId: "thread_1",
373
+ });
374
+ }).toThrow("TEXT_MESSAGE_END messageId mismatch");
375
+ });
376
+ it("clears active messageId on success", () => {
377
+ const state = createTestStreamState("thread_1");
378
+ state.threadMap.thread_1.streaming.messageId = "msg_1";
379
+ state.threadMap.thread_1.thread.messages = [
380
+ {
381
+ id: "msg_1",
382
+ role: "assistant",
383
+ content: [{ type: "text", text: "Hello" }],
384
+ createdAt: "2024-01-01T00:00:00.000Z",
385
+ },
386
+ ];
387
+ const event = {
388
+ type: EventType.TEXT_MESSAGE_END,
389
+ messageId: "msg_1",
390
+ };
391
+ const result = streamReducer(state, {
392
+ type: "EVENT",
393
+ event,
394
+ threadId: "thread_1",
395
+ });
396
+ expect(result.threadMap.thread_1.streaming.messageId).toBeUndefined();
397
+ });
398
+ });
399
+ describe("TOOL_CALL_START event", () => {
400
+ it("adds tool_use content block to message", () => {
401
+ const state = createTestStreamState("thread_1");
402
+ state.threadMap.thread_1.thread.messages = [
403
+ {
404
+ id: "msg_1",
405
+ role: "assistant",
406
+ content: [],
407
+ createdAt: "2024-01-01T00:00:00.000Z",
408
+ },
409
+ ];
410
+ const event = {
411
+ type: EventType.TOOL_CALL_START,
412
+ toolCallId: "tool_1",
413
+ toolCallName: "get_weather",
414
+ parentMessageId: "msg_1",
415
+ };
416
+ const result = streamReducer(state, {
417
+ type: "EVENT",
418
+ event,
419
+ threadId: "thread_1",
420
+ });
421
+ const content = result.threadMap.thread_1.thread.messages[0].content;
422
+ expect(content).toHaveLength(1);
423
+ expect(content[0]).toEqual({
424
+ type: "tool_use",
425
+ id: "tool_1",
426
+ name: "get_weather",
427
+ input: {},
428
+ });
429
+ });
430
+ });
431
+ describe("TOOL_CALL_START event", () => {
432
+ it("uses last message when no parentMessageId provided", () => {
433
+ const state = createTestStreamState("thread_1");
434
+ state.threadMap.thread_1.thread.messages = [
435
+ {
436
+ id: "msg_1",
437
+ role: "assistant",
438
+ content: [],
439
+ createdAt: "2024-01-01T00:00:00.000Z",
440
+ },
441
+ ];
442
+ const event = {
443
+ type: EventType.TOOL_CALL_START,
444
+ toolCallId: "tool_1",
445
+ toolCallName: "get_weather",
446
+ // No parentMessageId - should use last message
447
+ };
448
+ const result = streamReducer(state, {
449
+ type: "EVENT",
450
+ event,
451
+ threadId: "thread_1",
452
+ });
453
+ const content = result.threadMap.thread_1.thread.messages[0].content;
454
+ expect(content).toHaveLength(1);
455
+ expect(content[0]).toEqual({
456
+ type: "tool_use",
457
+ id: "tool_1",
458
+ name: "get_weather",
459
+ input: {},
460
+ });
461
+ });
462
+ it("throws when parentMessageId message not found", () => {
463
+ const state = createTestStreamState("thread_1");
464
+ state.threadMap.thread_1.thread.messages = [
465
+ {
466
+ id: "msg_1",
467
+ role: "assistant",
468
+ content: [],
469
+ createdAt: "2024-01-01T00:00:00.000Z",
470
+ },
471
+ ];
472
+ const event = {
473
+ type: EventType.TOOL_CALL_START,
474
+ toolCallId: "tool_1",
475
+ toolCallName: "get_weather",
476
+ parentMessageId: "unknown_msg",
477
+ };
478
+ expect(() => {
479
+ streamReducer(state, {
480
+ type: "EVENT",
481
+ event,
482
+ threadId: "thread_1",
483
+ });
484
+ }).toThrow("Message unknown_msg not found for TOOL_CALL_START event");
485
+ });
486
+ it("throws when no messages exist", () => {
487
+ const state = createTestStreamState("thread_1");
488
+ state.threadMap.thread_1.thread.messages = [];
489
+ const event = {
490
+ type: EventType.TOOL_CALL_START,
491
+ toolCallId: "tool_1",
492
+ toolCallName: "get_weather",
493
+ // No parentMessageId, no messages
494
+ };
495
+ expect(() => {
496
+ streamReducer(state, {
497
+ type: "EVENT",
498
+ event,
499
+ threadId: "thread_1",
500
+ });
501
+ }).toThrow("No messages exist for TOOL_CALL_START event");
502
+ });
503
+ });
504
+ describe("TOOL_CALL_ARGS and TOOL_CALL_END events", () => {
505
+ it("handles TOOL_CALL_END with no accumulated args", () => {
506
+ const state = createTestStreamState("thread_1");
507
+ state.threadMap.thread_1.thread.messages = [
508
+ {
509
+ id: "msg_1",
510
+ role: "assistant",
511
+ content: [
512
+ { type: "tool_use", id: "tool_1", name: "test", input: {} },
513
+ ],
514
+ createdAt: "2024-01-01T00:00:00.000Z",
515
+ },
516
+ ];
517
+ // Send TOOL_CALL_END without any TOOL_CALL_ARGS first
518
+ const endEvent = {
519
+ type: EventType.TOOL_CALL_END,
520
+ toolCallId: "tool_1",
521
+ };
522
+ const result = streamReducer(state, {
523
+ type: "EVENT",
524
+ event: endEvent,
525
+ threadId: "thread_1",
526
+ });
527
+ // Should return unchanged state since no args were accumulated
528
+ expect(result.threadMap.thread_1).toBe(state.threadMap.thread_1);
529
+ });
530
+ it("accumulates and parses tool arguments", () => {
531
+ const state = createTestStreamState("thread_1");
532
+ state.threadMap.thread_1.thread.messages = [
533
+ {
534
+ id: "msg_1",
535
+ role: "assistant",
536
+ content: [
537
+ { type: "tool_use", id: "tool_1", name: "test", input: {} },
538
+ ],
539
+ createdAt: "2024-01-01T00:00:00.000Z",
540
+ },
541
+ ];
542
+ // Send TOOL_CALL_ARGS
543
+ const argsEvent1 = {
544
+ type: EventType.TOOL_CALL_ARGS,
545
+ toolCallId: "tool_1",
546
+ delta: '{"city":',
547
+ };
548
+ let result = streamReducer(state, {
549
+ type: "EVENT",
550
+ event: argsEvent1,
551
+ threadId: "thread_1",
552
+ });
553
+ const argsEvent2 = {
554
+ type: EventType.TOOL_CALL_ARGS,
555
+ toolCallId: "tool_1",
556
+ delta: '"NYC"}',
557
+ };
558
+ result = streamReducer(result, {
559
+ type: "EVENT",
560
+ event: argsEvent2,
561
+ threadId: "thread_1",
562
+ });
563
+ // Send TOOL_CALL_END
564
+ const endEvent = {
565
+ type: EventType.TOOL_CALL_END,
566
+ toolCallId: "tool_1",
567
+ };
568
+ result = streamReducer(result, {
569
+ type: "EVENT",
570
+ event: endEvent,
571
+ threadId: "thread_1",
572
+ });
573
+ const toolContent = asToolUseContent(result.threadMap.thread_1.thread.messages[0].content, 0);
574
+ expect(toolContent.input).toEqual({ city: "NYC" });
575
+ });
576
+ it("throws when tool arguments JSON is invalid", () => {
577
+ const state = createTestStreamState("thread_1");
578
+ state.threadMap.thread_1.thread.messages = [
579
+ {
580
+ id: "msg_1",
581
+ role: "assistant",
582
+ content: [
583
+ { type: "tool_use", id: "tool_1", name: "test", input: {} },
584
+ ],
585
+ createdAt: "2024-01-01T00:00:00.000Z",
586
+ },
587
+ ];
588
+ // Send invalid JSON via TOOL_CALL_ARGS
589
+ const argsEvent = {
590
+ type: EventType.TOOL_CALL_ARGS,
591
+ toolCallId: "tool_1",
592
+ delta: "{invalid json",
593
+ };
594
+ const result = streamReducer(state, {
595
+ type: "EVENT",
596
+ event: argsEvent,
597
+ threadId: "thread_1",
598
+ });
599
+ // Send TOOL_CALL_END - should throw when parsing
600
+ const endEvent = {
601
+ type: EventType.TOOL_CALL_END,
602
+ toolCallId: "tool_1",
603
+ };
604
+ expect(() => {
605
+ streamReducer(result, {
606
+ type: "EVENT",
607
+ event: endEvent,
608
+ threadId: "thread_1",
609
+ });
610
+ }).toThrow("Failed to parse tool call arguments");
611
+ });
612
+ });
613
+ describe("custom component events", () => {
614
+ it("handles tambo.component.start event", () => {
615
+ const state = createTestStreamState("thread_1");
616
+ state.threadMap.thread_1.thread.messages = [
617
+ {
618
+ id: "msg_1",
619
+ role: "assistant",
620
+ content: [],
621
+ createdAt: "2024-01-01T00:00:00.000Z",
622
+ },
623
+ ];
624
+ const event = {
625
+ type: EventType.CUSTOM,
626
+ name: "tambo.component.start",
627
+ value: {
628
+ messageId: "msg_1",
629
+ componentId: "comp_1",
630
+ componentName: "WeatherCard",
631
+ },
632
+ };
633
+ const result = streamReducer(state, {
634
+ type: "EVENT",
635
+ event,
636
+ threadId: "thread_1",
637
+ });
638
+ const content = result.threadMap.thread_1.thread.messages[0].content;
639
+ expect(content).toHaveLength(1);
640
+ expect(content[0]).toEqual({
641
+ type: "component",
642
+ id: "comp_1",
643
+ name: "WeatherCard",
644
+ props: {},
645
+ });
646
+ });
647
+ it("handles tambo.component.props_delta event", () => {
648
+ const state = createTestStreamState("thread_1");
649
+ state.threadMap.thread_1.thread.messages = [
650
+ {
651
+ id: "msg_1",
652
+ role: "assistant",
653
+ content: [
654
+ { type: "component", id: "comp_1", name: "Test", props: {} },
655
+ ],
656
+ createdAt: "2024-01-01T00:00:00.000Z",
657
+ },
658
+ ];
659
+ const event = {
660
+ type: EventType.CUSTOM,
661
+ name: "tambo.component.props_delta",
662
+ value: {
663
+ componentId: "comp_1",
664
+ operations: [{ op: "add", path: "/temperature", value: 72 }],
665
+ },
666
+ };
667
+ const result = streamReducer(state, {
668
+ type: "EVENT",
669
+ event,
670
+ threadId: "thread_1",
671
+ });
672
+ const component = asComponentContent(result.threadMap.thread_1.thread.messages[0].content, 0);
673
+ expect(component.props).toEqual({ temperature: 72 });
674
+ });
675
+ it("throws when component not found for props_delta", () => {
676
+ const state = createTestStreamState("thread_1");
677
+ state.threadMap.thread_1.thread.messages = [
678
+ {
679
+ id: "msg_1",
680
+ role: "assistant",
681
+ content: [], // No component
682
+ createdAt: "2024-01-01T00:00:00.000Z",
683
+ },
684
+ ];
685
+ const event = {
686
+ type: EventType.CUSTOM,
687
+ name: "tambo.component.props_delta",
688
+ value: {
689
+ componentId: "unknown_comp",
690
+ operations: [{ op: "add", path: "/value", value: 1 }],
691
+ },
692
+ };
693
+ expect(() => {
694
+ streamReducer(state, {
695
+ type: "EVENT",
696
+ event,
697
+ threadId: "thread_1",
698
+ });
699
+ }).toThrow("component unknown_comp not found");
700
+ });
701
+ it("handles tambo.run.awaiting_input event", () => {
702
+ const state = createTestStreamState("thread_1");
703
+ state.threadMap.thread_1.thread.status = "streaming";
704
+ const event = {
705
+ type: EventType.CUSTOM,
706
+ name: "tambo.run.awaiting_input",
707
+ value: { pendingToolCallIds: ["tool_1", "tool_2"] },
708
+ };
709
+ const result = streamReducer(state, {
710
+ type: "EVENT",
711
+ event,
712
+ threadId: "thread_1",
713
+ });
714
+ expect(result.threadMap.thread_1.thread.status).toBe("waiting");
715
+ expect(result.threadMap.thread_1.streaming.status).toBe("waiting");
716
+ });
717
+ it("handles tambo.component.state_delta event", () => {
718
+ const state = createTestStreamState("thread_1");
719
+ state.threadMap.thread_1.thread.messages = [
720
+ {
721
+ id: "msg_1",
722
+ role: "assistant",
723
+ content: [
724
+ { type: "component", id: "comp_1", name: "Counter", props: {} },
725
+ ],
726
+ createdAt: "2024-01-01T00:00:00.000Z",
727
+ },
728
+ ];
729
+ const event = {
730
+ type: EventType.CUSTOM,
731
+ name: "tambo.component.state_delta",
732
+ value: {
733
+ componentId: "comp_1",
734
+ operations: [{ op: "add", path: "/count", value: 42 }],
735
+ },
736
+ };
737
+ const result = streamReducer(state, {
738
+ type: "EVENT",
739
+ event,
740
+ threadId: "thread_1",
741
+ });
742
+ const component = asComponentContent(result.threadMap.thread_1.thread.messages[0].content, 0);
743
+ expect(component.state).toEqual({ count: 42 });
744
+ });
745
+ it("handles tambo.component.end event", () => {
746
+ const state = createTestStreamState("thread_1");
747
+ state.threadMap.thread_1.thread.messages = [
748
+ {
749
+ id: "msg_1",
750
+ role: "assistant",
751
+ content: [
752
+ { type: "component", id: "comp_1", name: "Test", props: {} },
753
+ ],
754
+ createdAt: "2024-01-01T00:00:00.000Z",
755
+ },
756
+ ];
757
+ const event = {
758
+ type: EventType.CUSTOM,
759
+ name: "tambo.component.end",
760
+ value: { componentId: "comp_1" },
761
+ };
762
+ const result = streamReducer(state, {
763
+ type: "EVENT",
764
+ event,
765
+ threadId: "thread_1",
766
+ });
767
+ // component.end doesn't change state currently, just returns unchanged
768
+ expect(result.threadMap.thread_1.thread.messages[0].content[0]).toEqual({
769
+ type: "component",
770
+ id: "comp_1",
771
+ name: "Test",
772
+ props: {},
773
+ });
774
+ });
775
+ });
776
+ describe("snapshot tests for complex state transitions", () => {
777
+ it("matches snapshot for full message flow", () => {
778
+ let state = createTestStreamState("thread_1");
779
+ // RUN_STARTED
780
+ const runStarted = {
781
+ type: EventType.RUN_STARTED,
782
+ runId: "run_1",
783
+ threadId: "thread_1",
784
+ timestamp: 1704067200000,
785
+ };
786
+ state = streamReducer(state, {
787
+ type: "EVENT",
788
+ event: runStarted,
789
+ threadId: "thread_1",
790
+ });
791
+ // TEXT_MESSAGE_START
792
+ const msgStart = {
793
+ type: EventType.TEXT_MESSAGE_START,
794
+ messageId: "msg_1",
795
+ role: "assistant",
796
+ };
797
+ state = streamReducer(state, {
798
+ type: "EVENT",
799
+ event: msgStart,
800
+ threadId: "thread_1",
801
+ });
802
+ // TEXT_MESSAGE_CONTENT
803
+ const msgContent = {
804
+ type: EventType.TEXT_MESSAGE_CONTENT,
805
+ messageId: "msg_1",
806
+ delta: "Hello, how can I help?",
807
+ };
808
+ state = streamReducer(state, {
809
+ type: "EVENT",
810
+ event: msgContent,
811
+ threadId: "thread_1",
812
+ });
813
+ // TEXT_MESSAGE_END
814
+ const msgEnd = {
815
+ type: EventType.TEXT_MESSAGE_END,
816
+ messageId: "msg_1",
817
+ };
818
+ state = streamReducer(state, {
819
+ type: "EVENT",
820
+ event: msgEnd,
821
+ threadId: "thread_1",
822
+ });
823
+ // RUN_FINISHED
824
+ const runFinished = {
825
+ type: EventType.RUN_FINISHED,
826
+ runId: "run_1",
827
+ threadId: "thread_1",
828
+ };
829
+ state = streamReducer(state, {
830
+ type: "EVENT",
831
+ event: runFinished,
832
+ threadId: "thread_1",
833
+ });
834
+ // Normalize timestamps for snapshot stability
835
+ const snapshot = {
836
+ ...state,
837
+ threadMap: {
838
+ thread_1: {
839
+ ...state.threadMap.thread_1,
840
+ thread: {
841
+ ...state.threadMap.thread_1.thread,
842
+ messages: state.threadMap.thread_1.thread.messages.map((m) => ({
843
+ ...m,
844
+ createdAt: "[TIMESTAMP]",
845
+ })),
846
+ createdAt: "[TIMESTAMP]",
847
+ updatedAt: "[TIMESTAMP]",
848
+ },
849
+ },
850
+ },
851
+ };
852
+ expect(snapshot).toMatchSnapshot();
853
+ });
854
+ it("matches snapshot for component streaming flow", () => {
855
+ let state = createTestStreamState("thread_1");
856
+ // Add a message
857
+ state.threadMap.thread_1.thread.messages = [
858
+ {
859
+ id: "msg_1",
860
+ role: "assistant",
861
+ content: [],
862
+ createdAt: "2024-01-01T00:00:00.000Z",
863
+ },
864
+ ];
865
+ // COMPONENT_START
866
+ const compStart = {
867
+ type: EventType.CUSTOM,
868
+ name: "tambo.component.start",
869
+ value: {
870
+ messageId: "msg_1",
871
+ componentId: "comp_1",
872
+ componentName: "WeatherCard",
873
+ },
874
+ };
875
+ state = streamReducer(state, {
876
+ type: "EVENT",
877
+ event: compStart,
878
+ threadId: "thread_1",
879
+ });
880
+ // COMPONENT_PROPS_DELTA - add city
881
+ const propsDelta1 = {
882
+ type: EventType.CUSTOM,
883
+ name: "tambo.component.props_delta",
884
+ value: {
885
+ componentId: "comp_1",
886
+ operations: [{ op: "add", path: "/city", value: "New York" }],
887
+ },
888
+ };
889
+ state = streamReducer(state, {
890
+ type: "EVENT",
891
+ event: propsDelta1,
892
+ threadId: "thread_1",
893
+ });
894
+ // COMPONENT_PROPS_DELTA - add temperature
895
+ const propsDelta2 = {
896
+ type: EventType.CUSTOM,
897
+ name: "tambo.component.props_delta",
898
+ value: {
899
+ componentId: "comp_1",
900
+ operations: [{ op: "add", path: "/temperature", value: 72 }],
901
+ },
902
+ };
903
+ state = streamReducer(state, {
904
+ type: "EVENT",
905
+ event: propsDelta2,
906
+ threadId: "thread_1",
907
+ });
908
+ // COMPONENT_END
909
+ const compEnd = {
910
+ type: EventType.CUSTOM,
911
+ name: "tambo.component.end",
912
+ value: { componentId: "comp_1" },
913
+ };
914
+ state = streamReducer(state, {
915
+ type: "EVENT",
916
+ event: compEnd,
917
+ threadId: "thread_1",
918
+ });
919
+ // Normalize timestamps for snapshot stability
920
+ const snapshot = {
921
+ ...state,
922
+ threadMap: {
923
+ thread_1: {
924
+ ...state.threadMap.thread_1,
925
+ thread: {
926
+ ...state.threadMap.thread_1.thread,
927
+ messages: state.threadMap.thread_1.thread.messages.map((m) => ({
928
+ ...m,
929
+ createdAt: "[TIMESTAMP]",
930
+ })),
931
+ createdAt: "[TIMESTAMP]",
932
+ updatedAt: "[TIMESTAMP]",
933
+ },
934
+ },
935
+ },
936
+ };
937
+ expect(snapshot).toMatchSnapshot();
938
+ });
939
+ it("matches snapshot for tool call flow", () => {
940
+ let state = createTestStreamState("thread_1");
941
+ // Add a message with tool_use
942
+ state.threadMap.thread_1.thread.messages = [
943
+ {
944
+ id: "msg_1",
945
+ role: "assistant",
946
+ content: [
947
+ { type: "tool_use", id: "tool_1", name: "get_weather", input: {} },
948
+ ],
949
+ createdAt: "2024-01-01T00:00:00.000Z",
950
+ },
951
+ ];
952
+ // TOOL_CALL_ARGS
953
+ const toolArgs = {
954
+ type: EventType.TOOL_CALL_ARGS,
955
+ toolCallId: "tool_1",
956
+ delta: '{"city":"San Francisco","units":"fahrenheit"}',
957
+ };
958
+ state = streamReducer(state, {
959
+ type: "EVENT",
960
+ event: toolArgs,
961
+ threadId: "thread_1",
962
+ });
963
+ // TOOL_CALL_END
964
+ const toolEnd = {
965
+ type: EventType.TOOL_CALL_END,
966
+ toolCallId: "tool_1",
967
+ };
968
+ state = streamReducer(state, {
969
+ type: "EVENT",
970
+ event: toolEnd,
971
+ threadId: "thread_1",
972
+ });
973
+ // TOOL_CALL_RESULT
974
+ const toolResult = {
975
+ type: EventType.TOOL_CALL_RESULT,
976
+ toolCallId: "tool_1",
977
+ messageId: "msg_1",
978
+ content: "Temperature: 65°F, Sunny",
979
+ role: "tool",
980
+ };
981
+ state = streamReducer(state, {
982
+ type: "EVENT",
983
+ event: toolResult,
984
+ threadId: "thread_1",
985
+ });
986
+ // Normalize timestamps for snapshot stability
987
+ const snapshot = {
988
+ ...state,
989
+ threadMap: {
990
+ thread_1: {
991
+ ...state.threadMap.thread_1,
992
+ thread: {
993
+ ...state.threadMap.thread_1.thread,
994
+ messages: state.threadMap.thread_1.thread.messages.map((m) => ({
995
+ ...m,
996
+ createdAt: "[TIMESTAMP]",
997
+ })),
998
+ createdAt: "[TIMESTAMP]",
999
+ updatedAt: "[TIMESTAMP]",
1000
+ },
1001
+ },
1002
+ },
1003
+ };
1004
+ expect(snapshot).toMatchSnapshot();
1005
+ });
1006
+ });
1007
+ });
1008
+ //# sourceMappingURL=event-accumulator.test.js.map