@hanzo/ui 5.0.2 → 5.1.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 (371) hide show
  1. package/dist/accordion.js +1 -0
  2. package/dist/accordion.mjs +1 -0
  3. package/dist/alert-dialog.js +1 -0
  4. package/dist/alert-dialog.mjs +1 -0
  5. package/dist/alert.js +1 -0
  6. package/dist/alert.mjs +1 -0
  7. package/dist/avatar.js +1 -0
  8. package/dist/avatar.mjs +1 -0
  9. package/dist/badge.js +1 -0
  10. package/dist/badge.mjs +1 -0
  11. package/dist/breadcrumb.js +1 -0
  12. package/dist/breadcrumb.mjs +1 -0
  13. package/dist/calendar.js +1 -0
  14. package/dist/calendar.mjs +1 -0
  15. package/dist/carousel.js +1 -0
  16. package/dist/carousel.mjs +1 -0
  17. package/dist/checkbox.js +1 -0
  18. package/dist/checkbox.mjs +1 -0
  19. package/dist/chunk-3H5S2OQ3.mjs +1 -0
  20. package/dist/chunk-5GRJ7UQX.js +1 -0
  21. package/dist/chunk-63HNMH7C.js +1 -0
  22. package/dist/chunk-72TOQ4DM.mjs +1 -0
  23. package/dist/chunk-7AEFTV5R.mjs +1 -0
  24. package/dist/chunk-7M4AVV2R.js +1 -0
  25. package/dist/chunk-DKPVJSBC.js +1 -0
  26. package/dist/chunk-EI7MMDWY.js +1 -0
  27. package/dist/chunk-GANGDIZG.mjs +1 -0
  28. package/dist/chunk-GRGT2Z4K.js +1 -0
  29. package/dist/chunk-JCUUC6NY.mjs +1 -0
  30. package/dist/chunk-JUQMWLIN.js +1 -0
  31. package/dist/chunk-PRVEIITE.js +1 -0
  32. package/dist/chunk-SH52AKNZ.js +1 -0
  33. package/dist/chunk-TU67EJEW.mjs +1 -0
  34. package/dist/chunk-WN5KN73U.mjs +1 -0
  35. package/dist/chunk-YSXGDEY5.mjs +1 -0
  36. package/dist/chunk-Z76OOVUE.mjs +1 -0
  37. package/dist/collapsible.js +1 -0
  38. package/dist/collapsible.mjs +1 -0
  39. package/dist/command.js +1 -0
  40. package/dist/command.mjs +1 -0
  41. package/dist/context-menu.js +1 -0
  42. package/dist/context-menu.mjs +1 -0
  43. package/dist/dialog.js +1 -0
  44. package/dist/dialog.mjs +1 -0
  45. package/dist/drawer.js +1 -0
  46. package/dist/drawer.mjs +1 -0
  47. package/dist/dropdown-menu.js +1 -0
  48. package/dist/dropdown-menu.mjs +1 -0
  49. package/dist/form.js +1 -0
  50. package/dist/form.mjs +1 -0
  51. package/dist/hover-card.js +1 -0
  52. package/dist/hover-card.mjs +1 -0
  53. package/dist/index.js +1 -9079
  54. package/dist/index.mjs +1 -8700
  55. package/dist/input-otp.js +1 -0
  56. package/dist/input-otp.mjs +1 -0
  57. package/dist/lib/utils.js +1 -0
  58. package/dist/lib/utils.mjs +1 -0
  59. package/dist/navigation-menu.js +1 -0
  60. package/dist/navigation-menu.mjs +1 -0
  61. package/dist/popover.js +1 -0
  62. package/dist/popover.mjs +1 -0
  63. package/dist/progress.js +1 -0
  64. package/dist/progress.mjs +1 -0
  65. package/dist/radio-group.js +1 -0
  66. package/dist/radio-group.mjs +1 -0
  67. package/dist/resizable.js +1 -0
  68. package/dist/resizable.mjs +1 -0
  69. package/dist/scroll-area.js +1 -0
  70. package/dist/scroll-area.mjs +1 -0
  71. package/dist/select.js +1 -0
  72. package/dist/select.mjs +1 -0
  73. package/dist/separator.js +1 -0
  74. package/dist/separator.mjs +1 -0
  75. package/dist/sheet.js +1 -0
  76. package/dist/sheet.mjs +1 -0
  77. package/dist/skeleton.js +1 -0
  78. package/dist/skeleton.mjs +1 -0
  79. package/dist/slider.js +1 -0
  80. package/dist/slider.mjs +1 -0
  81. package/dist/sonner.js +1 -0
  82. package/dist/sonner.mjs +1 -0
  83. package/dist/src/utils.js +1 -0
  84. package/dist/src/utils.mjs +1 -0
  85. package/dist/switch.js +1 -0
  86. package/dist/switch.mjs +1 -0
  87. package/dist/table.js +1 -0
  88. package/dist/table.mjs +1 -0
  89. package/dist/tabs.js +1 -0
  90. package/dist/tabs.mjs +1 -0
  91. package/dist/tailwind/index.js +1 -0
  92. package/dist/tailwind/index.mjs +1 -0
  93. package/dist/textarea.js +1 -0
  94. package/dist/textarea.mjs +1 -0
  95. package/dist/toggle-group.js +1 -0
  96. package/dist/toggle-group.mjs +1 -0
  97. package/dist/toggle.js +1 -0
  98. package/dist/toggle.mjs +1 -0
  99. package/dist/tooltip.js +1 -0
  100. package/dist/tooltip.mjs +1 -0
  101. package/dist/types/index.js +1 -0
  102. package/dist/types/index.mjs +1 -0
  103. package/package.json +110 -81
  104. package/assets/ai-icons.tsx +0 -207
  105. package/assets/crypto.tsx +0 -33
  106. package/assets/file-type-icon.tsx +0 -66
  107. package/assets/file.tsx +0 -45
  108. package/assets/general.tsx +0 -2318
  109. package/assets/hanzo-logo.svg +0 -9
  110. package/assets/hanzo-logo.tsx +0 -17
  111. package/assets/index.ts +0 -122
  112. package/assets/index.tsx +0 -4
  113. package/assets/llm-provider.tsx +0 -1094
  114. package/blocks/auth/index.ts +0 -6
  115. package/blocks/auth/login-2fa.tsx +0 -165
  116. package/blocks/auth/login-basic.tsx +0 -94
  117. package/blocks/auth/login-social.tsx +0 -148
  118. package/blocks/auth/magic-link.tsx +0 -129
  119. package/blocks/auth/password-reset.tsx +0 -97
  120. package/blocks/auth/signup.tsx +0 -157
  121. package/blocks/components/accordian-block.tsx +0 -48
  122. package/blocks/components/block-component-props.ts +0 -11
  123. package/blocks/components/bullet-cards-block.tsx +0 -46
  124. package/blocks/components/card-block/index.tsx +0 -171
  125. package/blocks/components/card-block/link-out-button.tsx +0 -20
  126. package/blocks/components/card-block/util.ts +0 -28
  127. package/blocks/components/carte-blanche-block/index.tsx +0 -127
  128. package/blocks/components/carte-blanche-block/variant-content-left.tsx +0 -49
  129. package/blocks/components/content.tsx +0 -70
  130. package/blocks/components/cta-block.tsx +0 -115
  131. package/blocks/components/enh-heading-block.tsx +0 -204
  132. package/blocks/components/grid-block/grid-block-mutator.ts +0 -12
  133. package/blocks/components/grid-block/index.tsx +0 -83
  134. package/blocks/components/grid-block/mutator-registry.ts +0 -10
  135. package/blocks/components/grid-block/table-borders.mutator.ts +0 -47
  136. package/blocks/components/group-block.tsx +0 -83
  137. package/blocks/components/heading-block.tsx +0 -88
  138. package/blocks/components/image-block.tsx +0 -111
  139. package/blocks/components/index.ts +0 -30
  140. package/blocks/components/screenful-block/content.tsx +0 -123
  141. package/blocks/components/screenful-block/index.tsx +0 -107
  142. package/blocks/components/screenful-block/poster-background.tsx +0 -34
  143. package/blocks/components/screenful-block/video-background.tsx +0 -45
  144. package/blocks/components/space-block.tsx +0 -66
  145. package/blocks/components/video-block.tsx +0 -138
  146. package/blocks/data-display/activity-feed.tsx +0 -242
  147. package/blocks/data-display/data-table.tsx +0 -235
  148. package/blocks/data-display/stats-grid.tsx +0 -194
  149. package/blocks/def/accordian-block.ts +0 -14
  150. package/blocks/def/block.ts +0 -7
  151. package/blocks/def/bullet-cards-block.ts +0 -22
  152. package/blocks/def/card-block.ts +0 -22
  153. package/blocks/def/carte-blanche-block.ts +0 -21
  154. package/blocks/def/cta-block.ts +0 -19
  155. package/blocks/def/element-block.ts +0 -11
  156. package/blocks/def/enh-heading-block.ts +0 -44
  157. package/blocks/def/grid-block.ts +0 -16
  158. package/blocks/def/group-block.ts +0 -11
  159. package/blocks/def/heading-block.ts +0 -15
  160. package/blocks/def/image-block.ts +0 -31
  161. package/blocks/def/index.ts +0 -35
  162. package/blocks/def/screenful-block.ts +0 -54
  163. package/blocks/def/space-block.ts +0 -64
  164. package/blocks/def/video-block.ts +0 -9
  165. package/blocks/ecommerce/checkout.tsx +0 -242
  166. package/blocks/ecommerce/index.ts +0 -7
  167. package/blocks/ecommerce/product-detail.tsx +0 -257
  168. package/blocks/ecommerce/product-grid.tsx +0 -148
  169. package/blocks/ecommerce/shopping-cart.tsx +0 -181
  170. package/blocks/index.ts +0 -2
  171. package/blocks/marketing/cta-section.tsx +0 -207
  172. package/blocks/marketing/faq.tsx +0 -159
  173. package/blocks/marketing/features-grid.tsx +0 -156
  174. package/blocks/marketing/hero-section.tsx +0 -192
  175. package/blocks/marketing/index.ts +0 -6
  176. package/blocks/marketing/pricing-table.tsx +0 -121
  177. package/blocks/marketing/testimonials.tsx +0 -196
  178. package/components/index.ts +0 -9
  179. package/dist/index.js.map +0 -1
  180. package/dist/index.mjs.map +0 -1
  181. package/dist/tailwind.js +0 -2025
  182. package/dist/tailwind.js.map +0 -1
  183. package/dist/tailwind.mjs +0 -2013
  184. package/dist/tailwind.mjs.map +0 -1
  185. package/dist/types.js +0 -59
  186. package/dist/types.js.map +0 -1
  187. package/dist/types.mjs +0 -53
  188. package/dist/types.mjs.map +0 -1
  189. package/dist/utils.js +0 -30
  190. package/dist/utils.js.map +0 -1
  191. package/dist/utils.mjs +0 -26
  192. package/dist/utils.mjs.map +0 -1
  193. package/frameworks/core/index.ts +0 -6
  194. package/frameworks/core/utils/index.ts +0 -64
  195. package/frameworks/react/components/button.tsx +0 -26
  196. package/frameworks/react/components/index.ts +0 -5
  197. package/frameworks/react/hooks/index.ts +0 -5
  198. package/frameworks/react/index.ts +0 -9
  199. package/frameworks/react/package.json +0 -8
  200. package/frameworks/react/utils/index.ts +0 -2
  201. package/frameworks/react-native/index.ts +0 -9
  202. package/frameworks/react-native/package.json +0 -8
  203. package/frameworks/registry.json +0 -371
  204. package/frameworks/setup.sh +0 -69
  205. package/frameworks/svelte/index.ts +0 -9
  206. package/frameworks/svelte/package.json +0 -8
  207. package/frameworks/tracker.json +0 -1854
  208. package/frameworks/vue/index.ts +0 -9
  209. package/frameworks/vue/package.json +0 -8
  210. package/helpers/file.ts +0 -33
  211. package/helpers/memoization.ts +0 -40
  212. package/primitives/accordion.tsx +0 -74
  213. package/primitives/action-button.tsx +0 -42
  214. package/primitives/alert-dialog.tsx +0 -185
  215. package/primitives/alert.tsx +0 -74
  216. package/primitives/apply-typography.tsx +0 -55
  217. package/primitives/aspect-ratio.tsx +0 -5
  218. package/primitives/avatar.tsx +0 -57
  219. package/primitives/background-beams.tsx +0 -142
  220. package/primitives/badge.tsx +0 -45
  221. package/primitives/breadcrumb.tsx +0 -130
  222. package/primitives/breakpoint-indicator.tsx +0 -19
  223. package/primitives/button.tsx +0 -72
  224. package/primitives/calendar.tsx +0 -72
  225. package/primitives/card.tsx +0 -97
  226. package/primitives/carousel.tsx +0 -238
  227. package/primitives/chat/chat-input-area.tsx +0 -88
  228. package/primitives/chat/chat-input.tsx +0 -71
  229. package/primitives/chat/files-preview.tsx +0 -331
  230. package/primitives/chat/index.ts +0 -6
  231. package/primitives/chat/json-form.tsx +0 -8
  232. package/primitives/chat/message-list.tsx +0 -308
  233. package/primitives/chat/message.tsx +0 -569
  234. package/primitives/chat/sqlite-preview.tsx +0 -215
  235. package/primitives/checkbox.tsx +0 -32
  236. package/primitives/collapsible.tsx +0 -9
  237. package/primitives/combobox.tsx +0 -239
  238. package/primitives/command.tsx +0 -151
  239. package/primitives/context-menu.tsx +0 -206
  240. package/primitives/copy-to-clipboard-icon.tsx +0 -60
  241. package/primitives/dialog-video-controller.tsx +0 -38
  242. package/primitives/dialog.tsx +0 -128
  243. package/primitives/dot-pattern.tsx +0 -57
  244. package/primitives/dots-loader.tsx +0 -13
  245. package/primitives/drawer.tsx +0 -113
  246. package/primitives/dropdown-menu.tsx +0 -199
  247. package/primitives/error-message.tsx +0 -19
  248. package/primitives/file-uploader.tsx +0 -203
  249. package/primitives/form.tsx +0 -185
  250. package/primitives/hover-card.tsx +0 -28
  251. package/primitives/icons/github.tsx +0 -14
  252. package/primitives/icons/index.ts +0 -18
  253. package/primitives/icons/youtube-logo.tsx +0 -59
  254. package/primitives/index-client.ts +0 -4
  255. package/primitives/index-common.ts +0 -304
  256. package/primitives/index-next.ts +0 -4
  257. package/primitives/input-otp.tsx +0 -65
  258. package/primitives/input.tsx +0 -128
  259. package/primitives/label.tsx +0 -21
  260. package/primitives/list-adaptor.ts +0 -12
  261. package/primitives/list-box.tsx +0 -74
  262. package/primitives/loading-spinner.tsx +0 -33
  263. package/primitives/markdown-preview.tsx +0 -612
  264. package/primitives/mermaid.tsx +0 -196
  265. package/primitives/navigation-menu.tsx +0 -147
  266. package/primitives/next/image.tsx +0 -91
  267. package/primitives/next/index.ts +0 -7
  268. package/primitives/next/inline-icon.tsx +0 -36
  269. package/primitives/next/link-element.tsx +0 -109
  270. package/primitives/next/mdx-link.tsx +0 -22
  271. package/primitives/next/media-stack.tsx +0 -52
  272. package/primitives/next/nav-items.tsx +0 -45
  273. package/primitives/next/youtube-embed.tsx +0 -83
  274. package/primitives/pagination.tsx +0 -117
  275. package/primitives/popover.tsx +0 -34
  276. package/primitives/pretty-json-print.tsx +0 -28
  277. package/primitives/progress.tsx +0 -27
  278. package/primitives/prompt-textarea.tsx +0 -72
  279. package/primitives/qr-code.tsx +0 -112
  280. package/primitives/radio-group.tsx +0 -42
  281. package/primitives/resizable.tsx +0 -47
  282. package/primitives/scroll-area.tsx +0 -57
  283. package/primitives/search-input.tsx +0 -66
  284. package/primitives/select.tsx +0 -122
  285. package/primitives/separator.tsx +0 -26
  286. package/primitives/sheet.tsx +0 -139
  287. package/primitives/skeleton.tsx +0 -18
  288. package/primitives/slider.tsx +0 -63
  289. package/primitives/sonner.tsx +0 -35
  290. package/primitives/step-indicator.tsx +0 -69
  291. package/primitives/stepper.tsx +0 -272
  292. package/primitives/switch.tsx +0 -27
  293. package/primitives/table.tsx +0 -105
  294. package/primitives/tabs.tsx +0 -50
  295. package/primitives/text-area.tsx +0 -26
  296. package/primitives/text-link.tsx +0 -27
  297. package/primitives/textarea.tsx +0 -64
  298. package/primitives/textfield.tsx +0 -78
  299. package/primitives/toast.tsx +0 -30
  300. package/primitives/toggle-group.tsx +0 -63
  301. package/primitives/toggle.tsx +0 -44
  302. package/primitives/tooltip.tsx +0 -47
  303. package/primitives/video-player.tsx +0 -23
  304. package/src/button.ts +0 -1
  305. package/src/hooks/index.ts +0 -7
  306. package/src/hooks/use-click-away.ts +0 -31
  307. package/src/hooks/use-combined-refs.ts +0 -22
  308. package/src/hooks/use-copy-clipboard.ts +0 -30
  309. package/src/hooks/use-debounce.ts +0 -17
  310. package/src/hooks/use-fill-ids.ts +0 -25
  311. package/src/hooks/use-map.ts +0 -26
  312. package/src/hooks/use-measure.ts +0 -42
  313. package/src/hooks/use-reverse-video-playback.ts +0 -43
  314. package/src/hooks/use-scroll-restoration.ts +0 -50
  315. package/src/index-lean.ts +0 -87
  316. package/src/index.ts +0 -54
  317. package/src/mcp/README.md +0 -141
  318. package/src/mcp/enhanced-server.ts +0 -1208
  319. package/src/mcp/index.ts +0 -518
  320. package/src/mcp/package.json +0 -10
  321. package/src/registry/api.ts +0 -164
  322. package/src/registry/index.ts +0 -60
  323. package/src/registry/package.json +0 -10
  324. package/src/utils.ts +0 -19
  325. package/tailwind/colors.tailwind.js +0 -53
  326. package/tailwind/fontFamily.tailwind.ts +0 -7
  327. package/tailwind/fontSize.tailwind.ts +0 -13
  328. package/tailwind/index.ts +0 -7
  329. package/tailwind/safelist.tailwind.js +0 -26
  330. package/tailwind/screens.tailwind.js +0 -8
  331. package/tailwind/spacing.tailwind.js +0 -65
  332. package/tailwind/tailwind.config.hanzo-preset.d.ts +0 -5
  333. package/tailwind/tailwind.config.hanzo-preset.js +0 -915
  334. package/tailwind/tw-font-desc.ts +0 -15
  335. package/tailwind/typo-plugin/get-plugin-styles.js +0 -679
  336. package/tailwind/typo-plugin/index.d.ts +0 -9
  337. package/tailwind/typo-plugin/index.js +0 -141
  338. package/tailwind/typo-plugin/utils.js +0 -60
  339. package/tailwind/typography-test.mdx +0 -35
  340. package/tailwind/z-index.tailwind.js +0 -71
  341. package/types/animation-def.ts +0 -3
  342. package/types/breakpoints.ts +0 -11
  343. package/types/bullet-item.ts +0 -10
  344. package/types/button-def.ts +0 -39
  345. package/types/dimensions.ts +0 -8
  346. package/types/grid-def.ts +0 -56
  347. package/types/image-def.ts +0 -32
  348. package/types/index.ts +0 -30
  349. package/types/link-def.ts +0 -56
  350. package/types/media-stack-def.ts +0 -31
  351. package/types/t-shirt-size.ts +0 -5
  352. package/types/tshirt-dimensions.ts +0 -20
  353. package/types/video-def.ts +0 -25
  354. package/util/blob.ts +0 -33
  355. package/util/copy-to-clipboard.ts +0 -17
  356. package/util/create-shadow-root.ts +0 -22
  357. package/util/date.ts +0 -84
  358. package/util/debounce.ts +0 -11
  359. package/util/file.ts +0 -15
  360. package/util/format-and-abbreviate-as-currency.ts +0 -125
  361. package/util/format-text.ts +0 -34
  362. package/util/format-to-max-char.ts +0 -68
  363. package/util/index-client.ts +0 -3
  364. package/util/index.ts +0 -112
  365. package/util/number-abbreviate.ts +0 -49
  366. package/util/specifier.ts +0 -43
  367. package/util/spread-to-transform.ts +0 -25
  368. package/util/step-animation.ts +0 -90
  369. package/util/timing.ts +0 -3
  370. package/util/toasts.tsx +0 -17
  371. package/util/two-way-map.ts +0 -19
@@ -1,569 +0,0 @@
1
- import { zodResolver } from '@hookform/resolvers/zod';
2
- import { useTranslation } from '@hanzo_network/hanzo-i18n';
3
- import {
4
- type ToolArgs,
5
- ToolStatusType,
6
- } from '@hanzo_network/hanzo-message-ts/api/general/types';
7
- import {
8
- type Artifact,
9
- type FormattedMessage,
10
- } from '@hanzo_network/hanzo-node-state/v2/queries/getChatConversation/types';
11
- import { format } from 'date-fns';
12
- import { AnimatePresence, motion } from 'framer-motion';
13
- import { Edit3, Loader2, RotateCcw, XCircle } from 'lucide-react';
14
- import { InfoCircleIcon } from 'primereact/icons/infocircle';
15
- import React, { Fragment, memo, useEffect, useMemo, useState } from 'react';
16
- import { useForm } from 'react-hook-form';
17
- import { Link } from 'react-router';
18
- import { z } from 'zod';
19
-
20
- import { appIcon, ReactJsIcon, ToolsIcon } from '../../assets';
21
- import { formatText } from '../../helpers/format-text';
22
- import { cn } from '../src/utils';
23
- import {
24
- Accordion,
25
- AccordionContent,
26
- AccordionItem,
27
- AccordionTrigger,
28
- } from '../accordion';
29
- import { Avatar, AvatarFallback } from '../avatar';
30
- import { Button } from '../button';
31
- import { Card, CardContent } from '../card';
32
- import { CopyToClipboardIcon } from '../copy-to-clipboard-icon';
33
- import { DotsLoader } from '../dots-loader';
34
- import { Form, FormField } from '../form';
35
- import { MarkdownText } from '../markdown-preview';
36
- import { PrettyJsonPrint } from '../pretty-json-print';
37
- import {
38
- Tooltip,
39
- TooltipContent,
40
- TooltipPortal,
41
- TooltipProvider,
42
- TooltipTrigger,
43
- } from '../tooltip';
44
- import { ChatInputArea } from './chat-input-area';
45
- import { FileList } from './files-preview';
46
- // import { PythonCodeRunner } from './python-code-runner/python-code-runner';
47
-
48
- export const extractErrorPropertyOrContent = (
49
- content: string,
50
- property: 'error' | 'error_message',
51
- ) => {
52
- try {
53
- const parsedContent = JSON.parse(content);
54
- if (property in parsedContent) {
55
- return parsedContent[property];
56
- }
57
- } catch {
58
- /* ignore */
59
- }
60
- return String(content);
61
- };
62
-
63
- const containsPythonCode = (content: string): boolean => {
64
- const pythonCodeRegex = /```python\s[\s\S]*?```/;
65
- return pythonCodeRegex.test(content);
66
- };
67
-
68
- type MessageProps = {
69
- messageId: string;
70
- isPending?: boolean;
71
- message: FormattedMessage;
72
- handleRetryMessage?: () => void;
73
- disabledRetry?: boolean;
74
- disabledEdit?: boolean;
75
- handleEditMessage?: (message: string) => void;
76
- messageExtra?: React.ReactNode;
77
-
78
- artifacts?: Artifact[];
79
- artifact?: Artifact;
80
- hidePythonExecution?: boolean;
81
- };
82
-
83
- const actionBar = {
84
- rest: {
85
- opacity: 0,
86
- scale: 0.8,
87
- transition: {
88
- type: 'spring',
89
- bounce: 0,
90
- duration: 0.3,
91
- },
92
- },
93
- hover: {
94
- opacity: 1,
95
- scale: 1,
96
- transition: {
97
- type: 'spring',
98
- duration: 0.3,
99
- bounce: 0,
100
- },
101
- },
102
- };
103
-
104
- type ArtifactProps = {
105
- title: string;
106
- type: string;
107
- identifier: string;
108
- loading?: boolean;
109
- isSelected?: boolean;
110
- onArtifactClick?: () => void;
111
- };
112
- const ArtifactCard = ({
113
- title,
114
- loading = true,
115
- onArtifactClick,
116
- isSelected,
117
- identifier,
118
- }: ArtifactProps) => (
119
- <Card
120
- className={cn(
121
- 'w-full max-w-sm border border-gray-100',
122
- isSelected && 'border-gray-50 bg-gray-300',
123
- )}
124
- onClick={() => {
125
- onArtifactClick?.();
126
- }}
127
- role="button"
128
- >
129
- <CardContent className="flex items-center gap-1 p-1 py-1.5">
130
- <div className="rounded-md p-2">
131
- {loading ? (
132
- <Loader2 className="text-text-secondary h-5 w-5 animate-spin" />
133
- ) : (
134
- <ReactJsIcon
135
- className={cn(isSelected ? 'text-gray-50' : 'text-text-secondary')}
136
- />
137
- )}
138
- </div>
139
- <div className="flex flex-1 flex-col gap-0.5">
140
- <p className="!mb-0 line-clamp-1 text-sm font-medium text-gray-50">
141
- {title}
142
- </p>
143
- <p className="text-text-secondary !mb-0 text-xs">
144
- {loading ? 'Generating...' : 'Click to preview'}
145
- </p>
146
- </div>
147
- </CardContent>
148
- </Card>
149
- );
150
-
151
- export const editMessageFormSchema = z.object({
152
- message: z.string().min(1),
153
- });
154
-
155
- type EditMessageFormSchema = z.infer<typeof editMessageFormSchema>;
156
-
157
- const MessageBase = ({
158
- message,
159
- messageId,
160
- isPending,
161
- handleRetryMessage,
162
- disabledRetry,
163
- disabledEdit,
164
- handleEditMessage,
165
- hidePythonExecution,
166
- }: MessageProps) => {
167
- const { t } = useTranslation();
168
-
169
- const [editing, setEditing] = useState(false);
170
-
171
- const editMessageForm = useForm<EditMessageFormSchema>({
172
- resolver: zodResolver(editMessageFormSchema),
173
- defaultValues: {
174
- message: message.content,
175
- },
176
- });
177
-
178
- const { message: currentMessage } = editMessageForm.watch();
179
-
180
- const onSubmit = async (data: z.infer<typeof editMessageFormSchema>) => {
181
- if (message.role === 'user') {
182
- handleEditMessage?.(data.message);
183
- setEditing(false);
184
- }
185
- };
186
-
187
- useEffect(() => {
188
- if (message.role === 'user') {
189
- editMessageForm.reset({ message: message.content });
190
- }
191
- }, [editMessageForm, message.content]);
192
-
193
- const pythonCode = useMemo(() => {
194
- if (containsPythonCode(message.content)) {
195
- const match = message.content.match(/```python\s([\s\S]*?)```/);
196
- return match ? match[1] : null;
197
- }
198
- return null;
199
- }, [message.content]);
200
-
201
- return (
202
- <motion.div
203
- animate="rest"
204
- className="pb-10"
205
- data-testid={`message-${
206
- message.role === 'user' ? 'local' : 'remote'
207
- }-${message.messageId}`}
208
- id={message.messageId}
209
- initial="rest"
210
- whileHover="hover"
211
- >
212
- <div
213
- className={cn(
214
- 'relative flex flex-row space-x-2',
215
- message.role === 'user' &&
216
- 'mr-0 ml-auto flex-row-reverse space-x-reverse',
217
- message.role === 'assistant' && 'mr-auto ml-0 flex-row items-end',
218
- )}
219
- >
220
- <a href={`#${messageId}`}>
221
- <Avatar className={cn('mt-1 h-8 w-8')}>
222
- {message.role === 'assistant' ? (
223
- <img alt="Hanzo AI" src={appIcon} />
224
- ) : null}
225
- </Avatar>
226
- </a>
227
- <div
228
- className={cn(
229
- 'container flex flex-col overflow-hidden bg-transparent text-sm text-white',
230
- editing && 'w-full py-1',
231
- )}
232
- >
233
- {editing ? (
234
- <Form {...editMessageForm}>
235
- <form
236
- className="relative flex items-center"
237
- onSubmit={editMessageForm.handleSubmit(onSubmit)}
238
- >
239
- <div className="w-full">
240
- <FormField
241
- control={editMessageForm.control}
242
- name="message"
243
- render={({ field }) => (
244
- <ChatInputArea
245
- bottomAddons={
246
- <div className="flex w-full items-center justify-between px-1">
247
- <div className="text-text-secondary flex items-center gap-1 text-xs">
248
- <InfoCircleIcon className="text-text-secondary h-3 w-3" />
249
- <span>{t('chat.editMessage.warning')}</span>
250
- </div>
251
- <div className="flex items-center gap-2">
252
- <Button
253
- className="min-w-[90px] rounded-lg"
254
- onClick={() => setEditing(false)}
255
- size="sm"
256
- variant="outline"
257
- >
258
- {t('common.cancel')}
259
- </Button>
260
- <Button
261
- className="min-w-[90px] rounded-lg"
262
- disabled={!currentMessage}
263
- onClick={editMessageForm.handleSubmit(onSubmit)}
264
- size="sm"
265
- >
266
- {t('common.send')}
267
- </Button>
268
- </div>
269
- </div>
270
- }
271
- onChange={field.onChange}
272
- onSubmit={editMessageForm.handleSubmit(onSubmit)}
273
- value={field.value}
274
- />
275
- )}
276
- />
277
- </div>
278
- </form>
279
- </Form>
280
- ) : (
281
- <Fragment>
282
- <div
283
- className={cn(
284
- 'relative mt-1 flex flex-col rounded-lg bg-black/40 px-3.5 pt-3 text-sm text-white',
285
- message.role === 'user'
286
- ? 'rounded-tr-none bg-gray-300'
287
- : 'rounded-bl-none border-none bg-gray-200',
288
- !message.content ? 'pb-3' : 'pb-4',
289
- editing && 'w-full py-1',
290
- message.role === 'assistant' &&
291
- isPending &&
292
- 'relative overflow-hidden pb-4 before:absolute before:right-0 before:bottom-0 before:left-0 before:h-10 before:animate-pulse before:bg-gradient-to-l before:from-gray-200 before:to-gray-200/10',
293
- )}
294
- >
295
- {message.role === 'assistant' &&
296
- message.toolCalls &&
297
- message.toolCalls.length > 0 && (
298
- <Accordion
299
- className="space-y-1.5 self-baseline pb-3"
300
- type="multiple"
301
- >
302
- {message.toolCalls.map((tool, index) => {
303
- return (
304
- <AccordionItem
305
- className="bg-bg-secondary overflow-hidden rounded-lg"
306
- disabled={tool.status !== ToolStatusType.Complete}
307
- key={`${tool.name}-${index}`}
308
- value={tool.name}
309
- >
310
- <AccordionTrigger
311
- className={cn(
312
- 'min-w-[10rem] py-0 pr-2 no-underline hover:no-underline',
313
- 'hover:bg-bg-default [&[data-state=open]]:bg-bg-default transition-colors',
314
- tool.status !== ToolStatusType.Complete &&
315
- '[&>svg]:hidden',
316
- )}
317
- >
318
- <ToolCard
319
- args={tool.args}
320
- name={tool.name}
321
- status={tool.status ?? ToolStatusType.Complete}
322
- toolRouterKey={tool.toolRouterKey}
323
- />
324
- </AccordionTrigger>
325
- <AccordionContent className="bg-gray-450 flex flex-col gap-1 overflow-x-scroll rounded-b-lg px-3 pt-2 pb-3 text-xs">
326
- {Object.keys(tool.args).length > 0 && (
327
- <span className="font-medium text-white">
328
- {tool.name}(
329
- {Object.keys(tool.args).length > 0 && (
330
- <span className="text-text-secondary font-mono font-medium">
331
- {JSON.stringify(tool.args)}
332
- </span>
333
- )}
334
- )
335
- </span>
336
- )}
337
- {tool.result && (
338
- <div>
339
- <span>Response:</span>
340
- <span className="text-text-secondary font-mono break-all">
341
- <PrettyJsonPrint json={tool.result} />
342
- </span>
343
- </div>
344
- )}
345
- </AccordionContent>
346
- </AccordionItem>
347
- );
348
- })}
349
- </Accordion>
350
- )}
351
- {message.role === 'assistant' && (
352
- <MarkdownText
353
- content={extractErrorPropertyOrContent(
354
- message.content,
355
- 'error_message',
356
- )}
357
- isRunning={
358
- !!message.content && message.status.type === 'running'
359
- }
360
- />
361
- )}
362
-
363
- {message.role === 'user' && (
364
- <div className="whitespace-pre-line">{message.content}</div>
365
- )}
366
-
367
- {message.role === 'assistant' &&
368
- message.status.type === 'running' &&
369
- message.content === '' && (
370
- <div className="pt-1.5 whitespace-pre-line">
371
- <DotsLoader />
372
- </div>
373
- )}
374
- {/*{pythonCode && !hidePythonExecution && (*/}
375
- {/* <PythonCodeRunner code={pythonCode} />*/}
376
- {/*)}*/}
377
- {message.role === 'user' && !!message.attachments.length && (
378
- <FileList
379
- className="mt-2 max-w-[70vw] min-w-[200px]"
380
- files={message.attachments}
381
- />
382
- )}
383
- </div>
384
- {!isPending && (
385
- <motion.div
386
- className={cn(
387
- 'absolute -bottom-[34px] flex items-center justify-end gap-3',
388
- message.role === 'user'
389
- ? 'right-10 flex-row-reverse'
390
- : 'left-10 flex-row',
391
- )}
392
- variants={actionBar}
393
- >
394
- <div className="flex items-center gap-1.5">
395
- {message.role === 'user' && !disabledEdit && (
396
- <TooltipProvider delayDuration={0}>
397
- <Tooltip>
398
- <TooltipTrigger asChild>
399
- <button
400
- className={cn(
401
- 'text-text-secondary flex h-7 w-7 items-center justify-center rounded-lg border border-gray-200 bg-transparent transition-colors hover:bg-gray-300 hover:text-white [&>svg]:h-3 [&>svg]:w-3',
402
- )}
403
- onClick={() => {
404
- setEditing(true);
405
- }}
406
- >
407
- <Edit3 />
408
- </button>
409
- </TooltipTrigger>
410
- <TooltipPortal>
411
- <TooltipContent>
412
- <p>{t('common.editMessage')}</p>
413
- </TooltipContent>
414
- </TooltipPortal>
415
- </Tooltip>
416
- </TooltipProvider>
417
- )}
418
- {message.role === 'assistant' && !disabledRetry && (
419
- <TooltipProvider delayDuration={0}>
420
- <Tooltip>
421
- <TooltipTrigger asChild>
422
- <button
423
- className={cn(
424
- 'text-text-secondary flex h-7 w-7 items-center justify-center rounded-lg border border-gray-200 bg-transparent transition-colors hover:bg-gray-300 hover:text-white [&>svg]:h-3 [&>svg]:w-3',
425
- )}
426
- onClick={handleRetryMessage}
427
- >
428
- <RotateCcw />
429
- </button>
430
- </TooltipTrigger>
431
- <TooltipPortal>
432
- <TooltipContent>
433
- <p>{t('common.retry')}</p>
434
- </TooltipContent>
435
- </TooltipPortal>
436
- </Tooltip>
437
- </TooltipProvider>
438
- )}
439
- <TooltipProvider delayDuration={0}>
440
- <Tooltip>
441
- <TooltipTrigger asChild>
442
- <div>
443
- <CopyToClipboardIcon
444
- className={cn(
445
- 'text-text-secondary h-7 w-7 border border-gray-200 bg-transparent hover:bg-gray-300 [&>svg]:h-3 [&>svg]:w-3',
446
- )}
447
- string={extractErrorPropertyOrContent(
448
- message.content,
449
- 'error_message',
450
- )}
451
- />
452
- </div>
453
- </TooltipTrigger>
454
- <TooltipPortal>
455
- <TooltipContent>
456
- <p>{t('common.copy')}</p>
457
- </TooltipContent>
458
- </TooltipPortal>
459
- </Tooltip>
460
- </TooltipProvider>
461
- </div>
462
- <div
463
- className={cn(
464
- 'text-text-secondary flex items-center gap-1.5 text-xs',
465
- )}
466
- >
467
- <span>
468
- {format(new Date(message?.createdAt ?? ''), 'p')}
469
- </span>
470
- {message.role === 'assistant' && message?.metadata?.tps && (
471
- <>
472
- {' '}
473
-
474
- <span>
475
- {Math.round(Number(message?.metadata?.tps) * 10) / 10}{' '}
476
- tokens/s
477
- </span>
478
- </>
479
- )}
480
- </div>
481
- </motion.div>
482
- )}
483
- </Fragment>
484
- )}
485
- </div>
486
- </div>
487
- </motion.div>
488
- );
489
- };
490
-
491
- export const Message = memo(
492
- MessageBase,
493
- (prev, next) =>
494
- prev.messageId === next.messageId &&
495
- prev.message.content === next.message.content &&
496
- prev.artifacts?.length === next.artifacts?.length &&
497
- prev.artifact === next.artifact,
498
- );
499
-
500
- const variants = {
501
- initial: { opacity: 0, y: -25 },
502
- visible: { opacity: 1, y: 0 },
503
- exit: { opacity: 0, y: 25 },
504
- };
505
-
506
- export function ToolCard({
507
- name,
508
- // args,
509
- status,
510
- toolRouterKey,
511
- }: {
512
- args: ToolArgs;
513
- status: ToolStatusType;
514
- name: string;
515
- toolRouterKey: string;
516
- }) {
517
- const renderStatus = () => {
518
- if (status === ToolStatusType.Complete) {
519
- return <ToolsIcon className="text-brand size-full" />;
520
- }
521
- if (status === ToolStatusType.Incomplete) {
522
- return <XCircle className="text-text-secondary size-full" />;
523
- }
524
- if (status === ToolStatusType.RequiresAction) {
525
- return <InfoCircleIcon className="text-text-secondary size-full" />;
526
- }
527
- return <Loader2 className="text-brand size-full animate-spin" />;
528
- };
529
-
530
- const renderLabelText = () => {
531
- if (status === ToolStatusType.Complete) {
532
- return 'Tool Used';
533
- }
534
- if (status === ToolStatusType.Incomplete) {
535
- return 'Incomplete';
536
- }
537
- if (status === ToolStatusType.RequiresAction) {
538
- return 'Requires Action';
539
- }
540
- return 'Processing Tool';
541
- };
542
-
543
- return (
544
- <AnimatePresence initial={false} mode="popLayout">
545
- <motion.div
546
- animate="visible"
547
- exit="exit"
548
- initial="initial"
549
- transition={{ type: 'spring', duration: 0.3, bounce: 0 }}
550
- variants={variants}
551
- >
552
- <div className="flex items-center gap-1 p-[5px]">
553
- <div className="size-7 shrink-0 px-1.5">{renderStatus()}</div>
554
- <div className="flex items-center gap-1">
555
- <span className="text-text-secondary text-em-sm">
556
- {renderLabelText()}
557
- </span>
558
- <Link
559
- className="text-gray-white text-em-sm font-semibold hover:underline"
560
- to={`/tools/${toolRouterKey}`}
561
- >
562
- {formatText(name)}
563
- </Link>
564
- </div>
565
- </div>
566
- </motion.div>
567
- </AnimatePresence>
568
- );
569
- }