@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.js
CHANGED
|
@@ -48,6 +48,7 @@ __export(src_exports, {
|
|
|
48
48
|
ToolHeader: () => ToolHeader,
|
|
49
49
|
ToolInput: () => ToolInput,
|
|
50
50
|
ToolOutput: () => ToolOutput,
|
|
51
|
+
clearChatStorage: () => clearChatStorage,
|
|
51
52
|
default: () => ChatWidget_default,
|
|
52
53
|
fontOptions: () => fontOptions,
|
|
53
54
|
useChatStorageKey: () => useChatStorageKey,
|
|
@@ -592,14 +593,32 @@ var PromptInputBody = ({
|
|
|
592
593
|
className,
|
|
593
594
|
...props
|
|
594
595
|
}) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: cn(className, "flex flex-col"), ...props });
|
|
596
|
+
var TEXTAREA_MIN_HEIGHT = 28;
|
|
597
|
+
var TEXTAREA_MAX_HEIGHT = 192;
|
|
595
598
|
var PromptInputTextarea = import_react2.default.forwardRef(({
|
|
596
599
|
onChange,
|
|
597
600
|
onKeyDown: externalOnKeyDown,
|
|
598
601
|
className,
|
|
599
602
|
placeholder = "What would you like to know?",
|
|
603
|
+
value,
|
|
600
604
|
...props
|
|
601
605
|
}, ref) => {
|
|
602
606
|
const attachments = usePromptInputAttachments();
|
|
607
|
+
const innerRef = (0, import_react2.useRef)(null);
|
|
608
|
+
const setRefs = (node) => {
|
|
609
|
+
innerRef.current = node;
|
|
610
|
+
if (typeof ref === "function") ref(node);
|
|
611
|
+
else if (ref) ref.current = node;
|
|
612
|
+
};
|
|
613
|
+
const resize = () => {
|
|
614
|
+
const el = innerRef.current;
|
|
615
|
+
if (!el) return;
|
|
616
|
+
el.style.height = "auto";
|
|
617
|
+
const next = Math.min(el.scrollHeight, TEXTAREA_MAX_HEIGHT);
|
|
618
|
+
el.style.height = `${Math.max(next, TEXTAREA_MIN_HEIGHT)}px`;
|
|
619
|
+
el.style.overflowY = el.scrollHeight > TEXTAREA_MAX_HEIGHT ? "auto" : "hidden";
|
|
620
|
+
};
|
|
621
|
+
(0, import_react2.useLayoutEffect)(resize, [value]);
|
|
603
622
|
const handleKeyDown = (e) => {
|
|
604
623
|
externalOnKeyDown?.(e);
|
|
605
624
|
if (e.defaultPrevented) return;
|
|
@@ -639,17 +658,19 @@ var PromptInputTextarea = import_react2.default.forwardRef(({
|
|
|
639
658
|
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
640
659
|
Textarea,
|
|
641
660
|
{
|
|
642
|
-
ref,
|
|
661
|
+
ref: setRefs,
|
|
662
|
+
rows: 1,
|
|
663
|
+
value,
|
|
643
664
|
className: cn(
|
|
644
|
-
"w-full resize-none rounded-none border-none
|
|
645
|
-
"field-sizing-content",
|
|
646
|
-
"max-h-48 min-h-16",
|
|
665
|
+
"w-full resize-none rounded-none border-none px-3 py-2.5 shadow-none outline-none ring-0",
|
|
647
666
|
"focus-visible:ring-0 focus-visible:shadow-none focus:ring-0 focus:shadow-none",
|
|
648
667
|
className
|
|
649
668
|
),
|
|
669
|
+
style: { minHeight: TEXTAREA_MIN_HEIGHT, maxHeight: TEXTAREA_MAX_HEIGHT, overflowY: "hidden" },
|
|
650
670
|
name: "message",
|
|
651
671
|
onChange: (e) => {
|
|
652
672
|
onChange?.(e);
|
|
673
|
+
resize();
|
|
653
674
|
},
|
|
654
675
|
onKeyDown: handleKeyDown,
|
|
655
676
|
onPaste: handlePaste,
|
|
@@ -659,30 +680,6 @@ var PromptInputTextarea = import_react2.default.forwardRef(({
|
|
|
659
680
|
);
|
|
660
681
|
});
|
|
661
682
|
PromptInputTextarea.displayName = "PromptInputTextarea";
|
|
662
|
-
var PromptInputToolbar = ({
|
|
663
|
-
className,
|
|
664
|
-
...props
|
|
665
|
-
}) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
666
|
-
"div",
|
|
667
|
-
{
|
|
668
|
-
className: cn("flex items-center justify-between p-1", className),
|
|
669
|
-
...props
|
|
670
|
-
}
|
|
671
|
-
);
|
|
672
|
-
var PromptInputTools = ({
|
|
673
|
-
className,
|
|
674
|
-
...props
|
|
675
|
-
}) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
676
|
-
"div",
|
|
677
|
-
{
|
|
678
|
-
className: cn(
|
|
679
|
-
"flex items-center gap-1",
|
|
680
|
-
"[&_button:first-child]:rounded-bl-xl",
|
|
681
|
-
className
|
|
682
|
-
),
|
|
683
|
-
...props
|
|
684
|
-
}
|
|
685
|
-
);
|
|
686
683
|
var PromptInputButton = ({
|
|
687
684
|
variant = "ghost",
|
|
688
685
|
className,
|
|
@@ -1923,24 +1920,38 @@ function StarterMessageItem({
|
|
|
1923
1920
|
var import_react10 = require("react");
|
|
1924
1921
|
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
1925
1922
|
var ChatStorageContext = (0, import_react10.createContext)({
|
|
1926
|
-
storageKeyPrefix:
|
|
1923
|
+
storageKeyPrefix: null
|
|
1927
1924
|
});
|
|
1928
1925
|
function ChatStorageProvider({
|
|
1929
1926
|
children,
|
|
1930
|
-
userId
|
|
1927
|
+
userId,
|
|
1928
|
+
agentId
|
|
1931
1929
|
}) {
|
|
1932
|
-
const storageKeyPrefix = userId
|
|
1930
|
+
const storageKeyPrefix = userId && agentId ? `${encodeURIComponent(agentId)}|${encodeURIComponent(userId)}` : null;
|
|
1933
1931
|
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ChatStorageContext.Provider, { value: { storageKeyPrefix }, children });
|
|
1934
1932
|
}
|
|
1935
1933
|
function useChatStorageKey() {
|
|
1936
1934
|
return (0, import_react10.useContext)(ChatStorageContext);
|
|
1937
1935
|
}
|
|
1936
|
+
function clearChatStorage(opts) {
|
|
1937
|
+
if (typeof window === "undefined" || !window.localStorage) return;
|
|
1938
|
+
const scopedPrefix = opts?.agentId && opts?.userId ? `chat-${encodeURIComponent(opts.agentId)}|${encodeURIComponent(opts.userId)}-` : null;
|
|
1939
|
+
const toRemove = [];
|
|
1940
|
+
for (let i = 0; i < localStorage.length; i++) {
|
|
1941
|
+
const key = localStorage.key(i);
|
|
1942
|
+
if (!key) continue;
|
|
1943
|
+
if (scopedPrefix ? key.startsWith(scopedPrefix) : key.startsWith("chat-")) {
|
|
1944
|
+
toRemove.push(key);
|
|
1945
|
+
}
|
|
1946
|
+
}
|
|
1947
|
+
toRemove.forEach((key) => localStorage.removeItem(key));
|
|
1948
|
+
}
|
|
1938
1949
|
|
|
1939
1950
|
// src/components/interface.tsx
|
|
1940
1951
|
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
1941
1952
|
function ChatInterface({ id, initialMessages, config, onClose, headerActions } = {}) {
|
|
1942
1953
|
const { storageKeyPrefix } = useChatStorageKey();
|
|
1943
|
-
const storageKey = (key) => storageKeyPrefix ? `chat-${storageKeyPrefix}-${key}` :
|
|
1954
|
+
const storageKey = (key) => storageKeyPrefix ? `chat-${storageKeyPrefix}-${key}` : null;
|
|
1944
1955
|
const themeMode = config?.theme?.mode || "light";
|
|
1945
1956
|
const [input, setInput] = (0, import_react11.useState)("");
|
|
1946
1957
|
const inputRef = (0, import_react11.useRef)(null);
|
|
@@ -1972,9 +1983,12 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
1972
1983
|
const { messages, sendMessage, status, setMessages, stop, regenerate, error, clearError } = (0, import_react13.useChat)({
|
|
1973
1984
|
id: activeTabId || "temp-id",
|
|
1974
1985
|
transport: new import_ai.DefaultChatTransport({
|
|
1975
|
-
api: "/api/chat"
|
|
1986
|
+
api: `${config?.apiBase ?? "/api/chat"}`,
|
|
1976
1987
|
headers: {
|
|
1977
|
-
"X-User-Id": config?.userId || ""
|
|
1988
|
+
"X-User-Id": config?.userId || "",
|
|
1989
|
+
// Extra headers the host injects (e.g. the dashboard playground sends
|
|
1990
|
+
// its unsaved draft model/system-prompt for an owner-authed preview).
|
|
1991
|
+
...config?.extraHeaders ?? {}
|
|
1978
1992
|
}
|
|
1979
1993
|
}),
|
|
1980
1994
|
// Throttle UI updates to 200ms to prevent hanging during streaming
|
|
@@ -1998,7 +2012,7 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
1998
2012
|
formData.append("file", fileObj);
|
|
1999
2013
|
formData.append("conversationId", activeTabId || "default");
|
|
2000
2014
|
formData.append("userId", config?.userId || "demo-user");
|
|
2001
|
-
const uploadResponse = await fetch("/api/chat/upload
|
|
2015
|
+
const uploadResponse = await fetch(`${config?.apiBase ?? "/api/chat"}/upload`, {
|
|
2002
2016
|
method: "POST",
|
|
2003
2017
|
body: formData
|
|
2004
2018
|
});
|
|
@@ -2062,8 +2076,11 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2062
2076
|
PromptInputButton,
|
|
2063
2077
|
{
|
|
2064
2078
|
variant: "ghost",
|
|
2079
|
+
size: "icon",
|
|
2080
|
+
className: "size-9 rounded-full text-muted-foreground",
|
|
2081
|
+
"aria-label": "Attach files",
|
|
2065
2082
|
onClick: () => attachments.openFileDialog(),
|
|
2066
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react12.
|
|
2083
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react12.PaperclipIcon, { className: "size-4 -rotate-45" })
|
|
2067
2084
|
}
|
|
2068
2085
|
);
|
|
2069
2086
|
};
|
|
@@ -2073,7 +2090,7 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2073
2090
|
return;
|
|
2074
2091
|
}
|
|
2075
2092
|
try {
|
|
2076
|
-
const response = await fetch(
|
|
2093
|
+
const response = await fetch(`${config?.apiBase ?? "/api/chat"}/history/${conversationId}?userId=${config.userId}`);
|
|
2077
2094
|
if (response.ok) {
|
|
2078
2095
|
const data = await response.json();
|
|
2079
2096
|
const loadedMessages = data.messages || [];
|
|
@@ -2132,10 +2149,20 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2132
2149
|
const startNewConversation = (0, import_react11.useCallback)(() => {
|
|
2133
2150
|
createNewTab();
|
|
2134
2151
|
}, [createNewTab]);
|
|
2152
|
+
const prevPrefixRef = (0, import_react11.useRef)(storageKeyPrefix);
|
|
2135
2153
|
(0, import_react11.useEffect)(() => {
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2154
|
+
const prev = prevPrefixRef.current;
|
|
2155
|
+
if (prev && prev !== storageKeyPrefix) {
|
|
2156
|
+
const stalePrefix = `chat-${prev}-`;
|
|
2157
|
+
const toRemove = [];
|
|
2158
|
+
for (let i = 0; i < localStorage.length; i++) {
|
|
2159
|
+
const k = localStorage.key(i);
|
|
2160
|
+
if (k && k.startsWith(stalePrefix)) toRemove.push(k);
|
|
2161
|
+
}
|
|
2162
|
+
toRemove.forEach((k) => localStorage.removeItem(k));
|
|
2163
|
+
}
|
|
2164
|
+
prevPrefixRef.current = storageKeyPrefix;
|
|
2165
|
+
}, [storageKeyPrefix]);
|
|
2139
2166
|
const switchToTab = async (tabId) => {
|
|
2140
2167
|
const targetTab = tabs.find((tab) => tab.id === tabId);
|
|
2141
2168
|
if (!targetTab) return;
|
|
@@ -2166,11 +2193,13 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2166
2193
|
} else {
|
|
2167
2194
|
setTabs(filteredTabs);
|
|
2168
2195
|
}
|
|
2169
|
-
|
|
2170
|
-
|
|
2196
|
+
const tabsKey = storageKey("tabs");
|
|
2197
|
+
if (filteredTabs.length > 0 && tabsKey) {
|
|
2198
|
+
localStorage.setItem(tabsKey, JSON.stringify(filteredTabs));
|
|
2171
2199
|
if (tabId === activeTabId) {
|
|
2172
2200
|
const newActiveTab = filteredTabs[0];
|
|
2173
|
-
|
|
2201
|
+
const activeKey = storageKey("active-tab-id");
|
|
2202
|
+
if (activeKey) localStorage.setItem(activeKey, newActiveTab.id);
|
|
2174
2203
|
}
|
|
2175
2204
|
}
|
|
2176
2205
|
};
|
|
@@ -2181,7 +2210,7 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2181
2210
|
}
|
|
2182
2211
|
setLoadingHistory(true);
|
|
2183
2212
|
try {
|
|
2184
|
-
const response = await fetch(
|
|
2213
|
+
const response = await fetch(`${config?.apiBase ?? "/api/chat"}/history?userId=${config.userId}`);
|
|
2185
2214
|
if (response.ok) {
|
|
2186
2215
|
const data = await response.json();
|
|
2187
2216
|
setConversations(data.conversations || []);
|
|
@@ -2210,29 +2239,38 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2210
2239
|
(0, import_react11.useEffect)(() => {
|
|
2211
2240
|
if (tabs.length > 0) {
|
|
2212
2241
|
const timeoutId = setTimeout(() => {
|
|
2213
|
-
|
|
2214
|
-
|
|
2242
|
+
const tabsKey = storageKey("tabs");
|
|
2243
|
+
const activeKey = storageKey("active-tab-id");
|
|
2244
|
+
if (tabsKey) localStorage.setItem(tabsKey, JSON.stringify(tabs));
|
|
2245
|
+
if (activeKey) localStorage.setItem(activeKey, activeTabId);
|
|
2215
2246
|
}, 500);
|
|
2216
2247
|
return () => clearTimeout(timeoutId);
|
|
2217
2248
|
}
|
|
2218
|
-
}, [tabs, activeTabId,
|
|
2249
|
+
}, [tabs, activeTabId, storageKeyPrefix]);
|
|
2219
2250
|
(0, import_react11.useEffect)(() => {
|
|
2220
2251
|
if (hasInitialized.current) return;
|
|
2252
|
+
const startCleanTab = () => {
|
|
2253
|
+
const initialTabId = `chat-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
2254
|
+
setTabs([{ id: initialTabId, title: "New Chat", isActive: true }]);
|
|
2255
|
+
setActiveTabId(initialTabId);
|
|
2256
|
+
setInitialTabCreated(true);
|
|
2257
|
+
setIsInitializing(false);
|
|
2258
|
+
};
|
|
2259
|
+
if (!storageKeyPrefix) {
|
|
2260
|
+
if (!initialTabCreated && tabs.length === 0) startCleanTab();
|
|
2261
|
+
return;
|
|
2262
|
+
}
|
|
2221
2263
|
const loadInitialTabs = () => {
|
|
2222
|
-
const savedTabs = localStorage.getItem(
|
|
2223
|
-
const savedActiveTabId = localStorage.getItem(
|
|
2264
|
+
const savedTabs = localStorage.getItem(`chat-${storageKeyPrefix}-tabs`);
|
|
2265
|
+
const savedActiveTabId = localStorage.getItem(`chat-${storageKeyPrefix}-active-tab-id`);
|
|
2224
2266
|
if (savedTabs && savedTabs !== "[]") {
|
|
2225
2267
|
const parsedTabs = JSON.parse(savedTabs);
|
|
2226
2268
|
setTabs(parsedTabs);
|
|
2227
2269
|
const activeId = savedActiveTabId || parsedTabs[0]?.id;
|
|
2228
2270
|
setActiveTabId(activeId);
|
|
2229
2271
|
setInitialTabCreated(true);
|
|
2230
|
-
} else if (
|
|
2231
|
-
|
|
2232
|
-
setTabs([{ id: initialTabId, title: "New Chat", isActive: true }]);
|
|
2233
|
-
setActiveTabId(initialTabId);
|
|
2234
|
-
setInitialTabCreated(true);
|
|
2235
|
-
setIsInitializing(false);
|
|
2272
|
+
} else if (tabs.length === 0) {
|
|
2273
|
+
startCleanTab();
|
|
2236
2274
|
}
|
|
2237
2275
|
};
|
|
2238
2276
|
try {
|
|
@@ -2242,11 +2280,12 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2242
2280
|
setIsInitializing(false);
|
|
2243
2281
|
}
|
|
2244
2282
|
hasInitialized.current = true;
|
|
2245
|
-
}, []);
|
|
2283
|
+
}, [storageKeyPrefix]);
|
|
2246
2284
|
const hasLoadedInitialMessages = (0, import_react11.useRef)(false);
|
|
2247
2285
|
(0, import_react11.useEffect)(() => {
|
|
2248
2286
|
if (hasLoadedInitialMessages.current) return;
|
|
2249
2287
|
if (!config?.userId) return;
|
|
2288
|
+
if (!storageKeyPrefix) return;
|
|
2250
2289
|
if (!activeTabId) return;
|
|
2251
2290
|
(async () => {
|
|
2252
2291
|
try {
|
|
@@ -2256,7 +2295,7 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2256
2295
|
setIsInitializing(false);
|
|
2257
2296
|
}
|
|
2258
2297
|
})();
|
|
2259
|
-
}, [config?.userId, activeTabId]);
|
|
2298
|
+
}, [config?.userId, activeTabId, storageKeyPrefix]);
|
|
2260
2299
|
(0, import_react11.useEffect)(() => {
|
|
2261
2300
|
if (isInitializing) return;
|
|
2262
2301
|
if (activeTabId && tabs.length > 0 && activeTabId !== lastSyncedTabId.current) {
|
|
@@ -2713,7 +2752,7 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2713
2752
|
}
|
|
2714
2753
|
),
|
|
2715
2754
|
inputPlugins.panel,
|
|
2716
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.
|
|
2755
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
2717
2756
|
PromptInput,
|
|
2718
2757
|
{
|
|
2719
2758
|
onSubmit: handleSubmit,
|
|
@@ -2734,31 +2773,31 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2734
2773
|
setUploadError("Too many files attached.");
|
|
2735
2774
|
}
|
|
2736
2775
|
},
|
|
2737
|
-
children: [
|
|
2738
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.
|
|
2739
|
-
|
|
2776
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(PromptInputBody, { children: [
|
|
2777
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PromptInputAttachments, { children: (attachment) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PromptInputAttachment, { data: attachment }) }),
|
|
2778
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-end gap-1.5 px-2 py-2", children: [
|
|
2779
|
+
config?.features?.fileUpload === true && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(AttachButton, {}),
|
|
2740
2780
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
2741
2781
|
PromptInputTextarea,
|
|
2742
2782
|
{
|
|
2743
2783
|
ref: inputRef,
|
|
2744
2784
|
onChange: (e) => setInput(e.target.value),
|
|
2745
2785
|
onKeyDown: inputPlugins.onKeyDown,
|
|
2746
|
-
value: input
|
|
2786
|
+
value: input,
|
|
2787
|
+
className: "min-h-0 flex-1 px-1 py-1.5 leading-7"
|
|
2747
2788
|
}
|
|
2748
|
-
)
|
|
2749
|
-
] }),
|
|
2750
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(PromptInputToolbar, { children: [
|
|
2751
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PromptInputTools, { children: config?.features?.fileUpload === true && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(AttachButton, {}) }),
|
|
2789
|
+
),
|
|
2752
2790
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
2753
2791
|
PromptInputSubmit,
|
|
2754
2792
|
{
|
|
2793
|
+
className: "size-9 rounded-full p-0 [&_svg]:size-4",
|
|
2755
2794
|
disabled: status === "streaming" || status === "submitted" ? false : !input,
|
|
2756
2795
|
status,
|
|
2757
2796
|
onStop: stop
|
|
2758
2797
|
}
|
|
2759
2798
|
)
|
|
2760
2799
|
] })
|
|
2761
|
-
]
|
|
2800
|
+
] })
|
|
2762
2801
|
}
|
|
2763
2802
|
)
|
|
2764
2803
|
] })
|
|
@@ -2809,6 +2848,10 @@ function toHslTripletIfHex(value) {
|
|
|
2809
2848
|
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
2810
2849
|
function ChatWidget({
|
|
2811
2850
|
userId,
|
|
2851
|
+
agentId,
|
|
2852
|
+
apiBase,
|
|
2853
|
+
extraHeaders,
|
|
2854
|
+
widgetId,
|
|
2812
2855
|
conversationId,
|
|
2813
2856
|
initialMessages,
|
|
2814
2857
|
className,
|
|
@@ -2826,6 +2869,7 @@ function ChatWidget({
|
|
|
2826
2869
|
inputPlugins,
|
|
2827
2870
|
toolRenderers
|
|
2828
2871
|
}) {
|
|
2872
|
+
const effectiveAgentId = agentId ?? widgetId;
|
|
2829
2873
|
const layout = display?.layout || "popup";
|
|
2830
2874
|
const isControlled = open !== void 0;
|
|
2831
2875
|
const showToggleButton = !isControlled && display?.showToggleButton !== false;
|
|
@@ -2894,6 +2938,8 @@ function ChatWidget({
|
|
|
2894
2938
|
}, [isResizing]);
|
|
2895
2939
|
const config = (0, import_react14.useMemo)(() => ({
|
|
2896
2940
|
userId,
|
|
2941
|
+
apiBase: apiBase ?? "/api/chat",
|
|
2942
|
+
extraHeaders,
|
|
2897
2943
|
model,
|
|
2898
2944
|
systemPrompt,
|
|
2899
2945
|
temperature,
|
|
@@ -2902,11 +2948,11 @@ function ChatWidget({
|
|
|
2902
2948
|
starterPrompts,
|
|
2903
2949
|
inputPlugins,
|
|
2904
2950
|
toolRenderers
|
|
2905
|
-
}), [userId, model, systemPrompt, temperature, theme, features, starterPrompts, inputPlugins, toolRenderers]);
|
|
2951
|
+
}), [userId, apiBase, extraHeaders, model, systemPrompt, temperature, theme, features, starterPrompts, inputPlugins, toolRenderers]);
|
|
2906
2952
|
const togglePosition = display?.toggleButtonPosition || { bottom: "24px", right: "24px" };
|
|
2907
2953
|
const themeClass = theme?.mode === "dark" ? "dark" : "";
|
|
2908
2954
|
if (layout === "inline") {
|
|
2909
|
-
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ChatStorageProvider, { userId, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
2955
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ChatStorageProvider, { userId, agentId: effectiveAgentId, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
2910
2956
|
"div",
|
|
2911
2957
|
{
|
|
2912
2958
|
ref: containerRef,
|
|
@@ -2926,7 +2972,7 @@ function ChatWidget({
|
|
|
2926
2972
|
) });
|
|
2927
2973
|
}
|
|
2928
2974
|
if (layout === "page") {
|
|
2929
|
-
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ChatStorageProvider, { userId, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
2975
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ChatStorageProvider, { userId, agentId: effectiveAgentId, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
2930
2976
|
"div",
|
|
2931
2977
|
{
|
|
2932
2978
|
ref: containerRef,
|
|
@@ -2945,7 +2991,7 @@ function ChatWidget({
|
|
|
2945
2991
|
}
|
|
2946
2992
|
) });
|
|
2947
2993
|
}
|
|
2948
|
-
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(ChatStorageProvider, { userId, children: [
|
|
2994
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(ChatStorageProvider, { userId, agentId: effectiveAgentId, children: [
|
|
2949
2995
|
showToggleButton && !isOpen && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
2950
2996
|
"button",
|
|
2951
2997
|
{
|
|
@@ -3042,7 +3088,6 @@ var MODELS = [
|
|
|
3042
3088
|
value: "google/gemini-2.5-pro"
|
|
3043
3089
|
}
|
|
3044
3090
|
];
|
|
3045
|
-
var DEFAULT_MODEL = MODELS[0].value;
|
|
3046
3091
|
|
|
3047
3092
|
// src/hooks/use-chat-theme.ts
|
|
3048
3093
|
function hexToHSL(hex) {
|
|
@@ -3107,13 +3152,13 @@ var defaultConversationStarters = [
|
|
|
3107
3152
|
{ text: "What features does this product offer?", enabled: true },
|
|
3108
3153
|
{ text: "Tell me about your capabilities", enabled: true }
|
|
3109
3154
|
];
|
|
3110
|
-
var defaultModel =
|
|
3155
|
+
var defaultModel = MODELS[0].value;
|
|
3111
3156
|
var defaultSystemPrompt = "You are a helpful AI assistant.";
|
|
3112
3157
|
var defaultTemperature = 0.7;
|
|
3113
3158
|
var defaultThemeMode = "light";
|
|
3114
3159
|
function useChatTheme() {
|
|
3115
3160
|
const { storageKeyPrefix } = useChatStorageKey();
|
|
3116
|
-
const keyPrefix = storageKeyPrefix ? `chat-${storageKeyPrefix}-` :
|
|
3161
|
+
const keyPrefix = storageKeyPrefix ? `chat-${storageKeyPrefix}-` : null;
|
|
3117
3162
|
const [theme, setTheme] = (0, import_react15.useState)(defaultTheme);
|
|
3118
3163
|
const [conversationStarters, setConversationStarters] = (0, import_react15.useState)(defaultConversationStarters);
|
|
3119
3164
|
const [model, setModel] = (0, import_react15.useState)(defaultModel);
|
|
@@ -3121,6 +3166,7 @@ function useChatTheme() {
|
|
|
3121
3166
|
const [temperature, setTemperature] = (0, import_react15.useState)(defaultTemperature);
|
|
3122
3167
|
const [themeMode, setThemeMode] = (0, import_react15.useState)(defaultThemeMode);
|
|
3123
3168
|
(0, import_react15.useEffect)(() => {
|
|
3169
|
+
if (!keyPrefix) return;
|
|
3124
3170
|
const savedTheme = localStorage.getItem(`${keyPrefix}theme`);
|
|
3125
3171
|
if (savedTheme) {
|
|
3126
3172
|
try {
|
|
@@ -3209,7 +3255,7 @@ function useChatTheme() {
|
|
|
3209
3255
|
};
|
|
3210
3256
|
}, [keyPrefix]);
|
|
3211
3257
|
(0, import_react15.useEffect)(() => {
|
|
3212
|
-
localStorage.setItem(`${keyPrefix}theme`, JSON.stringify(theme));
|
|
3258
|
+
if (keyPrefix) localStorage.setItem(`${keyPrefix}theme`, JSON.stringify(theme));
|
|
3213
3259
|
const root = document.documentElement;
|
|
3214
3260
|
if (themeMode === "light") {
|
|
3215
3261
|
root.style.setProperty("--chat-primary", hexToHSL(theme.lightPrimary));
|
|
@@ -3225,23 +3271,23 @@ function useChatTheme() {
|
|
|
3225
3271
|
window.dispatchEvent(new CustomEvent("chat-theme-change", { detail: theme }));
|
|
3226
3272
|
}, [theme, themeMode, keyPrefix]);
|
|
3227
3273
|
(0, import_react15.useEffect)(() => {
|
|
3228
|
-
localStorage.setItem(`${keyPrefix}conversation-starters`, JSON.stringify(conversationStarters));
|
|
3274
|
+
if (keyPrefix) localStorage.setItem(`${keyPrefix}conversation-starters`, JSON.stringify(conversationStarters));
|
|
3229
3275
|
window.dispatchEvent(new CustomEvent("chat-starters-change", { detail: conversationStarters }));
|
|
3230
3276
|
}, [conversationStarters, keyPrefix]);
|
|
3231
3277
|
(0, import_react15.useEffect)(() => {
|
|
3232
|
-
localStorage.setItem(`${keyPrefix}model`, model);
|
|
3278
|
+
if (keyPrefix) localStorage.setItem(`${keyPrefix}model`, model);
|
|
3233
3279
|
window.dispatchEvent(new CustomEvent("chat-model-change", { detail: model }));
|
|
3234
3280
|
}, [model, keyPrefix]);
|
|
3235
3281
|
(0, import_react15.useEffect)(() => {
|
|
3236
|
-
localStorage.setItem(`${keyPrefix}system-prompt`, systemPrompt);
|
|
3282
|
+
if (keyPrefix) localStorage.setItem(`${keyPrefix}system-prompt`, systemPrompt);
|
|
3237
3283
|
window.dispatchEvent(new CustomEvent("chat-system-prompt-change", { detail: systemPrompt }));
|
|
3238
3284
|
}, [systemPrompt, keyPrefix]);
|
|
3239
3285
|
(0, import_react15.useEffect)(() => {
|
|
3240
|
-
localStorage.setItem(`${keyPrefix}temperature`, temperature.toString());
|
|
3286
|
+
if (keyPrefix) localStorage.setItem(`${keyPrefix}temperature`, temperature.toString());
|
|
3241
3287
|
window.dispatchEvent(new CustomEvent("chat-temperature-change", { detail: temperature }));
|
|
3242
3288
|
}, [temperature, keyPrefix]);
|
|
3243
3289
|
(0, import_react15.useEffect)(() => {
|
|
3244
|
-
localStorage.setItem(`${keyPrefix}theme-mode`, themeMode);
|
|
3290
|
+
if (keyPrefix) localStorage.setItem(`${keyPrefix}theme-mode`, themeMode);
|
|
3245
3291
|
window.dispatchEvent(new CustomEvent("chat-theme-mode-change", { detail: themeMode }));
|
|
3246
3292
|
}, [themeMode, keyPrefix]);
|
|
3247
3293
|
const updateColor = (key, value) => {
|
|
@@ -3448,6 +3494,7 @@ function DialogDescription({
|
|
|
3448
3494
|
ToolHeader,
|
|
3449
3495
|
ToolInput,
|
|
3450
3496
|
ToolOutput,
|
|
3497
|
+
clearChatStorage,
|
|
3451
3498
|
fontOptions,
|
|
3452
3499
|
useChatStorageKey,
|
|
3453
3500
|
useChatTheme
|