@assistant-ui/mcp-docs-server 0.1.14 → 0.1.16
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.
- package/.docs/organized/code-examples/store-example.md +628 -0
- package/.docs/organized/code-examples/with-ag-ui.md +792 -178
- package/.docs/organized/code-examples/with-ai-sdk-v5.md +762 -209
- package/.docs/organized/code-examples/with-assistant-transport.md +707 -254
- package/.docs/organized/code-examples/with-cloud.md +848 -202
- package/.docs/organized/code-examples/with-custom-thread-list.md +1855 -0
- package/.docs/organized/code-examples/with-external-store.md +788 -172
- package/.docs/organized/code-examples/with-ffmpeg.md +796 -196
- package/.docs/organized/code-examples/with-langgraph.md +864 -230
- package/.docs/organized/code-examples/with-parent-id-grouping.md +785 -255
- package/.docs/organized/code-examples/with-react-hook-form.md +804 -226
- package/.docs/organized/code-examples/with-tanstack.md +1574 -0
- package/.docs/raw/blog/2024-07-29-hello/index.mdx +2 -3
- package/.docs/raw/docs/api-reference/overview.mdx +6 -6
- package/.docs/raw/docs/api-reference/primitives/ActionBar.mdx +85 -4
- package/.docs/raw/docs/api-reference/primitives/AssistantIf.mdx +200 -0
- package/.docs/raw/docs/api-reference/primitives/Composer.mdx +0 -20
- package/.docs/raw/docs/api-reference/primitives/Message.mdx +0 -45
- package/.docs/raw/docs/api-reference/primitives/Thread.mdx +0 -50
- package/.docs/raw/docs/cli.mdx +396 -0
- package/.docs/raw/docs/cloud/persistence/ai-sdk.mdx +2 -3
- package/.docs/raw/docs/cloud/persistence/langgraph.mdx +2 -3
- package/.docs/raw/docs/devtools.mdx +2 -3
- package/.docs/raw/docs/getting-started.mdx +37 -1109
- package/.docs/raw/docs/guides/Attachments.mdx +3 -25
- package/.docs/raw/docs/guides/Branching.mdx +1 -1
- package/.docs/raw/docs/guides/Speech.mdx +1 -1
- package/.docs/raw/docs/guides/ToolUI.mdx +1 -1
- package/.docs/raw/docs/legacy/styled/AssistantModal.mdx +2 -3
- package/.docs/raw/docs/legacy/styled/Decomposition.mdx +6 -5
- package/.docs/raw/docs/legacy/styled/Markdown.mdx +2 -3
- package/.docs/raw/docs/legacy/styled/Thread.mdx +2 -3
- package/.docs/raw/docs/react-compatibility.mdx +2 -5
- package/.docs/raw/docs/runtimes/ai-sdk/use-chat.mdx +3 -4
- package/.docs/raw/docs/runtimes/ai-sdk/v4-legacy.mdx +3 -6
- package/.docs/raw/docs/runtimes/assistant-transport.mdx +891 -0
- package/.docs/raw/docs/runtimes/custom/external-store.mdx +2 -3
- package/.docs/raw/docs/runtimes/custom/local.mdx +11 -41
- package/.docs/raw/docs/runtimes/data-stream.mdx +15 -11
- package/.docs/raw/docs/runtimes/langgraph/index.mdx +4 -4
- package/.docs/raw/docs/runtimes/langgraph/tutorial/part-2.mdx +1 -1
- package/.docs/raw/docs/runtimes/langgraph/tutorial/part-3.mdx +2 -3
- package/.docs/raw/docs/runtimes/langserve.mdx +2 -3
- package/.docs/raw/docs/runtimes/mastra/full-stack-integration.mdx +2 -3
- package/.docs/raw/docs/runtimes/mastra/separate-server-integration.mdx +2 -3
- package/.docs/raw/docs/ui/AssistantModal.mdx +3 -25
- package/.docs/raw/docs/ui/AssistantSidebar.mdx +2 -24
- package/.docs/raw/docs/ui/Attachment.mdx +3 -25
- package/.docs/raw/docs/ui/Markdown.mdx +2 -24
- package/.docs/raw/docs/ui/Mermaid.mdx +2 -24
- package/.docs/raw/docs/ui/Reasoning.mdx +2 -24
- package/.docs/raw/docs/ui/Scrollbar.mdx +4 -6
- package/.docs/raw/docs/ui/SyntaxHighlighting.mdx +3 -47
- package/.docs/raw/docs/ui/Thread.mdx +38 -53
- package/.docs/raw/docs/ui/ThreadList.mdx +4 -47
- package/.docs/raw/docs/ui/ToolFallback.mdx +2 -24
- package/package.json +15 -8
|
@@ -261,6 +261,247 @@ export default function Home() {
|
|
|
261
261
|
|
|
262
262
|
```
|
|
263
263
|
|
|
264
|
+
## components/assistant-ui/attachment.tsx
|
|
265
|
+
|
|
266
|
+
```tsx
|
|
267
|
+
"use client";
|
|
268
|
+
|
|
269
|
+
import { PropsWithChildren, useEffect, useState, type FC } from "react";
|
|
270
|
+
import Image from "next/image";
|
|
271
|
+
import { XIcon, PlusIcon, FileText } from "lucide-react";
|
|
272
|
+
import {
|
|
273
|
+
AttachmentPrimitive,
|
|
274
|
+
ComposerPrimitive,
|
|
275
|
+
MessagePrimitive,
|
|
276
|
+
useAssistantState,
|
|
277
|
+
useAssistantApi,
|
|
278
|
+
} from "@assistant-ui/react";
|
|
279
|
+
import { useShallow } from "zustand/shallow";
|
|
280
|
+
import {
|
|
281
|
+
Tooltip,
|
|
282
|
+
TooltipContent,
|
|
283
|
+
TooltipTrigger,
|
|
284
|
+
} from "@/components/ui/tooltip";
|
|
285
|
+
import {
|
|
286
|
+
Dialog,
|
|
287
|
+
DialogTitle,
|
|
288
|
+
DialogContent,
|
|
289
|
+
DialogTrigger,
|
|
290
|
+
} from "@/components/ui/dialog";
|
|
291
|
+
import { Avatar, AvatarImage, AvatarFallback } from "@/components/ui/avatar";
|
|
292
|
+
import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
|
|
293
|
+
import { cn } from "@/lib/utils";
|
|
294
|
+
|
|
295
|
+
const useFileSrc = (file: File | undefined) => {
|
|
296
|
+
const [src, setSrc] = useState<string | undefined>(undefined);
|
|
297
|
+
|
|
298
|
+
useEffect(() => {
|
|
299
|
+
if (!file) {
|
|
300
|
+
setSrc(undefined);
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
const objectUrl = URL.createObjectURL(file);
|
|
305
|
+
setSrc(objectUrl);
|
|
306
|
+
|
|
307
|
+
return () => {
|
|
308
|
+
URL.revokeObjectURL(objectUrl);
|
|
309
|
+
};
|
|
310
|
+
}, [file]);
|
|
311
|
+
|
|
312
|
+
return src;
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
const useAttachmentSrc = () => {
|
|
316
|
+
const { file, src } = useAssistantState(
|
|
317
|
+
useShallow(({ attachment }): { file?: File; src?: string } => {
|
|
318
|
+
if (attachment.type !== "image") return {};
|
|
319
|
+
if (attachment.file) return { file: attachment.file };
|
|
320
|
+
const src = attachment.content?.filter((c) => c.type === "image")[0]
|
|
321
|
+
?.image;
|
|
322
|
+
if (!src) return {};
|
|
323
|
+
return { src };
|
|
324
|
+
}),
|
|
325
|
+
);
|
|
326
|
+
|
|
327
|
+
return useFileSrc(file) ?? src;
|
|
328
|
+
};
|
|
329
|
+
|
|
330
|
+
type AttachmentPreviewProps = {
|
|
331
|
+
src: string;
|
|
332
|
+
};
|
|
333
|
+
|
|
334
|
+
const AttachmentPreview: FC<AttachmentPreviewProps> = ({ src }) => {
|
|
335
|
+
const [isLoaded, setIsLoaded] = useState(false);
|
|
336
|
+
return (
|
|
337
|
+
<Image
|
|
338
|
+
src={src}
|
|
339
|
+
alt="Image Preview"
|
|
340
|
+
width={1}
|
|
341
|
+
height={1}
|
|
342
|
+
className={
|
|
343
|
+
isLoaded
|
|
344
|
+
? "aui-attachment-preview-image-loaded block h-auto max-h-[80vh] w-auto max-w-full object-contain"
|
|
345
|
+
: "aui-attachment-preview-image-loading hidden"
|
|
346
|
+
}
|
|
347
|
+
onLoadingComplete={() => setIsLoaded(true)}
|
|
348
|
+
priority={false}
|
|
349
|
+
/>
|
|
350
|
+
);
|
|
351
|
+
};
|
|
352
|
+
|
|
353
|
+
const AttachmentPreviewDialog: FC<PropsWithChildren> = ({ children }) => {
|
|
354
|
+
const src = useAttachmentSrc();
|
|
355
|
+
|
|
356
|
+
if (!src) return children;
|
|
357
|
+
|
|
358
|
+
return (
|
|
359
|
+
<Dialog>
|
|
360
|
+
<DialogTrigger
|
|
361
|
+
className="aui-attachment-preview-trigger cursor-pointer transition-colors hover:bg-accent/50"
|
|
362
|
+
asChild
|
|
363
|
+
>
|
|
364
|
+
{children}
|
|
365
|
+
</DialogTrigger>
|
|
366
|
+
<DialogContent className="aui-attachment-preview-dialog-content p-2 sm:max-w-3xl [&>button]:rounded-full [&>button]:bg-foreground/60 [&>button]:p-1 [&>button]:opacity-100 [&>button]:ring-0! [&_svg]:text-background [&>button]:hover:[&_svg]:text-destructive">
|
|
367
|
+
<DialogTitle className="aui-sr-only sr-only">
|
|
368
|
+
Image Attachment Preview
|
|
369
|
+
</DialogTitle>
|
|
370
|
+
<div className="aui-attachment-preview relative mx-auto flex max-h-[80dvh] w-full items-center justify-center overflow-hidden bg-background">
|
|
371
|
+
<AttachmentPreview src={src} />
|
|
372
|
+
</div>
|
|
373
|
+
</DialogContent>
|
|
374
|
+
</Dialog>
|
|
375
|
+
);
|
|
376
|
+
};
|
|
377
|
+
|
|
378
|
+
const AttachmentThumb: FC = () => {
|
|
379
|
+
const isImage = useAssistantState(
|
|
380
|
+
({ attachment }) => attachment.type === "image",
|
|
381
|
+
);
|
|
382
|
+
const src = useAttachmentSrc();
|
|
383
|
+
|
|
384
|
+
return (
|
|
385
|
+
<Avatar className="aui-attachment-tile-avatar h-full w-full rounded-none">
|
|
386
|
+
<AvatarImage
|
|
387
|
+
src={src}
|
|
388
|
+
alt="Attachment preview"
|
|
389
|
+
className="aui-attachment-tile-image object-cover"
|
|
390
|
+
/>
|
|
391
|
+
<AvatarFallback delayMs={isImage ? 200 : 0}>
|
|
392
|
+
<FileText className="aui-attachment-tile-fallback-icon size-8 text-muted-foreground" />
|
|
393
|
+
</AvatarFallback>
|
|
394
|
+
</Avatar>
|
|
395
|
+
);
|
|
396
|
+
};
|
|
397
|
+
|
|
398
|
+
const AttachmentUI: FC = () => {
|
|
399
|
+
const api = useAssistantApi();
|
|
400
|
+
const isComposer = api.attachment.source === "composer";
|
|
401
|
+
|
|
402
|
+
const isImage = useAssistantState(
|
|
403
|
+
({ attachment }) => attachment.type === "image",
|
|
404
|
+
);
|
|
405
|
+
const typeLabel = useAssistantState(({ attachment }) => {
|
|
406
|
+
const type = attachment.type;
|
|
407
|
+
switch (type) {
|
|
408
|
+
case "image":
|
|
409
|
+
return "Image";
|
|
410
|
+
case "document":
|
|
411
|
+
return "Document";
|
|
412
|
+
case "file":
|
|
413
|
+
return "File";
|
|
414
|
+
default:
|
|
415
|
+
const _exhaustiveCheck: never = type;
|
|
416
|
+
throw new Error(`Unknown attachment type: ${_exhaustiveCheck}`);
|
|
417
|
+
}
|
|
418
|
+
});
|
|
419
|
+
|
|
420
|
+
return (
|
|
421
|
+
<Tooltip>
|
|
422
|
+
<AttachmentPrimitive.Root
|
|
423
|
+
className={cn(
|
|
424
|
+
"aui-attachment-root relative",
|
|
425
|
+
isImage &&
|
|
426
|
+
"aui-attachment-root-composer only:[&>#attachment-tile]:size-24",
|
|
427
|
+
)}
|
|
428
|
+
>
|
|
429
|
+
<AttachmentPreviewDialog>
|
|
430
|
+
<TooltipTrigger asChild>
|
|
431
|
+
<div
|
|
432
|
+
className={cn(
|
|
433
|
+
"aui-attachment-tile size-14 cursor-pointer overflow-hidden rounded-[14px] border bg-muted transition-opacity hover:opacity-75",
|
|
434
|
+
isComposer &&
|
|
435
|
+
"aui-attachment-tile-composer border-foreground/20",
|
|
436
|
+
)}
|
|
437
|
+
role="button"
|
|
438
|
+
id="attachment-tile"
|
|
439
|
+
aria-label={`${typeLabel} attachment`}
|
|
440
|
+
>
|
|
441
|
+
<AttachmentThumb />
|
|
442
|
+
</div>
|
|
443
|
+
</TooltipTrigger>
|
|
444
|
+
</AttachmentPreviewDialog>
|
|
445
|
+
{isComposer && <AttachmentRemove />}
|
|
446
|
+
</AttachmentPrimitive.Root>
|
|
447
|
+
<TooltipContent side="top">
|
|
448
|
+
<AttachmentPrimitive.Name />
|
|
449
|
+
</TooltipContent>
|
|
450
|
+
</Tooltip>
|
|
451
|
+
);
|
|
452
|
+
};
|
|
453
|
+
|
|
454
|
+
const AttachmentRemove: FC = () => {
|
|
455
|
+
return (
|
|
456
|
+
<AttachmentPrimitive.Remove asChild>
|
|
457
|
+
<TooltipIconButton
|
|
458
|
+
tooltip="Remove file"
|
|
459
|
+
className="aui-attachment-tile-remove absolute top-1.5 right-1.5 size-3.5 rounded-full bg-white text-muted-foreground opacity-100 shadow-sm hover:bg-white! [&_svg]:text-black hover:[&_svg]:text-destructive"
|
|
460
|
+
side="top"
|
|
461
|
+
>
|
|
462
|
+
<XIcon className="aui-attachment-remove-icon size-3 dark:stroke-[2.5px]" />
|
|
463
|
+
</TooltipIconButton>
|
|
464
|
+
</AttachmentPrimitive.Remove>
|
|
465
|
+
);
|
|
466
|
+
};
|
|
467
|
+
|
|
468
|
+
export const UserMessageAttachments: FC = () => {
|
|
469
|
+
return (
|
|
470
|
+
<div className="aui-user-message-attachments-end col-span-full col-start-1 row-start-1 flex w-full flex-row justify-end gap-2">
|
|
471
|
+
<MessagePrimitive.Attachments components={{ Attachment: AttachmentUI }} />
|
|
472
|
+
</div>
|
|
473
|
+
);
|
|
474
|
+
};
|
|
475
|
+
|
|
476
|
+
export const ComposerAttachments: FC = () => {
|
|
477
|
+
return (
|
|
478
|
+
<div className="aui-composer-attachments mb-2 flex w-full flex-row items-center gap-2 overflow-x-auto px-1.5 pt-0.5 pb-1 empty:hidden">
|
|
479
|
+
<ComposerPrimitive.Attachments
|
|
480
|
+
components={{ Attachment: AttachmentUI }}
|
|
481
|
+
/>
|
|
482
|
+
</div>
|
|
483
|
+
);
|
|
484
|
+
};
|
|
485
|
+
|
|
486
|
+
export const ComposerAddAttachment: FC = () => {
|
|
487
|
+
return (
|
|
488
|
+
<ComposerPrimitive.AddAttachment asChild>
|
|
489
|
+
<TooltipIconButton
|
|
490
|
+
tooltip="Add Attachment"
|
|
491
|
+
side="bottom"
|
|
492
|
+
variant="ghost"
|
|
493
|
+
size="icon"
|
|
494
|
+
className="aui-composer-add-attachment size-[34px] rounded-full p-1 font-semibold text-xs hover:bg-muted-foreground/15 dark:border-muted-foreground/15 dark:hover:bg-muted-foreground/30"
|
|
495
|
+
aria-label="Add Attachment"
|
|
496
|
+
>
|
|
497
|
+
<PlusIcon className="aui-attachment-add-icon size-5 stroke-[1.5px]" />
|
|
498
|
+
</TooltipIconButton>
|
|
499
|
+
</ComposerPrimitive.AddAttachment>
|
|
500
|
+
);
|
|
501
|
+
};
|
|
502
|
+
|
|
503
|
+
```
|
|
504
|
+
|
|
264
505
|
## components/assistant-ui/markdown-text.tsx
|
|
265
506
|
|
|
266
507
|
```tsx
|
|
@@ -269,13 +510,13 @@ export default function Home() {
|
|
|
269
510
|
import "@assistant-ui/react-markdown/styles/dot.css";
|
|
270
511
|
|
|
271
512
|
import {
|
|
272
|
-
CodeHeaderProps,
|
|
513
|
+
type CodeHeaderProps,
|
|
273
514
|
MarkdownTextPrimitive,
|
|
274
515
|
unstable_memoizeMarkdownComponents as memoizeMarkdownComponents,
|
|
275
516
|
useIsMarkdownCodeBlock,
|
|
276
517
|
} from "@assistant-ui/react-markdown";
|
|
277
518
|
import remarkGfm from "remark-gfm";
|
|
278
|
-
import { FC, memo, useState } from "react";
|
|
519
|
+
import { type FC, memo, useState } from "react";
|
|
279
520
|
import { CheckIcon, CopyIcon } from "lucide-react";
|
|
280
521
|
|
|
281
522
|
import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
|
|
@@ -301,8 +542,10 @@ const CodeHeader: FC<CodeHeaderProps> = ({ language, code }) => {
|
|
|
301
542
|
};
|
|
302
543
|
|
|
303
544
|
return (
|
|
304
|
-
<div className="flex items-center justify-between gap-4 rounded-t-lg bg-
|
|
305
|
-
<span className="lowercase [&>span]:text-xs">
|
|
545
|
+
<div className="aui-code-header-root mt-4 flex items-center justify-between gap-4 rounded-t-lg bg-muted-foreground/15 px-4 py-2 font-semibold text-foreground text-sm dark:bg-muted-foreground/20">
|
|
546
|
+
<span className="aui-code-header-language lowercase [&>span]:text-xs">
|
|
547
|
+
{language}
|
|
548
|
+
</span>
|
|
306
549
|
<TooltipIconButton tooltip="Copy" onClick={onCopy}>
|
|
307
550
|
{!isCopied && <CopyIcon />}
|
|
308
551
|
{isCopied && <CheckIcon />}
|
|
@@ -334,7 +577,7 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
334
577
|
h1: ({ className, ...props }) => (
|
|
335
578
|
<h1
|
|
336
579
|
className={cn(
|
|
337
|
-
"mb-8 scroll-m-20 text-4xl
|
|
580
|
+
"aui-md-h1 mb-8 scroll-m-20 font-extrabold text-4xl tracking-tight last:mb-0",
|
|
338
581
|
className,
|
|
339
582
|
)}
|
|
340
583
|
{...props}
|
|
@@ -343,7 +586,7 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
343
586
|
h2: ({ className, ...props }) => (
|
|
344
587
|
<h2
|
|
345
588
|
className={cn(
|
|
346
|
-
"mt-8 mb-4 scroll-m-20 text-3xl
|
|
589
|
+
"aui-md-h2 mt-8 mb-4 scroll-m-20 font-semibold text-3xl tracking-tight first:mt-0 last:mb-0",
|
|
347
590
|
className,
|
|
348
591
|
)}
|
|
349
592
|
{...props}
|
|
@@ -352,7 +595,7 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
352
595
|
h3: ({ className, ...props }) => (
|
|
353
596
|
<h3
|
|
354
597
|
className={cn(
|
|
355
|
-
"mt-6 mb-4 scroll-m-20 text-2xl
|
|
598
|
+
"aui-md-h3 mt-6 mb-4 scroll-m-20 font-semibold text-2xl tracking-tight first:mt-0 last:mb-0",
|
|
356
599
|
className,
|
|
357
600
|
)}
|
|
358
601
|
{...props}
|
|
@@ -361,7 +604,7 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
361
604
|
h4: ({ className, ...props }) => (
|
|
362
605
|
<h4
|
|
363
606
|
className={cn(
|
|
364
|
-
"mt-6 mb-4 scroll-m-20 text-xl
|
|
607
|
+
"aui-md-h4 mt-6 mb-4 scroll-m-20 font-semibold text-xl tracking-tight first:mt-0 last:mb-0",
|
|
365
608
|
className,
|
|
366
609
|
)}
|
|
367
610
|
{...props}
|
|
@@ -370,7 +613,7 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
370
613
|
h5: ({ className, ...props }) => (
|
|
371
614
|
<h5
|
|
372
615
|
className={cn(
|
|
373
|
-
"my-4 text-lg
|
|
616
|
+
"aui-md-h5 my-4 font-semibold text-lg first:mt-0 last:mb-0",
|
|
374
617
|
className,
|
|
375
618
|
)}
|
|
376
619
|
{...props}
|
|
@@ -378,20 +621,26 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
378
621
|
),
|
|
379
622
|
h6: ({ className, ...props }) => (
|
|
380
623
|
<h6
|
|
381
|
-
className={cn(
|
|
624
|
+
className={cn(
|
|
625
|
+
"aui-md-h6 my-4 font-semibold first:mt-0 last:mb-0",
|
|
626
|
+
className,
|
|
627
|
+
)}
|
|
382
628
|
{...props}
|
|
383
629
|
/>
|
|
384
630
|
),
|
|
385
631
|
p: ({ className, ...props }) => (
|
|
386
632
|
<p
|
|
387
|
-
className={cn(
|
|
633
|
+
className={cn(
|
|
634
|
+
"aui-md-p mt-5 mb-5 leading-7 first:mt-0 last:mb-0",
|
|
635
|
+
className,
|
|
636
|
+
)}
|
|
388
637
|
{...props}
|
|
389
638
|
/>
|
|
390
639
|
),
|
|
391
640
|
a: ({ className, ...props }) => (
|
|
392
641
|
<a
|
|
393
642
|
className={cn(
|
|
394
|
-
"
|
|
643
|
+
"aui-md-a font-medium text-primary underline underline-offset-4",
|
|
395
644
|
className,
|
|
396
645
|
)}
|
|
397
646
|
{...props}
|
|
@@ -399,29 +648,29 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
399
648
|
),
|
|
400
649
|
blockquote: ({ className, ...props }) => (
|
|
401
650
|
<blockquote
|
|
402
|
-
className={cn("border-l-2 pl-6 italic", className)}
|
|
651
|
+
className={cn("aui-md-blockquote border-l-2 pl-6 italic", className)}
|
|
403
652
|
{...props}
|
|
404
653
|
/>
|
|
405
654
|
),
|
|
406
655
|
ul: ({ className, ...props }) => (
|
|
407
656
|
<ul
|
|
408
|
-
className={cn("my-5 ml-6 list-disc [&>li]:mt-2", className)}
|
|
657
|
+
className={cn("aui-md-ul my-5 ml-6 list-disc [&>li]:mt-2", className)}
|
|
409
658
|
{...props}
|
|
410
659
|
/>
|
|
411
660
|
),
|
|
412
661
|
ol: ({ className, ...props }) => (
|
|
413
662
|
<ol
|
|
414
|
-
className={cn("my-5 ml-6 list-decimal [&>li]:mt-2", className)}
|
|
663
|
+
className={cn("aui-md-ol my-5 ml-6 list-decimal [&>li]:mt-2", className)}
|
|
415
664
|
{...props}
|
|
416
665
|
/>
|
|
417
666
|
),
|
|
418
667
|
hr: ({ className, ...props }) => (
|
|
419
|
-
<hr className={cn("my-5 border-b", className)} {...props} />
|
|
668
|
+
<hr className={cn("aui-md-hr my-5 border-b", className)} {...props} />
|
|
420
669
|
),
|
|
421
670
|
table: ({ className, ...props }) => (
|
|
422
671
|
<table
|
|
423
672
|
className={cn(
|
|
424
|
-
"my-5 w-full border-separate border-spacing-0 overflow-y-auto",
|
|
673
|
+
"aui-md-table my-5 w-full border-separate border-spacing-0 overflow-y-auto",
|
|
425
674
|
className,
|
|
426
675
|
)}
|
|
427
676
|
{...props}
|
|
@@ -430,7 +679,7 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
430
679
|
th: ({ className, ...props }) => (
|
|
431
680
|
<th
|
|
432
681
|
className={cn(
|
|
433
|
-
"bg-muted px-4 py-2 text-left font-bold first:rounded-tl-lg last:rounded-tr-lg [
|
|
682
|
+
"aui-md-th bg-muted px-4 py-2 text-left font-bold first:rounded-tl-lg last:rounded-tr-lg [[align=center]]:text-center [[align=right]]:text-right",
|
|
434
683
|
className,
|
|
435
684
|
)}
|
|
436
685
|
{...props}
|
|
@@ -439,7 +688,7 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
439
688
|
td: ({ className, ...props }) => (
|
|
440
689
|
<td
|
|
441
690
|
className={cn(
|
|
442
|
-
"border-b border-l px-4 py-2 text-left last:border-r [
|
|
691
|
+
"aui-md-td border-b border-l px-4 py-2 text-left last:border-r [[align=center]]:text-center [[align=right]]:text-right",
|
|
443
692
|
className,
|
|
444
693
|
)}
|
|
445
694
|
{...props}
|
|
@@ -448,7 +697,7 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
448
697
|
tr: ({ className, ...props }) => (
|
|
449
698
|
<tr
|
|
450
699
|
className={cn(
|
|
451
|
-
"m-0 border-b p-0 first:border-t [&:last-child>td:first-child]:rounded-bl-lg [&:last-child>td:last-child]:rounded-br-lg",
|
|
700
|
+
"aui-md-tr m-0 border-b p-0 first:border-t [&:last-child>td:first-child]:rounded-bl-lg [&:last-child>td:last-child]:rounded-br-lg",
|
|
452
701
|
className,
|
|
453
702
|
)}
|
|
454
703
|
{...props}
|
|
@@ -456,14 +705,14 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
456
705
|
),
|
|
457
706
|
sup: ({ className, ...props }) => (
|
|
458
707
|
<sup
|
|
459
|
-
className={cn("[&>a]:text-xs [&>a]:no-underline", className)}
|
|
708
|
+
className={cn("aui-md-sup [&>a]:text-xs [&>a]:no-underline", className)}
|
|
460
709
|
{...props}
|
|
461
710
|
/>
|
|
462
711
|
),
|
|
463
712
|
pre: ({ className, ...props }) => (
|
|
464
713
|
<pre
|
|
465
714
|
className={cn(
|
|
466
|
-
"overflow-x-auto rounded-b-lg bg-black p-4 text-white",
|
|
715
|
+
"aui-md-pre overflow-x-auto rounded-t-none! rounded-b-lg bg-black p-4 text-white",
|
|
467
716
|
className,
|
|
468
717
|
)}
|
|
469
718
|
{...props}
|
|
@@ -474,7 +723,8 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
474
723
|
return (
|
|
475
724
|
<code
|
|
476
725
|
className={cn(
|
|
477
|
-
!isCodeBlock &&
|
|
726
|
+
!isCodeBlock &&
|
|
727
|
+
"aui-md-inline-code rounded border bg-muted font-semibold",
|
|
478
728
|
className,
|
|
479
729
|
)}
|
|
480
730
|
{...props}
|
|
@@ -489,57 +739,67 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
489
739
|
## components/assistant-ui/thread.tsx
|
|
490
740
|
|
|
491
741
|
```tsx
|
|
742
|
+
import {
|
|
743
|
+
ComposerAddAttachment,
|
|
744
|
+
ComposerAttachments,
|
|
745
|
+
UserMessageAttachments,
|
|
746
|
+
} from "@/components/assistant-ui/attachment";
|
|
747
|
+
import { MarkdownText } from "@/components/assistant-ui/markdown-text";
|
|
748
|
+
import { ToolFallback } from "@/components/assistant-ui/tool-fallback";
|
|
749
|
+
import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
|
|
750
|
+
import { Button } from "@/components/ui/button";
|
|
751
|
+
import { cn } from "@/lib/utils";
|
|
492
752
|
import {
|
|
493
753
|
ActionBarPrimitive,
|
|
754
|
+
AssistantIf,
|
|
494
755
|
BranchPickerPrimitive,
|
|
495
756
|
ComposerPrimitive,
|
|
757
|
+
ErrorPrimitive,
|
|
496
758
|
MessagePrimitive,
|
|
497
759
|
ThreadPrimitive,
|
|
498
760
|
} from "@assistant-ui/react";
|
|
499
|
-
import type { FC } from "react";
|
|
500
761
|
import {
|
|
501
762
|
ArrowDownIcon,
|
|
763
|
+
ArrowUpIcon,
|
|
502
764
|
CheckIcon,
|
|
503
765
|
ChevronLeftIcon,
|
|
504
766
|
ChevronRightIcon,
|
|
505
767
|
CopyIcon,
|
|
768
|
+
DownloadIcon,
|
|
506
769
|
PencilIcon,
|
|
507
770
|
RefreshCwIcon,
|
|
508
|
-
|
|
771
|
+
SquareIcon,
|
|
509
772
|
} from "lucide-react";
|
|
510
|
-
import {
|
|
511
|
-
|
|
512
|
-
import { Button } from "@/components/ui/button";
|
|
513
|
-
import { MarkdownText } from "@/components/assistant-ui/markdown-text";
|
|
514
|
-
import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
|
|
773
|
+
import type { FC } from "react";
|
|
515
774
|
|
|
516
775
|
export const Thread: FC = () => {
|
|
517
776
|
return (
|
|
518
777
|
<ThreadPrimitive.Root
|
|
519
|
-
className="
|
|
778
|
+
className="aui-root aui-thread-root @container flex h-full flex-col bg-background"
|
|
520
779
|
style={{
|
|
521
|
-
["--thread-max-width" as string]: "
|
|
780
|
+
["--thread-max-width" as string]: "44rem",
|
|
522
781
|
}}
|
|
523
782
|
>
|
|
524
|
-
<ThreadPrimitive.Viewport
|
|
525
|
-
|
|
783
|
+
<ThreadPrimitive.Viewport
|
|
784
|
+
turnAnchor="top"
|
|
785
|
+
className="aui-thread-viewport relative flex flex-1 flex-col overflow-x-auto overflow-y-scroll scroll-smooth px-4 pt-4"
|
|
786
|
+
>
|
|
787
|
+
<AssistantIf condition={({ thread }) => thread.isEmpty}>
|
|
788
|
+
<ThreadWelcome />
|
|
789
|
+
</AssistantIf>
|
|
526
790
|
|
|
527
791
|
<ThreadPrimitive.Messages
|
|
528
792
|
components={{
|
|
529
|
-
UserMessage
|
|
530
|
-
EditComposer
|
|
531
|
-
AssistantMessage
|
|
793
|
+
UserMessage,
|
|
794
|
+
EditComposer,
|
|
795
|
+
AssistantMessage,
|
|
532
796
|
}}
|
|
533
797
|
/>
|
|
534
798
|
|
|
535
|
-
<ThreadPrimitive.
|
|
536
|
-
<div className="min-h-8 flex-grow" />
|
|
537
|
-
</ThreadPrimitive.If>
|
|
538
|
-
|
|
539
|
-
<div className="sticky bottom-0 mt-3 flex w-full max-w-[var(--thread-max-width)] flex-col items-center justify-end rounded-t-lg bg-inherit pb-4">
|
|
799
|
+
<ThreadPrimitive.ViewportFooter className="aui-thread-viewport-footer sticky bottom-0 mx-auto mt-auto flex w-full max-w-(--thread-max-width) flex-col gap-4 overflow-visible rounded-t-3xl bg-background pb-4 md:pb-6">
|
|
540
800
|
<ThreadScrollToBottom />
|
|
541
801
|
<Composer />
|
|
542
|
-
</
|
|
802
|
+
</ThreadPrimitive.ViewportFooter>
|
|
543
803
|
</ThreadPrimitive.Viewport>
|
|
544
804
|
</ThreadPrimitive.Root>
|
|
545
805
|
);
|
|
@@ -551,7 +811,7 @@ const ThreadScrollToBottom: FC = () => {
|
|
|
551
811
|
<TooltipIconButton
|
|
552
812
|
tooltip="Scroll to bottom"
|
|
553
813
|
variant="outline"
|
|
554
|
-
className="
|
|
814
|
+
className="aui-thread-scroll-to-bottom -top-12 absolute z-10 self-center rounded-full p-4 disabled:invisible dark:bg-background dark:hover:bg-accent"
|
|
555
815
|
>
|
|
556
816
|
<ArrowDownIcon />
|
|
557
817
|
</TooltipIconButton>
|
|
@@ -561,175 +821,247 @@ const ThreadScrollToBottom: FC = () => {
|
|
|
561
821
|
|
|
562
822
|
const ThreadWelcome: FC = () => {
|
|
563
823
|
return (
|
|
564
|
-
<
|
|
565
|
-
<div className="
|
|
566
|
-
<div className="flex
|
|
567
|
-
<
|
|
824
|
+
<div className="aui-thread-welcome-root mx-auto my-auto flex w-full max-w-(--thread-max-width) grow flex-col">
|
|
825
|
+
<div className="aui-thread-welcome-center flex w-full grow flex-col items-center justify-center">
|
|
826
|
+
<div className="aui-thread-welcome-message flex size-full flex-col justify-center px-4">
|
|
827
|
+
<h1 className="aui-thread-welcome-message-inner fade-in slide-in-from-bottom-1 animate-in font-semibold text-2xl duration-200">
|
|
828
|
+
Hello there!
|
|
829
|
+
</h1>
|
|
830
|
+
<p className="aui-thread-welcome-message-inner fade-in slide-in-from-bottom-1 animate-in text-muted-foreground text-xl delay-75 duration-200">
|
|
831
|
+
How can I help you today?
|
|
832
|
+
</p>
|
|
568
833
|
</div>
|
|
569
|
-
<ThreadWelcomeSuggestions />
|
|
570
834
|
</div>
|
|
571
|
-
|
|
835
|
+
<ThreadSuggestions />
|
|
836
|
+
</div>
|
|
572
837
|
);
|
|
573
838
|
};
|
|
574
839
|
|
|
575
|
-
const
|
|
840
|
+
const SUGGESTIONS = [
|
|
841
|
+
{
|
|
842
|
+
title: "What's the weather",
|
|
843
|
+
label: "in San Francisco?",
|
|
844
|
+
prompt: "What's the weather in San Francisco?",
|
|
845
|
+
},
|
|
846
|
+
{
|
|
847
|
+
title: "Explain React hooks",
|
|
848
|
+
label: "like useState and useEffect",
|
|
849
|
+
prompt: "Explain React hooks like useState and useEffect",
|
|
850
|
+
},
|
|
851
|
+
] as const;
|
|
852
|
+
|
|
853
|
+
const ThreadSuggestions: FC = () => {
|
|
576
854
|
return (
|
|
577
|
-
<div className="
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
855
|
+
<div className="aui-thread-welcome-suggestions grid w-full @md:grid-cols-2 gap-2 pb-4">
|
|
856
|
+
{SUGGESTIONS.map((suggestion, index) => (
|
|
857
|
+
<div
|
|
858
|
+
key={suggestion.prompt}
|
|
859
|
+
className="aui-thread-welcome-suggestion-display fade-in slide-in-from-bottom-2 @md:nth-[n+3]:block nth-[n+3]:hidden animate-in fill-mode-both duration-200"
|
|
860
|
+
style={{ animationDelay: `${100 + index * 50}ms` }}
|
|
861
|
+
>
|
|
862
|
+
<ThreadPrimitive.Suggestion prompt={suggestion.prompt} send asChild>
|
|
863
|
+
<Button
|
|
864
|
+
variant="ghost"
|
|
865
|
+
className="aui-thread-welcome-suggestion h-auto w-full @md:flex-col flex-wrap items-start justify-start gap-1 rounded-2xl border px-4 py-3 text-left text-sm transition-colors hover:bg-muted"
|
|
866
|
+
aria-label={suggestion.prompt}
|
|
867
|
+
>
|
|
868
|
+
<span className="aui-thread-welcome-suggestion-text-1 font-medium">
|
|
869
|
+
{suggestion.title}
|
|
870
|
+
</span>
|
|
871
|
+
<span className="aui-thread-welcome-suggestion-text-2 text-muted-foreground">
|
|
872
|
+
{suggestion.label}
|
|
873
|
+
</span>
|
|
874
|
+
</Button>
|
|
875
|
+
</ThreadPrimitive.Suggestion>
|
|
876
|
+
</div>
|
|
877
|
+
))}
|
|
598
878
|
</div>
|
|
599
879
|
);
|
|
600
880
|
};
|
|
601
881
|
|
|
602
882
|
const Composer: FC = () => {
|
|
603
883
|
return (
|
|
604
|
-
<ComposerPrimitive.Root className="
|
|
605
|
-
<ComposerPrimitive.
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
884
|
+
<ComposerPrimitive.Root className="aui-composer-root relative flex w-full flex-col">
|
|
885
|
+
<ComposerPrimitive.AttachmentDropzone className="aui-composer-attachment-dropzone flex w-full flex-col rounded-2xl border border-input bg-background px-1 pt-2 outline-none transition-shadow has-[textarea:focus-visible]:border-ring has-[textarea:focus-visible]:ring-2 has-[textarea:focus-visible]:ring-ring/20 data-[dragging=true]:border-ring data-[dragging=true]:border-dashed data-[dragging=true]:bg-accent/50">
|
|
886
|
+
<ComposerAttachments />
|
|
887
|
+
<ComposerPrimitive.Input
|
|
888
|
+
placeholder="Send a message..."
|
|
889
|
+
className="aui-composer-input mb-1 max-h-32 min-h-14 w-full resize-none bg-transparent px-4 pt-2 pb-3 text-sm outline-none placeholder:text-muted-foreground focus-visible:ring-0"
|
|
890
|
+
rows={1}
|
|
891
|
+
autoFocus
|
|
892
|
+
aria-label="Message input"
|
|
893
|
+
/>
|
|
894
|
+
<ComposerAction />
|
|
895
|
+
</ComposerPrimitive.AttachmentDropzone>
|
|
612
896
|
</ComposerPrimitive.Root>
|
|
613
897
|
);
|
|
614
898
|
};
|
|
615
899
|
|
|
616
900
|
const ComposerAction: FC = () => {
|
|
617
901
|
return (
|
|
618
|
-
|
|
619
|
-
<
|
|
902
|
+
<div className="aui-composer-action-wrapper relative mx-2 mb-2 flex items-center justify-between">
|
|
903
|
+
<ComposerAddAttachment />
|
|
904
|
+
|
|
905
|
+
<AssistantIf condition={({ thread }) => !thread.isRunning}>
|
|
620
906
|
<ComposerPrimitive.Send asChild>
|
|
621
907
|
<TooltipIconButton
|
|
622
|
-
tooltip="Send"
|
|
908
|
+
tooltip="Send message"
|
|
909
|
+
side="bottom"
|
|
910
|
+
type="submit"
|
|
623
911
|
variant="default"
|
|
624
|
-
|
|
912
|
+
size="icon"
|
|
913
|
+
className="aui-composer-send size-8 rounded-full"
|
|
914
|
+
aria-label="Send message"
|
|
625
915
|
>
|
|
626
|
-
<
|
|
916
|
+
<ArrowUpIcon className="aui-composer-send-icon size-4" />
|
|
627
917
|
</TooltipIconButton>
|
|
628
918
|
</ComposerPrimitive.Send>
|
|
629
|
-
</
|
|
630
|
-
|
|
919
|
+
</AssistantIf>
|
|
920
|
+
|
|
921
|
+
<AssistantIf condition={({ thread }) => thread.isRunning}>
|
|
631
922
|
<ComposerPrimitive.Cancel asChild>
|
|
632
|
-
<
|
|
633
|
-
|
|
923
|
+
<Button
|
|
924
|
+
type="button"
|
|
634
925
|
variant="default"
|
|
635
|
-
|
|
926
|
+
size="icon"
|
|
927
|
+
className="aui-composer-cancel size-8 rounded-full"
|
|
928
|
+
aria-label="Stop generating"
|
|
636
929
|
>
|
|
637
|
-
<
|
|
638
|
-
</
|
|
930
|
+
<SquareIcon className="aui-composer-cancel-icon size-3 fill-current" />
|
|
931
|
+
</Button>
|
|
639
932
|
</ComposerPrimitive.Cancel>
|
|
640
|
-
</
|
|
641
|
-
|
|
933
|
+
</AssistantIf>
|
|
934
|
+
</div>
|
|
642
935
|
);
|
|
643
936
|
};
|
|
644
937
|
|
|
645
|
-
const
|
|
938
|
+
const MessageError: FC = () => {
|
|
646
939
|
return (
|
|
647
|
-
<MessagePrimitive.
|
|
648
|
-
<
|
|
940
|
+
<MessagePrimitive.Error>
|
|
941
|
+
<ErrorPrimitive.Root className="aui-message-error-root mt-2 rounded-md border border-destructive bg-destructive/10 p-3 text-destructive text-sm dark:bg-destructive/5 dark:text-red-200">
|
|
942
|
+
<ErrorPrimitive.Message className="aui-message-error-message line-clamp-2" />
|
|
943
|
+
</ErrorPrimitive.Root>
|
|
944
|
+
</MessagePrimitive.Error>
|
|
945
|
+
);
|
|
946
|
+
};
|
|
649
947
|
|
|
650
|
-
|
|
651
|
-
|
|
948
|
+
const AssistantMessage: FC = () => {
|
|
949
|
+
return (
|
|
950
|
+
<MessagePrimitive.Root
|
|
951
|
+
className="aui-assistant-message-root fade-in slide-in-from-bottom-1 relative mx-auto w-full max-w-(--thread-max-width) animate-in py-3 duration-150"
|
|
952
|
+
data-role="assistant"
|
|
953
|
+
>
|
|
954
|
+
<div className="aui-assistant-message-content wrap-break-word px-2 text-foreground leading-relaxed">
|
|
955
|
+
<MessagePrimitive.Parts
|
|
956
|
+
components={{
|
|
957
|
+
Text: MarkdownText,
|
|
958
|
+
tools: { Fallback: ToolFallback },
|
|
959
|
+
}}
|
|
960
|
+
/>
|
|
961
|
+
<MessageError />
|
|
652
962
|
</div>
|
|
653
963
|
|
|
654
|
-
<
|
|
964
|
+
<div className="aui-assistant-message-footer mt-1 ml-2 flex">
|
|
965
|
+
<BranchPicker />
|
|
966
|
+
<AssistantActionBar />
|
|
967
|
+
</div>
|
|
655
968
|
</MessagePrimitive.Root>
|
|
656
969
|
);
|
|
657
970
|
};
|
|
658
971
|
|
|
659
|
-
const
|
|
972
|
+
const AssistantActionBar: FC = () => {
|
|
660
973
|
return (
|
|
661
974
|
<ActionBarPrimitive.Root
|
|
662
975
|
hideWhenRunning
|
|
663
976
|
autohide="not-last"
|
|
664
|
-
|
|
977
|
+
autohideFloat="single-branch"
|
|
978
|
+
className="aui-assistant-action-bar-root -ml-1 col-start-3 row-start-2 flex gap-1 text-muted-foreground data-floating:absolute data-floating:rounded-md data-floating:border data-floating:bg-background data-floating:p-1 data-floating:shadow-sm"
|
|
665
979
|
>
|
|
666
|
-
<ActionBarPrimitive.
|
|
667
|
-
<TooltipIconButton tooltip="
|
|
668
|
-
<
|
|
980
|
+
<ActionBarPrimitive.Copy asChild>
|
|
981
|
+
<TooltipIconButton tooltip="Copy">
|
|
982
|
+
<AssistantIf condition={({ message }) => message.isCopied}>
|
|
983
|
+
<CheckIcon />
|
|
984
|
+
</AssistantIf>
|
|
985
|
+
<AssistantIf condition={({ message }) => !message.isCopied}>
|
|
986
|
+
<CopyIcon />
|
|
987
|
+
</AssistantIf>
|
|
669
988
|
</TooltipIconButton>
|
|
670
|
-
</ActionBarPrimitive.
|
|
989
|
+
</ActionBarPrimitive.Copy>
|
|
990
|
+
<ActionBarPrimitive.ExportMarkdown asChild>
|
|
991
|
+
<TooltipIconButton tooltip="Export as Markdown">
|
|
992
|
+
<DownloadIcon />
|
|
993
|
+
</TooltipIconButton>
|
|
994
|
+
</ActionBarPrimitive.ExportMarkdown>
|
|
995
|
+
<ActionBarPrimitive.Reload asChild>
|
|
996
|
+
<TooltipIconButton tooltip="Refresh">
|
|
997
|
+
<RefreshCwIcon />
|
|
998
|
+
</TooltipIconButton>
|
|
999
|
+
</ActionBarPrimitive.Reload>
|
|
671
1000
|
</ActionBarPrimitive.Root>
|
|
672
1001
|
);
|
|
673
1002
|
};
|
|
674
1003
|
|
|
675
|
-
const
|
|
1004
|
+
const UserMessage: FC = () => {
|
|
676
1005
|
return (
|
|
677
|
-
<
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
<Button variant="ghost">Cancel</Button>
|
|
683
|
-
</ComposerPrimitive.Cancel>
|
|
684
|
-
<ComposerPrimitive.Send asChild>
|
|
685
|
-
<Button>Send</Button>
|
|
686
|
-
</ComposerPrimitive.Send>
|
|
687
|
-
</div>
|
|
688
|
-
</ComposerPrimitive.Root>
|
|
689
|
-
);
|
|
690
|
-
};
|
|
1006
|
+
<MessagePrimitive.Root
|
|
1007
|
+
className="aui-user-message-root fade-in slide-in-from-bottom-1 mx-auto grid w-full max-w-(--thread-max-width) animate-in auto-rows-auto grid-cols-[minmax(72px,1fr)_auto] content-start gap-y-2 px-2 py-3 duration-150 [&:where(>*)]:col-start-2"
|
|
1008
|
+
data-role="user"
|
|
1009
|
+
>
|
|
1010
|
+
<UserMessageAttachments />
|
|
691
1011
|
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
<
|
|
1012
|
+
<div className="aui-user-message-content-wrapper relative col-start-2 min-w-0">
|
|
1013
|
+
<div className="aui-user-message-content wrap-break-word rounded-2xl bg-muted px-4 py-2.5 text-foreground">
|
|
1014
|
+
<MessagePrimitive.Parts />
|
|
1015
|
+
</div>
|
|
1016
|
+
<div className="aui-user-action-bar-wrapper -translate-x-full -translate-y-1/2 absolute top-1/2 left-0 pr-2">
|
|
1017
|
+
<UserActionBar />
|
|
1018
|
+
</div>
|
|
697
1019
|
</div>
|
|
698
1020
|
|
|
699
|
-
<
|
|
700
|
-
|
|
701
|
-
<BranchPicker className="col-start-2 row-start-2 mr-2 -ml-2" />
|
|
1021
|
+
<BranchPicker className="aui-user-branch-picker -mr-1 col-span-full col-start-1 row-start-3 justify-end" />
|
|
702
1022
|
</MessagePrimitive.Root>
|
|
703
1023
|
);
|
|
704
1024
|
};
|
|
705
1025
|
|
|
706
|
-
const
|
|
1026
|
+
const UserActionBar: FC = () => {
|
|
707
1027
|
return (
|
|
708
1028
|
<ActionBarPrimitive.Root
|
|
709
1029
|
hideWhenRunning
|
|
710
1030
|
autohide="not-last"
|
|
711
|
-
|
|
712
|
-
className="text-muted-foreground data-[floating]:bg-background col-start-3 row-start-2 -ml-1 flex gap-1 data-[floating]:absolute data-[floating]:rounded-md data-[floating]:border data-[floating]:p-1 data-[floating]:shadow-sm"
|
|
1031
|
+
className="aui-user-action-bar-root flex flex-col items-end"
|
|
713
1032
|
>
|
|
714
|
-
<ActionBarPrimitive.
|
|
715
|
-
<TooltipIconButton tooltip="
|
|
716
|
-
<
|
|
717
|
-
<CheckIcon />
|
|
718
|
-
</MessagePrimitive.If>
|
|
719
|
-
<MessagePrimitive.If copied={false}>
|
|
720
|
-
<CopyIcon />
|
|
721
|
-
</MessagePrimitive.If>
|
|
722
|
-
</TooltipIconButton>
|
|
723
|
-
</ActionBarPrimitive.Copy>
|
|
724
|
-
<ActionBarPrimitive.Reload asChild>
|
|
725
|
-
<TooltipIconButton tooltip="Refresh">
|
|
726
|
-
<RefreshCwIcon />
|
|
1033
|
+
<ActionBarPrimitive.Edit asChild>
|
|
1034
|
+
<TooltipIconButton tooltip="Edit" className="aui-user-action-edit p-4">
|
|
1035
|
+
<PencilIcon />
|
|
727
1036
|
</TooltipIconButton>
|
|
728
|
-
</ActionBarPrimitive.
|
|
1037
|
+
</ActionBarPrimitive.Edit>
|
|
729
1038
|
</ActionBarPrimitive.Root>
|
|
730
1039
|
);
|
|
731
1040
|
};
|
|
732
1041
|
|
|
1042
|
+
const EditComposer: FC = () => {
|
|
1043
|
+
return (
|
|
1044
|
+
<MessagePrimitive.Root className="aui-edit-composer-wrapper mx-auto flex w-full max-w-(--thread-max-width) flex-col px-2 py-3">
|
|
1045
|
+
<ComposerPrimitive.Root className="aui-edit-composer-root ml-auto flex w-full max-w-[85%] flex-col rounded-2xl bg-muted">
|
|
1046
|
+
<ComposerPrimitive.Input
|
|
1047
|
+
className="aui-edit-composer-input min-h-14 w-full resize-none bg-transparent p-4 text-foreground text-sm outline-none"
|
|
1048
|
+
autoFocus
|
|
1049
|
+
/>
|
|
1050
|
+
<div className="aui-edit-composer-footer mx-3 mb-3 flex items-center gap-2 self-end">
|
|
1051
|
+
<ComposerPrimitive.Cancel asChild>
|
|
1052
|
+
<Button variant="ghost" size="sm">
|
|
1053
|
+
Cancel
|
|
1054
|
+
</Button>
|
|
1055
|
+
</ComposerPrimitive.Cancel>
|
|
1056
|
+
<ComposerPrimitive.Send asChild>
|
|
1057
|
+
<Button size="sm">Update</Button>
|
|
1058
|
+
</ComposerPrimitive.Send>
|
|
1059
|
+
</div>
|
|
1060
|
+
</ComposerPrimitive.Root>
|
|
1061
|
+
</MessagePrimitive.Root>
|
|
1062
|
+
);
|
|
1063
|
+
};
|
|
1064
|
+
|
|
733
1065
|
const BranchPicker: FC<BranchPickerPrimitive.Root.Props> = ({
|
|
734
1066
|
className,
|
|
735
1067
|
...rest
|
|
@@ -738,7 +1070,7 @@ const BranchPicker: FC<BranchPickerPrimitive.Root.Props> = ({
|
|
|
738
1070
|
<BranchPickerPrimitive.Root
|
|
739
1071
|
hideWhenSingleBranch
|
|
740
1072
|
className={cn(
|
|
741
|
-
"
|
|
1073
|
+
"aui-branch-picker-root -ml-2 mr-2 inline-flex items-center text-muted-foreground text-xs",
|
|
742
1074
|
className,
|
|
743
1075
|
)}
|
|
744
1076
|
{...rest}
|
|
@@ -748,7 +1080,7 @@ const BranchPicker: FC<BranchPickerPrimitive.Root.Props> = ({
|
|
|
748
1080
|
<ChevronLeftIcon />
|
|
749
1081
|
</TooltipIconButton>
|
|
750
1082
|
</BranchPickerPrimitive.Previous>
|
|
751
|
-
<span className="font-medium">
|
|
1083
|
+
<span className="aui-branch-picker-state font-medium">
|
|
752
1084
|
<BranchPickerPrimitive.Number /> / <BranchPickerPrimitive.Count />
|
|
753
1085
|
</span>
|
|
754
1086
|
<BranchPickerPrimitive.Next asChild>
|
|
@@ -760,17 +1092,102 @@ const BranchPicker: FC<BranchPickerPrimitive.Root.Props> = ({
|
|
|
760
1092
|
);
|
|
761
1093
|
};
|
|
762
1094
|
|
|
763
|
-
|
|
1095
|
+
```
|
|
1096
|
+
|
|
1097
|
+
## components/assistant-ui/tool-fallback.tsx
|
|
1098
|
+
|
|
1099
|
+
```tsx
|
|
1100
|
+
import type { ToolCallMessagePartComponent } from "@assistant-ui/react";
|
|
1101
|
+
import {
|
|
1102
|
+
CheckIcon,
|
|
1103
|
+
ChevronDownIcon,
|
|
1104
|
+
ChevronUpIcon,
|
|
1105
|
+
XCircleIcon,
|
|
1106
|
+
} from "lucide-react";
|
|
1107
|
+
import { useState } from "react";
|
|
1108
|
+
import { Button } from "@/components/ui/button";
|
|
1109
|
+
import { cn } from "@/lib/utils";
|
|
1110
|
+
|
|
1111
|
+
export const ToolFallback: ToolCallMessagePartComponent = ({
|
|
1112
|
+
toolName,
|
|
1113
|
+
argsText,
|
|
1114
|
+
result,
|
|
1115
|
+
status,
|
|
1116
|
+
}) => {
|
|
1117
|
+
const [isCollapsed, setIsCollapsed] = useState(true);
|
|
1118
|
+
|
|
1119
|
+
const isCancelled =
|
|
1120
|
+
status?.type === "incomplete" && status.reason === "cancelled";
|
|
1121
|
+
const cancelledReason =
|
|
1122
|
+
isCancelled && status.error
|
|
1123
|
+
? typeof status.error === "string"
|
|
1124
|
+
? status.error
|
|
1125
|
+
: JSON.stringify(status.error)
|
|
1126
|
+
: null;
|
|
1127
|
+
|
|
764
1128
|
return (
|
|
765
|
-
<
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
height="16"
|
|
1129
|
+
<div
|
|
1130
|
+
className={cn(
|
|
1131
|
+
"aui-tool-fallback-root mb-4 flex w-full flex-col gap-3 rounded-lg border py-3",
|
|
1132
|
+
isCancelled && "border-muted-foreground/30 bg-muted/30",
|
|
1133
|
+
)}
|
|
771
1134
|
>
|
|
772
|
-
<
|
|
773
|
-
|
|
1135
|
+
<div className="aui-tool-fallback-header flex items-center gap-2 px-4">
|
|
1136
|
+
{isCancelled ? (
|
|
1137
|
+
<XCircleIcon className="aui-tool-fallback-icon size-4 text-muted-foreground" />
|
|
1138
|
+
) : (
|
|
1139
|
+
<CheckIcon className="aui-tool-fallback-icon size-4" />
|
|
1140
|
+
)}
|
|
1141
|
+
<p
|
|
1142
|
+
className={cn(
|
|
1143
|
+
"aui-tool-fallback-title grow",
|
|
1144
|
+
isCancelled && "text-muted-foreground line-through",
|
|
1145
|
+
)}
|
|
1146
|
+
>
|
|
1147
|
+
{isCancelled ? "Cancelled tool: " : "Used tool: "}
|
|
1148
|
+
<b>{toolName}</b>
|
|
1149
|
+
</p>
|
|
1150
|
+
<Button onClick={() => setIsCollapsed(!isCollapsed)}>
|
|
1151
|
+
{isCollapsed ? <ChevronUpIcon /> : <ChevronDownIcon />}
|
|
1152
|
+
</Button>
|
|
1153
|
+
</div>
|
|
1154
|
+
{!isCollapsed && (
|
|
1155
|
+
<div className="aui-tool-fallback-content flex flex-col gap-2 border-t pt-2">
|
|
1156
|
+
{cancelledReason && (
|
|
1157
|
+
<div className="aui-tool-fallback-cancelled-root px-4">
|
|
1158
|
+
<p className="aui-tool-fallback-cancelled-header font-semibold text-muted-foreground">
|
|
1159
|
+
Cancelled reason:
|
|
1160
|
+
</p>
|
|
1161
|
+
<p className="aui-tool-fallback-cancelled-reason text-muted-foreground">
|
|
1162
|
+
{cancelledReason}
|
|
1163
|
+
</p>
|
|
1164
|
+
</div>
|
|
1165
|
+
)}
|
|
1166
|
+
<div
|
|
1167
|
+
className={cn(
|
|
1168
|
+
"aui-tool-fallback-args-root px-4",
|
|
1169
|
+
isCancelled && "opacity-60",
|
|
1170
|
+
)}
|
|
1171
|
+
>
|
|
1172
|
+
<pre className="aui-tool-fallback-args-value whitespace-pre-wrap">
|
|
1173
|
+
{argsText}
|
|
1174
|
+
</pre>
|
|
1175
|
+
</div>
|
|
1176
|
+
{!isCancelled && result !== undefined && (
|
|
1177
|
+
<div className="aui-tool-fallback-result-root border-t border-dashed px-4 pt-2">
|
|
1178
|
+
<p className="aui-tool-fallback-result-header font-semibold">
|
|
1179
|
+
Result:
|
|
1180
|
+
</p>
|
|
1181
|
+
<pre className="aui-tool-fallback-result-content whitespace-pre-wrap">
|
|
1182
|
+
{typeof result === "string"
|
|
1183
|
+
? result
|
|
1184
|
+
: JSON.stringify(result, null, 2)}
|
|
1185
|
+
</pre>
|
|
1186
|
+
</div>
|
|
1187
|
+
)}
|
|
1188
|
+
</div>
|
|
1189
|
+
)}
|
|
1190
|
+
</div>
|
|
774
1191
|
);
|
|
775
1192
|
};
|
|
776
1193
|
|
|
@@ -781,7 +1198,7 @@ const CircleStopIcon = () => {
|
|
|
781
1198
|
```tsx
|
|
782
1199
|
"use client";
|
|
783
1200
|
|
|
784
|
-
import {
|
|
1201
|
+
import { ComponentPropsWithRef, forwardRef } from "react";
|
|
785
1202
|
import { Slottable } from "@radix-ui/react-slot";
|
|
786
1203
|
|
|
787
1204
|
import {
|
|
@@ -792,7 +1209,7 @@ import {
|
|
|
792
1209
|
import { Button } from "@/components/ui/button";
|
|
793
1210
|
import { cn } from "@/lib/utils";
|
|
794
1211
|
|
|
795
|
-
export type TooltipIconButtonProps =
|
|
1212
|
+
export type TooltipIconButtonProps = ComponentPropsWithRef<typeof Button> & {
|
|
796
1213
|
tooltip: string;
|
|
797
1214
|
side?: "top" | "bottom" | "left" | "right";
|
|
798
1215
|
};
|
|
@@ -808,11 +1225,11 @@ export const TooltipIconButton = forwardRef<
|
|
|
808
1225
|
variant="ghost"
|
|
809
1226
|
size="icon"
|
|
810
1227
|
{...rest}
|
|
811
|
-
className={cn("size-6 p-1", className)}
|
|
1228
|
+
className={cn("aui-button-icon size-6 p-1", className)}
|
|
812
1229
|
ref={ref}
|
|
813
1230
|
>
|
|
814
1231
|
<Slottable>{children}</Slottable>
|
|
815
|
-
<span className="sr-only">{tooltip}</span>
|
|
1232
|
+
<span className="aui-sr-only sr-only">{tooltip}</span>
|
|
816
1233
|
</Button>
|
|
817
1234
|
</TooltipTrigger>
|
|
818
1235
|
<TooltipContent side={side}>{tooltip}</TooltipContent>
|
|
@@ -824,6 +1241,62 @@ TooltipIconButton.displayName = "TooltipIconButton";
|
|
|
824
1241
|
|
|
825
1242
|
```
|
|
826
1243
|
|
|
1244
|
+
## components/ui/avatar.tsx
|
|
1245
|
+
|
|
1246
|
+
```tsx
|
|
1247
|
+
"use client";
|
|
1248
|
+
|
|
1249
|
+
import * as React from "react";
|
|
1250
|
+
import * as AvatarPrimitive from "@radix-ui/react-avatar";
|
|
1251
|
+
|
|
1252
|
+
import { cn } from "@/lib/utils";
|
|
1253
|
+
|
|
1254
|
+
const Avatar = React.forwardRef<
|
|
1255
|
+
React.ElementRef<typeof AvatarPrimitive.Root>,
|
|
1256
|
+
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>
|
|
1257
|
+
>(({ className, ...props }, ref) => (
|
|
1258
|
+
<AvatarPrimitive.Root
|
|
1259
|
+
ref={ref}
|
|
1260
|
+
className={cn(
|
|
1261
|
+
"relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full",
|
|
1262
|
+
className,
|
|
1263
|
+
)}
|
|
1264
|
+
{...props}
|
|
1265
|
+
/>
|
|
1266
|
+
));
|
|
1267
|
+
Avatar.displayName = AvatarPrimitive.Root.displayName;
|
|
1268
|
+
|
|
1269
|
+
const AvatarImage = React.forwardRef<
|
|
1270
|
+
React.ElementRef<typeof AvatarPrimitive.Image>,
|
|
1271
|
+
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>
|
|
1272
|
+
>(({ className, ...props }, ref) => (
|
|
1273
|
+
<AvatarPrimitive.Image
|
|
1274
|
+
ref={ref}
|
|
1275
|
+
className={cn("aspect-square h-full w-full", className)}
|
|
1276
|
+
{...props}
|
|
1277
|
+
/>
|
|
1278
|
+
));
|
|
1279
|
+
AvatarImage.displayName = AvatarPrimitive.Image.displayName;
|
|
1280
|
+
|
|
1281
|
+
const AvatarFallback = React.forwardRef<
|
|
1282
|
+
React.ElementRef<typeof AvatarPrimitive.Fallback>,
|
|
1283
|
+
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>
|
|
1284
|
+
>(({ className, ...props }, ref) => (
|
|
1285
|
+
<AvatarPrimitive.Fallback
|
|
1286
|
+
ref={ref}
|
|
1287
|
+
className={cn(
|
|
1288
|
+
"flex h-full w-full items-center justify-center rounded-full bg-muted",
|
|
1289
|
+
className,
|
|
1290
|
+
)}
|
|
1291
|
+
{...props}
|
|
1292
|
+
/>
|
|
1293
|
+
));
|
|
1294
|
+
AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
|
|
1295
|
+
|
|
1296
|
+
export { Avatar, AvatarImage, AvatarFallback };
|
|
1297
|
+
|
|
1298
|
+
```
|
|
1299
|
+
|
|
827
1300
|
## components/ui/button.tsx
|
|
828
1301
|
|
|
829
1302
|
```tsx
|
|
@@ -836,7 +1309,7 @@ import { cva, type VariantProps } from "class-variance-authority";
|
|
|
836
1309
|
import { cn } from "@/lib/utils";
|
|
837
1310
|
|
|
838
1311
|
const buttonVariants = cva(
|
|
839
|
-
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm
|
|
1312
|
+
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md font-medium text-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
|
840
1313
|
{
|
|
841
1314
|
variants: {
|
|
842
1315
|
variant: {
|
|
@@ -889,6 +1362,147 @@ export { Button, buttonVariants };
|
|
|
889
1362
|
|
|
890
1363
|
```
|
|
891
1364
|
|
|
1365
|
+
## components/ui/dialog.tsx
|
|
1366
|
+
|
|
1367
|
+
```tsx
|
|
1368
|
+
"use client";
|
|
1369
|
+
|
|
1370
|
+
import * as React from "react";
|
|
1371
|
+
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
|
1372
|
+
import { XIcon } from "lucide-react";
|
|
1373
|
+
|
|
1374
|
+
import { cn } from "@/lib/utils";
|
|
1375
|
+
|
|
1376
|
+
function Dialog({
|
|
1377
|
+
...props
|
|
1378
|
+
}: React.ComponentProps<typeof DialogPrimitive.Root>) {
|
|
1379
|
+
return <DialogPrimitive.Root data-slot="dialog" {...props} />;
|
|
1380
|
+
}
|
|
1381
|
+
|
|
1382
|
+
function DialogTrigger({
|
|
1383
|
+
...props
|
|
1384
|
+
}: React.ComponentProps<typeof DialogPrimitive.Trigger>) {
|
|
1385
|
+
return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} />;
|
|
1386
|
+
}
|
|
1387
|
+
|
|
1388
|
+
function DialogPortal({
|
|
1389
|
+
...props
|
|
1390
|
+
}: React.ComponentProps<typeof DialogPrimitive.Portal>) {
|
|
1391
|
+
return <DialogPrimitive.Portal data-slot="dialog-portal" {...props} />;
|
|
1392
|
+
}
|
|
1393
|
+
|
|
1394
|
+
function DialogClose({
|
|
1395
|
+
...props
|
|
1396
|
+
}: React.ComponentProps<typeof DialogPrimitive.Close>) {
|
|
1397
|
+
return <DialogPrimitive.Close data-slot="dialog-close" {...props} />;
|
|
1398
|
+
}
|
|
1399
|
+
|
|
1400
|
+
function DialogOverlay({
|
|
1401
|
+
className,
|
|
1402
|
+
...props
|
|
1403
|
+
}: React.ComponentProps<typeof DialogPrimitive.Overlay>) {
|
|
1404
|
+
return (
|
|
1405
|
+
<DialogPrimitive.Overlay
|
|
1406
|
+
data-slot="dialog-overlay"
|
|
1407
|
+
className={cn(
|
|
1408
|
+
"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/80 data-[state=closed]:animate-out data-[state=open]:animate-in",
|
|
1409
|
+
className,
|
|
1410
|
+
)}
|
|
1411
|
+
{...props}
|
|
1412
|
+
/>
|
|
1413
|
+
);
|
|
1414
|
+
}
|
|
1415
|
+
|
|
1416
|
+
function DialogContent({
|
|
1417
|
+
className,
|
|
1418
|
+
children,
|
|
1419
|
+
...props
|
|
1420
|
+
}: React.ComponentProps<typeof DialogPrimitive.Content>) {
|
|
1421
|
+
return (
|
|
1422
|
+
<DialogPortal data-slot="dialog-portal">
|
|
1423
|
+
<DialogOverlay />
|
|
1424
|
+
<DialogPrimitive.Content
|
|
1425
|
+
data-slot="dialog-content"
|
|
1426
|
+
className={cn(
|
|
1427
|
+
"data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border bg-background p-6 shadow-lg duration-200 data-[state=closed]:animate-out data-[state=open]:animate-in sm:max-w-lg",
|
|
1428
|
+
className,
|
|
1429
|
+
)}
|
|
1430
|
+
{...props}
|
|
1431
|
+
>
|
|
1432
|
+
{children}
|
|
1433
|
+
<DialogPrimitive.Close className="absolute top-4 right-4 rounded-xs opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0">
|
|
1434
|
+
<XIcon />
|
|
1435
|
+
<span className="sr-only">Close</span>
|
|
1436
|
+
</DialogPrimitive.Close>
|
|
1437
|
+
</DialogPrimitive.Content>
|
|
1438
|
+
</DialogPortal>
|
|
1439
|
+
);
|
|
1440
|
+
}
|
|
1441
|
+
|
|
1442
|
+
function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
|
|
1443
|
+
return (
|
|
1444
|
+
<div
|
|
1445
|
+
data-slot="dialog-header"
|
|
1446
|
+
className={cn("flex flex-col gap-2 text-center sm:text-left", className)}
|
|
1447
|
+
{...props}
|
|
1448
|
+
/>
|
|
1449
|
+
);
|
|
1450
|
+
}
|
|
1451
|
+
|
|
1452
|
+
function DialogFooter({ className, ...props }: React.ComponentProps<"div">) {
|
|
1453
|
+
return (
|
|
1454
|
+
<div
|
|
1455
|
+
data-slot="dialog-footer"
|
|
1456
|
+
className={cn(
|
|
1457
|
+
"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end",
|
|
1458
|
+
className,
|
|
1459
|
+
)}
|
|
1460
|
+
{...props}
|
|
1461
|
+
/>
|
|
1462
|
+
);
|
|
1463
|
+
}
|
|
1464
|
+
|
|
1465
|
+
function DialogTitle({
|
|
1466
|
+
className,
|
|
1467
|
+
...props
|
|
1468
|
+
}: React.ComponentProps<typeof DialogPrimitive.Title>) {
|
|
1469
|
+
return (
|
|
1470
|
+
<DialogPrimitive.Title
|
|
1471
|
+
data-slot="dialog-title"
|
|
1472
|
+
className={cn("font-semibold text-lg leading-none", className)}
|
|
1473
|
+
{...props}
|
|
1474
|
+
/>
|
|
1475
|
+
);
|
|
1476
|
+
}
|
|
1477
|
+
|
|
1478
|
+
function DialogDescription({
|
|
1479
|
+
className,
|
|
1480
|
+
...props
|
|
1481
|
+
}: React.ComponentProps<typeof DialogPrimitive.Description>) {
|
|
1482
|
+
return (
|
|
1483
|
+
<DialogPrimitive.Description
|
|
1484
|
+
data-slot="dialog-description"
|
|
1485
|
+
className={cn("text-muted-foreground text-sm", className)}
|
|
1486
|
+
{...props}
|
|
1487
|
+
/>
|
|
1488
|
+
);
|
|
1489
|
+
}
|
|
1490
|
+
|
|
1491
|
+
export {
|
|
1492
|
+
Dialog,
|
|
1493
|
+
DialogClose,
|
|
1494
|
+
DialogContent,
|
|
1495
|
+
DialogDescription,
|
|
1496
|
+
DialogFooter,
|
|
1497
|
+
DialogHeader,
|
|
1498
|
+
DialogOverlay,
|
|
1499
|
+
DialogPortal,
|
|
1500
|
+
DialogTitle,
|
|
1501
|
+
DialogTrigger,
|
|
1502
|
+
};
|
|
1503
|
+
|
|
1504
|
+
```
|
|
1505
|
+
|
|
892
1506
|
## components/ui/tooltip.tsx
|
|
893
1507
|
|
|
894
1508
|
```tsx
|
|
@@ -940,13 +1554,13 @@ function TooltipContent({
|
|
|
940
1554
|
data-slot="tooltip-content"
|
|
941
1555
|
sideOffset={sideOffset}
|
|
942
1556
|
className={cn(
|
|
943
|
-
"
|
|
1557
|
+
"fade-in-0 zoom-in-95 data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-[--radix-tooltip-content-transform-origin] animate-in text-balance rounded-md bg-primary px-3 py-1.5 text-primary-foreground text-xs data-[state=closed]:animate-out",
|
|
944
1558
|
className,
|
|
945
1559
|
)}
|
|
946
1560
|
{...props}
|
|
947
1561
|
>
|
|
948
1562
|
{children}
|
|
949
|
-
<TooltipPrimitive.Arrow className="
|
|
1563
|
+
<TooltipPrimitive.Arrow className="z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px] bg-primary fill-primary" />
|
|
950
1564
|
</TooltipPrimitive.Content>
|
|
951
1565
|
</TooltipPrimitive.Portal>
|
|
952
1566
|
);
|
|
@@ -991,24 +1605,26 @@ export default nextConfig;
|
|
|
991
1605
|
"scripts": {
|
|
992
1606
|
"dev": "next dev --turbo",
|
|
993
1607
|
"build": "next build",
|
|
994
|
-
"start": "next start"
|
|
995
|
-
"lint": "eslint ."
|
|
1608
|
+
"start": "next start"
|
|
996
1609
|
},
|
|
997
1610
|
"dependencies": {
|
|
998
|
-
"@ai-sdk/openai": "^2.0.
|
|
1611
|
+
"@ai-sdk/openai": "^2.0.77",
|
|
999
1612
|
"@assistant-ui/react": "workspace:*",
|
|
1000
1613
|
"@assistant-ui/react-markdown": "workspace:*",
|
|
1614
|
+
"@radix-ui/react-avatar": "^1.1.11",
|
|
1615
|
+
"@radix-ui/react-dialog": "^1.1.15",
|
|
1001
1616
|
"@radix-ui/react-slot": "^1.2.4",
|
|
1002
1617
|
"@radix-ui/react-tooltip": "^1.2.8",
|
|
1003
1618
|
"class-variance-authority": "^0.7.1",
|
|
1004
1619
|
"clsx": "^2.1.1",
|
|
1005
|
-
"lucide-react": "^0.
|
|
1006
|
-
"next": "16.0.
|
|
1007
|
-
"react": "19.2.
|
|
1008
|
-
"react-dom": "19.2.
|
|
1620
|
+
"lucide-react": "^0.556.0",
|
|
1621
|
+
"next": "16.0.7",
|
|
1622
|
+
"react": "19.2.1",
|
|
1623
|
+
"react-dom": "19.2.1",
|
|
1009
1624
|
"remark-gfm": "^4.0.1",
|
|
1010
1625
|
"tailwind-merge": "^3.4.0",
|
|
1011
|
-
"tw-animate-css": "^1.4.0"
|
|
1626
|
+
"tw-animate-css": "^1.4.0",
|
|
1627
|
+
"zustand": "^5.0.9"
|
|
1012
1628
|
},
|
|
1013
1629
|
"devDependencies": {
|
|
1014
1630
|
"@assistant-ui/x-buildutils": "workspace:*",
|