@larkup/workspace-app 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (440) hide show
  1. package/LICENSE +176 -0
  2. package/README.md +4 -2
  3. package/assets/github.svg +3 -0
  4. package/assets/icons/Confluence.png +0 -0
  5. package/assets/icons/Instagram.png +0 -0
  6. package/assets/icons/Northflank.png +0 -0
  7. package/assets/icons/Salesforce.png +0 -0
  8. package/assets/icons/agentskills.png +0 -0
  9. package/assets/icons/airtable.png +0 -0
  10. package/assets/icons/asana.png +0 -0
  11. package/assets/icons/ashby.png +0 -0
  12. package/assets/icons/audio.png +0 -0
  13. package/assets/icons/aws-kendra.png +0 -0
  14. package/assets/icons/aws.svg +38 -0
  15. package/assets/icons/azure-ai-search.png +0 -0
  16. package/assets/icons/azure.svg +1 -0
  17. package/assets/icons/bigquery.png +0 -0
  18. package/assets/icons/bing.png +0 -0
  19. package/assets/icons/bitbucket.png +0 -0
  20. package/assets/icons/brave.png +0 -0
  21. package/assets/icons/browserbase.png +0 -0
  22. package/assets/icons/calendly.png +0 -0
  23. package/assets/icons/chroma.png +0 -0
  24. package/assets/icons/cloudflare.png +0 -0
  25. package/assets/icons/cohere.svg +30 -0
  26. package/assets/icons/databricks.png +0 -0
  27. package/assets/icons/daytonaio.png +0 -0
  28. package/assets/icons/daytonaio2.png +0 -0
  29. package/assets/icons/deepgram.png +0 -0
  30. package/assets/icons/deepl.png +0 -0
  31. package/assets/icons/digital-ocean.webp +0 -0
  32. package/assets/icons/discord.png +0 -0
  33. package/assets/icons/e2b-2.png +0 -0
  34. package/assets/icons/e2b.png +0 -0
  35. package/assets/icons/elevenlabs.png +0 -0
  36. package/assets/icons/email.png +0 -0
  37. package/assets/icons/exa.png +0 -0
  38. package/assets/icons/excel.png +0 -0
  39. package/assets/icons/fal.png +0 -0
  40. package/assets/icons/firecrawl.png +0 -0
  41. package/assets/icons/firecrawl2.png +0 -0
  42. package/assets/icons/flyio.jpeg +0 -0
  43. package/assets/icons/gcp.svg +1 -0
  44. package/assets/icons/gemini.svg +1 -0
  45. package/assets/icons/gmail.png +0 -0
  46. package/assets/icons/google-analytics.png +0 -0
  47. package/assets/icons/google-calender.png +0 -0
  48. package/assets/icons/google-docs.png +0 -0
  49. package/assets/icons/google-drive.png +0 -0
  50. package/assets/icons/google-maps.png +0 -0
  51. package/assets/icons/google-meet.png +0 -0
  52. package/assets/icons/google-sheets.png +0 -0
  53. package/assets/icons/google-slides.png +0 -0
  54. package/assets/icons/google-tasks.png +0 -0
  55. package/assets/icons/google.png +0 -0
  56. package/assets/icons/grok.png +0 -0
  57. package/assets/icons/hubspot.png +0 -0
  58. package/assets/icons/image.png +0 -0
  59. package/assets/icons/jina.svg +1 -0
  60. package/assets/icons/jira.png +0 -0
  61. package/assets/icons/lancedb2.png +0 -0
  62. package/assets/icons/linear.png +0 -0
  63. package/assets/icons/linux.png +0 -0
  64. package/assets/icons/looker.png +0 -0
  65. package/assets/icons/luma.png +0 -0
  66. package/assets/icons/mac.png +0 -0
  67. package/assets/icons/markdown.png +0 -0
  68. package/assets/icons/mcp.png +0 -0
  69. package/assets/icons/mcp.svg +1 -0
  70. package/assets/icons/messenger.svg +1 -0
  71. package/assets/icons/microsoft-intra.png +0 -0
  72. package/assets/icons/microsoft-onenote.png +0 -0
  73. package/assets/icons/microsoft-planner.png +0 -0
  74. package/assets/icons/microsoft-teams.png +0 -0
  75. package/assets/icons/miro.png +0 -0
  76. package/assets/icons/mistral.svg +469 -0
  77. package/assets/icons/modal.png +0 -0
  78. package/assets/icons/ngrok.png +0 -0
  79. package/assets/icons/nomic.png +0 -0
  80. package/assets/icons/onedrive.png +0 -0
  81. package/assets/icons/openai.svg +1 -0
  82. package/assets/icons/outlook-calendar.png +0 -0
  83. package/assets/icons/outlook-email.png +0 -0
  84. package/assets/icons/outlook.png +0 -0
  85. package/assets/icons/pdf.png +0 -0
  86. package/assets/icons/personio.png +0 -0
  87. package/assets/icons/pgvector2.png +0 -0
  88. package/assets/icons/phone.png +0 -0
  89. package/assets/icons/pinecone.png +0 -0
  90. package/assets/icons/pipedrive.png +0 -0
  91. package/assets/icons/power-pi.png +0 -0
  92. package/assets/icons/pylon.png +0 -0
  93. package/assets/icons/python.png +0 -0
  94. package/assets/icons/qdrant.svg +35 -0
  95. package/assets/icons/revai.png +0 -0
  96. package/assets/icons/revai.svg +1 -0
  97. package/assets/icons/sap.png +0 -0
  98. package/assets/icons/serpapi.svg +34 -0
  99. package/assets/icons/serper.png +0 -0
  100. package/assets/icons/servicenow.png +0 -0
  101. package/assets/icons/sharepoint.png +0 -0
  102. package/assets/icons/slack.png +0 -0
  103. package/assets/icons/snowflake.png +0 -0
  104. package/assets/icons/statistia.png +0 -0
  105. package/assets/icons/stripe.png +0 -0
  106. package/assets/icons/supabase.png +0 -0
  107. package/assets/icons/tableau.png +0 -0
  108. package/assets/icons/tavily.png +0 -0
  109. package/assets/icons/telegram.png +0 -0
  110. package/assets/icons/typescript.png +0 -0
  111. package/assets/icons/vercel copy.svg +1 -0
  112. package/assets/icons/vercel.svg +1 -0
  113. package/assets/icons/vertex-ai.png +0 -0
  114. package/assets/icons/video.png +0 -0
  115. package/assets/icons/voyage-light.png +0 -0
  116. package/assets/icons/weaviate.webp +0 -0
  117. package/assets/icons/webcontainers.svg +11 -0
  118. package/assets/icons/webhook.png +0 -0
  119. package/assets/icons/whatsapp copy.png +0 -0
  120. package/assets/icons/whatsapp.png +0 -0
  121. package/assets/icons/windows.png +0 -0
  122. package/assets/icons/word.png +0 -0
  123. package/assets/icons/zendesk.png +0 -0
  124. package/assets/icons/zoom.png +0 -0
  125. package/assets/notion-white.png +0 -0
  126. package/assets/notion.png +0 -0
  127. package/dist-types/asset-server.d.ts +3 -0
  128. package/dist-types/asset-server.d.ts.map +1 -0
  129. package/dist-types/components/alerts/generic-alert.d.ts +15 -0
  130. package/dist-types/components/alerts/generic-alert.d.ts.map +1 -0
  131. package/dist-types/components/chat/canvas/doc-editor-provider.d.ts +62 -0
  132. package/dist-types/components/chat/canvas/doc-editor-provider.d.ts.map +1 -0
  133. package/dist-types/components/chat/canvas/document-canvas.d.ts +7 -0
  134. package/dist-types/components/chat/canvas/document-canvas.d.ts.map +1 -0
  135. package/dist-types/components/chat/canvas/document-field.d.ts +13 -0
  136. package/dist-types/components/chat/canvas/document-field.d.ts.map +1 -0
  137. package/dist-types/components/chat/canvas/document-viewer.d.ts +2 -0
  138. package/dist-types/components/chat/canvas/document-viewer.d.ts.map +1 -0
  139. package/dist-types/components/chat/canvas/file-attachment-button.d.ts +9 -0
  140. package/dist-types/components/chat/canvas/file-attachment-button.d.ts.map +1 -0
  141. package/dist-types/components/chat/chat-workspace.d.ts +4 -0
  142. package/dist-types/components/chat/chat-workspace.d.ts.map +1 -0
  143. package/dist-types/components/chat/message-actions.d.ts +11 -0
  144. package/dist-types/components/chat/message-actions.d.ts.map +1 -0
  145. package/dist-types/components/chat/message-item.d.ts +20 -0
  146. package/dist-types/components/chat/message-item.d.ts.map +1 -0
  147. package/dist-types/components/chat/message-queue.d.ts +15 -0
  148. package/dist-types/components/chat/message-queue.d.ts.map +1 -0
  149. package/dist-types/components/chat/tools/chat-chart.d.ts +6 -0
  150. package/dist-types/components/chat/tools/chat-chart.d.ts.map +1 -0
  151. package/dist-types/components/chat/tools/chat-citations.d.ts +32 -0
  152. package/dist-types/components/chat/tools/chat-citations.d.ts.map +1 -0
  153. package/dist-types/components/chat/tools/chat-data-table.d.ts +14 -0
  154. package/dist-types/components/chat/tools/chat-data-table.d.ts.map +1 -0
  155. package/dist-types/components/chat/tools/chat-file-export.d.ts +5 -0
  156. package/dist-types/components/chat/tools/chat-file-export.d.ts.map +1 -0
  157. package/dist-types/components/chat/tools/chat-media-preview.d.ts +35 -0
  158. package/dist-types/components/chat/tools/chat-media-preview.d.ts.map +1 -0
  159. package/dist-types/components/chat/tools/chat-sandbox-result.d.ts +17 -0
  160. package/dist-types/components/chat/tools/chat-sandbox-result.d.ts.map +1 -0
  161. package/dist-types/components/chat/tools/chat-signature-request.d.ts +13 -0
  162. package/dist-types/components/chat/tools/chat-signature-request.d.ts.map +1 -0
  163. package/dist-types/components/chat/tools/chat-tabs.d.ts +17 -0
  164. package/dist-types/components/chat/tools/chat-tabs.d.ts.map +1 -0
  165. package/dist-types/components/chat/tools/corpus-data-result.d.ts +36 -0
  166. package/dist-types/components/chat/tools/corpus-data-result.d.ts.map +1 -0
  167. package/dist-types/components/chat/tools/knowledge-base-result.d.ts +14 -0
  168. package/dist-types/components/chat/tools/knowledge-base-result.d.ts.map +1 -0
  169. package/dist-types/components/chat/tools/visual-placement-modal.d.ts +23 -0
  170. package/dist-types/components/chat/tools/visual-placement-modal.d.ts.map +1 -0
  171. package/dist-types/components/configure/custom-model-modal.d.ts +13 -0
  172. package/dist-types/components/configure/custom-model-modal.d.ts.map +1 -0
  173. package/dist-types/components/configure/store-fields.d.ts +11 -0
  174. package/dist-types/components/configure/store-fields.d.ts.map +1 -0
  175. package/dist-types/components/data/corpus-panel.d.ts +12 -0
  176. package/dist-types/components/data/corpus-panel.d.ts.map +1 -0
  177. package/dist-types/components/data/data-entry-mode-switch.d.ts +13 -0
  178. package/dist-types/components/data/data-entry-mode-switch.d.ts.map +1 -0
  179. package/dist-types/components/data/data-primary-action.d.ts +7 -0
  180. package/dist-types/components/data/data-primary-action.d.ts.map +1 -0
  181. package/dist-types/components/data/data-workspace.d.ts +6 -0
  182. package/dist-types/components/data/data-workspace.d.ts.map +1 -0
  183. package/dist-types/components/data/groups-panel.d.ts +5 -0
  184. package/dist-types/components/data/groups-panel.d.ts.map +1 -0
  185. package/dist-types/components/data/integration-resources-panel.d.ts +9 -0
  186. package/dist-types/components/data/integration-resources-panel.d.ts.map +1 -0
  187. package/dist-types/components/data/integrations-panel.d.ts +5 -0
  188. package/dist-types/components/data/integrations-panel.d.ts.map +1 -0
  189. package/dist-types/components/data/jobs-panel.d.ts +6 -0
  190. package/dist-types/components/data/jobs-panel.d.ts.map +1 -0
  191. package/dist-types/components/data/jobs-tracking-button.d.ts +2 -0
  192. package/dist-types/components/data/jobs-tracking-button.d.ts.map +1 -0
  193. package/dist-types/components/data/live-media-progress.d.ts +9 -0
  194. package/dist-types/components/data/live-media-progress.d.ts.map +1 -0
  195. package/dist-types/components/data/media-indexing-jobs-panel.d.ts +34 -0
  196. package/dist-types/components/data/media-indexing-jobs-panel.d.ts.map +1 -0
  197. package/dist-types/components/data/media-panel.d.ts +58 -0
  198. package/dist-types/components/data/media-panel.d.ts.map +1 -0
  199. package/dist-types/components/data/notion-panel.d.ts +6 -0
  200. package/dist-types/components/data/notion-panel.d.ts.map +1 -0
  201. package/dist-types/components/data/paste-panel.d.ts +7 -0
  202. package/dist-types/components/data/paste-panel.d.ts.map +1 -0
  203. package/dist-types/components/data/project-data-page.d.ts +3 -0
  204. package/dist-types/components/data/project-data-page.d.ts.map +1 -0
  205. package/dist-types/components/data/scrape-panel.d.ts +9 -0
  206. package/dist-types/components/data/scrape-panel.d.ts.map +1 -0
  207. package/dist-types/components/data/tabular-preview.d.ts +10 -0
  208. package/dist-types/components/data/tabular-preview.d.ts.map +1 -0
  209. package/dist-types/components/data/tool-indexing-dialog.d.ts +54 -0
  210. package/dist-types/components/data/tool-indexing-dialog.d.ts.map +1 -0
  211. package/dist-types/components/data/upload-panel.d.ts +7 -0
  212. package/dist-types/components/data/upload-panel.d.ts.map +1 -0
  213. package/dist-types/components/data/web-crawler-status.d.ts +3 -0
  214. package/dist-types/components/data/web-crawler-status.d.ts.map +1 -0
  215. package/dist-types/components/projects/project-form-dialog.d.ts +10 -0
  216. package/dist-types/components/projects/project-form-dialog.d.ts.map +1 -0
  217. package/dist-types/components/projects/project-provider.d.ts +34 -0
  218. package/dist-types/components/projects/project-provider.d.ts.map +1 -0
  219. package/dist-types/components/settings/general/agent-customization-section.d.ts +2 -0
  220. package/dist-types/components/settings/general/agent-customization-section.d.ts.map +1 -0
  221. package/dist-types/components/settings/general/mcp-connections-section.d.ts +2 -0
  222. package/dist-types/components/settings/general/mcp-connections-section.d.ts.map +1 -0
  223. package/dist-types/components/settings/general/model-combobox.d.ts +24 -0
  224. package/dist-types/components/settings/general/model-combobox.d.ts.map +1 -0
  225. package/dist-types/components/settings/general/models-section.d.ts +2 -0
  226. package/dist-types/components/settings/general/models-section.d.ts.map +1 -0
  227. package/dist-types/components/settings/general/sandbox-section.d.ts +7 -0
  228. package/dist-types/components/settings/general/sandbox-section.d.ts.map +1 -0
  229. package/dist-types/components/settings/general/search-scraping-section.d.ts +2 -0
  230. package/dist-types/components/settings/general/search-scraping-section.d.ts.map +1 -0
  231. package/dist-types/components/settings/general/storage-indexing-section.d.ts +2 -0
  232. package/dist-types/components/settings/general/storage-indexing-section.d.ts.map +1 -0
  233. package/dist-types/components/ui/alert-dialog.d.ts +19 -0
  234. package/dist-types/components/ui/alert-dialog.d.ts.map +1 -0
  235. package/dist-types/components/ui/alert.d.ts +11 -0
  236. package/dist-types/components/ui/alert.d.ts.map +1 -0
  237. package/dist-types/components/ui/badge.d.ts +8 -0
  238. package/dist-types/components/ui/badge.d.ts.map +1 -0
  239. package/dist-types/components/ui/card.d.ts +2 -0
  240. package/dist-types/components/ui/card.d.ts.map +1 -0
  241. package/dist-types/components/ui/checkbox.d.ts +4 -0
  242. package/dist-types/components/ui/checkbox.d.ts.map +1 -0
  243. package/dist-types/components/ui/collapsible.d.ts +6 -0
  244. package/dist-types/components/ui/collapsible.d.ts.map +1 -0
  245. package/dist-types/components/ui/command.d.ts +20 -0
  246. package/dist-types/components/ui/command.d.ts.map +1 -0
  247. package/dist-types/components/ui/dialog.d.ts +18 -0
  248. package/dist-types/components/ui/dialog.d.ts.map +1 -0
  249. package/dist-types/components/ui/dropdown-menu.d.ts +30 -0
  250. package/dist-types/components/ui/dropdown-menu.d.ts.map +1 -0
  251. package/dist-types/components/ui/input-group.d.ts +19 -0
  252. package/dist-types/components/ui/input-group.d.ts.map +1 -0
  253. package/dist-types/components/ui/input.d.ts +4 -0
  254. package/dist-types/components/ui/input.d.ts.map +1 -0
  255. package/dist-types/components/ui/line-tabs.d.ts +15 -0
  256. package/dist-types/components/ui/line-tabs.d.ts.map +1 -0
  257. package/dist-types/components/ui/popover.d.ts +10 -0
  258. package/dist-types/components/ui/popover.d.ts.map +1 -0
  259. package/dist-types/components/ui/progress.d.ts +8 -0
  260. package/dist-types/components/ui/progress.d.ts.map +1 -0
  261. package/dist-types/components/ui/scroll-area.d.ts +6 -0
  262. package/dist-types/components/ui/scroll-area.d.ts.map +1 -0
  263. package/dist-types/components/ui/sheet.d.ts +15 -0
  264. package/dist-types/components/ui/sheet.d.ts.map +1 -0
  265. package/dist-types/components/ui/slider.d.ts +4 -0
  266. package/dist-types/components/ui/slider.d.ts.map +1 -0
  267. package/dist-types/components/ui/switch.d.ts +6 -0
  268. package/dist-types/components/ui/switch.d.ts.map +1 -0
  269. package/dist-types/components/ui/table.d.ts +2 -0
  270. package/dist-types/components/ui/table.d.ts.map +1 -0
  271. package/dist-types/components/ui/tabs.d.ts +11 -0
  272. package/dist-types/components/ui/tabs.d.ts.map +1 -0
  273. package/dist-types/components/ui/textarea.d.ts +2 -0
  274. package/dist-types/components/ui/textarea.d.ts.map +1 -0
  275. package/dist-types/components/ui/tooltip.d.ts +7 -0
  276. package/dist-types/components/ui/tooltip.d.ts.map +1 -0
  277. package/dist-types/hooks/use-copy-to-clipboard.d.ts +5 -0
  278. package/dist-types/hooks/use-copy-to-clipboard.d.ts.map +1 -0
  279. package/dist-types/hooks/use-integration-auth.d.ts +10 -0
  280. package/dist-types/hooks/use-integration-auth.d.ts.map +1 -0
  281. package/dist-types/hooks/use-live-media-progress.d.ts +14 -0
  282. package/dist-types/hooks/use-live-media-progress.d.ts.map +1 -0
  283. package/dist-types/hooks/use-notion-auth.d.ts +9 -0
  284. package/dist-types/hooks/use-notion-auth.d.ts.map +1 -0
  285. package/dist-types/host.d.ts +20 -0
  286. package/dist-types/host.d.ts.map +1 -0
  287. package/dist-types/lib/browser-cache.d.ts +7 -0
  288. package/dist-types/lib/browser-cache.d.ts.map +1 -0
  289. package/dist-types/lib/chat/chart-config.d.ts +2 -0
  290. package/dist-types/lib/chat/chart-config.d.ts.map +1 -0
  291. package/dist-types/lib/chat/data-export.d.ts +2 -0
  292. package/dist-types/lib/chat/data-export.d.ts.map +1 -0
  293. package/dist-types/lib/chat/live-tool-progress.d.ts +44 -0
  294. package/dist-types/lib/chat/live-tool-progress.d.ts.map +1 -0
  295. package/dist-types/lib/chat/message-feedback.d.ts +2 -0
  296. package/dist-types/lib/chat/message-feedback.d.ts.map +1 -0
  297. package/dist-types/lib/chat/table-presentation.d.ts +2 -0
  298. package/dist-types/lib/chat/table-presentation.d.ts.map +1 -0
  299. package/dist-types/lib/chat/tool-output.d.ts +3 -0
  300. package/dist-types/lib/chat/tool-output.d.ts.map +1 -0
  301. package/dist-types/lib/chat-supporting-clip.d.ts +11 -0
  302. package/dist-types/lib/chat-supporting-clip.d.ts.map +1 -0
  303. package/dist-types/lib/constants/stores.d.ts +6 -0
  304. package/dist-types/lib/constants/stores.d.ts.map +1 -0
  305. package/dist-types/lib/constants/tools.d.ts +27 -0
  306. package/dist-types/lib/constants/tools.d.ts.map +1 -0
  307. package/dist-types/lib/error-formatter.d.ts +2 -0
  308. package/dist-types/lib/error-formatter.d.ts.map +1 -0
  309. package/dist-types/lib/jobs-client.d.ts +7 -0
  310. package/dist-types/lib/jobs-client.d.ts.map +1 -0
  311. package/dist-types/lib/media/pdf.d.ts +6 -0
  312. package/dist-types/lib/media/pdf.d.ts.map +1 -0
  313. package/dist-types/lib/media/progress.d.ts +61 -0
  314. package/dist-types/lib/media/progress.d.ts.map +1 -0
  315. package/dist-types/lib/media/source-selection.d.ts +10 -0
  316. package/dist-types/lib/media/source-selection.d.ts.map +1 -0
  317. package/dist-types/lib/media/tool-indexing-estimate.d.ts +13 -0
  318. package/dist-types/lib/media/tool-indexing-estimate.d.ts.map +1 -0
  319. package/dist-types/lib/media/video-intelligence-capacity.d.ts +2 -0
  320. package/dist-types/lib/media/video-intelligence-capacity.d.ts.map +1 -0
  321. package/dist-types/lib/media/video-runtime-scope.d.ts +2 -0
  322. package/dist-types/lib/media/video-runtime-scope.d.ts.map +1 -0
  323. package/dist-types/lib/shared/error-formatter.d.ts +2 -0
  324. package/dist-types/lib/shared/error-formatter.d.ts.map +1 -0
  325. package/dist-types/lib/utils.d.ts +3 -0
  326. package/dist-types/lib/utils.d.ts.map +1 -0
  327. package/dist-types/storage.d.ts +5 -0
  328. package/dist-types/storage.d.ts.map +1 -0
  329. package/dist-types/store/chat-store.d.ts +19 -0
  330. package/dist-types/store/chat-store.d.ts.map +1 -0
  331. package/dist-types/store/scrape-store.d.ts +42 -0
  332. package/dist-types/store/scrape-store.d.ts.map +1 -0
  333. package/package.json +579 -3
  334. package/scripts/build-assets.mjs +12 -0
  335. package/src/asset-data.json +1 -0
  336. package/src/asset-server.ts +19 -0
  337. package/src/components/alerts/generic-alert.tsx +76 -0
  338. package/src/components/chat/canvas/doc-editor-provider.tsx +338 -0
  339. package/src/components/chat/canvas/document-canvas.tsx +98 -0
  340. package/src/components/chat/canvas/document-field.tsx +167 -0
  341. package/src/components/chat/canvas/document-viewer.tsx +446 -0
  342. package/src/components/chat/canvas/file-attachment-button.tsx +88 -0
  343. package/src/components/chat/chat-workspace.tsx +1552 -0
  344. package/src/components/chat/message-actions.tsx +96 -0
  345. package/src/components/chat/message-item.tsx +1398 -0
  346. package/src/components/chat/message-queue.tsx +86 -0
  347. package/src/components/chat/tools/chat-chart.tsx +558 -0
  348. package/src/components/chat/tools/chat-citations.tsx +152 -0
  349. package/src/components/chat/tools/chat-data-table.tsx +373 -0
  350. package/src/components/chat/tools/chat-file-export.tsx +49 -0
  351. package/src/components/chat/tools/chat-media-preview.tsx +466 -0
  352. package/src/components/chat/tools/chat-sandbox-result.tsx +130 -0
  353. package/src/components/chat/tools/chat-signature-request.tsx +810 -0
  354. package/src/components/chat/tools/chat-tabs.tsx +59 -0
  355. package/src/components/chat/tools/corpus-data-result.tsx +194 -0
  356. package/src/components/chat/tools/knowledge-base-result.tsx +345 -0
  357. package/src/components/chat/tools/visual-placement-modal.tsx +308 -0
  358. package/src/components/configure/custom-model-modal.tsx +209 -0
  359. package/src/components/configure/store-fields.tsx +129 -0
  360. package/src/components/data/corpus-panel.tsx +1223 -0
  361. package/src/components/data/data-entry-mode-switch.tsx +53 -0
  362. package/src/components/data/data-primary-action.ts +6 -0
  363. package/src/components/data/data-workspace.tsx +623 -0
  364. package/src/components/data/groups-panel.tsx +530 -0
  365. package/src/components/data/integration-resources-panel.tsx +282 -0
  366. package/src/components/data/integrations-panel.tsx +392 -0
  367. package/src/components/data/jobs-panel.tsx +490 -0
  368. package/src/components/data/jobs-tracking-button.tsx +224 -0
  369. package/src/components/data/live-media-progress.tsx +79 -0
  370. package/src/components/data/media-indexing-jobs-panel.tsx +190 -0
  371. package/src/components/data/media-panel.tsx +2905 -0
  372. package/src/components/data/notion-panel.tsx +408 -0
  373. package/src/components/data/paste-panel.tsx +82 -0
  374. package/src/components/data/project-data-page.tsx +55 -0
  375. package/src/components/data/scrape-panel.tsx +1290 -0
  376. package/src/components/data/tabular-preview.tsx +205 -0
  377. package/src/components/data/tool-indexing-dialog.tsx +210 -0
  378. package/src/components/data/upload-panel.tsx +1313 -0
  379. package/src/components/data/web-crawler-status.tsx +132 -0
  380. package/src/components/projects/project-form-dialog.tsx +97 -0
  381. package/src/components/projects/project-provider.tsx +143 -0
  382. package/src/components/settings/general/agent-customization-section.tsx +620 -0
  383. package/src/components/settings/general/mcp-connections-section.tsx +907 -0
  384. package/src/components/settings/general/model-combobox.tsx +235 -0
  385. package/src/components/settings/general/models-section.tsx +909 -0
  386. package/src/components/settings/general/sandbox-section.tsx +394 -0
  387. package/src/components/settings/general/search-scraping-section.tsx +757 -0
  388. package/src/components/settings/general/storage-indexing-section.tsx +394 -0
  389. package/src/components/ui/alert-dialog.tsx +162 -0
  390. package/src/components/ui/alert.tsx +69 -0
  391. package/src/components/ui/badge.tsx +49 -0
  392. package/src/components/ui/card.tsx +9 -0
  393. package/src/components/ui/checkbox.tsx +28 -0
  394. package/src/components/ui/collapsible.tsx +17 -0
  395. package/src/components/ui/command.tsx +175 -0
  396. package/src/components/ui/dialog.tsx +138 -0
  397. package/src/components/ui/dropdown-menu.tsx +267 -0
  398. package/src/components/ui/input-group.tsx +146 -0
  399. package/src/components/ui/input.tsx +19 -0
  400. package/src/components/ui/line-tabs.tsx +49 -0
  401. package/src/components/ui/popover.tsx +77 -0
  402. package/src/components/ui/progress.tsx +66 -0
  403. package/src/components/ui/scroll-area.tsx +51 -0
  404. package/src/components/ui/sheet.tsx +125 -0
  405. package/src/components/ui/slider.tsx +52 -0
  406. package/src/components/ui/switch.tsx +32 -0
  407. package/src/components/ui/table.tsx +10 -0
  408. package/src/components/ui/tabs.tsx +77 -0
  409. package/src/components/ui/textarea.tsx +1 -0
  410. package/src/components/ui/tooltip.tsx +54 -0
  411. package/src/hooks/use-copy-to-clipboard.ts +25 -0
  412. package/src/hooks/use-integration-auth.ts +39 -0
  413. package/src/hooks/use-live-media-progress.ts +71 -0
  414. package/src/hooks/use-notion-auth.ts +66 -0
  415. package/src/host.ts +55 -0
  416. package/src/lib/browser-cache.ts +17 -0
  417. package/src/lib/chat/chart-config.ts +1 -0
  418. package/src/lib/chat/data-export.ts +1 -0
  419. package/src/lib/chat/live-tool-progress.ts +69 -0
  420. package/src/lib/chat/message-feedback.ts +1 -0
  421. package/src/lib/chat/table-presentation.ts +1 -0
  422. package/src/lib/chat/tool-output.ts +14 -0
  423. package/src/lib/chat-supporting-clip.ts +16 -0
  424. package/src/lib/constants/stores.ts +12 -0
  425. package/src/lib/constants/tools.ts +178 -0
  426. package/src/lib/error-formatter.ts +30 -0
  427. package/src/lib/jobs-client.ts +27 -0
  428. package/src/lib/media/pdf.ts +57 -0
  429. package/src/lib/media/progress.ts +209 -0
  430. package/src/lib/media/source-selection.ts +47 -0
  431. package/src/lib/media/tool-indexing-estimate.ts +39 -0
  432. package/src/lib/media/video-intelligence-capacity.ts +1 -0
  433. package/src/lib/media/video-runtime-scope.ts +1 -0
  434. package/src/lib/shared/error-formatter.ts +1 -0
  435. package/src/lib/utils.ts +6 -0
  436. package/src/source.css +1 -0
  437. package/src/storage.ts +16 -0
  438. package/src/store/chat-store.ts +19 -0
  439. package/src/store/scrape-store.ts +76 -0
  440. package/src/styles.d.ts +1 -0
@@ -0,0 +1,86 @@
1
+ 'use client';
2
+
3
+ import { ChevronUp, ChevronDown, Trash2, Paperclip } from 'lucide-react';
4
+
5
+ export interface QueuedMessage {
6
+ id: string;
7
+ text: string;
8
+ files?: File[];
9
+ }
10
+
11
+ interface MessageQueueProps {
12
+ items: QueuedMessage[];
13
+ onRemove: (id: string) => void;
14
+ onMoveUp: (id: string) => void;
15
+ onMoveDown: (id: string) => void;
16
+ onEdit: (id: string) => void;
17
+ }
18
+
19
+ export function MessageQueue({ items, onRemove, onMoveUp, onMoveDown, onEdit }: MessageQueueProps) {
20
+ if (items.length === 0) return null;
21
+
22
+ return (
23
+ <div className="mx-auto mb-2 w-full max-w-3xl overflow-hidden rounded-2xl border border-border bg-card">
24
+ <div className="border-b border-border/60 px-3 py-1.5">
25
+ <span className="text-xs font-medium text-muted-foreground">
26
+ {items.length} queued message{items.length > 1 ? 's' : ''}
27
+ </span>
28
+ </div>
29
+ <ul className="max-h-40 overflow-y-auto scrollbar-none [&::-webkit-scrollbar]:hidden">
30
+ {items.map((item, index) => (
31
+ <li
32
+ key={item.id}
33
+ className="group flex items-start gap-2 border-border/40 px-3 py-2 text-sm transition-colors last:border-b-0 hover:bg-secondary"
34
+ >
35
+ <button
36
+ type="button"
37
+ onClick={() => onEdit(item.id)}
38
+ className="min-w-0 flex-1 cursor-pointer text-left"
39
+ title="Click to edit"
40
+ >
41
+ <p className="line-clamp-2 break-words text-foreground">
42
+ {item.text || '(attachment only)'}
43
+ </p>
44
+ {item.files && item.files.length > 0 && (
45
+ <div className="mt-1 flex items-center gap-1 text-muted-foreground">
46
+ <Paperclip className="size-3 shrink-0" />
47
+ <span className="truncate text-xs">
48
+ {item.files.map((f) => f.name).join(', ')}
49
+ </span>
50
+ </div>
51
+ )}
52
+ </button>
53
+ <div className="flex shrink-0 items-center gap-0.5 opacity-0 transition-opacity group-hover:opacity-100">
54
+ <button
55
+ type="button"
56
+ onClick={() => onMoveUp(item.id)}
57
+ disabled={index === 0}
58
+ className="flex h-6 w-6 items-center justify-center rounded text-muted-foreground transition hover:bg-muted-foreground/10 hover:text-foreground disabled:pointer-events-none disabled:opacity-30"
59
+ aria-label="Move up in queue"
60
+ >
61
+ <ChevronUp className="size-3.5" />
62
+ </button>
63
+ <button
64
+ type="button"
65
+ onClick={() => onMoveDown(item.id)}
66
+ disabled={index === items.length - 1}
67
+ className="flex h-6 w-6 items-center justify-center rounded text-muted-foreground transition hover:bg-muted-foreground/10 hover:text-foreground disabled:pointer-events-none disabled:opacity-30"
68
+ aria-label="Move down in queue"
69
+ >
70
+ <ChevronDown className="size-3.5" />
71
+ </button>
72
+ <button
73
+ type="button"
74
+ onClick={() => onRemove(item.id)}
75
+ className="flex h-6 w-6 items-center justify-center rounded text-muted-foreground transition hover:bg-destructive/10 hover:text-destructive"
76
+ aria-label="Remove from queue"
77
+ >
78
+ <Trash2 className="size-3.5" />
79
+ </button>
80
+ </div>
81
+ </li>
82
+ ))}
83
+ </ul>
84
+ </div>
85
+ );
86
+ }
@@ -0,0 +1,558 @@
1
+ 'use client';
2
+
3
+ import { useState, useRef, useCallback, useMemo } from 'react';
4
+ import {
5
+ BarChart,
6
+ Bar,
7
+ AreaChart,
8
+ Area,
9
+ LineChart,
10
+ Line,
11
+ PieChart,
12
+ Pie,
13
+ Cell,
14
+ ScatterChart,
15
+ Scatter,
16
+ RadarChart,
17
+ Radar,
18
+ PolarGrid,
19
+ PolarAngleAxis,
20
+ PolarRadiusAxis,
21
+ XAxis,
22
+ YAxis,
23
+ CartesianGrid,
24
+ Tooltip,
25
+ Legend,
26
+ ResponsiveContainer,
27
+ } from 'recharts';
28
+ import { Download, Copy, Check } from 'lucide-react';
29
+ import { Button } from '@larkup/workspace-ui/button';
30
+ import {
31
+ normalizeChartConfig,
32
+ type ChartConfig,
33
+ type SeriesConfig,
34
+ } from '../../../lib/chat/chart-config';
35
+
36
+ const CHART_COLORS = [
37
+ '#10b981', // green (emerald)
38
+ '#f97316', // orange
39
+ '#3b82f6', // blue
40
+ '#22c55e', // green
41
+ '#f59e0b', // amber/orange
42
+ '#0ea5e9', // sky blue
43
+ '#84cc16', // lime green
44
+ '#ea580c', // dark orange
45
+ '#2563eb', // dark blue
46
+ ];
47
+
48
+ /* Gradient definitions for area / bar fills */
49
+ function ChartGradients({ series }: { series: SeriesConfig[] }) {
50
+ return (
51
+ <defs>
52
+ {series.map((s, i) => {
53
+ const color = s.color || CHART_COLORS[i % CHART_COLORS.length];
54
+ return (
55
+ <linearGradient key={s.dataKey} id={`gradient-${s.dataKey}`} x1="0" y1="0" x2="0" y2="1">
56
+ <stop offset="5%" stopColor={color} stopOpacity={0.25} />
57
+ <stop offset="95%" stopColor={color} stopOpacity={0.02} />
58
+ </linearGradient>
59
+ );
60
+ })}
61
+ </defs>
62
+ );
63
+ }
64
+
65
+ function CustomTooltip({ active, payload, label }: any) {
66
+ if (!active || !payload || payload.length === 0) return null;
67
+
68
+ return (
69
+ <div className="rounded-lg border border-border/40 bg-card px-3 py-2.5 backdrop-blur-sm">
70
+ <p className="mb-1.5 text-xs font-medium text-foreground">{label}</p>
71
+ <div className="flex flex-col gap-1">
72
+ {payload.map((entry: any, i: number) => (
73
+ <div key={i} className="flex items-center gap-2 text-xs">
74
+ <span
75
+ className="h-2 w-2 shrink-0 rounded-full"
76
+ style={{ backgroundColor: entry.color }}
77
+ />
78
+ <span className="text-muted-foreground">{entry.name || entry.dataKey}:</span>
79
+ <span className="font-medium tabular-nums text-foreground">
80
+ {typeof entry.value === 'number'
81
+ ? entry.value.toLocaleString(undefined, {
82
+ maximumFractionDigits: 2,
83
+ })
84
+ : entry.value}
85
+ </span>
86
+ </div>
87
+ ))}
88
+ </div>
89
+ </div>
90
+ );
91
+ }
92
+
93
+ export type { ChartConfig } from '../../../lib/chat/chart-config';
94
+
95
+ function downloadCSV(data: Record<string, any>[], title: string) {
96
+ if (data.length === 0) return;
97
+ const keys = Object.keys(data[0]);
98
+ const csv = [
99
+ keys.join(','),
100
+ ...data.map((row) =>
101
+ keys
102
+ .map((k) => {
103
+ const v = String(row[k] ?? '');
104
+ return v.includes(',') ? `"${v}"` : v;
105
+ })
106
+ .join(','),
107
+ ),
108
+ ].join('\n');
109
+
110
+ const blob = new Blob([csv], { type: 'text/csv' });
111
+ const url = URL.createObjectURL(blob);
112
+ const a = document.createElement('a');
113
+ a.href = url;
114
+ a.download = `${title.replace(/\s+/g, '_').toLowerCase()}.csv`;
115
+ a.click();
116
+ URL.revokeObjectURL(url);
117
+ }
118
+
119
+ function copyDataToClipboard(data: Record<string, any>[]) {
120
+ if (data.length === 0) return;
121
+ const keys = Object.keys(data[0]);
122
+ const text = [
123
+ keys.join('\t'),
124
+ ...data.map((row) => keys.map((k) => String(row[k] ?? '')).join('\t')),
125
+ ].join('\n');
126
+ navigator.clipboard.writeText(text);
127
+ }
128
+
129
+ const AXIS_TICK_STYLE = {
130
+ fontSize: 11,
131
+ fill: 'var(--muted-foreground)',
132
+ fontFamily: 'inherit',
133
+ };
134
+
135
+ const AXIS_LINE_STYLE = {
136
+ stroke: 'var(--border)',
137
+ };
138
+
139
+ const LEGEND_WRAPPER_STYLE = { fontSize: 11, paddingTop: 12 };
140
+ const LEGEND_WRAPPER_STYLE_PIE = { fontSize: 11 };
141
+ const PIE_LABEL_LINE = { stroke: 'var(--muted-foreground)', strokeWidth: 1 };
142
+ const SCATTER_CURSOR = { strokeDasharray: '3 3' };
143
+ const POLAR_ANGLE_TICK = { fontSize: 11, fill: 'var(--muted-foreground)' };
144
+ const POLAR_RADIUS_TICK = { fontSize: 10, fill: 'var(--muted-foreground)' };
145
+ const ACTIVE_DOT = { r: 4, strokeWidth: 2, stroke: 'var(--card)' };
146
+ const BAR_RADIUS: [number, number, number, number] = [4, 4, 0, 0];
147
+ const CARTESIAN_CHART_MARGIN = { top: 6, right: 12, bottom: 8, left: 12 };
148
+ const X_AXIS_HEIGHT = 52;
149
+ const Y_AXIS_WIDTH = 62;
150
+ const AXIS_TICK_MARGIN = 8;
151
+ const X_AXIS_MIN_TICK_GAP = 24;
152
+ const X_AXIS_LABEL_OFFSET = -4;
153
+ const Y_AXIS_LABEL_OFFSET = -8;
154
+
155
+ const renderPieLabel = ({ name, percent }: any) => `${name} ${(percent * 100).toFixed(0)}%`;
156
+
157
+ function useDeepMemo<T>(factory: () => T, deps: any[]): T {
158
+ const ref = useRef<{ deps: any[]; value: T } | null>(null);
159
+
160
+ const depsStr = JSON.stringify(deps);
161
+
162
+ if (ref.current === null || JSON.stringify(ref.current.deps) !== depsStr) {
163
+ ref.current = { deps: JSON.parse(depsStr), value: factory() };
164
+ }
165
+
166
+ return ref.current.value;
167
+ }
168
+
169
+ export function ChatChart({ config }: { config: ChartConfig }) {
170
+ const chartRef = useRef<HTMLDivElement>(null);
171
+ const [copied, setCopied] = useState(false);
172
+ // Tool outputs are model-generated and historic conversations may contain
173
+ // older payload shapes. Normalize immediately before rendering as a final
174
+ // defensive boundary.
175
+ const normalizedConfig = useMemo(() => normalizeChartConfig(config), [config]);
176
+ const {
177
+ chartType,
178
+ title,
179
+ subtitle,
180
+ data,
181
+ xAxisKey,
182
+ series,
183
+ colors,
184
+ stacked,
185
+ showLegend = true,
186
+ xAxisLabel,
187
+ yAxisLabel,
188
+ } = normalizedConfig;
189
+
190
+ const stableData = data;
191
+ const stableSeries = series;
192
+ const stableXAxisKey = xAxisKey;
193
+
194
+ const chartColors = useDeepMemo(() => {
195
+ const palette = colors && colors.length > 0 ? colors : CHART_COLORS;
196
+ return stableSeries.map((s, i) => s.color || palette[i % palette.length]);
197
+ }, [stableSeries, colors]);
198
+
199
+ const pieColors = useDeepMemo(() => {
200
+ return colors && colors.length > 0 ? colors : CHART_COLORS;
201
+ }, [colors]);
202
+
203
+ const chartDots = useDeepMemo(() => {
204
+ return chartColors.map((color) => ({ r: 3, fill: color }));
205
+ }, [chartColors]);
206
+
207
+ const handleCopy = useCallback(() => {
208
+ copyDataToClipboard(stableData);
209
+ setCopied(true);
210
+ setTimeout(() => setCopied(false), 2000);
211
+ }, [stableData]);
212
+
213
+ const handleDownload = useCallback(() => downloadCSV(stableData, title), [stableData, title]);
214
+
215
+ // Memoize axis labels stably
216
+ const xLabelObj = useDeepMemo(
217
+ () =>
218
+ xAxisLabel
219
+ ? {
220
+ value: xAxisLabel,
221
+ position: 'insideBottom',
222
+ offset: X_AXIS_LABEL_OFFSET,
223
+ style: { fontSize: 11, fill: 'var(--muted-foreground)' },
224
+ }
225
+ : undefined,
226
+ [xAxisLabel],
227
+ );
228
+
229
+ const yLabelObj = useDeepMemo(
230
+ () =>
231
+ yAxisLabel
232
+ ? {
233
+ value: yAxisLabel,
234
+ angle: -90,
235
+ position: 'insideLeft',
236
+ offset: Y_AXIS_LABEL_OFFSET,
237
+ style: { fontSize: 11, fill: 'var(--muted-foreground)' },
238
+ }
239
+ : undefined,
240
+ [yAxisLabel],
241
+ );
242
+
243
+ const renderChart = () => {
244
+ switch (chartType) {
245
+ case 'bar':
246
+ return (
247
+ <BarChart
248
+ data={stableData}
249
+ barGap={4}
250
+ barCategoryGap="20%"
251
+ margin={CARTESIAN_CHART_MARGIN}
252
+ >
253
+ <CartesianGrid
254
+ strokeDasharray="3 3"
255
+ stroke="var(--border)"
256
+ opacity={0.4}
257
+ vertical={false}
258
+ />
259
+ <XAxis
260
+ dataKey={stableXAxisKey}
261
+ tick={AXIS_TICK_STYLE}
262
+ axisLine={AXIS_LINE_STYLE}
263
+ tickLine={false}
264
+ tickMargin={AXIS_TICK_MARGIN}
265
+ minTickGap={X_AXIS_MIN_TICK_GAP}
266
+ height={X_AXIS_HEIGHT}
267
+ label={xLabelObj as any}
268
+ />
269
+ <YAxis
270
+ tick={AXIS_TICK_STYLE}
271
+ axisLine={false}
272
+ tickLine={false}
273
+ tickMargin={AXIS_TICK_MARGIN}
274
+ width={Y_AXIS_WIDTH}
275
+ label={yLabelObj as any}
276
+ />
277
+ <Tooltip content={CustomTooltip} cursor={false} />
278
+ {showLegend && (
279
+ <Legend iconType="circle" iconSize={7} wrapperStyle={LEGEND_WRAPPER_STYLE} />
280
+ )}
281
+ {stableSeries.map((s, i) => (
282
+ <Bar
283
+ key={s.dataKey}
284
+ dataKey={s.dataKey}
285
+ name={s.label || s.dataKey}
286
+ fill={chartColors[i]}
287
+ stackId={stacked ? 'stack' : undefined}
288
+ radius={BAR_RADIUS as any}
289
+ maxBarSize={40}
290
+ animationDuration={700}
291
+ animationEasing="ease-in-out"
292
+ />
293
+ ))}
294
+ </BarChart>
295
+ );
296
+
297
+ case 'area':
298
+ return (
299
+ <AreaChart data={stableData} margin={CARTESIAN_CHART_MARGIN}>
300
+ <ChartGradients series={stableSeries} />
301
+ <CartesianGrid
302
+ strokeDasharray="3 3"
303
+ stroke="var(--border)"
304
+ opacity={0.4}
305
+ vertical={false}
306
+ />
307
+ <XAxis
308
+ dataKey={stableXAxisKey}
309
+ tick={AXIS_TICK_STYLE}
310
+ axisLine={AXIS_LINE_STYLE}
311
+ tickLine={false}
312
+ tickMargin={AXIS_TICK_MARGIN}
313
+ minTickGap={X_AXIS_MIN_TICK_GAP}
314
+ height={X_AXIS_HEIGHT}
315
+ label={xLabelObj as any}
316
+ />
317
+ <YAxis
318
+ tick={AXIS_TICK_STYLE}
319
+ axisLine={false}
320
+ tickLine={false}
321
+ tickMargin={AXIS_TICK_MARGIN}
322
+ width={Y_AXIS_WIDTH}
323
+ label={yLabelObj as any}
324
+ />
325
+ <Tooltip content={CustomTooltip} />
326
+ {showLegend && (
327
+ <Legend iconType="circle" iconSize={7} wrapperStyle={LEGEND_WRAPPER_STYLE} />
328
+ )}
329
+ {stableSeries.map((s, i) => (
330
+ <Area
331
+ key={s.dataKey}
332
+ type="monotone"
333
+ dataKey={s.dataKey}
334
+ name={s.label || s.dataKey}
335
+ stroke={chartColors[i]}
336
+ strokeWidth={2}
337
+ fill={`url(#gradient-${s.dataKey})`}
338
+ stackId={stacked ? 'stack' : undefined}
339
+ animationDuration={800}
340
+ animationEasing="ease-in-out"
341
+ />
342
+ ))}
343
+ </AreaChart>
344
+ );
345
+
346
+ case 'line':
347
+ return (
348
+ <LineChart data={stableData} margin={CARTESIAN_CHART_MARGIN}>
349
+ <CartesianGrid
350
+ strokeDasharray="3 3"
351
+ stroke="var(--border)"
352
+ opacity={0.4}
353
+ vertical={false}
354
+ />
355
+ <XAxis
356
+ dataKey={stableXAxisKey}
357
+ tick={AXIS_TICK_STYLE}
358
+ axisLine={AXIS_LINE_STYLE}
359
+ tickLine={false}
360
+ tickMargin={AXIS_TICK_MARGIN}
361
+ minTickGap={X_AXIS_MIN_TICK_GAP}
362
+ height={X_AXIS_HEIGHT}
363
+ label={xLabelObj as any}
364
+ />
365
+ <YAxis
366
+ tick={AXIS_TICK_STYLE}
367
+ axisLine={false}
368
+ tickLine={false}
369
+ tickMargin={AXIS_TICK_MARGIN}
370
+ width={Y_AXIS_WIDTH}
371
+ label={yLabelObj as any}
372
+ />
373
+ <Tooltip content={CustomTooltip} />
374
+ {showLegend && (
375
+ <Legend iconType="circle" iconSize={7} wrapperStyle={LEGEND_WRAPPER_STYLE} />
376
+ )}
377
+ {stableSeries.map((s, i) => (
378
+ <Line
379
+ key={s.dataKey}
380
+ type="monotone"
381
+ dataKey={s.dataKey}
382
+ name={s.label || s.dataKey}
383
+ stroke={chartColors[i]}
384
+ strokeWidth={2}
385
+ dot={chartDots[i]}
386
+ activeDot={ACTIVE_DOT}
387
+ animationDuration={800}
388
+ animationEasing="ease-in-out"
389
+ />
390
+ ))}
391
+ </LineChart>
392
+ );
393
+
394
+ case 'pie': {
395
+ const dataKey = stableSeries[0]?.dataKey || 'value';
396
+ return (
397
+ <PieChart>
398
+ <Tooltip content={CustomTooltip} />
399
+ <Pie
400
+ data={stableData}
401
+ dataKey={dataKey}
402
+ nameKey={stableXAxisKey}
403
+ cx="50%"
404
+ cy="50%"
405
+ outerRadius="75%"
406
+ innerRadius="48%"
407
+ paddingAngle={2}
408
+ animationDuration={700}
409
+ animationEasing="ease-in-out"
410
+ label={renderPieLabel}
411
+ labelLine={PIE_LABEL_LINE}
412
+ >
413
+ {stableData.map((entry, i) => (
414
+ <Cell
415
+ key={`cell-${i}`}
416
+ fill={pieColors[i % pieColors.length]}
417
+ stroke="var(--card)"
418
+ strokeWidth={2}
419
+ />
420
+ ))}
421
+ </Pie>
422
+ {showLegend && (
423
+ <Legend iconType="circle" iconSize={7} wrapperStyle={LEGEND_WRAPPER_STYLE_PIE} />
424
+ )}
425
+ </PieChart>
426
+ );
427
+ }
428
+
429
+ case 'scatter':
430
+ return (
431
+ <ScatterChart margin={CARTESIAN_CHART_MARGIN}>
432
+ <CartesianGrid
433
+ strokeDasharray="3 3"
434
+ stroke="var(--border)"
435
+ opacity={0.4}
436
+ vertical={false}
437
+ />
438
+ <XAxis
439
+ dataKey={stableXAxisKey}
440
+ type="number"
441
+ tick={AXIS_TICK_STYLE}
442
+ axisLine={AXIS_LINE_STYLE}
443
+ tickLine={false}
444
+ tickMargin={AXIS_TICK_MARGIN}
445
+ minTickGap={X_AXIS_MIN_TICK_GAP}
446
+ height={X_AXIS_HEIGHT}
447
+ name={xAxisLabel || stableXAxisKey}
448
+ label={xLabelObj as any}
449
+ />
450
+ <YAxis
451
+ dataKey={stableSeries[0]?.dataKey}
452
+ type="number"
453
+ tick={AXIS_TICK_STYLE}
454
+ axisLine={false}
455
+ tickLine={false}
456
+ tickMargin={AXIS_TICK_MARGIN}
457
+ width={Y_AXIS_WIDTH}
458
+ name={yAxisLabel || stableSeries[0]?.label || stableSeries[0]?.dataKey}
459
+ label={yLabelObj as any}
460
+ />
461
+ <Tooltip content={CustomTooltip} cursor={SCATTER_CURSOR} />
462
+ <Scatter
463
+ name={stableSeries[0]?.label || stableSeries[0]?.dataKey}
464
+ data={stableData}
465
+ fill={chartColors[0]}
466
+ animationDuration={700}
467
+ animationEasing="ease-in-out"
468
+ />
469
+ </ScatterChart>
470
+ );
471
+
472
+ case 'radar':
473
+ return (
474
+ <RadarChart data={stableData} outerRadius="75%">
475
+ <PolarGrid stroke="var(--border)" opacity={0.5} />
476
+ <PolarAngleAxis dataKey={stableXAxisKey} tick={POLAR_ANGLE_TICK} />
477
+ <PolarRadiusAxis tick={POLAR_RADIUS_TICK} />
478
+ <Tooltip content={CustomTooltip} />
479
+ {stableSeries.map((s, i) => (
480
+ <Radar
481
+ key={s.dataKey}
482
+ dataKey={s.dataKey}
483
+ name={s.label || s.dataKey}
484
+ stroke={chartColors[i]}
485
+ fill={chartColors[i]}
486
+ fillOpacity={0.12}
487
+ strokeWidth={2}
488
+ animationDuration={700}
489
+ animationEasing="ease-in-out"
490
+ />
491
+ ))}
492
+ {showLegend && (
493
+ <Legend iconType="circle" iconSize={7} wrapperStyle={LEGEND_WRAPPER_STYLE_PIE} />
494
+ )}
495
+ </RadarChart>
496
+ );
497
+
498
+ default:
499
+ return null;
500
+ }
501
+ };
502
+
503
+ if (normalizedConfig.error) {
504
+ return (
505
+ <div className="my-3 flex flex-col items-center justify-center rounded-lg border border-border/70 bg-transparent p-6 text-center text-muted-foreground">
506
+ <p className="text-sm">This chart could not be prepared</p>
507
+ <p className="text-xs opacity-70 mt-1">{normalizedConfig.error}</p>
508
+ </div>
509
+ );
510
+ }
511
+
512
+ return (
513
+ <div
514
+ ref={chartRef}
515
+ data-testid="chat-chart"
516
+ className="my-3 overflow-hidden rounded-lg border border-border/70 bg-muted/25 animate-in fade-in duration-300 [&_.recharts-surface]:outline-none [&_.recharts-wrapper]:outline-none [&_*:focus]:outline-none [&_*:focus-visible]:outline-none [&_*:focus-visible]:ring-0"
517
+ >
518
+ {/* Header */}
519
+ <div className="flex flex-row items-center justify-between gap-4 border-b border-border/30 px-3.5 py-2.5">
520
+ <div className="flex flex-col justify-center min-w-0">
521
+ <h3 className="text-sm font-semibold text-foreground truncate">{title}</h3>
522
+ {subtitle && <p className="mt-0.5 text-xs text-muted-foreground truncate">{subtitle}</p>}
523
+ </div>
524
+ </div>
525
+
526
+ <div className="px-1 pt-2.5 pb-0">
527
+ <div className="h-68 min-h-68 w-full sm:h-72 sm:min-h-72">
528
+ <ResponsiveContainer width="100%" height="100%" debounce={50}>
529
+ {renderChart() as any}
530
+ </ResponsiveContainer>
531
+ </div>
532
+ </div>
533
+
534
+ {/* Footer actions */}
535
+ <div className="flex flex-wrap items-center justify-start gap-1.5 border-t border-border/30 px-3 py-2">
536
+ <Button
537
+ variant="ghost"
538
+ size="sm"
539
+ className="h-7 gap-1.5 text-[11px] text-muted-foreground hover:text-foreground focus:ring-0 focus-visible:ring-0"
540
+ onClick={handleCopy}
541
+ >
542
+ {copied ? <Check className="h-3 w-3 text-emerald-500" /> : <Copy className="h-3 w-3" />}
543
+ {copied ? 'Copied' : 'Copy Data'}
544
+ </Button>
545
+
546
+ <Button
547
+ variant="ghost"
548
+ size="sm"
549
+ className="h-7 gap-1.5 text-[11px] text-muted-foreground hover:text-foreground focus:ring-0 focus-visible:ring-0"
550
+ onClick={handleDownload}
551
+ >
552
+ <Download className="h-3 w-3" />
553
+ CSV
554
+ </Button>
555
+ </div>
556
+ </div>
557
+ );
558
+ }