@kitn.ai/ui 0.28.0 → 0.30.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 (615) hide show
  1. package/README.md +11 -7
  2. package/dist/{Icon-DObhsRtm.js → Icon-BzBET3E-.js} +1 -1
  3. package/dist/{action-icons-CcgNN2oT.js → action-icons-DaW2pU6m.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-D783iMJj.js +1 -0
  7. package/dist/arrow-left-0VLM5kyg.js +1 -0
  8. package/dist/artifact-DGjzHYUT.js +1 -0
  9. package/dist/{attachments-Qr4kg-2b.js → attachments-YvXHlg88.js} +1 -1
  10. package/dist/{audio-visualizer-DToYdfSc.js → audio-visualizer-9lz5IHsL.js} +1 -1
  11. package/dist/{badge-CdEu_jn2.js → badge-Dh_vp8A5.js} +1 -1
  12. package/dist/{bell-DQAAOpDz.js → bell-CT7_WUwS.js} +1 -1
  13. package/dist/{button-DkuOnGLy.js → button-C_3te6fm.js} +1 -1
  14. package/dist/{card-renderer-Jx70m6_l.js → card-renderer-DZVaGH2e.js} +1 -1
  15. package/dist/check-CiEOVnEN.js +1 -0
  16. package/dist/{checkbox-D7iRB3nL.js → checkbox-Bu2T2e0U.js} +1 -1
  17. package/dist/{checkbox-group-B2_rpoPM.js → checkbox-group-BiryEXPQ.js} +1 -1
  18. package/dist/chevron-down-CSobuZRG.js +1 -0
  19. package/dist/chevron-right-DR9ZAP-2.js +1 -0
  20. package/dist/{choice-card-m0BYqqOK.js → choice-card-CM6IjkmL.js} +1 -1
  21. package/dist/circle-BC66EYF7.js +1 -0
  22. package/dist/circle-check-BqmahW0O.js +1 -0
  23. package/dist/{circle-x-BPG0iPst.js → circle-x-Bk-dA5Wf.js} +1 -1
  24. package/dist/{code-block-ClMLKb7C.js → code-block-B26t-Q7q.js} +1 -1
  25. package/dist/{collapsible-B4DlWicL.js → collapsible-Bhc636Cf.js} +1 -1
  26. package/dist/components/builder-composer-triggers.d.ts +62 -0
  27. package/dist/components/builder-layout.d.ts +54 -0
  28. package/dist/components/builder-message-actions.d.ts +72 -0
  29. package/dist/components/builder-panel.d.ts +189 -0
  30. package/dist/components/builder-preview.d.ts +11 -0
  31. package/dist/components/builder-shell-controls.d.ts +69 -0
  32. package/dist/components/builder-skeleton.d.ts +58 -0
  33. package/dist/components/builder-start.d.ts +75 -0
  34. package/dist/components/builder-workspace-variants.d.ts +23 -0
  35. package/dist/components/captions.d.ts +66 -0
  36. package/dist/{composer-sQ0HcvyG.js → composer-DMI85B6j.js} +1 -1
  37. package/dist/{confirm-card-rQWDQsnC.js → confirm-card-B0YIAwXp.js} +1 -1
  38. package/dist/construct-cli.es.js +3 -3
  39. package/dist/construct.d.ts +5 -0
  40. package/dist/construct.js +327 -0
  41. package/dist/{context-0kg4ZX1J.js → context-DWgfhqWp.js} +1 -1
  42. package/dist/controllable-BagRpyHv.js +1 -0
  43. package/dist/{conversation-item-BxwQLaFJ.js → conversation-item-BsOsVGmT.js} +1 -1
  44. package/dist/{conversation-list-BCfGN1JU.js → conversation-list-aX3Vtc7L.js} +1 -1
  45. package/dist/{copy-n9u9rqpi.js → copy-BmEwsNhJ.js} +1 -1
  46. package/dist/core-C8fzo39E.js +1 -12
  47. package/dist/{create-tween-uPkArjIG.js → create-tween-CNOAU3Fx.js} +1 -1
  48. package/dist/{create-tween-C-q-JCM-.js → create-tween-WfqiENls.js} +1 -1
  49. package/dist/{create-tween-CRrJXxBd.js → create-tween-wlFtW9Kh.js} +1 -1
  50. package/dist/{create-tween-DZ3RRDHD.js → create-tween-zt79ba32.js} +1 -1
  51. package/dist/{default-input-CaMrJkgH.js → default-input-DMV5Eaze.js} +1 -1
  52. package/dist/define-CI0y3eE4.js +1 -0
  53. package/dist/define.js +40 -40
  54. package/dist/define.server.js +45 -45
  55. package/dist/{disclosure-WUImBbDv.js → disclosure-NnACBxsC.js} +1 -1
  56. package/dist/{dropdown-wZVeJOMd.js → dropdown-DT7G0RGR.js} +1 -1
  57. package/dist/elements/agent-card.js +1 -1
  58. package/dist/elements/artifact.js +1 -1
  59. package/dist/elements/attachments.js +1 -1
  60. package/dist/elements/audio-visualizer.js +1 -1
  61. package/dist/elements/avatar.js +1 -1
  62. package/dist/elements/badge.js +1 -1
  63. package/dist/elements/button.js +1 -1
  64. package/dist/elements/card.js +1 -1
  65. package/dist/elements/cards.js +1 -1
  66. package/dist/elements/chain-of-thought.js +1 -1
  67. package/dist/elements/chat-scope-picker.js +1 -1
  68. package/dist/elements/chat-workspace.js +1 -1
  69. package/dist/elements/chat.js +1 -1
  70. package/dist/elements/checkbox-group.js +1 -1
  71. package/dist/elements/checkbox.js +1 -1
  72. package/dist/elements/checkpoint.js +1 -1
  73. package/dist/elements/choice.js +1 -1
  74. package/dist/elements/coachmark.js +1 -1
  75. package/dist/elements/code-block.js +1 -1
  76. package/dist/elements/command.js +1 -1
  77. package/dist/elements/compare.js +1 -1
  78. package/dist/elements/composer.js +1 -1
  79. package/dist/elements/confirm-card.js +1 -1
  80. package/dist/elements/context-meter.js +1 -1
  81. package/dist/elements/conversation-item.js +1 -1
  82. package/dist/elements/conversation-list.js +1 -1
  83. package/dist/elements/dialog.js +1 -1
  84. package/dist/elements/dock.js +1 -1
  85. package/dist/elements/dropdown.js +1 -1
  86. package/dist/elements/editable-label.js +1 -1
  87. package/dist/elements/embed.js +1 -1
  88. package/dist/elements/empty.js +1 -1
  89. package/dist/elements/feedback-bar.js +1 -1
  90. package/dist/elements/file-tree.js +1 -1
  91. package/dist/elements/file-upload.js +1 -1
  92. package/dist/elements/form.js +1 -1
  93. package/dist/elements/hover-card.js +1 -1
  94. package/dist/elements/icon.js +1 -1
  95. package/dist/elements/image.js +1 -1
  96. package/dist/elements/input.js +1 -1
  97. package/dist/elements/kbd.js +1 -1
  98. package/dist/elements/link-preview.js +1 -1
  99. package/dist/elements/loader.js +1 -1
  100. package/dist/elements/markdown.js +1 -1
  101. package/dist/elements/menu.js +1 -1
  102. package/dist/elements/message-skills.js +1 -1
  103. package/dist/elements/message.js +1 -1
  104. package/dist/elements/model-switcher.js +1 -1
  105. package/dist/elements/nav.js +1 -1
  106. package/dist/elements/notice.js +1 -1
  107. package/dist/elements/pane-grid.js +1 -1
  108. package/dist/elements/pane-group.js +1 -1
  109. package/dist/elements/pane.js +1 -1
  110. package/dist/elements/popover.js +1 -1
  111. package/dist/elements/progress-bar.js +1 -1
  112. package/dist/elements/prompt-dock.js +1 -1
  113. package/dist/elements/prompt-input.js +1 -1
  114. package/dist/elements/prompt-suggestions.js +1 -1
  115. package/dist/elements/radio-group.js +1 -1
  116. package/dist/elements/reasoning.js +1 -1
  117. package/dist/elements/remote.js +1 -1
  118. package/dist/elements/resizable.js +1 -1
  119. package/dist/elements/response-stream.js +1 -1
  120. package/dist/elements/screen.js +1 -1
  121. package/dist/elements/scroll-area.js +1 -1
  122. package/dist/elements/scroll-button.js +1 -1
  123. package/dist/elements/search.js +1 -1
  124. package/dist/elements/segmented.js +1 -1
  125. package/dist/elements/select.js +1 -1
  126. package/dist/elements/separator.js +1 -1
  127. package/dist/elements/setting-item.js +1 -1
  128. package/dist/elements/settings-group.js +1 -1
  129. package/dist/elements/skeleton.js +1 -1
  130. package/dist/elements/slider.js +1 -1
  131. package/dist/elements/source.js +1 -1
  132. package/dist/elements/status.js +1 -1
  133. package/dist/elements/switch.js +1 -1
  134. package/dist/elements/tabs.js +1 -1
  135. package/dist/elements/tasks.js +1 -1
  136. package/dist/elements/text-shimmer.js +1 -1
  137. package/dist/elements/thinking-bar.js +1 -1
  138. package/dist/elements/thread.js +1 -1
  139. package/dist/elements/toast.js +1 -1
  140. package/dist/elements/tool.js +1 -1
  141. package/dist/elements/tooltip.js +1 -1
  142. package/dist/elements/voice-input.js +1 -1
  143. package/dist/elements/voice-output.js +1 -1
  144. package/dist/{ellipsis-CbOpJnU3.js → ellipsis-6pJ7SxYT.js} +1 -1
  145. package/dist/{embed-CrfjkbUG.js → embed-BMje-nxj.js} +1 -1
  146. package/dist/engine-javascript-C1x7zo1_.js +1 -141
  147. package/dist/{external-link-ByXAwBBQ.js → external-link-Beh9DKeR.js} +1 -1
  148. package/dist/{file-text-DMib2qwt.js → file-text-D1GPfZ8Q.js} +1 -1
  149. package/dist/{file-tree-CJqM2aP7.js → file-tree-Dwj2lqg-.js} +1 -1
  150. package/dist/{folder-_BAb929C.js → folder-b6D8x1DY.js} +1 -1
  151. package/dist/{form-DSZgZQZk.js → form-DWgdxDXu.js} +1 -1
  152. package/dist/{hover-card-BQbul9eq.js → hover-card-CWRkqm40.js} +1 -1
  153. package/dist/{icon-CdcfRhYI.js → icon-CL0jdhsf.js} +1 -1
  154. package/dist/index.js +1741 -1725
  155. package/dist/index.server.js +1582 -1566
  156. package/dist/{info-DsFjGuI_.js → info-0cOUherQ.js} +1 -1
  157. package/dist/{input-DKbmkMos.js → input-BH6Ru91Q.js} +1 -1
  158. package/dist/kai.es.js +1 -1
  159. package/dist/{kbd-PvdGhX4s.js → kbd-DRAnVtNX.js} +1 -1
  160. package/dist/{link-zF8PzWfF.js → link-Dlr0vssB.js} +1 -1
  161. package/dist/{link-preview-DbM1866N.js → link-preview-DODgRyV9.js} +1 -1
  162. package/dist/loader-KvJB6NrT.js +1 -0
  163. package/dist/{markdown-LMvmAyBk.js → markdown-DX9tuJVj.js} +1 -1
  164. package/dist/mcp.es.js +9 -5
  165. package/dist/{message-BYZECyek.js → message-BqQ7Ot5q.js} +1 -1
  166. package/dist/{message-BSsgvHvf.js → message-DkaGfBd8.js} +1 -1
  167. package/dist/message-circle-BPpp5QKv.js +1 -0
  168. package/dist/message-square-BLbsd9BJ.js +1 -0
  169. package/dist/{minimize-2-BQRoBV1V.js → minimize-2-CyOHJwcN.js} +1 -1
  170. package/dist/{model-switcher-CMpCOYcB.js → model-switcher-0hrKDiK2.js} +1 -1
  171. package/dist/{overlay-Cb-MkyDa.js → overlay-DBMFXie6.js} +1 -1
  172. package/dist/{panel-right-i8warFxT.js → panel-right-t8SWJL6e.js} +1 -1
  173. package/dist/{paperclip-ByY3UVO6.js → paperclip-CdzuOjbU.js} +1 -1
  174. package/dist/play-BXy1u7rW.js +1 -0
  175. package/dist/primitives/use-auto-resize.d.ts +11 -0
  176. package/dist/{progress-bar-jVAHvMUf.js → progress-bar-CiBtxMWT.js} +1 -1
  177. package/dist/{prompt-suggestion-CD-qtNgC.js → prompt-suggestion-I_DHP21i.js} +1 -1
  178. package/dist/{radio-BsoBMhkF.js → radio-C_p3n39l.js} +1 -1
  179. package/dist/{reasoning-4kBPtlTx.js → reasoning-BDwy_tIe.js} +1 -1
  180. package/dist/register-impl-DvEnhIxx.js +424 -0
  181. package/dist/{resizable-uPmY9VY-.js → resizable-SYC-fStM.js} +1 -1
  182. package/dist/{rotate-ccw-B2xn93py.js → rotate-ccw-B1nwmwuY.js} +1 -1
  183. package/dist/{rotate-cw-CMVLoCyH.js → rotate-cw-CLAnBcm1.js} +1 -1
  184. package/dist/{scroll-area-BqLUo8ZZ.js → scroll-area-zRyXoLhI.js} +1 -1
  185. package/dist/{scroll-button-DslXiJyL.js → scroll-button-jzrbYCG9.js} +1 -1
  186. package/dist/{select-2cLRtPGT.js → select-DM-0nEe0.js} +1 -1
  187. package/dist/{separator-BWQtNJcM.js → separator-BToOOoOt.js} +1 -1
  188. package/dist/{settings-BBR63jLg.js → settings-PaGo_S4U.js} +1 -1
  189. package/dist/{settings-group-B2ciy-Iw.js → settings-group-BFXGIfXq.js} +1 -1
  190. package/dist/{skeleton-CkHI-HgC.js → skeleton-DYpmFnnm.js} +1 -1
  191. package/dist/{slider-DDR9U-i0.js → slider-ebutAmkQ.js} +1 -1
  192. package/dist/{solid-DruVOXnf.js → solid-15v_3WVL.js} +3563 -3412
  193. package/dist/{solid-BzCFdL25.js → solid-5P-otgdi.js} +4502 -4296
  194. package/dist/solid.d.ts +6 -0
  195. package/dist/solid.js +259 -254
  196. package/dist/solid.server.js +259 -254
  197. package/dist/{source-GEnFF528.js → source-c1gpRl9h.js} +1 -1
  198. package/dist/{star-CilHq8GP.js → star-pcV_3LqF.js} +1 -1
  199. package/dist/{store-Ciyk6eZG.js → store-CSgbFFCg.js} +1 -1
  200. package/dist/{switch-KkeQIbuH.js → switch-Bh2OdLV2.js} +1 -1
  201. package/dist/{tasks-card-BrN4bggJ.js → tasks-card-CbqQAn2S.js} +1 -1
  202. package/dist/text-shimmer-BSzgEnDH.js +1 -0
  203. package/dist/textarea-DrYNt_0z.js +1 -0
  204. package/dist/theme.tokens.css +22 -21
  205. package/dist/{thumbs-up-CsT9Wzb9.js → thumbs-up-BL3-NenK.js} +1 -1
  206. package/dist/{toast-store-tgK6MuMv.js → toast-store-DkOlYczt.js} +1 -1
  207. package/dist/{tool-DzUjIBT8.js → tool-CeIWUVUe.js} +1 -1
  208. package/dist/{tooltip-Bkkg_4t0.js → tooltip-GA-nmg06.js} +1 -1
  209. package/dist/{trash-2-jBKxjGGQ.js → trash-2-CT66QWlm.js} +1 -1
  210. package/dist/{triangle-alert-DlQ68ppf.js → triangle-alert-CeHLWxhD.js} +1 -1
  211. package/dist/ui/color-field.d.ts +48 -0
  212. package/dist/ui/textarea.d.ts +4 -0
  213. package/dist/ui/toggle-chip.d.ts +40 -0
  214. package/dist/{upload-TcAHXv9W.js → upload-9Csb0F0J.js} +1 -1
  215. package/dist/{use-card-resolution-DaZqAdWf.js → use-card-resolution-Zg0a08Z-.js} +1 -1
  216. package/dist/{variant-aurora-DbW_OWL2.js → variant-aurora-4VBQHIKV.js} +1 -1
  217. package/dist/{variant-aurora-CNmfHhcx.js → variant-aurora-DBeCAQNk.js} +2 -2
  218. package/dist/{variant-aurora-D6GsdTPA.js → variant-aurora-FzHVXHby.js} +2 -2
  219. package/dist/{variant-aurora-BhLuYxJR.js → variant-aurora-LE3fqxgw.js} +1 -1
  220. package/dist/{variant-custom-BvYHR62b.js → variant-custom-AFRGcOBS.js} +1 -1
  221. package/dist/{variant-custom-DV2x254s.js → variant-custom-BQkNuPpE.js} +2 -2
  222. package/dist/{variant-custom-BRvaNHSi.js → variant-custom-DI5R0rln.js} +1 -1
  223. package/dist/{variant-custom-DMTrEO5w.js → variant-custom-WWnrrRHS.js} +2 -2
  224. package/dist/{variant-wave-CyBueXj9.js → variant-wave-DUCbH5oI.js} +2 -2
  225. package/dist/{variant-wave-BNMGrDfj.js → variant-wave-DuQV7DhQ.js} +2 -2
  226. package/dist/{variant-wave-BpDd8t3Z.js → variant-wave-nSI2sfII.js} +1 -1
  227. package/dist/{variant-wave-sp-qwsdI.js → variant-wave-wTP5v_jU.js} +1 -1
  228. package/dist/x-eiO9V6J6.js +1 -0
  229. package/{src/elements/styles.css → kit-base.css} +27 -44
  230. package/package.json +32 -17
  231. package/solid.css +33 -0
  232. package/theme.css +39 -23
  233. package/bin/route.test.js +0 -58
  234. package/dist/arrow-down-CjRU3JgV.js +0 -1
  235. package/dist/arrow-left-Bnpb1UEW.js +0 -1
  236. package/dist/artifact-Bwt7OgcR.js +0 -1
  237. package/dist/check-njkVdZu2.js +0 -1
  238. package/dist/chevron-down-B72s6PXR.js +0 -1
  239. package/dist/chevron-right-BatuHzUm.js +0 -1
  240. package/dist/circle-check-B62pODB3.js +0 -1
  241. package/dist/circle-zx0ByzY9.js +0 -1
  242. package/dist/controllable-CnGpMF6r.js +0 -1
  243. package/dist/define-By-uL588.js +0 -1
  244. package/dist/loader-BM4CEz4G.js +0 -1
  245. package/dist/message-circle-DruwObfX.js +0 -1
  246. package/dist/message-square-BG6q6mlm.js +0 -1
  247. package/dist/play-BvKKq3fX.js +0 -1
  248. package/dist/register-impl-B1hLkrI8.js +0 -424
  249. package/dist/text-shimmer-Dcj1MHuq.js +0 -1
  250. package/dist/textarea-Dpvbngbg.js +0 -1
  251. package/dist/x-Z5UntkIJ.js +0 -1
  252. package/src/agent-tooling/README.md +0 -192
  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 -147
  263. package/src/agent-tooling/construct/codegen.ts +0 -1635
  264. package/src/agent-tooling/construct/construct.v1.schema.json +0 -319
  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 -32
  269. package/src/agent-tooling/construct/schema.ts +0 -452
  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 -1014
  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 -241
  336. package/src/components/conversation-list.tsx +0 -429
  337. package/src/components/conversation-panel.tsx +0 -118
  338. package/src/components/dismissed-stub.tsx +0 -80
  339. package/src/components/embed.tsx +0 -200
  340. package/src/components/empty.tsx +0 -177
  341. package/src/components/feedback-bar.tsx +0 -166
  342. package/src/components/file-tree.tsx +0 -530
  343. package/src/components/file-upload.tsx +0 -167
  344. package/src/components/form-widgets.tsx +0 -525
  345. package/src/components/form.tsx +0 -1296
  346. package/src/components/home-panel.tsx +0 -159
  347. package/src/components/image.tsx +0 -65
  348. package/src/components/link-preview.tsx +0 -195
  349. package/src/components/loader.tsx +0 -367
  350. package/src/components/markdown.tsx +0 -162
  351. package/src/components/message-skills.tsx +0 -40
  352. package/src/components/message.tsx +0 -765
  353. package/src/components/model-switcher.tsx +0 -132
  354. package/src/components/prompt-input.tsx +0 -188
  355. package/src/components/prompt-suggestion.tsx +0 -150
  356. package/src/components/reasoning.tsx +0 -293
  357. package/src/components/response-compare-types.ts +0 -152
  358. package/src/components/response-compare.tsx +0 -455
  359. package/src/components/response-stream.tsx +0 -109
  360. package/src/components/screen.tsx +0 -181
  361. package/src/components/scroll-button.tsx +0 -93
  362. package/src/components/source.tsx +0 -192
  363. package/src/components/tasks-card.tsx +0 -801
  364. package/src/components/text-shimmer.tsx +0 -37
  365. package/src/components/thinking-bar.tsx +0 -50
  366. package/src/components/thread.tsx +0 -228
  367. package/src/components/toast.tsx +0 -503
  368. package/src/components/tool-classify.ts +0 -26
  369. package/src/components/tool-types.ts +0 -49
  370. package/src/components/tool.tsx +0 -190
  371. package/src/components/use-card-resolution.ts +0 -44
  372. package/src/components/voice-input.tsx +0 -222
  373. package/src/components/voice-output.tsx +0 -242
  374. package/src/components/widget-tab-bar.tsx +0 -73
  375. package/src/components/workspace-shell.tsx +0 -285
  376. package/src/diagnostics/hook.ts +0 -352
  377. package/src/diagnostics/index.ts +0 -82
  378. package/src/diagnostics/report-request.ts +0 -296
  379. package/src/elements/agent-card.tsx +0 -67
  380. package/src/elements/artifact.tsx +0 -194
  381. package/src/elements/attachments.tsx +0 -140
  382. package/src/elements/audio-visualizer.tsx +0 -227
  383. package/src/elements/autoloader.ts +0 -89
  384. package/src/elements/avatar.tsx +0 -33
  385. package/src/elements/badge.tsx +0 -32
  386. package/src/elements/button.tsx +0 -149
  387. package/src/elements/card.tsx +0 -133
  388. package/src/elements/cards.tsx +0 -266
  389. package/src/elements/chain-of-thought.tsx +0 -141
  390. package/src/elements/chat-scope-picker.tsx +0 -65
  391. package/src/elements/chat-types.ts +0 -102
  392. package/src/elements/chat-workspace.tsx +0 -188
  393. package/src/elements/chat.tsx +0 -304
  394. package/src/elements/checkbox-group.tsx +0 -164
  395. package/src/elements/checkbox.tsx +0 -134
  396. package/src/elements/checkpoint.tsx +0 -47
  397. package/src/elements/choice.tsx +0 -100
  398. package/src/elements/coachmark.tsx +0 -90
  399. package/src/elements/code-block.tsx +0 -60
  400. package/src/elements/command.tsx +0 -197
  401. package/src/elements/compare.tsx +0 -111
  402. package/src/elements/compiled.css +0 -2
  403. package/src/elements/composer.tsx +0 -162
  404. package/src/elements/confirm-card.tsx +0 -76
  405. package/src/elements/context-meter.tsx +0 -107
  406. package/src/elements/conversation-item.tsx +0 -120
  407. package/src/elements/conversation-list.tsx +0 -203
  408. package/src/elements/css.ts +0 -5
  409. package/src/elements/default-input.tsx +0 -392
  410. package/src/elements/define-entry.ts +0 -12
  411. package/src/elements/define.tsx +0 -563
  412. package/src/elements/diagnostic-events.ts +0 -114
  413. package/src/elements/dialog.tsx +0 -145
  414. package/src/elements/disclosure.ts +0 -95
  415. package/src/elements/dock.tsx +0 -215
  416. package/src/elements/dropdown.tsx +0 -123
  417. package/src/elements/editable-label.tsx +0 -140
  418. package/src/elements/element-data-types.ts +0 -152
  419. package/src/elements/element-diagnostics.ts +0 -392
  420. package/src/elements/element-manifest.json +0 -354
  421. package/src/elements/element-nonscalar.json +0 -187
  422. package/src/elements/element-types.d.ts +0 -4353
  423. package/src/elements/embed.tsx +0 -35
  424. package/src/elements/empty.tsx +0 -29
  425. package/src/elements/feedback-bar.tsx +0 -66
  426. package/src/elements/file-tree.tsx +0 -62
  427. package/src/elements/file-upload.tsx +0 -44
  428. package/src/elements/form.tsx +0 -94
  429. package/src/elements/hover-card.tsx +0 -80
  430. package/src/elements/icon.tsx +0 -41
  431. package/src/elements/image.tsx +0 -32
  432. package/src/elements/input.tsx +0 -492
  433. package/src/elements/kbd.tsx +0 -45
  434. package/src/elements/link-preview.tsx +0 -34
  435. package/src/elements/loader.tsx +0 -25
  436. package/src/elements/markdown.tsx +0 -38
  437. package/src/elements/menu.tsx +0 -241
  438. package/src/elements/message-skills.tsx +0 -83
  439. package/src/elements/message.tsx +0 -361
  440. package/src/elements/model-switcher.tsx +0 -121
  441. package/src/elements/nav.tsx +0 -87
  442. package/src/elements/notice.tsx +0 -53
  443. package/src/elements/pane-grid.tsx +0 -111
  444. package/src/elements/pane-group.tsx +0 -119
  445. package/src/elements/pane.tsx +0 -129
  446. package/src/elements/popover.tsx +0 -81
  447. package/src/elements/progress-bar.tsx +0 -39
  448. package/src/elements/prompt-dock.tsx +0 -82
  449. package/src/elements/prompt-input.tsx +0 -240
  450. package/src/elements/prompt-suggestions.tsx +0 -113
  451. package/src/elements/radio-group.tsx +0 -129
  452. package/src/elements/reasoning.tsx +0 -71
  453. package/src/elements/register-impl.ts +0 -148
  454. package/src/elements/register.ts +0 -76
  455. package/src/elements/remote.tsx +0 -225
  456. package/src/elements/resizable.globals.d.ts +0 -36
  457. package/src/elements/resizable.tsx +0 -704
  458. package/src/elements/response-stream.tsx +0 -40
  459. package/src/elements/screen.tsx +0 -90
  460. package/src/elements/scroll-area.tsx +0 -33
  461. package/src/elements/scroll-button.tsx +0 -179
  462. package/src/elements/search.tsx +0 -185
  463. package/src/elements/segmented.tsx +0 -129
  464. package/src/elements/select.tsx +0 -165
  465. package/src/elements/separator.tsx +0 -36
  466. package/src/elements/setting-item.tsx +0 -50
  467. package/src/elements/settings-group.tsx +0 -37
  468. package/src/elements/skeleton.tsx +0 -45
  469. package/src/elements/slider.tsx +0 -171
  470. package/src/elements/slot-text.ts +0 -73
  471. package/src/elements/slots.ts +0 -787
  472. package/src/elements/source.tsx +0 -126
  473. package/src/elements/status.tsx +0 -42
  474. package/src/elements/switch.tsx +0 -118
  475. package/src/elements/tabs.tsx +0 -95
  476. package/src/elements/tasks.tsx +0 -103
  477. package/src/elements/text-shimmer.tsx +0 -28
  478. package/src/elements/thinking-bar.tsx +0 -43
  479. package/src/elements/thread.tsx +0 -139
  480. package/src/elements/toast.tsx +0 -106
  481. package/src/elements/tool.tsx +0 -78
  482. package/src/elements/tooltip.tsx +0 -85
  483. package/src/elements/validate-messages.ts +0 -76
  484. package/src/elements/voice-input.tsx +0 -100
  485. package/src/elements/voice-output.tsx +0 -82
  486. package/src/index.ts +0 -430
  487. package/src/primitives/audio-bands.ts +0 -174
  488. package/src/primitives/card-component-types.ts +0 -63
  489. package/src/primitives/card-contract.ts +0 -80
  490. package/src/primitives/card-data-types.ts +0 -361
  491. package/src/primitives/card-host.tsx +0 -37
  492. package/src/primitives/card-recovery.ts +0 -160
  493. package/src/primitives/card-registry.tsx +0 -78
  494. package/src/primitives/card-resolution.ts +0 -36
  495. package/src/primitives/card-routing.ts +0 -85
  496. package/src/primitives/card-schemas/artifact.schema.json +0 -92
  497. package/src/primitives/card-schemas/card-envelope.schema.json +0 -14
  498. package/src/primitives/card-schemas/card-event.schema.json +0 -12
  499. package/src/primitives/card-schemas/choice.schema.json +0 -75
  500. package/src/primitives/card-schemas/confirm.schema.json +0 -65
  501. package/src/primitives/card-schemas/embed.schema.json +0 -63
  502. package/src/primitives/card-schemas/form.result.schema.json +0 -7
  503. package/src/primitives/card-schemas/form.schema.json +0 -53
  504. package/src/primitives/card-schemas/link.schema.json +0 -54
  505. package/src/primitives/card-schemas/tasks.result.schema.json +0 -16
  506. package/src/primitives/card-schemas/tasks.schema.json +0 -83
  507. package/src/primitives/card-tags.ts +0 -61
  508. package/src/primitives/card-validate-cards.ts +0 -255
  509. package/src/primitives/card-validate-schemas.ts +0 -58
  510. package/src/primitives/card-validate.ts +0 -131
  511. package/src/primitives/chat-config.tsx +0 -103
  512. package/src/primitives/composer-model.ts +0 -49
  513. package/src/primitives/composer-triggers.ts +0 -35
  514. package/src/primitives/controllable.ts +0 -21
  515. package/src/primitives/conversation-store.ts +0 -248
  516. package/src/primitives/create-kai-chat.ts +0 -66
  517. package/src/primitives/create-tween.ts +0 -266
  518. package/src/primitives/embed-providers.ts +0 -254
  519. package/src/primitives/field-mask.ts +0 -256
  520. package/src/primitives/field-semantics.ts +0 -115
  521. package/src/primitives/highlighter.ts +0 -157
  522. package/src/primitives/input-mask.ts +0 -853
  523. package/src/primitives/link-preview.ts +0 -87
  524. package/src/primitives/message-feedback.ts +0 -124
  525. package/src/primitives/pdf-preview.ts +0 -121
  526. package/src/primitives/toast-store.ts +0 -338
  527. package/src/primitives/url-scheme-policy.ts +0 -70
  528. package/src/primitives/use-audio-analysis.ts +0 -340
  529. package/src/primitives/use-auto-resize.ts +0 -31
  530. package/src/primitives/use-resize-observer.ts +0 -45
  531. package/src/primitives/use-sequencer.ts +0 -72
  532. package/src/primitives/use-speech-recognition.ts +0 -146
  533. package/src/primitives/use-stick-to-bottom.ts +0 -75
  534. package/src/primitives/use-text-stream.ts +0 -143
  535. package/src/primitives/use-voice-recorder.ts +0 -62
  536. package/src/primitives/visualizer-sequences.ts +0 -350
  537. package/src/remote/host-embed.ts +0 -345
  538. package/src/remote/index.ts +0 -2
  539. package/src/remote/origin.ts +0 -30
  540. package/src/remote/provider-runtime.ts +0 -262
  541. package/src/remote/provider.ts +0 -2
  542. package/src/remote/validate.ts +0 -22
  543. package/src/remote/version.ts +0 -12
  544. package/src/remote/wire.ts +0 -48
  545. package/src/schemas/from-tool-call.ts +0 -151
  546. package/src/schemas/index.ts +0 -341
  547. package/src/schemas/provider-subsets.ts +0 -538
  548. package/src/schemas/registry.ts +0 -355
  549. package/src/schemas/tool-defs.ts +0 -793
  550. package/src/solid.ts +0 -173
  551. package/src/state/index.ts +0 -44
  552. package/src/state/messages.ts +0 -53
  553. package/src/state/mock.ts +0 -297
  554. package/src/state/parts.ts +0 -295
  555. package/src/state/persistence.ts +0 -180
  556. package/src/state/stream.ts +0 -246
  557. package/src/state/suggestions.ts +0 -9
  558. package/src/state/threads.ts +0 -142
  559. package/src/test-utils/fake-clock.ts +0 -88
  560. package/src/types.ts +0 -95
  561. package/src/ui/action-icons.ts +0 -53
  562. package/src/ui/agent-card.tsx +0 -218
  563. package/src/ui/avatar.tsx +0 -23
  564. package/src/ui/badge.tsx +0 -21
  565. package/src/ui/button.tsx +0 -49
  566. package/src/ui/card.tsx +0 -245
  567. package/src/ui/checkbox-group.tsx +0 -153
  568. package/src/ui/checkbox.tsx +0 -63
  569. package/src/ui/collapsible.tsx +0 -163
  570. package/src/ui/command.tsx +0 -103
  571. package/src/ui/dialog.tsx +0 -223
  572. package/src/ui/dock.tsx +0 -630
  573. package/src/ui/dropdown.tsx +0 -636
  574. package/src/ui/editable-label.tsx +0 -112
  575. package/src/ui/hover-card.tsx +0 -345
  576. package/src/ui/icon.tsx +0 -167
  577. package/src/ui/input.tsx +0 -391
  578. package/src/ui/kbd.tsx +0 -118
  579. package/src/ui/nav.tsx +0 -282
  580. package/src/ui/notice.tsx +0 -84
  581. package/src/ui/overlay.tsx +0 -277
  582. package/src/ui/pane-grid.tsx +0 -117
  583. package/src/ui/pane-group.tsx +0 -291
  584. package/src/ui/pane.tsx +0 -193
  585. package/src/ui/popover.tsx +0 -106
  586. package/src/ui/progress-bar.tsx +0 -83
  587. package/src/ui/prompt-dock.tsx +0 -145
  588. package/src/ui/radio.tsx +0 -150
  589. package/src/ui/resizable.tsx +0 -693
  590. package/src/ui/scroll-area.tsx +0 -26
  591. package/src/ui/segmented.tsx +0 -109
  592. package/src/ui/select.tsx +0 -168
  593. package/src/ui/separator.tsx +0 -10
  594. package/src/ui/settings-group.tsx +0 -67
  595. package/src/ui/skeleton.tsx +0 -73
  596. package/src/ui/slider.tsx +0 -178
  597. package/src/ui/status.tsx +0 -48
  598. package/src/ui/switch.tsx +0 -119
  599. package/src/ui/tabs.tsx +0 -168
  600. package/src/ui/textarea.tsx +0 -21
  601. package/src/ui/tooltip.tsx +0 -118
  602. package/src/utils/cn.ts +0 -30
  603. package/src/wire/chunk.ts +0 -248
  604. package/src/wire/consume.ts +0 -599
  605. package/src/wire/diagnostics.ts +0 -727
  606. package/src/wire/encode-probe.ts +0 -214
  607. package/src/wire/encode.ts +0 -947
  608. package/src/wire/files.ts +0 -342
  609. package/src/wire/formats/anthropic.ts +0 -274
  610. package/src/wire/formats/openai.ts +0 -228
  611. package/src/wire/index.ts +0 -95
  612. package/src/wire/media-types.ts +0 -344
  613. package/src/wire/read.ts +0 -396
  614. package/src/wire/sink-helpers.ts +0 -50
  615. package/src/wire/sse.ts +0 -153
@@ -1,442 +0,0 @@
1
- import type { Integration } from '../types';
2
-
3
- /**
4
- * Anthropic Messages, and NOT a copy of the OpenRouter route.
5
- *
6
- * Four constraints established by live testing and recorded in
7
- * docs/superpowers/HANDOFF-model-driven-components.md §4. Every one of them is a
8
- * 400 (or worse, a silent 200) if you port an OpenAI-shaped body over verbatim:
9
- *
10
- * 1. `system` is a TOP-LEVEL field. A `{ role: 'system' }` entry in `messages`
11
- * is rejected.
12
- * 2. `tool_choice` is an OBJECT, never the bare string OpenAI accepts.
13
- * 3. `max_tokens` is REQUIRED. OpenAI defaults it; this API does not.
14
- * 4. Content blocks stream strictly sequentially and are indexed by CONTENT
15
- * BLOCK, so a thinking block pushes a tool call from block 0 to block 1.
16
- * OpenAI's `tool_calls[].index` counts TOOL CALLS, so the two indices are
17
- * not the same number and passing one through as the other is the original
18
- * Critical.
19
- *
20
- * The thinking constraint in that document has since MOVED, and the route says
21
- * so rather than repeating it: `budget_tokens` is not a tunable with a floor of
22
- * 1024 any more, it is REMOVED from the current models and returns a 400. See
23
- * the block comment beside `thinking` in the emitted body.
24
- */
25
- const anthropic: Integration = {
26
- id: 'anthropic',
27
- title: 'Anthropic',
28
- category: 'provider',
29
- language: 'ts',
30
- // 'native': the Messages API streams its OWN SSE dialect (message_start,
31
- // content_block_delta, message_stop), not OpenAI's. The route re-frames it —
32
- // see `reframeToOpenAISse` and the note in streamMapping for why.
33
- streamFormat: 'native',
34
- envVars: ['ANTHROPIC_API_KEY'],
35
- // No per-framework templates: the handler below is web-standard, so the
36
- // scaffolder wraps it in whatever the target framework routes with.
37
- routeTemplates: {},
38
- webRoute: `/** Where an image or document's bytes come from. Anthropic takes both forms
39
- * for both block types, which is why this route has no gap where the
40
- * OpenAI-shaped one does: a chat-completions \`file\` part is base64-only. */
41
- type AnthropicSource =
42
- | { type: 'base64'; media_type: string; data: string }
43
- | { type: 'url'; url: string };
44
-
45
- /** One Anthropic content block. Open union on the wire; these are the ones the
46
- * scaffold's own thread can produce. */
47
- type AnthropicBlock =
48
- | { type: 'text'; text: string }
49
- | { type: 'image'; source: AnthropicSource }
50
- | { type: 'document'; source: AnthropicSource }
51
- | { type: 'tool_use'; id: string; name: string; input: unknown }
52
- | { type: 'tool_result'; tool_use_id: string; content: string };
53
-
54
- /** Anthropic messages carry ONLY 'user' and 'assistant'. There is no 'system'
55
- * role here and no 'tool' role: a system prompt is a top-level field, and a
56
- * tool RESULT rides on a user message. Both are handled in toAnthropicBody. */
57
- type AnthropicMessage = { role: 'user' | 'assistant'; content: AnthropicBlock[] };
58
-
59
- /** Anthropic calls the JSON Schema \`input_schema\`; OpenAI calls it
60
- * \`parameters\`, and nests everything under \`function\`. Handing the OpenAI
61
- * shape over unconverted is a 400. */
62
- type AnthropicTool = { name: string; description?: string; input_schema: unknown };
63
-
64
- /** The OpenAI tool shape the front end sends, narrowed from \`unknown[]\`. */
65
- type OpenAIFunctionTool = {
66
- function?: { name?: string; description?: string; parameters?: unknown };
67
- };
68
-
69
- /** One decoded Messages-API SSE frame. Every field is optional because this is
70
- * a provider-owned union and an unrecognised frame must be skipped, not throw. */
71
- type AnthropicEvent = {
72
- type?: string;
73
- index?: number;
74
- content_block?: { type?: string; id?: string; name?: string };
75
- delta?: {
76
- type?: string;
77
- text?: string;
78
- thinking?: string;
79
- partial_json?: string;
80
- stop_reason?: string;
81
- };
82
- error?: { message?: string };
83
- };
84
-
85
- /** Anthropic stop reasons -> OpenAI finish_reason. 'refusal' has no OpenAI
86
- * equivalent and is reported in band instead (see the message_delta case). */
87
- const FINISH_REASONS: Record<string, string> = {
88
- end_turn: 'stop',
89
- stop_sequence: 'stop',
90
- max_tokens: 'length',
91
- tool_use: 'tool_calls',
92
- };
93
-
94
- function toAnthropicTools(tools: unknown[] | undefined): AnthropicTool[] | undefined {
95
- if (!tools || tools.length === 0) return undefined;
96
- return tools.map((raw) => {
97
- const fn = (raw as OpenAIFunctionTool).function ?? {};
98
- return {
99
- name: fn.name ?? '',
100
- description: fn.description,
101
- input_schema: fn.parameters ?? { type: 'object', properties: {} },
102
- };
103
- });
104
- }
105
-
106
- /**
107
- * The OpenAI-shaped thread the front end posts -> an Anthropic Messages body.
108
- *
109
- * \`system\` comes back SEPARATELY because it is a top-level request field here.
110
- * A \`{ role: 'system' }\` entry left in \`messages\` is a 400, and it is the most
111
- * common thing to get wrong when porting a route across.
112
- */
113
- function toAnthropicBody(messages: ChatRequestBody['messages']): {
114
- system?: string;
115
- messages: AnthropicMessage[];
116
- } {
117
- let system: string | undefined;
118
- const out: AnthropicMessage[] = [];
119
-
120
- // Append to the trailing user message when there is one. A tool result and the
121
- // user's next turn are one turn on this wire, and several Anthropic-compatible
122
- // proxies enforce strict alternation.
123
- const pushUser = (content: AnthropicBlock[]): void => {
124
- const last = out[out.length - 1];
125
- if (last?.role === 'user') last.content.push(...content);
126
- else out.push({ role: 'user', content });
127
- };
128
-
129
- for (const message of messages) {
130
- switch (message.role) {
131
- case 'system': {
132
- // TOP-LEVEL, not a message. Several system turns concatenate.
133
- const text = wireText(message.content);
134
- system = system === undefined ? text : \`\${system}\\n\\n\${text}\`;
135
- break;
136
- }
137
- case 'user': {
138
- // Attachments ride HERE, as image and document blocks beside the text,
139
- // in the order the thread authored them.
140
- const blocks = wireParts(message.content).map((part): AnthropicBlock => {
141
- if (part.kind === 'text') return { type: 'text', text: part.text };
142
- const source: AnthropicSource =
143
- part.source.type === 'data'
144
- ? { type: 'base64', media_type: part.mediaType, data: part.source.data }
145
- : { type: 'url', url: part.source.url };
146
- // \`image/png\` and the bare top-level \`image\` both mean an image; a URL
147
- // source reports only the segment because the wire carries no more.
148
- return part.mediaType.startsWith('image') ? { type: 'image', source } : { type: 'document', source };
149
- });
150
- if (blocks.length > 0) pushUser(blocks);
151
- break;
152
- }
153
- case 'tool': {
154
- // A tool RESULT is a block on a USER message here, not a role of its own.
155
- pushUser([
156
- {
157
- type: 'tool_result',
158
- tool_use_id: message.tool_call_id ?? '',
159
- content: wireText(message.content),
160
- },
161
- ]);
162
- break;
163
- }
164
- case 'assistant': {
165
- const content: AnthropicBlock[] = [];
166
- const text = wireText(message.content);
167
- if (text) content.push({ type: 'text', text });
168
- for (const call of message.tool_calls ?? []) {
169
- content.push({
170
- type: 'tool_use',
171
- id: call.id,
172
- name: call.function.name,
173
- // \`input\` is a parsed OBJECT here. OpenAI carries the same value as a
174
- // JSON STRING in \`function.arguments\`; forwarding the string is a 400.
175
- input: call.function.arguments ? JSON.parse(call.function.arguments) : {},
176
- });
177
- }
178
- // An assistant turn with nothing in it is not a legal message.
179
- if (content.length > 0) out.push({ role: 'assistant', content });
180
- break;
181
- }
182
- }
183
- }
184
-
185
- return { system, messages: out };
186
- }
187
-
188
- /**
189
- * Anthropic Messages SSE -> OpenAI-format SSE.
190
- *
191
- * WHY THIS EXISTS AT ALL: the front end reads with readOpenAIStream. Handing it
192
- * Anthropic frames does not throw — it parses to NOTHING, so the turn ends empty
193
- * with no error anywhere, which is the worst failure this kit has. Re-framing
194
- * here keeps the browser half of an anthropic scaffold identical to every other
195
- * integration's, the same way the cloudflare Worker route re-frames env.AI.
196
- *
197
- * The alternative, if you would rather keep the native frames: return
198
- * \`upstream.body\` untouched and read it with readAnthropicStream from
199
- * '@kitn.ai/ui/wire'. That is also the ONLY way to round-trip thinking blocks
200
- * verbatim (toAnthropicMessages echoes \`part.raw\` — a rebuilt block is a hard
201
- * 400), so it is the path to take the moment you enable thinking below.
202
- */
203
- function reframeToOpenAISse(body: ReadableStream<Uint8Array>): ReadableStream<Uint8Array> {
204
- const encoder = new TextEncoder();
205
- const decoder = new TextDecoder();
206
- // THE INDEX TRAP. Anthropic's \`index\` counts CONTENT BLOCKS; OpenAI's
207
- // \`tool_calls[].index\` counts TOOL CALLS. A thinking or text block ahead of a
208
- // tool call shifts the block index, but the call is still tool call 0 — so the
209
- // block index is translated through this map rather than passed through.
210
- const toolIndexOfBlock = new Map<number, number>();
211
- let toolCount = 0;
212
-
213
- return new ReadableStream<Uint8Array>({
214
- async start(controller) {
215
- const send = (chunk: unknown): void => {
216
- controller.enqueue(encoder.encode(\`data: \${JSON.stringify(chunk)}\\n\\n\`));
217
- };
218
- const reader = body.getReader();
219
- let buffer = '';
220
- try {
221
- for (;;) {
222
- const { value, done } = await reader.read();
223
- if (done) break;
224
- buffer += decoder.decode(value, { stream: true });
225
- // Split on \\n rather than readline: readline also breaks on the
226
- // Unicode separators U+2028/U+2029, which appear inside model output.
227
- const lines = buffer.split('\\n');
228
- buffer = lines.pop() ?? ''; // hold the partial line for the next chunk
229
- for (const line of lines) {
230
- const trimmed = line.trim();
231
- // \`event:\` lines are redundant — every frame's data carries \`type\`.
232
- if (!trimmed.startsWith('data:')) continue;
233
- let event: AnthropicEvent;
234
- try {
235
- event = JSON.parse(trimmed.slice(5)) as AnthropicEvent;
236
- } catch {
237
- continue; // skip a malformed frame rather than kill the turn
238
- }
239
-
240
- if (event.type === 'content_block_start') {
241
- const block = event.content_block;
242
- if (block?.type !== 'tool_use') continue;
243
- const index = toolCount;
244
- toolCount += 1;
245
- toolIndexOfBlock.set(event.index ?? 0, index);
246
- send({
247
- choices: [{
248
- delta: {
249
- tool_calls: [{
250
- index,
251
- id: block.id,
252
- type: 'function',
253
- function: { name: block.name, arguments: '' },
254
- }],
255
- },
256
- }],
257
- });
258
- continue;
259
- }
260
-
261
- if (event.type === 'content_block_delta') {
262
- const delta = event.delta;
263
- if (delta?.type === 'text_delta') {
264
- send({ choices: [{ delta: { content: delta.text } }] });
265
- } else if (delta?.type === 'thinking_delta') {
266
- send({ choices: [{ delta: { reasoning: delta.thinking } }] });
267
- } else if (delta?.type === 'input_json_delta') {
268
- const index = toolIndexOfBlock.get(event.index ?? 0);
269
- // No entry means these fragments belong to a block that is not a
270
- // tool_use. Dropping them beats inventing a tool call.
271
- if (index !== undefined) {
272
- send({
273
- choices: [{
274
- delta: {
275
- tool_calls: [{ index, function: { arguments: delta.partial_json } }],
276
- },
277
- }],
278
- });
279
- }
280
- }
281
- continue;
282
- }
283
-
284
- if (event.type === 'message_delta') {
285
- const reason = event.delta?.stop_reason;
286
- if (!reason) continue;
287
- if (reason === 'refusal') {
288
- // A safety classifier declined. HTTP 200, no content, so without
289
- // this the turn just ends blank. Report it IN BAND:
290
- // readOpenAIStream lands it on turn.error.
291
- send({ error: { message: 'The model declined this request (stop_reason: refusal).' } });
292
- continue;
293
- }
294
- send({ choices: [{ delta: {}, finish_reason: FINISH_REASONS[reason] ?? 'stop' }] });
295
- continue;
296
- }
297
-
298
- if (event.type === 'error') {
299
- send({ error: { message: event.error?.message ?? 'Anthropic returned an error frame.' } });
300
- }
301
- }
302
- }
303
- } catch (err) {
304
- // The headers went out with the first byte, so the status is spent:
305
- // report IN BAND. readOpenAIStream lands this on turn.error and keeps
306
- // whatever already streamed.
307
- const message = err instanceof Error ? err.message : 'Anthropic stream failed';
308
- send({ error: { message } });
309
- }
310
- // Always: an unclosed stream leaves the browser waiting forever.
311
- controller.enqueue(encoder.encode('data: [DONE]\\n\\n'));
312
- controller.close();
313
- },
314
- });
315
- }
316
-
317
- async function chatHandler(request: Request): Promise<Response> {
318
- // Both model and tools come from the browser. \`tools\` arrives in OpenAI
319
- // function form and is converted to this API's shape below.
320
- let chatBody: ChatRequestBody;
321
- try {
322
- chatBody = await readChatRequest(request);
323
- } catch (error) {
324
- return toChatErrorResponse(error);
325
- }
326
- const { model, messages, tools } = chatBody;
327
- const { system, messages: anthropicMessages } = toAnthropicBody(messages);
328
- const anthropicTools = toAnthropicTools(tools);
329
-
330
- const upstream = await fetch('https://api.anthropic.com/v1/messages', {
331
- method: 'POST',
332
- headers: {
333
- 'x-api-key': \`\${process.env.ANTHROPIC_API_KEY}\`,
334
- 'anthropic-version': '2023-06-01',
335
- 'Content-Type': 'application/json',
336
- },
337
- body: JSON.stringify({
338
- // Model ids here are Anthropic's own — 'claude-opus-5', 'claude-sonnet-5',
339
- // 'claude-haiku-4-5'. An OpenAI id or an OpenRouter 'vendor/model' slug is
340
- // a 404. The front end's \`model\` const is the one to edit; it is seeded
341
- // from CLIENT_MODEL_IDS.anthropic.
342
- model,
343
- // REQUIRED. OpenAI defaults it; this API 400s without it. It caps thinking
344
- // AND response text together, so raise it if you turn thinking on.
345
- max_tokens: 4096,
346
- // TOP-LEVEL, never a { role: 'system' } entry in \`messages\`.
347
- ...(system ? { system } : {}),
348
- messages: anthropicMessages,
349
- ...(anthropicTools ? { tools: anthropicTools } : {}),
350
- // tool_choice, if you set one, is an OBJECT: { type: 'auto' } |
351
- // { type: 'any' } | { type: 'tool', name: 'search' }. OpenAI's bare string
352
- // ('auto') is a 400 here.
353
- // tool_choice: { type: 'auto' },
354
- //
355
- // THINKING. The rules changed with the model generation, so check yours:
356
- // · claude-opus-5 / sonnet-5 / opus-4.8 / opus-4.7 / fable-5 —
357
- // \`budget_tokens\` is REMOVED and returns a 400. Use
358
- // \`thinking: { type: 'adaptive', display: 'summarized' }\` plus
359
- // \`output_config: { effort: 'low' | 'medium' | 'high' | 'xhigh' | 'max' }\`.
360
- // On claude-opus-5 thinking is already ON by default; what is NOT on is
361
- // \`display\`, which defaults to 'omitted' and streams thinking blocks
362
- // with EMPTY text. That reads exactly like "this model has no reasoning
363
- // mode" — a silent 200 with nothing in the panel — and it is the same
364
- // shape of mistake as the budget bug below. Set display explicitly.
365
- // · older models (claude-haiku-4-5, claude-sonnet-4-5) — still
366
- // \`thinking: { type: 'enabled', budget_tokens: N }\`, with N >= 1024 and
367
- // max_tokens STRICTLY GREATER than N. Deriving N as a fraction of a
368
- // small max_tokens returns HTTP 200 with no thinking and no error.
369
- // Either way, once thinking is on a tool loop must echo every thinking
370
- // block back VERBATIM, which this route cannot do: it re-frames to OpenAI
371
- // SSE and the thread is re-encoded with toOpenAIMessages each round. Switch
372
- // to readAnthropicStream + toAnthropicMessages (both from '@kitn.ai/ui/wire')
373
- // and pass upstream.body through untouched before you enable it.
374
- stream: true,
375
- }),
376
- });
377
-
378
- // FORWARD THE STATUS. Returning 200 here is how a missing key turns into
379
- // silence: the 401 body is JSON, it goes out labelled text/event-stream, the
380
- // SSE reader finds no frame, and the turn resolves empty with nothing logged
381
- // and no bubble. With the status intact readOpenAIStream throws a WireError
382
- // carrying Anthropic's own message — which for this API is usually the exact
383
- // field you got wrong.
384
- if (!upstream.ok) {
385
- return new Response(await upstream.text(), {
386
- status: upstream.status,
387
- headers: {
388
- 'Content-Type': upstream.headers.get('content-type') ?? 'application/json',
389
- },
390
- });
391
- }
392
- if (!upstream.body) {
393
- return new Response(JSON.stringify({ error: { message: 'Anthropic returned no body to stream.' } }), {
394
- status: 502,
395
- headers: { 'Content-Type': 'application/json' },
396
- });
397
- }
398
-
399
- return new Response(reframeToOpenAISse(upstream.body), {
400
- status: 200,
401
- headers: {
402
- 'Content-Type': 'text/event-stream; charset=utf-8',
403
- // no-transform stops a proxy buffering the stream into one blob.
404
- 'Cache-Control': 'no-cache, no-transform',
405
- Connection: 'keep-alive',
406
- },
407
- });
408
- }`,
409
- streamMapping:
410
- "The Anthropic Messages API streams its OWN SSE dialect: message_start, content_block_start / content_block_delta / content_block_stop, message_delta, message_stop. It is NOT OpenAI-format, and feeding it to readOpenAIStream does not throw — it parses to nothing and the turn ends silently empty. The route therefore re-frames each frame to OpenAI form before it reaches the browser: text_delta -> delta.content, thinking_delta -> delta.reasoning, a tool_use content_block_start plus its input_json_delta fragments -> delta.tool_calls, message_delta.stop_reason -> finish_reason, an error frame -> an in-band {error:{message}}. readOpenAIStream from @kitn.ai/ui/wire then parses it exactly as it does every other integration. Anthropic indexes by CONTENT BLOCK while OpenAI's tool_calls[].index counts TOOL CALLS, so the route keeps a block-index -> tool-index map: a thinking block ahead of a tool call shifts the block index but not the tool index. Usage is the one thing not re-framed (input_tokens arrives on message_start and output_tokens on message_delta, so joining them needs state) — map both onto a {usage:{prompt_tokens,completion_tokens}} frame if you want token counts. To keep the native frames instead, return upstream.body untouched and read it with readAnthropicStream; that is also the only way to round-trip thinking blocks verbatim.",
411
- runNote:
412
- "Set ANTHROPIC_API_KEY (console.anthropic.com). The route pins claude-opus-5; claude-sonnet-5 and claude-haiku-4-5 are the cheaper swaps. Four things this API does NOT share with the OpenAI one, all of them 400s: system is a top-level field and not a message, max_tokens is required, tool_choice is an object ({ type: 'auto' }) and not a string, and tool schemas use input_schema rather than function.parameters. Extended thinking: on claude-opus-5 and the other current models budget_tokens is REMOVED (400) — use thinking: { type: 'adaptive', display: 'summarized' } with output_config.effort, and note that display defaults to 'omitted', which streams empty thinking blocks that look exactly like no reasoning at all. On older models (claude-haiku-4-5, claude-sonnet-4-5) budget_tokens still applies and must be >= 1024 with max_tokens strictly greater.",
413
- docsSlug: 'integrations/connect-any-model',
414
- // 'model' was withheld until scaffold.ts could seed it correctly: the shared
415
- // fallback is 'openai/gpt-4o-mini', which api.anthropic.com rejects outright,
416
- // and shipping an editable const with a broken default is the dead-const defect
417
- // forwardsFromClient exists to prevent. CLIENT_MODEL_IDS now carries a real
418
- // Anthropic id, so the const is live and the route reads it.
419
- forwardsFromClient: ['model', 'tools'],
420
- // 'openai', NOT 'anthropic' — and this is the counter-intuitive one, so read
421
- // `toAnthropicTools` above before changing it. This route CONVERTS the array
422
- // server-side: it reads `raw.function.name` and `raw.function.parameters` off
423
- // each entry, i.e. the OpenAI envelope, and rebuilds it as
424
- // `{ name, description, input_schema }`. Sending Anthropic's own shape from the
425
- // client would leave `.function` undefined, so every tool would go upstream
426
- // with a blank name and an empty schema. The envelope belongs to the ROUTE's
427
- // request contract, not to the provider it happens to POST to — which is
428
- // exactly why this is declared here rather than derived from `streamFormat`.
429
- clientToolFormat: 'openai',
430
- // Nothing to install. The route hand-rolls the Messages API over global
431
- // `fetch` and its own re-framer, so it imports no module — not even
432
- // @anthropic-ai/sdk.
433
- deps: { npm: [], pip: [] },
434
- // The route reads ANTHROPIC_API_KEY into an `x-api-key` header. Note the
435
- // header is NOT `Authorization`, which is why the schema's detector matches
436
- // both spellings.
437
- keyExposure: 'needs-proxy',
438
- // A remote HTTPS endpoint and a key. Nothing to install, nothing to start.
439
- outOfBand: 'none',
440
- };
441
-
442
- export default anthropic;
@@ -1,218 +0,0 @@
1
- import type { Integration } from '../types';
2
-
3
- const cloudflare: Integration = {
4
- id: 'cloudflare',
5
- title: 'Cloudflare AI',
6
- category: 'provider',
7
- language: 'ts',
8
- streamFormat: 'openai-sse',
9
- envVars: ['CF_ACCOUNT_ID', 'CF_API_TOKEN'],
10
- routeTemplates: {
11
- // Kept as a framework-specific template because it cannot be expressed as a
12
- // portable handler: `env.AI` is a Worker binding, and only a Worker has one.
13
- // Everything else uses `webRoute` below.
14
- worker: `// Worker handler: env.AI is bound in wrangler.toml
15
- // env.AI.run emits Cloudflare-native SSE (data: {"response":"<token>"}).
16
- // The TransformStream below re-frames each chunk to OpenAI-format SSE so
17
- // readOpenAIStream reads it without any client-side changes.
18
- import type { OpenAIWireMessage } from '@kitn.ai/ui/wire';
19
-
20
- /**
21
- * What the front end POSTs. \`req.json()\` is \`unknown\` (it is whatever the
22
- * client sent), so the body is narrowed once here instead of at every use —
23
- * without it this Worker does not compile. Widen it as you add fields.
24
- */
25
- type ChatRequestBody = { messages: OpenAIWireMessage[] };
26
-
27
- class ChatRequestError extends Error {
28
- constructor(readonly status: number, message: string) { super(message); }
29
- }
30
-
31
- /** Narrow the JSON body once, at the edge. A bare GET, a malformed body, or a
32
- * missing messages array is a ChatRequestError with a status — NEVER an
33
- * unhandled SyntaxError (findings F-10). */
34
- async function readChatRequest(request: Request): Promise<ChatRequestBody> {
35
- if (request.method !== 'POST') {
36
- throw new ChatRequestError(405, \`Method \${request.method} not allowed — POST /api/chat.\`);
37
- }
38
- let parsed: unknown;
39
- try { parsed = await request.json(); } catch {
40
- throw new ChatRequestError(400, 'Request body is not valid JSON.');
41
- }
42
- const body = parsed as ChatRequestBody;
43
- if (!Array.isArray(body?.messages)) {
44
- throw new ChatRequestError(400, 'Request body must carry a messages array.');
45
- }
46
- return body;
47
- }
48
-
49
- /** Map a guard rejection to the Response its status demands; rethrow anything
50
- * else — an unexpected error should be loud, not laundered into a 400. */
51
- function toChatErrorResponse(error: unknown): Response {
52
- if (error instanceof ChatRequestError) return Response.json({ error: error.message }, { status: error.status });
53
- throw error;
54
- }
55
-
56
- export default {
57
- async fetch(req: Request, env: Env): Promise<Response> {
58
- let chatBody: ChatRequestBody;
59
- try {
60
- chatBody = await readChatRequest(req);
61
- } catch (error) {
62
- return toChatErrorResponse(error);
63
- }
64
- const { messages } = chatBody;
65
-
66
- let nativeStream: ReadableStream<Uint8Array>;
67
- try {
68
- // env.AI.run is typed to return the non-streaming shape; \`stream: true\`
69
- // makes it a ReadableStream at runtime, which the types cannot express, so
70
- // the hop through \`unknown\` is required rather than cosmetic.
71
- nativeStream = (await env.AI.run('@cf/meta/llama-3.1-8b-instruct', {
72
- messages,
73
- stream: true,
74
- })) as unknown as ReadableStream<Uint8Array>;
75
- } catch (err) {
76
- // A REAL status, before a byte is streamed. Returning 200 here would send
77
- // a JSON error labelled text/event-stream: the reader finds no frame and
78
- // the turn resolves empty, with nothing logged and no bubble.
79
- return new Response(
80
- JSON.stringify({ error: { message: err instanceof Error ? err.message : 'Workers AI call failed' } }),
81
- { status: 502, headers: { 'Content-Type': 'application/json' } },
82
- );
83
- }
84
-
85
- // Re-frame Cloudflare-native SSE → OpenAI-format SSE
86
- const { readable, writable } = new TransformStream();
87
- const writer = writable.getWriter();
88
- const encoder = new TextEncoder();
89
- const decoder = new TextDecoder();
90
-
91
- (async () => {
92
- const reader = nativeStream.getReader();
93
- let buffer = '';
94
- try {
95
- while (true) {
96
- const { value, done } = await reader.read();
97
- if (done) break;
98
- buffer += decoder.decode(value, { stream: true });
99
- const lines = buffer.split('\\n');
100
- buffer = lines.pop() ?? '';
101
- for (const line of lines) {
102
- const s = line.trim();
103
- if (!s.startsWith('data:')) continue;
104
- const payload = s.slice(5).trim();
105
- if (payload === '[DONE]') continue;
106
- try {
107
- const { response } = JSON.parse(payload) as { response?: string };
108
- if (response == null) continue;
109
- const openaiChunk = JSON.stringify({ choices: [{ delta: { content: response } }] });
110
- await writer.write(encoder.encode(\`data: \${openaiChunk}\\n\\n\`));
111
- } catch { /* skip malformed lines */ }
112
- }
113
- }
114
- } catch (err) {
115
- // The response is already streaming, so the status is spent: report the
116
- // failure IN BAND. readOpenAIStream lands this on turn.error and keeps
117
- // whatever already streamed.
118
- const message = err instanceof Error ? err.message : 'Workers AI stream failed';
119
- await writer.write(encoder.encode(\`data: \${JSON.stringify({ error: { message } })}\\n\\n\`));
120
- } finally {
121
- // Always: an unclosed writer leaves the browser waiting forever.
122
- await writer.write(encoder.encode('data: [DONE]\\n\\n'));
123
- await writer.close();
124
- }
125
- })();
126
-
127
- return new Response(readable, {
128
- status: 200,
129
- headers: {
130
- 'Content-Type': 'text/event-stream; charset=utf-8',
131
- 'Cache-Control': 'no-cache, no-transform',
132
- },
133
- });
134
- },
135
- };`,
136
- },
137
- webRoute: `async function chatHandler(request: Request): Promise<Response> {
138
- // Proxy Workers AI over its OpenAI-compatible HTTP endpoint, token server-side.
139
- let chatBody: ChatRequestBody;
140
- try {
141
- chatBody = await readChatRequest(request);
142
- } catch (error) {
143
- return toChatErrorResponse(error);
144
- }
145
- const { messages } = chatBody;
146
-
147
- const upstream = await fetch(
148
- \`https://api.cloudflare.com/client/v4/accounts/\${process.env.CF_ACCOUNT_ID}/ai/v1/chat/completions\`,
149
- {
150
- method: 'POST',
151
- headers: {
152
- Authorization: \`Bearer \${process.env.CF_API_TOKEN}\`,
153
- 'Content-Type': 'application/json',
154
- },
155
- body: JSON.stringify({
156
- model: '@cf/meta/llama-3.1-8b-instruct',
157
- messages,
158
- stream: true,
159
- }),
160
- },
161
- );
162
-
163
- // FORWARD THE STATUS. A wrong CF_API_TOKEN is a 401/403: returning 200 sends
164
- // its JSON body out labelled text/event-stream, the SSE reader finds no frame,
165
- // and the turn resolves empty with nothing logged and no bubble.
166
- if (!upstream.ok) {
167
- return new Response(await upstream.text(), {
168
- status: upstream.status,
169
- headers: {
170
- 'Content-Type': upstream.headers.get('content-type') ?? 'application/json',
171
- },
172
- });
173
- }
174
- if (!upstream.body) {
175
- return new Response(JSON.stringify({ error: { message: 'Workers AI returned no body to stream.' } }), {
176
- status: 502,
177
- headers: { 'Content-Type': 'application/json' },
178
- });
179
- }
180
-
181
- // Workers AI returns OpenAI-format SSE. Pass it straight through.
182
- return new Response(upstream.body, {
183
- status: 200,
184
- headers: {
185
- 'Content-Type': 'text/event-stream; charset=utf-8',
186
- 'Cache-Control': 'no-cache, no-transform',
187
- Connection: 'keep-alive',
188
- },
189
- });
190
- }`,
191
- streamMapping:
192
- "Workers AI via the OpenAI-compatible HTTP endpoint returns OpenAI-format SSE. Pipe upstream.body straight to the browser; readOpenAIStream from @kitn.ai/ui/wire parses it, including tool calls and reasoning. The native env.AI binding streams Cloudflare's own format (data: {\"response\":\"...token...\"}); the worker route template re-frames these chunks to OpenAI-format SSE via a TransformStream before returning.",
193
- runNote: 'Set CF_ACCOUNT_ID and CF_API_TOKEN. Model ids are prefixed with @cf/, e.g. @cf/meta/llama-3.1-8b-instruct. For the AI binding (worker key), add an [ai] block with binding = "AI" in wrangler.toml.',
194
- docsSlug: 'integrations/cloudflare-ai',
195
- // Nothing. Both routes pin '@cf/meta/llama-3.1-8b-instruct' (the generic
196
- // 'openai/gpt-4o-mini' a scaffold used to default to is not even a valid
197
- // Workers AI id), and the worker route's re-framing reader forwards only the
198
- // text `response` field, so a tool call could not reach the browser anyway.
199
- forwardsFromClient: [],
200
- // Nothing. The webRoute is global `fetch`, and the worker template's only
201
- // import is a type from '@kitn.ai/ui/wire' — the kit itself, which every
202
- // scaffold already depends on. Its `Env` is an ambient wrangler type, not an
203
- // import, and the Worker skeleton owns wrangler/@cloudflare/workers-types.
204
- deps: { npm: [], pip: [] },
205
- // The webRoute reads CF_API_TOKEN into an `Authorization: Bearer` header.
206
- //
207
- // The two routes differ and the stricter one governs: the worker template uses
208
- // the `env.AI` binding and holds no token in code at all, but a binding is a
209
- // Worker capability, not a browser one. Either way a server is required.
210
- keyExposure: 'needs-proxy',
211
- // Workers AI is a remote HTTPS endpoint (the REST route) or a platform binding
212
- // (the worker route) — either way there is nothing on the developer's machine
213
- // to install or run. `wrangler` is a devDependency of a Worker app, not an
214
- // out-of-band prerequisite of this integration.
215
- outOfBand: 'none',
216
- };
217
-
218
- export default cloudflare;