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