veryfront 0.1.997 → 0.1.999

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 (386) hide show
  1. package/esm/cli/templates/manifest.d.ts +1 -1
  2. package/esm/cli/templates/manifest.js +15 -15
  3. package/esm/deno.d.ts +7 -0
  4. package/esm/deno.js +11 -3
  5. package/esm/deps/esm.sh/react-dom@19.2.4.d.ts +2 -0
  6. package/esm/deps/esm.sh/react-dom@19.2.4.d.ts.map +1 -0
  7. package/esm/deps/esm.sh/react-dom@19.2.4.js +3 -0
  8. package/esm/react/react-dom.d.ts +3 -0
  9. package/esm/react/react-dom.d.ts.map +1 -0
  10. package/esm/react/react-dom.js +2 -0
  11. package/esm/src/agent/ag-ui/host-support.d.ts.map +1 -1
  12. package/esm/src/agent/ag-ui/host-support.js +12 -0
  13. package/esm/src/agent/react/index.d.ts +4 -2
  14. package/esm/src/agent/react/index.d.ts.map +1 -1
  15. package/esm/src/agent/react/index.js +2 -1
  16. package/esm/src/agent/react/use-agent-metadata.d.ts +5 -0
  17. package/esm/src/agent/react/use-agent-metadata.d.ts.map +1 -1
  18. package/esm/src/agent/react/use-agent-metadata.js +18 -9
  19. package/esm/src/agent/react/use-agents.d.ts +33 -0
  20. package/esm/src/agent/react/use-agents.d.ts.map +1 -0
  21. package/esm/src/agent/react/use-agents.js +72 -0
  22. package/esm/src/agent/react/use-chat/index.d.ts +1 -1
  23. package/esm/src/agent/react/use-chat/index.d.ts.map +1 -1
  24. package/esm/src/agent/react/use-chat/types.d.ts +3 -2
  25. package/esm/src/agent/react/use-chat/types.d.ts.map +1 -1
  26. package/esm/src/agent/react/use-chat/use-chat.d.ts +12 -1
  27. package/esm/src/agent/react/use-chat/use-chat.d.ts.map +1 -1
  28. package/esm/src/agent/react/use-chat/use-chat.js +47 -7
  29. package/esm/src/agent/react/use-chat/utils.d.ts.map +1 -1
  30. package/esm/src/agent/react/use-chat/utils.js +4 -0
  31. package/esm/src/agent/runtime/message-adapter.d.ts.map +1 -1
  32. package/esm/src/agent/runtime/message-adapter.js +3 -1
  33. package/esm/src/agent/runtime/text-generation-runtime-message-converter.d.ts.map +1 -1
  34. package/esm/src/agent/runtime/text-generation-runtime-message-converter.js +6 -2
  35. package/esm/src/chat/index.d.ts +17 -7
  36. package/esm/src/chat/index.d.ts.map +1 -1
  37. package/esm/src/chat/index.js +33 -7
  38. package/esm/src/chat/protocol.d.ts +13 -1
  39. package/esm/src/chat/protocol.d.ts.map +1 -1
  40. package/esm/src/chat/upload-handler.d.ts +55 -0
  41. package/esm/src/chat/upload-handler.d.ts.map +1 -0
  42. package/esm/src/chat/upload-handler.js +180 -0
  43. package/esm/src/discovery/import-rewriter.d.ts +1 -1
  44. package/esm/src/discovery/import-rewriter.d.ts.map +1 -1
  45. package/esm/src/discovery/import-rewriter.js +2 -0
  46. package/esm/src/discovery/transpiler.d.ts.map +1 -1
  47. package/esm/src/discovery/transpiler.js +2 -0
  48. package/esm/src/embedding/index.d.ts +0 -2
  49. package/esm/src/embedding/index.d.ts.map +1 -1
  50. package/esm/src/embedding/index.js +0 -1
  51. package/esm/src/embedding/upload-handler.d.ts +2 -13
  52. package/esm/src/embedding/upload-handler.d.ts.map +1 -1
  53. package/esm/src/embedding/upload-handler.js +24 -17
  54. package/esm/src/modules/import-map/default-import-map.d.ts.map +1 -1
  55. package/esm/src/modules/import-map/default-import-map.js +0 -5
  56. package/esm/src/react/components/chat/agent-card.d.ts +84 -11
  57. package/esm/src/react/components/chat/agent-card.d.ts.map +1 -1
  58. package/esm/src/react/components/chat/agent-card.js +151 -57
  59. package/esm/src/react/components/chat/agent-picker.d.ts +166 -0
  60. package/esm/src/react/components/chat/agent-picker.d.ts.map +1 -0
  61. package/esm/src/react/components/chat/agent-picker.js +183 -0
  62. package/esm/src/react/components/chat/chat/components/animations.js +1 -1
  63. package/esm/src/react/components/chat/chat/components/attachment-pill.d.ts +125 -3
  64. package/esm/src/react/components/chat/chat/components/attachment-pill.d.ts.map +1 -1
  65. package/esm/src/react/components/chat/chat/components/attachment-pill.js +209 -25
  66. package/esm/src/react/components/chat/chat/components/attachments-panel.d.ts +149 -0
  67. package/esm/src/react/components/chat/chat/components/attachments-panel.d.ts.map +1 -0
  68. package/esm/src/react/components/chat/chat/components/attachments-panel.js +187 -0
  69. package/esm/src/react/components/chat/chat/components/branch-picker.d.ts +13 -2
  70. package/esm/src/react/components/chat/chat/components/branch-picker.d.ts.map +1 -1
  71. package/esm/src/react/components/chat/chat/components/branch-picker.js +6 -8
  72. package/esm/src/react/components/chat/chat/components/chat-messages-skeleton.d.ts +20 -0
  73. package/esm/src/react/components/chat/chat/components/chat-messages-skeleton.d.ts.map +1 -0
  74. package/esm/src/react/components/chat/chat/components/chat-messages-skeleton.js +31 -0
  75. package/esm/src/react/components/chat/chat/components/code-block.d.ts +9 -1
  76. package/esm/src/react/components/chat/chat/components/code-block.d.ts.map +1 -1
  77. package/esm/src/react/components/chat/chat/components/code-block.js +14 -6
  78. package/esm/src/react/components/chat/chat/components/drop-zone.d.ts +11 -4
  79. package/esm/src/react/components/chat/chat/components/drop-zone.d.ts.map +1 -1
  80. package/esm/src/react/components/chat/chat/components/drop-zone.js +10 -8
  81. package/esm/src/react/components/chat/chat/components/empty-state.d.ts +2 -1
  82. package/esm/src/react/components/chat/chat/components/empty-state.d.ts.map +1 -1
  83. package/esm/src/react/components/chat/chat/components/empty-state.js +7 -8
  84. package/esm/src/react/components/chat/chat/components/inference-badge.d.ts +6 -2
  85. package/esm/src/react/components/chat/chat/components/inference-badge.d.ts.map +1 -1
  86. package/esm/src/react/components/chat/chat/components/inference-badge.js +5 -4
  87. package/esm/src/react/components/chat/chat/components/inline-citation.d.ts +9 -1
  88. package/esm/src/react/components/chat/chat/components/inline-citation.d.ts.map +1 -1
  89. package/esm/src/react/components/chat/chat/components/inline-citation.js +19 -20
  90. package/esm/src/react/components/chat/chat/components/message-actions.d.ts +28 -5
  91. package/esm/src/react/components/chat/chat/components/message-actions.d.ts.map +1 -1
  92. package/esm/src/react/components/chat/chat/components/message-actions.js +24 -36
  93. package/esm/src/react/components/chat/chat/components/message-edit-form.d.ts +7 -2
  94. package/esm/src/react/components/chat/chat/components/message-edit-form.d.ts.map +1 -1
  95. package/esm/src/react/components/chat/chat/components/message-edit-form.js +5 -5
  96. package/esm/src/react/components/chat/chat/components/message-feedback.d.ts +11 -1
  97. package/esm/src/react/components/chat/chat/components/message-feedback.d.ts.map +1 -1
  98. package/esm/src/react/components/chat/chat/components/message-feedback.js +9 -11
  99. package/esm/src/react/components/chat/chat/components/quick-actions.d.ts.map +1 -1
  100. package/esm/src/react/components/chat/chat/components/quick-actions.js +3 -1
  101. package/esm/src/react/components/chat/chat/components/reasoning.d.ts +66 -3
  102. package/esm/src/react/components/chat/chat/components/reasoning.d.ts.map +1 -1
  103. package/esm/src/react/components/chat/chat/components/reasoning.js +95 -21
  104. package/esm/src/react/components/chat/chat/components/sidebar.d.ts +178 -12
  105. package/esm/src/react/components/chat/chat/components/sidebar.d.ts.map +1 -1
  106. package/esm/src/react/components/chat/chat/components/sidebar.js +228 -45
  107. package/esm/src/react/components/chat/chat/components/skill-badge.d.ts +6 -1
  108. package/esm/src/react/components/chat/chat/components/skill-badge.d.ts.map +1 -1
  109. package/esm/src/react/components/chat/chat/components/skill-badge.js +6 -5
  110. package/esm/src/react/components/chat/chat/components/skill-tool.d.ts +37 -0
  111. package/esm/src/react/components/chat/chat/components/skill-tool.d.ts.map +1 -0
  112. package/esm/src/react/components/chat/chat/components/skill-tool.js +46 -0
  113. package/esm/src/react/components/chat/chat/components/sources.d.ts +55 -3
  114. package/esm/src/react/components/chat/chat/components/sources.d.ts.map +1 -1
  115. package/esm/src/react/components/chat/chat/components/sources.js +50 -16
  116. package/esm/src/react/components/chat/chat/components/step-indicator.d.ts +42 -3
  117. package/esm/src/react/components/chat/chat/components/step-indicator.d.ts.map +1 -1
  118. package/esm/src/react/components/chat/chat/components/step-indicator.js +55 -12
  119. package/esm/src/react/components/chat/chat/components/tab-switcher.d.ts +1 -1
  120. package/esm/src/react/components/chat/chat/components/tab-switcher.d.ts.map +1 -1
  121. package/esm/src/react/components/chat/chat/components/tab-switcher.js +3 -3
  122. package/esm/src/react/components/chat/chat/components/tool-ui.d.ts +96 -3
  123. package/esm/src/react/components/chat/chat/components/tool-ui.d.ts.map +1 -1
  124. package/esm/src/react/components/chat/chat/components/tool-ui.js +158 -36
  125. package/esm/src/react/components/chat/chat/composition/api.d.ts +4 -2
  126. package/esm/src/react/components/chat/chat/composition/api.d.ts.map +1 -1
  127. package/esm/src/react/components/chat/chat/composition/api.js +4 -2
  128. package/esm/src/react/components/chat/chat/composition/chat-composer.d.ts +112 -5
  129. package/esm/src/react/components/chat/chat/composition/chat-composer.d.ts.map +1 -1
  130. package/esm/src/react/components/chat/chat/composition/chat-composer.js +251 -61
  131. package/esm/src/react/components/chat/chat/composition/chat-empty-state.d.ts +78 -0
  132. package/esm/src/react/components/chat/chat/composition/chat-empty-state.d.ts.map +1 -0
  133. package/esm/src/react/components/chat/chat/composition/chat-empty-state.js +63 -0
  134. package/esm/src/react/components/chat/chat/composition/chat-empty.d.ts +4 -1
  135. package/esm/src/react/components/chat/chat/composition/chat-empty.d.ts.map +1 -1
  136. package/esm/src/react/components/chat/chat/composition/chat-empty.js +11 -10
  137. package/esm/src/react/components/chat/chat/composition/chat-message-list.d.ts +11 -3
  138. package/esm/src/react/components/chat/chat/composition/chat-message-list.d.ts.map +1 -1
  139. package/esm/src/react/components/chat/chat/composition/chat-message-list.js +81 -111
  140. package/esm/src/react/components/chat/chat/composition/chat-root.d.ts +4 -0
  141. package/esm/src/react/components/chat/chat/composition/chat-root.d.ts.map +1 -1
  142. package/esm/src/react/components/chat/chat/composition/chat-root.js +3 -1
  143. package/esm/src/react/components/chat/chat/composition/error-banner.d.ts +4 -0
  144. package/esm/src/react/components/chat/chat/composition/error-banner.d.ts.map +1 -1
  145. package/esm/src/react/components/chat/chat/composition/error-banner.js +10 -7
  146. package/esm/src/react/components/chat/chat/composition/message.d.ts +123 -5
  147. package/esm/src/react/components/chat/chat/composition/message.d.ts.map +1 -1
  148. package/esm/src/react/components/chat/chat/composition/message.js +332 -53
  149. package/esm/src/react/components/chat/chat/composition/model-avatar.d.ts +6 -1
  150. package/esm/src/react/components/chat/chat/composition/model-avatar.d.ts.map +1 -1
  151. package/esm/src/react/components/chat/chat/composition/model-avatar.js +3 -4
  152. package/esm/src/react/components/chat/chat/composition/pending-message.d.ts +31 -0
  153. package/esm/src/react/components/chat/chat/composition/pending-message.d.ts.map +1 -0
  154. package/esm/src/react/components/chat/chat/composition/pending-message.js +31 -0
  155. package/esm/src/react/components/chat/chat/contexts/chat-context.d.ts +4 -0
  156. package/esm/src/react/components/chat/chat/contexts/chat-context.d.ts.map +1 -1
  157. package/esm/src/react/components/chat/chat/contexts/composer-context.d.ts +1 -0
  158. package/esm/src/react/components/chat/chat/contexts/composer-context.d.ts.map +1 -1
  159. package/esm/src/react/components/chat/chat/contexts/conversations-context.d.ts +29 -0
  160. package/esm/src/react/components/chat/chat/contexts/conversations-context.d.ts.map +1 -0
  161. package/esm/src/react/components/chat/chat/contexts/conversations-context.js +39 -0
  162. package/esm/src/react/components/chat/chat/contexts/index.d.ts +1 -1
  163. package/esm/src/react/components/chat/chat/contexts/index.d.ts.map +1 -1
  164. package/esm/src/react/components/chat/chat/contexts/index.js +1 -1
  165. package/esm/src/react/components/chat/chat/contexts/message-context.d.ts +2 -0
  166. package/esm/src/react/components/chat/chat/contexts/message-context.d.ts.map +1 -1
  167. package/esm/src/react/components/chat/chat/hooks/use-clipboard.d.ts +10 -0
  168. package/esm/src/react/components/chat/chat/hooks/use-clipboard.d.ts.map +1 -0
  169. package/esm/src/react/components/chat/chat/hooks/use-clipboard.js +34 -0
  170. package/esm/src/react/components/chat/chat/hooks/use-conversation.d.ts +21 -0
  171. package/esm/src/react/components/chat/chat/hooks/use-conversation.d.ts.map +1 -0
  172. package/esm/src/react/components/chat/chat/hooks/use-conversation.js +54 -0
  173. package/esm/src/react/components/chat/chat/hooks/use-conversations.d.ts +67 -0
  174. package/esm/src/react/components/chat/chat/hooks/use-conversations.d.ts.map +1 -0
  175. package/esm/src/react/components/chat/chat/hooks/use-conversations.js +317 -0
  176. package/esm/src/react/components/chat/chat/hooks/use-drop-zone.d.ts +27 -0
  177. package/esm/src/react/components/chat/chat/hooks/use-drop-zone.d.ts.map +1 -0
  178. package/esm/src/react/components/chat/chat/hooks/use-drop-zone.js +50 -0
  179. package/esm/src/react/components/chat/chat/hooks/use-stick-to-bottom.d.ts +49 -0
  180. package/esm/src/react/components/chat/chat/hooks/use-stick-to-bottom.d.ts.map +1 -0
  181. package/esm/src/react/components/chat/chat/hooks/use-stick-to-bottom.js +120 -0
  182. package/esm/src/react/components/chat/chat/hooks/use-upload.d.ts +34 -0
  183. package/esm/src/react/components/chat/chat/hooks/use-upload.d.ts.map +1 -0
  184. package/esm/src/react/components/chat/chat/hooks/use-upload.js +147 -0
  185. package/esm/src/react/components/chat/chat/hooks/use-uploads-registry.d.ts +37 -0
  186. package/esm/src/react/components/chat/chat/hooks/use-uploads-registry.d.ts.map +1 -0
  187. package/esm/src/react/components/chat/chat/hooks/use-uploads-registry.js +178 -0
  188. package/esm/src/react/components/chat/chat/index.d.ts +171 -31
  189. package/esm/src/react/components/chat/chat/index.d.ts.map +1 -1
  190. package/esm/src/react/components/chat/chat/index.js +371 -77
  191. package/esm/src/react/components/chat/chat/persistence/conversation-store.d.ts +63 -0
  192. package/esm/src/react/components/chat/chat/persistence/conversation-store.d.ts.map +1 -0
  193. package/esm/src/react/components/chat/chat/persistence/conversation-store.js +1 -0
  194. package/esm/src/react/components/chat/chat/persistence/local-conversation-store.d.ts +13 -0
  195. package/esm/src/react/components/chat/chat/persistence/local-conversation-store.d.ts.map +1 -0
  196. package/esm/src/react/components/chat/chat/persistence/local-conversation-store.js +102 -0
  197. package/esm/src/react/components/chat/chat/persistence/memory-conversation-store.d.ts +11 -0
  198. package/esm/src/react/components/chat/chat/persistence/memory-conversation-store.d.ts.map +1 -0
  199. package/esm/src/react/components/chat/chat/persistence/memory-conversation-store.js +33 -0
  200. package/esm/src/react/components/chat/chat/utils/message-parts.d.ts +4 -1
  201. package/esm/src/react/components/chat/chat/utils/message-parts.d.ts.map +1 -1
  202. package/esm/src/react/components/chat/chat/utils/message-parts.js +4 -0
  203. package/esm/src/react/components/chat/chat-actions.d.ts +164 -0
  204. package/esm/src/react/components/chat/chat-actions.d.ts.map +1 -0
  205. package/esm/src/react/components/chat/chat-actions.js +191 -0
  206. package/esm/src/react/components/chat/chat-agent-picker.d.ts +50 -0
  207. package/esm/src/react/components/chat/chat-agent-picker.d.ts.map +1 -0
  208. package/esm/src/react/components/chat/chat-agent-picker.js +40 -0
  209. package/esm/src/react/components/chat/chat-theme-scope.d.ts +26 -0
  210. package/esm/src/react/components/chat/chat-theme-scope.d.ts.map +1 -0
  211. package/esm/src/react/components/chat/chat-theme-scope.js +27 -0
  212. package/esm/src/react/components/chat/chat-tokens-style.d.ts +21 -0
  213. package/esm/src/react/components/chat/chat-tokens-style.d.ts.map +1 -0
  214. package/esm/src/react/components/chat/chat-tokens-style.js +24 -0
  215. package/esm/src/react/components/chat/chat.d.ts +5 -5
  216. package/esm/src/react/components/chat/chat.d.ts.map +1 -1
  217. package/esm/src/react/components/chat/chat.js +5 -5
  218. package/esm/src/react/components/chat/color-mode.d.ts +46 -0
  219. package/esm/src/react/components/chat/color-mode.d.ts.map +1 -0
  220. package/esm/src/react/components/chat/color-mode.js +123 -0
  221. package/esm/src/react/components/chat/error-boundary.js +2 -2
  222. package/esm/src/react/components/chat/icons/index.d.ts +8 -0
  223. package/esm/src/react/components/chat/icons/index.d.ts.map +1 -1
  224. package/esm/src/react/components/chat/icons/index.js +64 -0
  225. package/esm/src/react/components/chat/markdown.d.ts +24 -1
  226. package/esm/src/react/components/chat/markdown.d.ts.map +1 -1
  227. package/esm/src/react/components/chat/markdown.js +122 -38
  228. package/esm/src/react/components/chat/model-selector.d.ts +130 -8
  229. package/esm/src/react/components/chat/model-selector.d.ts.map +1 -1
  230. package/esm/src/react/components/chat/model-selector.js +148 -121
  231. package/esm/src/react/components/chat/theme.d.ts +9 -12
  232. package/esm/src/react/components/chat/theme.d.ts.map +1 -1
  233. package/esm/src/react/components/chat/theme.js +149 -93
  234. package/esm/src/react/components/chat/ui/alert.d.ts +30 -0
  235. package/esm/src/react/components/chat/ui/alert.d.ts.map +1 -0
  236. package/esm/src/react/components/chat/ui/alert.js +35 -0
  237. package/esm/src/react/components/chat/ui/app-shell.d.ts +155 -0
  238. package/esm/src/react/components/chat/ui/app-shell.d.ts.map +1 -0
  239. package/esm/src/react/components/chat/ui/app-shell.js +276 -0
  240. package/esm/src/react/components/chat/ui/avatar.d.ts +24 -0
  241. package/esm/src/react/components/chat/ui/avatar.d.ts.map +1 -0
  242. package/esm/src/react/components/chat/ui/avatar.js +44 -0
  243. package/esm/src/react/components/chat/ui/badge.d.ts +24 -0
  244. package/esm/src/react/components/chat/ui/badge.d.ts.map +1 -0
  245. package/esm/src/react/components/chat/ui/badge.js +30 -0
  246. package/esm/src/react/components/chat/ui/button.d.ts +44 -0
  247. package/esm/src/react/components/chat/ui/button.d.ts.map +1 -0
  248. package/esm/src/react/components/chat/ui/button.js +108 -0
  249. package/esm/src/react/components/chat/ui/card.d.ts +42 -0
  250. package/esm/src/react/components/chat/ui/card.d.ts.map +1 -0
  251. package/esm/src/react/components/chat/ui/card.js +55 -0
  252. package/esm/src/react/components/chat/ui/checkbox.d.ts +28 -0
  253. package/esm/src/react/components/chat/ui/checkbox.d.ts.map +1 -0
  254. package/esm/src/react/components/chat/ui/checkbox.js +36 -0
  255. package/esm/src/react/components/chat/ui/code-block.d.ts +89 -0
  256. package/esm/src/react/components/chat/ui/code-block.d.ts.map +1 -0
  257. package/esm/src/react/components/chat/ui/code-block.js +277 -0
  258. package/esm/src/react/components/chat/ui/collapsible.d.ts +30 -0
  259. package/esm/src/react/components/chat/ui/collapsible.d.ts.map +1 -0
  260. package/esm/src/react/components/chat/ui/collapsible.js +44 -0
  261. package/esm/src/react/components/chat/ui/command.d.ts +65 -0
  262. package/esm/src/react/components/chat/ui/command.d.ts.map +1 -0
  263. package/esm/src/react/components/chat/ui/command.js +121 -0
  264. package/esm/src/react/components/chat/ui/cva.d.ts +36 -0
  265. package/esm/src/react/components/chat/ui/cva.d.ts.map +1 -0
  266. package/esm/src/react/components/chat/ui/cva.js +45 -0
  267. package/esm/src/react/components/chat/ui/dialog.d.ts +55 -0
  268. package/esm/src/react/components/chat/ui/dialog.d.ts.map +1 -0
  269. package/esm/src/react/components/chat/ui/dialog.js +116 -0
  270. package/esm/src/react/components/chat/ui/drawer.d.ts +41 -0
  271. package/esm/src/react/components/chat/ui/drawer.d.ts.map +1 -0
  272. package/esm/src/react/components/chat/ui/drawer.js +92 -0
  273. package/esm/src/react/components/chat/ui/dropdown-menu.d.ts +63 -0
  274. package/esm/src/react/components/chat/ui/dropdown-menu.d.ts.map +1 -0
  275. package/esm/src/react/components/chat/ui/dropdown-menu.js +76 -0
  276. package/esm/src/react/components/chat/ui/file-type.d.ts +26 -0
  277. package/esm/src/react/components/chat/ui/file-type.d.ts.map +1 -0
  278. package/esm/src/react/components/chat/ui/file-type.js +235 -0
  279. package/esm/src/react/components/chat/ui/floating.d.ts +29 -0
  280. package/esm/src/react/components/chat/ui/floating.d.ts.map +1 -0
  281. package/esm/src/react/components/chat/ui/floating.js +90 -0
  282. package/esm/src/react/components/chat/ui/icon-button.d.ts +19 -0
  283. package/esm/src/react/components/chat/ui/icon-button.d.ts.map +1 -0
  284. package/esm/src/react/components/chat/ui/icon-button.js +20 -0
  285. package/esm/src/react/components/chat/ui/index.d.ts +43 -0
  286. package/esm/src/react/components/chat/ui/index.d.ts.map +1 -0
  287. package/esm/src/react/components/chat/ui/index.js +42 -0
  288. package/esm/src/react/components/chat/ui/input.d.ts +27 -0
  289. package/esm/src/react/components/chat/ui/input.d.ts.map +1 -0
  290. package/esm/src/react/components/chat/ui/input.js +41 -0
  291. package/esm/src/react/components/chat/ui/label.d.ts +29 -0
  292. package/esm/src/react/components/chat/ui/label.d.ts.map +1 -0
  293. package/esm/src/react/components/chat/ui/label.js +40 -0
  294. package/esm/src/react/components/chat/ui/list.d.ts +47 -0
  295. package/esm/src/react/components/chat/ui/list.d.ts.map +1 -0
  296. package/esm/src/react/components/chat/ui/list.js +40 -0
  297. package/esm/src/react/components/chat/ui/pill.d.ts +26 -0
  298. package/esm/src/react/components/chat/ui/pill.d.ts.map +1 -0
  299. package/esm/src/react/components/chat/ui/pill.js +39 -0
  300. package/esm/src/react/components/chat/ui/popover.d.ts +47 -0
  301. package/esm/src/react/components/chat/ui/popover.d.ts.map +1 -0
  302. package/esm/src/react/components/chat/ui/popover.js +68 -0
  303. package/esm/src/react/components/chat/ui/progress-bar.d.ts +20 -0
  304. package/esm/src/react/components/chat/ui/progress-bar.d.ts.map +1 -0
  305. package/esm/src/react/components/chat/ui/progress-bar.js +31 -0
  306. package/esm/src/react/components/chat/ui/radio.d.ts +25 -0
  307. package/esm/src/react/components/chat/ui/radio.d.ts.map +1 -0
  308. package/esm/src/react/components/chat/ui/radio.js +29 -0
  309. package/esm/src/react/components/chat/ui/scroll-fade.d.ts +23 -0
  310. package/esm/src/react/components/chat/ui/scroll-fade.d.ts.map +1 -0
  311. package/esm/src/react/components/chat/ui/scroll-fade.js +40 -0
  312. package/esm/src/react/components/chat/ui/select.d.ts +64 -0
  313. package/esm/src/react/components/chat/ui/select.d.ts.map +1 -0
  314. package/esm/src/react/components/chat/ui/select.js +148 -0
  315. package/esm/src/react/components/chat/ui/shimmer.d.ts +25 -0
  316. package/esm/src/react/components/chat/ui/shimmer.d.ts.map +1 -0
  317. package/esm/src/react/components/chat/ui/shimmer.js +24 -0
  318. package/esm/src/react/components/chat/ui/skeleton.d.ts +14 -0
  319. package/esm/src/react/components/chat/ui/skeleton.d.ts.map +1 -0
  320. package/esm/src/react/components/chat/ui/skeleton.js +12 -0
  321. package/esm/src/react/components/chat/ui/slot.d.ts +21 -0
  322. package/esm/src/react/components/chat/ui/slot.d.ts.map +1 -0
  323. package/esm/src/react/components/chat/ui/slot.js +70 -0
  324. package/esm/src/react/components/chat/ui/status.d.ts +28 -0
  325. package/esm/src/react/components/chat/ui/status.d.ts.map +1 -0
  326. package/esm/src/react/components/chat/ui/status.js +23 -0
  327. package/esm/src/react/components/chat/ui/switch.d.ts +34 -0
  328. package/esm/src/react/components/chat/ui/switch.d.ts.map +1 -0
  329. package/esm/src/react/components/chat/ui/switch.js +58 -0
  330. package/esm/src/react/components/chat/ui/tabs.d.ts +44 -0
  331. package/esm/src/react/components/chat/ui/tabs.d.ts.map +1 -0
  332. package/esm/src/react/components/chat/ui/tabs.js +51 -0
  333. package/esm/src/react/components/chat/ui/tag.d.ts +22 -0
  334. package/esm/src/react/components/chat/ui/tag.d.ts.map +1 -0
  335. package/esm/src/react/components/chat/ui/tag.js +27 -0
  336. package/esm/src/react/components/chat/ui/textarea.d.ts +22 -0
  337. package/esm/src/react/components/chat/ui/textarea.d.ts.map +1 -0
  338. package/esm/src/react/components/chat/ui/textarea.js +35 -0
  339. package/esm/src/react/components/chat/ui/tooltip.d.ts +40 -0
  340. package/esm/src/react/components/chat/ui/tooltip.d.ts.map +1 -0
  341. package/esm/src/react/components/chat/ui/tooltip.js +132 -0
  342. package/esm/src/react/primitives/input-box.d.ts.map +1 -1
  343. package/esm/src/react/primitives/input-box.js +17 -4
  344. package/esm/src/server/handlers/dev/framework-candidates.generated.d.ts.map +1 -1
  345. package/esm/src/server/handlers/dev/framework-candidates.generated.js +9437 -1064
  346. package/esm/src/server/handlers/dev/projects/html-shell.d.ts +1 -1
  347. package/esm/src/server/handlers/dev/projects/html-shell.d.ts.map +1 -1
  348. package/esm/src/server/handlers/dev/projects/html-shell.js +1 -12
  349. package/esm/src/server/handlers/request/public-agents-list.handler.d.ts +18 -0
  350. package/esm/src/server/handlers/request/public-agents-list.handler.d.ts.map +1 -0
  351. package/esm/src/server/handlers/request/public-agents-list.handler.js +44 -0
  352. package/esm/src/server/runtime-handler/index.d.ts +1 -1
  353. package/esm/src/server/runtime-handler/index.d.ts.map +1 -1
  354. package/esm/src/server/runtime-handler/index.js +3 -0
  355. package/esm/src/studio/bridge/bridge-bundle.generated.d.ts +1 -1
  356. package/esm/src/studio/bridge/bridge-bundle.generated.d.ts.map +1 -1
  357. package/esm/src/studio/bridge/bridge-bundle.generated.js +3 -2
  358. package/esm/src/utils/version-constant.d.ts +1 -1
  359. package/esm/src/utils/version-constant.js +1 -1
  360. package/esm/src/workflow/blob/local-storage.d.ts +32 -0
  361. package/esm/src/workflow/blob/local-storage.d.ts.map +1 -0
  362. package/esm/src/workflow/blob/local-storage.js +179 -0
  363. package/esm/src/workflow/blob/types.d.ts +5 -0
  364. package/esm/src/workflow/blob/types.d.ts.map +1 -1
  365. package/esm/src/workflow/blob/veryfront-cloud-storage.d.ts +11 -0
  366. package/esm/src/workflow/blob/veryfront-cloud-storage.d.ts.map +1 -1
  367. package/esm/src/workflow/blob/veryfront-cloud-storage.js +36 -0
  368. package/package.json +5 -1
  369. package/esm/src/embedding/react/use-uploads.d.ts +0 -33
  370. package/esm/src/embedding/react/use-uploads.d.ts.map +0 -1
  371. package/esm/src/embedding/react/use-uploads.js +0 -76
  372. package/esm/src/react/components/chat/chat/components/uploads-panel.d.ts +0 -20
  373. package/esm/src/react/components/chat/chat/components/uploads-panel.d.ts.map +0 -1
  374. package/esm/src/react/components/chat/chat/components/uploads-panel.js +0 -49
  375. package/esm/src/react/components/chat/chat/contexts/thread-list-context.d.ts +0 -28
  376. package/esm/src/react/components/chat/chat/contexts/thread-list-context.d.ts.map +0 -1
  377. package/esm/src/react/components/chat/chat/contexts/thread-list-context.js +0 -27
  378. package/esm/src/react/components/chat/chat/hooks/use-threads.d.ts +0 -28
  379. package/esm/src/react/components/chat/chat/hooks/use-threads.d.ts.map +0 -1
  380. package/esm/src/react/components/chat/chat/hooks/use-threads.js +0 -151
  381. package/esm/src/react/components/chat/chat-with-sidebar.d.ts +0 -110
  382. package/esm/src/react/components/chat/chat-with-sidebar.d.ts.map +0 -1
  383. package/esm/src/react/components/chat/chat-with-sidebar.js +0 -167
  384. package/esm/src/react/components/chat/message.d.ts +0 -42
  385. package/esm/src/react/components/chat/message.d.ts.map +0 -1
  386. package/esm/src/react/components/chat/message.js +0 -69
@@ -50,10 +50,10 @@ declare namespace _default {
50
50
  "agents/rag.ts": string;
51
51
  "app/api/ag-ui/route.ts": string;
52
52
  "app/api/ingest/route.ts": string;
53
- "app/api/uploads/[id]/route.ts": string;
54
53
  "app/api/uploads/route.ts": string;
55
54
  "app/layout.tsx": string;
56
55
  "app/page.tsx": string;
56
+ "app/uploads/page.tsx": string;
57
57
  "content/architecture.md": string;
58
58
  "content/getting-started.md": string;
59
59
  "globals.css": string;
@@ -21,22 +21,22 @@ export default {
21
21
  },
22
22
  "ai-agent": {
23
23
  "files": {
24
- "agents/assistant.ts": "import { agent } from \"veryfront/agent\";\n\nexport default agent({\n id: \"assistant\",\n system: \"You are a helpful assistant. Answer questions clearly and concisely.\",\n tools: true,\n maxSteps: 10,\n});\n",
24
+ "agents/assistant.ts": "import { agent } from \"veryfront/agent\";\n\nexport default agent({\n id: \"assistant\",\n name: \"AI Agent\",\n description: \"Ask questions and use tools.\",\n system: \"You are a helpful assistant. Answer questions clearly and concisely.\",\n tools: true,\n maxSteps: 10,\n suggestions: {\n suggestions: [\n {\n type: \"prompt\",\n title: \"Draft a plan\",\n prompt: \"Help me make a concise plan for \",\n },\n {\n type: \"prompt\",\n title: \"Explain a topic\",\n prompt: \"Explain this clearly: \",\n },\n ],\n },\n});\n",
25
25
  "app/api/ag-ui/route.ts": "import { createAgUiHandler } from \"veryfront/agent\";\n\nexport const POST = createAgUiHandler(\"assistant\");\n",
26
26
  "app/layout.tsx": "import \"../globals.css\";\nimport { Head } from \"veryfront/head\";\n\nexport default function RootLayout({\n children,\n}: {\n children: React.ReactNode;\n}): React.ReactNode {\n return (\n <>\n <Head>\n <title>AI Chat</title>\n </Head>\n <div className=\"flex flex-col h-screen bg-white dark:bg-neutral-900\">\n {children}\n </div>\n </>\n );\n}\n",
27
- "app/page.tsx": "'use client'\n\nimport { Chat, useChat } from 'veryfront/chat'\n\nexport default function ChatPage(): React.JSX.Element {\n const chat = useChat({ api: '/api/ag-ui' })\n\n return <Chat {...chat} className=\"flex-1 min-h-0\" placeholder=\"Message\" />\n}\n",
27
+ "app/page.tsx": "'use client'\n\nimport { Chat } from 'veryfront/chat'\n\nexport default function ChatPage(): React.JSX.Element {\n return <Chat agentId=\"assistant\" api=\"/api/ag-ui\" className=\"flex-1 min-h-0\" placeholder=\"Message\" />\n}\n",
28
28
  "globals.css": "@import \"tailwindcss\";\n",
29
- "README.md": "# AI Agent\n\nA simple conversational AI with tool support.\n\n## What's included\n\n- Single assistant agent with streaming chat UI\n- Example calculator tool\n- `useChat` hook for real-time responses\n\n## Structure\n\n```\nagents/assistant.ts Agent definition\ntools/calculator.ts Example tool\napp/\n api/ag-ui/route.ts AG-UI endpoint\n page.tsx Chat interface\n```\n\nThis starter is not production-ready.\n",
29
+ "README.md": "# AI Agent\n\nA simple conversational AI with tool support.\n\n## What's included\n\n- Single assistant agent with streaming chat UI\n- Example calculator tool\n- App-mode `Chat` component for real-time responses\n\n## Structure\n\n```\nagents/assistant.ts Agent definition\ntools/calculator.ts Example tool\napp/\n api/ag-ui/route.ts AG-UI endpoint\n page.tsx Chat interface\n```\n\nThis starter is not production-ready.\n",
30
30
  "tools/calculator.ts": "import { tool } from \"veryfront/tool\";\nimport { defineSchema } from \"veryfront/schemas\";\n\nexport default tool({\n id: \"calculator\",\n description: \"Perform basic arithmetic operations\",\n inputSchema: defineSchema((v) => v.object({\n operation: v.enum([\"add\", \"subtract\", \"multiply\", \"divide\"]),\n a: v.number(),\n b: v.number(),\n }))(),\n execute: ({ operation, a, b }) => {\n if (operation === \"divide\" && b === 0) {\n throw new Error(\"Cannot divide by zero\");\n }\n\n if (operation === \"add\") return { result: a + b };\n if (operation === \"subtract\") return { result: a - b };\n if (operation === \"multiply\") return { result: a * b };\n return { result: a / b };\n },\n});\n",
31
31
  "tsconfig.json": "{\n \"compilerOptions\": {\n \"target\": \"ES2022\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"jsx\": \"react-jsx\",\n \"skipLibCheck\": true,\n \"esModuleInterop\": true,\n \"paths\": {\n \"@/*\": [\"./*\"]\n }\n },\n \"include\": [\"**/*.ts\", \"**/*.tsx\"],\n \"exclude\": [\"node_modules\"]\n}\n"
32
32
  }
33
33
  },
34
34
  "coding-agent": {
35
35
  "files": {
36
- "agents/coder.ts": "import { agent } from \"veryfront/agent\";\n\nexport default agent({\n id: \"coder\",\n system: `You are an expert coding assistant. You can read, search, and modify code files in the project.\n\nWhen asked to make changes:\n1. First read the relevant files to understand the codebase\n2. Explain what you'll change and why\n3. Make the changes\n4. Verify the result\n\nAlways explain your reasoning before making edits.`,\n tools: true,\n maxSteps: 15,\n});\n",
36
+ "agents/coder.ts": "import { agent } from \"veryfront/agent\";\n\nexport default agent({\n id: \"coder\",\n name: \"Code Agent\",\n description: \"Read, search, and edit project files.\",\n system: `You are an expert coding assistant. You can read, search, and modify code files in the project.\n\nWhen asked to make changes:\n1. First read the relevant files to understand the codebase\n2. Explain what you'll change and why\n3. Make the changes\n4. Verify the result\n\nAlways explain your reasoning before making edits.`,\n tools: true,\n maxSteps: 15,\n suggestions: {\n suggestions: [\n {\n type: \"prompt\",\n title: \"Explain the codebase\",\n prompt: \"Explain how this project is organized.\",\n },\n {\n type: \"prompt\",\n title: \"Make a change\",\n prompt: \"Make this code change: \",\n },\n ],\n },\n});\n",
37
37
  "app/api/ag-ui/route.ts": "import { createAgUiHandler } from \"veryfront/agent\";\n\nexport const POST = createAgUiHandler(\"coder\");\n",
38
38
  "app/layout.tsx": "import \"../globals.css\";\nimport { Head } from \"veryfront/head\";\n\nexport default function RootLayout({\n children,\n}: {\n children: React.ReactNode;\n}): React.ReactNode {\n return (\n <>\n <Head>\n <title>Code Agent</title>\n </Head>\n <div className=\"dark\">\n <div className=\"flex flex-col h-screen bg-neutral-950\">\n <header className=\"flex-shrink-0 border-b border-neutral-800\">\n <div className=\"max-w-4xl mx-auto flex items-center gap-3 px-4 py-3\">\n <div className=\"w-8 h-8 rounded-lg bg-emerald-500/10 flex items-center justify-center\">\n <svg\n className=\"w-4 h-4 text-emerald-400\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth={2}\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M17.25 6.75L22.5 12l-5.25 5.25m-10.5 0L1.5 12l5.25-5.25m7.5-3l-4.5 16.5\"\n />\n </svg>\n </div>\n <div>\n <h1 className=\"font-medium text-white text-sm font-mono\">\n code-agent\n </h1>\n <p className=\"text-xs text-neutral-500\">\n read, search, edit project files\n </p>\n </div>\n <div className=\"ml-auto flex items-center gap-1.5\">\n <span className=\"w-2 h-2 rounded-full bg-emerald-400 animate-pulse\" />\n <span className=\"text-xs text-neutral-500 font-mono\">ready</span>\n </div>\n </div>\n </header>\n {children}\n </div>\n </div>\n </>\n );\n}\n",
39
- "app/page.tsx": "'use client'\n\nimport { Chat, useChat } from 'veryfront/chat'\n\nexport default function CodeAgent(): React.JSX.Element {\n const chat = useChat({ api: '/api/ag-ui' })\n\n return (\n <Chat\n {...chat}\n className=\"flex-1 min-h-0\"\n placeholder=\"Describe what you want to build or fix...\"\n />\n )\n}\n",
39
+ "app/page.tsx": "'use client'\n\nimport { Chat } from 'veryfront/chat'\n\nexport default function CodeAgent(): React.JSX.Element {\n return (\n <Chat\n agentId=\"coder\"\n api=\"/api/ag-ui\"\n className=\"flex-1 min-h-0\"\n placeholder=\"Describe what you want to build or fix...\"\n />\n )\n}\n",
40
40
  "globals.css": "@import \"tailwindcss\";\n",
41
41
  "README.md": "# Coding Agent\n\nAn AI assistant that can read, understand, and modify project files.\n\n## What's included\n\n- Coder agent with file system tools\n- Read, list, and edit files through conversation\n- Safe search/replace editing pattern\n\n## Structure\n\n```\nagents/coder.ts Agent with coding instructions\ntools/\n read-file.ts Read file contents\n list-files.ts List directory contents\n edit-file.ts Search and replace in files\napp/\n api/ag-ui/route.ts AG-UI endpoint\n page.tsx Chat interface\n```\n\nThis starter is not production-ready.\n",
42
42
  "tools/edit-file.ts": "import { tool } from \"veryfront/tool\";\nimport { defineSchema } from \"veryfront/schemas\";\nimport { cwd, readTextFile, realPath, resolve, writeTextFile } from \"veryfront/fs\";\n\n/** True when `target` is the same as, or nested under, `root` (both canonical). */\nfunction isWithin(root: string, target: string): boolean {\n const r = root.replace(/\\\\/g, \"/\");\n const t = target.replace(/\\\\/g, \"/\");\n return t === r || t.startsWith(`${r}/`);\n}\n\nexport default tool({\n id: \"edit-file\",\n description: \"Edit a file by replacing a specific string with new content\",\n inputSchema: defineSchema((v) => v.object({\n path: v.string().describe(\"File path relative to the project root\"),\n search: v.string().describe(\"Exact string to find in the file\"),\n replace: v.string().describe(\"String to replace it with\"),\n }))(),\n execute: async ({ path, search, replace }) => {\n let projectDir: string;\n let absolute: string;\n try {\n // Canonicalize both sides so a symlink that points outside the project\n // is resolved to its real target before the containment check.\n projectDir = await realPath(cwd());\n absolute = await realPath(resolve(projectDir, path));\n } catch {\n return { error: `File not found: ${path}` };\n }\n if (!isWithin(projectDir, absolute)) {\n return { error: `Path escapes project directory: ${path}` };\n }\n\n const content = await readTextFile(absolute);\n if (!content.includes(search)) {\n return { error: \"Search string not found in file\" };\n }\n\n const updated = content.replace(search, replace);\n await writeTextFile(absolute, updated);\n return { path, success: true };\n },\n});\n",
@@ -47,17 +47,17 @@ export default {
47
47
  },
48
48
  "docs-agent": {
49
49
  "files": {
50
- "agents/rag.ts": "import { agent } from \"veryfront/agent\";\n\nexport default agent({\n id: \"rag\",\n system:\n `You answer questions using the provided documents. ` +\n `Always cite your sources by referencing the document title. ` +\n `If the search results don't contain a clear answer, say so honestly.`,\n});\n",
50
+ "agents/rag.ts": "import { agent } from \"veryfront/agent\";\n\nexport default agent({\n id: \"rag\",\n name: \"Docs Agent\",\n description: \"Upload files and ask questions.\",\n system:\n `You answer questions using the provided documents. ` +\n `Always cite your sources by referencing the document title. ` +\n `If the search results don't contain a clear answer, say so honestly.`,\n suggestions: {\n suggestions: [\n {\n type: \"prompt\",\n title: \"Ask Question\",\n prompt: \"I have a question about this document: \",\n },\n {\n type: \"prompt\",\n title: \"Extract Insights\",\n prompt: \"Extract the key insights from the uploaded documents.\",\n },\n {\n type: \"prompt\",\n title: \"Find Sources\",\n prompt: \"Find relevant sources and references in the documents for: \",\n },\n ],\n },\n});\n",
51
51
  "app/api/ag-ui/route.ts": "import { createAgUiHandler } from \"veryfront/agent\";\nimport { store } from \"../../../store.ts\";\n\nexport const POST = createAgUiHandler(\"rag\", {\n beforeStream: async ({ lastUserText }) => {\n const query = lastUserText.trim();\n if (!query) return;\n\n try {\n const results = await store.search(query, { topK: 5 });\n if (results.length === 0) return;\n\n const contextBlock = results\n .map(\n (result) =>\n `[${result.title}] (score: ${\n result.score.toFixed(2)\n })\\n${result.text}`,\n )\n .join(\"\\n\\n---\\n\\n\");\n\n return {\n prepend: [\n {\n role: \"system\",\n parts: [\n {\n type: \"text\",\n text:\n `Here are relevant documents retrieved for your question:\\n\\n${contextBlock}\\n\\n` +\n \"Use these documents to answer. Cite the document title when referencing information.\",\n },\n ],\n },\n ],\n };\n } catch (e) {\n console.error(\"[RAG] Retrieval failed:\", e);\n return;\n }\n },\n});\n",
52
52
  "app/api/ingest/route.ts": "import { store } from \"../../../store.ts\";\n\nexport async function POST() {\n await store.indexContentDir();\n return Response.json({ ok: true });\n}\n",
53
- "app/api/uploads/[id]/route.ts": "import { createUploadHandler } from \"veryfront/embedding\";\nimport { store } from \"../../../../store.ts\";\n\nexport const { DELETE } = createUploadHandler(store, {\n auth: { type: \"none\", allowUnauthenticated: true },\n});\n",
54
- "app/api/uploads/route.ts": "import { createUploadHandler } from \"veryfront/embedding\";\nimport { store } from \"../../../store.ts\";\n\nexport const { POST, GET } = createUploadHandler(store, {\n auth: { type: \"none\", allowUnauthenticated: true },\n});\n",
55
- "app/layout.tsx": "import \"../globals.css\";\nimport { Head } from \"veryfront/head\";\n\nexport default function RootLayout({ children }: { children: React.ReactNode }): React.ReactNode {\n return (\n <>\n <Head><title>Docs Agent</title></Head>\n <div className=\"flex flex-col h-screen\">\n {children}\n </div>\n </>\n );\n}\n",
56
- "app/page.tsx": "'use client'\n\nimport { useState, useEffect, useCallback, useMemo } from 'react'\nimport { ChatWithSidebar, useChat, type QuickAction } from 'veryfront/chat'\n\nconst UPLOAD_API = '/api/uploads'\nconst ACCEPT = '.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.csv,.txt,.md,.mdx,.html,.rtf,.epub,.json,.xml'\n\nconst QUICK_ACTIONS: QuickAction[] = [\n { id: 'ask-question', label: 'Ask Question', prompt: 'I have a question about this document: ' },\n { id: 'extract-insights', label: 'Extract Insights', prompt: 'Extract the key insights from the uploaded documents.' },\n { id: 'find-sources', label: 'Find Sources', prompt: 'Find relevant sources and references in the documents for: ' },\n]\n\ninterface Doc { id: string; title: string; source: string; url?: string }\n\nfunction useUploads(api: string) {\n const [docs, setDocs] = useState<Doc[]>([])\n const [uploading, setUploading] = useState(false)\n const [error, setError] = useState<string | null>(null)\n\n const refresh = useCallback(async () => {\n try {\n const res = await fetch(api)\n if (res.ok) {\n const data = await res.json()\n setDocs(Array.isArray(data) ? data : data.uploads ?? [])\n }\n } catch { /* ignore */ }\n }, [api])\n\n useEffect(() => { refresh() }, [refresh])\n\n const upload = useCallback(async (file: File) => {\n setUploading(true)\n setError(null)\n try {\n const form = new FormData()\n form.append('file', file)\n const res = await fetch(api, { method: 'POST', body: form })\n if (!res.ok) throw new Error(await res.text())\n await refresh()\n } catch (e) {\n setError(e instanceof Error ? e.message : 'Upload failed')\n } finally {\n setUploading(false)\n }\n }, [api, refresh])\n\n const remove = useCallback(async (id: string) => {\n await fetch(`${api}/${id}`, { method: 'DELETE' })\n await refresh()\n }, [api, refresh])\n\n const uploads = useMemo(\n () => docs.filter((d) => d.source.startsWith('upload:')),\n [docs],\n )\n\n return { uploads, uploading, error, upload, remove }\n}\n\nexport default function DocsChat() {\n const chat = useChat({ api: '/api/ag-ui' })\n const docs = useUploads(UPLOAD_API)\n\n const attachmentItems = useMemo(() => {\n const items = docs.uploads.map((d) => ({\n id: d.id,\n name: d.title,\n status: 'ready' as const,\n }))\n if (docs.uploading) {\n items.push({ id: '__uploading', name: 'Uploading...', status: 'uploading' as const })\n }\n return items\n }, [docs.uploads, docs.uploading])\n\n const uploadFiles = useMemo(\n () => docs.uploads.map((d) => ({ id: d.id, name: d.title, url: d.url })),\n [docs.uploads],\n )\n\n const handleAttach = useCallback((files: FileList) => {\n for (const file of Array.from(files)) {\n docs.upload(file)\n }\n }, [docs.upload])\n\n const handleQuickAction = useCallback((action: QuickAction) => {\n if (action.prompt) chat.setInput(action.prompt)\n }, [chat.setInput])\n\n return (\n <ChatWithSidebar\n chat={chat}\n sidebar={{ storageKey: 'rag-threads' }}\n features={{ steps: true, tabs: true, sources: true, export: true }}\n models={{\n options: [\n {\n value: 'anthropic/claude-sonnet-4-6',\n label: 'Claude Sonnet',\n },\n {\n value: 'openai/gpt-4.1-mini',\n label: 'GPT-4.1 Mini',\n },\n {\n value: 'google/gemini-2.5-flash',\n label: 'Gemini 2.5 Flash',\n badge: 'Fast',\n },\n ],\n }}\n attachments={{\n uploads: uploadFiles,\n onRemoveUpload: docs.remove,\n onAttach: handleAttach,\n accept: ACCEPT,\n items: attachmentItems,\n onRemoveItem: docs.remove,\n }}\n quickActions={{\n actions: QUICK_ACTIONS,\n onAction: handleQuickAction,\n }}\n message={{\n renderTool: () => null,\n }}\n className=\"flex-1 min-h-0\"\n placeholder=\"Ask anything about your documents...\"\n emptyState={{ title: 'Docs Agent', description: 'Upload files and ask questions' }}\n />\n )\n}\n",
53
+ "app/api/uploads/route.ts": "import { createUploadHandler } from \"veryfront/embedding\";\nimport { store } from \"../../../store.ts\";\n\nexport const { POST, GET, DELETE } = createUploadHandler(store, {\n auth: { type: \"none\", allowUnauthenticated: true },\n});\n",
54
+ "app/layout.tsx": "'use client'\n\nimport \"../globals.css\";\nimport {\n AppShell,\n ChatSidebar,\n ChatThemeScope,\n ConversationsProvider,\n Tabs,\n TabsItem,\n} from \"veryfront/chat\";\nimport { Head } from \"veryfront/head\";\nimport { useRouter } from \"veryfront/router\";\n\nexport default function RootLayout({ children }: { children: React.ReactNode }): React.ReactNode {\n const router = useRouter();\n const activeTab = router.pathname.startsWith(\"/uploads\") ? \"uploads\" : \"chat\";\n\n return (\n <>\n <Head><title>Docs Agent</title></Head>\n <ChatThemeScope className=\"flex flex-col h-screen\">\n <ConversationsProvider storageKey=\"rag-conversations\">\n <AppShell className=\"flex-1 min-h-0\">\n <AppShell.Sidebar side=\"left\" className=\"border-r border-[var(--outline-border)]\">\n <AppShell.SidebarContent className=\"p-0\">\n <ChatSidebar fill />\n </AppShell.SidebarContent>\n </AppShell.Sidebar>\n <AppShell.Main>\n <AppShell.Header border className=\"h-16 gap-3 px-3\">\n <AppShell.Trigger side=\"left\" />\n <div className=\"flex flex-1 justify-center\">\n <Tabs\n value={activeTab}\n onValueChange={(value) => router.push(value === \"uploads\" ? \"/uploads\" : \"/\")}\n >\n <TabsItem value=\"chat\">Chat</TabsItem>\n <TabsItem value=\"uploads\">Uploads</TabsItem>\n </Tabs>\n </div>\n </AppShell.Header>\n <AppShell.Content className=\"flex flex-col min-h-0 pt-3\">\n {children}\n </AppShell.Content>\n </AppShell.Main>\n </AppShell>\n </ConversationsProvider>\n </ChatThemeScope>\n </>\n );\n}\n",
55
+ "app/page.tsx": "'use client'\n\nimport { Chat } from 'veryfront/chat'\n\nconst ACCEPT = '.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.csv,.txt,.md,.mdx,.html,.rtf,.epub,.json,.xml'\n\nexport default function DocsChat() {\n return (\n <Chat\n agentId=\"rag\"\n api=\"/api/ag-ui\"\n uploadApi=\"/api/uploads\"\n showSteps\n showSources\n attachAccept={ACCEPT}\n className=\"flex-1 min-h-0\"\n placeholder=\"Ask anything about your documents...\"\n />\n )\n}\n",
56
+ "app/uploads/page.tsx": "'use client'\n\nimport { AttachmentsPanel, useUploadsRegistry } from 'veryfront/chat'\n\nconst UPLOAD_API = '/api/uploads'\nconst ACCEPT = '.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.csv,.txt,.md,.mdx,.html,.rtf,.epub,.json,.xml'\n\nexport default function UploadsPage(): React.JSX.Element {\n const uploads = useUploadsRegistry({ url: UPLOAD_API, storageKey: 'rag-uploads' })\n\n return (\n <AttachmentsPanel\n uploads={uploads.items}\n loading={uploads.isLoading}\n onAttach={uploads.upload}\n onRemoveUpload={uploads.remove}\n attachAccept={ACCEPT}\n className=\"flex-1 min-h-0\"\n />\n )\n}\n",
57
57
  "content/architecture.md": "# Architecture\n\nAcme Platform uses a modular, event-driven architecture.\n\n## Core Components\n\n### API Gateway\nRoutes incoming requests to the appropriate microservice. Handles authentication, rate limiting, and request validation.\n\n### Event Bus\nAsynchronous message broker connecting all services. Supports pub/sub and point-to-point messaging patterns.\n\n### Data Layer\nMulti-tenant data storage with automatic sharding. Supports PostgreSQL for relational data and Redis for caching.\n\n## Request Flow\n\n1. Client sends request to API Gateway\n2. Gateway validates authentication token\n3. Request is routed to the target service\n4. Service processes request and publishes events\n5. Response is returned through the gateway\n\n## Scaling\n\nEach component scales independently. The API Gateway uses horizontal scaling with load balancing. Services auto-scale based on queue depth and CPU utilization.\n\n## Security\n\n- All inter-service communication uses mTLS\n- API tokens are rotated every 24 hours\n- Data at rest is encrypted with AES-256\n- Audit logs are retained for 90 days\n",
58
58
  "content/getting-started.md": "# Getting Started\n\nWelcome to Acme Platform. This guide covers initial setup and core concepts.\n\n## Installation\n\nInstall the CLI globally:\n\n```bash\nnpm install -g @acme/cli\n```\n\n## Creating a Project\n\nRun the init command to scaffold a new project:\n\n```bash\nacme init my-project\ncd my-project\n```\n\n## Project Structure\n\n- `src/`: Application source code\n- `config/`: Configuration files\n- `tests/`: Test suite\n- `docs/`: Documentation\n\n## Configuration\n\nCreate an `acme.config.ts` file in your project root:\n\n```ts\nexport default {\n name: \"my-project\",\n region: \"us-east-1\",\n features: [\"auth\", \"storage\"],\n};\n```\n\n## Next Steps\n\n- Read the [Architecture Guide](./architecture) to understand the system design\n- Check [API Reference](./api-reference) for available endpoints\n- Join our Discord community for support\n",
59
59
  "globals.css": "@import \"tailwindcss\";\n",
60
- "README.md": "# Docs Agent\n\nA chatbot that answers questions from your own documents using Retrieval-Augmented Generation (RAG).\n\n## What's included\n\n- Q&A agent with source citation\n- Embedding-based semantic search with convention-based model selection\n- Document upload supporting PDF, DOCX, XLSX, PPTX, CSV, HTML, RTF, EPUB, TXT, and Markdown\n- `ragStore()` with local JSON storage by default, and Veryfront Cloud RAG when bootstrap is present\n- Veryfront Cloud AI Gateway routing for generation and embeddings when bootstrap is present\n- Original uploaded files stored in Veryfront Cloud project uploads when cloud bootstrap is present\n- Sample content in `/content` indexed through a dedicated ingestion route\n\n## Getting started\n\n1. Set your Veryfront Cloud bootstrap vars:\n\n ```bash\n export VERYFRONT_API_TOKEN=vf_...\n export VERYFRONT_PROJECT_SLUG=my-project\n ```\n\n2. Start the dev server:\n\n ```bash\n npx veryfront dev\n ```\n\n3. Index the sample docs in `content/`:\n\n ```bash\n curl -X POST http://localhost:3000/api/ingest\n ```\n\n4. Open the app and upload a document or ask a question.\n\nIf you are using a self-hosted Veryfront API, also set `VERYFRONT_API_URL`.\n\n## Cloud mode\n\nWith `VERYFRONT_API_TOKEN` and `VERYFRONT_PROJECT_SLUG` set, the template uses\nVeryfront Cloud automatically:\n\n- Agent generation routes through Veryfront Cloud model routing.\n- Query and document embeddings route through Veryfront Cloud embedding routing.\n- `veryfront-cloud/openai/...` and `veryfront-cloud/google/...` models use AI Gateway.\n- RAG documents, chunks, and embeddings are stored in the target project.\n\nThe default cloud embedding model is\n`veryfront-cloud/openai/text-embedding-3-small`. Set\n`VERYFRONT_DEFAULT_EMBEDDING_MODEL` only when you need a different embedding\nmodel.\n\n## Architecture\n\nRAG grounds LLM responses in your documents through three pipelines: **Ingestion**, **Query**, and **RAG**. These pipelines are orchestrated around a shared vector store.\n\n```mermaid\nflowchart LR\n ChatUI_L[\"Chat UI\"]\n\n subgraph IngestionFlow[\"Ingestion Pipeline\"]\n D[\"Documents\"] --> EXT[\"Extraction\"] --> DC[\"Chunking\"] --> DE[\"Document\\nEmbedding\"] --> ING[\"Storage\"]\n end\n\n subgraph QueryFlow[\"Query Pipeline\"]\n Q[\"Query\"] --> QE[\"Query\\nEmbedding\"] --> SS[\"Similarity\\nSearch\"]\n end\n\n subgraph RAGFlow[\"RAG Pipeline\"]\n BF[\"beforeStream\\nHook\"] --> RET[\"Retrieval\"] --> AUG[\"Augmentation\"] --> AG[\"Agent\"] --> GEN[\"Generation\"]\n end\n\n EMB((\"Embedding\\nModel\"))\n GEN_LLM((\"Generative\\nModel\"))\n VS[(\"Vector\\nStore\")]\n ChatUI_R[\"Chat UI\"]\n\n ChatUI_L --> D\n ChatUI_L --> Q\n\n QE -.- EMB\n DE -.- EMB\n\n SS --> VS\n ING --> VS\n\n Q --> BF\n VS --> RET\n AG -.- GEN_LLM\n GEN -.- GEN_LLM\n GEN --> ChatUI_R\n```\n\n### Pipelines\n\n**Ingestion**: Documents are parsed into plain text via the built-in kreuzberg extraction engine (supporting PDF, DOCX, XLSX, PPTX, HTML, RTF, EPUB, and 76+ formats), split into overlapping chunks (~1000 chars, 200 char overlap), and stored in the default `ragStore()`. In local mode that means `data/index.json`; with Veryfront Cloud bootstrap it upgrades to the cloud RAG backend automatically. The original uploaded binary is also stored in the project's Veryfront Cloud uploads store so remote projects retain the source file, not just the extracted text. Uploaded files are ingested by the upload route. Bundled files in `content/` are ingested by the `/api/ingest` route.\n\n**Query**: The user's query is embedded into the same vector space as the documents, then compared against all stored chunks using cosine similarity to find the top-*k* most relevant results.\n\n**RAG**: The `beforeStream` hook in the AG-UI route intercepts each message before it reaches the agent. It searches the document store for relevant chunks, assembles them into context, and prepends them as retrieved reference data. The agent then generates a cited response streamed back to the user.\n\n## Structure\n\n```\nstore.ts RAG store config\nagents/rag.ts Q&A agent with citation instructions\ncontent/\n getting-started.md Sample document\n architecture.md Sample document\napp/\n api/ag-ui/route.ts AG-UI endpoint\n api/ingest/route.ts Bundled content ingestion\n api/uploads/route.ts Upload (POST) and list (GET) uploads\n api/uploads/[id]/route.ts Delete upload\n page.tsx Chat UI with document upload panel\n layout.tsx Root layout with header\n```\n\n## Framework usage\n\n| What | Framework | Template code |\n|------|-----------|---------------|\n| Chat UI + streaming | `Chat`, `useChat` | `page.tsx` |\n| Upload management | `useUploads` hook | `page.tsx` |\n| Source display | `showSources` prop on `Chat` | `page.tsx` |\n| Upload API routes | `createUploadHandler` | 1-line per route file |\n| AG-UI route | `createAgUiHandler` | 1 line in `route.ts` |\n| Agent definition | `agent()` | Config object in `agents/rag.ts` |\n| RAG retrieval | `beforeStream` hook | Context injection in `api/ag-ui/route.ts` |\n| Vector store | `ragStore()` | Config in `store.ts` |\n\n## Adding documents\n\n- Drop files into `content/`, then run `curl -X POST http://localhost:3000/api/ingest`\n- Or use the upload panel in the UI for PDF, DOCX, XLSX, PPTX, CSV, HTML, RTF, EPUB, TXT, and MD files\n\n## Production notes\n\nThis is a starter template, not a production-ready setup. For production, consider:\n\n- **Vector store**: Replace the default store with pgvector, Pinecone, or Qdrant for datasets beyond ~10k chunks\n- **Reranking**: Add a cross-encoder reranker (e.g. Cohere Rerank) after retrieval to improve precision\n- **Hybrid search**: Combine dense vectors with BM25 keyword matching for better recall\n",
60
+ "README.md": "# Docs Agent\n\nA chatbot that answers questions from your own documents using Retrieval-Augmented Generation (RAG).\n\n## What's included\n\n- Q&A agent with source citation\n- Embedding-based semantic search with convention-based model selection\n- Document upload supporting PDF, DOCX, XLSX, PPTX, CSV, HTML, RTF, EPUB, TXT, and Markdown\n- `ragStore()` with local JSON storage by default, and Veryfront Cloud RAG when bootstrap is present\n- Veryfront Cloud AI Gateway routing for generation and embeddings when bootstrap is present\n- Original uploaded files stored in Veryfront Cloud project uploads when cloud bootstrap is present\n- Sample content in `/content` indexed through a dedicated ingestion route\n\n## Getting started\n\n1. Set your Veryfront Cloud bootstrap vars:\n\n ```bash\n export VERYFRONT_API_TOKEN=vf_...\n export VERYFRONT_PROJECT_SLUG=my-project\n ```\n\n2. Start the dev server:\n\n ```bash\n npx veryfront dev\n ```\n\n3. Index the sample docs in `content/`:\n\n ```bash\n curl -X POST http://localhost:3000/api/ingest\n ```\n\n4. Open the app and upload a document or ask a question.\n\nIf you are using a self-hosted Veryfront API, also set `VERYFRONT_API_URL`.\n\n## Cloud mode\n\nWith `VERYFRONT_API_TOKEN` and `VERYFRONT_PROJECT_SLUG` set, the template uses\nVeryfront Cloud automatically:\n\n- Agent generation routes through Veryfront Cloud model routing.\n- Query and document embeddings route through Veryfront Cloud embedding routing.\n- `veryfront-cloud/openai/...` and `veryfront-cloud/google/...` models use AI Gateway.\n- RAG documents, chunks, and embeddings are stored in the target project.\n\nThe default cloud embedding model is\n`veryfront-cloud/openai/text-embedding-3-small`. Set\n`VERYFRONT_DEFAULT_EMBEDDING_MODEL` only when you need a different embedding\nmodel.\n\n## Architecture\n\nRAG grounds LLM responses in your documents through three pipelines: **Ingestion**, **Query**, and **RAG**. These pipelines are orchestrated around a shared vector store.\n\n```mermaid\nflowchart LR\n ChatUI_L[\"Chat UI\"]\n\n subgraph IngestionFlow[\"Ingestion Pipeline\"]\n D[\"Documents\"] --> EXT[\"Extraction\"] --> DC[\"Chunking\"] --> DE[\"Document\\nEmbedding\"] --> ING[\"Storage\"]\n end\n\n subgraph QueryFlow[\"Query Pipeline\"]\n Q[\"Query\"] --> QE[\"Query\\nEmbedding\"] --> SS[\"Similarity\\nSearch\"]\n end\n\n subgraph RAGFlow[\"RAG Pipeline\"]\n BF[\"beforeStream\\nHook\"] --> RET[\"Retrieval\"] --> AUG[\"Augmentation\"] --> AG[\"Agent\"] --> GEN[\"Generation\"]\n end\n\n EMB((\"Embedding\\nModel\"))\n GEN_LLM((\"Generative\\nModel\"))\n VS[(\"Vector\\nStore\")]\n ChatUI_R[\"Chat UI\"]\n\n ChatUI_L --> D\n ChatUI_L --> Q\n\n QE -.- EMB\n DE -.- EMB\n\n SS --> VS\n ING --> VS\n\n Q --> BF\n VS --> RET\n AG -.- GEN_LLM\n GEN -.- GEN_LLM\n GEN --> ChatUI_R\n```\n\n### Pipelines\n\n**Ingestion**: Documents are parsed into plain text via the built-in kreuzberg extraction engine (supporting PDF, DOCX, XLSX, PPTX, HTML, RTF, EPUB, and 76+ formats), split into overlapping chunks (~1000 chars, 200 char overlap), and stored in the default `ragStore()`. In local mode that means `data/index.json`; with Veryfront Cloud bootstrap it upgrades to the cloud RAG backend automatically. The original uploaded binary is also stored in the project's Veryfront Cloud uploads store so remote projects retain the source file, not just the extracted text. Uploaded files are ingested by the upload route. Bundled files in `content/` are ingested by the `/api/ingest` route.\n\n**Query**: The user's query is embedded into the same vector space as the documents, then compared against all stored chunks using cosine similarity to find the top-*k* most relevant results.\n\n**RAG**: The `beforeStream` hook in the AG-UI route intercepts each message before it reaches the agent. It searches the document store for relevant chunks, assembles them into context, and prepends them as retrieved reference data. The agent then generates a cited response streamed back to the user.\n\n## Structure\n\n```\nstore.ts RAG store config\nagents/rag.ts Q&A agent with citation instructions\ncontent/\n getting-started.md Sample document\n architecture.md Sample document\napp/\n api/ag-ui/route.ts AG-UI endpoint\n api/ingest/route.ts Bundled content ingestion\n api/uploads/route.ts Upload, list, and delete uploads\n uploads/page.tsx Upload management panel\n page.tsx Chat UI\n layout.tsx Chat shell with sidebar and tabs\n```\n\n## Framework usage\n\n| What | Framework | Template code |\n|------|-----------|---------------|\n| Chat UI + streaming | app-mode `Chat` | `page.tsx` |\n| Upload management | `AttachmentsPanel`, `useUploadsRegistry` | `uploads/page.tsx` |\n| Source display | `showSources` prop on `Chat` | `page.tsx` |\n| Upload API route | `createUploadHandler` | 1 line in `route.ts` |\n| AG-UI route | `createAgUiHandler` | 1 line in `route.ts` |\n| Agent definition | `agent()` | Config object in `agents/rag.ts` |\n| RAG retrieval | `beforeStream` hook | Context injection in `api/ag-ui/route.ts` |\n| Vector store | `ragStore()` | Config in `store.ts` |\n\n## Adding documents\n\n- Drop files into `content/`, then run `curl -X POST http://localhost:3000/api/ingest`\n- Or use the upload panel in the UI for PDF, DOCX, XLSX, PPTX, CSV, HTML, RTF, EPUB, TXT, and MD files\n\n## Production notes\n\nThis is a starter template, not a production-ready setup. For production, consider:\n\n- **Vector store**: Replace the default store with pgvector, Pinecone, or Qdrant for datasets beyond ~10k chunks\n- **Reranking**: Add a cross-encoder reranker (e.g. Cohere Rerank) after retrieval to improve precision\n- **Hybrid search**: Combine dense vectors with BM25 keyword matching for better recall\n",
61
61
  "store.ts": "import { ragStore } from \"veryfront/embedding\";\n\nexport const store = ragStore({\n storagePath: \"data/index.json\",\n contentDir: \"content\",\n});\n",
62
62
  "tsconfig.json": "{\n \"compilerOptions\": {\n \"target\": \"ES2022\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"jsx\": \"react-jsx\",\n \"skipLibCheck\": true,\n \"esModuleInterop\": true,\n \"paths\": {\n \"@/*\": [\"./*\"]\n }\n },\n \"include\": [\"**/*.ts\", \"**/*.tsx\"],\n \"exclude\": [\"node_modules\"]\n}\n"
63
63
  }
@@ -72,12 +72,12 @@ export default {
72
72
  },
73
73
  "multi-agent-system": {
74
74
  "files": {
75
- "agents/orchestrator.ts": "import { agent, getAgentsAsTools } from \"veryfront/agent\";\n\nexport default agent({\n id: \"orchestrator\",\n system:\n \"You coordinate a team of AI agents. \" +\n \"Delegate research tasks to the researcher and writing tasks to the writer. \" +\n \"Combine their outputs into a polished response.\",\n tools: getAgentsAsTools([\"researcher\", \"writer\"]),\n maxSteps: 10,\n});\n",
75
+ "agents/orchestrator.ts": "import { agent, getAgentsAsTools } from \"veryfront/agent\";\n\nexport default agent({\n id: \"orchestrator\",\n name: \"Agent Team\",\n description: \"Coordinate research and writing agents.\",\n system:\n \"You coordinate a team of AI agents. \" +\n \"Delegate research tasks to the researcher and writing tasks to the writer. \" +\n \"Combine their outputs into a polished response.\",\n tools: getAgentsAsTools([\"researcher\", \"writer\"]),\n maxSteps: 10,\n suggestions: {\n suggestions: [\n {\n type: \"prompt\",\n title: \"Research a topic\",\n prompt: \"Research this topic and summarize the key findings: \",\n },\n {\n type: \"prompt\",\n title: \"Write a brief\",\n prompt: \"Research and write a concise brief about \",\n },\n ],\n },\n});\n",
76
76
  "agents/researcher.ts": "import { agent } from \"veryfront/agent\";\n\nexport default agent({\n id: \"researcher\",\n system:\n \"You are a research specialist. \" +\n \"Gather comprehensive information on the given topic. \" +\n \"Present findings as structured bullet points with key facts and data.\",\n tools: true,\n maxSteps: 5,\n});\n",
77
77
  "agents/writer.ts": "import { agent } from \"veryfront/agent\";\n\nexport default agent({\n id: \"writer\",\n system:\n \"You are a writing specialist. \" +\n \"Take research notes and transform them into clear, engaging prose. \" +\n \"Use a professional but approachable tone.\",\n maxSteps: 3,\n});\n",
78
78
  "app/api/ag-ui/route.ts": "import { createAgUiHandler } from \"veryfront/agent\";\n\nexport const POST = createAgUiHandler(\"orchestrator\");\n",
79
79
  "app/layout.tsx": "import \"../globals.css\";\nimport { Head } from \"veryfront/head\";\n\nexport default function RootLayout({\n children,\n}: {\n children: React.ReactNode;\n}): React.ReactNode {\n return (\n <>\n <Head>\n <title>Multi-Agent System</title>\n </Head>\n <div className=\"flex flex-col h-screen bg-white dark:bg-neutral-950\">\n <header className=\"flex-shrink-0 border-b border-neutral-200 dark:border-neutral-800\">\n <div className=\"max-w-3xl mx-auto flex items-center gap-3 px-4 py-3\">\n <div className=\"flex -space-x-2\">\n <div className=\"w-7 h-7 rounded-full bg-blue-500 ring-2 ring-white dark:ring-neutral-950 flex items-center justify-center text-[10px] font-bold text-white\">\n O\n </div>\n <div className=\"w-7 h-7 rounded-full bg-amber-500 ring-2 ring-white dark:ring-neutral-950 flex items-center justify-center text-[10px] font-bold text-white\">\n R\n </div>\n <div className=\"w-7 h-7 rounded-full bg-violet-500 ring-2 ring-white dark:ring-neutral-950 flex items-center justify-center text-[10px] font-bold text-white\">\n W\n </div>\n </div>\n <div>\n <h1 className=\"font-medium text-neutral-900 dark:text-white text-sm\">\n Agent Team\n </h1>\n <p className=\"text-xs text-neutral-500 dark:text-neutral-400\">\n Orchestrator, Researcher, Writer\n </p>\n </div>\n </div>\n </header>\n {children}\n </div>\n </>\n );\n}\n",
80
- "app/page.tsx": "'use client'\n\nimport { Chat, useChat } from 'veryfront/chat'\n\nexport default function MultiAgentChat(): React.JSX.Element {\n const chat = useChat({ api: '/api/ag-ui' })\n\n return <Chat {...chat} className=\"flex-1 min-h-0\" placeholder=\"Give the team a task...\" />\n}\n",
80
+ "app/page.tsx": "'use client'\n\nimport { Chat } from 'veryfront/chat'\n\nexport default function MultiAgentChat(): React.JSX.Element {\n return (\n <Chat\n agentId=\"orchestrator\"\n api=\"/api/ag-ui\"\n className=\"flex-1 min-h-0\"\n placeholder=\"Give the team a task...\"\n />\n )\n}\n",
81
81
  "globals.css": "@import \"tailwindcss\";\n",
82
82
  "README.md": "# Multi-Agent System\n\nA team of specialized agents that collaborate on tasks.\n\n## What's included\n\n- Orchestrator that delegates to researcher and writer agents\n- Agent-as-tool composition via `getAgentsAsTools()`\n- Web search tool (placeholder, configure your own API)\n\n## Structure\n\n```\nagents/\n orchestrator.ts Coordinates the team\n researcher.ts Gathers information\n writer.ts Produces polished content\ntools/web-search.ts Placeholder search tool\napp/\n api/ag-ui/route.ts AG-UI endpoint\n page.tsx Chat interface\n```\n\nThis starter is not production-ready.\n",
83
83
  "tools/web-search.ts": "import { tool } from \"veryfront/tool\";\nimport { defineSchema } from \"veryfront/schemas\";\n\nexport default tool({\n id: \"web-search\",\n description: \"Search the web for information on a topic\",\n inputSchema: defineSchema((v) => v.object({\n query: v.string().describe(\"Search query\"),\n }))(),\n execute: async ({ query: _query }) => {\n // Connect a real search API to use this tool.\n // Popular options: Tavily, SerpAPI, Brave Search\n throw new Error(\n \"No search API configured. \" +\n \"See https://veryfront.com/docs/code/guides/tools for setup instructions.\",\n );\n },\n});\n",
@@ -86,9 +86,9 @@ export default {
86
86
  },
87
87
  "saas-starter": {
88
88
  "files": {
89
- "agents/assistant.ts": "import { agent } from \"veryfront/agent\";\n\nexport default agent({\n id: \"assistant\",\n system: \"You are a helpful AI assistant. Be concise and direct.\",\n tools: true,\n memory: { type: \"conversation\", maxMessages: 50 },\n maxSteps: 10,\n});\n",
89
+ "agents/assistant.ts": "import { agent } from \"veryfront/agent\";\n\nexport default agent({\n id: \"assistant\",\n name: \"SaaS Assistant\",\n description: \"Answer product and customer questions.\",\n system: \"You are a helpful AI assistant. Be concise and direct.\",\n tools: true,\n memory: { type: \"conversation\", maxMessages: 50 },\n maxSteps: 10,\n suggestions: {\n suggestions: [\n {\n type: \"prompt\",\n title: \"Summarize account\",\n prompt: \"Summarize the latest account activity.\",\n },\n {\n type: \"prompt\",\n title: \"Find customers\",\n prompt: \"Find customers who need attention.\",\n },\n ],\n },\n});\n",
90
90
  "app/api/ag-ui/route.ts": "import { createAgUiHandler } from \"veryfront/agent\";\n\nexport const POST = createAgUiHandler(\"assistant\");\n",
91
- "app/dashboard/page.tsx": "\"use client\";\n\nimport { useState } from \"react\";\nimport { Chat, useChat } from \"veryfront/chat\";\n\ninterface Conversation {\n id: string;\n title: string;\n updatedAt: string;\n}\n\nconst INITIAL_CONVERSATIONS: Conversation[] = [\n { id: \"1\", title: \"Getting started\", updatedAt: \"Just now\" },\n];\n\nexport default function Dashboard(): React.JSX.Element {\n const [conversations] = useState<Conversation[]>(INITIAL_CONVERSATIONS);\n const [activeId, setActiveId] = useState(\"1\");\n const chat = useChat({ api: \"/api/ag-ui\" });\n\n return (\n <div className=\"flex h-screen bg-white dark:bg-neutral-950\">\n {/* Sidebar */}\n <aside className=\"w-64 border-r border-neutral-200 dark:border-neutral-800 flex flex-col bg-neutral-50 dark:bg-neutral-900\">\n <div className=\"p-4 border-b border-neutral-200 dark:border-neutral-800\">\n <button className=\"w-full flex items-center gap-2 px-3 py-2 text-sm font-medium text-neutral-700 dark:text-neutral-300 bg-white dark:bg-neutral-800 border border-neutral-200 dark:border-neutral-700 rounded-lg hover:bg-neutral-50 dark:hover:bg-neutral-700 transition-colors\">\n <svg\n className=\"w-4 h-4\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth={2}\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M12 4.5v15m7.5-7.5h-15\"\n />\n </svg>\n New chat\n </button>\n </div>\n\n <nav className=\"flex-1 overflow-y-auto p-2 space-y-0.5\">\n {conversations.map((conv) => (\n <button\n key={conv.id}\n onClick={() => setActiveId(conv.id)}\n className={`w-full text-left px-3 py-2 rounded-lg text-sm transition-colors ${\n activeId === conv.id\n ? \"bg-neutral-200 dark:bg-neutral-800 text-neutral-900 dark:text-white\"\n : \"text-neutral-600 dark:text-neutral-400 hover:bg-neutral-100 dark:hover:bg-neutral-800/50\"\n }`}\n >\n <p className=\"truncate\">{conv.title}</p>\n <p className=\"text-xs text-neutral-400 mt-0.5\">\n {conv.updatedAt}\n </p>\n </button>\n ))}\n </nav>\n\n <div className=\"p-4 border-t border-neutral-200 dark:border-neutral-800\">\n <div className=\"flex items-center gap-2\">\n <div className=\"w-8 h-8 rounded-full bg-neutral-200 dark:bg-neutral-700 flex items-center justify-center text-xs font-medium text-neutral-600 dark:text-neutral-300\">\n U\n </div>\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm font-medium text-neutral-900 dark:text-white truncate\">\n User\n </p>\n <p className=\"text-xs text-neutral-500 truncate\">\n user@example.com\n </p>\n </div>\n </div>\n </div>\n </aside>\n\n {/* Chat */}\n <main className=\"flex-1 flex flex-col\">\n <Chat {...chat} className=\"flex-1 min-h-0\" placeholder=\"Message...\" />\n </main>\n </div>\n );\n}\n",
91
+ "app/dashboard/page.tsx": "\"use client\";\n\nimport { useState } from \"react\";\nimport { Chat } from \"veryfront/chat\";\n\ninterface Conversation {\n id: string;\n title: string;\n updatedAt: string;\n}\n\nconst INITIAL_CONVERSATIONS: Conversation[] = [\n { id: \"1\", title: \"Getting started\", updatedAt: \"Just now\" },\n];\n\nexport default function Dashboard(): React.JSX.Element {\n const [conversations] = useState<Conversation[]>(INITIAL_CONVERSATIONS);\n const [activeId, setActiveId] = useState(\"1\");\n\n return (\n <div className=\"flex h-screen bg-white dark:bg-neutral-950\">\n {/* Sidebar */}\n <aside className=\"w-64 border-r border-neutral-200 dark:border-neutral-800 flex flex-col bg-neutral-50 dark:bg-neutral-900\">\n <div className=\"p-4 border-b border-neutral-200 dark:border-neutral-800\">\n <button className=\"w-full flex items-center gap-2 px-3 py-2 text-sm font-medium text-neutral-700 dark:text-neutral-300 bg-white dark:bg-neutral-800 border border-neutral-200 dark:border-neutral-700 rounded-lg hover:bg-neutral-50 dark:hover:bg-neutral-700 transition-colors\">\n <svg\n className=\"w-4 h-4\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth={2}\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M12 4.5v15m7.5-7.5h-15\"\n />\n </svg>\n New chat\n </button>\n </div>\n\n <nav className=\"flex-1 overflow-y-auto p-2 space-y-0.5\">\n {conversations.map((conv) => (\n <button\n key={conv.id}\n onClick={() => setActiveId(conv.id)}\n className={`w-full text-left px-3 py-2 rounded-lg text-sm transition-colors ${\n activeId === conv.id\n ? \"bg-neutral-200 dark:bg-neutral-800 text-neutral-900 dark:text-white\"\n : \"text-neutral-600 dark:text-neutral-400 hover:bg-neutral-100 dark:hover:bg-neutral-800/50\"\n }`}\n >\n <p className=\"truncate\">{conv.title}</p>\n <p className=\"text-xs text-neutral-400 mt-0.5\">\n {conv.updatedAt}\n </p>\n </button>\n ))}\n </nav>\n\n <div className=\"p-4 border-t border-neutral-200 dark:border-neutral-800\">\n <div className=\"flex items-center gap-2\">\n <div className=\"w-8 h-8 rounded-full bg-neutral-200 dark:bg-neutral-700 flex items-center justify-center text-xs font-medium text-neutral-600 dark:text-neutral-300\">\n U\n </div>\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm font-medium text-neutral-900 dark:text-white truncate\">\n User\n </p>\n <p className=\"text-xs text-neutral-500 truncate\">\n user@example.com\n </p>\n </div>\n </div>\n </div>\n </aside>\n\n {/* Chat */}\n <main className=\"flex-1 flex flex-col\">\n <Chat\n agentId=\"assistant\"\n api=\"/api/ag-ui\"\n className=\"flex-1 min-h-0\"\n placeholder=\"Message...\"\n />\n </main>\n </div>\n );\n}\n",
92
92
  "app/layout.tsx": "import \"../globals.css\";\nimport { Head } from \"veryfront/head\";\n\nexport default function RootLayout({\n children,\n}: {\n children: React.ReactNode;\n}): React.ReactNode {\n return (\n <>\n <Head>\n <title>AI SaaS</title>\n </Head>\n <div className=\"antialiased\">\n {children}\n </div>\n </>\n );\n}\n",
93
93
  "app/login/page.tsx": "\"use client\";\n\n// Demo sign-in: the buttons below pass straight through to /dashboard so the\n// starter is usable out of the box. To wire up real OAuth, scaffold provider\n// routes at app/api/auth/google/route.ts and app/api/auth/github/route.ts and\n// point the hrefs there. See https://veryfront.com/docs/code/guides/oauth.\nexport default function LoginPage(): React.JSX.Element {\n return (\n <div className=\"min-h-screen flex items-center justify-center bg-neutral-50 dark:bg-neutral-950 px-4\">\n <div className=\"w-full max-w-sm\">\n <div className=\"text-center mb-8\">\n <h1 className=\"text-xl font-bold text-neutral-900 dark:text-white\">\n Welcome back\n </h1>\n <p className=\"text-sm text-neutral-500 dark:text-neutral-400 mt-1\">\n Sign in to continue\n </p>\n </div>\n\n <div className=\"bg-white dark:bg-neutral-900 rounded-2xl border border-neutral-200 dark:border-neutral-800 p-6 space-y-3\">\n <a\n href=\"/dashboard\"\n className=\"flex items-center justify-center gap-2 w-full px-4 py-2.5 border border-neutral-200 dark:border-neutral-800 rounded-xl text-sm font-medium text-neutral-700 dark:text-neutral-300 hover:bg-neutral-50 dark:hover:bg-neutral-800 transition-colors\"\n >\n <svg className=\"w-4 h-4\" viewBox=\"0 0 24 24\">\n <path\n fill=\"#4285F4\"\n d=\"M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92a5.06 5.06 0 01-2.2 3.32v2.76h3.57c2.08-1.92 3.28-4.74 3.28-8.09z\"\n />\n <path\n fill=\"#34A853\"\n d=\"M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z\"\n />\n <path\n fill=\"#FBBC05\"\n d=\"M5.84 14.09a7.12 7.12 0 010-4.18V7.07H2.18A11.99 11.99 0 001 12c0 1.94.46 3.77 1.18 5.43l3.66-3.34z\"\n />\n <path\n fill=\"#EA4335\"\n d=\"M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z\"\n />\n </svg>\n Continue with Google\n </a>\n <a\n href=\"/dashboard\"\n className=\"flex items-center justify-center gap-2 w-full px-4 py-2.5 border border-neutral-200 dark:border-neutral-800 rounded-xl text-sm font-medium text-neutral-700 dark:text-neutral-300 hover:bg-neutral-50 dark:hover:bg-neutral-800 transition-colors\"\n >\n <svg className=\"w-4 h-4\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\n <path d=\"M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23A11.51 11.51 0 0112 5.803c1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576C20.566 21.797 24 17.3 24 12c0-6.627-5.373-12-12-12z\" />\n </svg>\n Continue with GitHub\n </a>\n </div>\n\n <p className=\"mt-6 text-center text-xs text-neutral-400\">\n <a\n href=\"/\"\n className=\"hover:text-neutral-600 dark:hover:text-neutral-300\"\n >\n &larr; Back to home\n </a>\n </p>\n </div>\n </div>\n );\n}\n",
94
94
  "app/page.tsx": "export default function LandingPage(): React.JSX.Element {\n return (\n <div className=\"min-h-screen bg-white dark:bg-neutral-950\">\n {/* Nav */}\n <nav className=\"border-b border-neutral-100 dark:border-neutral-900\">\n <div className=\"max-w-5xl mx-auto flex items-center justify-between px-6 h-14\">\n <span className=\"font-semibold text-neutral-900 dark:text-white\">\n AI SaaS\n </span>\n <div className=\"flex items-center gap-4\">\n <a\n href=\"/login\"\n className=\"text-sm text-neutral-600 dark:text-neutral-400 hover:text-neutral-900 dark:hover:text-white transition-colors\"\n >\n Sign in\n </a>\n <a\n href=\"/login\"\n className=\"text-sm px-4 py-1.5 bg-neutral-900 dark:bg-white text-white dark:text-neutral-900 rounded-full font-medium hover:opacity-90 transition-opacity\"\n >\n Get started\n </a>\n </div>\n </div>\n </nav>\n\n {/* Hero */}\n <main className=\"max-w-5xl mx-auto px-6\">\n <div className=\"pt-24 pb-16 text-center\">\n <h1 className=\"text-4xl md:text-5xl font-bold tracking-tight text-neutral-900 dark:text-white\">\n Your AI-powered platform\n </h1>\n <p className=\"mt-4 text-lg text-neutral-500 dark:text-neutral-400 max-w-lg mx-auto\">\n Built with Veryfront. Agents, tools, and memory are ready for\n production.\n </p>\n <div className=\"mt-8 flex gap-3 justify-center\">\n <a\n href=\"/login\"\n className=\"px-6 py-2.5 bg-neutral-900 dark:bg-white text-white dark:text-neutral-900 rounded-full font-medium hover:opacity-90 transition-opacity\"\n >\n Start free\n </a>\n <a\n href=\"https://veryfront.com/docs/code/guides\"\n className=\"px-6 py-2.5 border border-neutral-200 dark:border-neutral-800 text-neutral-700 dark:text-neutral-300 rounded-full font-medium hover:bg-neutral-50 dark:hover:bg-neutral-900 transition-colors\"\n >\n Documentation\n </a>\n </div>\n </div>\n\n {/* Features */}\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-6 py-16 border-t border-neutral-100 dark:border-neutral-900\">\n {[\n {\n title: \"AI Agents\",\n desc: \"Define agents with tools, memory, and streaming. Veryfront auto-discovers them from your project.\",\n },\n {\n title: \"Per-User Memory\",\n desc: \"Each user gets their own conversation history, persisted across sessions.\",\n },\n {\n title: \"Production Ready\",\n desc: \"Use auth, rate limiting, and deployment to ship to production with one command.\",\n },\n ].map(({ title, desc }) => (\n <div key={title}>\n <h3 className=\"font-medium text-neutral-900 dark:text-white\">\n {title}\n </h3>\n <p className=\"mt-1 text-sm text-neutral-500 dark:text-neutral-400\">\n {desc}\n </p>\n </div>\n ))}\n </div>\n </main>\n </div>\n );\n}\n",
package/esm/deno.d.ts CHANGED
@@ -20,6 +20,7 @@ declare namespace _default {
20
20
  "./chat/ag-ui": string;
21
21
  "./chat/protocol": string;
22
22
  "./chat/types": string;
23
+ "./chat/uploads": string;
23
24
  "./markdown": string;
24
25
  "./mdx": string;
25
26
  "./agent": string;
@@ -89,6 +90,7 @@ declare namespace _default {
89
90
  "veryfront/fonts": string;
90
91
  "veryfront/chat": string;
91
92
  "veryfront/chat/types": string;
93
+ "veryfront/chat/uploads": string;
92
94
  "veryfront/markdown": string;
93
95
  "veryfront/mdx": string;
94
96
  "veryfront/fs": string;
@@ -188,6 +190,7 @@ declare namespace _default {
188
190
  "#veryfront/chat/protocol": string;
189
191
  "#veryfront/chat/provider-errors": string;
190
192
  "#veryfront/chat/stream-watchdog": string;
193
+ "#veryfront/chat/uploads": string;
191
194
  "#veryfront/build": string;
192
195
  "#veryfront/cache": string;
193
196
  "#veryfront/config": string;
@@ -347,6 +350,9 @@ declare namespace _default {
347
350
  "coverage:html": string;
348
351
  bench: string;
349
352
  clean: string;
353
+ storybook: string;
354
+ "build:storybook": string;
355
+ "storybook:check": string;
350
356
  lint: string;
351
357
  fmt: string;
352
358
  "fmt:check": string;
@@ -368,6 +374,7 @@ declare namespace _default {
368
374
  "lint:ban-deep-imports": string;
369
375
  "lint:imports": string;
370
376
  "lint:ban-internal-root-imports": string;
377
+ "lint:chat-composability": string;
371
378
  "lint:style": string;
372
379
  "lint:cli-boundary": string;
373
380
  "validate:architecture": string;
package/esm/deno.js CHANGED
@@ -1,6 +1,6 @@
1
1
  export default {
2
2
  "name": "veryfront",
3
- "version": "0.1.997",
3
+ "version": "0.1.999",
4
4
  "license": "Apache-2.0",
5
5
  "nodeModulesDir": "auto",
6
6
  "minimumDependencyAge": {
@@ -59,6 +59,7 @@ export default {
59
59
  "dist/",
60
60
  "coverage/",
61
61
  "scripts/",
62
+ "storybook/",
62
63
  "examples/",
63
64
  "data/",
64
65
  ".deno_cache/",
@@ -76,6 +77,7 @@ export default {
76
77
  "./chat/ag-ui": "./src/chat/ag-ui.ts",
77
78
  "./chat/protocol": "./src/chat/protocol.ts",
78
79
  "./chat/types": "./src/chat/types.ts",
80
+ "./chat/uploads": "./src/chat/upload-handler.ts",
79
81
  "./markdown": "./src/markdown/index.ts",
80
82
  "./mdx": "./src/mdx/index.ts",
81
83
  "./agent": "./src/agent/index.ts",
@@ -145,6 +147,7 @@ export default {
145
147
  "veryfront/fonts": "./src/react/fonts/index.ts",
146
148
  "veryfront/chat": "./src/chat/index.ts",
147
149
  "veryfront/chat/types": "./src/chat/types.ts",
150
+ "veryfront/chat/uploads": "./src/chat/upload-handler.ts",
148
151
  "veryfront/markdown": "./src/markdown/index.ts",
149
152
  "veryfront/mdx": "./src/mdx/index.ts",
150
153
  "veryfront/fs": "./src/fs/index.ts",
@@ -244,6 +247,7 @@ export default {
244
247
  "#veryfront/chat/protocol": "./src/chat/protocol.ts",
245
248
  "#veryfront/chat/provider-errors": "./src/chat/provider-errors.ts",
246
249
  "#veryfront/chat/stream-watchdog": "./src/chat/stream-watchdog.ts",
250
+ "#veryfront/chat/uploads": "./src/chat/upload-handler.ts",
247
251
  "#veryfront/build": "./src/build/index.ts",
248
252
  "#veryfront/cache": "./src/cache/index.ts",
249
253
  "#veryfront/config": "./src/config/index.ts",
@@ -409,12 +413,15 @@ export default {
409
413
  "coverage:html": "deno coverage coverage --include=src/ --exclude=tests '--exclude=src/**/*_test.ts' '--exclude=src/**/*_test.tsx' '--exclude=src/**/*.test.ts' '--exclude=src/**/*.test.tsx' --html",
410
414
  "bench": "VF_DISABLE_LRU_INTERVAL=1 NODE_ENV=production LOG_FORMAT=text deno bench --no-check --allow-all --unstable-worker-options --unstable-net $(find src -name '*.bench.ts')",
411
415
  "clean": "rm -rf .cache/",
416
+ "storybook": "npm --prefix storybook run storybook",
417
+ "build:storybook": "npm --prefix storybook run build-storybook",
418
+ "storybook:check": "deno test --no-lock --config=scripts/test.deno.json --no-check --allow-read scripts/storybook/storybook-workbench.test.ts",
412
419
  "lint": "DENO_NO_PACKAGE_JSON=1 deno lint src/ cli/ react/ && deno lint --config=scripts/test.deno.json scripts/test/ scripts/build/npm-package-metadata.test.ts",
413
420
  "fmt": "deno fmt src/ cli/ react/ && deno fmt --config=scripts/test.deno.json scripts/test/",
414
421
  "fmt:check": "deno fmt --check src/ cli/ react/ && deno fmt --check --config=scripts/test.deno.json scripts/test/",
415
422
  "typecheck": "deno task generate:manifests:check && deno check src/index.ts cli/main.ts src/server/index.ts src/routing/api/index.ts src/rendering/index.ts src/platform/index.ts src/platform/adapters/index.ts src/build/index.ts src/build/production-build/index.ts src/transforms/index.ts src/config/index.ts src/utils/index.ts src/data/index.ts src/security/index.ts src/middleware/index.ts src/server/handlers/dev/index.ts src/server/handlers/request/api/index.ts src/rendering/cache/index.ts src/rendering/cache/stores/index.ts src/rendering/rsc/actions/index.ts src/html/index.ts src/modules/index.ts src/proxy/main.ts src/chat/index.ts src/markdown/index.ts src/mdx/index.ts src/fs/index.ts src/oauth/index.ts src/agent/index.ts src/agent/service/route-export.check.ts src/eval/index.ts src/tool/index.ts src/workflow/index.ts src/work/index.ts src/prompt/index.ts src/resource/index.ts src/runs/index.ts src/mcp/index.ts src/provider/index.ts",
416
- "verify": "deno task generate:manifests:check && deno task fmt:check && deno task lint && deno task lint:style && deno task lint:cli-boundary && deno task lint:wildcard-exports && deno task lint:barrel-jsdoc && deno task lint:ban-test-only && deno task lint:sanitizer-baseline && deno task lint:skipped-tests && deno task lint:ban-zod && deno task lint:core-deps && deno task lint:dependency-boundaries && deno task lint:extension-contracts && deno task lint:extension-capabilities && deno task docs:validate && deno task typecheck && deno task test && deno task test:e2e:binary",
417
- "verify:quick": "deno task generate:manifests:check && deno task fmt:check && deno task lint && deno task lint:style && deno task lint:cli-boundary && deno task lint:wildcard-exports && deno task lint:barrel-jsdoc && deno task lint:ban-test-only && deno task lint:sanitizer-baseline && deno task lint:skipped-tests && deno task lint:ban-zod && deno task lint:core-deps && deno task lint:dependency-boundaries && deno task lint:extension-contracts && deno task lint:extension-capabilities && deno task docs:validate && deno task typecheck",
423
+ "verify": "deno task generate:manifests:check && deno task fmt:check && deno task lint && deno task lint:style && deno task lint:chat-composability && deno task lint:cli-boundary && deno task lint:wildcard-exports && deno task lint:barrel-jsdoc && deno task lint:ban-test-only && deno task lint:sanitizer-baseline && deno task lint:skipped-tests && deno task lint:ban-zod && deno task lint:core-deps && deno task lint:dependency-boundaries && deno task lint:extension-contracts && deno task lint:extension-capabilities && deno task docs:validate && deno task typecheck && deno task test && deno task test:e2e:binary",
424
+ "verify:quick": "deno task generate:manifests:check && deno task fmt:check && deno task lint && deno task lint:style && deno task lint:chat-composability && deno task lint:cli-boundary && deno task lint:wildcard-exports && deno task lint:barrel-jsdoc && deno task lint:ban-test-only && deno task lint:sanitizer-baseline && deno task lint:skipped-tests && deno task lint:ban-zod && deno task lint:core-deps && deno task lint:dependency-boundaries && deno task lint:extension-contracts && deno task lint:extension-capabilities && deno task docs:validate && deno task typecheck",
418
425
  "docs": "deno run --allow-read --allow-write --allow-run --allow-env scripts/docs/generate-api-reference.ts",
419
426
  "docs:coverage": "deno run --allow-read scripts/docs/docs-coverage.ts",
420
427
  "docs:copy": "rm -rf ../../docs/docs/code/api-reference && cp -r docs/api-reference/ ../../docs/docs/code/api-reference/",
@@ -430,6 +437,7 @@ export default {
430
437
  "lint:ban-deep-imports": "deno run --allow-read scripts/lint/ban-deep-imports.ts",
431
438
  "lint:imports": "deno run --allow-read scripts/lint/no-cross-boundary-relative-imports.ts",
432
439
  "lint:ban-internal-root-imports": "deno run --allow-read scripts/lint/ban-internal-root-imports.ts",
440
+ "lint:chat-composability": "deno run --allow-read scripts/lint/audit-chat-composability.ts",
433
441
  "lint:style": "deno run --allow-read scripts/lint/enforce-style-conventions.ts",
434
442
  "lint:cli-boundary": "deno run --allow-read scripts/lint/enforce-cli-boundary.ts",
435
443
  "validate:architecture": "deno run --allow-read scripts/lint/validate-architecture.ts",
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=react-dom@19.2.4.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react-dom@19.2.4.d.ts","sourceRoot":"","sources":["../../../src/deps/esm.sh/react-dom@19.2.4.js"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ /* npm package shim for esm.sh react-dom@19.2.4.js */
2
+ export * from "react-dom";
3
+ export { default } from "react-dom";
@@ -0,0 +1,3 @@
1
+ export * from "../deps/esm.sh/react-dom@19.2.4.js";
2
+ export { default } from "../deps/esm.sh/react-dom@19.2.4.js";
3
+ //# sourceMappingURL=react-dom.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react-dom.d.ts","sourceRoot":"","sources":["../../src/react/react-dom.ts"],"names":[],"mappings":"AAAA,cAAc,oCAAoC,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,oCAAoC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from "../deps/esm.sh/react-dom@19.2.4.js";
2
+ export { default } from "../deps/esm.sh/react-dom@19.2.4.js";
@@ -1 +1 @@
1
- {"version":3,"file":"host-support.d.ts","sourceRoot":"","sources":["../../../../src/src/agent/ag-ui/host-support.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAEpE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAa3C,mCAAmC;AACnC,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAgBD,eAAO,MAAM,yBAAyB;;;;GASrC,CAAC;AAEF,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;GAuBpC,CAAC;AAuBF,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiBhC,CAAC;AAEF,kDAAkD;AAClD,eAAO,MAAM,sBAAsB;;;;GAAwC,CAAC;AAC5E,iDAAiD;AACjD,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;GAAuC,CAAC;AAC1E;;GAEG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAAmC,CAAC;AAElE,mDAAmD;AACnD,MAAM,MAAM,gBAAgB,GAAG,WAAW,CAAC,UAAU,CAAC,OAAO,yBAAyB,CAAC,CAAC,CAAC;AACzF,kDAAkD;AAClD,MAAM,MAAM,eAAe,GAAG,WAAW,CAAC,UAAU,CAAC,OAAO,wBAAwB,CAAC,CAAC,CAAC;AACvF,iCAAiC;AACjC,MAAM,MAAM,WAAW,GAAG,WAAW,CAAC,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC,CAAC;AAE/E,MAAM,WAAW,4BAA4B;IAC3C,sBAAsB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5C;AA8ND,uCAAuC;AACvC,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,WAAW,CAAC,CAE7E;AAED,8CAA8C;AAC9C,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,WAAW,GAAG,QAAQ,CAAC,CAKjC;AAED,iCAAiC;AACjC,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,WAAW,CAAC,UAAU,CAAC,EACjC,OAAO,GAAE,4BAAiC,GACzC,OAAO,EAAE,CAsCX;AAED,gDAAgD;AAChD,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,YAAY,CAQpF;AAED,mDAAmD;AACnD,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,GAAG,QAAQ,CAUxF;AAED,6CAA6C;AAC7C,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,GAAG,QAAQ,CASlF"}
1
+ {"version":3,"file":"host-support.d.ts","sourceRoot":"","sources":["../../../../src/src/agent/ag-ui/host-support.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAEpE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAa3C,mCAAmC;AACnC,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAgBD,eAAO,MAAM,yBAAyB;;;;GASrC,CAAC;AAEF,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;GAuBpC,CAAC;AAuBF,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiBhC,CAAC;AAEF,kDAAkD;AAClD,eAAO,MAAM,sBAAsB;;;;GAAwC,CAAC;AAC5E,iDAAiD;AACjD,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;GAAuC,CAAC;AAC1E;;GAEG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAAmC,CAAC;AAElE,mDAAmD;AACnD,MAAM,MAAM,gBAAgB,GAAG,WAAW,CAAC,UAAU,CAAC,OAAO,yBAAyB,CAAC,CAAC,CAAC;AACzF,kDAAkD;AAClD,MAAM,MAAM,eAAe,GAAG,WAAW,CAAC,UAAU,CAAC,OAAO,wBAAwB,CAAC,CAAC,CAAC;AACvF,iCAAiC;AACjC,MAAM,MAAM,WAAW,GAAG,WAAW,CAAC,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC,CAAC;AAE/E,MAAM,WAAW,4BAA4B;IAC3C,sBAAsB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5C;AA6OD,uCAAuC;AACvC,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,WAAW,CAAC,CAE7E;AAED,8CAA8C;AAC9C,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,WAAW,GAAG,QAAQ,CAAC,CAKjC;AAED,iCAAiC;AACjC,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,WAAW,CAAC,UAAU,CAAC,EACjC,OAAO,GAAE,4BAAiC,GACzC,OAAO,EAAE,CAsCX;AAED,gDAAgD;AAChD,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,YAAY,CAQpF;AAED,mDAAmD;AACnD,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,GAAG,QAAQ,CAUxF;AAED,6CAA6C;AAC7C,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,GAAG,QAAQ,CASlF"}
@@ -181,6 +181,18 @@ function normalizeMessagePart(part, toolNamesById = new Map()) {
181
181
  result: "result" in part ? part.result : undefined,
182
182
  };
183
183
  }
184
+ // Attachments: keep `file`/`image` parts (multimodal input). The composer
185
+ // sends every attachment as `type: "file"`, so route by media type — images
186
+ // become `image` parts the model can view, everything else stays `file`.
187
+ // The `url` may be a fetchable URL or an inline `data:` base64 URL.
188
+ if ((part.type === "file" || part.type === "image") &&
189
+ typeof part.url === "string" && part.url.length > 0 &&
190
+ typeof part.mediaType === "string" && part.mediaType.length > 0) {
191
+ const isImage = part.type === "image" || part.mediaType.startsWith("image/");
192
+ return isImage
193
+ ? { type: "image", url: part.url, mediaType: part.mediaType }
194
+ : { type: "file", url: part.url, mediaType: part.mediaType };
195
+ }
184
196
  return null;
185
197
  }
186
198
  function buildMessageMetadataFields(message) {
@@ -4,11 +4,13 @@
4
4
  * @module agent/react
5
5
  */
6
6
  export { useChat } from "./use-chat/index.js";
7
- export type { BranchInfo, ChatDynamicToolPart, ChatFinishReason, ChatMessage, ChatMessagePart, ChatReasoningPart, ChatStepPart, ChatStreamEvent, ChatTextPart, ChatToolPart, ChatToolResultPart, ChatToolState, InferenceMode, OnToolCallArg, ToolOutput, UseChatOptions, UseChatResult, } from "./use-chat/index.js";
7
+ export type { BranchInfo, ChatDynamicToolPart, ChatFilePart, ChatFinishReason, ChatMessage, ChatMessagePart, ChatReasoningPart, ChatStepPart, ChatStreamEvent, ChatTextPart, ChatToolPart, ChatToolResultPart, ChatToolState, InferenceMode, OnToolCallArg, ToolOutput, UseChatOptions, UseChatResult, } from "./use-chat/index.js";
8
8
  export { useAgent } from "./use-agent.js";
9
9
  export type { UseAgentOptions, UseAgentResult } from "./use-agent.js";
10
- export { getAgentPromptSuggestions, normalizeAgentMetadataResponse, useAgentMetadata, } from "./use-agent-metadata.js";
10
+ export { getAgentPromptSuggestions, normalizeAgentMetadata, normalizeAgentMetadataResponse, useAgentMetadata, } from "./use-agent-metadata.js";
11
11
  export type { AgentMetadata, AgentMetadataPromptSuggestion, AgentMetadataSuggestion, AgentMetadataSuggestions, AgentMetadataTaskSuggestion, UseAgentMetadataResult, } from "./use-agent-metadata.js";
12
+ export { normalizeAgentsListResponse, useAgents } from "./use-agents.js";
13
+ export type { UseAgentsOptions, UseAgentsResult } from "./use-agents.js";
12
14
  export { useCompletion } from "./use-completion.js";
13
15
  export type { UseCompletionOptions, UseCompletionResult } from "./use-completion.js";
14
16
  export { useStreaming } from "./use-streaming.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/src/agent/react/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,YAAY,EACV,UAAU,EACV,mBAAmB,EACnB,gBAAgB,EAChB,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,YAAY,EACZ,eAAe,EACf,YAAY,EACZ,YAAY,EACZ,kBAAkB,EAClB,aAAa,EACb,aAAa,EACb,aAAa,EACb,UAAU,EACV,cAAc,EACd,aAAa,GACd,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEtE,OAAO,EACL,yBAAyB,EACzB,8BAA8B,EAC9B,gBAAgB,GACjB,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACV,aAAa,EACb,6BAA6B,EAC7B,uBAAuB,EACvB,wBAAwB,EACxB,2BAA2B,EAC3B,sBAAsB,GACvB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAErF,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,YAAY,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAElF,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,YAAY,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/src/agent/react/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,YAAY,EACV,UAAU,EACV,mBAAmB,EACnB,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,YAAY,EACZ,eAAe,EACf,YAAY,EACZ,YAAY,EACZ,kBAAkB,EAClB,aAAa,EACb,aAAa,EACb,aAAa,EACb,UAAU,EACV,cAAc,EACd,aAAa,GACd,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEtE,OAAO,EACL,yBAAyB,EACzB,sBAAsB,EACtB,8BAA8B,EAC9B,gBAAgB,GACjB,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACV,aAAa,EACb,6BAA6B,EAC7B,uBAAuB,EACvB,wBAAwB,EACxB,2BAA2B,EAC3B,sBAAsB,GACvB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,2BAA2B,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACzE,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEzE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAErF,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,YAAY,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAElF,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,YAAY,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC"}
@@ -5,7 +5,8 @@
5
5
  */
6
6
  export { useChat } from "./use-chat/index.js";
7
7
  export { useAgent } from "./use-agent.js";
8
- export { getAgentPromptSuggestions, normalizeAgentMetadataResponse, useAgentMetadata, } from "./use-agent-metadata.js";
8
+ export { getAgentPromptSuggestions, normalizeAgentMetadata, normalizeAgentMetadataResponse, useAgentMetadata, } from "./use-agent-metadata.js";
9
+ export { normalizeAgentsListResponse, useAgents } from "./use-agents.js";
9
10
  export { useCompletion } from "./use-completion.js";
10
11
  export { useStreaming } from "./use-streaming.js";
11
12
  export { useVoiceInput } from "./use-voice-input.js";
@@ -33,6 +33,11 @@ export interface UseAgentMetadataResult {
33
33
  isLoading: boolean;
34
34
  error: Error | null;
35
35
  }
36
+ /**
37
+ * Normalize a single browser-safe agent record (the `agent` object inside the
38
+ * `/api/agents/:id` response, or one entry of the `/api/agents` list).
39
+ */
40
+ export declare function normalizeAgentMetadata(value: unknown): AgentMetadata;
36
41
  /** Normalize the wire response from /api/agents/:id. */
37
42
  export declare function normalizeAgentMetadataResponse(value: unknown): AgentMetadata;
38
43
  /** Return prompt text suggestions that the current Chat component can render. */
@@ -1 +1 @@
1
- {"version":3,"file":"use-agent-metadata.d.ts","sourceRoot":"","sources":["../../../../src/src/agent/react/use-agent-metadata.ts"],"names":[],"mappings":"AAGA,+DAA+D;AAC/D,MAAM,MAAM,6BAA6B,GACrC;IACA,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,GACC;IACA,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,QAAQ,CAAC;CAChB,CAAC;AAEJ,6DAA6D;AAC7D,MAAM,MAAM,2BAA2B,GAAG;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ,CAAC;AAEF,uCAAuC;AACvC,MAAM,MAAM,uBAAuB,GAAG,6BAA6B,GAAG,2BAA2B,CAAC;AAElG,oDAAoD;AACpD,MAAM,WAAW,wBAAwB;IACvC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,uBAAuB,EAAE,CAAC;CACxC;AAED,kDAAkD;AAClD,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,CAAC,EAAE,wBAAwB,CAAC;CACxC;AAED,6CAA6C;AAC7C,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,aAAa,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;CACrB;AA2ED,wDAAwD;AACxD,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,OAAO,GAAG,aAAa,CAa5E;AAED,iFAAiF;AACjF,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,GAAG,MAAM,EAAE,CAK/E;AAED,iEAAiE;AACjE,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,sBAAsB,CAkD3F"}
1
+ {"version":3,"file":"use-agent-metadata.d.ts","sourceRoot":"","sources":["../../../../src/src/agent/react/use-agent-metadata.ts"],"names":[],"mappings":"AAGA,+DAA+D;AAC/D,MAAM,MAAM,6BAA6B,GACrC;IACA,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,GACC;IACA,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,QAAQ,CAAC;CAChB,CAAC;AAEJ,6DAA6D;AAC7D,MAAM,MAAM,2BAA2B,GAAG;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ,CAAC;AAEF,uCAAuC;AACvC,MAAM,MAAM,uBAAuB,GAAG,6BAA6B,GAAG,2BAA2B,CAAC;AAElG,oDAAoD;AACpD,MAAM,WAAW,wBAAwB;IACvC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,uBAAuB,EAAE,CAAC;CACxC;AAED,kDAAkD;AAClD,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,CAAC,EAAE,wBAAwB,CAAC;CACxC;AAED,6CAA6C;AAC7C,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,aAAa,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;CACrB;AA2ED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,aAAa,CAYpE;AAED,wDAAwD;AACxD,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,OAAO,GAAG,aAAa,CAK5E;AAED,iFAAiF;AACjF,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,GAAG,MAAM,EAAE,CAK/E;AAED,iEAAiE;AACjE,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,sBAAsB,CAkD3F"}
@@ -62,19 +62,28 @@ function normalizeSuggestions(value) {
62
62
  suggestions: rawSuggestions.map(normalizeSuggestion),
63
63
  };
64
64
  }
65
+ /**
66
+ * Normalize a single browser-safe agent record (the `agent` object inside the
67
+ * `/api/agents/:id` response, or one entry of the `/api/agents` list).
68
+ */
69
+ export function normalizeAgentMetadata(value) {
70
+ if (!isRecord(value)) {
71
+ throw new Error("Invalid agent metadata: agent must be an object");
72
+ }
73
+ return {
74
+ id: getRequiredString(value, "id"),
75
+ name: getRequiredString(value, "name"),
76
+ description: getNullableString(value, "description"),
77
+ avatarUrl: getNullableString(value, "avatar_url"),
78
+ suggestions: normalizeSuggestions(value.suggestions),
79
+ };
80
+ }
65
81
  /** Normalize the wire response from /api/agents/:id. */
66
82
  export function normalizeAgentMetadataResponse(value) {
67
- if (!isRecord(value) || !isRecord(value.agent)) {
83
+ if (!isRecord(value)) {
68
84
  throw new Error("Invalid agent metadata response");
69
85
  }
70
- const agent = value.agent;
71
- return {
72
- id: getRequiredString(agent, "id"),
73
- name: getRequiredString(agent, "name"),
74
- description: getNullableString(agent, "description"),
75
- avatarUrl: getNullableString(agent, "avatar_url"),
76
- suggestions: normalizeSuggestions(agent.suggestions),
77
- };
86
+ return normalizeAgentMetadata(value.agent);
78
87
  }
79
88
  /** Return prompt text suggestions that the current Chat component can render. */
80
89
  export function getAgentPromptSuggestions(agent) {
@@ -0,0 +1,33 @@
1
+ import { type AgentMetadata } from "./use-agent-metadata.js";
2
+ /** Options accepted by {@link useAgents}. */
3
+ export interface UseAgentsOptions {
4
+ /**
5
+ * When `false`, the request is skipped and the hook stays idle with an empty
6
+ * list. Flip it to `true` to fetch (or refetch). Defaults to `true`.
7
+ */
8
+ enabled?: boolean;
9
+ }
10
+ /** Result returned from {@link useAgents}. */
11
+ export interface UseAgentsResult {
12
+ /** Browser-safe metadata for every agent the project exposes, sorted by name. */
13
+ agents: AgentMetadata[];
14
+ /** `true` while the list request is in flight. */
15
+ isLoading: boolean;
16
+ /** The last request error, or `null`. */
17
+ error: Error | null;
18
+ /** Re-run the request, bypassing nothing — always hits the network. */
19
+ refetch: () => void;
20
+ }
21
+ /** Normalize the wire response from `GET /api/agents`. */
22
+ export declare function normalizeAgentsListResponse(value: unknown): AgentMetadata[];
23
+ /**
24
+ * React hook that lists the browser-safe agents a project exposes, via
25
+ * `GET /api/agents`. Companion to {@link useAgentMetadata} (single agent) — use
26
+ * it to drive an agent switcher, e.g. only rendering a picker when
27
+ * `agents.length > 1`.
28
+ *
29
+ * The in-flight request is aborted on unmount, on option change, and before a
30
+ * `refetch`, so state never lands from a stale response.
31
+ */
32
+ export declare function useAgents(options?: UseAgentsOptions): UseAgentsResult;
33
+ //# sourceMappingURL=use-agents.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-agents.d.ts","sourceRoot":"","sources":["../../../../src/src/agent/react/use-agents.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,aAAa,EAA0B,MAAM,yBAAyB,CAAC;AAErF,6CAA6C;AAC7C,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,8CAA8C;AAC9C,MAAM,WAAW,eAAe;IAC9B,iFAAiF;IACjF,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,kDAAkD;IAClD,SAAS,EAAE,OAAO,CAAC;IACnB,yCAAyC;IACzC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,uEAAuE;IACvE,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAQD,0DAA0D;AAC1D,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,GAAG,aAAa,EAAE,CAK3E;AAED;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,OAAO,GAAE,gBAAqB,GAAG,eAAe,CAuDzE"}