@assistant-ui/mcp-docs-server 0.1.14 → 0.1.15
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 +554 -0
- package/.docs/organized/code-examples/with-ag-ui.md +582 -32
- package/.docs/organized/code-examples/with-ai-sdk-v5.md +549 -47
- package/.docs/organized/code-examples/with-assistant-transport.md +547 -46
- package/.docs/organized/code-examples/with-cloud.md +634 -39
- package/.docs/organized/code-examples/with-external-store.md +581 -31
- package/.docs/organized/code-examples/with-ffmpeg.md +581 -47
- package/.docs/organized/code-examples/with-langgraph.md +633 -50
- package/.docs/organized/code-examples/with-parent-id-grouping.md +581 -31
- package/.docs/organized/code-examples/with-react-hook-form.md +582 -70
- package/.docs/raw/blog/2024-07-29-hello/index.mdx +0 -1
- package/.docs/raw/docs/cli.mdx +396 -0
- package/.docs/raw/docs/getting-started.mdx +31 -37
- package/.docs/raw/docs/runtimes/assistant-transport.mdx +891 -0
- package/.docs/raw/docs/runtimes/langgraph/index.mdx +1 -1
- package/package.json +13 -5
|
@@ -261,6 +261,247 @@ export default function Home() {
|
|
|
261
261
|
|
|
262
262
|
```
|
|
263
263
|
|
|
264
|
+
## components/assistant-ui/attachment.tsx
|
|
265
|
+
|
|
266
|
+
```tsx
|
|
267
|
+
"use client";
|
|
268
|
+
|
|
269
|
+
import { PropsWithChildren, useEffect, useState, type FC } from "react";
|
|
270
|
+
import Image from "next/image";
|
|
271
|
+
import { XIcon, PlusIcon, FileText } from "lucide-react";
|
|
272
|
+
import {
|
|
273
|
+
AttachmentPrimitive,
|
|
274
|
+
ComposerPrimitive,
|
|
275
|
+
MessagePrimitive,
|
|
276
|
+
useAssistantState,
|
|
277
|
+
useAssistantApi,
|
|
278
|
+
} from "@assistant-ui/react";
|
|
279
|
+
import { useShallow } from "zustand/shallow";
|
|
280
|
+
import {
|
|
281
|
+
Tooltip,
|
|
282
|
+
TooltipContent,
|
|
283
|
+
TooltipTrigger,
|
|
284
|
+
} from "@/components/ui/tooltip";
|
|
285
|
+
import {
|
|
286
|
+
Dialog,
|
|
287
|
+
DialogTitle,
|
|
288
|
+
DialogContent,
|
|
289
|
+
DialogTrigger,
|
|
290
|
+
} from "@/components/ui/dialog";
|
|
291
|
+
import { Avatar, AvatarImage, AvatarFallback } from "@/components/ui/avatar";
|
|
292
|
+
import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
|
|
293
|
+
import { cn } from "@/lib/utils";
|
|
294
|
+
|
|
295
|
+
const useFileSrc = (file: File | undefined) => {
|
|
296
|
+
const [src, setSrc] = useState<string | undefined>(undefined);
|
|
297
|
+
|
|
298
|
+
useEffect(() => {
|
|
299
|
+
if (!file) {
|
|
300
|
+
setSrc(undefined);
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
const objectUrl = URL.createObjectURL(file);
|
|
305
|
+
setSrc(objectUrl);
|
|
306
|
+
|
|
307
|
+
return () => {
|
|
308
|
+
URL.revokeObjectURL(objectUrl);
|
|
309
|
+
};
|
|
310
|
+
}, [file]);
|
|
311
|
+
|
|
312
|
+
return src;
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
const useAttachmentSrc = () => {
|
|
316
|
+
const { file, src } = useAssistantState(
|
|
317
|
+
useShallow(({ attachment }): { file?: File; src?: string } => {
|
|
318
|
+
if (attachment.type !== "image") return {};
|
|
319
|
+
if (attachment.file) return { file: attachment.file };
|
|
320
|
+
const src = attachment.content?.filter((c) => c.type === "image")[0]
|
|
321
|
+
?.image;
|
|
322
|
+
if (!src) return {};
|
|
323
|
+
return { src };
|
|
324
|
+
}),
|
|
325
|
+
);
|
|
326
|
+
|
|
327
|
+
return useFileSrc(file) ?? src;
|
|
328
|
+
};
|
|
329
|
+
|
|
330
|
+
type AttachmentPreviewProps = {
|
|
331
|
+
src: string;
|
|
332
|
+
};
|
|
333
|
+
|
|
334
|
+
const AttachmentPreview: FC<AttachmentPreviewProps> = ({ src }) => {
|
|
335
|
+
const [isLoaded, setIsLoaded] = useState(false);
|
|
336
|
+
return (
|
|
337
|
+
<Image
|
|
338
|
+
src={src}
|
|
339
|
+
alt="Image Preview"
|
|
340
|
+
width={1}
|
|
341
|
+
height={1}
|
|
342
|
+
className={
|
|
343
|
+
isLoaded
|
|
344
|
+
? "aui-attachment-preview-image-loaded block h-auto max-h-[80vh] w-auto max-w-full object-contain"
|
|
345
|
+
: "aui-attachment-preview-image-loading hidden"
|
|
346
|
+
}
|
|
347
|
+
onLoadingComplete={() => setIsLoaded(true)}
|
|
348
|
+
priority={false}
|
|
349
|
+
/>
|
|
350
|
+
);
|
|
351
|
+
};
|
|
352
|
+
|
|
353
|
+
const AttachmentPreviewDialog: FC<PropsWithChildren> = ({ children }) => {
|
|
354
|
+
const src = useAttachmentSrc();
|
|
355
|
+
|
|
356
|
+
if (!src) return children;
|
|
357
|
+
|
|
358
|
+
return (
|
|
359
|
+
<Dialog>
|
|
360
|
+
<DialogTrigger
|
|
361
|
+
className="aui-attachment-preview-trigger hover:bg-accent/50 cursor-pointer transition-colors"
|
|
362
|
+
asChild
|
|
363
|
+
>
|
|
364
|
+
{children}
|
|
365
|
+
</DialogTrigger>
|
|
366
|
+
<DialogContent className="aui-attachment-preview-dialog-content [&_svg]:text-background [&>button]:bg-foreground/60 [&>button]:hover:[&_svg]:text-destructive p-2 sm:max-w-3xl [&>button]:rounded-full [&>button]:p-1 [&>button]:opacity-100 [&>button]:!ring-0">
|
|
367
|
+
<DialogTitle className="aui-sr-only sr-only">
|
|
368
|
+
Image Attachment Preview
|
|
369
|
+
</DialogTitle>
|
|
370
|
+
<div className="aui-attachment-preview bg-background relative mx-auto flex max-h-[80dvh] w-full items-center justify-center overflow-hidden">
|
|
371
|
+
<AttachmentPreview src={src} />
|
|
372
|
+
</div>
|
|
373
|
+
</DialogContent>
|
|
374
|
+
</Dialog>
|
|
375
|
+
);
|
|
376
|
+
};
|
|
377
|
+
|
|
378
|
+
const AttachmentThumb: FC = () => {
|
|
379
|
+
const isImage = useAssistantState(
|
|
380
|
+
({ attachment }) => attachment.type === "image",
|
|
381
|
+
);
|
|
382
|
+
const src = useAttachmentSrc();
|
|
383
|
+
|
|
384
|
+
return (
|
|
385
|
+
<Avatar className="aui-attachment-tile-avatar h-full w-full rounded-none">
|
|
386
|
+
<AvatarImage
|
|
387
|
+
src={src}
|
|
388
|
+
alt="Attachment preview"
|
|
389
|
+
className="aui-attachment-tile-image object-cover"
|
|
390
|
+
/>
|
|
391
|
+
<AvatarFallback delayMs={isImage ? 200 : 0}>
|
|
392
|
+
<FileText className="aui-attachment-tile-fallback-icon text-muted-foreground size-8" />
|
|
393
|
+
</AvatarFallback>
|
|
394
|
+
</Avatar>
|
|
395
|
+
);
|
|
396
|
+
};
|
|
397
|
+
|
|
398
|
+
const AttachmentUI: FC = () => {
|
|
399
|
+
const api = useAssistantApi();
|
|
400
|
+
const isComposer = api.attachment.source === "composer";
|
|
401
|
+
|
|
402
|
+
const isImage = useAssistantState(
|
|
403
|
+
({ attachment }) => attachment.type === "image",
|
|
404
|
+
);
|
|
405
|
+
const typeLabel = useAssistantState(({ attachment }) => {
|
|
406
|
+
const type = attachment.type;
|
|
407
|
+
switch (type) {
|
|
408
|
+
case "image":
|
|
409
|
+
return "Image";
|
|
410
|
+
case "document":
|
|
411
|
+
return "Document";
|
|
412
|
+
case "file":
|
|
413
|
+
return "File";
|
|
414
|
+
default:
|
|
415
|
+
const _exhaustiveCheck: never = type;
|
|
416
|
+
throw new Error(`Unknown attachment type: ${_exhaustiveCheck}`);
|
|
417
|
+
}
|
|
418
|
+
});
|
|
419
|
+
|
|
420
|
+
return (
|
|
421
|
+
<Tooltip>
|
|
422
|
+
<AttachmentPrimitive.Root
|
|
423
|
+
className={cn(
|
|
424
|
+
"aui-attachment-root relative",
|
|
425
|
+
isImage &&
|
|
426
|
+
"aui-attachment-root-composer only:[&>#attachment-tile]:size-24",
|
|
427
|
+
)}
|
|
428
|
+
>
|
|
429
|
+
<AttachmentPreviewDialog>
|
|
430
|
+
<TooltipTrigger asChild>
|
|
431
|
+
<div
|
|
432
|
+
className={cn(
|
|
433
|
+
"aui-attachment-tile bg-muted size-14 cursor-pointer overflow-hidden rounded-[14px] border transition-opacity hover:opacity-75",
|
|
434
|
+
isComposer &&
|
|
435
|
+
"aui-attachment-tile-composer border-foreground/20",
|
|
436
|
+
)}
|
|
437
|
+
role="button"
|
|
438
|
+
id="attachment-tile"
|
|
439
|
+
aria-label={`${typeLabel} attachment`}
|
|
440
|
+
>
|
|
441
|
+
<AttachmentThumb />
|
|
442
|
+
</div>
|
|
443
|
+
</TooltipTrigger>
|
|
444
|
+
</AttachmentPreviewDialog>
|
|
445
|
+
{isComposer && <AttachmentRemove />}
|
|
446
|
+
</AttachmentPrimitive.Root>
|
|
447
|
+
<TooltipContent side="top">
|
|
448
|
+
<AttachmentPrimitive.Name />
|
|
449
|
+
</TooltipContent>
|
|
450
|
+
</Tooltip>
|
|
451
|
+
);
|
|
452
|
+
};
|
|
453
|
+
|
|
454
|
+
const AttachmentRemove: FC = () => {
|
|
455
|
+
return (
|
|
456
|
+
<AttachmentPrimitive.Remove asChild>
|
|
457
|
+
<TooltipIconButton
|
|
458
|
+
tooltip="Remove file"
|
|
459
|
+
className="aui-attachment-tile-remove text-muted-foreground hover:[&_svg]:text-destructive absolute top-1.5 right-1.5 size-3.5 rounded-full bg-white opacity-100 shadow-sm hover:!bg-white [&_svg]:text-black"
|
|
460
|
+
side="top"
|
|
461
|
+
>
|
|
462
|
+
<XIcon className="aui-attachment-remove-icon size-3 dark:stroke-[2.5px]" />
|
|
463
|
+
</TooltipIconButton>
|
|
464
|
+
</AttachmentPrimitive.Remove>
|
|
465
|
+
);
|
|
466
|
+
};
|
|
467
|
+
|
|
468
|
+
export const UserMessageAttachments: FC = () => {
|
|
469
|
+
return (
|
|
470
|
+
<div className="aui-user-message-attachments-end col-span-full col-start-1 row-start-1 flex w-full flex-row justify-end gap-2">
|
|
471
|
+
<MessagePrimitive.Attachments components={{ Attachment: AttachmentUI }} />
|
|
472
|
+
</div>
|
|
473
|
+
);
|
|
474
|
+
};
|
|
475
|
+
|
|
476
|
+
export const ComposerAttachments: FC = () => {
|
|
477
|
+
return (
|
|
478
|
+
<div className="aui-composer-attachments mb-2 flex w-full flex-row items-center gap-2 overflow-x-auto px-1.5 pt-0.5 pb-1 empty:hidden">
|
|
479
|
+
<ComposerPrimitive.Attachments
|
|
480
|
+
components={{ Attachment: AttachmentUI }}
|
|
481
|
+
/>
|
|
482
|
+
</div>
|
|
483
|
+
);
|
|
484
|
+
};
|
|
485
|
+
|
|
486
|
+
export const ComposerAddAttachment: FC = () => {
|
|
487
|
+
return (
|
|
488
|
+
<ComposerPrimitive.AddAttachment asChild>
|
|
489
|
+
<TooltipIconButton
|
|
490
|
+
tooltip="Add Attachment"
|
|
491
|
+
side="bottom"
|
|
492
|
+
variant="ghost"
|
|
493
|
+
size="icon"
|
|
494
|
+
className="aui-composer-add-attachment hover:bg-muted-foreground/15 dark:border-muted-foreground/15 dark:hover:bg-muted-foreground/30 size-[34px] rounded-full p-1 text-xs font-semibold"
|
|
495
|
+
aria-label="Add Attachment"
|
|
496
|
+
>
|
|
497
|
+
<PlusIcon className="aui-attachment-add-icon size-5 stroke-[1.5px]" />
|
|
498
|
+
</TooltipIconButton>
|
|
499
|
+
</ComposerPrimitive.AddAttachment>
|
|
500
|
+
);
|
|
501
|
+
};
|
|
502
|
+
|
|
503
|
+
```
|
|
504
|
+
|
|
264
505
|
## components/assistant-ui/markdown-text.tsx
|
|
265
506
|
|
|
266
507
|
```tsx
|
|
@@ -269,13 +510,13 @@ export default function Home() {
|
|
|
269
510
|
import "@assistant-ui/react-markdown/styles/dot.css";
|
|
270
511
|
|
|
271
512
|
import {
|
|
272
|
-
CodeHeaderProps,
|
|
513
|
+
type CodeHeaderProps,
|
|
273
514
|
MarkdownTextPrimitive,
|
|
274
515
|
unstable_memoizeMarkdownComponents as memoizeMarkdownComponents,
|
|
275
516
|
useIsMarkdownCodeBlock,
|
|
276
517
|
} from "@assistant-ui/react-markdown";
|
|
277
518
|
import remarkGfm from "remark-gfm";
|
|
278
|
-
import { FC, memo, useState } from "react";
|
|
519
|
+
import { type FC, memo, useState } from "react";
|
|
279
520
|
import { CheckIcon, CopyIcon } from "lucide-react";
|
|
280
521
|
|
|
281
522
|
import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
|
|
@@ -301,8 +542,10 @@ const CodeHeader: FC<CodeHeaderProps> = ({ language, code }) => {
|
|
|
301
542
|
};
|
|
302
543
|
|
|
303
544
|
return (
|
|
304
|
-
<div className="flex items-center justify-between gap-4 rounded-t-lg
|
|
305
|
-
<span className="lowercase [&>span]:text-xs">
|
|
545
|
+
<div className="aui-code-header-root bg-muted-foreground/15 text-foreground dark:bg-muted-foreground/20 mt-4 flex items-center justify-between gap-4 rounded-t-lg px-4 py-2 text-sm font-semibold">
|
|
546
|
+
<span className="aui-code-header-language lowercase [&>span]:text-xs">
|
|
547
|
+
{language}
|
|
548
|
+
</span>
|
|
306
549
|
<TooltipIconButton tooltip="Copy" onClick={onCopy}>
|
|
307
550
|
{!isCopied && <CopyIcon />}
|
|
308
551
|
{isCopied && <CheckIcon />}
|
|
@@ -334,7 +577,7 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
334
577
|
h1: ({ className, ...props }) => (
|
|
335
578
|
<h1
|
|
336
579
|
className={cn(
|
|
337
|
-
"mb-8 scroll-m-20 text-4xl font-extrabold tracking-tight last:mb-0",
|
|
580
|
+
"aui-md-h1 mb-8 scroll-m-20 text-4xl font-extrabold tracking-tight last:mb-0",
|
|
338
581
|
className,
|
|
339
582
|
)}
|
|
340
583
|
{...props}
|
|
@@ -343,7 +586,7 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
343
586
|
h2: ({ className, ...props }) => (
|
|
344
587
|
<h2
|
|
345
588
|
className={cn(
|
|
346
|
-
"mt-8 mb-4 scroll-m-20 text-3xl font-semibold tracking-tight first:mt-0 last:mb-0",
|
|
589
|
+
"aui-md-h2 mt-8 mb-4 scroll-m-20 text-3xl font-semibold tracking-tight first:mt-0 last:mb-0",
|
|
347
590
|
className,
|
|
348
591
|
)}
|
|
349
592
|
{...props}
|
|
@@ -352,7 +595,7 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
352
595
|
h3: ({ className, ...props }) => (
|
|
353
596
|
<h3
|
|
354
597
|
className={cn(
|
|
355
|
-
"mt-6 mb-4 scroll-m-20 text-2xl font-semibold tracking-tight first:mt-0 last:mb-0",
|
|
598
|
+
"aui-md-h3 mt-6 mb-4 scroll-m-20 text-2xl font-semibold tracking-tight first:mt-0 last:mb-0",
|
|
356
599
|
className,
|
|
357
600
|
)}
|
|
358
601
|
{...props}
|
|
@@ -361,7 +604,7 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
361
604
|
h4: ({ className, ...props }) => (
|
|
362
605
|
<h4
|
|
363
606
|
className={cn(
|
|
364
|
-
"mt-6 mb-4 scroll-m-20 text-xl font-semibold tracking-tight first:mt-0 last:mb-0",
|
|
607
|
+
"aui-md-h4 mt-6 mb-4 scroll-m-20 text-xl font-semibold tracking-tight first:mt-0 last:mb-0",
|
|
365
608
|
className,
|
|
366
609
|
)}
|
|
367
610
|
{...props}
|
|
@@ -370,7 +613,7 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
370
613
|
h5: ({ className, ...props }) => (
|
|
371
614
|
<h5
|
|
372
615
|
className={cn(
|
|
373
|
-
"my-4 text-lg font-semibold first:mt-0 last:mb-0",
|
|
616
|
+
"aui-md-h5 my-4 text-lg font-semibold first:mt-0 last:mb-0",
|
|
374
617
|
className,
|
|
375
618
|
)}
|
|
376
619
|
{...props}
|
|
@@ -378,20 +621,26 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
378
621
|
),
|
|
379
622
|
h6: ({ className, ...props }) => (
|
|
380
623
|
<h6
|
|
381
|
-
className={cn(
|
|
624
|
+
className={cn(
|
|
625
|
+
"aui-md-h6 my-4 font-semibold first:mt-0 last:mb-0",
|
|
626
|
+
className,
|
|
627
|
+
)}
|
|
382
628
|
{...props}
|
|
383
629
|
/>
|
|
384
630
|
),
|
|
385
631
|
p: ({ className, ...props }) => (
|
|
386
632
|
<p
|
|
387
|
-
className={cn(
|
|
633
|
+
className={cn(
|
|
634
|
+
"aui-md-p mt-5 mb-5 leading-7 first:mt-0 last:mb-0",
|
|
635
|
+
className,
|
|
636
|
+
)}
|
|
388
637
|
{...props}
|
|
389
638
|
/>
|
|
390
639
|
),
|
|
391
640
|
a: ({ className, ...props }) => (
|
|
392
641
|
<a
|
|
393
642
|
className={cn(
|
|
394
|
-
"text-primary font-medium underline underline-offset-4",
|
|
643
|
+
"aui-md-a text-primary font-medium underline underline-offset-4",
|
|
395
644
|
className,
|
|
396
645
|
)}
|
|
397
646
|
{...props}
|
|
@@ -399,29 +648,29 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
399
648
|
),
|
|
400
649
|
blockquote: ({ className, ...props }) => (
|
|
401
650
|
<blockquote
|
|
402
|
-
className={cn("border-l-2 pl-6 italic", className)}
|
|
651
|
+
className={cn("aui-md-blockquote border-l-2 pl-6 italic", className)}
|
|
403
652
|
{...props}
|
|
404
653
|
/>
|
|
405
654
|
),
|
|
406
655
|
ul: ({ className, ...props }) => (
|
|
407
656
|
<ul
|
|
408
|
-
className={cn("my-5 ml-6 list-disc [&>li]:mt-2", className)}
|
|
657
|
+
className={cn("aui-md-ul my-5 ml-6 list-disc [&>li]:mt-2", className)}
|
|
409
658
|
{...props}
|
|
410
659
|
/>
|
|
411
660
|
),
|
|
412
661
|
ol: ({ className, ...props }) => (
|
|
413
662
|
<ol
|
|
414
|
-
className={cn("my-5 ml-6 list-decimal [&>li]:mt-2", className)}
|
|
663
|
+
className={cn("aui-md-ol my-5 ml-6 list-decimal [&>li]:mt-2", className)}
|
|
415
664
|
{...props}
|
|
416
665
|
/>
|
|
417
666
|
),
|
|
418
667
|
hr: ({ className, ...props }) => (
|
|
419
|
-
<hr className={cn("my-5 border-b", className)} {...props} />
|
|
668
|
+
<hr className={cn("aui-md-hr my-5 border-b", className)} {...props} />
|
|
420
669
|
),
|
|
421
670
|
table: ({ className, ...props }) => (
|
|
422
671
|
<table
|
|
423
672
|
className={cn(
|
|
424
|
-
"my-5 w-full border-separate border-spacing-0 overflow-y-auto",
|
|
673
|
+
"aui-md-table my-5 w-full border-separate border-spacing-0 overflow-y-auto",
|
|
425
674
|
className,
|
|
426
675
|
)}
|
|
427
676
|
{...props}
|
|
@@ -430,7 +679,7 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
430
679
|
th: ({ className, ...props }) => (
|
|
431
680
|
<th
|
|
432
681
|
className={cn(
|
|
433
|
-
"bg-muted px-4 py-2 text-left font-bold first:rounded-tl-lg last:rounded-tr-lg [&[align=center]]:text-center [&[align=right]]:text-right",
|
|
682
|
+
"aui-md-th bg-muted px-4 py-2 text-left font-bold first:rounded-tl-lg last:rounded-tr-lg [&[align=center]]:text-center [&[align=right]]:text-right",
|
|
434
683
|
className,
|
|
435
684
|
)}
|
|
436
685
|
{...props}
|
|
@@ -439,7 +688,7 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
439
688
|
td: ({ className, ...props }) => (
|
|
440
689
|
<td
|
|
441
690
|
className={cn(
|
|
442
|
-
"border-b border-l px-4 py-2 text-left last:border-r [&[align=center]]:text-center [&[align=right]]:text-right",
|
|
691
|
+
"aui-md-td border-b border-l px-4 py-2 text-left last:border-r [&[align=center]]:text-center [&[align=right]]:text-right",
|
|
443
692
|
className,
|
|
444
693
|
)}
|
|
445
694
|
{...props}
|
|
@@ -448,7 +697,7 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
448
697
|
tr: ({ className, ...props }) => (
|
|
449
698
|
<tr
|
|
450
699
|
className={cn(
|
|
451
|
-
"m-0 border-b p-0 first:border-t [&:last-child>td:first-child]:rounded-bl-lg [&:last-child>td:last-child]:rounded-br-lg",
|
|
700
|
+
"aui-md-tr m-0 border-b p-0 first:border-t [&:last-child>td:first-child]:rounded-bl-lg [&:last-child>td:last-child]:rounded-br-lg",
|
|
452
701
|
className,
|
|
453
702
|
)}
|
|
454
703
|
{...props}
|
|
@@ -456,14 +705,14 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
456
705
|
),
|
|
457
706
|
sup: ({ className, ...props }) => (
|
|
458
707
|
<sup
|
|
459
|
-
className={cn("[&>a]:text-xs [&>a]:no-underline", className)}
|
|
708
|
+
className={cn("aui-md-sup [&>a]:text-xs [&>a]:no-underline", className)}
|
|
460
709
|
{...props}
|
|
461
710
|
/>
|
|
462
711
|
),
|
|
463
712
|
pre: ({ className, ...props }) => (
|
|
464
713
|
<pre
|
|
465
714
|
className={cn(
|
|
466
|
-
"overflow-x-auto rounded-b-lg bg-black p-4 text-white",
|
|
715
|
+
"aui-md-pre overflow-x-auto !rounded-t-none rounded-b-lg bg-black p-4 text-white",
|
|
467
716
|
className,
|
|
468
717
|
)}
|
|
469
718
|
{...props}
|
|
@@ -474,7 +723,8 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
474
723
|
return (
|
|
475
724
|
<code
|
|
476
725
|
className={cn(
|
|
477
|
-
!isCodeBlock &&
|
|
726
|
+
!isCodeBlock &&
|
|
727
|
+
"aui-md-inline-code bg-muted rounded border font-semibold",
|
|
478
728
|
className,
|
|
479
729
|
)}
|
|
480
730
|
{...props}
|
|
@@ -776,12 +1026,111 @@ const CircleStopIcon = () => {
|
|
|
776
1026
|
|
|
777
1027
|
```
|
|
778
1028
|
|
|
1029
|
+
## components/assistant-ui/tool-fallback.tsx
|
|
1030
|
+
|
|
1031
|
+
```tsx
|
|
1032
|
+
import type { ToolCallMessagePartComponent } from "@assistant-ui/react";
|
|
1033
|
+
import {
|
|
1034
|
+
CheckIcon,
|
|
1035
|
+
ChevronDownIcon,
|
|
1036
|
+
ChevronUpIcon,
|
|
1037
|
+
XCircleIcon,
|
|
1038
|
+
} from "lucide-react";
|
|
1039
|
+
import { useState } from "react";
|
|
1040
|
+
import { Button } from "@/components/ui/button";
|
|
1041
|
+
import { cn } from "@/lib/utils";
|
|
1042
|
+
|
|
1043
|
+
export const ToolFallback: ToolCallMessagePartComponent = ({
|
|
1044
|
+
toolName,
|
|
1045
|
+
argsText,
|
|
1046
|
+
result,
|
|
1047
|
+
status,
|
|
1048
|
+
}) => {
|
|
1049
|
+
const [isCollapsed, setIsCollapsed] = useState(true);
|
|
1050
|
+
|
|
1051
|
+
const isCancelled =
|
|
1052
|
+
status?.type === "incomplete" && status.reason === "cancelled";
|
|
1053
|
+
const cancelledReason =
|
|
1054
|
+
isCancelled && status.error
|
|
1055
|
+
? typeof status.error === "string"
|
|
1056
|
+
? status.error
|
|
1057
|
+
: JSON.stringify(status.error)
|
|
1058
|
+
: null;
|
|
1059
|
+
|
|
1060
|
+
return (
|
|
1061
|
+
<div
|
|
1062
|
+
className={cn(
|
|
1063
|
+
"aui-tool-fallback-root mb-4 flex w-full flex-col gap-3 rounded-lg border py-3",
|
|
1064
|
+
isCancelled && "border-muted-foreground/30 bg-muted/30",
|
|
1065
|
+
)}
|
|
1066
|
+
>
|
|
1067
|
+
<div className="aui-tool-fallback-header flex items-center gap-2 px-4">
|
|
1068
|
+
{isCancelled ? (
|
|
1069
|
+
<XCircleIcon className="aui-tool-fallback-icon text-muted-foreground size-4" />
|
|
1070
|
+
) : (
|
|
1071
|
+
<CheckIcon className="aui-tool-fallback-icon size-4" />
|
|
1072
|
+
)}
|
|
1073
|
+
<p
|
|
1074
|
+
className={cn(
|
|
1075
|
+
"aui-tool-fallback-title grow",
|
|
1076
|
+
isCancelled && "text-muted-foreground line-through",
|
|
1077
|
+
)}
|
|
1078
|
+
>
|
|
1079
|
+
{isCancelled ? "Cancelled tool: " : "Used tool: "}
|
|
1080
|
+
<b>{toolName}</b>
|
|
1081
|
+
</p>
|
|
1082
|
+
<Button onClick={() => setIsCollapsed(!isCollapsed)}>
|
|
1083
|
+
{isCollapsed ? <ChevronUpIcon /> : <ChevronDownIcon />}
|
|
1084
|
+
</Button>
|
|
1085
|
+
</div>
|
|
1086
|
+
{!isCollapsed && (
|
|
1087
|
+
<div className="aui-tool-fallback-content flex flex-col gap-2 border-t pt-2">
|
|
1088
|
+
{cancelledReason && (
|
|
1089
|
+
<div className="aui-tool-fallback-cancelled-root px-4">
|
|
1090
|
+
<p className="aui-tool-fallback-cancelled-header text-muted-foreground font-semibold">
|
|
1091
|
+
Cancelled reason:
|
|
1092
|
+
</p>
|
|
1093
|
+
<p className="aui-tool-fallback-cancelled-reason text-muted-foreground">
|
|
1094
|
+
{cancelledReason}
|
|
1095
|
+
</p>
|
|
1096
|
+
</div>
|
|
1097
|
+
)}
|
|
1098
|
+
<div
|
|
1099
|
+
className={cn(
|
|
1100
|
+
"aui-tool-fallback-args-root px-4",
|
|
1101
|
+
isCancelled && "opacity-60",
|
|
1102
|
+
)}
|
|
1103
|
+
>
|
|
1104
|
+
<pre className="aui-tool-fallback-args-value whitespace-pre-wrap">
|
|
1105
|
+
{argsText}
|
|
1106
|
+
</pre>
|
|
1107
|
+
</div>
|
|
1108
|
+
{!isCancelled && result !== undefined && (
|
|
1109
|
+
<div className="aui-tool-fallback-result-root border-t border-dashed px-4 pt-2">
|
|
1110
|
+
<p className="aui-tool-fallback-result-header font-semibold">
|
|
1111
|
+
Result:
|
|
1112
|
+
</p>
|
|
1113
|
+
<pre className="aui-tool-fallback-result-content whitespace-pre-wrap">
|
|
1114
|
+
{typeof result === "string"
|
|
1115
|
+
? result
|
|
1116
|
+
: JSON.stringify(result, null, 2)}
|
|
1117
|
+
</pre>
|
|
1118
|
+
</div>
|
|
1119
|
+
)}
|
|
1120
|
+
</div>
|
|
1121
|
+
)}
|
|
1122
|
+
</div>
|
|
1123
|
+
);
|
|
1124
|
+
};
|
|
1125
|
+
|
|
1126
|
+
```
|
|
1127
|
+
|
|
779
1128
|
## components/assistant-ui/tooltip-icon-button.tsx
|
|
780
1129
|
|
|
781
1130
|
```tsx
|
|
782
1131
|
"use client";
|
|
783
1132
|
|
|
784
|
-
import {
|
|
1133
|
+
import { ComponentPropsWithRef, forwardRef } from "react";
|
|
785
1134
|
import { Slottable } from "@radix-ui/react-slot";
|
|
786
1135
|
|
|
787
1136
|
import {
|
|
@@ -792,7 +1141,7 @@ import {
|
|
|
792
1141
|
import { Button } from "@/components/ui/button";
|
|
793
1142
|
import { cn } from "@/lib/utils";
|
|
794
1143
|
|
|
795
|
-
export type TooltipIconButtonProps =
|
|
1144
|
+
export type TooltipIconButtonProps = ComponentPropsWithRef<typeof Button> & {
|
|
796
1145
|
tooltip: string;
|
|
797
1146
|
side?: "top" | "bottom" | "left" | "right";
|
|
798
1147
|
};
|
|
@@ -808,11 +1157,11 @@ export const TooltipIconButton = forwardRef<
|
|
|
808
1157
|
variant="ghost"
|
|
809
1158
|
size="icon"
|
|
810
1159
|
{...rest}
|
|
811
|
-
className={cn("size-6 p-1", className)}
|
|
1160
|
+
className={cn("aui-button-icon size-6 p-1", className)}
|
|
812
1161
|
ref={ref}
|
|
813
1162
|
>
|
|
814
1163
|
<Slottable>{children}</Slottable>
|
|
815
|
-
<span className="sr-only">{tooltip}</span>
|
|
1164
|
+
<span className="aui-sr-only sr-only">{tooltip}</span>
|
|
816
1165
|
</Button>
|
|
817
1166
|
</TooltipTrigger>
|
|
818
1167
|
<TooltipContent side={side}>{tooltip}</TooltipContent>
|
|
@@ -824,6 +1173,62 @@ TooltipIconButton.displayName = "TooltipIconButton";
|
|
|
824
1173
|
|
|
825
1174
|
```
|
|
826
1175
|
|
|
1176
|
+
## components/ui/avatar.tsx
|
|
1177
|
+
|
|
1178
|
+
```tsx
|
|
1179
|
+
"use client";
|
|
1180
|
+
|
|
1181
|
+
import * as React from "react";
|
|
1182
|
+
import * as AvatarPrimitive from "@radix-ui/react-avatar";
|
|
1183
|
+
|
|
1184
|
+
import { cn } from "@/lib/utils";
|
|
1185
|
+
|
|
1186
|
+
const Avatar = React.forwardRef<
|
|
1187
|
+
React.ElementRef<typeof AvatarPrimitive.Root>,
|
|
1188
|
+
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>
|
|
1189
|
+
>(({ className, ...props }, ref) => (
|
|
1190
|
+
<AvatarPrimitive.Root
|
|
1191
|
+
ref={ref}
|
|
1192
|
+
className={cn(
|
|
1193
|
+
"relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full",
|
|
1194
|
+
className,
|
|
1195
|
+
)}
|
|
1196
|
+
{...props}
|
|
1197
|
+
/>
|
|
1198
|
+
));
|
|
1199
|
+
Avatar.displayName = AvatarPrimitive.Root.displayName;
|
|
1200
|
+
|
|
1201
|
+
const AvatarImage = React.forwardRef<
|
|
1202
|
+
React.ElementRef<typeof AvatarPrimitive.Image>,
|
|
1203
|
+
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>
|
|
1204
|
+
>(({ className, ...props }, ref) => (
|
|
1205
|
+
<AvatarPrimitive.Image
|
|
1206
|
+
ref={ref}
|
|
1207
|
+
className={cn("aspect-square h-full w-full", className)}
|
|
1208
|
+
{...props}
|
|
1209
|
+
/>
|
|
1210
|
+
));
|
|
1211
|
+
AvatarImage.displayName = AvatarPrimitive.Image.displayName;
|
|
1212
|
+
|
|
1213
|
+
const AvatarFallback = React.forwardRef<
|
|
1214
|
+
React.ElementRef<typeof AvatarPrimitive.Fallback>,
|
|
1215
|
+
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>
|
|
1216
|
+
>(({ className, ...props }, ref) => (
|
|
1217
|
+
<AvatarPrimitive.Fallback
|
|
1218
|
+
ref={ref}
|
|
1219
|
+
className={cn(
|
|
1220
|
+
"bg-muted flex h-full w-full items-center justify-center rounded-full",
|
|
1221
|
+
className,
|
|
1222
|
+
)}
|
|
1223
|
+
{...props}
|
|
1224
|
+
/>
|
|
1225
|
+
));
|
|
1226
|
+
AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
|
|
1227
|
+
|
|
1228
|
+
export { Avatar, AvatarImage, AvatarFallback };
|
|
1229
|
+
|
|
1230
|
+
```
|
|
1231
|
+
|
|
827
1232
|
## components/ui/button.tsx
|
|
828
1233
|
|
|
829
1234
|
```tsx
|
|
@@ -889,6 +1294,147 @@ export { Button, buttonVariants };
|
|
|
889
1294
|
|
|
890
1295
|
```
|
|
891
1296
|
|
|
1297
|
+
## components/ui/dialog.tsx
|
|
1298
|
+
|
|
1299
|
+
```tsx
|
|
1300
|
+
"use client";
|
|
1301
|
+
|
|
1302
|
+
import * as React from "react";
|
|
1303
|
+
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
|
1304
|
+
import { XIcon } from "lucide-react";
|
|
1305
|
+
|
|
1306
|
+
import { cn } from "@/lib/utils";
|
|
1307
|
+
|
|
1308
|
+
function Dialog({
|
|
1309
|
+
...props
|
|
1310
|
+
}: React.ComponentProps<typeof DialogPrimitive.Root>) {
|
|
1311
|
+
return <DialogPrimitive.Root data-slot="dialog" {...props} />;
|
|
1312
|
+
}
|
|
1313
|
+
|
|
1314
|
+
function DialogTrigger({
|
|
1315
|
+
...props
|
|
1316
|
+
}: React.ComponentProps<typeof DialogPrimitive.Trigger>) {
|
|
1317
|
+
return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} />;
|
|
1318
|
+
}
|
|
1319
|
+
|
|
1320
|
+
function DialogPortal({
|
|
1321
|
+
...props
|
|
1322
|
+
}: React.ComponentProps<typeof DialogPrimitive.Portal>) {
|
|
1323
|
+
return <DialogPrimitive.Portal data-slot="dialog-portal" {...props} />;
|
|
1324
|
+
}
|
|
1325
|
+
|
|
1326
|
+
function DialogClose({
|
|
1327
|
+
...props
|
|
1328
|
+
}: React.ComponentProps<typeof DialogPrimitive.Close>) {
|
|
1329
|
+
return <DialogPrimitive.Close data-slot="dialog-close" {...props} />;
|
|
1330
|
+
}
|
|
1331
|
+
|
|
1332
|
+
function DialogOverlay({
|
|
1333
|
+
className,
|
|
1334
|
+
...props
|
|
1335
|
+
}: React.ComponentProps<typeof DialogPrimitive.Overlay>) {
|
|
1336
|
+
return (
|
|
1337
|
+
<DialogPrimitive.Overlay
|
|
1338
|
+
data-slot="dialog-overlay"
|
|
1339
|
+
className={cn(
|
|
1340
|
+
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/80",
|
|
1341
|
+
className,
|
|
1342
|
+
)}
|
|
1343
|
+
{...props}
|
|
1344
|
+
/>
|
|
1345
|
+
);
|
|
1346
|
+
}
|
|
1347
|
+
|
|
1348
|
+
function DialogContent({
|
|
1349
|
+
className,
|
|
1350
|
+
children,
|
|
1351
|
+
...props
|
|
1352
|
+
}: React.ComponentProps<typeof DialogPrimitive.Content>) {
|
|
1353
|
+
return (
|
|
1354
|
+
<DialogPortal data-slot="dialog-portal">
|
|
1355
|
+
<DialogOverlay />
|
|
1356
|
+
<DialogPrimitive.Content
|
|
1357
|
+
data-slot="dialog-content"
|
|
1358
|
+
className={cn(
|
|
1359
|
+
"bg-background data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in 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 p-6 shadow-lg duration-200 sm:max-w-lg",
|
|
1360
|
+
className,
|
|
1361
|
+
)}
|
|
1362
|
+
{...props}
|
|
1363
|
+
>
|
|
1364
|
+
{children}
|
|
1365
|
+
<DialogPrimitive.Close className="ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4">
|
|
1366
|
+
<XIcon />
|
|
1367
|
+
<span className="sr-only">Close</span>
|
|
1368
|
+
</DialogPrimitive.Close>
|
|
1369
|
+
</DialogPrimitive.Content>
|
|
1370
|
+
</DialogPortal>
|
|
1371
|
+
);
|
|
1372
|
+
}
|
|
1373
|
+
|
|
1374
|
+
function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
|
|
1375
|
+
return (
|
|
1376
|
+
<div
|
|
1377
|
+
data-slot="dialog-header"
|
|
1378
|
+
className={cn("flex flex-col gap-2 text-center sm:text-left", className)}
|
|
1379
|
+
{...props}
|
|
1380
|
+
/>
|
|
1381
|
+
);
|
|
1382
|
+
}
|
|
1383
|
+
|
|
1384
|
+
function DialogFooter({ className, ...props }: React.ComponentProps<"div">) {
|
|
1385
|
+
return (
|
|
1386
|
+
<div
|
|
1387
|
+
data-slot="dialog-footer"
|
|
1388
|
+
className={cn(
|
|
1389
|
+
"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end",
|
|
1390
|
+
className,
|
|
1391
|
+
)}
|
|
1392
|
+
{...props}
|
|
1393
|
+
/>
|
|
1394
|
+
);
|
|
1395
|
+
}
|
|
1396
|
+
|
|
1397
|
+
function DialogTitle({
|
|
1398
|
+
className,
|
|
1399
|
+
...props
|
|
1400
|
+
}: React.ComponentProps<typeof DialogPrimitive.Title>) {
|
|
1401
|
+
return (
|
|
1402
|
+
<DialogPrimitive.Title
|
|
1403
|
+
data-slot="dialog-title"
|
|
1404
|
+
className={cn("text-lg leading-none font-semibold", className)}
|
|
1405
|
+
{...props}
|
|
1406
|
+
/>
|
|
1407
|
+
);
|
|
1408
|
+
}
|
|
1409
|
+
|
|
1410
|
+
function DialogDescription({
|
|
1411
|
+
className,
|
|
1412
|
+
...props
|
|
1413
|
+
}: React.ComponentProps<typeof DialogPrimitive.Description>) {
|
|
1414
|
+
return (
|
|
1415
|
+
<DialogPrimitive.Description
|
|
1416
|
+
data-slot="dialog-description"
|
|
1417
|
+
className={cn("text-muted-foreground text-sm", className)}
|
|
1418
|
+
{...props}
|
|
1419
|
+
/>
|
|
1420
|
+
);
|
|
1421
|
+
}
|
|
1422
|
+
|
|
1423
|
+
export {
|
|
1424
|
+
Dialog,
|
|
1425
|
+
DialogClose,
|
|
1426
|
+
DialogContent,
|
|
1427
|
+
DialogDescription,
|
|
1428
|
+
DialogFooter,
|
|
1429
|
+
DialogHeader,
|
|
1430
|
+
DialogOverlay,
|
|
1431
|
+
DialogPortal,
|
|
1432
|
+
DialogTitle,
|
|
1433
|
+
DialogTrigger,
|
|
1434
|
+
};
|
|
1435
|
+
|
|
1436
|
+
```
|
|
1437
|
+
|
|
892
1438
|
## components/ui/tooltip.tsx
|
|
893
1439
|
|
|
894
1440
|
```tsx
|
|
@@ -995,20 +1541,24 @@ export default nextConfig;
|
|
|
995
1541
|
"lint": "eslint ."
|
|
996
1542
|
},
|
|
997
1543
|
"dependencies": {
|
|
998
|
-
"@ai-sdk/openai": "^2.0.
|
|
1544
|
+
"@ai-sdk/openai": "^2.0.73",
|
|
999
1545
|
"@assistant-ui/react": "workspace:*",
|
|
1000
1546
|
"@assistant-ui/react-markdown": "workspace:*",
|
|
1547
|
+
"@radix-ui/react-avatar": "^1.1.4",
|
|
1548
|
+
"@radix-ui/react-dialog": "^1.1.7",
|
|
1001
1549
|
"@radix-ui/react-slot": "^1.2.4",
|
|
1002
1550
|
"@radix-ui/react-tooltip": "^1.2.8",
|
|
1003
1551
|
"class-variance-authority": "^0.7.1",
|
|
1004
1552
|
"clsx": "^2.1.1",
|
|
1005
|
-
"lucide-react": "^0.
|
|
1006
|
-
"
|
|
1553
|
+
"lucide-react": "^0.555.0",
|
|
1554
|
+
"motion": "^11.18.2",
|
|
1555
|
+
"next": "16.0.4",
|
|
1007
1556
|
"react": "19.2.0",
|
|
1008
1557
|
"react-dom": "19.2.0",
|
|
1009
1558
|
"remark-gfm": "^4.0.1",
|
|
1010
1559
|
"tailwind-merge": "^3.4.0",
|
|
1011
|
-
"tw-animate-css": "^1.4.0"
|
|
1560
|
+
"tw-animate-css": "^1.4.0",
|
|
1561
|
+
"zustand": "^5.0.8"
|
|
1012
1562
|
},
|
|
1013
1563
|
"devDependencies": {
|
|
1014
1564
|
"@assistant-ui/x-buildutils": "workspace:*",
|