@kitn.ai/ui 0.20.1 → 0.22.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 (510) hide show
  1. package/README.md +44 -45
  2. package/dist/components/artifact-card.d.ts +51 -0
  3. package/dist/components/artifact.d.ts +1 -1
  4. package/dist/components/attachments.d.ts +2 -2
  5. package/dist/components/audio-visualizer/index.d.ts +3 -3
  6. package/dist/components/audio-visualizer/labs/lab-choreography.d.ts +59 -0
  7. package/dist/components/audio-visualizer/labs/lab-shaders.d.ts +22 -0
  8. package/dist/components/audio-visualizer/labs/lab-visualizer.d.ts +18 -0
  9. package/dist/components/audio-visualizer/variant-aurora.d.ts +2 -2
  10. package/dist/components/audio-visualizer/variant-bar.d.ts +2 -2
  11. package/dist/components/audio-visualizer/variant-custom.d.ts +2 -2
  12. package/dist/components/audio-visualizer/variant-grid.d.ts +1 -1
  13. package/dist/components/audio-visualizer/variant-radial.d.ts +1 -1
  14. package/dist/components/audio-visualizer/variant-wave.d.ts +1 -1
  15. package/dist/components/card-fallback.d.ts +12 -2
  16. package/dist/components/card-renderer.d.ts +63 -2
  17. package/dist/components/chat-container.d.ts +3 -0
  18. package/dist/components/chat-scope-picker.d.ts +2 -2
  19. package/dist/components/chat-thread.d.ts +77 -18
  20. package/dist/components/choice-card.d.ts +3 -28
  21. package/dist/components/composer-dom.d.ts +1 -1
  22. package/dist/components/composer-highlight.d.ts +1 -1
  23. package/dist/components/composer-history.d.ts +1 -1
  24. package/dist/components/composer.d.ts +1 -1
  25. package/dist/components/confirm-card.d.ts +3 -18
  26. package/dist/components/context.d.ts +8 -4
  27. package/dist/components/conversation-item.d.ts +1 -1
  28. package/dist/components/conversation-list.d.ts +4 -3
  29. package/dist/components/embed.d.ts +3 -3
  30. package/dist/components/file-tree.d.ts +11 -22
  31. package/dist/components/form-widgets.d.ts +1 -1
  32. package/dist/components/form.d.ts +3 -44
  33. package/dist/components/link-preview.d.ts +3 -3
  34. package/dist/components/loader.d.ts +30 -48
  35. package/dist/components/message-skills.d.ts +4 -0
  36. package/dist/components/message.d.ts +84 -21
  37. package/dist/components/model-switcher.d.ts +2 -2
  38. package/dist/components/prompt-input.d.ts +2 -2
  39. package/dist/components/response-compare-types.d.ts +11 -2
  40. package/dist/components/response-compare.d.ts +3 -3
  41. package/dist/components/source.d.ts +12 -3
  42. package/dist/components/tasks-card.d.ts +3 -31
  43. package/dist/components/thread.d.ts +17 -5
  44. package/dist/components/toast.d.ts +2 -2
  45. package/dist/components/tool-classify.d.ts +8 -0
  46. package/dist/components/tool-types.d.ts +29 -1
  47. package/dist/components/tool.d.ts +3 -3
  48. package/dist/components/use-card-resolution.d.ts +1 -1
  49. package/dist/create-tween-COnPwAQN.js +338 -0
  50. package/dist/create-tween-DmTUaXWE.js +341 -0
  51. package/dist/create-tween-qs-jjvNA.js +7 -0
  52. package/dist/custom-elements.json +1726 -463
  53. package/dist/elements/agent-card.js +1 -1
  54. package/dist/elements/artifact.js +1 -1
  55. package/dist/elements/attachments.js +1 -1
  56. package/dist/elements/audio-visualizer.js +1 -1
  57. package/dist/elements/avatar.js +1 -1
  58. package/dist/elements/badge.js +1 -1
  59. package/dist/elements/button.js +1 -1
  60. package/dist/elements/card.js +1 -1
  61. package/dist/elements/cards.js +1 -1
  62. package/dist/elements/chain-of-thought.js +1 -1
  63. package/dist/elements/chat-scope-picker.js +1 -1
  64. package/dist/elements/chat-types.d.ts +70 -10
  65. package/dist/elements/chat-workspace.js +1 -1
  66. package/dist/elements/chat.js +1 -1
  67. package/dist/elements/checkpoint.js +1 -1
  68. package/dist/elements/choice.js +1 -1
  69. package/dist/elements/chunks/{Icon-Tj58ES_d.js → Icon-CHG5z5L7.js} +1 -1
  70. package/dist/elements/chunks/{action-icons-ns1Fnedj.js → action-icons-BAtCEEgg.js} +1 -1
  71. package/dist/elements/chunks/arrow-left-CFPTeL1Y.js +1 -0
  72. package/dist/elements/chunks/artifact-fBZOE4SO.js +1 -0
  73. package/dist/elements/chunks/{attachments-mCB5F1Fq.js → attachments-DpYMe5VQ.js} +1 -1
  74. package/dist/elements/chunks/audio-visualizer-DFwzAcuL.js +1 -0
  75. package/dist/elements/chunks/{badge-B4Zuajl2.js → badge-D6zodm6E.js} +1 -1
  76. package/dist/elements/chunks/{button-ZWNif3--.js → button-C42vrGvO.js} +1 -1
  77. package/dist/elements/chunks/card-renderer-DMZsSuvU.js +1 -0
  78. package/dist/elements/chunks/card-tags-D8lZ-C_U.js +1 -0
  79. package/dist/elements/chunks/chat-thread-CNNEhol-.js +1 -0
  80. package/dist/elements/chunks/check-7Q3K-iXE.js +1 -0
  81. package/dist/elements/chunks/chevron-down-CpNYLn7E.js +1 -0
  82. package/dist/elements/chunks/chevron-right-DrH85Fha.js +1 -0
  83. package/dist/elements/chunks/choice-card-YoWjpsFV.js +1 -0
  84. package/dist/elements/chunks/circle-C9KRjKYv.js +1 -0
  85. package/dist/elements/chunks/circle-check-Dmi7Y4zw.js +1 -0
  86. package/dist/elements/chunks/{circle-x-B7faJFlY.js → circle-x-QIxXda6k.js} +1 -1
  87. package/dist/elements/chunks/code-block-CqeugReY.js +1 -0
  88. package/dist/elements/chunks/{collapsible-DM1Ckd4e.js → collapsible-sTv-_5lF.js} +1 -1
  89. package/dist/elements/chunks/{composer-BguS0QL_.js → composer-ldQyeVEB.js} +2 -2
  90. package/dist/elements/chunks/confirm-card-C0RNOwfn.js +1 -0
  91. package/dist/elements/chunks/context-5qgypNHC.js +1 -0
  92. package/dist/elements/chunks/conversation-list-DLzOacXz.js +1 -0
  93. package/dist/elements/chunks/create-tween-V4TXZ93X.js +7 -0
  94. package/dist/elements/chunks/default-input-DeeRSDHc.js +1 -0
  95. package/dist/elements/chunks/define-lE-QvQFn.js +1 -0
  96. package/dist/elements/chunks/{disclosure-CIZ5c8nO.js → disclosure-DZSa9jog.js} +1 -1
  97. package/dist/elements/chunks/{download-Dsbg3ste.js → download-B2ZmnGqW.js} +1 -1
  98. package/dist/elements/chunks/{dropdown-BDd1-Zgi.js → dropdown-R3B7cSRE.js} +1 -1
  99. package/dist/elements/chunks/{ellipsis-Dw6qrss-.js → ellipsis-BmxceY4l.js} +1 -1
  100. package/dist/elements/chunks/embed-BVrtTZPo.js +1 -0
  101. package/dist/elements/chunks/{external-link-Vt74zAoL.js → external-link-BbdR7YO7.js} +1 -1
  102. package/dist/elements/chunks/{file-text-CZrZF6_v.js → file-text-D7dijo1A.js} +1 -1
  103. package/dist/elements/chunks/{file-tree-DF4okKyo.js → file-tree-0upJ5jeb.js} +1 -1
  104. package/dist/elements/chunks/{folder-glP5rha4.js → folder-D8z58t7B.js} +1 -1
  105. package/dist/elements/chunks/form-p5BKJNw5.js +1 -0
  106. package/dist/elements/chunks/hover-card-CN9s2md5.js +1 -0
  107. package/dist/elements/chunks/{icon-BLb8beoi.js → icon-CNiKP37E.js} +1 -1
  108. package/dist/elements/chunks/{info-CIsv92JK.js → info-BSnuJiHI.js} +1 -1
  109. package/dist/elements/chunks/{input-Dds1kFyt.js → input-BauDmzxX.js} +1 -1
  110. package/dist/elements/chunks/{kbd-De_xbgi9.js → kbd-BlHJaP9b.js} +1 -1
  111. package/dist/elements/chunks/{link-i4r_k7z4.js → link-DEi5iUWC.js} +1 -1
  112. package/dist/elements/chunks/link-preview-BaHyM6W4.js +1 -0
  113. package/dist/elements/chunks/{loader-BmQH4s3V.js → loader-CmJG_Fkq.js} +1 -1
  114. package/dist/elements/chunks/{markdown-Zi21WhUz.js → markdown-D2jaMpCN.js} +1 -1
  115. package/dist/elements/chunks/message-C5UfXZ2Z.js +1 -0
  116. package/dist/elements/chunks/message-CXWLmmLn.js +1 -0
  117. package/dist/elements/chunks/message-square-hXylwsy0.js +1 -0
  118. package/dist/elements/chunks/{minimize-2--ifeCGrl.js → minimize-2-C9ytZFMU.js} +1 -1
  119. package/dist/elements/chunks/model-switcher-CivGfD7-.js +1 -0
  120. package/dist/elements/chunks/{overlay-kD8dwRv_.js → overlay-DJL_sbOm.js} +1 -1
  121. package/dist/elements/chunks/{paperclip-q21dYOSK.js → paperclip-CFaB8naM.js} +1 -1
  122. package/dist/elements/chunks/{progress-bar-BrAIIaaJ.js → progress-bar-Br5SksfR.js} +1 -1
  123. package/dist/elements/chunks/{prompt-suggestion-Bjn2K-fR.js → prompt-suggestion-CMIvtAhU.js} +1 -1
  124. package/dist/elements/chunks/reasoning-DpZcNzLq.js +1 -0
  125. package/dist/elements/chunks/{resizable-Dp4JExql.js → resizable-Q8i3T9a_.js} +1 -1
  126. package/dist/elements/chunks/{rotate-cw-CFWWkpj2.js → rotate-cw-B5IHCBFV.js} +1 -1
  127. package/dist/elements/chunks/{scroll-area-Bb0kHH1j.js → scroll-area-eLeydBje.js} +1 -1
  128. package/dist/elements/chunks/scroll-button-DWbz0yA1.js +1 -0
  129. package/dist/elements/chunks/{separator-9kRgr1X9.js → separator-Xic78AD_.js} +1 -1
  130. package/dist/elements/chunks/{settings-B8lmec4D.js → settings-B8H51pAx.js} +1 -1
  131. package/dist/elements/chunks/{settings-group-I0hEuXiN.js → settings-group-CsG9eYLe.js} +1 -1
  132. package/dist/elements/chunks/{share-C3lTiYGt.js → share-CNTx0z__.js} +1 -1
  133. package/dist/elements/chunks/skeleton-CLlHTcMI.js +1 -0
  134. package/dist/elements/chunks/slots-CIw9RlAe.js +1 -0
  135. package/dist/elements/chunks/source-BoVcU5ok.js +1 -0
  136. package/dist/elements/chunks/{star-CSJtGxgv.js → star-CxQVTVhI.js} +1 -1
  137. package/dist/elements/chunks/{store-CHyW95TP.js → store-CLtS5CUG.js} +1 -1
  138. package/dist/elements/chunks/tasks-card-CzlkLmUt.js +1 -0
  139. package/dist/elements/chunks/{text-shimmer-Cn9TmNpI.js → text-shimmer-D5NhpIQ1.js} +1 -1
  140. package/dist/elements/chunks/textarea-x5Uxsmtm.js +1 -0
  141. package/dist/elements/chunks/{thumbs-up-PNVVThEF.js → thumbs-up-UobcJnx9.js} +1 -1
  142. package/dist/elements/chunks/{toast-store-DKbQn3Wn.js → toast-store-BOfs9eXq.js} +1 -1
  143. package/dist/elements/chunks/{tool-DjTRpIpl.js → tool-Be6Dh_dt.js} +1 -1
  144. package/dist/elements/chunks/tooltip-RxMxyCLF.js +1 -0
  145. package/dist/elements/chunks/{triangle-alert-DsHTHCPm.js → triangle-alert-C4yxH2XN.js} +1 -1
  146. package/dist/elements/chunks/use-card-resolution-jva9ehH6.js +1 -0
  147. package/dist/elements/chunks/{variant-aurora-Dc4nQUia.js → variant-aurora-Dx4VRcjS.js} +2 -2
  148. package/dist/elements/chunks/{variant-custom-y_3kVQhS.js → variant-custom-Y1ZTWgEa.js} +1 -1
  149. package/dist/elements/chunks/{variant-wave-D5OR1-9Z.js → variant-wave-B9gml9Cg.js} +2 -2
  150. package/dist/elements/chunks/{video-B7vmenoC.js → video-CrPHsytT.js} +1 -1
  151. package/dist/elements/chunks/x-_-OPHept.js +1 -0
  152. package/dist/elements/coachmark.js +1 -1
  153. package/dist/elements/code-block.js +1 -1
  154. package/dist/elements/command.js +1 -1
  155. package/dist/elements/compare.js +1 -1
  156. package/dist/elements/composer.js +1 -1
  157. package/dist/elements/confirm-card.js +1 -1
  158. package/dist/elements/context-meter.js +1 -1
  159. package/dist/elements/conversation-list.js +1 -1
  160. package/dist/elements/default-input.d.ts +34 -7
  161. package/dist/elements/define.d.ts +1 -0
  162. package/dist/elements/dialog.js +1 -1
  163. package/dist/elements/disclosure.d.ts +1 -1
  164. package/dist/elements/editable-label.js +1 -1
  165. package/dist/elements/element-data-types.d.ts +107 -0
  166. package/dist/elements/embed.js +1 -1
  167. package/dist/elements/empty.js +1 -1
  168. package/dist/elements/feedback-bar.js +1 -1
  169. package/dist/elements/file-tree.js +1 -1
  170. package/dist/elements/file-upload.js +1 -1
  171. package/dist/elements/form.js +1 -1
  172. package/dist/elements/hover-card.js +1 -1
  173. package/dist/elements/icon.js +1 -1
  174. package/dist/elements/image.js +1 -1
  175. package/dist/elements/input.js +1 -1
  176. package/dist/elements/kbd.js +1 -1
  177. package/dist/elements/link-preview.js +1 -1
  178. package/dist/elements/loader.js +1 -1
  179. package/dist/elements/markdown.js +1 -1
  180. package/dist/elements/menu.js +1 -1
  181. package/dist/elements/message-skills.js +1 -1
  182. package/dist/elements/message.js +1 -1
  183. package/dist/elements/model-switcher.js +1 -1
  184. package/dist/elements/nav.js +1 -1
  185. package/dist/elements/notice.js +1 -1
  186. package/dist/elements/pane-group.js +1 -1
  187. package/dist/elements/pane.js +1 -1
  188. package/dist/elements/popover.js +1 -1
  189. package/dist/elements/progress-bar.js +1 -1
  190. package/dist/elements/prompt-dock.js +1 -1
  191. package/dist/elements/prompt-input.js +1 -1
  192. package/dist/elements/prompt-suggestions.js +1 -1
  193. package/dist/elements/reasoning.js +1 -1
  194. package/dist/elements/register.d.ts +8 -6
  195. package/dist/elements/remote.js +1 -1
  196. package/dist/elements/resizable.js +1 -1
  197. package/dist/elements/response-stream.js +1 -1
  198. package/dist/elements/screen.js +1 -1
  199. package/dist/elements/scroll-area.js +1 -1
  200. package/dist/elements/scroll-button.js +1 -1
  201. package/dist/elements/search.js +1 -1
  202. package/dist/elements/segmented.js +1 -1
  203. package/dist/elements/separator.js +1 -1
  204. package/dist/elements/setting-item.js +1 -1
  205. package/dist/elements/settings-group.js +1 -1
  206. package/dist/elements/skeleton.js +1 -1
  207. package/dist/elements/slot-text.d.ts +51 -0
  208. package/dist/elements/slots.d.ts +21 -0
  209. package/dist/elements/source.js +1 -1
  210. package/dist/elements/status.js +1 -1
  211. package/dist/elements/switch.js +1 -1
  212. package/dist/elements/tabs.js +1 -1
  213. package/dist/elements/tasks.js +1 -1
  214. package/dist/elements/text-shimmer.js +1 -1
  215. package/dist/elements/thinking-bar.js +1 -1
  216. package/dist/elements/thread.js +1 -1
  217. package/dist/elements/toast.js +1 -1
  218. package/dist/elements/tool.js +1 -1
  219. package/dist/elements/tooltip.js +1 -1
  220. package/dist/elements/validate-messages.d.ts +25 -0
  221. package/dist/elements/voice-input.js +1 -1
  222. package/dist/elements/voice-output.js +1 -1
  223. package/dist/elements.d.ts +2734 -217
  224. package/dist/index.d.ts +163 -125
  225. package/dist/index.js +6572 -5990
  226. package/dist/index.server.d.ts +5 -0
  227. package/dist/index.server.js +5403 -4860
  228. package/dist/kai-provider.es.d.ts +5 -0
  229. package/dist/kai-provider.es.js +79 -77
  230. package/dist/kai.es.d.ts +5 -0
  231. package/dist/kai.es.js +1 -1
  232. package/dist/llms/llms-full.txt +774 -151
  233. package/dist/llms/llms.txt +57 -5
  234. package/dist/mcp.es.js +4756 -782
  235. package/dist/primitives/card-component-types.d.ts +11 -0
  236. package/dist/primitives/card-data-types.d.ts +196 -0
  237. package/dist/primitives/card-host.d.ts +1 -1
  238. package/dist/primitives/card-recovery.d.ts +3 -3
  239. package/dist/primitives/card-registry.d.ts +4 -14
  240. package/dist/primitives/card-resolution.d.ts +1 -1
  241. package/dist/primitives/card-routing.d.ts +1 -1
  242. package/dist/primitives/card-tags.d.ts +11 -0
  243. package/dist/primitives/card-validate-cards.d.ts +57 -0
  244. package/dist/primitives/card-validate-generator.testlib.d.ts +20 -0
  245. package/dist/primitives/card-validate-schemas.d.ts +17 -0
  246. package/dist/primitives/card-validate.d.ts +24 -0
  247. package/dist/primitives/create-kai-chat.d.ts +3 -3
  248. package/dist/primitives/embed-providers.d.ts +1 -1
  249. package/dist/primitives/link-preview.d.ts +1 -1
  250. package/dist/primitives/message-feedback.d.ts +2 -2
  251. package/dist/primitives/toast-store.d.ts +1 -1
  252. package/dist/react/index.d.ts +730 -302
  253. package/dist/react/use-kai-chat.d.ts +8 -4
  254. package/dist/react.d.ts +5 -0
  255. package/dist/react.js +418 -317
  256. package/dist/register-impl-AxIlqjo7.js +145 -0
  257. package/dist/remote/host-embed.d.ts +1 -1
  258. package/dist/remote/index.d.ts +2 -2
  259. package/dist/remote/provider-runtime.d.ts +2 -2
  260. package/dist/remote/provider.d.ts +2 -2
  261. package/dist/remote/validate.d.ts +1 -1
  262. package/dist/remote/wire.d.ts +1 -1
  263. package/dist/schemas/artifact.schema.json +92 -0
  264. package/dist/schemas/embed.schema.json +0 -2
  265. package/dist/schemas/from-tool-call.d.ts +48 -0
  266. package/dist/schemas/index.d.ts +48 -0
  267. package/dist/schemas/link.schema.json +0 -2
  268. package/dist/schemas/provider-subsets.d.ts +136 -0
  269. package/dist/schemas/registry.d.ts +140 -0
  270. package/dist/schemas/tool-defs.d.ts +121 -0
  271. package/dist/schemas.d.ts +5 -0
  272. package/dist/schemas.js +717 -0
  273. package/dist/solid-BGYSJyHG.js +22960 -0
  274. package/dist/solid-Dt2nEwfl.js +20194 -0
  275. package/dist/solid.d.ts +66 -0
  276. package/dist/solid.js +261 -0
  277. package/dist/solid.server.d.ts +5 -0
  278. package/dist/solid.server.js +261 -0
  279. package/dist/state/index.d.ts +14 -4
  280. package/dist/state/messages.d.ts +8 -3
  281. package/dist/state/mock.d.ts +46 -0
  282. package/dist/state/parts.d.ts +85 -0
  283. package/dist/state/stream.d.ts +15 -9
  284. package/dist/state.d.ts +5 -0
  285. package/dist/state.js +253 -84
  286. package/dist/ui/action-icons.d.ts +1 -1
  287. package/dist/ui/collapsible.d.ts +11 -6
  288. package/dist/ui/dropdown.d.ts +47 -42
  289. package/dist/ui/pane-group.d.ts +1 -1
  290. package/dist/{variant-aurora-DVtGqVH6.js → variant-aurora-B44X69AG.js} +1 -1
  291. package/dist/variant-aurora-BRhV8Flk.js +391 -0
  292. package/dist/variant-aurora-Ds5ou9BH.js +381 -0
  293. package/dist/variant-custom-B20FhtYj.js +170 -0
  294. package/dist/{variant-custom-Dif-IV4u.js → variant-custom-BvA1Schl.js} +1 -1
  295. package/dist/variant-custom-D6Rtvneb.js +200 -0
  296. package/dist/{variant-wave-DbfNdvSi.js → variant-wave-BUQtkryq.js} +1 -1
  297. package/dist/variant-wave-BVYnqy9L.js +218 -0
  298. package/dist/variant-wave-DXC6_LcH.js +208 -0
  299. package/dist/wire/chunk.d.ts +171 -0
  300. package/dist/wire/consume.d.ts +26 -0
  301. package/dist/wire/encode.d.ts +221 -0
  302. package/dist/wire/files.d.ts +116 -0
  303. package/dist/wire/formats/anthropic.d.ts +2 -0
  304. package/dist/wire/formats/openai.d.ts +5 -0
  305. package/dist/wire/index.d.ts +16 -0
  306. package/dist/wire/media-types.d.ts +106 -0
  307. package/dist/wire/read.d.ts +26 -0
  308. package/dist/wire/sink-helpers.d.ts +21 -0
  309. package/dist/wire/sse.d.ts +33 -0
  310. package/dist/wire.d.ts +5 -53
  311. package/dist/wire.js +1126 -0
  312. package/frameworks/react/index.tsx +191 -158
  313. package/frameworks/react/runtime.tsx +21 -1
  314. package/frameworks/react/use-kai-chat.tsx +11 -1
  315. package/llms-full.txt +774 -151
  316. package/llms.txt +57 -5
  317. package/package.json +62 -8
  318. package/src/agent-tooling/archetypes.ts +127 -0
  319. package/src/agent-tooling/integrations/anthropic.ts +436 -0
  320. package/src/agent-tooling/integrations/cloudflare.ts +141 -52
  321. package/src/agent-tooling/integrations/langgraph.ts +80 -13
  322. package/src/agent-tooling/integrations/mastra.ts +161 -12
  323. package/src/agent-tooling/integrations/mock.ts +47 -8
  324. package/src/agent-tooling/integrations/ollama.ts +68 -24
  325. package/src/agent-tooling/integrations/openai.ts +89 -0
  326. package/src/agent-tooling/integrations/openrouter.ts +58 -8
  327. package/src/agent-tooling/integrations/pi.ts +104 -23
  328. package/src/agent-tooling/integrations/pydantic-ai.ts +61 -5
  329. package/src/agent-tooling/integrations/vercel-ai-sdk.ts +120 -13
  330. package/src/agent-tooling/mcp/manifest.ts +206 -25
  331. package/src/agent-tooling/mcp/tools/debug.ts +13 -7
  332. package/src/agent-tooling/mcp/tools/reference.ts +285 -6
  333. package/src/agent-tooling/mcp/tools/scaffold.ts +4152 -661
  334. package/src/agent-tooling/registry.ts +74 -0
  335. package/src/agent-tooling/types.ts +361 -1
  336. package/src/components/artifact-card.tsx +120 -0
  337. package/src/components/audio-visualizer/index.tsx +9 -0
  338. package/src/components/audio-visualizer/labs/lab-choreography.ts +187 -0
  339. package/src/components/audio-visualizer/labs/lab-shaders.ts +363 -0
  340. package/src/components/audio-visualizer/labs/lab-visualizer.tsx +102 -0
  341. package/src/components/audio-visualizer/shader-canvas.tsx +31 -1
  342. package/src/components/card-fallback.tsx +42 -10
  343. package/src/components/card-renderer.tsx +146 -9
  344. package/src/components/chat-container.tsx +4 -0
  345. package/src/components/chat-thread.tsx +128 -52
  346. package/src/components/choice-card.tsx +17 -29
  347. package/src/components/composer.tsx +12 -2
  348. package/src/components/confirm-card.tsx +24 -20
  349. package/src/components/context.tsx +30 -16
  350. package/src/components/conversation-item.tsx +6 -0
  351. package/src/components/conversation-list.tsx +18 -2
  352. package/src/components/file-tree.tsx +11 -22
  353. package/src/components/file-upload.tsx +14 -8
  354. package/src/components/form.tsx +14 -47
  355. package/src/components/loader.tsx +39 -12
  356. package/src/components/message-skills.tsx +4 -0
  357. package/src/components/message.tsx +294 -46
  358. package/src/components/model-switcher.tsx +38 -8
  359. package/src/components/reasoning.tsx +92 -5
  360. package/src/components/response-compare-types.ts +25 -0
  361. package/src/components/response-compare.tsx +4 -9
  362. package/src/components/source.tsx +50 -24
  363. package/src/components/tasks-card.tsx +10 -33
  364. package/src/components/thread.tsx +84 -42
  365. package/src/components/toast.tsx +17 -6
  366. package/src/components/tool-classify.ts +26 -0
  367. package/src/components/tool-types.ts +31 -1
  368. package/src/elements/agent-card.tsx +11 -11
  369. package/src/elements/artifact.tsx +15 -7
  370. package/src/elements/attachments.tsx +6 -4
  371. package/src/elements/avatar.tsx +1 -1
  372. package/src/elements/button.tsx +29 -6
  373. package/src/elements/card.tsx +2 -2
  374. package/src/elements/cards.tsx +109 -14
  375. package/src/elements/chain-of-thought.tsx +14 -10
  376. package/src/elements/chat-scope-picker.tsx +9 -7
  377. package/src/elements/chat-types.ts +59 -6
  378. package/src/elements/chat-workspace.tsx +50 -9
  379. package/src/elements/chat.tsx +90 -3
  380. package/src/elements/choice.tsx +8 -8
  381. package/src/elements/coachmark.tsx +1 -1
  382. package/src/elements/command.tsx +8 -23
  383. package/src/elements/compare.tsx +7 -6
  384. package/src/elements/compiled.css +1 -1
  385. package/src/elements/composer.tsx +8 -8
  386. package/src/elements/confirm-card.tsx +9 -9
  387. package/src/elements/context-meter.tsx +4 -18
  388. package/src/elements/conversation-list.tsx +14 -9
  389. package/src/elements/default-input.tsx +131 -8
  390. package/src/elements/define.tsx +178 -43
  391. package/src/elements/editable-label.tsx +17 -2
  392. package/src/elements/element-data-types.ts +112 -0
  393. package/src/elements/element-meta.json +1624 -306
  394. package/src/elements/element-types.d.ts +2645 -214
  395. package/src/elements/feedback-bar.tsx +1 -1
  396. package/src/elements/file-tree.tsx +1 -1
  397. package/src/elements/file-upload.tsx +1 -1
  398. package/src/elements/form.tsx +14 -6
  399. package/src/elements/input.tsx +1 -1
  400. package/src/elements/kbd.tsx +1 -1
  401. package/src/elements/menu.tsx +40 -32
  402. package/src/elements/message-skills.tsx +7 -9
  403. package/src/elements/message.tsx +200 -32
  404. package/src/elements/model-switcher.tsx +5 -3
  405. package/src/elements/pane.tsx +1 -1
  406. package/src/elements/prompt-dock.tsx +8 -8
  407. package/src/elements/prompt-input.tsx +10 -10
  408. package/src/elements/prompt-suggestions.tsx +7 -4
  409. package/src/elements/reasoning.tsx +1 -1
  410. package/src/elements/register.ts +9 -0
  411. package/src/elements/resizable.globals.d.ts +36 -0
  412. package/src/elements/resizable.tsx +24 -13
  413. package/src/elements/response-stream.tsx +1 -1
  414. package/src/elements/scroll-button.tsx +1 -1
  415. package/src/elements/search.tsx +6 -1
  416. package/src/elements/segmented.tsx +5 -11
  417. package/src/elements/separator.tsx +1 -1
  418. package/src/elements/slot-text.ts +73 -0
  419. package/src/elements/slots.ts +67 -24
  420. package/src/elements/source.tsx +21 -22
  421. package/src/elements/switch.tsx +3 -3
  422. package/src/elements/tasks.tsx +5 -4
  423. package/src/elements/thread.tsx +36 -4
  424. package/src/elements/toast.tsx +3 -2
  425. package/src/elements/tool.tsx +1 -1
  426. package/src/elements/validate-messages.ts +76 -0
  427. package/src/elements/voice-input.tsx +7 -7
  428. package/src/elements/voice-output.tsx +4 -4
  429. package/src/index.ts +145 -6
  430. package/src/primitives/card-component-types.ts +63 -0
  431. package/src/primitives/card-data-types.ts +312 -0
  432. package/src/primitives/card-recovery.ts +13 -2
  433. package/src/primitives/card-registry.tsx +34 -23
  434. package/src/primitives/card-schemas/artifact.schema.json +92 -0
  435. package/src/primitives/card-schemas/embed.schema.json +0 -2
  436. package/src/primitives/card-schemas/link.schema.json +0 -2
  437. package/src/primitives/card-tags.ts +61 -0
  438. package/src/primitives/card-validate-cards.ts +255 -0
  439. package/src/primitives/card-validate-generator.testlib.ts +38 -0
  440. package/src/primitives/card-validate-schemas.ts +58 -0
  441. package/src/primitives/card-validate.ts +48 -20
  442. package/src/primitives/create-tween.ts +54 -2
  443. package/src/primitives/message-feedback.ts +3 -2
  444. package/src/primitives/use-audio-analysis.ts +20 -1
  445. package/src/primitives/use-sequencer.ts +20 -1
  446. package/src/schemas/from-tool-call.ts +151 -0
  447. package/src/schemas/index.ts +340 -0
  448. package/src/schemas/provider-subsets.ts +538 -0
  449. package/src/schemas/registry.ts +355 -0
  450. package/src/schemas/tool-defs.ts +492 -0
  451. package/src/solid.ts +150 -0
  452. package/src/state/index.ts +27 -1
  453. package/src/state/messages.ts +21 -4
  454. package/src/state/mock.ts +211 -0
  455. package/src/state/parts.ts +295 -0
  456. package/src/state/stream.ts +56 -58
  457. package/src/ui/collapsible.tsx +17 -5
  458. package/src/ui/dropdown.tsx +46 -12
  459. package/src/ui/overlay.tsx +10 -4
  460. package/src/wire/chunk.ts +201 -0
  461. package/src/wire/consume.ts +440 -0
  462. package/src/wire/encode.ts +689 -0
  463. package/src/wire/files.ts +342 -0
  464. package/src/wire/formats/anthropic.ts +267 -0
  465. package/src/wire/formats/openai.ts +187 -0
  466. package/src/wire/index.ts +73 -0
  467. package/src/wire/media-types.ts +344 -0
  468. package/src/wire/read.ts +152 -0
  469. package/src/wire/sink-helpers.ts +50 -0
  470. package/src/wire/sse.ts +140 -0
  471. package/dist/create-tween-hvpmSuwW.js +0 -7
  472. package/dist/elements/chunks/arrow-left-DQocUFvy.js +0 -1
  473. package/dist/elements/chunks/audio-visualizer-BqNy7dfm.js +0 -1
  474. package/dist/elements/chunks/card-BkHbp4BA.js +0 -1
  475. package/dist/elements/chunks/chat-thread-CkRN6pZ7.js +0 -1
  476. package/dist/elements/chunks/check-B9-gn6SS.js +0 -1
  477. package/dist/elements/chunks/chevron-down-BNsxc2hk.js +0 -1
  478. package/dist/elements/chunks/chevron-right-Hv00StBO.js +0 -1
  479. package/dist/elements/chunks/circle-0e3KJTDr.js +0 -1
  480. package/dist/elements/chunks/circle-check-BNAS0JEy.js +0 -1
  481. package/dist/elements/chunks/code-block-BFUHn6Va.js +0 -1
  482. package/dist/elements/chunks/context-Cb7k4F-v.js +0 -1
  483. package/dist/elements/chunks/conversation-list-CvoAkWhN.js +0 -1
  484. package/dist/elements/chunks/create-tween-oVvAIG8r.js +0 -7
  485. package/dist/elements/chunks/default-input-Cqqilg9t.js +0 -1
  486. package/dist/elements/chunks/define-D1din7Ld.js +0 -1
  487. package/dist/elements/chunks/hover-card-Cmm6Q53m.js +0 -1
  488. package/dist/elements/chunks/message-BqyXDN3-.js +0 -1
  489. package/dist/elements/chunks/message-feedback-Djr3z6Yb.js +0 -1
  490. package/dist/elements/chunks/message-square-vFAgbDaX.js +0 -1
  491. package/dist/elements/chunks/model-switcher-B94YAKsM.js +0 -1
  492. package/dist/elements/chunks/reasoning-DTpCGtnY.js +0 -1
  493. package/dist/elements/chunks/scroll-button-B0cH5fXf.js +0 -1
  494. package/dist/elements/chunks/skeleton-DSXW5Yya.js +0 -1
  495. package/dist/elements/chunks/slots--V19HwUb.js +0 -1
  496. package/dist/elements/chunks/textarea-CUwqAX0G.js +0 -1
  497. package/dist/elements/chunks/tooltip-CgBZCVKp.js +0 -1
  498. package/dist/elements/chunks/use-card-resolution-BSu_XHjH.js +0 -1
  499. package/dist/elements/chunks/x-GRUeeQFT.js +0 -1
  500. package/dist/host-embed.d.ts +0 -33
  501. package/dist/kai-provider.d.ts +0 -2
  502. package/dist/origin.d.ts +0 -5
  503. package/dist/provider-runtime.d.ts +0 -27
  504. package/dist/register-impl-DQyejdfb.js +0 -145
  505. package/dist/validate.d.ts +0 -4
  506. package/dist/version.d.ts +0 -4
  507. package/src/components/component-meta.json +0 -4550
  508. package/src/elements/card-media.jpg +0 -0
  509. package/src/elements/resizable.d.ts +0 -27
  510. package/src/elements/video-poster.jpg +0 -0
@@ -0,0 +1,440 @@
1
+ // The adapter core: read neutral chunks, drive a sink, and report the turn.
2
+ //
3
+ // PORTABILITY RULES: no React, no Solid, no DOM, no fetch, no SSE, and NO
4
+ // PROVIDER SDK. The only kit values imported are the three part builders, which
5
+ // are REUSED rather than reimplemented so that `ModelTurn.parts` is produced by
6
+ // exactly the code that drove the sink.
7
+ import type { MessagePart, MessageSource } from '../elements/chat-types';
8
+ import { appendReasoningPart, appendTextPart, fingerprint, upsertToolPart } from '../state/parts';
9
+ import {
10
+ normalizeStopReason,
11
+ type AssistantStreamSink,
12
+ type ConsumeOptions,
13
+ type ModelStreamChunk,
14
+ type ModelToolCall,
15
+ type ModelToolCallDelta,
16
+ type ModelTurn,
17
+ type ModelUsage,
18
+ type StopReason,
19
+ } from './chunk';
20
+ import type { RawOrigin } from '../components/tool-types';
21
+
22
+ // ── Tool-call accumulator ────────────────────────────────────────────────────
23
+
24
+ interface MutableCall {
25
+ index: number;
26
+ id: string | null;
27
+ name: string;
28
+ argumentsText: string;
29
+ announced: boolean;
30
+ /** Fingerprint of the last `input` written, so a re-parse of unchanged text
31
+ * does not patch the part again. */
32
+ lastInputFp: string | null;
33
+ providerExecuted: boolean;
34
+ output?: Record<string, unknown>;
35
+ outputError?: string;
36
+ }
37
+
38
+ const snapshot = (c: MutableCall): ModelToolCall => ({
39
+ index: c.index,
40
+ id: c.id ?? `call_${c.index}`,
41
+ name: c.name,
42
+ argumentsText: c.argumentsText,
43
+ });
44
+
45
+ /**
46
+ * The provider-shaped tool-call block, REASSEMBLED from the fragments, kept on
47
+ * the part so an encoder can round-trip without re-deriving it.
48
+ *
49
+ * Tagged `custom.` on purpose: it is a reconstruction, not a payload the
50
+ * provider handed over intact, so it must never be mistaken for one of the
51
+ * verbatim blocks (Anthropic `thinking`) a provider refuses to accept rebuilt.
52
+ */
53
+ const rawOf = (c: MutableCall): RawOrigin => ({
54
+ source: 'custom.wire.tool_call',
55
+ payload: { id: c.id ?? `call_${c.index}`, name: c.name, arguments: c.argumentsText },
56
+ });
57
+
58
+ function clip(s: string, n: number): string {
59
+ return s.length <= n ? s : `${s.slice(0, n)}...`;
60
+ }
61
+
62
+ /** Parse accumulated argument text into a JSON OBJECT, or undefined. A prefix of
63
+ * a JSON object never parses, which is why `rawInput` exists. No tolerant
64
+ * partial-JSON closer ships: guessing at a half-written object produces
65
+ * confidently wrong tool inputs. */
66
+ function parseArgumentObject(text: string): Record<string, unknown> | undefined {
67
+ const trimmed = text.trim();
68
+ if (trimmed === '') return undefined;
69
+ try {
70
+ const value: unknown = JSON.parse(trimmed);
71
+ if (value === null || typeof value !== 'object' || Array.isArray(value)) return undefined;
72
+ return value as Record<string, unknown>;
73
+ } catch {
74
+ return undefined;
75
+ }
76
+ }
77
+
78
+ /**
79
+ * Correlate tool-call fragments by `index` and drive the ToolPart lifecycle.
80
+ * THE HARD PART: `id`, `name` and each slice of `arguments` arrive across
81
+ * arbitrarily many chunks in provider-dependent order.
82
+ *
83
+ * A ToolPart is pushed (`input-streaming`) the first time a call has BOTH an id
84
+ * and a non-empty name: announcing earlier would create a panel whose `type` is
85
+ * the empty string. Everything before that is buffered and flushed at announce.
86
+ */
87
+ export function createToolCallAccumulator(sink: AssistantStreamSink, opts: ConsumeOptions = {}) {
88
+ const calls = new Map<number, MutableCall>();
89
+
90
+ /** Write the argument text that has arrived so far.
91
+ *
92
+ * `rawInput` is written on EVERY fragment, so a consumer watching the part
93
+ * sees the arguments assemble character by character. `input` is written only
94
+ * when the whole accumulated text parses to a JSON object. Honest caveat:
95
+ * with plain `JSON.parse` a prefix never parses, so `input` in practice still
96
+ * lands once, at the end. `rawInput` is what streams. */
97
+ const writeArguments = (call: MutableCall) => {
98
+ const id = call.id!;
99
+ const text = call.argumentsText;
100
+ const parsed = parseArgumentObject(text);
101
+ if (parsed) {
102
+ const fp = fingerprint(parsed);
103
+ if (fp !== call.lastInputFp) {
104
+ call.lastInputFp = fp;
105
+ sink.upsertTool(id, { rawInput: text, input: parsed, state: 'input-available' });
106
+ return;
107
+ }
108
+ }
109
+ sink.upsertTool(id, { rawInput: text });
110
+ };
111
+
112
+ const announce = (call: MutableCall) => {
113
+ if (call.announced) return;
114
+ call.id ??= `call_${call.index}`;
115
+ call.announced = true;
116
+ sink.upsertTool(call.id, { type: call.name || 'unknown_tool', state: 'input-streaming' });
117
+ // Fragments that arrived before the id did are flushed now.
118
+ if (call.argumentsText) writeArguments(call);
119
+ };
120
+
121
+ const apply = (raw: ModelToolCallDelta) => {
122
+ const index = typeof raw.index === 'number' ? raw.index : 0;
123
+ let call = calls.get(index);
124
+ if (!call) {
125
+ call = {
126
+ index,
127
+ id: null,
128
+ name: '',
129
+ argumentsText: '',
130
+ announced: false,
131
+ lastInputFp: null,
132
+ providerExecuted: false,
133
+ };
134
+ calls.set(index, call);
135
+ }
136
+ if (raw.id && !call.id) call.id = raw.id;
137
+ if (raw.name) call.name += raw.name;
138
+ if (call.id && call.name) announce(call);
139
+
140
+ if (typeof raw.arguments === 'string' && raw.arguments !== '') {
141
+ call.argumentsText += raw.arguments;
142
+ if (call.announced) writeArguments(call);
143
+ }
144
+
145
+ if (raw.output !== undefined || raw.outputError !== undefined) {
146
+ // A result the PROVIDER executed. Force the announce so the panel exists,
147
+ // then complete it. `settle` must not touch it afterwards.
148
+ announce(call);
149
+ call.providerExecuted = true;
150
+ if (raw.outputError !== undefined) {
151
+ call.outputError = raw.outputError;
152
+ sink.upsertTool(call.id!, { state: 'output-error', errorText: raw.outputError });
153
+ } else {
154
+ call.output = raw.output;
155
+ sink.upsertTool(call.id!, { state: 'output-available', output: raw.output });
156
+ }
157
+ }
158
+ };
159
+
160
+ /** Settle every accumulated call once the stream ends. */
161
+ const settle = (stopReason: StopReason | undefined, streamError?: string): ModelToolCall[] =>
162
+ [...calls.values()]
163
+ .sort((a, b) => a.index - b.index)
164
+ .map((call) => {
165
+ announce(call); // a call that only ever had arguments still gets a panel
166
+ const id = call.id!;
167
+ const base = snapshot(call);
168
+
169
+ if (call.providerExecuted) {
170
+ // Already at output-available/output-error. Re-settling would overwrite
171
+ // the provider's own result with a parse of its arguments.
172
+ return {
173
+ ...base,
174
+ providerExecuted: true,
175
+ ...(call.output !== undefined ? { output: call.output } : {}),
176
+ ...(call.outputError !== undefined ? { error: call.outputError } : {}),
177
+ };
178
+ }
179
+
180
+ // Attached once, at settle: before that `argumentsText` is still growing
181
+ // and a raw snapshot of half a JSON string is worse than none.
182
+ const raw = rawOf(call);
183
+ // `type` is re-sent because a provider may split the tool NAME across
184
+ // fragments; the announce could have fired on a prefix.
185
+ const name = call.name || 'unknown_tool';
186
+
187
+ if (streamError) {
188
+ const error = `Stream failed before the tool call completed: ${streamError}`;
189
+ sink.upsertTool(id, {
190
+ type: name,
191
+ state: 'output-error',
192
+ errorText: error,
193
+ rawInput: call.argumentsText,
194
+ raw,
195
+ });
196
+ return { ...base, error };
197
+ }
198
+
199
+ if (!call.name) {
200
+ const error = 'Tool call arrived with no function name; cannot dispatch it.';
201
+ sink.upsertTool(id, { state: 'output-error', errorText: error, raw });
202
+ return { ...base, error };
203
+ }
204
+
205
+ const rawArgs = call.argumentsText.trim();
206
+ try {
207
+ // An argument-less tool legitimately streams '' or '{}'.
208
+ const parsed: unknown = rawArgs === '' ? {} : JSON.parse(rawArgs);
209
+ if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {
210
+ throw new Error('arguments must be a JSON object');
211
+ }
212
+ const input = parsed as Record<string, unknown>;
213
+ sink.upsertTool(id, {
214
+ type: name,
215
+ state: 'input-available',
216
+ input,
217
+ rawInput: call.argumentsText,
218
+ raw,
219
+ });
220
+ const ready: ModelToolCall = { ...base, input };
221
+ opts.onToolCallReady?.(ready);
222
+ return ready;
223
+ } catch (e) {
224
+ const truncated =
225
+ stopReason === 'length' ? ' (the stream hit the token limit mid-call)' : '';
226
+ const error =
227
+ `Malformed tool arguments${truncated}: ${(e as Error).message}. ` +
228
+ `Received ${rawArgs.length} chars: ${clip(rawArgs, 160)}`;
229
+ sink.upsertTool(id, {
230
+ type: name,
231
+ state: 'output-error',
232
+ errorText: error,
233
+ rawInput: call.argumentsText,
234
+ raw,
235
+ });
236
+ return { ...base, error };
237
+ }
238
+ });
239
+
240
+ return { apply, settle };
241
+ }
242
+
243
+ // ── Part recording and sink tee ──────────────────────────────────────────────
244
+
245
+ /** A sink that writes nowhere but into a `MessagePart[]`, using the kit's own
246
+ * builders. Teed alongside the real sink so `ModelTurn.parts` cannot drift from
247
+ * what the message actually received. */
248
+ function createPartsRecorder(): AssistantStreamSink & { parts(): MessagePart[] } {
249
+ let parts: MessagePart[] = [];
250
+ return {
251
+ appendText(delta) {
252
+ parts = appendTextPart(parts, delta);
253
+ },
254
+ appendReasoning(delta, opts) {
255
+ // `streamId` is DROPPED here on purpose. It namespaces block indices for a
256
+ // sink that outlives one stream; this recorder starts a fresh array per
257
+ // call, so within `ModelTurn.parts` there is nothing to disambiguate. Worse,
258
+ // it is a new value on every call, so keeping it would make `parts`
259
+ // non-reproducible for identical input and break the determinism the
260
+ // adapter guarantees (same chunks in, same parts out, whatever the byte
261
+ // boundaries). The host's own sink still receives it.
262
+ parts = appendReasoningPart(parts, delta, { ...opts, streamId: undefined });
263
+ },
264
+ upsertTool(toolCallId, patch) {
265
+ parts = upsertToolPart(parts, toolCallId, patch);
266
+ },
267
+ addSource(source) {
268
+ parts = [...parts, { type: 'source', source }];
269
+ },
270
+ parts: () => parts,
271
+ };
272
+ }
273
+
274
+ /** Drive two sinks from one call. `a` (the host's) goes first so the visible
275
+ * message updates in stream order. */
276
+ function teeSink(a: AssistantStreamSink, b: AssistantStreamSink): AssistantStreamSink {
277
+ return {
278
+ appendText(delta) {
279
+ a.appendText(delta);
280
+ b.appendText(delta);
281
+ },
282
+ appendReasoning(delta, opts) {
283
+ a.appendReasoning(delta, opts);
284
+ b.appendReasoning(delta, opts);
285
+ },
286
+ upsertTool(toolCallId, patch) {
287
+ a.upsertTool(toolCallId, patch);
288
+ b.upsertTool(toolCallId, patch);
289
+ },
290
+ addSource(source) {
291
+ a.addSource?.(source);
292
+ b.addSource?.(source);
293
+ },
294
+ };
295
+ }
296
+
297
+ // ── The main loop ────────────────────────────────────────────────────────────
298
+
299
+ /** One id per `consumeModelStream` call, i.e. per provider response stream.
300
+ *
301
+ * It namespaces reasoning block indices. Anthropic restarts content-block
302
+ * indices at 0 on every message, and a tool loop reads several messages into ONE
303
+ * assistant turn, so without this round 2's block 0 merges into round 1's part
304
+ * and overwrites its verbatim `raw`. See `appendReasoningPart`.
305
+ *
306
+ * A monotonic counter, not a UUID: this never leaves the process, is compared
307
+ * only for equality against parts built in the same process, and a counter keeps
308
+ * the value short and reproducible in test output. */
309
+ let streamSeq = 0;
310
+ const nextStreamId = (): string => `wire-${++streamSeq}`;
311
+
312
+ /**
313
+ * Read one turn's worth of `ModelStreamChunk`s and drive `sink` with them.
314
+ *
315
+ * The sink is expected to be the kit's `AssistantStream`, which produces a NEW
316
+ * message object (and a new `parts` array) on every real mutation: that is what
317
+ * makes `<kai-thread>` re-render. This adapter calls the sink once per delta and
318
+ * never batches; batching is a host concern.
319
+ *
320
+ * This is also the escape hatch for a consumer who already has neutral chunks
321
+ * from somewhere else and does not need a WireFormat at all.
322
+ */
323
+ export async function consumeModelStream(
324
+ chunks: AsyncIterable<ModelStreamChunk>,
325
+ sink: AssistantStreamSink,
326
+ opts: ConsumeOptions = {},
327
+ ): Promise<ModelTurn> {
328
+ const label = opts.reasoningLabel ?? 'Thinking';
329
+ const streamId = nextStreamId();
330
+ const recorder = createPartsRecorder();
331
+ const out = teeSink(sink, recorder);
332
+ const tools = createToolCallAccumulator(out, opts);
333
+
334
+ let text = '';
335
+ let reasoning = '';
336
+ let reasoningChunks = 0;
337
+ let chunkCount = 0;
338
+ let finishReason: string | null = null;
339
+ let error: ModelTurn['error'];
340
+ let usage: ModelUsage | undefined;
341
+ const sources: MessageSource[] = [];
342
+
343
+ for await (const chunk of chunks) {
344
+ chunkCount++;
345
+
346
+ if (chunk.usage) usage = { ...usage, ...chunk.usage };
347
+
348
+ if (chunk.error) {
349
+ error = chunk.error;
350
+ if (chunk.finishReason) finishReason = chunk.finishReason;
351
+ break;
352
+ }
353
+
354
+ if (chunk.text) {
355
+ text += chunk.text;
356
+ out.appendText(chunk.text);
357
+ }
358
+
359
+ // REWORK 1. The spike gated this whole branch on `if (chunk.reasoning)`,
360
+ // which is falsy for ''. That dropped exactly the payloads `raw` exists to
361
+ // preserve: an Anthropic redacted_thinking block (opaque, no readable text,
362
+ // and the docs require sending it back "including any blocks with empty
363
+ // thinking fields") and the assembled block emitted at content_block_stop
364
+ // after signature_delta. Both arrive with no text.
365
+ if (
366
+ chunk.reasoning !== undefined ||
367
+ chunk.reasoningRaw !== undefined ||
368
+ chunk.reasoningSignature !== undefined
369
+ ) {
370
+ const delta = chunk.reasoning ?? '';
371
+ reasoning += delta;
372
+ // Only NON-EMPTY text counts as "reasoning streamed".
373
+ if (delta !== '') reasoningChunks++;
374
+ // `raw` and `signature` are spread in only when present: passing undefined
375
+ // would blank a value an earlier delta already established.
376
+ out.appendReasoning(delta, {
377
+ index: chunk.reasoningIndex ?? 0,
378
+ // Namespaces the index to THIS stream, so a later round reading into the
379
+ // same sink opens its own part instead of overwriting this one's `raw`.
380
+ streamId,
381
+ label,
382
+ ...(chunk.reasoningRaw ? { raw: chunk.reasoningRaw } : {}),
383
+ ...(chunk.reasoningSignature ? { signature: chunk.reasoningSignature } : {}),
384
+ });
385
+ }
386
+
387
+ if (chunk.toolCalls) for (const tc of chunk.toolCalls) tools.apply(tc);
388
+
389
+ if (chunk.sources) {
390
+ for (const source of chunk.sources) {
391
+ sources.push(source);
392
+ out.addSource?.(source);
393
+ }
394
+ }
395
+
396
+ if (chunk.finishReason) finishReason = chunk.finishReason;
397
+ }
398
+
399
+ // A turn that received NOTHING has failed, and used to say so nowhere.
400
+ //
401
+ // The response was 200 and the body carried no parsable frame at all, which is
402
+ // exactly what a proxy route produces when it forwards a provider failure
403
+ // WITHOUT its status: an upstream 401 (no key — the most common first run)
404
+ // arrives as HTTP 200 whose body is a JSON error object mislabelled
405
+ // text/event-stream. `readModelStream` cannot throw for it (the response is
406
+ // ok) and the SSE decoder finds no `data:` line, so the turn resolved empty:
407
+ // no text, no error, no console output, nothing to debug. The route templates
408
+ // forward the status now; this is the second, independent guard, and it also
409
+ // covers a truncated body, a non-streaming completion returned by mistake, and
410
+ // an HTML proxy page.
411
+ if (chunkCount === 0 && !error) {
412
+ error = {
413
+ code: 'empty-stream',
414
+ message:
415
+ 'The model stream produced no chunks. The response was 200 but nothing in its body parsed ' +
416
+ 'as a stream frame — check the endpoint really sent Content-Type: text/event-stream and that ' +
417
+ 'the request set stream: true. A route that forwards a provider error without its status ' +
418
+ 'lands here: the body is a JSON error, not SSE.',
419
+ };
420
+ }
421
+
422
+ // REWORK 3. `finishReason` is reported verbatim; `stopReason` is what the
423
+ // adapter itself branches on, so no OpenAI literal leaks into adapter logic.
424
+ const stopReason = normalizeStopReason(finishReason) ?? (error ? 'error' : undefined);
425
+ const toolCalls = tools.settle(stopReason, error?.message);
426
+
427
+ return {
428
+ parts: recorder.parts(),
429
+ text,
430
+ reasoning,
431
+ toolCalls,
432
+ sources,
433
+ finishReason,
434
+ reasoningChunks,
435
+ chunks: chunkCount,
436
+ ...(stopReason ? { stopReason } : {}),
437
+ ...(error ? { error } : {}),
438
+ ...(usage ? { usage } : {}),
439
+ };
440
+ }