@mordn/chat-widget 0.9.0 → 0.10.1
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/dist/{chat-store-DdykLpDo.d.mts → chat-store-Dq1Zy_qV.d.mts} +1 -1
- package/dist/{chat-store-DdykLpDo.d.ts → chat-store-Dq1Zy_qV.d.ts} +1 -1
- package/dist/handler-types-Bil94kTX.d.ts +204 -0
- package/dist/handler-types-CCSjDZZ9.d.mts +204 -0
- package/dist/index.d.mts +44 -5
- package/dist/index.d.ts +44 -5
- package/dist/index.js +127 -80
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +127 -81
- package/dist/index.mjs.map +1 -1
- package/dist/models.d.mts +6 -0
- package/dist/models.d.ts +6 -0
- package/dist/models.js +75 -0
- package/dist/models.js.map +1 -0
- package/dist/models.mjs +50 -0
- package/dist/models.mjs.map +1 -0
- package/dist/server/drizzle/index.d.mts +1 -1
- package/dist/server/drizzle/index.d.ts +1 -1
- package/dist/server/hosted/index.d.mts +14 -2
- package/dist/server/hosted/index.d.ts +14 -2
- package/dist/server/hosted/index.js +36 -0
- package/dist/server/hosted/index.js.map +1 -1
- package/dist/server/hosted/index.mjs +35 -0
- package/dist/server/hosted/index.mjs.map +1 -1
- package/dist/server/index.d.mts +6 -180
- package/dist/server/index.d.ts +6 -180
- package/dist/server/index.js +26 -11
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +26 -11
- package/dist/server/index.mjs.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +6 -1
package/dist/index.mjs
CHANGED
|
@@ -560,14 +560,32 @@ var PromptInputBody = ({
|
|
|
560
560
|
className,
|
|
561
561
|
...props
|
|
562
562
|
}) => /* @__PURE__ */ jsx8("div", { className: cn(className, "flex flex-col"), ...props });
|
|
563
|
+
var TEXTAREA_MIN_HEIGHT = 28;
|
|
564
|
+
var TEXTAREA_MAX_HEIGHT = 192;
|
|
563
565
|
var PromptInputTextarea = React2.forwardRef(({
|
|
564
566
|
onChange,
|
|
565
567
|
onKeyDown: externalOnKeyDown,
|
|
566
568
|
className,
|
|
567
569
|
placeholder = "What would you like to know?",
|
|
570
|
+
value,
|
|
568
571
|
...props
|
|
569
572
|
}, ref) => {
|
|
570
573
|
const attachments = usePromptInputAttachments();
|
|
574
|
+
const innerRef = useRef(null);
|
|
575
|
+
const setRefs = (node) => {
|
|
576
|
+
innerRef.current = node;
|
|
577
|
+
if (typeof ref === "function") ref(node);
|
|
578
|
+
else if (ref) ref.current = node;
|
|
579
|
+
};
|
|
580
|
+
const resize = () => {
|
|
581
|
+
const el = innerRef.current;
|
|
582
|
+
if (!el) return;
|
|
583
|
+
el.style.height = "auto";
|
|
584
|
+
const next = Math.min(el.scrollHeight, TEXTAREA_MAX_HEIGHT);
|
|
585
|
+
el.style.height = `${Math.max(next, TEXTAREA_MIN_HEIGHT)}px`;
|
|
586
|
+
el.style.overflowY = el.scrollHeight > TEXTAREA_MAX_HEIGHT ? "auto" : "hidden";
|
|
587
|
+
};
|
|
588
|
+
useLayoutEffect(resize, [value]);
|
|
571
589
|
const handleKeyDown = (e) => {
|
|
572
590
|
externalOnKeyDown?.(e);
|
|
573
591
|
if (e.defaultPrevented) return;
|
|
@@ -607,17 +625,19 @@ var PromptInputTextarea = React2.forwardRef(({
|
|
|
607
625
|
return /* @__PURE__ */ jsx8(
|
|
608
626
|
Textarea,
|
|
609
627
|
{
|
|
610
|
-
ref,
|
|
628
|
+
ref: setRefs,
|
|
629
|
+
rows: 1,
|
|
630
|
+
value,
|
|
611
631
|
className: cn(
|
|
612
|
-
"w-full resize-none rounded-none border-none
|
|
613
|
-
"field-sizing-content",
|
|
614
|
-
"max-h-48 min-h-16",
|
|
632
|
+
"w-full resize-none rounded-none border-none px-3 py-2.5 shadow-none outline-none ring-0",
|
|
615
633
|
"focus-visible:ring-0 focus-visible:shadow-none focus:ring-0 focus:shadow-none",
|
|
616
634
|
className
|
|
617
635
|
),
|
|
636
|
+
style: { minHeight: TEXTAREA_MIN_HEIGHT, maxHeight: TEXTAREA_MAX_HEIGHT, overflowY: "hidden" },
|
|
618
637
|
name: "message",
|
|
619
638
|
onChange: (e) => {
|
|
620
639
|
onChange?.(e);
|
|
640
|
+
resize();
|
|
621
641
|
},
|
|
622
642
|
onKeyDown: handleKeyDown,
|
|
623
643
|
onPaste: handlePaste,
|
|
@@ -627,30 +647,6 @@ var PromptInputTextarea = React2.forwardRef(({
|
|
|
627
647
|
);
|
|
628
648
|
});
|
|
629
649
|
PromptInputTextarea.displayName = "PromptInputTextarea";
|
|
630
|
-
var PromptInputToolbar = ({
|
|
631
|
-
className,
|
|
632
|
-
...props
|
|
633
|
-
}) => /* @__PURE__ */ jsx8(
|
|
634
|
-
"div",
|
|
635
|
-
{
|
|
636
|
-
className: cn("flex items-center justify-between p-1", className),
|
|
637
|
-
...props
|
|
638
|
-
}
|
|
639
|
-
);
|
|
640
|
-
var PromptInputTools = ({
|
|
641
|
-
className,
|
|
642
|
-
...props
|
|
643
|
-
}) => /* @__PURE__ */ jsx8(
|
|
644
|
-
"div",
|
|
645
|
-
{
|
|
646
|
-
className: cn(
|
|
647
|
-
"flex items-center gap-1",
|
|
648
|
-
"[&_button:first-child]:rounded-bl-xl",
|
|
649
|
-
className
|
|
650
|
-
),
|
|
651
|
-
...props
|
|
652
|
-
}
|
|
653
|
-
);
|
|
654
650
|
var PromptInputButton = ({
|
|
655
651
|
variant = "ghost",
|
|
656
652
|
className,
|
|
@@ -1199,7 +1195,7 @@ function ActionButton({ onClick, disabled, ariaLabel, children }) {
|
|
|
1199
1195
|
|
|
1200
1196
|
// src/components/interface.tsx
|
|
1201
1197
|
import { useState as useState6, useEffect as useEffect5, useRef as useRef4, useMemo as useMemo3, useCallback as useCallback4 } from "react";
|
|
1202
|
-
import { HistoryIcon, MessageSquareIcon, SearchIcon, ChevronRightIcon as ChevronRightIcon2, PlusIcon as PlusIcon2, XIcon as XIcon3 } from "lucide-react";
|
|
1198
|
+
import { HistoryIcon, MessageSquareIcon, SearchIcon, ChevronRightIcon as ChevronRightIcon2, PaperclipIcon as PaperclipIcon2, PlusIcon as PlusIcon2, XIcon as XIcon3 } from "lucide-react";
|
|
1203
1199
|
import { Fragment as Fragment5 } from "react";
|
|
1204
1200
|
import { useChat } from "@ai-sdk/react";
|
|
1205
1201
|
import { DefaultChatTransport } from "ai";
|
|
@@ -1906,24 +1902,38 @@ function StarterMessageItem({
|
|
|
1906
1902
|
import { createContext as createContext4, useContext as useContext4 } from "react";
|
|
1907
1903
|
import { jsx as jsx22 } from "react/jsx-runtime";
|
|
1908
1904
|
var ChatStorageContext = createContext4({
|
|
1909
|
-
storageKeyPrefix:
|
|
1905
|
+
storageKeyPrefix: null
|
|
1910
1906
|
});
|
|
1911
1907
|
function ChatStorageProvider({
|
|
1912
1908
|
children,
|
|
1913
|
-
userId
|
|
1909
|
+
userId,
|
|
1910
|
+
agentId
|
|
1914
1911
|
}) {
|
|
1915
|
-
const storageKeyPrefix = userId
|
|
1912
|
+
const storageKeyPrefix = userId && agentId ? `${encodeURIComponent(agentId)}|${encodeURIComponent(userId)}` : null;
|
|
1916
1913
|
return /* @__PURE__ */ jsx22(ChatStorageContext.Provider, { value: { storageKeyPrefix }, children });
|
|
1917
1914
|
}
|
|
1918
1915
|
function useChatStorageKey() {
|
|
1919
1916
|
return useContext4(ChatStorageContext);
|
|
1920
1917
|
}
|
|
1918
|
+
function clearChatStorage(opts) {
|
|
1919
|
+
if (typeof window === "undefined" || !window.localStorage) return;
|
|
1920
|
+
const scopedPrefix = opts?.agentId && opts?.userId ? `chat-${encodeURIComponent(opts.agentId)}|${encodeURIComponent(opts.userId)}-` : null;
|
|
1921
|
+
const toRemove = [];
|
|
1922
|
+
for (let i = 0; i < localStorage.length; i++) {
|
|
1923
|
+
const key = localStorage.key(i);
|
|
1924
|
+
if (!key) continue;
|
|
1925
|
+
if (scopedPrefix ? key.startsWith(scopedPrefix) : key.startsWith("chat-")) {
|
|
1926
|
+
toRemove.push(key);
|
|
1927
|
+
}
|
|
1928
|
+
}
|
|
1929
|
+
toRemove.forEach((key) => localStorage.removeItem(key));
|
|
1930
|
+
}
|
|
1921
1931
|
|
|
1922
1932
|
// src/components/interface.tsx
|
|
1923
1933
|
import { jsx as jsx23, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
1924
1934
|
function ChatInterface({ id, initialMessages, config, onClose, headerActions } = {}) {
|
|
1925
1935
|
const { storageKeyPrefix } = useChatStorageKey();
|
|
1926
|
-
const storageKey = (key) => storageKeyPrefix ? `chat-${storageKeyPrefix}-${key}` :
|
|
1936
|
+
const storageKey = (key) => storageKeyPrefix ? `chat-${storageKeyPrefix}-${key}` : null;
|
|
1927
1937
|
const themeMode = config?.theme?.mode || "light";
|
|
1928
1938
|
const [input, setInput] = useState6("");
|
|
1929
1939
|
const inputRef = useRef4(null);
|
|
@@ -1955,9 +1965,12 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
1955
1965
|
const { messages, sendMessage, status, setMessages, stop, regenerate, error, clearError } = useChat({
|
|
1956
1966
|
id: activeTabId || "temp-id",
|
|
1957
1967
|
transport: new DefaultChatTransport({
|
|
1958
|
-
api: "/api/chat"
|
|
1968
|
+
api: `${config?.apiBase ?? "/api/chat"}`,
|
|
1959
1969
|
headers: {
|
|
1960
|
-
"X-User-Id": config?.userId || ""
|
|
1970
|
+
"X-User-Id": config?.userId || "",
|
|
1971
|
+
// Extra headers the host injects (e.g. the dashboard playground sends
|
|
1972
|
+
// its unsaved draft model/system-prompt for an owner-authed preview).
|
|
1973
|
+
...config?.extraHeaders ?? {}
|
|
1961
1974
|
}
|
|
1962
1975
|
}),
|
|
1963
1976
|
// Throttle UI updates to 200ms to prevent hanging during streaming
|
|
@@ -1981,7 +1994,7 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
1981
1994
|
formData.append("file", fileObj);
|
|
1982
1995
|
formData.append("conversationId", activeTabId || "default");
|
|
1983
1996
|
formData.append("userId", config?.userId || "demo-user");
|
|
1984
|
-
const uploadResponse = await fetch("/api/chat/upload
|
|
1997
|
+
const uploadResponse = await fetch(`${config?.apiBase ?? "/api/chat"}/upload`, {
|
|
1985
1998
|
method: "POST",
|
|
1986
1999
|
body: formData
|
|
1987
2000
|
});
|
|
@@ -2045,8 +2058,11 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2045
2058
|
PromptInputButton,
|
|
2046
2059
|
{
|
|
2047
2060
|
variant: "ghost",
|
|
2061
|
+
size: "icon",
|
|
2062
|
+
className: "size-9 rounded-full text-muted-foreground",
|
|
2063
|
+
"aria-label": "Attach files",
|
|
2048
2064
|
onClick: () => attachments.openFileDialog(),
|
|
2049
|
-
children: /* @__PURE__ */ jsx23(
|
|
2065
|
+
children: /* @__PURE__ */ jsx23(PaperclipIcon2, { className: "size-4 -rotate-45" })
|
|
2050
2066
|
}
|
|
2051
2067
|
);
|
|
2052
2068
|
};
|
|
@@ -2056,7 +2072,7 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2056
2072
|
return;
|
|
2057
2073
|
}
|
|
2058
2074
|
try {
|
|
2059
|
-
const response = await fetch(
|
|
2075
|
+
const response = await fetch(`${config?.apiBase ?? "/api/chat"}/history/${conversationId}?userId=${config.userId}`);
|
|
2060
2076
|
if (response.ok) {
|
|
2061
2077
|
const data = await response.json();
|
|
2062
2078
|
const loadedMessages = data.messages || [];
|
|
@@ -2115,10 +2131,20 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2115
2131
|
const startNewConversation = useCallback4(() => {
|
|
2116
2132
|
createNewTab();
|
|
2117
2133
|
}, [createNewTab]);
|
|
2134
|
+
const prevPrefixRef = useRef4(storageKeyPrefix);
|
|
2118
2135
|
useEffect5(() => {
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2136
|
+
const prev = prevPrefixRef.current;
|
|
2137
|
+
if (prev && prev !== storageKeyPrefix) {
|
|
2138
|
+
const stalePrefix = `chat-${prev}-`;
|
|
2139
|
+
const toRemove = [];
|
|
2140
|
+
for (let i = 0; i < localStorage.length; i++) {
|
|
2141
|
+
const k = localStorage.key(i);
|
|
2142
|
+
if (k && k.startsWith(stalePrefix)) toRemove.push(k);
|
|
2143
|
+
}
|
|
2144
|
+
toRemove.forEach((k) => localStorage.removeItem(k));
|
|
2145
|
+
}
|
|
2146
|
+
prevPrefixRef.current = storageKeyPrefix;
|
|
2147
|
+
}, [storageKeyPrefix]);
|
|
2122
2148
|
const switchToTab = async (tabId) => {
|
|
2123
2149
|
const targetTab = tabs.find((tab) => tab.id === tabId);
|
|
2124
2150
|
if (!targetTab) return;
|
|
@@ -2149,11 +2175,13 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2149
2175
|
} else {
|
|
2150
2176
|
setTabs(filteredTabs);
|
|
2151
2177
|
}
|
|
2152
|
-
|
|
2153
|
-
|
|
2178
|
+
const tabsKey = storageKey("tabs");
|
|
2179
|
+
if (filteredTabs.length > 0 && tabsKey) {
|
|
2180
|
+
localStorage.setItem(tabsKey, JSON.stringify(filteredTabs));
|
|
2154
2181
|
if (tabId === activeTabId) {
|
|
2155
2182
|
const newActiveTab = filteredTabs[0];
|
|
2156
|
-
|
|
2183
|
+
const activeKey = storageKey("active-tab-id");
|
|
2184
|
+
if (activeKey) localStorage.setItem(activeKey, newActiveTab.id);
|
|
2157
2185
|
}
|
|
2158
2186
|
}
|
|
2159
2187
|
};
|
|
@@ -2164,7 +2192,7 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2164
2192
|
}
|
|
2165
2193
|
setLoadingHistory(true);
|
|
2166
2194
|
try {
|
|
2167
|
-
const response = await fetch(
|
|
2195
|
+
const response = await fetch(`${config?.apiBase ?? "/api/chat"}/history?userId=${config.userId}`);
|
|
2168
2196
|
if (response.ok) {
|
|
2169
2197
|
const data = await response.json();
|
|
2170
2198
|
setConversations(data.conversations || []);
|
|
@@ -2193,29 +2221,38 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2193
2221
|
useEffect5(() => {
|
|
2194
2222
|
if (tabs.length > 0) {
|
|
2195
2223
|
const timeoutId = setTimeout(() => {
|
|
2196
|
-
|
|
2197
|
-
|
|
2224
|
+
const tabsKey = storageKey("tabs");
|
|
2225
|
+
const activeKey = storageKey("active-tab-id");
|
|
2226
|
+
if (tabsKey) localStorage.setItem(tabsKey, JSON.stringify(tabs));
|
|
2227
|
+
if (activeKey) localStorage.setItem(activeKey, activeTabId);
|
|
2198
2228
|
}, 500);
|
|
2199
2229
|
return () => clearTimeout(timeoutId);
|
|
2200
2230
|
}
|
|
2201
|
-
}, [tabs, activeTabId,
|
|
2231
|
+
}, [tabs, activeTabId, storageKeyPrefix]);
|
|
2202
2232
|
useEffect5(() => {
|
|
2203
2233
|
if (hasInitialized.current) return;
|
|
2234
|
+
const startCleanTab = () => {
|
|
2235
|
+
const initialTabId = `chat-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
2236
|
+
setTabs([{ id: initialTabId, title: "New Chat", isActive: true }]);
|
|
2237
|
+
setActiveTabId(initialTabId);
|
|
2238
|
+
setInitialTabCreated(true);
|
|
2239
|
+
setIsInitializing(false);
|
|
2240
|
+
};
|
|
2241
|
+
if (!storageKeyPrefix) {
|
|
2242
|
+
if (!initialTabCreated && tabs.length === 0) startCleanTab();
|
|
2243
|
+
return;
|
|
2244
|
+
}
|
|
2204
2245
|
const loadInitialTabs = () => {
|
|
2205
|
-
const savedTabs = localStorage.getItem(
|
|
2206
|
-
const savedActiveTabId = localStorage.getItem(
|
|
2246
|
+
const savedTabs = localStorage.getItem(`chat-${storageKeyPrefix}-tabs`);
|
|
2247
|
+
const savedActiveTabId = localStorage.getItem(`chat-${storageKeyPrefix}-active-tab-id`);
|
|
2207
2248
|
if (savedTabs && savedTabs !== "[]") {
|
|
2208
2249
|
const parsedTabs = JSON.parse(savedTabs);
|
|
2209
2250
|
setTabs(parsedTabs);
|
|
2210
2251
|
const activeId = savedActiveTabId || parsedTabs[0]?.id;
|
|
2211
2252
|
setActiveTabId(activeId);
|
|
2212
2253
|
setInitialTabCreated(true);
|
|
2213
|
-
} else if (
|
|
2214
|
-
|
|
2215
|
-
setTabs([{ id: initialTabId, title: "New Chat", isActive: true }]);
|
|
2216
|
-
setActiveTabId(initialTabId);
|
|
2217
|
-
setInitialTabCreated(true);
|
|
2218
|
-
setIsInitializing(false);
|
|
2254
|
+
} else if (tabs.length === 0) {
|
|
2255
|
+
startCleanTab();
|
|
2219
2256
|
}
|
|
2220
2257
|
};
|
|
2221
2258
|
try {
|
|
@@ -2225,11 +2262,12 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2225
2262
|
setIsInitializing(false);
|
|
2226
2263
|
}
|
|
2227
2264
|
hasInitialized.current = true;
|
|
2228
|
-
}, []);
|
|
2265
|
+
}, [storageKeyPrefix]);
|
|
2229
2266
|
const hasLoadedInitialMessages = useRef4(false);
|
|
2230
2267
|
useEffect5(() => {
|
|
2231
2268
|
if (hasLoadedInitialMessages.current) return;
|
|
2232
2269
|
if (!config?.userId) return;
|
|
2270
|
+
if (!storageKeyPrefix) return;
|
|
2233
2271
|
if (!activeTabId) return;
|
|
2234
2272
|
(async () => {
|
|
2235
2273
|
try {
|
|
@@ -2239,7 +2277,7 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2239
2277
|
setIsInitializing(false);
|
|
2240
2278
|
}
|
|
2241
2279
|
})();
|
|
2242
|
-
}, [config?.userId, activeTabId]);
|
|
2280
|
+
}, [config?.userId, activeTabId, storageKeyPrefix]);
|
|
2243
2281
|
useEffect5(() => {
|
|
2244
2282
|
if (isInitializing) return;
|
|
2245
2283
|
if (activeTabId && tabs.length > 0 && activeTabId !== lastSyncedTabId.current) {
|
|
@@ -2696,7 +2734,7 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2696
2734
|
}
|
|
2697
2735
|
),
|
|
2698
2736
|
inputPlugins.panel,
|
|
2699
|
-
/* @__PURE__ */
|
|
2737
|
+
/* @__PURE__ */ jsx23(
|
|
2700
2738
|
PromptInput,
|
|
2701
2739
|
{
|
|
2702
2740
|
onSubmit: handleSubmit,
|
|
@@ -2717,31 +2755,31 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2717
2755
|
setUploadError("Too many files attached.");
|
|
2718
2756
|
}
|
|
2719
2757
|
},
|
|
2720
|
-
children: [
|
|
2721
|
-
/* @__PURE__ */
|
|
2722
|
-
|
|
2758
|
+
children: /* @__PURE__ */ jsxs16(PromptInputBody, { children: [
|
|
2759
|
+
/* @__PURE__ */ jsx23(PromptInputAttachments, { children: (attachment) => /* @__PURE__ */ jsx23(PromptInputAttachment, { data: attachment }) }),
|
|
2760
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex items-end gap-1.5 px-2 py-2", children: [
|
|
2761
|
+
config?.features?.fileUpload === true && /* @__PURE__ */ jsx23(AttachButton, {}),
|
|
2723
2762
|
/* @__PURE__ */ jsx23(
|
|
2724
2763
|
PromptInputTextarea,
|
|
2725
2764
|
{
|
|
2726
2765
|
ref: inputRef,
|
|
2727
2766
|
onChange: (e) => setInput(e.target.value),
|
|
2728
2767
|
onKeyDown: inputPlugins.onKeyDown,
|
|
2729
|
-
value: input
|
|
2768
|
+
value: input,
|
|
2769
|
+
className: "min-h-0 flex-1 px-1 py-1.5 leading-7"
|
|
2730
2770
|
}
|
|
2731
|
-
)
|
|
2732
|
-
] }),
|
|
2733
|
-
/* @__PURE__ */ jsxs16(PromptInputToolbar, { children: [
|
|
2734
|
-
/* @__PURE__ */ jsx23(PromptInputTools, { children: config?.features?.fileUpload === true && /* @__PURE__ */ jsx23(AttachButton, {}) }),
|
|
2771
|
+
),
|
|
2735
2772
|
/* @__PURE__ */ jsx23(
|
|
2736
2773
|
PromptInputSubmit,
|
|
2737
2774
|
{
|
|
2775
|
+
className: "size-9 rounded-full p-0 [&_svg]:size-4",
|
|
2738
2776
|
disabled: status === "streaming" || status === "submitted" ? false : !input,
|
|
2739
2777
|
status,
|
|
2740
2778
|
onStop: stop
|
|
2741
2779
|
}
|
|
2742
2780
|
)
|
|
2743
2781
|
] })
|
|
2744
|
-
]
|
|
2782
|
+
] })
|
|
2745
2783
|
}
|
|
2746
2784
|
)
|
|
2747
2785
|
] })
|
|
@@ -2792,6 +2830,10 @@ function toHslTripletIfHex(value) {
|
|
|
2792
2830
|
import { jsx as jsx24, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
2793
2831
|
function ChatWidget({
|
|
2794
2832
|
userId,
|
|
2833
|
+
agentId,
|
|
2834
|
+
apiBase,
|
|
2835
|
+
extraHeaders,
|
|
2836
|
+
widgetId,
|
|
2795
2837
|
conversationId,
|
|
2796
2838
|
initialMessages,
|
|
2797
2839
|
className,
|
|
@@ -2809,6 +2851,7 @@ function ChatWidget({
|
|
|
2809
2851
|
inputPlugins,
|
|
2810
2852
|
toolRenderers
|
|
2811
2853
|
}) {
|
|
2854
|
+
const effectiveAgentId = agentId ?? widgetId;
|
|
2812
2855
|
const layout = display?.layout || "popup";
|
|
2813
2856
|
const isControlled = open !== void 0;
|
|
2814
2857
|
const showToggleButton = !isControlled && display?.showToggleButton !== false;
|
|
@@ -2877,6 +2920,8 @@ function ChatWidget({
|
|
|
2877
2920
|
}, [isResizing]);
|
|
2878
2921
|
const config = useMemo4(() => ({
|
|
2879
2922
|
userId,
|
|
2923
|
+
apiBase: apiBase ?? "/api/chat",
|
|
2924
|
+
extraHeaders,
|
|
2880
2925
|
model,
|
|
2881
2926
|
systemPrompt,
|
|
2882
2927
|
temperature,
|
|
@@ -2885,11 +2930,11 @@ function ChatWidget({
|
|
|
2885
2930
|
starterPrompts,
|
|
2886
2931
|
inputPlugins,
|
|
2887
2932
|
toolRenderers
|
|
2888
|
-
}), [userId, model, systemPrompt, temperature, theme, features, starterPrompts, inputPlugins, toolRenderers]);
|
|
2933
|
+
}), [userId, apiBase, extraHeaders, model, systemPrompt, temperature, theme, features, starterPrompts, inputPlugins, toolRenderers]);
|
|
2889
2934
|
const togglePosition = display?.toggleButtonPosition || { bottom: "24px", right: "24px" };
|
|
2890
2935
|
const themeClass = theme?.mode === "dark" ? "dark" : "";
|
|
2891
2936
|
if (layout === "inline") {
|
|
2892
|
-
return /* @__PURE__ */ jsx24(ChatStorageProvider, { userId, children: /* @__PURE__ */ jsx24(
|
|
2937
|
+
return /* @__PURE__ */ jsx24(ChatStorageProvider, { userId, agentId: effectiveAgentId, children: /* @__PURE__ */ jsx24(
|
|
2893
2938
|
"div",
|
|
2894
2939
|
{
|
|
2895
2940
|
ref: containerRef,
|
|
@@ -2909,7 +2954,7 @@ function ChatWidget({
|
|
|
2909
2954
|
) });
|
|
2910
2955
|
}
|
|
2911
2956
|
if (layout === "page") {
|
|
2912
|
-
return /* @__PURE__ */ jsx24(ChatStorageProvider, { userId, children: /* @__PURE__ */ jsx24(
|
|
2957
|
+
return /* @__PURE__ */ jsx24(ChatStorageProvider, { userId, agentId: effectiveAgentId, children: /* @__PURE__ */ jsx24(
|
|
2913
2958
|
"div",
|
|
2914
2959
|
{
|
|
2915
2960
|
ref: containerRef,
|
|
@@ -2928,7 +2973,7 @@ function ChatWidget({
|
|
|
2928
2973
|
}
|
|
2929
2974
|
) });
|
|
2930
2975
|
}
|
|
2931
|
-
return /* @__PURE__ */ jsxs17(ChatStorageProvider, { userId, children: [
|
|
2976
|
+
return /* @__PURE__ */ jsxs17(ChatStorageProvider, { userId, agentId: effectiveAgentId, children: [
|
|
2932
2977
|
showToggleButton && !isOpen && /* @__PURE__ */ jsx24(
|
|
2933
2978
|
"button",
|
|
2934
2979
|
{
|
|
@@ -3025,7 +3070,6 @@ var MODELS = [
|
|
|
3025
3070
|
value: "google/gemini-2.5-pro"
|
|
3026
3071
|
}
|
|
3027
3072
|
];
|
|
3028
|
-
var DEFAULT_MODEL = MODELS[0].value;
|
|
3029
3073
|
|
|
3030
3074
|
// src/hooks/use-chat-theme.ts
|
|
3031
3075
|
function hexToHSL(hex) {
|
|
@@ -3090,13 +3134,13 @@ var defaultConversationStarters = [
|
|
|
3090
3134
|
{ text: "What features does this product offer?", enabled: true },
|
|
3091
3135
|
{ text: "Tell me about your capabilities", enabled: true }
|
|
3092
3136
|
];
|
|
3093
|
-
var defaultModel =
|
|
3137
|
+
var defaultModel = MODELS[0].value;
|
|
3094
3138
|
var defaultSystemPrompt = "You are a helpful AI assistant.";
|
|
3095
3139
|
var defaultTemperature = 0.7;
|
|
3096
3140
|
var defaultThemeMode = "light";
|
|
3097
3141
|
function useChatTheme() {
|
|
3098
3142
|
const { storageKeyPrefix } = useChatStorageKey();
|
|
3099
|
-
const keyPrefix = storageKeyPrefix ? `chat-${storageKeyPrefix}-` :
|
|
3143
|
+
const keyPrefix = storageKeyPrefix ? `chat-${storageKeyPrefix}-` : null;
|
|
3100
3144
|
const [theme, setTheme] = useState8(defaultTheme);
|
|
3101
3145
|
const [conversationStarters, setConversationStarters] = useState8(defaultConversationStarters);
|
|
3102
3146
|
const [model, setModel] = useState8(defaultModel);
|
|
@@ -3104,6 +3148,7 @@ function useChatTheme() {
|
|
|
3104
3148
|
const [temperature, setTemperature] = useState8(defaultTemperature);
|
|
3105
3149
|
const [themeMode, setThemeMode] = useState8(defaultThemeMode);
|
|
3106
3150
|
useEffect7(() => {
|
|
3151
|
+
if (!keyPrefix) return;
|
|
3107
3152
|
const savedTheme = localStorage.getItem(`${keyPrefix}theme`);
|
|
3108
3153
|
if (savedTheme) {
|
|
3109
3154
|
try {
|
|
@@ -3192,7 +3237,7 @@ function useChatTheme() {
|
|
|
3192
3237
|
};
|
|
3193
3238
|
}, [keyPrefix]);
|
|
3194
3239
|
useEffect7(() => {
|
|
3195
|
-
localStorage.setItem(`${keyPrefix}theme`, JSON.stringify(theme));
|
|
3240
|
+
if (keyPrefix) localStorage.setItem(`${keyPrefix}theme`, JSON.stringify(theme));
|
|
3196
3241
|
const root = document.documentElement;
|
|
3197
3242
|
if (themeMode === "light") {
|
|
3198
3243
|
root.style.setProperty("--chat-primary", hexToHSL(theme.lightPrimary));
|
|
@@ -3208,23 +3253,23 @@ function useChatTheme() {
|
|
|
3208
3253
|
window.dispatchEvent(new CustomEvent("chat-theme-change", { detail: theme }));
|
|
3209
3254
|
}, [theme, themeMode, keyPrefix]);
|
|
3210
3255
|
useEffect7(() => {
|
|
3211
|
-
localStorage.setItem(`${keyPrefix}conversation-starters`, JSON.stringify(conversationStarters));
|
|
3256
|
+
if (keyPrefix) localStorage.setItem(`${keyPrefix}conversation-starters`, JSON.stringify(conversationStarters));
|
|
3212
3257
|
window.dispatchEvent(new CustomEvent("chat-starters-change", { detail: conversationStarters }));
|
|
3213
3258
|
}, [conversationStarters, keyPrefix]);
|
|
3214
3259
|
useEffect7(() => {
|
|
3215
|
-
localStorage.setItem(`${keyPrefix}model`, model);
|
|
3260
|
+
if (keyPrefix) localStorage.setItem(`${keyPrefix}model`, model);
|
|
3216
3261
|
window.dispatchEvent(new CustomEvent("chat-model-change", { detail: model }));
|
|
3217
3262
|
}, [model, keyPrefix]);
|
|
3218
3263
|
useEffect7(() => {
|
|
3219
|
-
localStorage.setItem(`${keyPrefix}system-prompt`, systemPrompt);
|
|
3264
|
+
if (keyPrefix) localStorage.setItem(`${keyPrefix}system-prompt`, systemPrompt);
|
|
3220
3265
|
window.dispatchEvent(new CustomEvent("chat-system-prompt-change", { detail: systemPrompt }));
|
|
3221
3266
|
}, [systemPrompt, keyPrefix]);
|
|
3222
3267
|
useEffect7(() => {
|
|
3223
|
-
localStorage.setItem(`${keyPrefix}temperature`, temperature.toString());
|
|
3268
|
+
if (keyPrefix) localStorage.setItem(`${keyPrefix}temperature`, temperature.toString());
|
|
3224
3269
|
window.dispatchEvent(new CustomEvent("chat-temperature-change", { detail: temperature }));
|
|
3225
3270
|
}, [temperature, keyPrefix]);
|
|
3226
3271
|
useEffect7(() => {
|
|
3227
|
-
localStorage.setItem(`${keyPrefix}theme-mode`, themeMode);
|
|
3272
|
+
if (keyPrefix) localStorage.setItem(`${keyPrefix}theme-mode`, themeMode);
|
|
3228
3273
|
window.dispatchEvent(new CustomEvent("chat-theme-mode-change", { detail: themeMode }));
|
|
3229
3274
|
}, [themeMode, keyPrefix]);
|
|
3230
3275
|
const updateColor = (key, value) => {
|
|
@@ -3430,6 +3475,7 @@ export {
|
|
|
3430
3475
|
ToolHeader,
|
|
3431
3476
|
ToolInput,
|
|
3432
3477
|
ToolOutput,
|
|
3478
|
+
clearChatStorage,
|
|
3433
3479
|
ChatWidget_default as default,
|
|
3434
3480
|
fontOptions,
|
|
3435
3481
|
useChatStorageKey,
|