@open-mercato/ui 0.6.2-develop.3461.1.605f31c2c9 → 0.6.2-develop.3467.1.2a1818709d
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/.turbo/turbo-build.log +1 -1
- package/dist/ai/AiChat.js +130 -22
- package/dist/ai/AiChat.js.map +2 -2
- package/dist/ai/AiChatSessions.js +73 -3
- package/dist/ai/AiChatSessions.js.map +2 -2
- package/dist/ai/conversation-store.js +147 -0
- package/dist/ai/conversation-store.js.map +7 -0
- package/dist/ai/useAiChat.js +80 -4
- package/dist/ai/useAiChat.js.map +2 -2
- package/dist/backend/AuthSessionGuard.js +99 -0
- package/dist/backend/AuthSessionGuard.js.map +7 -0
- package/package.json +3 -3
- package/src/ai/AiChat.tsx +138 -22
- package/src/ai/AiChatSessions.tsx +89 -9
- package/src/ai/__tests__/AiChat.conversation.test.tsx +86 -0
- package/src/ai/conversation-store.ts +244 -0
- package/src/ai/useAiChat.ts +97 -8
- package/src/backend/AuthSessionGuard.tsx +114 -0
- package/src/backend/__tests__/AuthSessionGuard.test.tsx +150 -0
package/.turbo/turbo-build.log
CHANGED
package/dist/ai/AiChat.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
import {
|
|
5
5
|
Activity,
|
|
@@ -16,12 +16,14 @@ import {
|
|
|
16
16
|
CircleDashed,
|
|
17
17
|
Copy,
|
|
18
18
|
Database,
|
|
19
|
+
Download,
|
|
19
20
|
FileQuestion,
|
|
20
21
|
GitBranch,
|
|
21
22
|
Handshake,
|
|
22
23
|
Lightbulb,
|
|
23
24
|
ListChecks,
|
|
24
25
|
Loader2,
|
|
26
|
+
Maximize2,
|
|
25
27
|
Paperclip,
|
|
26
28
|
Plus,
|
|
27
29
|
Search,
|
|
@@ -38,6 +40,13 @@ import { useT } from "@open-mercato/shared/lib/i18n/context";
|
|
|
38
40
|
import { cn } from "@open-mercato/shared/lib/utils";
|
|
39
41
|
import { Alert, AlertDescription, AlertTitle } from "../primitives/alert.js";
|
|
40
42
|
import { Button } from "../primitives/button.js";
|
|
43
|
+
import {
|
|
44
|
+
Dialog,
|
|
45
|
+
DialogContent,
|
|
46
|
+
DialogDescription,
|
|
47
|
+
DialogHeader,
|
|
48
|
+
DialogTitle
|
|
49
|
+
} from "../primitives/dialog.js";
|
|
41
50
|
import { IconButton } from "../primitives/icon-button.js";
|
|
42
51
|
import { Label } from "../primitives/label.js";
|
|
43
52
|
import { Textarea } from "../primitives/textarea.js";
|
|
@@ -391,6 +400,124 @@ function ReasoningPanel({ text, streaming }) {
|
|
|
391
400
|
}
|
|
392
401
|
);
|
|
393
402
|
}
|
|
403
|
+
function getAttachmentImageUrl(file) {
|
|
404
|
+
if (file.id) return `/api/attachments/image/${encodeURIComponent(file.id)}`;
|
|
405
|
+
return file.previewUrl ?? null;
|
|
406
|
+
}
|
|
407
|
+
function getAttachmentDownloadUrl(file) {
|
|
408
|
+
if (file.id) return `/api/attachments/file/${encodeURIComponent(file.id)}?download=1`;
|
|
409
|
+
return file.previewUrl ?? null;
|
|
410
|
+
}
|
|
411
|
+
function MessageFileAttachment({ file }) {
|
|
412
|
+
const t = useT();
|
|
413
|
+
const [zoomOpen, setZoomOpen] = React.useState(false);
|
|
414
|
+
const imageUrl = file.previewUrl ? getAttachmentImageUrl(file) : null;
|
|
415
|
+
const downloadUrl = getAttachmentDownloadUrl(file);
|
|
416
|
+
const downloadLabel = t("ai_assistant.chat.downloadFile", "Download {name}").replace(
|
|
417
|
+
"{name}",
|
|
418
|
+
file.name
|
|
419
|
+
);
|
|
420
|
+
const zoomLabel = t("ai_assistant.chat.zoomImage", "Open {name} preview").replace(
|
|
421
|
+
"{name}",
|
|
422
|
+
file.name
|
|
423
|
+
);
|
|
424
|
+
if (!file.previewUrl) {
|
|
425
|
+
return /* @__PURE__ */ jsxs("span", { className: "inline-flex max-w-full items-center gap-1 rounded-full border border-border bg-muted px-2 py-0.5 text-xs", children: [
|
|
426
|
+
/* @__PURE__ */ jsx(Paperclip, { className: "size-3 shrink-0", "aria-hidden": true }),
|
|
427
|
+
/* @__PURE__ */ jsx("span", { className: "max-w-[180px] truncate", children: file.name }),
|
|
428
|
+
downloadUrl ? /* @__PURE__ */ jsx(
|
|
429
|
+
IconButton,
|
|
430
|
+
{
|
|
431
|
+
asChild: true,
|
|
432
|
+
variant: "ghost",
|
|
433
|
+
size: "xs",
|
|
434
|
+
className: "-mr-1 size-5 shrink-0",
|
|
435
|
+
children: /* @__PURE__ */ jsx("a", { href: downloadUrl, download: file.name, "aria-label": downloadLabel, children: /* @__PURE__ */ jsx(Download, { className: "size-3", "aria-hidden": true }) })
|
|
436
|
+
}
|
|
437
|
+
) : null
|
|
438
|
+
] });
|
|
439
|
+
}
|
|
440
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
441
|
+
/* @__PURE__ */ jsxs("div", { className: "group/file relative max-w-full", children: [
|
|
442
|
+
/* @__PURE__ */ jsxs(
|
|
443
|
+
"button",
|
|
444
|
+
{
|
|
445
|
+
type: "button",
|
|
446
|
+
className: "block max-w-full rounded-md border border-border bg-muted/30 focus-visible:outline-none focus-visible:shadow-focus",
|
|
447
|
+
onClick: () => setZoomOpen(true),
|
|
448
|
+
"aria-label": zoomLabel,
|
|
449
|
+
"data-ai-chat-image-preview": "",
|
|
450
|
+
children: [
|
|
451
|
+
/* @__PURE__ */ jsx(
|
|
452
|
+
"img",
|
|
453
|
+
{
|
|
454
|
+
src: file.previewUrl,
|
|
455
|
+
alt: file.name,
|
|
456
|
+
className: "max-h-32 max-w-[200px] rounded-md object-cover"
|
|
457
|
+
}
|
|
458
|
+
),
|
|
459
|
+
/* @__PURE__ */ jsx("span", { className: "pointer-events-none absolute right-1 top-1 inline-flex size-6 items-center justify-center rounded-md bg-background/90 text-muted-foreground opacity-0 shadow-xs transition-opacity group-hover/file:opacity-100 group-focus-within/file:opacity-100", children: /* @__PURE__ */ jsx(Maximize2, { className: "size-3.5", "aria-hidden": true }) })
|
|
460
|
+
]
|
|
461
|
+
}
|
|
462
|
+
),
|
|
463
|
+
downloadUrl ? /* @__PURE__ */ jsx(
|
|
464
|
+
IconButton,
|
|
465
|
+
{
|
|
466
|
+
asChild: true,
|
|
467
|
+
variant: "white",
|
|
468
|
+
size: "xs",
|
|
469
|
+
className: "absolute bottom-1 right-1 opacity-0 shadow-xs transition-opacity group-hover/file:opacity-100 group-focus-within/file:opacity-100",
|
|
470
|
+
children: /* @__PURE__ */ jsx(
|
|
471
|
+
"a",
|
|
472
|
+
{
|
|
473
|
+
href: downloadUrl,
|
|
474
|
+
download: file.name,
|
|
475
|
+
"aria-label": downloadLabel,
|
|
476
|
+
onClick: (event) => event.stopPropagation(),
|
|
477
|
+
"data-ai-chat-file-download": "",
|
|
478
|
+
children: /* @__PURE__ */ jsx(Download, { className: "size-3.5", "aria-hidden": true })
|
|
479
|
+
}
|
|
480
|
+
)
|
|
481
|
+
}
|
|
482
|
+
) : null
|
|
483
|
+
] }),
|
|
484
|
+
/* @__PURE__ */ jsx(Dialog, { open: zoomOpen, onOpenChange: setZoomOpen, children: /* @__PURE__ */ jsxs(DialogContent, { className: "gap-3 p-4 sm:max-w-[min(96vw,960px)]", children: [
|
|
485
|
+
/* @__PURE__ */ jsxs(DialogHeader, { className: "min-w-0 pr-16", children: [
|
|
486
|
+
/* @__PURE__ */ jsx(DialogTitle, { className: "truncate text-sm", children: file.name }),
|
|
487
|
+
/* @__PURE__ */ jsx(DialogDescription, { className: "sr-only", children: t("ai_assistant.chat.imagePreviewDialogDescription", "Image preview") })
|
|
488
|
+
] }),
|
|
489
|
+
/* @__PURE__ */ jsxs("div", { className: "relative flex min-h-0 items-center justify-center overflow-auto rounded-md bg-muted/30 p-2", children: [
|
|
490
|
+
/* @__PURE__ */ jsx(
|
|
491
|
+
"img",
|
|
492
|
+
{
|
|
493
|
+
src: imageUrl ?? file.previewUrl,
|
|
494
|
+
alt: file.name,
|
|
495
|
+
className: "max-h-[75vh] max-w-full object-contain"
|
|
496
|
+
}
|
|
497
|
+
),
|
|
498
|
+
downloadUrl ? /* @__PURE__ */ jsx(
|
|
499
|
+
IconButton,
|
|
500
|
+
{
|
|
501
|
+
asChild: true,
|
|
502
|
+
variant: "white",
|
|
503
|
+
size: "sm",
|
|
504
|
+
className: "absolute bottom-3 right-3 shadow-xs",
|
|
505
|
+
children: /* @__PURE__ */ jsx(
|
|
506
|
+
"a",
|
|
507
|
+
{
|
|
508
|
+
href: downloadUrl,
|
|
509
|
+
download: file.name,
|
|
510
|
+
"aria-label": downloadLabel,
|
|
511
|
+
"data-ai-chat-file-download": "",
|
|
512
|
+
children: /* @__PURE__ */ jsx(Download, { className: "size-4", "aria-hidden": true })
|
|
513
|
+
}
|
|
514
|
+
)
|
|
515
|
+
}
|
|
516
|
+
) : null
|
|
517
|
+
] })
|
|
518
|
+
] }) })
|
|
519
|
+
] });
|
|
520
|
+
}
|
|
394
521
|
function MessageRow({
|
|
395
522
|
message,
|
|
396
523
|
registry,
|
|
@@ -468,27 +595,7 @@ function MessageRow({
|
|
|
468
595
|
}
|
|
469
596
|
) : null
|
|
470
597
|
] }),
|
|
471
|
-
message.files && message.files.length > 0 ? /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2 py-1", children: message.files.map(
|
|
472
|
-
(file, i) => file.previewUrl ? /* @__PURE__ */ jsx(
|
|
473
|
-
"img",
|
|
474
|
-
{
|
|
475
|
-
src: file.previewUrl,
|
|
476
|
-
alt: file.name,
|
|
477
|
-
className: "max-h-32 max-w-[200px] rounded-md border border-border object-cover"
|
|
478
|
-
},
|
|
479
|
-
i
|
|
480
|
-
) : /* @__PURE__ */ jsxs(
|
|
481
|
-
"span",
|
|
482
|
-
{
|
|
483
|
-
className: "inline-flex items-center gap-1 rounded-full border border-border bg-muted px-2 py-0.5 text-xs",
|
|
484
|
-
children: [
|
|
485
|
-
/* @__PURE__ */ jsx(Paperclip, { className: "size-3", "aria-hidden": true }),
|
|
486
|
-
file.name
|
|
487
|
-
]
|
|
488
|
-
},
|
|
489
|
-
i
|
|
490
|
-
)
|
|
491
|
-
) }) : null,
|
|
598
|
+
message.files && message.files.length > 0 ? /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2 py-1", children: message.files.map((file, i) => /* @__PURE__ */ jsx(MessageFileAttachment, { file }, `${file.id ?? file.name}:${i}`)) }) : null,
|
|
492
599
|
isAssistant && message.reasoning ? /* @__PURE__ */ jsx(
|
|
493
600
|
ReasoningPanel,
|
|
494
601
|
{
|
|
@@ -867,6 +974,7 @@ function AiChat({
|
|
|
867
974
|
const isImage = entry.file.type.startsWith("image/");
|
|
868
975
|
const fallback = isImage ? URL.createObjectURL(entry.file) : void 0;
|
|
869
976
|
return {
|
|
977
|
+
id: entry.attachmentId,
|
|
870
978
|
name: entry.file.name,
|
|
871
979
|
type: entry.file.type,
|
|
872
980
|
previewUrl: isImage ? entry.previewDataUrl ?? fallback : void 0
|