@kitn.ai/ui 0.27.0 → 0.29.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 (612) hide show
  1. package/README.md +10 -2
  2. package/dist/{Icon-BnFKqqtY.js → Icon-DObhsRtm.js} +1 -1
  3. package/dist/{action-icons-CBskfBMz.js → action-icons-CcgNN2oT.js} +1 -1
  4. package/dist/agent-tooling/construct/public.d.ts +15 -0
  5. package/dist/agent-tooling/construct/schema.d.ts +111 -0
  6. package/dist/arrow-down-CjRU3JgV.js +1 -0
  7. package/dist/arrow-left-Bnpb1UEW.js +1 -0
  8. package/dist/{artifact-CvXEm1lS.js → artifact-Bwt7OgcR.js} +1 -1
  9. package/dist/{attachments-C43ZegEq.js → attachments-Qr4kg-2b.js} +1 -1
  10. package/dist/{audio-visualizer-B-79y1Tj.js → audio-visualizer-DToYdfSc.js} +1 -1
  11. package/dist/{badge-BpUbq8c0.js → badge-CdEu_jn2.js} +1 -1
  12. package/dist/{bell-sn17Ip9v.js → bell-DQAAOpDz.js} +1 -1
  13. package/dist/{button-BH6rN0U-.js → button-DkuOnGLy.js} +1 -1
  14. package/dist/{card-renderer-Cb1gQmth.js → card-renderer-Jx70m6_l.js} +1 -1
  15. package/dist/{card-routing-DifQgS7n.js → card-routing-0YidER_3.js} +1 -1
  16. package/dist/check-njkVdZu2.js +1 -0
  17. package/dist/{checkbox-Dc9Yov_B.js → checkbox-D7iRB3nL.js} +1 -1
  18. package/dist/{checkbox-group-B1kDLLYk.js → checkbox-group-B2_rpoPM.js} +1 -1
  19. package/dist/chevron-down-B72s6PXR.js +1 -0
  20. package/dist/chevron-right-BatuHzUm.js +1 -0
  21. package/dist/{choice-card-BT3c1S8g.js → choice-card-m0BYqqOK.js} +1 -1
  22. package/dist/circle-check-B62pODB3.js +1 -0
  23. package/dist/{circle-x-wobWkoSx.js → circle-x-BPG0iPst.js} +1 -1
  24. package/dist/circle-zx0ByzY9.js +1 -0
  25. package/dist/code-block-ClMLKb7C.js +1 -0
  26. package/dist/{collapsible-CPJbf6FM.js → collapsible-B4DlWicL.js} +1 -1
  27. package/dist/components/chat-thread.d.ts +89 -1
  28. package/dist/components/conversation-item.d.ts +16 -0
  29. package/dist/components/conversation-panel.d.ts +29 -0
  30. package/dist/components/home-panel.d.ts +34 -0
  31. package/dist/components/widget-tab-bar.d.ts +16 -0
  32. package/dist/{composer-CjngLzal.js → composer-sQ0HcvyG.js} +3 -3
  33. package/dist/{confirm-card-DCx_A4bU.js → confirm-card-rQWDQsnC.js} +1 -1
  34. package/dist/construct-cli.es.js +185 -17
  35. package/dist/construct.d.ts +5 -0
  36. package/dist/construct.js +327 -0
  37. package/dist/{context-BY8V-Nlp.js → context-0kg4ZX1J.js} +1 -1
  38. package/dist/controllable-CnGpMF6r.js +1 -0
  39. package/dist/conversation-item-BxwQLaFJ.js +1 -0
  40. package/dist/conversation-list-BCfGN1JU.js +1 -0
  41. package/dist/{copy-B6DO4PqB.js → copy-n9u9rqpi.js} +1 -1
  42. package/dist/core-C8fzo39E.js +1 -12
  43. package/dist/{create-tween-CnMHviKB.js → create-tween-C-q-JCM-.js} +1 -1
  44. package/dist/{create-tween-D1aiGZZh.js → create-tween-CRrJXxBd.js} +1 -1
  45. package/dist/{create-tween-BPzaefTp.js → create-tween-DZ3RRDHD.js} +1 -1
  46. package/dist/{create-tween-DUSQUKpr.js → create-tween-uPkArjIG.js} +1 -1
  47. package/dist/custom-elements.json +51 -2
  48. package/dist/{default-input-CucQEOqH.js → default-input-CaMrJkgH.js} +1 -1
  49. package/dist/define-By-uL588.js +1 -0
  50. package/dist/define.js +2 -2
  51. package/dist/define.server.js +2 -2
  52. package/dist/{disclosure-CbLtajUQ.js → disclosure-WUImBbDv.js} +1 -1
  53. package/dist/{dropdown-BwhViJFd.js → dropdown-wZVeJOMd.js} +1 -1
  54. package/dist/elements/agent-card.js +1 -1
  55. package/dist/elements/artifact.js +1 -1
  56. package/dist/elements/attachments.js +1 -1
  57. package/dist/elements/audio-visualizer.js +1 -1
  58. package/dist/elements/avatar.js +1 -1
  59. package/dist/elements/badge.js +1 -1
  60. package/dist/elements/button.js +1 -1
  61. package/dist/elements/card.js +1 -1
  62. package/dist/elements/cards.js +1 -1
  63. package/dist/elements/chain-of-thought.js +1 -1
  64. package/dist/elements/chat-scope-picker.js +1 -1
  65. package/dist/elements/chat-workspace.js +1 -1
  66. package/dist/elements/chat.js +1 -1
  67. package/dist/elements/checkbox-group.js +1 -1
  68. package/dist/elements/checkbox.js +1 -1
  69. package/dist/elements/checkpoint.js +1 -1
  70. package/dist/elements/choice.js +1 -1
  71. package/dist/elements/coachmark.js +1 -1
  72. package/dist/elements/code-block.js +1 -1
  73. package/dist/elements/command.js +1 -1
  74. package/dist/elements/compare.js +1 -1
  75. package/dist/elements/composer.js +1 -1
  76. package/dist/elements/confirm-card.js +1 -1
  77. package/dist/elements/context-meter.js +1 -1
  78. package/dist/elements/conversation-item.js +1 -1
  79. package/dist/elements/conversation-list.js +1 -1
  80. package/dist/elements/dialog.js +1 -1
  81. package/dist/elements/dock.js +3 -3
  82. package/dist/elements/dropdown.js +1 -1
  83. package/dist/elements/editable-label.js +1 -1
  84. package/dist/elements/embed.js +1 -1
  85. package/dist/elements/empty.js +1 -1
  86. package/dist/elements/feedback-bar.js +1 -1
  87. package/dist/elements/file-tree.js +1 -1
  88. package/dist/elements/file-upload.js +1 -1
  89. package/dist/elements/form.js +1 -1
  90. package/dist/elements/hover-card.js +1 -1
  91. package/dist/elements/icon.js +1 -1
  92. package/dist/elements/image.js +1 -1
  93. package/dist/elements/input.js +1 -1
  94. package/dist/elements/kbd.js +1 -1
  95. package/dist/elements/link-preview.js +1 -1
  96. package/dist/elements/loader.js +1 -1
  97. package/dist/elements/markdown.js +1 -1
  98. package/dist/elements/menu.js +1 -1
  99. package/dist/elements/message-skills.js +1 -1
  100. package/dist/elements/message.js +1 -1
  101. package/dist/elements/model-switcher.js +1 -1
  102. package/dist/elements/nav.js +1 -1
  103. package/dist/elements/notice.js +1 -1
  104. package/dist/elements/pane-grid.js +1 -1
  105. package/dist/elements/pane-group.js +1 -1
  106. package/dist/elements/pane.js +1 -1
  107. package/dist/elements/popover.js +1 -1
  108. package/dist/elements/progress-bar.js +1 -1
  109. package/dist/elements/prompt-dock.js +1 -1
  110. package/dist/elements/prompt-input.js +1 -1
  111. package/dist/elements/prompt-suggestions.js +1 -1
  112. package/dist/elements/radio-group.js +1 -1
  113. package/dist/elements/reasoning.js +1 -1
  114. package/dist/elements/remote.js +1 -1
  115. package/dist/elements/resizable.js +1 -1
  116. package/dist/elements/response-stream.js +1 -1
  117. package/dist/elements/screen.js +1 -1
  118. package/dist/elements/scroll-area.js +1 -1
  119. package/dist/elements/scroll-button.js +1 -1
  120. package/dist/elements/search.js +1 -1
  121. package/dist/elements/segmented.js +1 -1
  122. package/dist/elements/select.js +1 -1
  123. package/dist/elements/separator.js +1 -1
  124. package/dist/elements/setting-item.js +1 -1
  125. package/dist/elements/settings-group.js +1 -1
  126. package/dist/elements/skeleton.js +1 -1
  127. package/dist/elements/slider.js +1 -1
  128. package/dist/elements/source.js +1 -1
  129. package/dist/elements/status.js +1 -1
  130. package/dist/elements/switch.js +1 -1
  131. package/dist/elements/tabs.js +1 -1
  132. package/dist/elements/tasks.js +1 -1
  133. package/dist/elements/text-shimmer.js +1 -1
  134. package/dist/elements/thinking-bar.js +1 -1
  135. package/dist/elements/thread.js +1 -1
  136. package/dist/elements/toast.js +1 -1
  137. package/dist/elements/tool.js +1 -1
  138. package/dist/elements/tooltip.js +1 -1
  139. package/dist/elements/voice-input.js +1 -1
  140. package/dist/elements/voice-output.js +1 -1
  141. package/dist/elements.d.ts +20 -4
  142. package/dist/{ellipsis-DFr4Vqr3.js → ellipsis-CbOpJnU3.js} +1 -1
  143. package/dist/{embed-5s_vU4J0.js → embed-CrfjkbUG.js} +1 -1
  144. package/dist/engine-javascript-C1x7zo1_.js +1 -141
  145. package/dist/{external-link-u9d85ORQ.js → external-link-ByXAwBBQ.js} +1 -1
  146. package/dist/{file-text-CX7_x42o.js → file-text-DMib2qwt.js} +1 -1
  147. package/dist/{file-tree-D3kBjXI5.js → file-tree-CJqM2aP7.js} +1 -1
  148. package/dist/{folder-V-YdIL8f.js → folder-_BAb929C.js} +1 -1
  149. package/dist/{form-BRNUMCN2.js → form-DSZgZQZk.js} +1 -1
  150. package/dist/{hover-card-DaeiYrTA.js → hover-card-BQbul9eq.js} +1 -1
  151. package/dist/{icon-BpixdZNq.js → icon-CdcfRhYI.js} +1 -1
  152. package/dist/index.d.ts +3 -1
  153. package/dist/index.js +2842 -2703
  154. package/dist/index.server.js +2820 -2681
  155. package/dist/{info-8mFsIjS3.js → info-DsFjGuI_.js} +1 -1
  156. package/dist/{input-d1Yuu-hz.js → input-DKbmkMos.js} +1 -1
  157. package/dist/kai.es.js +1 -1
  158. package/dist/{kbd-961zMPFB.js → kbd-PvdGhX4s.js} +1 -1
  159. package/dist/{link-preview-DIIbV2Sd.js → link-preview-DbM1866N.js} +1 -1
  160. package/dist/{link-DlZZBGaR.js → link-zF8PzWfF.js} +1 -1
  161. package/dist/{loader-YQszHFaW.js → loader-BM4CEz4G.js} +1 -1
  162. package/dist/{markdown-CVk1MPsj.js → markdown-LMvmAyBk.js} +7 -7
  163. package/dist/mcp.es.js +79 -5
  164. package/dist/{message-CwKVEdZg.js → message-BSsgvHvf.js} +1 -1
  165. package/dist/{message-DS8lzHc1.js → message-BYZECyek.js} +1 -1
  166. package/dist/message-circle-DruwObfX.js +1 -0
  167. package/dist/message-square-BG6q6mlm.js +1 -0
  168. package/dist/{minimize-2-UEZmP2QT.js → minimize-2-BQRoBV1V.js} +1 -1
  169. package/dist/{model-switcher-Kk1jEQ5t.js → model-switcher-CMpCOYcB.js} +1 -1
  170. package/dist/{overlay-C1od6LOz.js → overlay-Cb-MkyDa.js} +1 -1
  171. package/dist/{panel-right-ryET0yyn.js → panel-right-i8warFxT.js} +1 -1
  172. package/dist/{paperclip-BDNoZFJP.js → paperclip-ByY3UVO6.js} +1 -1
  173. package/dist/play-BvKKq3fX.js +1 -0
  174. package/dist/primitives/conversation-store.d.ts +54 -0
  175. package/dist/{progress-bar-BvYX0aoy.js → progress-bar-jVAHvMUf.js} +1 -1
  176. package/dist/{prompt-suggestion-BRFu2lcu.js → prompt-suggestion-CD-qtNgC.js} +1 -1
  177. package/dist/{radio-DcL23cNJ.js → radio-BsoBMhkF.js} +1 -1
  178. package/dist/react/index.d.ts +393 -0
  179. package/dist/react.js +20 -20
  180. package/dist/{reasoning-Cackq4Rh.js → reasoning-4kBPtlTx.js} +1 -1
  181. package/dist/register-impl-B1hLkrI8.js +424 -0
  182. package/dist/{resizable-Cp9HUYih.js → resizable-uPmY9VY-.js} +1 -1
  183. package/dist/{rotate-ccw-0DLRDHH5.js → rotate-ccw-B2xn93py.js} +1 -1
  184. package/dist/{rotate-cw-DOB9IGcU.js → rotate-cw-CMVLoCyH.js} +1 -1
  185. package/dist/{scroll-area-emVmWP4K.js → scroll-area-BqLUo8ZZ.js} +1 -1
  186. package/dist/{scroll-button-CeP_gv1x.js → scroll-button-DslXiJyL.js} +1 -1
  187. package/dist/{select-CWmu00tS.js → select-2cLRtPGT.js} +1 -1
  188. package/dist/{separator-CE6vly6z.js → separator-BWQtNJcM.js} +1 -1
  189. package/dist/{settings-CE-78SvZ.js → settings-BBR63jLg.js} +1 -1
  190. package/dist/{settings-group-ZFWNxFQR.js → settings-group-B2ciy-Iw.js} +1 -1
  191. package/dist/{skeleton-BebdP4mf.js → skeleton-CkHI-HgC.js} +1 -1
  192. package/dist/{slider-BAKRYUlz.js → slider-DDR9U-i0.js} +1 -1
  193. package/dist/{solid-BE5ui6sy.js → solid-BzCFdL25.js} +7720 -7058
  194. package/dist/{solid-DFhsce3O.js → solid-DruVOXnf.js} +5864 -5283
  195. package/dist/solid.d.ts +6 -2
  196. package/dist/solid.js +217 -210
  197. package/dist/solid.server.js +217 -210
  198. package/dist/{source-B0FlguSx.js → source-GEnFF528.js} +1 -1
  199. package/dist/{star-CBMZvLuN.js → star-CilHq8GP.js} +1 -1
  200. package/dist/store-Ciyk6eZG.js +1 -0
  201. package/dist/{switch-CViARZCy.js → switch-KkeQIbuH.js} +1 -1
  202. package/dist/{tasks-card-MjCcOhR_.js → tasks-card-BrN4bggJ.js} +1 -1
  203. package/dist/{text-shimmer-DKlwRF2G.js → text-shimmer-Dcj1MHuq.js} +1 -1
  204. package/dist/{textarea-3ay2Me2-.js → textarea-Dpvbngbg.js} +1 -1
  205. package/dist/theme.tokens.css +28 -0
  206. package/dist/{thumbs-up-DQcu2HMO.js → thumbs-up-CsT9Wzb9.js} +1 -1
  207. package/dist/{toast-store-C6yKOhbk.js → toast-store-tgK6MuMv.js} +1 -1
  208. package/dist/{tool-BCYNlfKy.js → tool-DzUjIBT8.js} +1 -1
  209. package/dist/{tooltip-05zI4hjs.js → tooltip-Bkkg_4t0.js} +1 -1
  210. package/dist/{trash-2-BR1RxGky.js → trash-2-jBKxjGGQ.js} +1 -1
  211. package/dist/{triangle-alert-DHohDOCy.js → triangle-alert-DlQ68ppf.js} +1 -1
  212. package/dist/types.d.ts +48 -3
  213. package/dist/ui/dock.d.ts +29 -0
  214. package/dist/{upload-BbGW6A_u.js → upload-TcAHXv9W.js} +1 -1
  215. package/dist/{url-scheme-policy-DHpoTJwB.js → url-scheme-policy-DR5DgvkM.js} +1 -1
  216. package/dist/{use-card-resolution-CJW4grFa.js → use-card-resolution-DaZqAdWf.js} +1 -1
  217. package/dist/{variant-aurora-xiMPty8f.js → variant-aurora-BhLuYxJR.js} +1 -1
  218. package/dist/{variant-aurora-BUOVgPOB.js → variant-aurora-CNmfHhcx.js} +2 -2
  219. package/dist/{variant-aurora-CUsUJvFI.js → variant-aurora-D6GsdTPA.js} +2 -2
  220. package/dist/{variant-aurora-CW2i4bfr.js → variant-aurora-DbW_OWL2.js} +1 -1
  221. package/dist/{variant-custom-D91HjAKz.js → variant-custom-BRvaNHSi.js} +1 -1
  222. package/dist/{variant-custom-BQtOnmeO.js → variant-custom-BvYHR62b.js} +1 -1
  223. package/dist/{variant-custom-CAnzzppW.js → variant-custom-DMTrEO5w.js} +2 -2
  224. package/dist/{variant-custom-CAm9L-E5.js → variant-custom-DV2x254s.js} +2 -2
  225. package/dist/{variant-wave-Ca1Ls4_y.js → variant-wave-BNMGrDfj.js} +2 -2
  226. package/dist/{variant-wave-uY5crU_K.js → variant-wave-BpDd8t3Z.js} +1 -1
  227. package/dist/{variant-wave-CxX39DKd.js → variant-wave-CyBueXj9.js} +2 -2
  228. package/dist/{variant-wave-DYyzIIZv.js → variant-wave-sp-qwsdI.js} +1 -1
  229. package/dist/x-Z5UntkIJ.js +1 -0
  230. package/frameworks/react/index.tsx +14 -4
  231. package/llms-full.txt +7 -2
  232. package/package.json +16 -16
  233. package/src/elements/element-meta.json +49 -6
  234. package/theme.css +28 -0
  235. package/bin/route.test.js +0 -58
  236. package/dist/arrow-down-Br0qtpsz.js +0 -1
  237. package/dist/arrow-left-Dj7xgE12.js +0 -1
  238. package/dist/check-DPeeMUYx.js +0 -1
  239. package/dist/chevron-down-CHSWk7ZT.js +0 -1
  240. package/dist/chevron-right-B7l_fMgx.js +0 -1
  241. package/dist/circle-Bb0yOpqM.js +0 -1
  242. package/dist/circle-check-BGZpCiz7.js +0 -1
  243. package/dist/code-block-CUQ5mtv0.js +0 -1
  244. package/dist/controllable-D43BKmtX.js +0 -1
  245. package/dist/conversation-list-D4lLU_yS.js +0 -1
  246. package/dist/define-CGGX-7Vg.js +0 -1
  247. package/dist/message-circle-Xf8Q-vZp.js +0 -1
  248. package/dist/message-square-Cxnwgkns.js +0 -1
  249. package/dist/play-OFIvYXUQ.js +0 -1
  250. package/dist/register-impl-C7rENvPK.js +0 -424
  251. package/dist/store-7eoadydQ.js +0 -1
  252. package/dist/x-C5m1JFgi.js +0 -1
  253. package/src/agent-tooling/archetypes.ts +0 -205
  254. package/src/agent-tooling/catalog/README.md +0 -676
  255. package/src/agent-tooling/catalog/catalog-types.ts +0 -231
  256. package/src/agent-tooling/catalog/fabrications.ts +0 -96
  257. package/src/agent-tooling/catalog/invariants.ts +0 -284
  258. package/src/agent-tooling/catalog/labs-titles.ts +0 -114
  259. package/src/agent-tooling/catalog/scenarios.ts +0 -87
  260. package/src/agent-tooling/catalog/surfaces.ts +0 -347
  261. package/src/agent-tooling/construct/cli-entry.ts +0 -8
  262. package/src/agent-tooling/construct/cli.ts +0 -131
  263. package/src/agent-tooling/construct/codegen.ts +0 -1353
  264. package/src/agent-tooling/construct/construct.v1.schema.json +0 -250
  265. package/src/agent-tooling/construct/dev.ts +0 -148
  266. package/src/agent-tooling/construct/fixtures/demo-widget.construct.json +0 -7
  267. package/src/agent-tooling/construct/fixtures/ops-console.construct.json +0 -44
  268. package/src/agent-tooling/construct/fixtures/owner-widget.construct.json +0 -23
  269. package/src/agent-tooling/construct/schema.ts +0 -371
  270. package/src/agent-tooling/integrations/anthropic.ts +0 -442
  271. package/src/agent-tooling/integrations/cloudflare.ts +0 -218
  272. package/src/agent-tooling/integrations/langgraph.ts +0 -133
  273. package/src/agent-tooling/integrations/mastra.ts +0 -182
  274. package/src/agent-tooling/integrations/mock.ts +0 -148
  275. package/src/agent-tooling/integrations/ollama.ts +0 -97
  276. package/src/agent-tooling/integrations/openai.ts +0 -95
  277. package/src/agent-tooling/integrations/openrouter.ts +0 -82
  278. package/src/agent-tooling/integrations/pi.ts +0 -176
  279. package/src/agent-tooling/integrations/pydantic-ai.ts +0 -108
  280. package/src/agent-tooling/integrations/vercel-ai-sdk.ts +0 -398
  281. package/src/agent-tooling/mcp/css-raw.d.ts +0 -12
  282. package/src/agent-tooling/mcp/manifest.ts +0 -422
  283. package/src/agent-tooling/mcp/server.ts +0 -116
  284. package/src/agent-tooling/mcp/stdio.ts +0 -18
  285. package/src/agent-tooling/mcp/tools/construct.ts +0 -130
  286. package/src/agent-tooling/mcp/tools/debug.ts +0 -621
  287. package/src/agent-tooling/mcp/tools/reference.ts +0 -980
  288. package/src/agent-tooling/mcp/tools/scaffold.ts +0 -6708
  289. package/src/agent-tooling/mcp/tools/theme.ts +0 -456
  290. package/src/agent-tooling/mcp/tools/types.ts +0 -14
  291. package/src/agent-tooling/mcp/validate-args.ts +0 -141
  292. package/src/agent-tooling/recipes/composed-thread.ts +0 -714
  293. package/src/agent-tooling/recipes/index.ts +0 -22
  294. package/src/agent-tooling/recipes/types.ts +0 -32
  295. package/src/agent-tooling/registry.ts +0 -132
  296. package/src/agent-tooling/route-emit.ts +0 -305
  297. package/src/agent-tooling/types.ts +0 -390
  298. package/src/components/artifact-card.tsx +0 -120
  299. package/src/components/artifact.tsx +0 -914
  300. package/src/components/attachment-types.ts +0 -66
  301. package/src/components/attachments.tsx +0 -536
  302. package/src/components/audio-visualizer/audio-visualizer.voice-fixture.ts +0 -257
  303. package/src/components/audio-visualizer/aurora.glsl.ts +0 -330
  304. package/src/components/audio-visualizer/fit-scale.ts +0 -112
  305. package/src/components/audio-visualizer/index.tsx +0 -528
  306. package/src/components/audio-visualizer/labs/lab-choreography.ts +0 -187
  307. package/src/components/audio-visualizer/labs/lab-shaders.ts +0 -363
  308. package/src/components/audio-visualizer/labs/lab-visualizer.tsx +0 -102
  309. package/src/components/audio-visualizer/shader-canvas.tsx +0 -876
  310. package/src/components/audio-visualizer/sizes.ts +0 -54
  311. package/src/components/audio-visualizer/variant-aurora.tsx +0 -305
  312. package/src/components/audio-visualizer/variant-bar.tsx +0 -175
  313. package/src/components/audio-visualizer/variant-custom.tsx +0 -344
  314. package/src/components/audio-visualizer/variant-grid.tsx +0 -175
  315. package/src/components/audio-visualizer/variant-radial.tsx +0 -163
  316. package/src/components/audio-visualizer/variant-wave.tsx +0 -130
  317. package/src/components/audio-visualizer/wave.glsl.ts +0 -130
  318. package/src/components/card-fallback.tsx +0 -60
  319. package/src/components/card-renderer.tsx +0 -220
  320. package/src/components/card.tsx +0 -212
  321. package/src/components/chain-of-thought.tsx +0 -348
  322. package/src/components/chat-container.tsx +0 -89
  323. package/src/components/chat-scope-picker.tsx +0 -57
  324. package/src/components/chat-thread.tsx +0 -518
  325. package/src/components/checkpoint.tsx +0 -88
  326. package/src/components/choice-card.tsx +0 -743
  327. package/src/components/coachmark.tsx +0 -249
  328. package/src/components/code-block.tsx +0 -181
  329. package/src/components/composer-dom.ts +0 -159
  330. package/src/components/composer-highlight.ts +0 -242
  331. package/src/components/composer-history.ts +0 -82
  332. package/src/components/composer.tsx +0 -1075
  333. package/src/components/confirm-card.tsx +0 -402
  334. package/src/components/context.tsx +0 -377
  335. package/src/components/conversation-item.tsx +0 -218
  336. package/src/components/conversation-list.tsx +0 -429
  337. package/src/components/dismissed-stub.tsx +0 -80
  338. package/src/components/embed.tsx +0 -200
  339. package/src/components/empty.tsx +0 -177
  340. package/src/components/feedback-bar.tsx +0 -166
  341. package/src/components/file-tree.tsx +0 -530
  342. package/src/components/file-upload.tsx +0 -167
  343. package/src/components/form-widgets.tsx +0 -525
  344. package/src/components/form.tsx +0 -1296
  345. package/src/components/image.tsx +0 -65
  346. package/src/components/link-preview.tsx +0 -195
  347. package/src/components/loader.tsx +0 -367
  348. package/src/components/markdown.tsx +0 -162
  349. package/src/components/message-skills.tsx +0 -40
  350. package/src/components/message.tsx +0 -765
  351. package/src/components/model-switcher.tsx +0 -132
  352. package/src/components/prompt-input.tsx +0 -188
  353. package/src/components/prompt-suggestion.tsx +0 -150
  354. package/src/components/reasoning.tsx +0 -293
  355. package/src/components/response-compare-types.ts +0 -152
  356. package/src/components/response-compare.tsx +0 -455
  357. package/src/components/response-stream.tsx +0 -109
  358. package/src/components/screen.tsx +0 -181
  359. package/src/components/scroll-button.tsx +0 -93
  360. package/src/components/source.tsx +0 -192
  361. package/src/components/tasks-card.tsx +0 -801
  362. package/src/components/text-shimmer.tsx +0 -37
  363. package/src/components/thinking-bar.tsx +0 -50
  364. package/src/components/thread.tsx +0 -228
  365. package/src/components/toast.tsx +0 -503
  366. package/src/components/tool-classify.ts +0 -26
  367. package/src/components/tool-types.ts +0 -49
  368. package/src/components/tool.tsx +0 -190
  369. package/src/components/use-card-resolution.ts +0 -44
  370. package/src/components/voice-input.tsx +0 -222
  371. package/src/components/voice-output.tsx +0 -242
  372. package/src/components/workspace-shell.tsx +0 -285
  373. package/src/diagnostics/hook.ts +0 -352
  374. package/src/diagnostics/index.ts +0 -82
  375. package/src/diagnostics/report-request.ts +0 -296
  376. package/src/elements/agent-card.tsx +0 -67
  377. package/src/elements/artifact.tsx +0 -194
  378. package/src/elements/attachments.tsx +0 -140
  379. package/src/elements/audio-visualizer.tsx +0 -227
  380. package/src/elements/autoloader.ts +0 -89
  381. package/src/elements/avatar.tsx +0 -33
  382. package/src/elements/badge.tsx +0 -32
  383. package/src/elements/button.tsx +0 -149
  384. package/src/elements/card.tsx +0 -133
  385. package/src/elements/cards.tsx +0 -266
  386. package/src/elements/chain-of-thought.tsx +0 -141
  387. package/src/elements/chat-scope-picker.tsx +0 -65
  388. package/src/elements/chat-types.ts +0 -102
  389. package/src/elements/chat-workspace.tsx +0 -188
  390. package/src/elements/chat.tsx +0 -212
  391. package/src/elements/checkbox-group.tsx +0 -164
  392. package/src/elements/checkbox.tsx +0 -134
  393. package/src/elements/checkpoint.tsx +0 -47
  394. package/src/elements/choice.tsx +0 -100
  395. package/src/elements/coachmark.tsx +0 -90
  396. package/src/elements/code-block.tsx +0 -60
  397. package/src/elements/command.tsx +0 -197
  398. package/src/elements/compare.tsx +0 -111
  399. package/src/elements/compiled.css +0 -2
  400. package/src/elements/composer.tsx +0 -162
  401. package/src/elements/confirm-card.tsx +0 -76
  402. package/src/elements/context-meter.tsx +0 -107
  403. package/src/elements/conversation-item.tsx +0 -120
  404. package/src/elements/conversation-list.tsx +0 -203
  405. package/src/elements/css.ts +0 -5
  406. package/src/elements/default-input.tsx +0 -392
  407. package/src/elements/define-entry.ts +0 -12
  408. package/src/elements/define.tsx +0 -563
  409. package/src/elements/diagnostic-events.ts +0 -114
  410. package/src/elements/dialog.tsx +0 -145
  411. package/src/elements/disclosure.ts +0 -95
  412. package/src/elements/dock.tsx +0 -215
  413. package/src/elements/dropdown.tsx +0 -123
  414. package/src/elements/editable-label.tsx +0 -140
  415. package/src/elements/element-data-types.ts +0 -152
  416. package/src/elements/element-diagnostics.ts +0 -392
  417. package/src/elements/element-manifest.json +0 -354
  418. package/src/elements/element-nonscalar.json +0 -185
  419. package/src/elements/element-types.d.ts +0 -4337
  420. package/src/elements/embed.tsx +0 -35
  421. package/src/elements/empty.tsx +0 -29
  422. package/src/elements/feedback-bar.tsx +0 -66
  423. package/src/elements/file-tree.tsx +0 -62
  424. package/src/elements/file-upload.tsx +0 -44
  425. package/src/elements/form.tsx +0 -94
  426. package/src/elements/hover-card.tsx +0 -80
  427. package/src/elements/icon.tsx +0 -41
  428. package/src/elements/image.tsx +0 -32
  429. package/src/elements/input.tsx +0 -492
  430. package/src/elements/kbd.tsx +0 -45
  431. package/src/elements/link-preview.tsx +0 -34
  432. package/src/elements/loader.tsx +0 -25
  433. package/src/elements/markdown.tsx +0 -38
  434. package/src/elements/menu.tsx +0 -241
  435. package/src/elements/message-skills.tsx +0 -83
  436. package/src/elements/message.tsx +0 -361
  437. package/src/elements/model-switcher.tsx +0 -121
  438. package/src/elements/nav.tsx +0 -87
  439. package/src/elements/notice.tsx +0 -53
  440. package/src/elements/pane-grid.tsx +0 -111
  441. package/src/elements/pane-group.tsx +0 -119
  442. package/src/elements/pane.tsx +0 -129
  443. package/src/elements/popover.tsx +0 -81
  444. package/src/elements/progress-bar.tsx +0 -39
  445. package/src/elements/prompt-dock.tsx +0 -82
  446. package/src/elements/prompt-input.tsx +0 -240
  447. package/src/elements/prompt-suggestions.tsx +0 -113
  448. package/src/elements/radio-group.tsx +0 -129
  449. package/src/elements/reasoning.tsx +0 -71
  450. package/src/elements/register-impl.ts +0 -148
  451. package/src/elements/register.ts +0 -76
  452. package/src/elements/remote.tsx +0 -225
  453. package/src/elements/resizable.globals.d.ts +0 -36
  454. package/src/elements/resizable.tsx +0 -704
  455. package/src/elements/response-stream.tsx +0 -40
  456. package/src/elements/screen.tsx +0 -90
  457. package/src/elements/scroll-area.tsx +0 -33
  458. package/src/elements/scroll-button.tsx +0 -179
  459. package/src/elements/search.tsx +0 -185
  460. package/src/elements/segmented.tsx +0 -129
  461. package/src/elements/select.tsx +0 -165
  462. package/src/elements/separator.tsx +0 -36
  463. package/src/elements/setting-item.tsx +0 -50
  464. package/src/elements/settings-group.tsx +0 -37
  465. package/src/elements/skeleton.tsx +0 -45
  466. package/src/elements/slider.tsx +0 -171
  467. package/src/elements/slot-text.ts +0 -73
  468. package/src/elements/slots.ts +0 -787
  469. package/src/elements/source.tsx +0 -126
  470. package/src/elements/status.tsx +0 -42
  471. package/src/elements/styles.css +0 -328
  472. package/src/elements/switch.tsx +0 -118
  473. package/src/elements/tabs.tsx +0 -95
  474. package/src/elements/tasks.tsx +0 -103
  475. package/src/elements/text-shimmer.tsx +0 -28
  476. package/src/elements/thinking-bar.tsx +0 -43
  477. package/src/elements/thread.tsx +0 -139
  478. package/src/elements/toast.tsx +0 -106
  479. package/src/elements/tool.tsx +0 -78
  480. package/src/elements/tooltip.tsx +0 -85
  481. package/src/elements/validate-messages.ts +0 -76
  482. package/src/elements/voice-input.tsx +0 -100
  483. package/src/elements/voice-output.tsx +0 -82
  484. package/src/index.ts +0 -428
  485. package/src/primitives/audio-bands.ts +0 -174
  486. package/src/primitives/card-component-types.ts +0 -63
  487. package/src/primitives/card-contract.ts +0 -80
  488. package/src/primitives/card-data-types.ts +0 -361
  489. package/src/primitives/card-host.tsx +0 -37
  490. package/src/primitives/card-recovery.ts +0 -160
  491. package/src/primitives/card-registry.tsx +0 -78
  492. package/src/primitives/card-resolution.ts +0 -36
  493. package/src/primitives/card-routing.ts +0 -85
  494. package/src/primitives/card-schemas/artifact.schema.json +0 -92
  495. package/src/primitives/card-schemas/card-envelope.schema.json +0 -14
  496. package/src/primitives/card-schemas/card-event.schema.json +0 -12
  497. package/src/primitives/card-schemas/choice.schema.json +0 -75
  498. package/src/primitives/card-schemas/confirm.schema.json +0 -65
  499. package/src/primitives/card-schemas/embed.schema.json +0 -63
  500. package/src/primitives/card-schemas/form.result.schema.json +0 -7
  501. package/src/primitives/card-schemas/form.schema.json +0 -53
  502. package/src/primitives/card-schemas/link.schema.json +0 -54
  503. package/src/primitives/card-schemas/tasks.result.schema.json +0 -16
  504. package/src/primitives/card-schemas/tasks.schema.json +0 -83
  505. package/src/primitives/card-tags.ts +0 -61
  506. package/src/primitives/card-validate-cards.ts +0 -255
  507. package/src/primitives/card-validate-schemas.ts +0 -58
  508. package/src/primitives/card-validate.ts +0 -131
  509. package/src/primitives/chat-config.tsx +0 -103
  510. package/src/primitives/composer-model.ts +0 -49
  511. package/src/primitives/composer-triggers.ts +0 -35
  512. package/src/primitives/controllable.ts +0 -21
  513. package/src/primitives/create-kai-chat.ts +0 -66
  514. package/src/primitives/create-tween.ts +0 -266
  515. package/src/primitives/embed-providers.ts +0 -254
  516. package/src/primitives/field-mask.ts +0 -256
  517. package/src/primitives/field-semantics.ts +0 -115
  518. package/src/primitives/highlighter.ts +0 -157
  519. package/src/primitives/input-mask.ts +0 -853
  520. package/src/primitives/link-preview.ts +0 -87
  521. package/src/primitives/message-feedback.ts +0 -124
  522. package/src/primitives/pdf-preview.ts +0 -121
  523. package/src/primitives/toast-store.ts +0 -338
  524. package/src/primitives/url-scheme-policy.ts +0 -70
  525. package/src/primitives/use-audio-analysis.ts +0 -340
  526. package/src/primitives/use-auto-resize.ts +0 -31
  527. package/src/primitives/use-resize-observer.ts +0 -45
  528. package/src/primitives/use-sequencer.ts +0 -72
  529. package/src/primitives/use-speech-recognition.ts +0 -146
  530. package/src/primitives/use-stick-to-bottom.ts +0 -75
  531. package/src/primitives/use-text-stream.ts +0 -143
  532. package/src/primitives/use-voice-recorder.ts +0 -62
  533. package/src/primitives/visualizer-sequences.ts +0 -350
  534. package/src/remote/host-embed.ts +0 -345
  535. package/src/remote/index.ts +0 -2
  536. package/src/remote/origin.ts +0 -30
  537. package/src/remote/provider-runtime.ts +0 -262
  538. package/src/remote/provider.ts +0 -2
  539. package/src/remote/validate.ts +0 -22
  540. package/src/remote/version.ts +0 -12
  541. package/src/remote/wire.ts +0 -48
  542. package/src/schemas/from-tool-call.ts +0 -151
  543. package/src/schemas/index.ts +0 -341
  544. package/src/schemas/provider-subsets.ts +0 -538
  545. package/src/schemas/registry.ts +0 -355
  546. package/src/schemas/tool-defs.ts +0 -793
  547. package/src/solid.ts +0 -165
  548. package/src/state/index.ts +0 -44
  549. package/src/state/messages.ts +0 -53
  550. package/src/state/mock.ts +0 -297
  551. package/src/state/parts.ts +0 -295
  552. package/src/state/persistence.ts +0 -180
  553. package/src/state/stream.ts +0 -246
  554. package/src/state/suggestions.ts +0 -9
  555. package/src/state/threads.ts +0 -142
  556. package/src/test-utils/fake-clock.ts +0 -88
  557. package/src/types.ts +0 -53
  558. package/src/ui/action-icons.ts +0 -53
  559. package/src/ui/agent-card.tsx +0 -218
  560. package/src/ui/avatar.tsx +0 -23
  561. package/src/ui/badge.tsx +0 -21
  562. package/src/ui/button.tsx +0 -49
  563. package/src/ui/card.tsx +0 -245
  564. package/src/ui/checkbox-group.tsx +0 -153
  565. package/src/ui/checkbox.tsx +0 -63
  566. package/src/ui/collapsible.tsx +0 -163
  567. package/src/ui/command.tsx +0 -103
  568. package/src/ui/dialog.tsx +0 -223
  569. package/src/ui/dock.tsx +0 -584
  570. package/src/ui/dropdown.tsx +0 -636
  571. package/src/ui/editable-label.tsx +0 -112
  572. package/src/ui/hover-card.tsx +0 -345
  573. package/src/ui/icon.tsx +0 -167
  574. package/src/ui/input.tsx +0 -391
  575. package/src/ui/kbd.tsx +0 -118
  576. package/src/ui/nav.tsx +0 -282
  577. package/src/ui/notice.tsx +0 -84
  578. package/src/ui/overlay.tsx +0 -277
  579. package/src/ui/pane-grid.tsx +0 -117
  580. package/src/ui/pane-group.tsx +0 -291
  581. package/src/ui/pane.tsx +0 -193
  582. package/src/ui/popover.tsx +0 -106
  583. package/src/ui/progress-bar.tsx +0 -83
  584. package/src/ui/prompt-dock.tsx +0 -145
  585. package/src/ui/radio.tsx +0 -150
  586. package/src/ui/resizable.tsx +0 -693
  587. package/src/ui/scroll-area.tsx +0 -26
  588. package/src/ui/segmented.tsx +0 -109
  589. package/src/ui/select.tsx +0 -168
  590. package/src/ui/separator.tsx +0 -10
  591. package/src/ui/settings-group.tsx +0 -67
  592. package/src/ui/skeleton.tsx +0 -73
  593. package/src/ui/slider.tsx +0 -178
  594. package/src/ui/status.tsx +0 -48
  595. package/src/ui/switch.tsx +0 -119
  596. package/src/ui/tabs.tsx +0 -168
  597. package/src/ui/textarea.tsx +0 -21
  598. package/src/ui/tooltip.tsx +0 -118
  599. package/src/utils/cn.ts +0 -30
  600. package/src/wire/chunk.ts +0 -248
  601. package/src/wire/consume.ts +0 -599
  602. package/src/wire/diagnostics.ts +0 -727
  603. package/src/wire/encode-probe.ts +0 -214
  604. package/src/wire/encode.ts +0 -947
  605. package/src/wire/files.ts +0 -342
  606. package/src/wire/formats/anthropic.ts +0 -274
  607. package/src/wire/formats/openai.ts +0 -228
  608. package/src/wire/index.ts +0 -95
  609. package/src/wire/media-types.ts +0 -344
  610. package/src/wire/read.ts +0 -396
  611. package/src/wire/sink-helpers.ts +0 -50
  612. package/src/wire/sse.ts +0 -153
@@ -1,228 +0,0 @@
1
- // OpenAI chat-completions SSE. Also the shape every non-mock integration in the
2
- // kit's catalog re-frames to server-side, so this one decoder covers all nine.
3
- //
4
- // Input is an ALREADY DECODED JSON frame typed `unknown`. Nothing here imports a
5
- // provider SDK, and nothing here throws: a frame this format does not recognise
6
- // yields [] so a provider adding a field cannot take a turn down.
7
- import type { MessageSource } from '../../elements/chat-types';
8
- import type {
9
- ModelStreamChunk,
10
- ModelToolCallDelta,
11
- ModelUsage,
12
- WireFormat,
13
- WireFormatReader,
14
- } from '../chunk';
15
-
16
- function isRecord(v: unknown): v is Record<string, unknown> {
17
- return typeof v === 'object' && v !== null && !Array.isArray(v);
18
- }
19
-
20
- function str(v: unknown): string | undefined {
21
- return typeof v === 'string' ? v : undefined;
22
- }
23
-
24
- function num(v: unknown): number | undefined {
25
- return typeof v === 'number' ? v : undefined;
26
- }
27
-
28
- function usageOf(raw: unknown): ModelUsage | undefined {
29
- if (!isRecord(raw)) return undefined;
30
- const out: ModelUsage = {};
31
- const input = num(raw.prompt_tokens);
32
- if (input !== undefined) out.inputTokens = input;
33
- const output = num(raw.completion_tokens);
34
- if (output !== undefined) out.outputTokens = output;
35
- const total = num(raw.total_tokens);
36
- if (total !== undefined) out.totalTokens = total;
37
- const details = raw.completion_tokens_details;
38
- if (isRecord(details)) {
39
- // The one number that proves reasoning happened even when no reasoning text
40
- // was streamed back.
41
- const reasoning = num(details.reasoning_tokens);
42
- if (reasoning !== undefined) out.reasoningTokens = reasoning;
43
- }
44
- const promptDetails = raw.prompt_tokens_details;
45
- if (isRecord(promptDetails)) {
46
- const cached = num(promptDetails.cached_tokens);
47
- if (cached !== undefined) out.cachedInputTokens = cached;
48
- }
49
- const cost = num(raw.cost);
50
- if (cost !== undefined) out.costUsd = cost;
51
- return Object.keys(out).length > 0 ? out : undefined;
52
- }
53
-
54
- function toolCallDelta(raw: unknown, position: number): ModelToolCallDelta | undefined {
55
- if (!isRecord(raw)) return undefined;
56
- const fn = isRecord(raw.function) ? raw.function : undefined;
57
- const out: ModelToolCallDelta = { index: num(raw.index) ?? position };
58
- const id = str(raw.id);
59
- if (id) out.id = id;
60
- const name = str(fn?.name);
61
- if (name) out.name = name;
62
- const args = str(fn?.arguments);
63
- if (args !== undefined) out.arguments = args;
64
- return out;
65
- }
66
-
67
- /** Sum the READABLE text across reasoning_details entries. Entries with no
68
- * readable text (`reasoning.encrypted`, opaque signed blobs) contribute nothing
69
- * here; they still ride along whole in `reasoningRaw`. */
70
- function detailText(details: unknown[]): string {
71
- let out = '';
72
- for (const d of details) {
73
- if (!isRecord(d)) continue;
74
- const text = str(d.text) ?? str(d.summary);
75
- if (text) out += text;
76
- }
77
- return out;
78
- }
79
-
80
- function detailField(details: unknown[], key: 'index' | 'signature'): unknown {
81
- for (const d of details) {
82
- if (isRecord(d) && d[key] !== undefined) return d[key];
83
- }
84
- return undefined;
85
- }
86
-
87
- /** The sibling reasoning STRINGS, in precedence order. See `applyReasoning`. */
88
- const REASONING_KEYS = ['reasoning', 'reasoning_content'] as const;
89
-
90
- /** First non-empty sibling string wins. These are alternative SPELLINGS of the
91
- * same text, never two halves of it, so this coalesces and never concatenates. */
92
- function siblingReasoning(delta: Record<string, unknown>): string | undefined {
93
- for (const key of REASONING_KEYS) {
94
- const raw = str(delta[key]);
95
- if (raw !== undefined && raw !== '') return raw;
96
- }
97
- return undefined;
98
- }
99
-
100
- /**
101
- * FINDINGS: OpenRouter frequently puts the SAME text in `reasoning` AND in
102
- * `reasoning_details` on the same delta. Concatenating both doubles every
103
- * reasoning token, so `reasoning` wins and details are only a text FALLBACK.
104
- *
105
- * `reasoning_details` is still read in BOTH cases, for `reasoningRaw`, the block
106
- * index and the signature. It is the provider's own block list, and dropping it
107
- * is exactly the Anthropic 400 this entry exists to avoid.
108
- *
109
- * SIBLING NAMES. Chat-completions says nothing about reasoning, so every vendor
110
- * extended it on its own and each parser in the wild reads a different subset:
111
- * `reasoning` is what OpenRouter normalises to, `reasoning_content` is what
112
- * DeepSeek's own API emits and what LiteLLM forwards. Nobody is ahead here and
113
- * there is no canonical spelling. A stream that only ever went through
114
- * OpenRouter never shows the other name, which is the whole reason this one
115
- * stayed invisible: reading `reasoning` alone loses a DeepSeek-direct stream's
116
- * reasoning completely, and silently.
117
- *
118
- * PRECEDENCE. The siblings coalesce, first non-empty wins, and both outrank the
119
- * details text. `reasoning` is checked first, which is what keeps this additive:
120
- * any stream that already carried `reasoning` parses byte for byte as it did
121
- * before, so the order is only observable on a provider that disagrees with
122
- * itself. A gateway that aliases one spelling onto the other sends identical
123
- * text in both, and summing them would double every token exactly the way
124
- * summing `reasoning` and `reasoning_details` does.
125
- *
126
- * SCOPE, and it is NOT a closed class. This covers the NAMING axis only.
127
- * Reasoning on this wire is fragmented three ways STRUCTURALLY: a sibling string
128
- * (here), a block array (`reasoning_details`), and reasoning carried inside a
129
- * polymorphic `content` array. Aliasing bridges names, not shapes. A fourth
130
- * spelling is one entry in REASONING_KEYS; a fourth SHAPE is not, and needs its
131
- * own branch plus its own fixture.
132
- */
133
- function applyReasoning(delta: Record<string, unknown>, out: ModelStreamChunk): void {
134
- const details = Array.isArray(delta.reasoning_details) ? delta.reasoning_details : undefined;
135
- const primary = siblingReasoning(delta);
136
- const fallback = details ? detailText(details) : undefined;
137
- const hasDetails = details !== undefined && details.length > 0;
138
- const text = primary ?? fallback;
139
- if (text === undefined && !hasDetails) return;
140
-
141
- // '' is deliberate and meaningful: an encrypted-only detail entry has no
142
- // readable text but must still produce a reasoning part carrying its payload.
143
- out.reasoning = text ?? '';
144
- if (!hasDetails) return;
145
-
146
- out.reasoningRaw = { source: 'openai.reasoning_details', payload: details };
147
- const index = num(detailField(details, 'index'));
148
- if (index !== undefined) out.reasoningIndex = index;
149
- const signature = str(detailField(details, 'signature'));
150
- if (signature !== undefined) out.reasoningSignature = signature;
151
- }
152
-
153
- function sourcesOf(delta: Record<string, unknown>): MessageSource[] {
154
- if (!Array.isArray(delta.annotations)) return [];
155
- const out: MessageSource[] = [];
156
- for (const a of delta.annotations) {
157
- if (!isRecord(a)) continue;
158
- const citation = isRecord(a.url_citation) ? a.url_citation : undefined;
159
- const url = str(citation?.url);
160
- if (!url) continue;
161
- const source: MessageSource = { url };
162
- const title = str(citation?.title);
163
- if (title) source.title = title;
164
- const snippet = str(citation?.content);
165
- if (snippet) source.snippet = snippet;
166
- out.push(source);
167
- }
168
- return out;
169
- }
170
-
171
- function pushOpenAI(frame: unknown): ModelStreamChunk[] {
172
- if (!isRecord(frame)) return [];
173
- const out: ModelStreamChunk = {};
174
-
175
- const err = frame.error;
176
- if (isRecord(err)) {
177
- const message = str(err.message);
178
- if (message) {
179
- out.error = { message };
180
- const code = err.code;
181
- if (typeof code === 'string' || typeof code === 'number') out.error.code = code;
182
- }
183
- }
184
-
185
- // Stated per frame and reported per frame, no dedupe: a stream that changes
186
- // its mind mid-turn is a finding, and collapsing it would hide one.
187
- const model = str(frame.model);
188
- if (model) out.model = model;
189
-
190
- const usage = usageOf(frame.usage);
191
- if (usage) out.usage = usage;
192
-
193
- const choices = Array.isArray(frame.choices) ? frame.choices : [];
194
- const choice = isRecord(choices[0]) ? choices[0] : undefined;
195
- if (choice) {
196
- const delta = isRecord(choice.delta) ? choice.delta : undefined;
197
- if (delta) {
198
- const content = str(delta.content);
199
- if (content) out.text = content;
200
-
201
- applyReasoning(delta, out);
202
-
203
- if (Array.isArray(delta.tool_calls) && delta.tool_calls.length > 0) {
204
- const calls = delta.tool_calls
205
- .map((raw, i) => toolCallDelta(raw, i))
206
- .filter((c): c is ModelToolCallDelta => c !== undefined);
207
- if (calls.length > 0) out.toolCalls = calls;
208
- }
209
-
210
- const sources = sourcesOf(delta);
211
- if (sources.length > 0) out.sources = sources;
212
- }
213
- const finish = str(choice.finish_reason);
214
- if (finish) out.finishReason = finish;
215
- }
216
-
217
- return Object.keys(out).length > 0 ? [out] : [];
218
- }
219
-
220
- /** Stateless: every frame is self-describing, so `open()` returns a reader with
221
- * no closure state. The interface still calls it per stream, which is what lets
222
- * the stateful Anthropic format use the same seam. */
223
- export const openaiChatFormat: WireFormat = {
224
- id: 'openai.chat-completions',
225
- open(): WireFormatReader {
226
- return { push: pushOpenAI };
227
- },
228
- };
package/src/wire/index.ts DELETED
@@ -1,95 +0,0 @@
1
- // @kitn.ai/ui/wire: the model-stream adapter.
2
- //
3
- // Separate from ./state on purpose. `state` is I/O-free pure functions over
4
- // ChatMessage[]; `wire` touches Response, TextDecoder and byte streams. Keeping
5
- // them apart leaves the bring-your-own-transport consumer at zero cost, and
6
- // gives a future AG-UI format an obvious home. The cost is that importing both
7
- // entries ships state/parts.ts twice, about 2 KB.
8
- //
9
- // The kit PARSES. The consumer FETCHES. There is no client, no key handling and
10
- // no provider SDK anywhere below this file.
11
-
12
- export { readModelStream, readOpenAIStream, readAnthropicStream, WireError } from './read';
13
- export type { StreamSource, ReadOptions } from './read';
14
-
15
- export { consumeModelStream, createToolCallAccumulator } from './consume';
16
- export { applyToolOutput, applyToolFailure, bufferText } from './sink-helpers';
17
-
18
- export { toOpenAIMessages, toAnthropicMessages, WireEncodeError } from './encode';
19
- export type {
20
- AnthropicContentBlock,
21
- AnthropicEncodeOptions,
22
- AnthropicWireMessage,
23
- FileEncodeOptions,
24
- OpenAIContentPart,
25
- OpenAIEncodeOptions,
26
- OpenAIReasoningDetail,
27
- OpenAIToolCall,
28
- OpenAIWireMessage,
29
- UnencodableFilePolicy,
30
- } from './encode';
31
-
32
- // What the encoders CAN represent, published as a value.
33
- //
34
- // The point is not introspection. A consumer who wants their own file picker,
35
- // their own validation and their own error copy can build all three off
36
- // `encodableMediaTypes()` and `resolveMediaPolicy(...).decide(...)` without
37
- // using our composer at all -- the kit states a fact about itself and the
38
- // application decides what to do about it. `<kai-chat accept="...">` is a
39
- // convenience over exactly this, not a separate mechanism.
40
- export { encodableMediaTypes, resolveMediaPolicy } from './media-types';
41
- export type {
42
- EncodableKind,
43
- MediaDecision,
44
- MediaPolicy,
45
- MediaPolicyOptions,
46
- MediaTypeFilter,
47
- } from './media-types';
48
-
49
- export { openaiChatFormat } from './formats/openai';
50
- export { anthropicMessagesFormat } from './formats/anthropic';
51
-
52
- export { sseDataFrames, sseJson, readableToAsyncIterable } from './sse';
53
- export type { ByteSource } from './sse';
54
-
55
- // The diagnostic event stream: metadata about what the pipeline SAW.
56
- //
57
- // Only the subscription and the types are public. `emitWireDiagnostic`,
58
- // `wireDiagnosticsActive` and `nextStreamId` stay internal on purpose -- they
59
- // are the producer side, and a consumer that can forge events or reset the
60
- // stream counter can make a panel lie about a stream that never happened.
61
- export { subscribeWireDiagnostics } from './diagnostics';
62
- export type {
63
- AppRequestEvent,
64
- EncodeAttachmentReport,
65
- EncodeDroppedEvent,
66
- EncodeRequestEvent,
67
- WireCloseEvent,
68
- WireDiagnosticBase,
69
- WireDiagnosticEvent,
70
- WireFailedEvent,
71
- WireFrameEvent,
72
- WireInterruptedEvent,
73
- WireOpenEvent,
74
- WirePartEvent,
75
- } from './diagnostics';
76
-
77
- export { normalizeStopReason } from './chunk';
78
- export type {
79
- AssistantStreamSink,
80
- ConsumeOptions,
81
- ModelStreamChunk,
82
- ModelToolCall,
83
- ModelToolCallDelta,
84
- ModelTurn,
85
- ModelUsage,
86
- StopReason,
87
- WireFormat,
88
- WireFormatReader,
89
- } from './chunk';
90
-
91
- // The content-model types every signature above mentions, re-exported so a
92
- // consumer importing only from '@kitn.ai/ui/wire' can annotate the values these
93
- // functions take and return without a second import.
94
- export type { ChatMessage, MessagePart, MessageSource, RawOrigin } from '../elements/chat-types';
95
- export type { ToolPart } from '../components/tool-types';
@@ -1,344 +0,0 @@
1
- // THE media-type declaration. One table, read by every layer that has an
2
- // opinion about attachments.
3
- //
4
- // WHY THIS FILE EXISTS AT ALL. Two features want the same knowledge: the
5
- // composer needs to know what a user is allowed to stage, and the encoders need
6
- // to know what they can turn into provider content. Those are the same set. When
7
- // each grows its own copy they drift, and the drift is not theoretical -- it is
8
- // the exact defect #186 fixed one layer down, where a composer happily staged a
9
- // `blob:` URL that the encoder could not represent. So the set is declared ONCE,
10
- // here, and both layers derive from it rather than restating it.
11
- //
12
- // THE BOUNDARY THIS DRAWS. The kit owns "what CAN be encoded" -- a fact about
13
- // `encode.ts`, not a policy. The developer owns "what I want to ALLOW", and can
14
- // only ever NARROW the kit's set, never widen it: widening would just move a
15
- // provider 400 later in the request. That asymmetry is why the filter is a
16
- // declarative list rather than a hook, and why `encodableMediaTypes()` is public.
17
- //
18
- // No I/O, like the rest of `wire/`. Pattern matching and, for text, decoding
19
- // base64 that is already inline -- computation over bytes already in hand, never
20
- // a fetch.
21
-
22
- /** What a media type BECOMES on the wire. Named for the Anthropic block set,
23
- * which is the narrower of the two: `text` / `image` / `document` and nothing
24
- * else. There is no arbitrary-file block on either API, which is why a text
25
- * file has to ride as text content and a `.zip` has no representation at all. */
26
- export type EncodableKind = 'image' | 'document' | 'text';
27
-
28
- // WHAT A BROWSER ACTUALLY CALLS A FILE -- ONE OBSERVATION, NOT A STANDING FACT.
29
- //
30
- // Observed 2026-08-13 (UTC), Chrome 151.0.7922.137, macOS 26.5 arm64, with the
31
- // files handed to a real `<input type="file">` so the browser built every `File`
32
- // itself. Re-run it rather than trusting it:
33
- // node scripts/probe-file-media-types.mjs
34
- //
35
- // .txt text/plain .js text/javascript .png image/png
36
- // .md text/markdown .css text/css .zip application/zip
37
- // .csv text/csv .html text/html .pdf application/pdf
38
- // .json application/json .sh text/x-sh
39
- // .xml text/xml .py text/x-python-script
40
- // .yaml application/x-yaml .yml application/x-yaml
41
- // .ts .tsx .rs .go .sql .toml .log -> "" (the browser could not name them)
42
- //
43
- // THESE VALUES ARE PLATFORM-SPECIFIC. Nineteen of the twenty-two match macOS's
44
- // own `preferredMIMEType`, so the browser is answering out of the OS type
45
- // database and Linux and Windows will answer differently. Nothing returned
46
- // `application/octet-stream` -- Chrome's failure mode here is the EMPTY STRING.
47
- // (`.ts` is not a TypeScript file to macOS: it resolves to an MPEG-2
48
- // transport-stream UTI, which carries no MIME string at all, which is why it
49
- // comes back empty rather than as `video/mp2t`.)
50
- //
51
- // EXACTLY TWO THINGS BELOW REST ON THIS TABLE, and both survive it being wrong
52
- // somewhere else:
53
- // 1. `application/x-yaml` is a row because it was measured here. A platform
54
- // that says something else does not make this row wrong, only incomplete.
55
- // 2. Seven of the twenty-two extensions are the ones a developer is likeliest
56
- // to attach to a coding chat, and the browser names NONE of them. That is
57
- // why an unnamed file is decided by DECODING its bytes and never by reading
58
- // its filename -- see `decide()`. Another OS moves WHICH rows come back
59
- // empty; it cannot move the fact that some do.
60
- // Anything else read off this table is being read too hard.
61
-
62
- /**
63
- * ★ THE DECLARATION. Everything else in this file, and both `accept` surfaces,
64
- * are derived from this array. Adding a row teaches the encoder AND widens the
65
- * composer's picker; deleting one narrows both. If you find yourself writing a
66
- * second list of media types anywhere in this repo, delete it and read this.
67
- *
68
- * Patterns are HTML `accept` syntax: an exact type (`image/png`) or a subtype
69
- * wildcard (`text/*`). File EXTENSIONS (`.md`) are deliberately not supported --
70
- * they map to media types only by convention, and guessing is how a `.md` full
71
- * of base64 becomes a 400. An extension in a developer's `accept` THROWS rather
72
- * than matching nothing; a file the browser could not name is settled by
73
- * decoding it. Neither path ever consults a filename.
74
- *
75
- * On the image list: JPEG, PNG, GIF and WebP are the four formats BOTH APIs
76
- * document. SVG and BMP are the ones people actually try, and both are a 400 at
77
- * request time, so they are absent on purpose.
78
- *
79
- * On the text list: `text/*` is the core, because a media type in that tree is
80
- * text by definition of the tree. The `application/` rows are the judgement
81
- * calls -- textual formats that IANA files outside `text/` for historical
82
- * reasons, and that people genuinely attach. `application/json` and
83
- * `application/xml` are the two obvious ones.
84
- *
85
- * On YAML, since it is two rows for one format: `application/x-yaml` is what
86
- * Chrome hands back for a `.yaml` on macOS, MEASURED in the table above.
87
- * `application/yaml` is the IANA-registered type (RFC 9512, 2024) and is what a
88
- * correctly configured server sends, so it is here on REGISTRY grounds rather
89
- * than on a measurement. `text/yaml` and `text/x-yaml` are in the wild too and
90
- * need no row of their own: `text/*` already covers both.
91
- */
92
- const ENCODABLE: readonly { readonly pattern: string; readonly kind: EncodableKind }[] = [
93
- { pattern: 'image/jpeg', kind: 'image' },
94
- { pattern: 'image/png', kind: 'image' },
95
- { pattern: 'image/gif', kind: 'image' },
96
- { pattern: 'image/webp', kind: 'image' },
97
- { pattern: 'application/pdf', kind: 'document' },
98
- { pattern: 'text/*', kind: 'text' },
99
- { pattern: 'application/json', kind: 'text' },
100
- { pattern: 'application/xml', kind: 'text' },
101
- { pattern: 'application/x-yaml', kind: 'text' },
102
- { pattern: 'application/yaml', kind: 'text' },
103
- ];
104
-
105
- /**
106
- * The media type an unnamed file gets once its BYTES have proven to be UTF-8
107
- * text, and the type whose presence in the effective policy is what permits that
108
- * proof to be attempted at all.
109
- *
110
- * `text/plain` is not a guess dressed up as a fact. It is the media type for
111
- * "text, no further structure claimed", which is exactly what a successful
112
- * decode establishes and the most any decode could ever establish. A `.rs` file
113
- * arriving as `text/plain` is true; arriving as `text/x-rust` would be the
114
- * filename talking.
115
- */
116
- export const UNNAMED_TEXT_MEDIA_TYPE = 'text/plain';
117
-
118
- /**
119
- * Media types that say nothing about the bytes they label.
120
- *
121
- * The empty string is what `File.type` is when the OS type database had no
122
- * answer (seven of the twenty-two rows above). `application/octet-stream` is the
123
- * same non-answer written down: RFC 2046 defines it as "arbitrary binary data",
124
- * and it is what `FileReader.readAsDataURL` substitutes for an empty type --
125
- * measured in Chrome 151 AND in the jsdom the unit suite runs on, both of which
126
- * produce `data:application/octet-stream;base64,...` for a `File` whose `type`
127
- * is `''`. So the same typeless file reaches the composer as `''` and reaches
128
- * the encoder as `application/octet-stream`, and both spellings have to mean the
129
- * same thing or the two layers disagree about one file.
130
- */
131
- const NAMES_NOTHING: readonly string[] = ['', 'application/octet-stream'];
132
-
133
- /** A developer's narrowing filter. A comma-separated string (so it works as an
134
- * HTML attribute under the `kai-` contract) or an array (so it composes in JS).
135
- * Both spell the same thing; the string form is what `<kai-chat accept="...">`
136
- * takes and what the `kai` MCP scaffolder can emit as data. */
137
- export type MediaTypeFilter = string | readonly string[];
138
-
139
- /** One media type, decided against the effective set.
140
- *
141
- * `unsupported` and `filtered` are split because the developer needs different
142
- * things from them: `unsupported` means fix your expectations (no API takes
143
- * this), `filtered` means fix your `accept` (the kit could have sent it). */
144
- export type MediaDecision =
145
- | { status: 'allowed'; kind: EncodableKind }
146
- | { status: 'unsupported' }
147
- | { status: 'filtered' }
148
- /**
149
- * Nobody named this file, so its media type cannot decide it. LOOK AT THE
150
- * BYTES: decode them as UTF-8 (`classifyAttachment` does), and it is `text`
151
- * if they decode and unencodable if they do not. Do not look at the filename.
152
- *
153
- * ★ THIS VARIANT IS WHERE THE DEVELOPER'S FILTER IS ENFORCED, so the caller
154
- * cannot get it wrong by forgetting to check. It is returned ONLY when the
155
- * effective policy still admits `text/plain` -- the one thing a decode can
156
- * establish. Narrow `accept` to `image/png` and an unnamed file comes back
157
- * `unsupported` instead, so the decode path is unreachable and a typeless
158
- * `.rs` cannot slip past an images-only filter. That is the whole reason the
159
- * check lives here rather than at each call site: there is one place to get
160
- * right, and the callers physically cannot reach the bytes without being told
161
- * to.
162
- */
163
- | { status: 'undetermined' };
164
-
165
- export interface MediaPolicy {
166
- /** The effective patterns: the kit's capability set narrowed by the
167
- * developer's filter. Never wider than `encodableMediaTypes()`. */
168
- readonly types: readonly string[];
169
- /** The same set as an HTML `accept` attribute value, ready to put on an
170
- * `<input type="file">`. This is what makes the picker and the encoder
171
- * provably one thing rather than two lists that agree today. */
172
- readonly accept: string;
173
- /**
174
- * What this policy makes of one media type, including "I cannot tell from
175
- * this, go and read the bytes" -- see `undetermined`.
176
- *
177
- * The primitive behind "expose information, do not make decisions": it answers
178
- * a question and returns a fact, so a consumer can build their own picker,
179
- * their own validation and their own error copy on top of it without the kit
180
- * deciding anything on their behalf.
181
- */
182
- decide(mediaType: string | undefined): MediaDecision;
183
- }
184
-
185
- export interface MediaPolicyOptions {
186
- /** Narrow the kit's capability set. Omitted means the full set. Anything here
187
- * that the kit cannot encode is dropped rather than honoured, because
188
- * allowing it would only relocate the failure to the provider. */
189
- accept?: MediaTypeFilter;
190
- }
191
-
192
- // NOTE ON WHAT IS DELIBERATELY ABSENT: there is no size cap, no file count, and
193
- // no truncation path here, and their absence is a decision rather than an
194
- // omission. How many bytes to send is a cost decision that lands on the
195
- // consumer's invoice, and a component library that grows a limits engine starts
196
- // making application choices on their behalf. The kit encodes what it is given.
197
- // A developer who wants a ceiling has `File.size` and `decide()` and can enforce
198
- // one in three lines of their own code, where it belongs.
199
-
200
- const normalize = (value: string): string => value.trim().toLowerCase();
201
-
202
- /** Does this media type say anything at all about the bytes it labels? Exported
203
- * so `files.ts` decides "nameless" by the same rule `decide()` does, rather
204
- * than growing a second opinion about which spellings mean "I don't know". */
205
- export const namesNothing = (mediaType: string | undefined): boolean =>
206
- NAMES_NOTHING.includes(mediaType === undefined ? '' : normalize(mediaType));
207
-
208
- /**
209
- * A file EXTENSION in `accept` is a hard error, and the loudness is the point.
210
- *
211
- * HTML's own `accept` takes extensions, the prop is called `accept`, and it is
212
- * documented as HTML `accept` syntax -- so `accept=".py"` is a reasonable thing
213
- * for a developer to write, and it is a trap. Measured on this branch before the
214
- * throw existed: `.py` alone resolved to zero effective types and a picker with
215
- * `accept=""`, a composer that silently accepted NOTHING. `".py,text/plain"` was
216
- * worse, because the half that worked made it read as correct while the `.py`
217
- * vanished without a word.
218
- *
219
- * A silent empty set is the one outcome nobody can debug, so this throws. It is
220
- * safe to throw: no released version of this kit ships the prop, so no existing
221
- * app can be relying on the old silence.
222
- */
223
- const assertMediaType = (entry: string): string => {
224
- if (!entry.startsWith('.')) return entry;
225
- throw new Error(
226
- `\`accept\` entry "${entry}" is a file extension, and this kit takes media types only. ` +
227
- `HTML's own accept attribute does take extensions, which is exactly why this throws rather ` +
228
- `than quietly matching nothing. Use a media type instead -- "text/*" covers source files, ` +
229
- `"image/*" images, "application/pdf" PDFs, and \`encodableMediaTypes()\` is the full set. ` +
230
- `You lose nothing by dropping the extension: a file the browser cannot name is decided by ` +
231
- `decoding its bytes, which is stronger than matching its name.`,
232
- );
233
- };
234
-
235
- const splitFilter = (filter: MediaTypeFilter): string[] =>
236
- (typeof filter === 'string' ? filter.split(',') : filter)
237
- .map(normalize)
238
- .filter((v) => v !== '')
239
- .map(assertMediaType);
240
-
241
- /** `image/png` -> `['image','png']`; `text/*` -> `['text','*']`. */
242
- const parts = (pattern: string): [string, string] => {
243
- const slash = pattern.indexOf('/');
244
- return slash === -1 ? [pattern, ''] : [pattern.slice(0, slash), pattern.slice(slash + 1)];
245
- };
246
-
247
- const matches = (pattern: string, mediaType: string): boolean => {
248
- const [pType, pSub] = parts(pattern);
249
- const [mType, mSub] = parts(mediaType);
250
- if (pType !== '*' && pType !== mType) return false;
251
- return pSub === '*' || pSub === mSub;
252
- };
253
-
254
- /**
255
- * The narrower of two patterns, or `undefined` when they do not overlap.
256
- *
257
- * This is what "narrow, never widen" means mechanically. `accept: 'image/*'`
258
- * against a capability of `image/png` yields `image/png`, not `image/*`: the
259
- * developer asked for images, and the kit's answer is the images it can actually
260
- * send. Conversely `accept: 'text/markdown'` against a capability of `text/*`
261
- * yields `text/markdown`, because there the developer is the narrower one.
262
- */
263
- const intersect = (capability: string, filter: string): string | undefined => {
264
- if (matches(capability, filter)) return filter;
265
- if (matches(filter, capability)) return capability;
266
- return undefined;
267
- };
268
-
269
- /**
270
- * Every media type this kit's encoders can represent, as HTML `accept` patterns.
271
- *
272
- * PUBLIC ON PURPOSE, and not merely for introspection: a consumer who wants
273
- * their own picker, their own validation and their own error copy can build all
274
- * three against this without touching `<kai-chat>` at all. That demotes the
275
- * `accept` prop from "the only door" to a convenience over a published fact,
276
- * which is the composition-first shape this project already committed to.
277
- */
278
- export function encodableMediaTypes(): readonly string[] {
279
- return ENCODABLE.map((entry) => entry.pattern);
280
- }
281
-
282
- /**
283
- * The effective policy: the kit's capability set narrowed by the developer's
284
- * filter, plus the text ceiling.
285
- *
286
- * BOTH LAYERS CALL THIS. The composer calls it to build its picker `accept`
287
- * attribute and to filter what actually gets staged; the encoders call it to
288
- * decide what reaches the wire. That shared call is the whole design -- it is
289
- * why changing `ENCODABLE` above moves the picker and the encoder together
290
- * rather than moving one and leaving the other to be noticed in production.
291
- */
292
- export function resolveMediaPolicy(options: MediaPolicyOptions = {}): MediaPolicy {
293
- const filter = options.accept === undefined ? undefined : splitFilter(options.accept);
294
-
295
- const effective: { pattern: string; kind: EncodableKind }[] = [];
296
- for (const capability of ENCODABLE) {
297
- if (filter === undefined) {
298
- effective.push({ ...capability });
299
- continue;
300
- }
301
- for (const wanted of filter) {
302
- const overlap = intersect(capability.pattern, wanted);
303
- // A capability can overlap several filter entries (`text/*` against
304
- // `text/plain,text/csv`), and each overlap is its own effective pattern.
305
- if (overlap !== undefined && !effective.some((e) => e.pattern === overlap)) {
306
- effective.push({ pattern: overlap, kind: capability.kind });
307
- }
308
- }
309
- }
310
-
311
- return {
312
- types: effective.map((e) => e.pattern),
313
- accept: effective.map((e) => e.pattern).join(','),
314
- decide(mediaType) {
315
- const type = mediaType === undefined ? '' : normalize(mediaType);
316
-
317
- if (namesNothing(type)) {
318
- // Nothing here names the bytes, and the filename is not evidence, so
319
- // the answer is in the bytes themselves -- but only if the developer's
320
- // filter would still take what a decode can prove. See the
321
- // `undetermined` variant: this is the single place that gate exists.
322
- return effective.some((e) => matches(e.pattern, UNNAMED_TEXT_MEDIA_TYPE))
323
- ? { status: 'undetermined' }
324
- : // `unsupported` rather than `filtered`, deliberately: `filtered`
325
- // claims the kit COULD have encoded this file, and nobody has
326
- // established what it is. Unread and unnamed, it is not a text
327
- // file the filter excluded -- it is a file with no known type.
328
- { status: 'unsupported' };
329
- }
330
-
331
- const hit = effective.find((e) => matches(e.pattern, type));
332
- if (hit) return { status: 'allowed', kind: hit.kind };
333
- // Distinguishing these two is the point: one is the kit's limit, the
334
- // other is the developer's own filter looking back at them.
335
- return ENCODABLE.some((e) => matches(e.pattern, type))
336
- ? { status: 'filtered' }
337
- : { status: 'unsupported' };
338
- },
339
- };
340
- }
341
-
342
- /** The policy every caller gets when nobody narrowed anything: the kit's full
343
- * capability set. Built once -- it has no inputs. */
344
- export const DEFAULT_MEDIA_POLICY: MediaPolicy = resolveMediaPolicy();