@admin-layout/tailwind-ui 12.2.4-alpha.55 → 12.2.4-alpha.56
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/lib/components/AIToolbar/components/completion/AssistantAvatar.d.ts +12 -0
- package/lib/components/AIToolbar/components/completion/AssistantAvatar.d.ts.map +1 -0
- package/lib/components/AIToolbar/components/completion/AssistantAvatar.js +36 -0
- package/lib/components/AIToolbar/components/completion/AssistantAvatar.js.map +1 -0
- package/lib/components/AIToolbar/components/completion/AssistantSenderBadge.d.ts +15 -0
- package/lib/components/AIToolbar/components/completion/AssistantSenderBadge.d.ts.map +1 -0
- package/lib/components/AIToolbar/components/completion/Input.d.ts.map +1 -1
- package/lib/components/AIToolbar/components/completion/Input.js +99 -49
- package/lib/components/AIToolbar/components/completion/Input.js.map +1 -1
- package/lib/components/AIToolbar/components/completion/MessageHistory.d.ts.map +1 -1
- package/lib/components/AIToolbar/components/completion/MessageHistory.js +59 -20
- package/lib/components/AIToolbar/components/completion/MessageHistory.js.map +1 -1
- package/lib/components/AIToolbar/components/speech/ResultsSection.d.ts.map +1 -1
- package/lib/components/AIToolbar/components/speech/ResultsSection.js +14 -4
- package/lib/components/AIToolbar/components/speech/ResultsSection.js.map +1 -1
- package/lib/components/AIToolbar/hooks/useActiveCharacter.d.ts +18 -0
- package/lib/components/AIToolbar/hooks/useActiveCharacter.d.ts.map +1 -0
- package/lib/components/AIToolbar/hooks/useActiveCharacter.js +103 -0
- package/lib/components/AIToolbar/hooks/useActiveCharacter.js.map +1 -0
- package/lib/components/AIToolbar/hooks/useChatBackgroundImage.d.ts +10 -0
- package/lib/components/AIToolbar/hooks/useChatBackgroundImage.d.ts.map +1 -0
- package/lib/components/AIToolbar/hooks/useChatBackgroundImage.js +126 -0
- package/lib/components/AIToolbar/hooks/useChatBackgroundImage.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
interface AssistantAvatarProps {
|
|
2
|
+
avatarSrc: string | null;
|
|
3
|
+
/** Optional message sequence number rendered as "#N" beneath the avatar. */
|
|
4
|
+
index?: number;
|
|
5
|
+
/** Avatar diameter in px. */
|
|
6
|
+
size?: number;
|
|
7
|
+
/** Tailwind classes applied to the column wrapper. */
|
|
8
|
+
className?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function AssistantAvatar({ avatarSrc, index, size, className }: AssistantAvatarProps): import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
export default AssistantAvatar;
|
|
12
|
+
//# sourceMappingURL=AssistantAvatar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AssistantAvatar.d.ts","sourceRoot":"","sources":["../../../../../src/components/AIToolbar/components/completion/AssistantAvatar.tsx"],"names":[],"mappings":"AASA,UAAU,oBAAoB;IAC1B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,4EAA4E;IAC5E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6BAA6B;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,eAAe,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,IAAS,EAAE,SAAS,EAAE,EAAE,oBAAoB,2CA6B/F;AAED,eAAe,eAAe,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import {jsxs,jsx}from'react/jsx-runtime';import'../../../../utils/isBrowser/index.js';import {cn}from'../../../../utils/util.js';import'react';import'fast-deep-equal/react.js';function AssistantAvatar({
|
|
2
|
+
avatarSrc,
|
|
3
|
+
index,
|
|
4
|
+
size = 44,
|
|
5
|
+
className
|
|
6
|
+
}) {
|
|
7
|
+
const hasNumber = typeof index === 'number';
|
|
8
|
+
return jsxs("div", {
|
|
9
|
+
className: cn('flex shrink-0 flex-col items-center gap-1 pt-0.5', className),
|
|
10
|
+
"aria-hidden": !hasNumber,
|
|
11
|
+
children: [avatarSrc ? jsx("img", {
|
|
12
|
+
src: avatarSrc,
|
|
13
|
+
alt: "",
|
|
14
|
+
"aria-hidden": "true",
|
|
15
|
+
draggable: false,
|
|
16
|
+
width: size,
|
|
17
|
+
height: size,
|
|
18
|
+
className: "rounded-full object-cover ring-1 ring-border/60 shadow-sm",
|
|
19
|
+
style: {
|
|
20
|
+
width: size,
|
|
21
|
+
height: size
|
|
22
|
+
}
|
|
23
|
+
}) : jsx("div", {
|
|
24
|
+
"aria-hidden": "true",
|
|
25
|
+
className: "flex items-center justify-center rounded-full bg-muted text-[10px] font-semibold text-muted-foreground ring-1 ring-border/60",
|
|
26
|
+
style: {
|
|
27
|
+
width: size,
|
|
28
|
+
height: size
|
|
29
|
+
},
|
|
30
|
+
children: "AI"
|
|
31
|
+
}), hasNumber ? jsxs("span", {
|
|
32
|
+
className: "text-[10px] font-medium leading-none text-muted-foreground",
|
|
33
|
+
children: ["#", index]
|
|
34
|
+
}) : null]
|
|
35
|
+
});
|
|
36
|
+
}export{AssistantAvatar};//# sourceMappingURL=AssistantAvatar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AssistantAvatar.js","sources":["../../../../../src/components/AIToolbar/components/completion/AssistantAvatar.tsx"],"sourcesContent":[null],"names":["_jsxs"],"mappings":"gLAWI,SAAA,eAAA,CAAA;WACM;OACN;MACA,GAAK,EAAE;;;AAGV,EAAA,MAAA,SAAA,GAAA,OAAA,KAAA,KAAA,QAAA;AAED,EAAA,OAAAA,IAAA,CAAA,KAAA,EAAA;AA+BA,IAAA,SAAA,EAAe,qDAAgB,EAAA,SAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
interface AssistantSenderBadgeProps {
|
|
2
|
+
name: string;
|
|
3
|
+
avatarSrc: string | null;
|
|
4
|
+
/** Tailwind override on the wrapping span (e.g. scale text down inside dense lists). */
|
|
5
|
+
className?: string;
|
|
6
|
+
/** Avatar square size in px; defaults to 44 — matches SillyTavern's chat-header portrait. */
|
|
7
|
+
avatarSize?: number;
|
|
8
|
+
/** Optional message sequence number — rendered as "#N" beneath the avatar (SillyTavern style). */
|
|
9
|
+
index?: number;
|
|
10
|
+
/** Tailwind classes applied to the name `<span>`. Override when reusing inside denser surfaces. */
|
|
11
|
+
nameClassName?: string;
|
|
12
|
+
}
|
|
13
|
+
export declare function AssistantSenderBadge({ name, avatarSrc, className, avatarSize, index, nameClassName, }: AssistantSenderBadgeProps): import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
export default AssistantSenderBadge;
|
|
15
|
+
//# sourceMappingURL=AssistantSenderBadge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AssistantSenderBadge.d.ts","sourceRoot":"","sources":["../../../../../src/components/AIToolbar/components/completion/AssistantSenderBadge.tsx"],"names":[],"mappings":"AAUA,UAAU,yBAAyB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,wFAAwF;IACxF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6FAA6F;IAC7F,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kGAAkG;IAClG,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mGAAmG;IACnG,aAAa,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,oBAAoB,CAAC,EACjC,IAAI,EACJ,SAAS,EACT,SAAS,EACT,UAAe,EACf,KAAK,EACL,aAAa,GAChB,EAAE,yBAAyB,2CA0B3B;AAED,eAAe,oBAAoB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Input.d.ts","sourceRoot":"","sources":["../../../../../src/components/AIToolbar/components/completion/Input.tsx"],"names":[],"mappings":"AAQA,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"Input.d.ts","sourceRoot":"","sources":["../../../../../src/components/AIToolbar/components/completion/Input.tsx"],"names":[],"mappings":"AAQA,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAO/C,eAAO,MAAM,KAAK,GAAI,sTAsBnB,mBAAmB,GAAG;IAAE,QAAQ,EAAE,OAAO,CAAA;CAAE,4CAoT7C,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {jsx,jsxs}from'react/jsx-runtime';import {useRef,useMemo,useLayoutEffect}from'react';import {AIToolbarInputSurface}from'../AIToolbarPrimitives.js';import {XIcon,Loader2}from'lucide-react';import'../../../../shardui/accordion.js';import'../../../../shardui/alert.js';import'../../../../shardui/alert-dialog.js';import'@radix-ui/react-aspect-ratio';import'../../../../shardui/avatar.js';import'../../../../shardui/badge.js';import'../../../../shardui/breadcrumb.js';import {Button}from'../../../../shardui/button.js';import'../../../../shardui/calendar.js';import'../../../../shardui/card.js';import'../../../../shardui/carousel.js';import'../../../../shardui/chart.js';import'../../../../shardui/checkbox.js';import'@radix-ui/react-collapsible';import'../../../../shardui/command.js';import'../../../../shardui/context-menu.js';import'../../../../shardui/dialog.js';import'../../../../shardui/drawer.js';import'../../../../shardui/dropdown-menu.js';import'../../../../shardui/form.js';import'../../../../shardui/hover-card.js';import {Input as Input$1}from'../../../../shardui/input.js';import'../../../../shardui/input-otp.js';import'../../../../shardui/label.js';import'../../../../shardui/menubar.js';import'../../../../shardui/navigation-menu.js';import'../../../../shardui/pagination.js';import {Popover,PopoverContent,PopoverTrigger}from'../../../../shardui/popover.js';import'../../../../shardui/progress.js';import'../../../../shardui/radio-group.js';import'react-resizable-panels';import'../../../../utils/isBrowser/index.js';import {cn}from'../../../../utils/util.js';import'fast-deep-equal/react.js';import'../../../../shardui/scroll-area.js';import'../../../../shardui/select.js';import'../../../../shardui/separator.js';import'../../../../shardui/sheet.js';import'../../../../shardui/sidebar.js';import'../../../../shardui/slider.js';import'../../../ThemeProvider/ThemeProvider.js';import'sonner';import {Switch}from'../../../../shardui/switch.js';import'../../../../shardui/table.js';import'../../../../shardui/tabs.js';import'../../../../shardui/textarea.js';import'../../../../shardui/toast.js';import'../../../../shardui/toggle.js';import'../../../../shardui/toggle-group.js';import'../../../../shardui/tooltip.js';import {Markdown}from'../Markdown/index.js';import {AssistantMessageActions}from'./AssistantMessageActions.js';import {CopyButton}from'../Markdown/copy-button.js';import {MessageHistory}from'./MessageHistory.js';const Input = ({
|
|
1
|
+
import {jsx,jsxs,Fragment}from'react/jsx-runtime';import {useRef,useMemo,useLayoutEffect}from'react';import {AIToolbarInputSurface}from'../AIToolbarPrimitives.js';import {XIcon,Loader2}from'lucide-react';import'../../../../shardui/accordion.js';import'../../../../shardui/alert.js';import'../../../../shardui/alert-dialog.js';import'@radix-ui/react-aspect-ratio';import'../../../../shardui/avatar.js';import'../../../../shardui/badge.js';import'../../../../shardui/breadcrumb.js';import {Button}from'../../../../shardui/button.js';import'../../../../shardui/calendar.js';import'../../../../shardui/card.js';import'../../../../shardui/carousel.js';import'../../../../shardui/chart.js';import'../../../../shardui/checkbox.js';import'@radix-ui/react-collapsible';import'../../../../shardui/command.js';import'../../../../shardui/context-menu.js';import'../../../../shardui/dialog.js';import'../../../../shardui/drawer.js';import'../../../../shardui/dropdown-menu.js';import'../../../../shardui/form.js';import'../../../../shardui/hover-card.js';import {Input as Input$1}from'../../../../shardui/input.js';import'../../../../shardui/input-otp.js';import'../../../../shardui/label.js';import'../../../../shardui/menubar.js';import'../../../../shardui/navigation-menu.js';import'../../../../shardui/pagination.js';import {Popover,PopoverContent,PopoverTrigger}from'../../../../shardui/popover.js';import'../../../../shardui/progress.js';import'../../../../shardui/radio-group.js';import'react-resizable-panels';import'../../../../utils/isBrowser/index.js';import {cn}from'../../../../utils/util.js';import'fast-deep-equal/react.js';import'../../../../shardui/scroll-area.js';import'../../../../shardui/select.js';import'../../../../shardui/separator.js';import'../../../../shardui/sheet.js';import'../../../../shardui/sidebar.js';import'../../../../shardui/slider.js';import'../../../ThemeProvider/ThemeProvider.js';import'sonner';import {Switch}from'../../../../shardui/switch.js';import'../../../../shardui/table.js';import'../../../../shardui/tabs.js';import'../../../../shardui/textarea.js';import'../../../../shardui/toast.js';import'../../../../shardui/toggle.js';import'../../../../shardui/toggle-group.js';import'../../../../shardui/tooltip.js';import {Markdown}from'../Markdown/index.js';import {AssistantMessageActions}from'./AssistantMessageActions.js';import {CopyButton}from'../Markdown/copy-button.js';import {MessageHistory}from'./MessageHistory.js';import {useActiveCharacter}from'../../hooks/useActiveCharacter.js';import {useChatBackgroundImage}from'../../hooks/useChatBackgroundImage.js';import {AssistantAvatar}from'./AssistantAvatar.js';const Input = ({
|
|
2
2
|
isPopoverOpen,
|
|
3
3
|
isLoading,
|
|
4
4
|
reset,
|
|
@@ -22,6 +22,9 @@ import {jsx,jsxs}from'react/jsx-runtime';import {useRef,useMemo,useLayoutEffect}
|
|
|
22
22
|
regenerateAssistantMessage
|
|
23
23
|
}) => {
|
|
24
24
|
const conversationEndRef = useRef(null);
|
|
25
|
+
const character = useActiveCharacter();
|
|
26
|
+
const assistantName = character?.name ?? 'AI';
|
|
27
|
+
const chatBgImage = useChatBackgroundImage();
|
|
25
28
|
const sortedAsc = useMemo(() => [...conversationHistory].sort((a, b) => (a.timestamp ?? 0) - (b.timestamp ?? 0)), [conversationHistory]);
|
|
26
29
|
/** In-flight assistant bubble: hide when history already contains the same assistant text (avoids double render if `response` lingers). */
|
|
27
30
|
const streamingAssistantVisible = useMemo(() => {
|
|
@@ -51,13 +54,13 @@ import {jsx,jsxs}from'react/jsx-runtime';import {useRef,useMemo,useLayoutEffect}
|
|
|
51
54
|
return () => cancelAnimationFrame(outer);
|
|
52
55
|
}, [isPopoverOpen, sortedAsc, response, isLoading, error, streamingAssistantVisible]);
|
|
53
56
|
const copyPayload = useMemo(() => {
|
|
54
|
-
const lines = sortedAsc.map(m => m.role === 'user' ? `You:\n${m.content}` :
|
|
57
|
+
const lines = sortedAsc.map(m => m.role === 'user' ? `You:\n${m.content}` : `${assistantName}:\n${m.content}`);
|
|
55
58
|
const last = sortedAsc[sortedAsc.length - 1];
|
|
56
59
|
if (response && !(last?.role === 'assistant' && last.content === response)) {
|
|
57
|
-
lines.push(
|
|
60
|
+
lines.push(`${assistantName}:\n${response}`);
|
|
58
61
|
}
|
|
59
62
|
return lines.join('\n\n');
|
|
60
|
-
}, [sortedAsc, response]);
|
|
63
|
+
}, [sortedAsc, response, assistantName]);
|
|
61
64
|
return jsx("div", {
|
|
62
65
|
className: "relative flex-1",
|
|
63
66
|
children: jsxs(Popover, {
|
|
@@ -77,9 +80,22 @@ import {jsx,jsxs}from'react/jsx-runtime';import {useRef,useMemo,useLayoutEffect}
|
|
|
77
80
|
left: 8,
|
|
78
81
|
right: 8
|
|
79
82
|
},
|
|
80
|
-
className: cn('z-[200] flex h-[min(90vh,calc(100dvh-1rem))] flex-col overflow-hidden border
|
|
81
|
-
|
|
82
|
-
|
|
83
|
+
className: cn('relative z-[200] flex h-[min(90vh,calc(100dvh-1rem))] flex-col overflow-hidden border p-0 text-popover-foreground shadow-lg',
|
|
84
|
+
// Solid base when no wallpaper; translucent so the wallpaper bleeds through when one is selected.
|
|
85
|
+
chatBgImage ? 'bg-popover/70' : 'bg-popover', 'w-[calc(100vw-16px)] max-w-[calc(100vw-16px)] min-w-0 rounded-md'),
|
|
86
|
+
children: [chatBgImage ? jsxs(Fragment, {
|
|
87
|
+
children: [jsx("div", {
|
|
88
|
+
"aria-hidden": true,
|
|
89
|
+
className: "pointer-events-none absolute inset-0 bg-cover bg-center",
|
|
90
|
+
style: {
|
|
91
|
+
backgroundImage: `url(${chatBgImage})`
|
|
92
|
+
}
|
|
93
|
+
}), jsx("div", {
|
|
94
|
+
"aria-hidden": true,
|
|
95
|
+
className: "pointer-events-none absolute inset-0 bg-background/30 backdrop-blur-[2px]"
|
|
96
|
+
})]
|
|
97
|
+
}) : null, jsxs("div", {
|
|
98
|
+
className: "relative z-10 flex shrink-0 items-center justify-between border-b bg-muted/30 px-4 py-2",
|
|
83
99
|
children: [jsxs("div", {
|
|
84
100
|
className: "flex flex-row items-center gap-1",
|
|
85
101
|
children: [jsx("h3", {
|
|
@@ -130,7 +146,7 @@ import {jsx,jsxs}from'react/jsx-runtime';import {useRef,useMemo,useLayoutEffect}
|
|
|
130
146
|
})]
|
|
131
147
|
}), jsx("div", {
|
|
132
148
|
ref: scrollAreaRef,
|
|
133
|
-
className: cn('min-h-0 flex-1 basis-0 overflow-x-hidden overflow-y-scroll overscroll-contain', 'pr-1 [scrollbar-gutter:stable]'),
|
|
149
|
+
className: cn('relative z-10 min-h-0 flex-1 basis-0 overflow-x-hidden overflow-y-scroll overscroll-contain', 'pr-1 [scrollbar-gutter:stable]'),
|
|
134
150
|
children: jsxs("div", {
|
|
135
151
|
className: "space-y-3 p-4 pb-8",
|
|
136
152
|
children: [error ? jsxs("div", {
|
|
@@ -138,54 +154,88 @@ import {jsx,jsxs}from'react/jsx-runtime';import {useRef,useMemo,useLayoutEffect}
|
|
|
138
154
|
children: [jsx("strong", {
|
|
139
155
|
children: "Error:"
|
|
140
156
|
}), " ", error]
|
|
141
|
-
}) : null, sortedAsc.map(msg => jsx("div", {
|
|
157
|
+
}) : null, sortedAsc.map((msg, idx) => jsx("div", {
|
|
142
158
|
className: cn('flex w-full', msg.role === 'user' ? 'justify-end' : 'justify-start'),
|
|
143
|
-
children:
|
|
159
|
+
children: jsx("div", {
|
|
144
160
|
className: cn('rounded-xl px-3 py-2 text-sm shadow-sm', msg.role === 'user' ? 'max-w-[min(100%,40rem)] border border-border/60 bg-muted/70 text-foreground' : 'w-full min-w-0 max-w-full border border-border/60 bg-muted/70'),
|
|
145
|
-
children:
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
161
|
+
children: msg.role === 'user' ? jsxs(Fragment, {
|
|
162
|
+
children: [jsxs("div", {
|
|
163
|
+
className: "mb-1.5 flex items-center gap-2",
|
|
164
|
+
children: [jsx("span", {
|
|
165
|
+
className: "text-[10px] font-semibold uppercase text-muted-foreground",
|
|
166
|
+
children: "You"
|
|
167
|
+
}), jsx("span", {
|
|
168
|
+
className: "text-[11px] text-muted-foreground",
|
|
169
|
+
children: new Date(msg.timestamp).toLocaleTimeString([], {
|
|
170
|
+
hour: '2-digit',
|
|
171
|
+
minute: '2-digit'
|
|
172
|
+
})
|
|
173
|
+
})]
|
|
174
|
+
}), jsx(Markdown, {
|
|
175
|
+
children: msg.content
|
|
176
|
+
})]
|
|
177
|
+
}) : jsxs("div", {
|
|
178
|
+
className: "flex w-full gap-3",
|
|
179
|
+
children: [jsx(AssistantAvatar, {
|
|
180
|
+
avatarSrc: character?.avatarSrc ?? null,
|
|
181
|
+
index: idx + 1
|
|
182
|
+
}), jsxs("div", {
|
|
183
|
+
className: "min-w-0 flex-1",
|
|
184
|
+
children: [jsxs("div", {
|
|
185
|
+
className: "mb-1 flex items-baseline gap-2",
|
|
186
|
+
children: [jsx("span", {
|
|
187
|
+
className: "text-sm font-semibold text-foreground",
|
|
188
|
+
children: assistantName
|
|
189
|
+
}), jsx("span", {
|
|
190
|
+
className: "text-[11px] text-muted-foreground",
|
|
191
|
+
children: new Date(msg.timestamp).toLocaleTimeString([], {
|
|
192
|
+
hour: '2-digit',
|
|
193
|
+
minute: '2-digit'
|
|
194
|
+
})
|
|
195
|
+
})]
|
|
196
|
+
}), jsx(Markdown, {
|
|
197
|
+
children: msg.content
|
|
198
|
+
}), jsx(AssistantMessageActions, {
|
|
199
|
+
messageId: msg.id,
|
|
200
|
+
content: msg.content,
|
|
201
|
+
onRegenerate: regenerateAssistantMessage ? id => void regenerateAssistantMessage(id) : undefined
|
|
202
|
+
})]
|
|
156
203
|
})]
|
|
157
|
-
})
|
|
158
|
-
children: msg.content
|
|
159
|
-
}), msg.role === 'assistant' ? jsx(AssistantMessageActions, {
|
|
160
|
-
messageId: msg.id,
|
|
161
|
-
content: msg.content,
|
|
162
|
-
onRegenerate: regenerateAssistantMessage ? id => void regenerateAssistantMessage(id) : undefined
|
|
163
|
-
}) : null]
|
|
204
|
+
})
|
|
164
205
|
})
|
|
165
206
|
}, msg.id)), streamingAssistantVisible ? jsx("div", {
|
|
166
207
|
className: "flex w-full justify-start",
|
|
167
|
-
children:
|
|
208
|
+
children: jsx("div", {
|
|
168
209
|
className: "w-full min-w-0 max-w-full rounded-xl border border-border/60 bg-muted/70 px-3 py-2 text-sm shadow-sm",
|
|
169
|
-
children:
|
|
170
|
-
className: "
|
|
171
|
-
children: [jsx(
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
}),
|
|
175
|
-
className: "
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
210
|
+
children: jsxs("div", {
|
|
211
|
+
className: "flex w-full gap-3",
|
|
212
|
+
children: [jsx(AssistantAvatar, {
|
|
213
|
+
avatarSrc: character?.avatarSrc ?? null,
|
|
214
|
+
index: sortedAsc.length + 1
|
|
215
|
+
}), jsxs("div", {
|
|
216
|
+
className: "min-w-0 flex-1",
|
|
217
|
+
children: [jsxs("div", {
|
|
218
|
+
className: "mb-1 flex items-baseline gap-2",
|
|
219
|
+
children: [jsx("span", {
|
|
220
|
+
className: "text-sm font-semibold text-foreground",
|
|
221
|
+
children: assistantName
|
|
222
|
+
}), isLoading && !response ? jsx(Loader2, {
|
|
223
|
+
className: "h-3.5 w-3.5 animate-spin text-muted-foreground"
|
|
224
|
+
}) : null]
|
|
225
|
+
}), response ? jsx(Markdown, {
|
|
226
|
+
children: response
|
|
227
|
+
}) : isLoading ? jsx("p", {
|
|
228
|
+
className: "text-sm text-muted-foreground",
|
|
229
|
+
children: "Generating response\u2026"
|
|
230
|
+
}) : null, response ? jsx(AssistantMessageActions, {
|
|
231
|
+
messageId: "streaming",
|
|
232
|
+
content: response,
|
|
233
|
+
visibility: {
|
|
234
|
+
regenerate: false
|
|
235
|
+
}
|
|
236
|
+
}) : null]
|
|
237
|
+
})]
|
|
238
|
+
})
|
|
189
239
|
})
|
|
190
240
|
}) : null, jsx("div", {
|
|
191
241
|
ref: conversationEndRef,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Input.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Input.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MessageHistory.d.ts","sourceRoot":"","sources":["../../../../../src/components/AIToolbar/components/completion/MessageHistory.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"MessageHistory.d.ts","sourceRoot":"","sources":["../../../../../src/components/AIToolbar/components/completion/MessageHistory.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAM5C,UAAU,mBAAmB;IACzB,mBAAmB,EAAE,WAAW,EAAE,CAAC;IACnC,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,sBAAsB,EAAE,MAAM,IAAI,CAAC;IACnC,kBAAkB,EAAE,OAAO,CAAC;IAC5B,qBAAqB,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CAClD;AAED,eAAO,MAAM,cAAc,GAAI,6FAK5B,mBAAmB,4CAuIrB,CAAC"}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
import {jsxs,jsx}from'react/jsx-runtime';import {MessageSquareText,ChevronUp,ChevronDown}from'lucide-react';import'../../../../shardui/accordion.js';import'../../../../shardui/alert.js';import'../../../../shardui/alert-dialog.js';import'@radix-ui/react-aspect-ratio';import'../../../../shardui/avatar.js';import'../../../../shardui/badge.js';import'../../../../shardui/breadcrumb.js';import {Button}from'../../../../shardui/button.js';import'../../../../shardui/calendar.js';import'../../../../shardui/card.js';import'../../../../shardui/carousel.js';import'../../../../shardui/chart.js';import'../../../../shardui/checkbox.js';import'@radix-ui/react-collapsible';import'../../../../shardui/command.js';import'../../../../shardui/context-menu.js';import'../../../../shardui/dialog.js';import'../../../../shardui/drawer.js';import'../../../../shardui/dropdown-menu.js';import'../../../../shardui/form.js';import'../../../../shardui/hover-card.js';import'../../../../shardui/input.js';import'../../../../shardui/input-otp.js';import'../../../../shardui/label.js';import'../../../../shardui/menubar.js';import'../../../../shardui/navigation-menu.js';import'../../../../shardui/pagination.js';import {Popover,PopoverTrigger,PopoverContent}from'../../../../shardui/popover.js';import'../../../../shardui/progress.js';import'../../../../shardui/radio-group.js';import'react-resizable-panels';import'../../../../utils/isBrowser/index.js';import'clsx';import'tailwind-merge';import'react';import'fast-deep-equal/react.js';import {ScrollArea}from'../../../../shardui/scroll-area.js';import'../../../../shardui/select.js';import'../../../../shardui/separator.js';import'../../../../shardui/sheet.js';import'../../../../shardui/sidebar.js';import'../../../../shardui/slider.js';import'../../../ThemeProvider/ThemeProvider.js';import'sonner';import'../../../../shardui/switch.js';import'../../../../shardui/table.js';import'../../../../shardui/tabs.js';import'../../../../shardui/textarea.js';import'../../../../shardui/toast.js';import'../../../../shardui/toggle.js';import'../../../../shardui/toggle-group.js';import'../../../../shardui/tooltip.js';import {Markdown}from'../Markdown/index.js';const MessageHistory = ({
|
|
1
|
+
import {jsxs,jsx,Fragment}from'react/jsx-runtime';import {MessageSquareText,ChevronUp,ChevronDown}from'lucide-react';import'../../../../shardui/accordion.js';import'../../../../shardui/alert.js';import'../../../../shardui/alert-dialog.js';import'@radix-ui/react-aspect-ratio';import'../../../../shardui/avatar.js';import'../../../../shardui/badge.js';import'../../../../shardui/breadcrumb.js';import {Button}from'../../../../shardui/button.js';import'../../../../shardui/calendar.js';import'../../../../shardui/card.js';import'../../../../shardui/carousel.js';import'../../../../shardui/chart.js';import'../../../../shardui/checkbox.js';import'@radix-ui/react-collapsible';import'../../../../shardui/command.js';import'../../../../shardui/context-menu.js';import'../../../../shardui/dialog.js';import'../../../../shardui/drawer.js';import'../../../../shardui/dropdown-menu.js';import'../../../../shardui/form.js';import'../../../../shardui/hover-card.js';import'../../../../shardui/input.js';import'../../../../shardui/input-otp.js';import'../../../../shardui/label.js';import'../../../../shardui/menubar.js';import'../../../../shardui/navigation-menu.js';import'../../../../shardui/pagination.js';import {Popover,PopoverTrigger,PopoverContent}from'../../../../shardui/popover.js';import'../../../../shardui/progress.js';import'../../../../shardui/radio-group.js';import'react-resizable-panels';import'../../../../utils/isBrowser/index.js';import'clsx';import'tailwind-merge';import'react';import'fast-deep-equal/react.js';import {ScrollArea}from'../../../../shardui/scroll-area.js';import'../../../../shardui/select.js';import'../../../../shardui/separator.js';import'../../../../shardui/sheet.js';import'../../../../shardui/sidebar.js';import'../../../../shardui/slider.js';import'../../../ThemeProvider/ThemeProvider.js';import'sonner';import'../../../../shardui/switch.js';import'../../../../shardui/table.js';import'../../../../shardui/tabs.js';import'../../../../shardui/textarea.js';import'../../../../shardui/toast.js';import'../../../../shardui/toggle.js';import'../../../../shardui/toggle-group.js';import'../../../../shardui/tooltip.js';import {Markdown}from'../Markdown/index.js';import {useActiveCharacter}from'../../hooks/useActiveCharacter.js';import {useChatBackgroundImage}from'../../hooks/useChatBackgroundImage.js';import {AssistantAvatar}from'./AssistantAvatar.js';const MessageHistory = ({
|
|
2
2
|
conversationHistory,
|
|
3
3
|
onStartNewConversation,
|
|
4
4
|
messageHistoryOpen,
|
|
5
5
|
setMessageHistoryOpen
|
|
6
6
|
}) => {
|
|
7
|
+
const character = useActiveCharacter();
|
|
8
|
+
const assistantName = character?.name ?? 'AI';
|
|
9
|
+
const chatBgImage = useChatBackgroundImage();
|
|
7
10
|
return jsxs(Popover, {
|
|
8
11
|
open: messageHistoryOpen,
|
|
9
12
|
onOpenChange: setMessageHistoryOpen,
|
|
@@ -24,9 +27,20 @@ import {jsxs,jsx}from'react/jsx-runtime';import {MessageSquareText,ChevronUp,Che
|
|
|
24
27
|
}), jsxs(PopoverContent, {
|
|
25
28
|
align: "end",
|
|
26
29
|
side: "bottom",
|
|
27
|
-
className:
|
|
28
|
-
children: [
|
|
29
|
-
|
|
30
|
+
className: `relative z-[200] select-none w-screen max-h-[min(90vh,calc(100vh-1rem))] p-0 mt-3 border overflow-hidden border-input/50 ${chatBgImage ? 'bg-popover/70' : ''}`,
|
|
31
|
+
children: [chatBgImage ? jsxs(Fragment, {
|
|
32
|
+
children: [jsx("div", {
|
|
33
|
+
"aria-hidden": true,
|
|
34
|
+
className: "pointer-events-none absolute inset-0 bg-cover bg-center",
|
|
35
|
+
style: {
|
|
36
|
+
backgroundImage: `url(${chatBgImage})`
|
|
37
|
+
}
|
|
38
|
+
}), jsx("div", {
|
|
39
|
+
"aria-hidden": true,
|
|
40
|
+
className: "pointer-events-none absolute inset-0 bg-background/30 backdrop-blur-[2px]"
|
|
41
|
+
})]
|
|
42
|
+
}) : null, jsx("div", {
|
|
43
|
+
className: "relative z-10 border-b border-input/50 p-4",
|
|
30
44
|
children: jsxs("div", {
|
|
31
45
|
className: "flex items-center justify-between",
|
|
32
46
|
children: [jsxs("div", {
|
|
@@ -62,26 +76,51 @@ import {jsxs,jsx}from'react/jsx-runtime';import {MessageSquareText,ChevronUp,Che
|
|
|
62
76
|
})]
|
|
63
77
|
})
|
|
64
78
|
}), jsx(ScrollArea, {
|
|
65
|
-
className: "h-[calc(100vh-10rem)]",
|
|
79
|
+
className: "relative z-10 h-[calc(100vh-10rem)]",
|
|
66
80
|
children: jsx("div", {
|
|
67
81
|
className: "p-4 space-y-4",
|
|
68
|
-
children: conversationHistory.sort((a, b) => b?.timestamp - a?.timestamp).map(message =>
|
|
82
|
+
children: conversationHistory.sort((a, b) => b?.timestamp - a?.timestamp).map((message, descIdx, arr) => jsx("div", {
|
|
69
83
|
className: `p-3 rounded-lg ${message.role === 'user' ? 'bg-primary/10 border-l-4 border-primary' : 'bg-muted/50'}`,
|
|
70
|
-
children:
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
84
|
+
children: message.role === 'user' ? jsxs(Fragment, {
|
|
85
|
+
children: [jsxs("div", {
|
|
86
|
+
className: "mb-2 flex items-center gap-2",
|
|
87
|
+
children: [jsx("span", {
|
|
88
|
+
className: "text-xs font-medium uppercase text-muted-foreground",
|
|
89
|
+
children: "You"
|
|
90
|
+
}), jsx("span", {
|
|
91
|
+
className: "text-xs text-muted-foreground",
|
|
92
|
+
children: new Date(message.timestamp).toLocaleTimeString([], {
|
|
93
|
+
hour: '2-digit',
|
|
94
|
+
minute: '2-digit'
|
|
95
|
+
})
|
|
96
|
+
})]
|
|
97
|
+
}), jsx(Markdown, {
|
|
98
|
+
children: message.content
|
|
81
99
|
})]
|
|
82
|
-
})
|
|
83
|
-
|
|
84
|
-
|
|
100
|
+
}) : jsxs("div", {
|
|
101
|
+
className: "flex w-full gap-3",
|
|
102
|
+
children: [jsx(AssistantAvatar, {
|
|
103
|
+
avatarSrc: character?.avatarSrc ?? null,
|
|
104
|
+
index: arr.length - descIdx
|
|
105
|
+
}), jsxs("div", {
|
|
106
|
+
className: "min-w-0 flex-1",
|
|
107
|
+
children: [jsxs("div", {
|
|
108
|
+
className: "mb-1 flex items-baseline gap-2",
|
|
109
|
+
children: [jsx("span", {
|
|
110
|
+
className: "text-sm font-semibold text-foreground",
|
|
111
|
+
children: assistantName
|
|
112
|
+
}), jsx("span", {
|
|
113
|
+
className: "text-xs text-muted-foreground",
|
|
114
|
+
children: new Date(message.timestamp).toLocaleTimeString([], {
|
|
115
|
+
hour: '2-digit',
|
|
116
|
+
minute: '2-digit'
|
|
117
|
+
})
|
|
118
|
+
})]
|
|
119
|
+
}), jsx(Markdown, {
|
|
120
|
+
children: message.content
|
|
121
|
+
})]
|
|
122
|
+
})]
|
|
123
|
+
})
|
|
85
124
|
}, message.id))
|
|
86
125
|
})
|
|
87
126
|
})]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MessageHistory.js","sources":["../../../../../src/components/AIToolbar/components/completion/MessageHistory.tsx"],"sourcesContent":[null],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"MessageHistory.js","sources":["../../../../../src/components/AIToolbar/components/completion/MessageHistory.tsx"],"sourcesContent":[null],"names":[],"mappings":"i1EAcC,MAAA,cAAA,GAAA,CAAA;AAED,EAAA,mBAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ResultsSection.d.ts","sourceRoot":"","sources":["../../../../../src/components/AIToolbar/components/speech/ResultsSection.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"ResultsSection.d.ts","sourceRoot":"","sources":["../../../../../src/components/AIToolbar/components/speech/ResultsSection.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAQjD,KAAK,KAAK,GAAG;IACT,iBAAiB,EAAE,MAAM,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,OAAO,CAAC;IACxB,YAAY,EAAE,gBAAgB,CAAC;IAC/B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,mBAAmB,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CAChD,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,6GAO5B,KAAK,4CAiJP,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {jsxs,jsx}from'react/jsx-runtime';import {Markdown}from'../Markdown/index.js';import'../../../../shardui/accordion.js';import'../../../../shardui/alert.js';import'../../../../shardui/alert-dialog.js';import'@radix-ui/react-aspect-ratio';import'../../../../shardui/avatar.js';import'../../../../shardui/badge.js';import'../../../../shardui/breadcrumb.js';import'../../../../shardui/button.js';import'../../../../shardui/calendar.js';import'../../../../shardui/card.js';import'../../../../shardui/carousel.js';import'../../../../shardui/chart.js';import'../../../../shardui/checkbox.js';import'@radix-ui/react-collapsible';import'../../../../shardui/command.js';import'../../../../shardui/context-menu.js';import'../../../../shardui/dialog.js';import'../../../../shardui/drawer.js';import'../../../../shardui/dropdown-menu.js';import'../../../../shardui/form.js';import'../../../../shardui/hover-card.js';import'../../../../shardui/input.js';import'../../../../shardui/input-otp.js';import'../../../../shardui/label.js';import'../../../../shardui/menubar.js';import'../../../../shardui/navigation-menu.js';import'../../../../shardui/pagination.js';import'../../../../shardui/popover.js';import'../../../../shardui/progress.js';import'../../../../shardui/radio-group.js';import {SparklesIcon,Loader2,BotIcon,HeadphonesIcon}from'lucide-react';import'react-resizable-panels';import'../../../../utils/isBrowser/index.js';import {cn}from'../../../../utils/util.js';import'react';import'fast-deep-equal/react.js';import'../../../../shardui/scroll-area.js';import'../../../../shardui/select.js';import'../../../../shardui/separator.js';import'../../../../shardui/sheet.js';import'../../../../shardui/sidebar.js';import'../../../../shardui/slider.js';import'../../../ThemeProvider/ThemeProvider.js';import'sonner';import {Switch}from'../../../../shardui/switch.js';import'../../../../shardui/table.js';import'../../../../shardui/tabs.js';import'../../../../shardui/textarea.js';import'../../../../shardui/toast.js';import'../../../../shardui/toggle.js';import'../../../../shardui/toggle-group.js';import'../../../../shardui/tooltip.js';import {CopyButton}from'../Markdown/copy-button.js';const ResultsSection = ({
|
|
1
|
+
import {jsxs,jsx}from'react/jsx-runtime';import {Markdown}from'../Markdown/index.js';import'../../../../shardui/accordion.js';import'../../../../shardui/alert.js';import'../../../../shardui/alert-dialog.js';import'@radix-ui/react-aspect-ratio';import'../../../../shardui/avatar.js';import'../../../../shardui/badge.js';import'../../../../shardui/breadcrumb.js';import'../../../../shardui/button.js';import'../../../../shardui/calendar.js';import'../../../../shardui/card.js';import'../../../../shardui/carousel.js';import'../../../../shardui/chart.js';import'../../../../shardui/checkbox.js';import'@radix-ui/react-collapsible';import'../../../../shardui/command.js';import'../../../../shardui/context-menu.js';import'../../../../shardui/dialog.js';import'../../../../shardui/drawer.js';import'../../../../shardui/dropdown-menu.js';import'../../../../shardui/form.js';import'../../../../shardui/hover-card.js';import'../../../../shardui/input.js';import'../../../../shardui/input-otp.js';import'../../../../shardui/label.js';import'../../../../shardui/menubar.js';import'../../../../shardui/navigation-menu.js';import'../../../../shardui/pagination.js';import'../../../../shardui/popover.js';import'../../../../shardui/progress.js';import'../../../../shardui/radio-group.js';import {SparklesIcon,Loader2,BotIcon,HeadphonesIcon}from'lucide-react';import'react-resizable-panels';import'../../../../utils/isBrowser/index.js';import {cn}from'../../../../utils/util.js';import'react';import'fast-deep-equal/react.js';import'../../../../shardui/scroll-area.js';import'../../../../shardui/select.js';import'../../../../shardui/separator.js';import'../../../../shardui/sheet.js';import'../../../../shardui/sidebar.js';import'../../../../shardui/slider.js';import'../../../ThemeProvider/ThemeProvider.js';import'sonner';import {Switch}from'../../../../shardui/switch.js';import'../../../../shardui/table.js';import'../../../../shardui/tabs.js';import'../../../../shardui/textarea.js';import'../../../../shardui/toast.js';import'../../../../shardui/toggle.js';import'../../../../shardui/toggle-group.js';import'../../../../shardui/tooltip.js';import {CopyButton}from'../Markdown/copy-button.js';import {useActiveCharacter}from'../../hooks/useActiveCharacter.js';const ResultsSection = ({
|
|
2
2
|
lastTranscription,
|
|
3
3
|
lastAIResponse,
|
|
4
4
|
isAIProcessing,
|
|
@@ -6,6 +6,8 @@ import {jsxs,jsx}from'react/jsx-runtime';import {Markdown}from'../Markdown/index
|
|
|
6
6
|
conversationMode,
|
|
7
7
|
setConversationMode
|
|
8
8
|
}) => {
|
|
9
|
+
const character = useActiveCharacter();
|
|
10
|
+
const assistantName = character?.name ?? 'AI';
|
|
9
11
|
const hasResponse = lastAIResponse || isAIProcessing;
|
|
10
12
|
const hasHistory = conversation.messages.length > 2;
|
|
11
13
|
if (!hasResponse && !lastTranscription) {
|
|
@@ -70,11 +72,19 @@ import {jsxs,jsx}from'react/jsx-runtime';import {Markdown}from'../Markdown/index
|
|
|
70
72
|
className: "rounded-md bg-background/50 p-2.5",
|
|
71
73
|
children: [jsxs("div", {
|
|
72
74
|
className: "flex items-center gap-1.5 mb-1",
|
|
73
|
-
children: [jsx(
|
|
75
|
+
children: [character?.avatarSrc ? jsx("img", {
|
|
76
|
+
src: character.avatarSrc,
|
|
77
|
+
alt: "",
|
|
78
|
+
"aria-hidden": "true",
|
|
79
|
+
draggable: false,
|
|
80
|
+
width: 14,
|
|
81
|
+
height: 14,
|
|
82
|
+
className: "h-3.5 w-3.5 rounded-full object-cover ring-1 ring-border/60"
|
|
83
|
+
}) : jsx(BotIcon, {
|
|
74
84
|
className: "h-3 w-3 text-muted-foreground"
|
|
75
85
|
}), jsx("span", {
|
|
76
86
|
className: "text-[9px] font-medium text-muted-foreground uppercase tracking-wide",
|
|
77
|
-
children:
|
|
87
|
+
children: assistantName
|
|
78
88
|
})]
|
|
79
89
|
}), isAIProcessing && !lastAIResponse ? jsxs("div", {
|
|
80
90
|
className: "flex items-center gap-2",
|
|
@@ -117,7 +127,7 @@ import {jsxs,jsx}from'react/jsx-runtime';import {Markdown}from'../Markdown/index
|
|
|
117
127
|
className: cn('p-2 rounded-md text-[11px]', message.role === 'user' ? 'bg-primary/5 border-l-2 border-primary/30' : 'bg-background/50'),
|
|
118
128
|
children: [jsx("span", {
|
|
119
129
|
className: "text-[8px] font-medium text-muted-foreground uppercase",
|
|
120
|
-
children: message.role === 'user' ? 'System' :
|
|
130
|
+
children: message.role === 'user' ? 'System' : assistantName
|
|
121
131
|
}), jsx("div", {
|
|
122
132
|
className: "text-muted-foreground leading-relaxed mt-0.5",
|
|
123
133
|
children: jsx(Markdown, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ResultsSection.js","sources":["../../../../../src/components/AIToolbar/components/speech/ResultsSection.tsx"],"sourcesContent":[null],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ResultsSection.js","sources":["../../../../../src/components/AIToolbar/components/speech/ResultsSection.tsx"],"sourcesContent":[null],"names":[],"mappings":"4sEAcI,MAAA,cAAsB,GAAI;EAC5B,iBAAA;AAEF,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface ActiveCharacter {
|
|
2
|
+
/** Manifest `name` (or filesystem stem) — e.g. "Seraphina". */
|
|
3
|
+
name: string;
|
|
4
|
+
/** PNG card filename without extension — used to fetch avatar / sprites. */
|
|
5
|
+
fileName?: string;
|
|
6
|
+
/** Pre-baked `data:` URL for the avatar PNG, or null if not yet loaded. */
|
|
7
|
+
avatarSrc: string | null;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Return the first discovered character (name + avatar) or null when no
|
|
11
|
+
* character extension is installed / we're not running under Tauri.
|
|
12
|
+
*
|
|
13
|
+
* Today the desktop ships at most one active character at a time, so we just
|
|
14
|
+
* pick the first entry. When multi-character support lands we'll switch this
|
|
15
|
+
* to read from a presence bus.
|
|
16
|
+
*/
|
|
17
|
+
export declare function useActiveCharacter(): ActiveCharacter | null;
|
|
18
|
+
//# sourceMappingURL=useActiveCharacter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useActiveCharacter.d.ts","sourceRoot":"","sources":["../../../../src/components/AIToolbar/hooks/useActiveCharacter.ts"],"names":[],"mappings":"AAqBA,MAAM,WAAW,eAAe;IAC5B,+DAA+D;IAC/D,IAAI,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2EAA2E;IAC3E,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAkDD;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,IAAI,eAAe,GAAG,IAAI,CA8C3D"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import*as React from'react';// Active-character lookup for the AIToolbar.
|
|
2
|
+
//
|
|
3
|
+
// Surfaces the currently-installed character (name + avatar data URL) so the
|
|
4
|
+
// completion popover and message history can show "Seraphina" with her avatar
|
|
5
|
+
// instead of a generic "AI" label. Backed by the desktop Tauri commands
|
|
6
|
+
// `character_list` and `character_get_avatar` (see
|
|
7
|
+
// `yantra-app/portable-devices/desktop/src-tauri/src/features/character_feature/`).
|
|
8
|
+
//
|
|
9
|
+
// Degrades gracefully:
|
|
10
|
+
// - Outside Tauri (regular browser, SSR): returns null synchronously.
|
|
11
|
+
// - Tauri without any character-contributing extension installed: returns null.
|
|
12
|
+
// - Tauri with an extension but no avatar: returns name-only (avatarSrc = null).
|
|
13
|
+
//
|
|
14
|
+
// Re-fetches on the `yantra:character-refresh` Tauri event, which the desktop
|
|
15
|
+
// shell emits after the marketplace install/uninstall path triggers
|
|
16
|
+
// `character_refresh`. Hook will quietly stay current as extensions come and go.
|
|
17
|
+
// constants
|
|
18
|
+
const CHARACTER_REFRESH_EVENT = 'yantra:character-refresh';
|
|
19
|
+
// helpers
|
|
20
|
+
function isTauri() {
|
|
21
|
+
if (typeof window === 'undefined') return false;
|
|
22
|
+
const w = window;
|
|
23
|
+
return Boolean(w.__TAURI_INTERNALS__ ?? w.__TAURI__);
|
|
24
|
+
}
|
|
25
|
+
async function safeInvoke(cmd, args) {
|
|
26
|
+
if (!isTauri()) return null;
|
|
27
|
+
try {
|
|
28
|
+
// @ts-ignore — optional dynamic import, present as a peer dep in Tauri builds.
|
|
29
|
+
const mod = await import('@tauri-apps/api/core');
|
|
30
|
+
return await mod.invoke(cmd, args);
|
|
31
|
+
} catch {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
async function safeListen(event, cb) {
|
|
36
|
+
if (!isTauri()) return () => {};
|
|
37
|
+
try {
|
|
38
|
+
// @ts-ignore — see safeInvoke note.
|
|
39
|
+
const mod = await import('@tauri-apps/api/event');
|
|
40
|
+
const unlisten = await mod.listen(event, e => cb(e.payload));
|
|
41
|
+
return unlisten;
|
|
42
|
+
} catch {
|
|
43
|
+
return () => {};
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// main API
|
|
47
|
+
/**
|
|
48
|
+
* Return the first discovered character (name + avatar) or null when no
|
|
49
|
+
* character extension is installed / we're not running under Tauri.
|
|
50
|
+
*
|
|
51
|
+
* Today the desktop ships at most one active character at a time, so we just
|
|
52
|
+
* pick the first entry. When multi-character support lands we'll switch this
|
|
53
|
+
* to read from a presence bus.
|
|
54
|
+
*/
|
|
55
|
+
function useActiveCharacter() {
|
|
56
|
+
const [character, setCharacter] = React.useState(null);
|
|
57
|
+
const [avatarSrc, setAvatarSrc] = React.useState(null);
|
|
58
|
+
const reload = React.useCallback(async () => {
|
|
59
|
+
const list = await safeInvoke('character_list', {
|
|
60
|
+
shallow: false
|
|
61
|
+
});
|
|
62
|
+
setCharacter(list?.[0] ?? null);
|
|
63
|
+
}, []);
|
|
64
|
+
React.useEffect(() => {
|
|
65
|
+
void reload();
|
|
66
|
+
}, [reload]);
|
|
67
|
+
React.useEffect(() => {
|
|
68
|
+
let unlisten = null;
|
|
69
|
+
let cancelled = false;
|
|
70
|
+
safeListen(CHARACTER_REFRESH_EVENT, () => {
|
|
71
|
+
void reload();
|
|
72
|
+
}).then(fn => {
|
|
73
|
+
if (cancelled) fn();else unlisten = fn;
|
|
74
|
+
});
|
|
75
|
+
return () => {
|
|
76
|
+
cancelled = true;
|
|
77
|
+
if (unlisten) unlisten();
|
|
78
|
+
};
|
|
79
|
+
}, [reload]);
|
|
80
|
+
React.useEffect(() => {
|
|
81
|
+
if (!character?.file_name) {
|
|
82
|
+
setAvatarSrc(null);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
let alive = true;
|
|
86
|
+
safeInvoke('character_get_avatar', {
|
|
87
|
+
fileName: character.file_name
|
|
88
|
+
}).then(dto => {
|
|
89
|
+
if (!alive) return;
|
|
90
|
+
const valid = dto && dto.base64 && dto.base64.length > 100;
|
|
91
|
+
setAvatarSrc(valid ? `data:${dto.mime_type || 'image/png'};base64,${dto.base64}` : null);
|
|
92
|
+
});
|
|
93
|
+
return () => {
|
|
94
|
+
alive = false;
|
|
95
|
+
};
|
|
96
|
+
}, [character?.file_name]);
|
|
97
|
+
if (!character) return null;
|
|
98
|
+
return {
|
|
99
|
+
name: character.name,
|
|
100
|
+
fileName: character.file_name,
|
|
101
|
+
avatarSrc
|
|
102
|
+
};
|
|
103
|
+
}export{useActiveCharacter};//# sourceMappingURL=useActiveCharacter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useActiveCharacter.js","sources":["../../../../src/components/AIToolbar/hooks/useActiveCharacter.ts"],"sourcesContent":[null],"names":[],"mappings":"4BAqBA;;;;;;AAMI;AACH;AAkDD;;;;;;;AAOG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns the current chat-background image as a `data:` URL, or `null` when
|
|
3
|
+
* no wallpaper is selected / we are not running under Tauri.
|
|
4
|
+
*
|
|
5
|
+
* Re-fetches whenever the user picks a different wallpaper, regardless of
|
|
6
|
+
* which webview the picker lives in.
|
|
7
|
+
*/
|
|
8
|
+
export declare function useChatBackgroundImage(): string | null;
|
|
9
|
+
export default useChatBackgroundImage;
|
|
10
|
+
//# sourceMappingURL=useChatBackgroundImage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useChatBackgroundImage.d.ts","sourceRoot":"","sources":["../../../../src/components/AIToolbar/hooks/useChatBackgroundImage.ts"],"names":[],"mappings":"AA4EA;;;;;;GAMG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,GAAG,IAAI,CA+DtD;AAED,eAAe,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import*as React from'react';// Chat-background image lookup for AIToolbar surfaces.
|
|
2
|
+
//
|
|
3
|
+
// The desktop app lets users pick a wallpaper that paints behind the `/chat`
|
|
4
|
+
// route. The toolbar's Conversation popover and Message History popover render
|
|
5
|
+
// in Radix portals (outside the chat tree), so the wallpaper does not bleed
|
|
6
|
+
// through to them by default. This hook re-subscribes to the same contract
|
|
7
|
+
// `yantra-app/packages-modules/account/browser/src/hooks/useChatBackground.tsx`
|
|
8
|
+
// already publishes:
|
|
9
|
+
//
|
|
10
|
+
// - localStorage key `yantra:chat-background:selected-id` → currently-selected background ID
|
|
11
|
+
// - cross-webview event `yantra:chat-background-change` → fan-out when the picker mutates the selection
|
|
12
|
+
// - Tauri command `background_get` { id } → returns { mime_type, base64 }
|
|
13
|
+
//
|
|
14
|
+
// Reusing the same key/event lets the popovers stay in lock-step with the
|
|
15
|
+
// `/chat` overlay without yantra-app having to inject anything through props.
|
|
16
|
+
//
|
|
17
|
+
// Degrades gracefully:
|
|
18
|
+
// - Outside Tauri (regular browser, SSR): returns null synchronously.
|
|
19
|
+
// - No selection / unknown ID: returns null.
|
|
20
|
+
// - Selection changes mid-session: re-fetches automatically.
|
|
21
|
+
// constants
|
|
22
|
+
const SELECTED_BG_STORAGE_KEY = 'yantra:chat-background:selected-id';
|
|
23
|
+
const BG_CHANGE_EVENT = 'yantra:chat-background-change';
|
|
24
|
+
// helpers
|
|
25
|
+
function isTauri() {
|
|
26
|
+
if (typeof window === 'undefined') return false;
|
|
27
|
+
const w = window;
|
|
28
|
+
return Boolean(w.__TAURI_INTERNALS__ ?? w.__TAURI__);
|
|
29
|
+
}
|
|
30
|
+
async function safeInvoke(cmd, args) {
|
|
31
|
+
if (!isTauri()) return null;
|
|
32
|
+
try {
|
|
33
|
+
// @ts-ignore — optional dynamic import, present as a peer dep in Tauri builds.
|
|
34
|
+
const mod = await import('@tauri-apps/api/core');
|
|
35
|
+
return await mod.invoke(cmd, args);
|
|
36
|
+
} catch {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
async function safeListen(event, cb) {
|
|
41
|
+
if (!isTauri()) return () => {};
|
|
42
|
+
try {
|
|
43
|
+
// @ts-ignore — see safeInvoke note.
|
|
44
|
+
const mod = await import('@tauri-apps/api/event');
|
|
45
|
+
const unlisten = await mod.listen(event, e => cb(e.payload));
|
|
46
|
+
return unlisten;
|
|
47
|
+
} catch {
|
|
48
|
+
return () => {};
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function readSelectedId() {
|
|
52
|
+
if (typeof window === 'undefined') return null;
|
|
53
|
+
try {
|
|
54
|
+
return window.localStorage.getItem(SELECTED_BG_STORAGE_KEY);
|
|
55
|
+
} catch {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// main API
|
|
60
|
+
/**
|
|
61
|
+
* Returns the current chat-background image as a `data:` URL, or `null` when
|
|
62
|
+
* no wallpaper is selected / we are not running under Tauri.
|
|
63
|
+
*
|
|
64
|
+
* Re-fetches whenever the user picks a different wallpaper, regardless of
|
|
65
|
+
* which webview the picker lives in.
|
|
66
|
+
*/
|
|
67
|
+
function useChatBackgroundImage() {
|
|
68
|
+
const [selectedId, setSelectedId] = React.useState(() => readSelectedId());
|
|
69
|
+
const [imageUrl, setImageUrl] = React.useState(null);
|
|
70
|
+
// Subscribe to selection changes from three possible sources:
|
|
71
|
+
// (a) same-window `dispatchEvent` (picker on this webview).
|
|
72
|
+
// (b) cross-tab `storage` event (rare in the Tauri shell but free).
|
|
73
|
+
// (c) Tauri `listen` (picker on the *other* webview — desktop-bar vs dashboard).
|
|
74
|
+
React.useEffect(() => {
|
|
75
|
+
function localHandler(e) {
|
|
76
|
+
const detail = e.detail;
|
|
77
|
+
setSelectedId(detail?.id ?? null);
|
|
78
|
+
}
|
|
79
|
+
function storageHandler(e) {
|
|
80
|
+
if (e.key !== SELECTED_BG_STORAGE_KEY) return;
|
|
81
|
+
setSelectedId(e.newValue);
|
|
82
|
+
}
|
|
83
|
+
if (typeof window !== 'undefined') {
|
|
84
|
+
window.addEventListener(BG_CHANGE_EVENT, localHandler);
|
|
85
|
+
window.addEventListener('storage', storageHandler);
|
|
86
|
+
}
|
|
87
|
+
let unlisten = null;
|
|
88
|
+
let cancelled = false;
|
|
89
|
+
safeListen(BG_CHANGE_EVENT, payload => {
|
|
90
|
+
setSelectedId(payload?.id ?? null);
|
|
91
|
+
}).then(fn => {
|
|
92
|
+
if (cancelled) fn();else unlisten = fn;
|
|
93
|
+
});
|
|
94
|
+
return () => {
|
|
95
|
+
cancelled = true;
|
|
96
|
+
if (typeof window !== 'undefined') {
|
|
97
|
+
window.removeEventListener(BG_CHANGE_EVENT, localHandler);
|
|
98
|
+
window.removeEventListener('storage', storageHandler);
|
|
99
|
+
}
|
|
100
|
+
if (unlisten) unlisten();
|
|
101
|
+
};
|
|
102
|
+
}, []);
|
|
103
|
+
// Resolve ID → data URL. Tauri returns base64 — we only build the data URL
|
|
104
|
+
// once per ID change to avoid churning the popover background.
|
|
105
|
+
React.useEffect(() => {
|
|
106
|
+
if (!selectedId) {
|
|
107
|
+
setImageUrl(null);
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
let alive = true;
|
|
111
|
+
safeInvoke('background_get', {
|
|
112
|
+
id: selectedId
|
|
113
|
+
}).then(dto => {
|
|
114
|
+
if (!alive) return;
|
|
115
|
+
if (dto && dto.base64) {
|
|
116
|
+
setImageUrl(`data:${dto.mime_type || 'image/png'};base64,${dto.base64}`);
|
|
117
|
+
} else {
|
|
118
|
+
setImageUrl(null);
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
return () => {
|
|
122
|
+
alive = false;
|
|
123
|
+
};
|
|
124
|
+
}, [selectedId]);
|
|
125
|
+
return imageUrl;
|
|
126
|
+
}export{useChatBackgroundImage};//# sourceMappingURL=useChatBackgroundImage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useChatBackgroundImage.js","sources":["../../../../src/components/AIToolbar/hooks/useChatBackgroundImage.ts"],"sourcesContent":[null],"names":[],"mappings":"4BA4EA;;;;;;AAMG;AACH;AAiEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@admin-layout/tailwind-ui",
|
|
3
|
-
"version": "12.2.4-alpha.
|
|
3
|
+
"version": "12.2.4-alpha.56",
|
|
4
4
|
"description": "Sample core for higher packages to depend on",
|
|
5
5
|
"license": "ISC",
|
|
6
6
|
"author": "CDMBase LLC",
|
|
@@ -96,5 +96,5 @@
|
|
|
96
96
|
"typescript": {
|
|
97
97
|
"definition": "lib/index.d.ts"
|
|
98
98
|
},
|
|
99
|
-
"gitHead": "
|
|
99
|
+
"gitHead": "61757b2c770347ae8d91008b4d2b366fd363e299"
|
|
100
100
|
}
|