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