@chatwidgetai/chat-widget 0.1.8 → 0.2.0
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/ai-chat-widget.umd.js +404 -233
- package/dist/ai-chat-widget.umd.js.map +1 -1
- package/dist/api/client.d.ts +9 -0
- package/dist/api/client.d.ts.map +1 -1
- package/dist/components/ChatWidget.d.ts +0 -1
- package/dist/components/ChatWidget.d.ts.map +1 -1
- package/dist/components/ChatWindow.d.ts +5 -0
- package/dist/components/ChatWindow.d.ts.map +1 -1
- package/dist/components/Message.d.ts +0 -1
- package/dist/components/Message.d.ts.map +1 -1
- package/dist/components/MessageList.d.ts +2 -0
- package/dist/components/MessageList.d.ts.map +1 -1
- package/dist/components/SuggestedQuestions.d.ts +1 -1
- package/dist/components/SuggestedQuestions.d.ts.map +1 -1
- package/dist/hooks/useChat.d.ts.map +1 -1
- package/dist/index.esm.js +405 -234
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +404 -233
- package/dist/index.js.map +1 -1
- package/dist/types/index.d.ts +22 -6
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/generateThemeStyles.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -17533,6 +17533,124 @@
|
|
|
17533
17533
|
throw error;
|
|
17534
17534
|
}
|
|
17535
17535
|
}
|
|
17536
|
+
/**
|
|
17537
|
+
* Stream chat message responses
|
|
17538
|
+
*/
|
|
17539
|
+
async *sendMessageStream(conversationId, message, fileIds) {
|
|
17540
|
+
const response = await fetch(`${this.config.apiUrl}/api/widget/${this.config.widgetId}/chat`, {
|
|
17541
|
+
method: 'POST',
|
|
17542
|
+
headers: {
|
|
17543
|
+
'Content-Type': 'application/json',
|
|
17544
|
+
},
|
|
17545
|
+
body: JSON.stringify({
|
|
17546
|
+
conversationId: conversationId,
|
|
17547
|
+
message,
|
|
17548
|
+
fileIds,
|
|
17549
|
+
timeZone: this.getTimeZone(),
|
|
17550
|
+
}),
|
|
17551
|
+
});
|
|
17552
|
+
if (!response.ok) {
|
|
17553
|
+
throw await buildApiError(response, 'Failed to send message');
|
|
17554
|
+
}
|
|
17555
|
+
if (!response.body) {
|
|
17556
|
+
throw new Error('Response body is null');
|
|
17557
|
+
}
|
|
17558
|
+
const reader = response.body.getReader();
|
|
17559
|
+
const decoder = new TextDecoder();
|
|
17560
|
+
let buffer = '';
|
|
17561
|
+
try {
|
|
17562
|
+
while (true) {
|
|
17563
|
+
const { done, value } = await reader.read();
|
|
17564
|
+
if (done)
|
|
17565
|
+
break;
|
|
17566
|
+
buffer += decoder.decode(value, { stream: true });
|
|
17567
|
+
const lines = buffer.split('\n');
|
|
17568
|
+
buffer = lines.pop() || '';
|
|
17569
|
+
for (const line of lines) {
|
|
17570
|
+
if (line.startsWith('data: ')) {
|
|
17571
|
+
try {
|
|
17572
|
+
const data = JSON.parse(line.slice(6));
|
|
17573
|
+
// Handle error events
|
|
17574
|
+
if (data.type === 'error') {
|
|
17575
|
+
throw new Error(data.error || 'Stream error');
|
|
17576
|
+
}
|
|
17577
|
+
// Yield ConversationMessage objects
|
|
17578
|
+
if (data.id) {
|
|
17579
|
+
yield data;
|
|
17580
|
+
}
|
|
17581
|
+
}
|
|
17582
|
+
catch (e) {
|
|
17583
|
+
console.error('[Widget API Client] Failed to parse SSE data:', line, e);
|
|
17584
|
+
throw e;
|
|
17585
|
+
}
|
|
17586
|
+
}
|
|
17587
|
+
}
|
|
17588
|
+
}
|
|
17589
|
+
}
|
|
17590
|
+
finally {
|
|
17591
|
+
reader.releaseLock();
|
|
17592
|
+
}
|
|
17593
|
+
}
|
|
17594
|
+
/**
|
|
17595
|
+
* Stream agent message responses with tool execution
|
|
17596
|
+
* Handles streaming events from backend and yields ConversationMessage updates
|
|
17597
|
+
*/
|
|
17598
|
+
async *sendAgentMessageStream(conversationId, message, fileIds) {
|
|
17599
|
+
const response = await fetch(`${this.config.apiUrl}/api/widget/${this.config.widgetId}/agent`, {
|
|
17600
|
+
method: 'POST',
|
|
17601
|
+
headers: {
|
|
17602
|
+
'Content-Type': 'application/json',
|
|
17603
|
+
},
|
|
17604
|
+
body: JSON.stringify({
|
|
17605
|
+
conversationId: conversationId,
|
|
17606
|
+
message,
|
|
17607
|
+
fileIds,
|
|
17608
|
+
timeZone: this.getTimeZone(),
|
|
17609
|
+
}),
|
|
17610
|
+
});
|
|
17611
|
+
if (!response.ok) {
|
|
17612
|
+
throw await buildApiError(response, 'Failed to send agent message');
|
|
17613
|
+
}
|
|
17614
|
+
if (!response.body) {
|
|
17615
|
+
throw new Error('Response body is null');
|
|
17616
|
+
}
|
|
17617
|
+
const reader = response.body.getReader();
|
|
17618
|
+
const decoder = new TextDecoder();
|
|
17619
|
+
let buffer = '';
|
|
17620
|
+
try {
|
|
17621
|
+
while (true) {
|
|
17622
|
+
const { done, value } = await reader.read();
|
|
17623
|
+
if (done)
|
|
17624
|
+
break;
|
|
17625
|
+
buffer += decoder.decode(value, { stream: true });
|
|
17626
|
+
const lines = buffer.split('\n');
|
|
17627
|
+
buffer = lines.pop() || '';
|
|
17628
|
+
for (const line of lines) {
|
|
17629
|
+
if (line.startsWith('data: ')) {
|
|
17630
|
+
try {
|
|
17631
|
+
const data = JSON.parse(line.slice(6));
|
|
17632
|
+
// Handle error events
|
|
17633
|
+
if (data.type === 'error') {
|
|
17634
|
+
throw new Error(data.error || 'Stream error');
|
|
17635
|
+
}
|
|
17636
|
+
// Yield ConversationMessage objects that come from the backend
|
|
17637
|
+
// The backend yields full ConversationMessage objects during streaming
|
|
17638
|
+
if (data.id) {
|
|
17639
|
+
yield data;
|
|
17640
|
+
}
|
|
17641
|
+
}
|
|
17642
|
+
catch (e) {
|
|
17643
|
+
console.error('[Widget API Client] Failed to parse SSE data:', line, e);
|
|
17644
|
+
throw e;
|
|
17645
|
+
}
|
|
17646
|
+
}
|
|
17647
|
+
}
|
|
17648
|
+
}
|
|
17649
|
+
}
|
|
17650
|
+
finally {
|
|
17651
|
+
reader.releaseLock();
|
|
17652
|
+
}
|
|
17653
|
+
}
|
|
17536
17654
|
/**
|
|
17537
17655
|
* Submit feedback for a message
|
|
17538
17656
|
*/
|
|
@@ -17880,7 +17998,7 @@
|
|
|
17880
17998
|
console.log('[useChat] Config fetched successfully:', {
|
|
17881
17999
|
hasAppearance: !!config.appearance,
|
|
17882
18000
|
});
|
|
17883
|
-
const persistConversation = config.
|
|
18001
|
+
const persistConversation = config.settings.persistConversation ?? true;
|
|
17884
18002
|
let conversationId = '';
|
|
17885
18003
|
let messages = [];
|
|
17886
18004
|
if (persistConversation && isStorageAvailable()) {
|
|
@@ -17928,14 +18046,14 @@
|
|
|
17928
18046
|
}, [widgetId, apiUrl, onError]);
|
|
17929
18047
|
// Save conversation when messages change
|
|
17930
18048
|
reactExports.useEffect(() => {
|
|
17931
|
-
const persistConversation = state.config?.
|
|
18049
|
+
const persistConversation = state.config?.settings.persistConversation ?? true;
|
|
17932
18050
|
if (persistConversation &&
|
|
17933
18051
|
isStorageAvailable() &&
|
|
17934
18052
|
state.messages.length > 0 &&
|
|
17935
18053
|
state.conversationId) {
|
|
17936
18054
|
saveConversation(widgetId, state.conversationId, state.messages);
|
|
17937
18055
|
}
|
|
17938
|
-
}, [widgetId, state.messages, state.conversationId, state.config?.
|
|
18056
|
+
}, [widgetId, state.messages, state.conversationId, state.config?.settings.persistConversation]);
|
|
17939
18057
|
/**
|
|
17940
18058
|
* Send a message
|
|
17941
18059
|
*/
|
|
@@ -17957,8 +18075,8 @@
|
|
|
17957
18075
|
setState(prev => ({
|
|
17958
18076
|
...prev,
|
|
17959
18077
|
messages: [...prev.messages, userMessage],
|
|
17960
|
-
isLoading:
|
|
17961
|
-
isTyping: true,
|
|
18078
|
+
isLoading: false, // Don't show loading, will show typing when stream starts
|
|
18079
|
+
isTyping: true, // Show typing indicator immediately
|
|
17962
18080
|
error: null,
|
|
17963
18081
|
}));
|
|
17964
18082
|
onMessage?.(userMessage);
|
|
@@ -18004,71 +18122,56 @@
|
|
|
18004
18122
|
}
|
|
18005
18123
|
// Determine if widget has actions (use agent endpoint)
|
|
18006
18124
|
const useAgent = state.config?.behavior.agentic || (state.config?.actions && state.config.actions.length > 0);
|
|
18007
|
-
|
|
18008
|
-
|
|
18009
|
-
|
|
18010
|
-
|
|
18011
|
-
|
|
18012
|
-
|
|
18013
|
-
|
|
18014
|
-
|
|
18015
|
-
|
|
18016
|
-
|
|
18017
|
-
|
|
18018
|
-
|
|
18019
|
-
|
|
18020
|
-
|
|
18021
|
-
|
|
18022
|
-
|
|
18023
|
-
|
|
18024
|
-
|
|
18025
|
-
|
|
18026
|
-
|
|
18027
|
-
|
|
18028
|
-
|
|
18029
|
-
|
|
18030
|
-
|
|
18031
|
-
|
|
18032
|
-
|
|
18033
|
-
|
|
18034
|
-
|
|
18035
|
-
|
|
18036
|
-
|
|
18037
|
-
|
|
18038
|
-
|
|
18039
|
-
|
|
18040
|
-
|
|
18041
|
-
|
|
18042
|
-
|
|
18043
|
-
|
|
18044
|
-
|
|
18045
|
-
|
|
18046
|
-
|
|
18047
|
-
isLoading: false,
|
|
18048
|
-
isTyping: false,
|
|
18049
|
-
error: errorContent,
|
|
18050
|
-
}));
|
|
18051
|
-
onMessage?.(errorMessage);
|
|
18125
|
+
// Stream the response
|
|
18126
|
+
let lastStreamedMessage = null;
|
|
18127
|
+
const stream = useAgent
|
|
18128
|
+
? apiClient.current.sendAgentMessageStream(conversationId, trimmedContent, fileIds)
|
|
18129
|
+
: apiClient.current.sendMessageStream(conversationId, trimmedContent, fileIds);
|
|
18130
|
+
for await (const message of stream) {
|
|
18131
|
+
lastStreamedMessage = message;
|
|
18132
|
+
// Update state with streamed message
|
|
18133
|
+
setState(prev => {
|
|
18134
|
+
const existingIndex = prev.messages.findIndex(m => m.id === message.id);
|
|
18135
|
+
if (existingIndex >= 0) {
|
|
18136
|
+
// Update existing streaming message
|
|
18137
|
+
const newMessages = [...prev.messages];
|
|
18138
|
+
newMessages[existingIndex] = message;
|
|
18139
|
+
// Show typing indicator if:
|
|
18140
|
+
// 1. Message is streaming AND has no content (waiting for first token or after tool call)
|
|
18141
|
+
// 2. Message is a tool execution (shows loading spinner on the tool)
|
|
18142
|
+
const isAIMessage = message.message.type === 'ai';
|
|
18143
|
+
const hasContent = isAIMessage && message.message.content.trim().length > 0;
|
|
18144
|
+
const isToolExecuting = message.toolExecuting !== undefined;
|
|
18145
|
+
return {
|
|
18146
|
+
...prev,
|
|
18147
|
+
messages: newMessages,
|
|
18148
|
+
isTyping: (message.isStreaming && !hasContent && isAIMessage) || isToolExecuting,
|
|
18149
|
+
isLoading: false,
|
|
18150
|
+
};
|
|
18151
|
+
}
|
|
18152
|
+
else {
|
|
18153
|
+
// Add new streaming message
|
|
18154
|
+
const isAIMessage = message.message.type === 'ai';
|
|
18155
|
+
const hasContent = isAIMessage && message.message.content.trim().length > 0;
|
|
18156
|
+
const isToolExecuting = message.toolExecuting !== undefined;
|
|
18157
|
+
return {
|
|
18158
|
+
...prev,
|
|
18159
|
+
messages: [...prev.messages, message],
|
|
18160
|
+
isTyping: (message.isStreaming && !hasContent && isAIMessage) || isToolExecuting,
|
|
18161
|
+
isLoading: false,
|
|
18162
|
+
};
|
|
18163
|
+
}
|
|
18164
|
+
});
|
|
18052
18165
|
}
|
|
18053
|
-
|
|
18054
|
-
|
|
18055
|
-
|
|
18056
|
-
|
|
18057
|
-
|
|
18058
|
-
|
|
18059
|
-
|
|
18060
|
-
|
|
18061
|
-
|
|
18062
|
-
timestamp: response.timestamp || new Date().toISOString(),
|
|
18063
|
-
sources: response.sources || [],
|
|
18064
|
-
};
|
|
18065
|
-
setState(prev => ({
|
|
18066
|
-
...prev,
|
|
18067
|
-
messages: [...prev.messages, assistantMessage],
|
|
18068
|
-
isLoading: false,
|
|
18069
|
-
isTyping: false,
|
|
18070
|
-
}));
|
|
18071
|
-
onMessage?.(assistantMessage);
|
|
18166
|
+
// Stream completed - finalize state
|
|
18167
|
+
setState(prev => ({
|
|
18168
|
+
...prev,
|
|
18169
|
+
isLoading: false,
|
|
18170
|
+
isTyping: false,
|
|
18171
|
+
}));
|
|
18172
|
+
// Notify about final message
|
|
18173
|
+
if (lastStreamedMessage) {
|
|
18174
|
+
onMessage?.(lastStreamedMessage);
|
|
18072
18175
|
}
|
|
18073
18176
|
}
|
|
18074
18177
|
catch (error) {
|
|
@@ -18126,11 +18229,11 @@
|
|
|
18126
18229
|
conversationId: '',
|
|
18127
18230
|
error: null,
|
|
18128
18231
|
}));
|
|
18129
|
-
const persistConversation = state.config?.
|
|
18232
|
+
const persistConversation = state.config?.settings.persistConversation ?? true;
|
|
18130
18233
|
if (persistConversation && isStorageAvailable()) {
|
|
18131
18234
|
clearConversation(widgetId);
|
|
18132
18235
|
}
|
|
18133
|
-
}, [widgetId, state.config?.
|
|
18236
|
+
}, [widgetId, state.config?.settings.persistConversation]);
|
|
18134
18237
|
/**
|
|
18135
18238
|
* Submit feedback for a message
|
|
18136
18239
|
*/
|
|
@@ -18157,7 +18260,7 @@
|
|
|
18157
18260
|
* Load conversation history list from localStorage
|
|
18158
18261
|
*/
|
|
18159
18262
|
const loadConversations = reactExports.useCallback(() => {
|
|
18160
|
-
const persistConversation = state.config?.
|
|
18263
|
+
const persistConversation = state.config?.settings.persistConversation ?? true;
|
|
18161
18264
|
if (!persistConversation || !isStorageAvailable()) {
|
|
18162
18265
|
setConversations([]);
|
|
18163
18266
|
return;
|
|
@@ -18170,12 +18273,12 @@
|
|
|
18170
18273
|
messageCount: entry.messageCount,
|
|
18171
18274
|
startedAt: entry.lastUpdated,
|
|
18172
18275
|
})));
|
|
18173
|
-
}, [widgetId, state.config?.
|
|
18276
|
+
}, [widgetId, state.config?.settings.persistConversation]);
|
|
18174
18277
|
/**
|
|
18175
18278
|
* Switch to a different conversation (from localStorage first, then fetch from server if needed)
|
|
18176
18279
|
*/
|
|
18177
18280
|
const switchConversation = reactExports.useCallback(async (conversationId) => {
|
|
18178
|
-
const persistConversation = state.config?.
|
|
18281
|
+
const persistConversation = state.config?.settings.persistConversation ?? true;
|
|
18179
18282
|
// First try to load from localStorage
|
|
18180
18283
|
if (persistConversation && isStorageAvailable()) {
|
|
18181
18284
|
const stored = loadConversationById(widgetId, conversationId);
|
|
@@ -18208,7 +18311,7 @@
|
|
|
18208
18311
|
const errorInfo = deriveErrorInfo(error);
|
|
18209
18312
|
setState(prev => ({ ...prev, isLoading: false, error: errorInfo.message }));
|
|
18210
18313
|
}
|
|
18211
|
-
}, [widgetId, state.config?.
|
|
18314
|
+
}, [widgetId, state.config?.settings.persistConversation]);
|
|
18212
18315
|
/**
|
|
18213
18316
|
* Start a new conversation (keeps history)
|
|
18214
18317
|
*/
|
|
@@ -18220,11 +18323,11 @@
|
|
|
18220
18323
|
error: null,
|
|
18221
18324
|
}));
|
|
18222
18325
|
// Clear active conversation but keep history
|
|
18223
|
-
const persistConversation = state.config?.
|
|
18326
|
+
const persistConversation = state.config?.settings.persistConversation ?? true;
|
|
18224
18327
|
if (persistConversation && isStorageAvailable()) {
|
|
18225
18328
|
clearConversation(widgetId);
|
|
18226
18329
|
}
|
|
18227
|
-
}, [widgetId, state.config?.
|
|
18330
|
+
}, [widgetId, state.config?.settings.persistConversation]);
|
|
18228
18331
|
return {
|
|
18229
18332
|
messages: state.messages,
|
|
18230
18333
|
isLoading: state.isLoading,
|
|
@@ -38928,7 +39031,7 @@
|
|
|
38928
39031
|
return (jsxRuntimeExports.jsxs("div", { className: "ai-chat-sources", children: [jsxRuntimeExports.jsxs("button", { className: "ai-chat-sources-toggle", onClick: () => setIsExpanded(!isExpanded), "aria-expanded": isExpanded, children: [jsxRuntimeExports.jsx("span", { className: "ai-chat-sources-icon", children: isExpanded ? '▼' : '▶' }), jsxRuntimeExports.jsxs("span", { className: "ai-chat-sources-title", children: [sources.length, " source", sources.length > 1 ? 's' : ''] })] }), isExpanded && displayMode !== 'minimal' && (jsxRuntimeExports.jsx("div", { className: "ai-chat-sources-list", children: sources.map((source, index) => (jsxRuntimeExports.jsxs("div", { className: "ai-chat-source-item", children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-source-number", children: [index + 1, "."] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-source-details", children: [displayMode === 'with-score' && source.score && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-source-score", children: ["Score: ", (source.score * 100).toFixed(0), "%"] })), (displayMode === 'with-content' || displayMode === 'full') && source.doc.pageContent && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-source-content", children: [source.doc.pageContent.substring(0, 100), source.doc.pageContent.length > 100 ? '...' : ''] })), displayMode === 'full' && (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [source.score && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-source-score", children: ["Score: ", (source.score * 100).toFixed(0), "%"] })), source.doc.metadata && Object.keys(source.doc.metadata).length > 0 && (jsxRuntimeExports.jsx("div", { className: "ai-chat-source-metadata", children: Object.entries(source.doc.metadata).map(([key, value]) => (jsxRuntimeExports.jsxs("span", { className: "ai-chat-source-meta-item", children: [key, ": ", String(value)] }, key))) }))] }))] })] }, `${source.kbId}-${source.doc.id}-${index}`))) }))] }));
|
|
38929
39032
|
};
|
|
38930
39033
|
|
|
38931
|
-
const Message = ({ message, showTimestamp = true, enableFeedback = true, showSources = true, sourceDisplayMode = 'with-score', onFeedback,
|
|
39034
|
+
const Message = ({ message, showTimestamp = true, enableFeedback = true, showSources = true, sourceDisplayMode = 'with-score', onFeedback, }) => {
|
|
38932
39035
|
const formatTime = (timestamp) => {
|
|
38933
39036
|
const date = typeof timestamp === 'string' ? new Date(timestamp) : timestamp;
|
|
38934
39037
|
return date.toLocaleTimeString('en-US', {
|
|
@@ -38937,72 +39040,84 @@
|
|
|
38937
39040
|
hour12: true,
|
|
38938
39041
|
});
|
|
38939
39042
|
};
|
|
38940
|
-
// Map message type to CSS class
|
|
38941
|
-
const messageClass = message.message.type === 'human' ? 'user' :
|
|
38942
|
-
message.message.type === 'ai' ? 'assistant' :
|
|
38943
|
-
message.message.type === 'system' ? 'system' : 'tool';
|
|
38944
|
-
const isAssistant = message.message.type === 'ai';
|
|
38945
|
-
const isSystem = message.message.type === 'system';
|
|
38946
|
-
const isTool = message.message.type === 'tool';
|
|
38947
|
-
const isHuman = message.message.type === 'human';
|
|
38948
|
-
const userMessage = isHuman ? message.message.content.split('--- File Content ---')[0] : '';
|
|
38949
|
-
const aiContent = isAssistant ? (message.message.content || '') : '';
|
|
38950
|
-
const aiHasContent = isAssistant ? aiContent.trim().length > 0 : false;
|
|
38951
|
-
const renderAssistant = () => {
|
|
38952
|
-
// Only render assistant bubble if there's textual content
|
|
38953
|
-
return jsxRuntimeExports.jsx(Markdown, { children: aiContent });
|
|
38954
|
-
};
|
|
38955
39043
|
const formatToolName = (name) => {
|
|
38956
|
-
|
|
38957
|
-
|
|
38958
|
-
// Convert snake_case to Title Case
|
|
38959
|
-
formatted = formatted
|
|
39044
|
+
return name
|
|
39045
|
+
.replace(/^(action_|tool_)/, '')
|
|
38960
39046
|
.split('_')
|
|
38961
39047
|
.map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
|
|
38962
39048
|
.join(' ');
|
|
38963
|
-
return formatted;
|
|
38964
|
-
};
|
|
38965
|
-
const renderTool = () => {
|
|
38966
|
-
const tool = message.message;
|
|
38967
|
-
const rawToolName = (toolCallNameById && toolCallNameById[tool.tool_call_id]) || 'Tool';
|
|
38968
|
-
const displayName = formatToolName(rawToolName);
|
|
38969
|
-
return (jsxRuntimeExports.jsxs("div", { className: "ai-chat-tool-message", title: rawToolName, children: [jsxRuntimeExports.jsx("span", { className: "tool-finished", children: jsxRuntimeExports.jsx("span", { className: "tool-check", children: "\u2713" }) }), jsxRuntimeExports.jsx("span", { className: "tool-name", children: displayName })] }));
|
|
38970
39049
|
};
|
|
38971
|
-
|
|
38972
|
-
|
|
38973
|
-
|
|
39050
|
+
const SpinnerIcon = () => (jsxRuntimeExports.jsx("svg", { className: "ai-chat-tool-spinner", width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntimeExports.jsx("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" }) }));
|
|
39051
|
+
const CheckIcon = () => (jsxRuntimeExports.jsx("svg", { className: "ai-chat-tool-check", width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntimeExports.jsx("polyline", { points: "20 6 9 17 4 12" }) }));
|
|
39052
|
+
const ErrorIcon = () => (jsxRuntimeExports.jsx("svg", { className: "ai-chat-tool-error", width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntimeExports.jsx("path", { d: "M18 6L6 18M6 6l12 12" }) }));
|
|
39053
|
+
const msgType = message.message.type;
|
|
39054
|
+
const isError = message.isError || false;
|
|
39055
|
+
const isTool = msgType === 'tool';
|
|
39056
|
+
const isAssistant = msgType === 'ai';
|
|
39057
|
+
const isSystem = msgType === 'system';
|
|
39058
|
+
const isHuman = msgType === 'human';
|
|
39059
|
+
// Tool message rendering - show as a minimal pill
|
|
39060
|
+
if (isTool) {
|
|
39061
|
+
// Get tool name from toolExecuting (during execution) or message.name (persisted)
|
|
39062
|
+
const toolName = message.toolExecuting || message.message.name || 'Tool';
|
|
39063
|
+
const hasError = isError;
|
|
39064
|
+
return (jsxRuntimeExports.jsx("div", { className: "ai-chat-message tool", children: jsxRuntimeExports.jsxs("div", { className: `ai-chat-tool-message ${hasError ? 'error' : ''}`, title: toolName, children: [message.isStreaming ? (jsxRuntimeExports.jsx(SpinnerIcon, {})) : hasError ? (jsxRuntimeExports.jsx(ErrorIcon, {})) : (jsxRuntimeExports.jsx(CheckIcon, {})), jsxRuntimeExports.jsx("span", { className: "tool-name", children: formatToolName(toolName) })] }) }));
|
|
39065
|
+
}
|
|
39066
|
+
// AI message rendering
|
|
39067
|
+
if (isAssistant) {
|
|
39068
|
+
const aiContent = message.message.content || '';
|
|
39069
|
+
const hasContent = aiContent.trim().length > 0;
|
|
39070
|
+
if (!hasContent)
|
|
39071
|
+
return null;
|
|
39072
|
+
return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-message assistant ${isError ? 'error' : ''}`, children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-message-content", children: [isError && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-error-indicator", children: [jsxRuntimeExports.jsx("span", { className: "error-icon", children: "\u26A0\uFE0F" }), jsxRuntimeExports.jsx("span", { className: "error-text", children: "Error" })] })), jsxRuntimeExports.jsx(Markdown, { children: aiContent })] }), showTimestamp && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-message-meta", children: [jsxRuntimeExports.jsx("span", { className: "ai-chat-message-timestamp", children: formatTime(message.timestamp) }), enableFeedback && onFeedback && (jsxRuntimeExports.jsx(FeedbackButtons, { messageId: message.id, currentFeedback: message.feedback, onFeedback: onFeedback }))] })), showSources && message.sources?.length > 0 && (jsxRuntimeExports.jsx(Sources, { sources: message.sources, displayMode: sourceDisplayMode }))] }));
|
|
39073
|
+
}
|
|
39074
|
+
// System message rendering
|
|
39075
|
+
if (isSystem) {
|
|
39076
|
+
return (jsxRuntimeExports.jsxs("div", { className: "ai-chat-message system", children: [jsxRuntimeExports.jsx("div", { className: "ai-chat-message-content", children: jsxRuntimeExports.jsxs("div", { className: "ai-chat-system-message", children: [jsxRuntimeExports.jsx("span", { className: "system-icon", children: "\u2139\uFE0F" }), message.message.content] }) }), showTimestamp && (jsxRuntimeExports.jsx("div", { className: "ai-chat-message-meta", children: jsxRuntimeExports.jsx("span", { className: "ai-chat-message-timestamp", children: formatTime(message.timestamp) }) }))] }));
|
|
38974
39077
|
}
|
|
38975
|
-
|
|
38976
|
-
|
|
38977
|
-
|
|
38978
|
-
|
|
39078
|
+
// Human message rendering
|
|
39079
|
+
if (isHuman) {
|
|
39080
|
+
const userContent = message.message.content.split('--- File Content ---')[0];
|
|
39081
|
+
return (jsxRuntimeExports.jsxs("div", { className: "ai-chat-message user", children: [jsxRuntimeExports.jsx("div", { className: "ai-chat-message-content", children: userContent }), showTimestamp && (jsxRuntimeExports.jsx("div", { className: "ai-chat-message-meta", children: jsxRuntimeExports.jsx("span", { className: "ai-chat-message-timestamp", children: formatTime(message.timestamp) }) }))] }));
|
|
39082
|
+
}
|
|
39083
|
+
return null;
|
|
38979
39084
|
};
|
|
38980
39085
|
|
|
38981
39086
|
const TypingIndicator = () => {
|
|
38982
39087
|
return (jsxRuntimeExports.jsx("div", { className: "ai-chat-message assistant", children: jsxRuntimeExports.jsxs("div", { className: "ai-chat-typing", children: [jsxRuntimeExports.jsx("span", { className: "ai-chat-typing-dot" }), jsxRuntimeExports.jsx("span", { className: "ai-chat-typing-dot" }), jsxRuntimeExports.jsx("span", { className: "ai-chat-typing-dot" })] }) }));
|
|
38983
39088
|
};
|
|
38984
39089
|
|
|
38985
|
-
const
|
|
39090
|
+
const SuggestedQuestions = ({ questions, onQuestionClick, }) => {
|
|
39091
|
+
if (!questions || questions.length === 0) {
|
|
39092
|
+
return null;
|
|
39093
|
+
}
|
|
39094
|
+
// Filter out empty questions
|
|
39095
|
+
const validQuestions = questions.filter(q => q && q.trim());
|
|
39096
|
+
if (validQuestions.length === 0) {
|
|
39097
|
+
return null;
|
|
39098
|
+
}
|
|
39099
|
+
return (jsxRuntimeExports.jsx("div", { className: "ai-chat-suggested-questions", children: jsxRuntimeExports.jsx("div", { className: "ai-chat-suggested-questions-list", children: validQuestions.slice(0, 5).map((question, index) => (jsxRuntimeExports.jsx("button", { className: "ai-chat-suggested-question", onClick: () => onQuestionClick(question), type: "button", children: jsxRuntimeExports.jsx("span", { className: "ai-chat-suggested-question-text", children: question }) }, index))) }) }));
|
|
39100
|
+
};
|
|
39101
|
+
|
|
39102
|
+
const MessageList = ({ messages, isTyping = false, showTypingIndicator = true, showTimestamps = true, enableFeedback = true, showSources = true, sourceDisplayMode = 'with-score', welcomeTitle, welcomeMessage, suggestedQuestions, onSuggestedQuestionClick, onFeedback, }) => {
|
|
39103
|
+
const containerRef = reactExports.useRef(null);
|
|
38986
39104
|
const messagesEndRef = reactExports.useRef(null);
|
|
38987
|
-
// Auto-scroll to bottom
|
|
39105
|
+
// Auto-scroll to bottom only on initial mount/load
|
|
38988
39106
|
reactExports.useEffect(() => {
|
|
38989
|
-
|
|
38990
|
-
|
|
38991
|
-
|
|
38992
|
-
|
|
38993
|
-
|
|
38994
|
-
|
|
38995
|
-
|
|
38996
|
-
|
|
38997
|
-
|
|
38998
|
-
|
|
38999
|
-
|
|
39000
|
-
}
|
|
39001
|
-
}
|
|
39107
|
+
const container = containerRef.current;
|
|
39108
|
+
if (!container)
|
|
39109
|
+
return;
|
|
39110
|
+
// Only scroll if content actually overflows AND the user is near the bottom.
|
|
39111
|
+
// This prevents the "first message" case from being pushed to the very bottom
|
|
39112
|
+
// (which looks like a huge empty gap above the first user message).
|
|
39113
|
+
const overflow = container.scrollHeight - container.clientHeight;
|
|
39114
|
+
const isOverflowing = overflow > 20;
|
|
39115
|
+
const nearBottom = container.scrollTop + container.clientHeight >= container.scrollHeight - 80;
|
|
39116
|
+
if (isOverflowing && nearBottom) {
|
|
39117
|
+
messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
|
|
39002
39118
|
}
|
|
39003
|
-
|
|
39004
|
-
},
|
|
39005
|
-
return (jsxRuntimeExports.jsxs("div", { className: "ai-chat-messages", role: "log", "aria-live": "polite", "aria-atomic": "false", children: [messages.length === 0 && (welcomeTitle || welcomeMessage) && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-welcome", children: [welcomeTitle && (jsxRuntimeExports.jsx("div", { className: "ai-chat-welcome-title", children: welcomeTitle })), welcomeMessage && (jsxRuntimeExports.jsx("div", { className: "ai-chat-welcome-text", children: welcomeMessage }))] })), messages.map((message) => (jsxRuntimeExports.jsx(Message, { message: message, showTimestamp: showTimestamps, enableFeedback: enableFeedback, showSources: showSources, sourceDisplayMode: sourceDisplayMode, toolCallNameById: toolCallNameById, onFeedback: onFeedback }, message.id))), isTyping && showTypingIndicator && jsxRuntimeExports.jsx(TypingIndicator, {}), jsxRuntimeExports.jsx("div", { ref: messagesEndRef })] }));
|
|
39119
|
+
}, [messages, isTyping]);
|
|
39120
|
+
return (jsxRuntimeExports.jsxs("div", { ref: containerRef, className: "ai-chat-messages", role: "log", "aria-live": "polite", "aria-atomic": "false", children: [(welcomeTitle || welcomeMessage) && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-welcome", children: [welcomeTitle && (jsxRuntimeExports.jsx("div", { className: "ai-chat-welcome-title", children: welcomeTitle })), welcomeMessage && (jsxRuntimeExports.jsx("div", { className: "ai-chat-welcome-text", children: welcomeMessage })), messages.length === 0 && onSuggestedQuestionClick && suggestedQuestions && suggestedQuestions.length > 0 && (jsxRuntimeExports.jsx(SuggestedQuestions, { questions: suggestedQuestions, onQuestionClick: onSuggestedQuestionClick }))] })), messages.map((message) => (jsxRuntimeExports.jsx(Message, { message: message, showTimestamp: showTimestamps, enableFeedback: enableFeedback, showSources: showSources, sourceDisplayMode: sourceDisplayMode, onFeedback: onFeedback }, message.id))), isTyping && showTypingIndicator && jsxRuntimeExports.jsx(TypingIndicator, {}), jsxRuntimeExports.jsx("div", { ref: messagesEndRef })] }));
|
|
39006
39121
|
};
|
|
39007
39122
|
|
|
39008
39123
|
// Allowed file types
|
|
@@ -39090,49 +39205,38 @@
|
|
|
39090
39205
|
return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-input-container ${separateFromChat ? 'separate' : 'integrated'}`, children: [selectedFiles.length > 0 && (jsxRuntimeExports.jsx("div", { className: "ai-chat-file-list", children: selectedFiles.map((file, index) => {
|
|
39091
39206
|
const ext = getFileExtension(file.name);
|
|
39092
39207
|
return (jsxRuntimeExports.jsxs("div", { className: "ai-chat-file-item", children: [jsxRuntimeExports.jsx("span", { className: "ai-chat-file-extension", children: ext }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-file-info", children: [jsxRuntimeExports.jsx("span", { className: "ai-chat-file-name", children: file.name }), jsxRuntimeExports.jsx("span", { className: "ai-chat-file-size", children: formatFileSize(file.size) })] }), jsxRuntimeExports.jsx("button", { className: "ai-chat-file-remove", onClick: () => handleRemoveFile(index), "aria-label": "Remove file", children: jsxRuntimeExports.jsx("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntimeExports.jsx("path", { d: "M18 6L6 18M6 6l12 12" }) }) })] }, index));
|
|
39093
|
-
}) })), jsxRuntimeExports.jsxs("div", { className: "ai-chat-input-wrapper", children: [enableFileUpload && (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("input", { ref: fileInputRef, type: "file", onChange: handleFileSelect, style: { display: 'none' }, multiple: true, accept: ALLOWED_EXTENSIONS.join(','), "aria-label": "File input" }), jsxRuntimeExports.jsx("button", { className: "ai-chat-file-button", onClick: () => fileInputRef.current?.click(), disabled: disabled, "aria-label": "Attach file", children: jsxRuntimeExports.jsx("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntimeExports.jsx("path", { d: "M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48" }) }) })] })), jsxRuntimeExports.jsx("textarea", { ref: textareaRef, className: "ai-chat-input", value: value, onChange: handleChange, onKeyDown: handleKeyDown, placeholder: placeholder, disabled: disabled, rows: 1, "aria-label": "Message input" }), jsxRuntimeExports.jsx("button", { className: `ai-chat-send-button ${canSend ? 'active' : ''}`, onClick: handleSend, disabled: disabled || !canSend, "aria-label": "Send message", children: jsxRuntimeExports.jsxs("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("path", { d: "
|
|
39094
|
-
};
|
|
39095
|
-
|
|
39096
|
-
const ArrowIcon = () => (jsxRuntimeExports.jsx("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntimeExports.jsx("path", { d: "M5 12h14M12 5l7 7-7 7" }) }));
|
|
39097
|
-
const SuggestedQuestions = ({ questions, onQuestionClick, }) => {
|
|
39098
|
-
if (!questions || questions.length === 0) {
|
|
39099
|
-
return null;
|
|
39100
|
-
}
|
|
39101
|
-
// Filter out empty questions
|
|
39102
|
-
const validQuestions = questions.filter(q => q && q.trim());
|
|
39103
|
-
if (validQuestions.length === 0) {
|
|
39104
|
-
return null;
|
|
39105
|
-
}
|
|
39106
|
-
return (jsxRuntimeExports.jsx("div", { className: "ai-chat-suggested-questions", children: jsxRuntimeExports.jsx("div", { className: "ai-chat-suggested-questions-list", children: validQuestions.slice(0, 3).map((question, index) => (jsxRuntimeExports.jsxs("button", { className: "ai-chat-suggested-question", onClick: () => onQuestionClick(question), type: "button", children: [jsxRuntimeExports.jsx("span", { className: "ai-chat-suggested-question-text", children: question }), jsxRuntimeExports.jsx("span", { className: "ai-chat-suggested-question-icon", children: jsxRuntimeExports.jsx(ArrowIcon, {}) })] }, index))) }) }));
|
|
39208
|
+
}) })), jsxRuntimeExports.jsxs("div", { className: "ai-chat-input-wrapper", children: [enableFileUpload && (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("input", { ref: fileInputRef, type: "file", onChange: handleFileSelect, style: { display: 'none' }, multiple: true, accept: ALLOWED_EXTENSIONS.join(','), "aria-label": "File input" }), jsxRuntimeExports.jsx("button", { className: "ai-chat-file-button", onClick: () => fileInputRef.current?.click(), disabled: disabled, "aria-label": "Attach file", children: jsxRuntimeExports.jsx("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntimeExports.jsx("path", { d: "M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48" }) }) })] })), jsxRuntimeExports.jsx("textarea", { ref: textareaRef, className: "ai-chat-input", value: value, onChange: handleChange, onKeyDown: handleKeyDown, placeholder: placeholder, disabled: disabled, rows: 1, "aria-label": "Message input" }), jsxRuntimeExports.jsx("button", { className: `ai-chat-send-button ${canSend ? 'active' : ''}`, onClick: handleSend, disabled: disabled || !canSend, "aria-label": "Send message", children: jsxRuntimeExports.jsxs("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("path", { d: "M12 19V5" }), jsxRuntimeExports.jsx("path", { d: "M5 12l7-7 7 7" })] }) })] })] }));
|
|
39107
39209
|
};
|
|
39108
39210
|
|
|
39109
|
-
const
|
|
39110
|
-
const
|
|
39111
|
-
const
|
|
39112
|
-
const BackIcon = () => (jsxRuntimeExports.jsx("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntimeExports.jsx("path", { d: "M19 12H5M12 19l-7-7 7-7" }) }));
|
|
39113
|
-
const ChatWindow = ({ messages, isLoading, isTyping, error, config, onSendMessage, onClose, onFeedback,
|
|
39211
|
+
const MenuIcon = () => (jsxRuntimeExports.jsxs("svg", { width: "26", height: "26", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("path", { d: "M4 10h16" }), jsxRuntimeExports.jsx("path", { d: "M10 14h10" })] }));
|
|
39212
|
+
const PlusIcon = () => (jsxRuntimeExports.jsxs("svg", { width: "26", height: "26", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("path", { d: "M12 5v14" }), jsxRuntimeExports.jsx("path", { d: "M5 12h14" })] }));
|
|
39213
|
+
const ChatWindow = ({ messages, isLoading, isTyping, error, config, onSendMessage, onClose: _onClose, onFeedback,
|
|
39114
39214
|
// Chat history props (only active when persistConversation is true)
|
|
39115
|
-
conversations = [], onLoadConversations, onSwitchConversation, onStartNewConversation, currentConversationId,
|
|
39215
|
+
conversations = [], onLoadConversations, onSwitchConversation, onStartNewConversation, currentConversationId,
|
|
39216
|
+
// Override props for live preview
|
|
39217
|
+
headerTitleOverride, welcomeTitleOverride, welcomeMessageOverride, placeholderOverride, suggestedQuestionsOverride, }) => {
|
|
39116
39218
|
console.log('[ChatWindow] Rendering ChatWindow component');
|
|
39117
39219
|
const appearance = config?.appearance;
|
|
39118
|
-
const
|
|
39119
|
-
//
|
|
39220
|
+
const settings = config?.settings;
|
|
39221
|
+
// Check if chat history should be shown (requires both persistConversation AND showChatHistory)
|
|
39222
|
+
const canShowHistory = (settings?.persistConversation ?? true) && (settings?.showChatHistory ?? true);
|
|
39223
|
+
// Apply overrides for live preview (overrides take priority over saved config)
|
|
39120
39224
|
const size = appearance?.size || 'medium';
|
|
39121
|
-
const headerTitle = appearance?.headerTitle
|
|
39122
|
-
const
|
|
39123
|
-
const
|
|
39225
|
+
const headerTitle = headerTitleOverride ?? appearance?.headerTitle ?? 'AI Assistant';
|
|
39226
|
+
const welcomeTitle = welcomeTitleOverride ?? appearance?.welcomeTitle ?? '';
|
|
39227
|
+
const welcomeMessage = welcomeMessageOverride ?? appearance?.welcomeMessage ?? '';
|
|
39228
|
+
const inputPlaceholder = placeholderOverride ?? appearance?.placeholder ?? 'Ask me anything...';
|
|
39124
39229
|
console.log('[ChatWindow] Appearance values:', {
|
|
39125
39230
|
size,
|
|
39126
39231
|
headerTitle,
|
|
39232
|
+
welcomeTitle,
|
|
39127
39233
|
welcomeMessage,
|
|
39128
39234
|
inputPlaceholder,
|
|
39129
39235
|
});
|
|
39130
|
-
// Track if suggested questions should be shown
|
|
39131
|
-
const [showSuggestedQuestions, setShowSuggestedQuestions] = reactExports.useState(true);
|
|
39132
39236
|
// Track if history panel is open
|
|
39133
39237
|
const [showHistory, setShowHistory] = reactExports.useState(false);
|
|
39134
|
-
//
|
|
39135
|
-
const
|
|
39238
|
+
// History exit animation when starting a new chat from overview
|
|
39239
|
+
const [isHistoryExiting, setIsHistoryExiting] = reactExports.useState(false);
|
|
39136
39240
|
// Load conversations when history panel opens
|
|
39137
39241
|
const handleOpenHistory = () => {
|
|
39138
39242
|
setShowHistory(true);
|
|
@@ -39147,30 +39251,37 @@
|
|
|
39147
39251
|
setShowHistory(false);
|
|
39148
39252
|
}
|
|
39149
39253
|
};
|
|
39150
|
-
// Handle new conversation
|
|
39151
39254
|
const handleNewConversation = () => {
|
|
39152
|
-
if (onStartNewConversation)
|
|
39153
|
-
|
|
39255
|
+
if (!onStartNewConversation)
|
|
39256
|
+
return;
|
|
39257
|
+
onStartNewConversation();
|
|
39258
|
+
setShowHistory(false);
|
|
39259
|
+
};
|
|
39260
|
+
const handleSendFromOverview = (content) => {
|
|
39261
|
+
const trimmed = content.trim();
|
|
39262
|
+
if (!trimmed)
|
|
39263
|
+
return;
|
|
39264
|
+
if (!onStartNewConversation) {
|
|
39265
|
+
// Fallback: just go back to chat and send
|
|
39154
39266
|
setShowHistory(false);
|
|
39267
|
+
onSendMessage(trimmed);
|
|
39268
|
+
return;
|
|
39155
39269
|
}
|
|
39270
|
+
setIsHistoryExiting(true);
|
|
39271
|
+
window.setTimeout(() => {
|
|
39272
|
+
onStartNewConversation();
|
|
39273
|
+
setShowHistory(false);
|
|
39274
|
+
setIsHistoryExiting(false);
|
|
39275
|
+
onSendMessage(trimmed);
|
|
39276
|
+
}, 240);
|
|
39156
39277
|
};
|
|
39157
|
-
// Hide suggested questions after first user message
|
|
39158
|
-
reactExports.useEffect(() => {
|
|
39159
|
-
const userMessages = messages.filter(m => m.message.type === 'human');
|
|
39160
|
-
if (userMessages.length > 0) {
|
|
39161
|
-
setShowSuggestedQuestions(false);
|
|
39162
|
-
}
|
|
39163
|
-
}, [messages]);
|
|
39164
39278
|
// Check if message limit is reached
|
|
39165
|
-
const maxMessages =
|
|
39279
|
+
const maxMessages = settings?.maxMessagesPerSession;
|
|
39166
39280
|
const userMessageCount = messages.filter(m => m.message.type === 'human').length;
|
|
39167
39281
|
const isLimitReached = maxMessages ? userMessageCount >= maxMessages : false;
|
|
39168
|
-
// Handle suggested question click
|
|
39169
39282
|
const handleQuestionClick = (question) => {
|
|
39170
|
-
setShowSuggestedQuestions(false);
|
|
39171
39283
|
onSendMessage(question);
|
|
39172
39284
|
};
|
|
39173
|
-
const hasMessages = messages.length > 0;
|
|
39174
39285
|
// Format date for conversation list
|
|
39175
39286
|
const formatDate = (dateString) => {
|
|
39176
39287
|
const date = new Date(dateString);
|
|
@@ -39185,7 +39296,7 @@
|
|
|
39185
39296
|
return `${diffDays} days ago`;
|
|
39186
39297
|
return date.toLocaleDateString();
|
|
39187
39298
|
};
|
|
39188
|
-
return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-window size-${size}`, role: "dialog", "aria-label": "Chat window", children: [jsxRuntimeExports.jsx("div", { className:
|
|
39299
|
+
return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-window size-${size}`, role: "dialog", "aria-label": "Chat window", children: [jsxRuntimeExports.jsx("div", { className: `ai-chat-header ${showHistory ? 'is-history' : ''}`, children: showHistory ? (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("div", { className: "ai-chat-title", children: headerTitle }), jsxRuntimeExports.jsx("button", { className: "ai-chat-header-button", onClick: handleNewConversation, "aria-label": "New chat", children: jsxRuntimeExports.jsx(PlusIcon, {}) })] })) : (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-header-content", children: [appearance?.logo && (jsxRuntimeExports.jsx("img", { src: appearance.logo, alt: "Logo", className: "ai-chat-logo" })), jsxRuntimeExports.jsx("div", { className: "ai-chat-title", children: headerTitle })] }), canShowHistory && (jsxRuntimeExports.jsx("div", { className: "ai-chat-header-actions", children: jsxRuntimeExports.jsx("button", { className: "ai-chat-close-button", onClick: handleOpenHistory, "aria-label": "Chat overview", children: jsxRuntimeExports.jsx(MenuIcon, {}) }) }))] })) }), showHistory ? (jsxRuntimeExports.jsxs("div", { className: "ai-chat-history-panel", children: [conversations.length === 0 ? (jsxRuntimeExports.jsx("div", { className: "ai-chat-history-empty", children: "No previous conversations" })) : (jsxRuntimeExports.jsx("div", { className: `ai-chat-history-list ${isHistoryExiting ? 'exiting' : ''}`, children: conversations.map((conv) => (jsxRuntimeExports.jsxs("button", { className: `ai-chat-history-item ${conv.id === currentConversationId ? 'active' : ''}`, onClick: () => handleSelectConversation(conv.id), children: [jsxRuntimeExports.jsx("div", { className: "ai-chat-history-item-preview", children: conv.preview }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-history-item-meta", children: [jsxRuntimeExports.jsx("span", { children: formatDate(conv.lastMessageAt) }), jsxRuntimeExports.jsxs("span", { children: [conv.messageCount, " messages"] })] })] }, conv.id))) })), jsxRuntimeExports.jsx(MessageInput, { onSend: (text) => handleSendFromOverview(text), placeholder: inputPlaceholder, disabled: isLoading, enableFileUpload: settings?.enableFileUpload })] })) : (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [error && (jsxRuntimeExports.jsx("div", { className: "ai-chat-error", role: "alert", children: error })), maxMessages && userMessageCount >= maxMessages - 2 && !isLimitReached && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-warning", role: "alert", children: [maxMessages - userMessageCount, " message", maxMessages - userMessageCount !== 1 ? 's' : '', " remaining"] })), isLimitReached && (jsxRuntimeExports.jsx("div", { className: "ai-chat-error", role: "alert", children: "Message limit reached. Please start a new conversation." })), jsxRuntimeExports.jsx(MessageList, { messages: messages, isTyping: isTyping, showTypingIndicator: settings?.showTypingIndicator, showTimestamps: settings?.showTimestamps, enableFeedback: settings?.enableFeedback, showSources: settings?.showSources, sourceDisplayMode: settings?.sourceDisplayMode, welcomeTitle: welcomeTitle || 'Welcome Message', welcomeMessage: welcomeMessage, suggestedQuestions: suggestedQuestionsOverride ?? settings?.suggestedQuestions, onSuggestedQuestionClick: handleQuestionClick, onFeedback: onFeedback }), jsxRuntimeExports.jsx(MessageInput, { onSend: onSendMessage, placeholder: isLimitReached ? 'Message limit reached' : inputPlaceholder, disabled: isLoading || isLimitReached, enableFileUpload: settings?.enableFileUpload })] }))] }));
|
|
39189
39300
|
};
|
|
39190
39301
|
|
|
39191
39302
|
/**
|
|
@@ -39368,22 +39479,18 @@
|
|
|
39368
39479
|
* Generate all CSS custom properties for the widget
|
|
39369
39480
|
*/
|
|
39370
39481
|
function generateThemeStyles(appearance, theme) {
|
|
39371
|
-
const
|
|
39372
|
-
? generateDarkPalette(appearance.accentColor)
|
|
39373
|
-
: generateLightPalette(appearance.accentColor);
|
|
39482
|
+
const hasAccentColor = appearance.accentColor && appearance.accentColor.trim() !== '';
|
|
39374
39483
|
// Liquid glass design - frosted glass with transparency
|
|
39375
39484
|
const isLight = theme === 'light';
|
|
39376
|
-
|
|
39485
|
+
// Base styles that don't depend on accent color
|
|
39486
|
+
const styles = {
|
|
39377
39487
|
// ========================================================================
|
|
39378
|
-
// BUTTON (FAB) -
|
|
39488
|
+
// BUTTON (FAB) - Base styles
|
|
39379
39489
|
// ========================================================================
|
|
39380
|
-
'--button-color': palette.accent,
|
|
39381
39490
|
'--button-opacity': '1',
|
|
39382
39491
|
'--button-size': '56px',
|
|
39383
|
-
'--button-icon-color': palette.userBubbleText,
|
|
39384
39492
|
'--button-border-radius': '50%',
|
|
39385
39493
|
'--button-border-width': '0px',
|
|
39386
|
-
'--button-border-color': palette.accent,
|
|
39387
39494
|
'--button-border-opacity': '1',
|
|
39388
39495
|
'--button-backdrop-blur': '20px',
|
|
39389
39496
|
'--button-shadow': `0 4px 24px rgba(0, 0, 0, 0.15), 0 2px 8px rgba(0, 0, 0, 0.1)`,
|
|
@@ -39406,7 +39513,6 @@
|
|
|
39406
39513
|
// ========================================================================
|
|
39407
39514
|
'--header-background': 'transparent',
|
|
39408
39515
|
'--header-opacity': '1',
|
|
39409
|
-
'--header-text-color': palette.accent,
|
|
39410
39516
|
'--header-border-bottom-width': '0px',
|
|
39411
39517
|
'--header-border-bottom-color': 'transparent',
|
|
39412
39518
|
'--header-border-bottom-opacity': '0',
|
|
@@ -39416,17 +39522,13 @@
|
|
|
39416
39522
|
// ========================================================================
|
|
39417
39523
|
'--chat-background': 'transparent',
|
|
39418
39524
|
'--chat-opacity': '1',
|
|
39419
|
-
'--welcome-color': palette.text,
|
|
39420
|
-
'--message-text-color': palette.text,
|
|
39421
39525
|
// ========================================================================
|
|
39422
39526
|
// MESSAGE BUBBLES - Glass style
|
|
39423
39527
|
// ========================================================================
|
|
39424
|
-
'--bubble-user-color': palette.userBubble,
|
|
39425
39528
|
'--bubble-user-opacity': '1',
|
|
39426
|
-
'--user-message-text': palette.userBubbleText,
|
|
39427
39529
|
'--bubble-assistant-color': isLight ? 'rgba(255, 255, 255, 0.8)' : 'rgba(255, 255, 255, 0.1)',
|
|
39428
39530
|
'--bubble-assistant-opacity': '1',
|
|
39429
|
-
'--assistant-message-text': isLight ?
|
|
39531
|
+
'--assistant-message-text': isLight ? '#000000' : '#f0f0f0',
|
|
39430
39532
|
'--bubble-border-radius': '20px',
|
|
39431
39533
|
'--bubble-border-width': isLight ? '1px' : '1px',
|
|
39432
39534
|
'--bubble-border-color': isLight ? 'rgba(0, 0, 0, 0.05)' : 'rgba(255, 255, 255, 0.08)',
|
|
@@ -39448,38 +39550,48 @@
|
|
|
39448
39550
|
'--input-border-color': isLight ? 'rgba(0, 0, 0, 0.08)' : 'rgba(255, 255, 255, 0.1)',
|
|
39449
39551
|
'--input-border-opacity': '1',
|
|
39450
39552
|
'--input-shadow': `inset 0 1px 3px rgba(0, 0, 0, 0.04), 0 2px 8px rgba(0, 0, 0, 0.04)`,
|
|
39451
|
-
'--send-button-background': palette.accent,
|
|
39452
39553
|
'--send-button-opacity': '1',
|
|
39453
39554
|
'--send-button-border-radius': '50%',
|
|
39454
39555
|
'--send-button-border-width': '0px',
|
|
39455
|
-
'--send-button-border-color': palette.accent,
|
|
39456
39556
|
'--send-button-border-opacity': '1',
|
|
39457
39557
|
// ========================================================================
|
|
39458
39558
|
// HOVER STATES
|
|
39459
39559
|
// ========================================================================
|
|
39460
39560
|
'--hover-button-scale': '1.08',
|
|
39461
39561
|
'--hover-button-opacity': '1',
|
|
39462
|
-
'--hover-input-border-color': palette.accent,
|
|
39463
39562
|
'--hover-send-button-opacity': '1',
|
|
39464
39563
|
'--hover-close-button-opacity': '1',
|
|
39465
39564
|
// ========================================================================
|
|
39466
|
-
// ACTIVE STATES
|
|
39467
|
-
// ========================================================================
|
|
39468
|
-
'--active-input-border-color': palette.accent,
|
|
39469
|
-
'--active-input-shadow': `0 0 0 4px ${withAlpha(palette.accent, 0.15)}`,
|
|
39470
|
-
// ========================================================================
|
|
39471
|
-
// GENERAL
|
|
39472
|
-
// ========================================================================
|
|
39473
|
-
'--primary-color': palette.accent,
|
|
39474
|
-
'--background-color': palette.background,
|
|
39475
|
-
'--text-color': palette.text,
|
|
39476
|
-
'--border-color': palette.border,
|
|
39477
|
-
// ========================================================================
|
|
39478
39565
|
// GLASS EFFECTS
|
|
39479
39566
|
// ========================================================================
|
|
39480
39567
|
'--glass-blur': '20px',
|
|
39481
39568
|
'--glass-saturation': '180%',
|
|
39482
39569
|
};
|
|
39570
|
+
// Only add accent-color-based styles if an accent color is provided
|
|
39571
|
+
if (hasAccentColor) {
|
|
39572
|
+
const palette = theme === 'dark'
|
|
39573
|
+
? generateDarkPalette(appearance.accentColor)
|
|
39574
|
+
: generateLightPalette(appearance.accentColor);
|
|
39575
|
+
// Add accent color styles
|
|
39576
|
+
styles['--button-color'] = palette.accent;
|
|
39577
|
+
styles['--button-icon-color'] = palette.userBubbleText;
|
|
39578
|
+
styles['--button-border-color'] = palette.accent;
|
|
39579
|
+
styles['--header-text-color'] = palette.accent;
|
|
39580
|
+
styles['--welcome-color'] = palette.text;
|
|
39581
|
+
styles['--message-text-color'] = palette.text;
|
|
39582
|
+
styles['--bubble-user-color'] = palette.userBubble;
|
|
39583
|
+
styles['--user-message-text'] = palette.userBubbleText;
|
|
39584
|
+
styles['--send-button-background'] = palette.accent;
|
|
39585
|
+
styles['--send-button-border-color'] = palette.accent;
|
|
39586
|
+
styles['--hover-input-border-color'] = palette.accent;
|
|
39587
|
+
styles['--active-input-border-color'] = palette.accent;
|
|
39588
|
+
styles['--active-input-shadow'] = `0 0 0 4px ${withAlpha(palette.accent, 0.15)}`;
|
|
39589
|
+
styles['--primary-color'] = palette.accent;
|
|
39590
|
+
styles['--background-color'] = palette.background;
|
|
39591
|
+
styles['--text-color'] = palette.text;
|
|
39592
|
+
styles['--border-color'] = palette.border;
|
|
39593
|
+
}
|
|
39594
|
+
return styles;
|
|
39483
39595
|
}
|
|
39484
39596
|
|
|
39485
39597
|
/**
|
|
@@ -39590,7 +39702,7 @@
|
|
|
39590
39702
|
if ( ref === void 0 ) ref = {};
|
|
39591
39703
|
var insertAt = ref.insertAt;
|
|
39592
39704
|
|
|
39593
|
-
if (
|
|
39705
|
+
if (typeof document === 'undefined') { return; }
|
|
39594
39706
|
|
|
39595
39707
|
var head = document.head || document.getElementsByTagName('head')[0];
|
|
39596
39708
|
var style = document.createElement('style');
|
|
@@ -39613,10 +39725,7 @@
|
|
|
39613
39725
|
}
|
|
39614
39726
|
}
|
|
39615
39727
|
|
|
39616
|
-
var css_248z$1 = ".ai-chat-widget{--primary-color:#07f;--background-color:#fff;--text-color:#1f2937;--border-color:#e5e7eb;--user-message-bg:var(--primary-color);--user-message-text:#fff;--assistant-message-bg:#f3f4f6;--assistant-message-text:#374151;--input-bg:#fff;--input-border:#d1d5db;--shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06);--shadow-lg:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -2px rgba(0,0,0,.05);--button-color:#07f;--button-size:56px;--button-border-radius:28px;--button-border-width:0px;--button-border-color:#07f;--button-opacity:1;--button-backdrop-blur:0px;--button-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -2px rgba(0,0,0,.05);--card-background:#fff;--card-border-radius:16px;--card-border-width:0px;--card-border-color:#e5e7eb;--card-opacity:1;--card-backdrop-blur:0px;--card-shadow:0 25px 50px -12px rgba(0,0,0,.25);--header-background:#07f;--header-text-color:#fff;--header-font-size:18px;--header-border-bottom-width:0px;--header-border-bottom-color:#e5e7eb;--header-opacity:1;--header-backdrop-blur:0px;--chat-background:#fff;--chat-opacity:1;--chat-backdrop-blur:0px;--welcome-font-size:16px;--welcome-color:#1f2937;--welcome-opacity:1;--bubble-user-color:#07f;--bubble-assistant-color:#f3f4f6;--bubble-border-radius:16px;--bubble-border-width:0px;--bubble-border-color:#e5e7eb;--bubble-opacity:1;--typing-animation-color:#f3f4f6;--typing-animation-opacity:1;--typing-animation-border-width:0px;--typing-animation-border-color:#e5e7eb;--typing-animation-border-radius:16px;--footer-background:#fff;--footer-border-top-width:1px;--footer-border-top-color:#e5e7eb;--footer-opacity:1;--footer-backdrop-blur:0px;--input-background:#fff;--input-border-radius:24px;--input-border-width:1.5px;--input-border-color:#d1d5db;--input-opacity:1;--input-shadow:0 1px 2px 0 rgba(0,0,0,.05);--send-button-background:#07f;--send-button-border-radius:20px;--send-button-border-width:0px;--send-button-border-color:#07f;--send-button-opacity:1;--hover-button-scale:1.05;--hover-button-opacity:0.9;--hover-input-border-color:#9ca3af;--hover-send-button-opacity:0.85;--hover-close-button-opacity:1;--active-input-border-color:#07f;--active-input-shadow:0 0 0 3px rgba(0,119,255,.1);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif}.ai-chat-widget.dark{--background-color:#001d3d;--text-color:#f9fafb;--border-color:#374151;--assistant-message-bg:#036;--assistant-message-text:#e5e7eb;--input-bg:#002855;--input-border:#374151}.ai-chat-widget.dark .ai-chat-message.system .ai-chat-message-content{background-color:#78350f;color:#fef3c7}.ai-chat-widget.dark .ai-chat-message.tool .ai-chat-message-content{background-color:#1e3a8a;color:#dbeafe}.ai-chat-widget-container{font-size:14px;line-height:1.5;position:fixed;z-index:9999}.ai-chat-widget-container.bottom-right{bottom:20px;right:20px}.ai-chat-widget-container.bottom-left{bottom:20px;left:20px}.ai-chat-widget-container.top-right{right:20px;top:20px}.ai-chat-widget-container.top-left{left:20px;top:20px}.ai-chat-button{align-items:center;backdrop-filter:blur(var(--button-backdrop-blur));-webkit-backdrop-filter:blur(var(--button-backdrop-blur));background-color:var(--button-color);border:var(--button-border-width) solid var(--button-border-color);border-radius:var(--button-border-radius);box-shadow:var(--button-shadow);color:#fff;cursor:pointer;display:flex;height:var(--button-size);justify-content:center;opacity:var(--button-opacity);transition:all .3s cubic-bezier(.4,0,.2,1);width:var(--button-size)}.ai-chat-button:hover{opacity:.9}.ai-chat-button:active{opacity:.8}.ai-chat-button-svg{height:50%;min-height:24px;min-width:24px;width:50%}.ai-chat-button-icon{font-size:1.5em;line-height:1}.ai-chat-window{border-radius:var(--card-border-radius);box-shadow:0 0 0 var(--card-border-width) var(--card-border-color-rgba,var(--card-border-color)),var(--card-shadow);display:flex;flex-direction:column;overflow:hidden;position:absolute}.ai-chat-window>*{position:relative;z-index:1}.ai-chat-window:before{backdrop-filter:blur(var(--card-backdrop-blur));-webkit-backdrop-filter:blur(var(--card-backdrop-blur));background-color:var(--card-background);border-radius:var(--card-border-radius);content:\"\";inset:0;opacity:var(--card-opacity);pointer-events:none;position:absolute;z-index:0}.ai-chat-widget-container.bottom-right .ai-chat-window{bottom:calc(var(--button-size, 60px) + 16px);right:0}.ai-chat-widget-container.bottom-left .ai-chat-window{bottom:calc(var(--button-size, 60px) + 16px);left:0}.ai-chat-widget-container.top-right .ai-chat-window{right:0;top:calc(var(--button-size, 60px) + 16px)}.ai-chat-widget-container.top-left .ai-chat-window{left:0;top:calc(var(--button-size, 60px) + 16px)}.ai-chat-button{z-index:1}.ai-chat-window{z-index:2}.ai-chat-window.size-small{height:500px;width:380px}.ai-chat-window.size-medium{height:650px;width:440px}.ai-chat-window.size-large{height:750px;width:520px}.ai-chat-logo{border-radius:50%;height:32px;object-fit:cover;width:32px}.ai-chat-messages::-webkit-scrollbar{width:6px}.ai-chat-messages::-webkit-scrollbar-track{background:transparent}.ai-chat-messages::-webkit-scrollbar-thumb{background:var(--border-color);border-radius:3px}.ai-chat-messages::-webkit-scrollbar-thumb:hover{background:var(--input-border)}.ai-chat-message{display:flex;flex-direction:column;gap:4px}.ai-chat-message.user{align-items:flex-end}.ai-chat-message.assistant{align-items:flex-start}.ai-chat-message.system{align-items:center}.ai-chat-message.tool{align-items:flex-start}.ai-chat-message-content{word-wrap:break-word;border:var(--bubble-border-width) solid var(--bubble-border-color);border-radius:var(--bubble-border-radius);font-size:15px;line-height:1.6;max-width:80%;opacity:var(--bubble-opacity);padding:12px 16px}.ai-chat-message.user .ai-chat-message-content{background-color:var(--bubble-user-color);border-bottom-right-radius:4px;box-shadow:0 1px 2px rgba(0,0,0,.1);color:var(--user-message-text)}.ai-chat-message.assistant .ai-chat-message-content{background-color:var(--bubble-assistant-color,#f3f4f6);border:1px solid var(--bubble-border-color,rgba(0,0,0,.08));border-radius:var(--bubble-border-radius,16px);border-bottom-left-radius:4px;box-shadow:none;color:var(--assistant-message-text);max-width:85%;padding:12px 16px}.ai-chat-message.assistant .ai-chat-message-content p{margin:0 0 12px}.ai-chat-message.assistant .ai-chat-message-content p:last-child{margin-bottom:0}.ai-chat-message.assistant .ai-chat-message-content ol,.ai-chat-message.assistant .ai-chat-message-content ul{margin:8px 0 12px;padding-left:24px}.ai-chat-message.assistant .ai-chat-message-content li{line-height:1.5;margin:6px 0}.ai-chat-message.assistant .ai-chat-message-content li::marker{color:var(--primary-color,#07f)}.ai-chat-message.assistant .ai-chat-message-content ol li::marker{font-weight:600}.ai-chat-message.assistant .ai-chat-message-content strong{font-weight:600}.ai-chat-message.assistant .ai-chat-message-content em{font-style:italic}.ai-chat-message.assistant .ai-chat-message-content code{background-color:rgba(0,0,0,.06);border-radius:4px;font-family:SF Mono,Consolas,Monaco,monospace;font-size:.9em;padding:2px 6px}.ai-chat-widget.dark .ai-chat-message.assistant .ai-chat-message-content code{background-color:hsla(0,0%,100%,.1)}.ai-chat-message.assistant .ai-chat-message-content pre{background-color:rgba(0,0,0,.06);border-radius:8px;margin:8px 0 12px;overflow-x:auto;padding:12px}.ai-chat-widget.dark .ai-chat-message.assistant .ai-chat-message-content pre{background-color:hsla(0,0%,100%,.08)}.ai-chat-message.assistant .ai-chat-message-content pre code{background-color:transparent;border-radius:0;padding:0}.ai-chat-message.assistant .ai-chat-message-content blockquote{border-left:3px solid var(--primary-color,#07f);color:var(--text-muted,#6b7280);margin:8px 0 12px;padding:4px 0 4px 12px}.ai-chat-message.assistant .ai-chat-message-content a{color:var(--primary-color,#07f);text-decoration:underline}.ai-chat-message.assistant .ai-chat-message-content a:hover{opacity:.8}.ai-chat-message.assistant .ai-chat-message-content h1,.ai-chat-message.assistant .ai-chat-message-content h2,.ai-chat-message.assistant .ai-chat-message-content h3,.ai-chat-message.assistant .ai-chat-message-content h4,.ai-chat-message.assistant .ai-chat-message-content h5,.ai-chat-message.assistant .ai-chat-message-content h6{font-weight:600;line-height:1.3;margin:16px 0 8px}.ai-chat-message.assistant .ai-chat-message-content h1:first-child,.ai-chat-message.assistant .ai-chat-message-content h2:first-child,.ai-chat-message.assistant .ai-chat-message-content h3:first-child{margin-top:0}.ai-chat-message.assistant .ai-chat-message-content hr{border:none;border-top:1px solid var(--border-color,#e5e7eb);margin:12px 0}.ai-chat-message.system .ai-chat-message-content{background-color:#fef3c7;border-radius:8px;color:#92400e;font-size:12px;font-style:italic;max-width:90%;text-align:center}.ai-chat-message.tool .ai-chat-message-content{background-color:#dbeafe;border-bottom-left-radius:4px;color:#1e40af;font-family:Courier New,monospace;font-size:13px}.ai-chat-tool-indicators{display:flex;gap:6px;margin-top:6px}.tool-indicator{align-items:center;background:#dbeafe;border-radius:50%;color:#1e40af;display:inline-flex;height:18px;justify-content:center;overflow:hidden;position:relative;width:18px}.tool-indicator .icon{font-size:12px;line-height:1;z-index:1}.tool-indicator.started:after{animation:ai-spin 1s linear infinite;border:2px solid rgba(30,64,175,.25);border-radius:50%;border-top-color:#1e40af;content:\"\";inset:0;position:absolute}@keyframes ai-spin{to{transform:rotate(1turn)}}.ai-chat-tool-message{align-items:center;background:rgba(16,185,129,.1);border:1px solid rgba(16,185,129,.2);border-radius:20px;color:#059669;display:inline-flex;gap:8px;padding:8px 14px}.ai-chat-widget.dark .ai-chat-tool-message{background:rgba(16,185,129,.15);border-color:rgba(16,185,129,.25);color:#34d399}.tool-finished{align-items:center;display:inline-flex;font-size:14px;justify-content:center}.tool-finished .tool-icon{display:none}.tool-finished .tool-check{font-size:14px;font-weight:700}.tool-name{font-size:13px;font-weight:500}.ai-chat-message-timestamp{color:rgba(0,0,0,.6);filter:invert(1) grayscale(1) contrast(1.2);mix-blend-mode:difference;padding:0 4px}.ai-chat-welcome{align-items:center;color:var(--welcome-color);display:flex;flex-direction:column;justify-content:center;min-height:200px;opacity:var(--welcome-opacity);padding:60px 32px 40px;text-align:center}.ai-chat-welcome-title{color:var(--primary-color);font-size:28px;font-weight:700;letter-spacing:-.03em;margin-bottom:12px}.ai-chat-welcome-text{color:var(--assistant-message-text);font-size:16px;line-height:1.6;max-width:280px;opacity:.7}.ai-chat-typing{align-items:center;background-color:var(--assistant-message-bg);border-radius:12px;border-bottom-left-radius:4px;display:flex;gap:4px;max-width:80px;padding:10px 14px}.ai-chat-typing-dot{animation:typingBounce 1.4s infinite;background-color:#9ca3af;border-radius:50%;height:8px;width:8px}.ai-chat-typing-dot:nth-child(2){animation-delay:.2s}.ai-chat-typing-dot:nth-child(3){animation-delay:.4s}@keyframes typingBounce{0%,60%,to{transform:translateY(0)}30%{transform:translateY(-8px)}}.ai-chat-file-button{align-items:center;background:none;border:none;border-radius:6px;color:var(--text-color);cursor:pointer;display:flex;justify-content:center;padding:8px;transition:background-color .2s}.ai-chat-file-button:hover:not(:disabled){background-color:rgba(0,0,0,.05)}.ai-chat-file-button:disabled{cursor:not-allowed;opacity:.5}.ai-chat-file-list{display:flex;flex-wrap:wrap;gap:8px;padding:8px 12px}.ai-chat-file-item{align-items:center;background-color:rgba(0,0,0,.05);border-radius:6px;display:flex;font-size:12px;gap:8px;padding:6px 10px}.ai-chat-file-extension{background-color:var(--primary-color);border-radius:3px;color:#fff;display:inline-block;font-size:10px;font-weight:600;min-width:40px;padding:2px 6px;text-align:center;text-transform:uppercase}.ai-chat-file-info{display:flex;flex:1;flex-direction:column;gap:2px;min-width:0}.ai-chat-file-name{font-weight:500;max-width:150px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ai-chat-file-size{color:var(--text-muted);font-size:10px;opacity:.7}.ai-chat-file-remove{align-items:center;background:none;border:none;color:inherit;cursor:pointer;display:flex;justify-content:center;opacity:.5;padding:4px;transition:opacity .15s ease}.ai-chat-file-remove:hover{opacity:1}.ai-chat-message-attachments{display:flex;flex-wrap:wrap;gap:6px;margin-top:6px}.ai-chat-message-attachment{align-items:center;background-color:rgba(0,0,0,.08);border-radius:4px;display:inline-flex;font-size:11px;gap:4px;padding:3px 8px}.ai-chat-attachment-icon{font-size:12px}.ai-chat-attachment-ext{background-color:var(--primary-color);border-radius:2px;color:#fff;display:inline-block;font-size:9px;font-weight:600;padding:1px 4px;text-transform:uppercase}.ai-chat-attachment-name{max-width:120px;opacity:.8;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ai-chat-sources{background-color:rgba(0,0,0,.02);border-radius:6px;font-size:12px;margin-top:8px;overflow:hidden}.ai-chat-sources-toggle{align-items:center;background:none;border:none;cursor:pointer;display:flex;gap:6px;padding:8px 10px;text-align:left;transition:background-color .2s;width:100%}.ai-chat-sources-toggle:hover{background-color:rgba(0,0,0,.03)}.ai-chat-sources-icon{color:var(--text-muted);font-size:10px;transition:transform .2s}.ai-chat-sources-title{color:var(--text-color);flex:1;font-size:11px;font-weight:600;letter-spacing:.5px;text-transform:uppercase}.ai-chat-source-item{border-top:1px solid rgba(0,0,0,.05);color:#6b7280;display:flex;gap:8px;padding:8px 10px}.ai-chat-source-item:last-child{border-bottom:none}.ai-chat-source-number{color:var(--primary-color);flex-shrink:0;font-weight:600}.ai-chat-source-details{display:flex;flex:1;flex-direction:column;gap:4px}.ai-chat-source-score{color:#9ca3af;font-size:11px}.ai-chat-source-content{color:#6b7280;font-size:11px;font-style:italic;line-height:1.4}.ai-chat-source-metadata{display:flex;flex-wrap:wrap;gap:6px;margin-top:2px}.ai-chat-source-meta-item{background-color:rgba(0,0,0,.05);border-radius:3px;color:#6b7280;font-size:10px;padding:2px 6px}.ai-chat-message-meta{align-items:center;display:inline-flex;gap:6px;height:20px}.ai-chat-message-timestamp{color:#71717a;font-size:11px;line-height:1}.ai-chat-feedback{gap:0}.ai-chat-feedback,.ai-chat-feedback-button{align-items:center;display:inline-flex;height:20px}.ai-chat-feedback-button{background:none!important;border:none;border-radius:0;color:#71717a;cursor:pointer;justify-content:center;padding:0 4px;transition:color .15s ease}.ai-chat-feedback-button:hover:not(:disabled){background:none!important;color:#52525b}.ai-chat-feedback-button:active:not(:disabled){opacity:.7}.ai-chat-feedback-button:disabled{cursor:not-allowed;opacity:.4}.ai-chat-feedback-button.active{background:none!important;color:var(--primary-color,#07f)}.ai-chat-feedback-submitted{align-items:center;animation:feedbackMorph .3s cubic-bezier(.34,1.56,.64,1);display:flex;gap:6px}.ai-chat-feedback-checkmark{animation:checkmarkPop .3s cubic-bezier(.34,1.56,.64,1);color:#10b981;font-size:16px;font-weight:700}.ai-chat-feedback-text{animation:textSlideIn .3s ease;color:#10b981;font-size:13px;font-weight:500}@keyframes feedbackMorph{0%{opacity:.5;transform:scale(.8)}to{opacity:1;transform:scale(1)}}@keyframes checkmarkPop{0%{opacity:0;transform:scale(0) rotate(-45deg)}50%{transform:scale(1.3) rotate(0deg)}to{opacity:1;transform:scale(1) rotate(0deg)}}@keyframes textSlideIn{0%{opacity:0;transform:translateX(-10px)}to{opacity:1;transform:translateX(0)}}.ai-chat-error{align-items:flex-start;background-color:rgba(239,68,68,.1);border:1px solid rgba(239,68,68,.2);border-radius:12px;color:#ef4444;display:flex;font-size:14px;font-weight:500;gap:10px;line-height:1.5;margin:8px 16px;padding:12px 16px}.ai-chat-widget.dark .ai-chat-error{background-color:rgba(239,68,68,.15);border-color:rgba(239,68,68,.25);color:#fca5a5}.ai-chat-error:before{align-items:center;background:rgba(239,68,68,.2);border-radius:50%;content:\"⚠\";display:flex;flex-shrink:0;font-size:14px;font-weight:700;height:20px;justify-content:center;width:20px}.ai-chat-widget.dark .ai-chat-error:before{background:rgba(239,68,68,.25)}.ai-chat-warning{background-color:rgba(245,158,11,.1);border:1px solid rgba(245,158,11,.2);border-radius:12px;color:#d97706;font-size:13px;margin:8px 16px;padding:12px 16px}.ai-chat-widget.dark .ai-chat-warning{background-color:rgba(245,158,11,.15);border-color:rgba(245,158,11,.25);color:#fbbf24}.ai-chat-suggested-questions{bottom:80px;left:0;padding:0 20px 16px;position:absolute;right:0;z-index:5}.ai-chat-suggested-questions-list{display:flex;flex-direction:column;gap:8px}.ai-chat-suggested-question{align-items:center;background:#fff;border:1px solid rgba(0,0,0,.08);border-radius:14px;box-shadow:0 1px 3px rgba(0,0,0,.04);color:#374151;cursor:pointer;display:flex;font-size:14px;font-weight:500;gap:12px;justify-content:space-between;padding:14px 16px;text-align:left;transition:all .15s ease;width:100%}.ai-chat-suggested-question:hover{background:#f9fafb;border-color:rgba(0,0,0,.12);box-shadow:0 2px 8px rgba(0,0,0,.06)}.ai-chat-suggested-question:active{transform:scale(.98)}.ai-chat-suggested-question-text{flex:1;line-height:1.4}.ai-chat-suggested-question-icon{color:var(--primary-color,#07f);flex-shrink:0;opacity:.7;transition:transform .15s ease,opacity .15s ease}.ai-chat-suggested-question:hover .ai-chat-suggested-question-icon{opacity:1;transform:translateX(3px)}@media (max-width:480px){.ai-chat-window{border-radius:0!important;bottom:0!important;height:100%!important;left:0!important;position:fixed!important;right:0!important;top:0!important;width:100%!important}.ai-chat-widget-container{bottom:20px!important;right:20px!important}.ai-chat-suggested-question{font-size:13px;padding:9px 10px}}.ai-chat-action-approval{background:linear-gradient(135deg,#07f,#001d3d);border-radius:16px;box-shadow:0 4px 12px rgba(0,119,255,.3);color:#fff;margin:16px;padding:16px}.ai-chat-action-approval-content{align-items:flex-start;display:flex;gap:12px;margin-bottom:16px}.ai-chat-action-approval-icon{align-items:center;background:hsla(0,0%,100%,.2);border-radius:8px;display:flex;flex-shrink:0;height:40px;justify-content:center;width:40px}.ai-chat-action-approval-text{flex:1}.ai-chat-action-approval-title{font-size:15px;font-weight:600;margin-bottom:4px}.ai-chat-action-approval-description{font-size:13px;line-height:1.4;opacity:.95}.ai-chat-action-approval-buttons{display:flex;gap:8px;justify-content:flex-end}.ai-chat-action-button{align-items:center;border:none;border-radius:8px;cursor:pointer;display:flex;font-family:inherit;font-size:14px;font-weight:500;gap:6px;padding:8px 16px;transition:all .2s ease}.ai-chat-action-button:disabled{cursor:not-allowed;opacity:.6}.ai-chat-action-button-reject{background:hsla(0,0%,100%,.2);color:#fff}.ai-chat-action-button-reject:hover:not(:disabled){background:hsla(0,0%,100%,.3)}.ai-chat-action-button-approve{background:#fff;color:#07f}.ai-chat-action-button-approve:hover:not(:disabled){background:#f0f0f0;box-shadow:0 2px 8px rgba(0,0,0,.15);transform:translateY(-1px)}.ai-chat-action-spinner{animation:ai-chat-spin .6s linear infinite;border:2px solid rgba(0,119,255,.3);border-radius:50%;border-top-color:#07f;display:inline-block;height:14px;width:14px}@keyframes ai-chat-spin{to{transform:rotate(1turn)}}.ai-chat-header-actions{align-items:center;display:flex;gap:4px}.ai-chat-header-button{align-items:center;background:transparent;border:none;border-radius:8px;color:var(--header-text-color,#fff);cursor:pointer;display:flex;height:32px;justify-content:center;opacity:.8;transition:background-color .15s ease;width:32px}.ai-chat-header-button:hover{background:hsla(0,0%,100%,.15);opacity:1}.ai-chat-header-button svg{height:18px;width:18px}.ai-chat-history-panel{background:var(--chat-background,#fff);display:flex;flex:1;flex-direction:column;overflow:hidden}.ai-chat-history-empty,.ai-chat-history-loading{align-items:center;color:var(--text-color,#6b7280);display:flex;flex:1;font-size:14px;justify-content:center;padding:24px;text-align:center}.ai-chat-history-list{flex:1;overflow-y:auto;padding:8px}.ai-chat-history-item{align-items:stretch;background:transparent;border:none;border-bottom:1px solid var(--border-color,rgba(0,0,0,.06));border-radius:0;cursor:pointer;display:flex;flex-direction:column;padding:12px 16px;text-align:left;transition:background-color .12s ease;width:100%}.ai-chat-history-item:last-child{border-bottom:none}.ai-chat-history-item:hover{background:rgba(0,0,0,.03)}.ai-chat-widget.dark .ai-chat-history-item:hover{background:hsla(0,0%,100%,.05)}.ai-chat-history-item.active{background:rgba(0,0,0,.05)}.ai-chat-widget.dark .ai-chat-history-item.active{background:hsla(0,0%,100%,.08)}.ai-chat-history-item.active .ai-chat-history-item-meta{opacity:.8}.ai-chat-history-item-preview{color:var(--text-color,#1f2937);font-size:14px;font-weight:400;line-height:1.4;margin-bottom:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ai-chat-history-item.active .ai-chat-history-item-preview{font-weight:500}.ai-chat-history-item-meta{color:var(--text-color,#9ca3af);display:flex;font-size:11px;gap:8px;opacity:.8}.ai-chat-history-list::-webkit-scrollbar{width:6px}.ai-chat-history-list::-webkit-scrollbar-track{background:transparent}.ai-chat-history-list::-webkit-scrollbar-thumb{background:var(--border-color,#e5e7eb);border-radius:3px}.ai-chat-history-list::-webkit-scrollbar-thumb:hover{background:var(--input-border,#d1d5db)}";
|
|
39617
|
-
styleInject(css_248z$1);
|
|
39618
|
-
|
|
39619
|
-
var css_248z = ".ai-chat-widget{--spring-bounce:cubic-bezier(0.34,1.56,0.64,1);--spring-smooth:cubic-bezier(0.4,0,0.2,1);--spring-snappy:cubic-bezier(0.2,0,0,1);--duration-fast:0.2s;--duration-normal:0.35s;--duration-slow:0.5s}.ai-chat-button{align-items:center;background:var(--button-color,var(--primary-color,#07f));border:none;border-radius:50%;box-shadow:0 2px 8px rgba(0,0,0,.15);cursor:pointer;display:flex;height:48px;justify-content:center;overflow:hidden;position:relative;transition:opacity .15s ease;width:48px}.ai-chat-button:hover{opacity:.9}.ai-chat-button:active{opacity:.8}.ai-chat-button-svg{height:20px;transition:transform .15s ease;width:20px}.ai-chat-button.is-open .ai-chat-button-svg{transform:rotate(0deg)}.ai-chat-window{animation:windowOpen var(--duration-slow) var(--spring-bounce);background:#fff;border:1px solid #e5e7eb;border-radius:16px;box-shadow:0 4px 24px rgba(0,0,0,.12),0 1px 3px rgba(0,0,0,.08);display:flex;flex-direction:column;overflow:hidden;position:absolute;transform-origin:bottom right}.ai-chat-widget.dark .ai-chat-window{background:#18181b;border-color:#27272a}@keyframes windowOpen{0%{opacity:0;transform:scale(.9) translateY(20px)}to{opacity:1;transform:scale(1) translateY(0)}}.ai-chat-window.closing{animation:windowClose var(--duration-normal) var(--spring-smooth) forwards}@keyframes windowClose{0%{opacity:1;transform:scale(1) translateY(0)}to{opacity:0;transform:scale(.9) translateY(20px)}}.ai-chat-header{align-items:center;background:#fff;border-bottom:1px solid #e5e7eb;display:flex;justify-content:space-between;padding:16px 20px;position:relative;z-index:10}.ai-chat-widget.dark .ai-chat-header{background:#18181b;border-bottom-color:#27272a}.ai-chat-header-content{align-items:center;display:flex;flex:1;gap:12px}.ai-chat-logo{border-radius:10px;height:36px;object-fit:cover;width:36px}.ai-chat-title{color:#18181b;font-size:15px;font-weight:600;letter-spacing:-.01em}.ai-chat-widget.dark .ai-chat-title{color:#fafafa}.ai-chat-close-button{align-items:center;background:transparent;border:none;border-radius:8px;color:#a1a1aa;cursor:pointer;display:flex;height:32px;justify-content:center;padding:0;transition:all .15s ease;width:32px}.ai-chat-widget.dark .ai-chat-close-button{color:#71717a}.ai-chat-close-button:hover{background:#f4f4f5;color:#52525b}.ai-chat-widget.dark .ai-chat-close-button:hover{background:#27272a;color:#a1a1aa}.ai-chat-close-button:active{transform:scale(.95)}.ai-chat-messages{-webkit-overflow-scrolling:touch;background:#f4f4f5;display:flex;flex:1;flex-direction:column;gap:12px;overflow-x:hidden;overflow-y:auto;padding:16px 16px 90px;position:relative;scroll-behavior:smooth}.ai-chat-widget.dark .ai-chat-messages{background:#18181b}.ai-chat-messages::-webkit-scrollbar{width:4px}.ai-chat-messages::-webkit-scrollbar-track{background:transparent}.ai-chat-messages::-webkit-scrollbar-thumb{background:rgba(0,0,0,.15);border-radius:4px}.ai-chat-messages::-webkit-scrollbar-thumb:hover{background:rgba(0,0,0,.25)}.ai-chat-message{animation:messageSlideIn var(--duration-normal) var(--spring-bounce);display:flex;flex-direction:column;gap:6px}@keyframes messageSlideIn{0%{opacity:0;transform:translateY(12px)}to{opacity:1;transform:translateY(0)}}.ai-chat-message-content{word-wrap:break-word;border-radius:12px;font-size:14px;line-height:1.5;max-width:85%;padding:8px 14px}.ai-chat-message.user .ai-chat-message-content{background:var(--bubble-user-color,var(--primary-color,#07f));border-bottom-right-radius:4px;color:#fff;margin-left:auto}.ai-chat-message.assistant .ai-chat-message-content{background:#fff;border:1px solid #e5e7eb;border-bottom-left-radius:4px;color:#374151}.ai-chat-widget.dark .ai-chat-message.assistant .ai-chat-message-content{background:#18181b;border-color:#27272a;color:#e4e4e7}.ai-chat-typing{align-items:center;animation:messageSlideIn var(--duration-normal) var(--spring-bounce);background:#fff;border:1px solid #e5e7eb;border-radius:12px;border-bottom-left-radius:4px;display:flex;gap:4px;max-width:64px;padding:12px 16px}.ai-chat-widget.dark .ai-chat-typing{background:#18181b;border-color:#27272a}.ai-chat-typing-dot{animation:typingPulse 1.4s ease-in-out infinite;background:linear-gradient(135deg,var(--primary-color) 0,color-mix(in srgb,var(--primary-color) 70%,#000) 100%);border-radius:50%;height:8px;width:8px}.ai-chat-typing-dot:nth-child(2){animation-delay:.15s}.ai-chat-typing-dot:nth-child(3){animation-delay:.3s}@keyframes typingPulse{0%,60%,to{opacity:.4;transform:translateY(0) scale(1)}30%{opacity:1;transform:translateY(-6px) scale(1.1)}}.ai-chat-input-container{background:transparent;bottom:0;left:0;padding:0 16px 16px;position:absolute;right:0;z-index:10}.ai-chat-input-container:before{background:linear-gradient(0deg,#f4f4f5 80%,transparent);bottom:0;content:\"\";height:48px;left:0;pointer-events:none;position:absolute;right:0;z-index:-1}.ai-chat-widget.dark .ai-chat-input-container:before{background:linear-gradient(0deg,#18181b 80%,transparent)}.ai-chat-input-wrapper{align-items:center;background:#f4f4f5;border:1px solid #e5e7eb;border-radius:9999px;display:flex;gap:0;padding:4px 4px 4px 16px;position:relative;transition:all .15s ease;z-index:5}.ai-chat-widget.dark .ai-chat-input-wrapper{background:#27272a;border-color:#3f3f46}.ai-chat-input-wrapper:focus-within{border-color:var(--primary-color);box-shadow:0 0 0 2px rgba(var(--primary-color-rgb,0,119,255),.15)}.ai-chat-input{background:transparent;border:none;color:var(--text-color);flex:1;font-family:inherit;font-size:14px;line-height:1.4;max-height:100px;min-height:20px;outline:none;padding:8px 0;resize:none}.ai-chat-input::placeholder{color:rgba(0,0,0,.35)}.ai-chat-widget.dark .ai-chat-input::placeholder{color:hsla(0,0%,100%,.35)}.ai-chat-send-button{align-items:center;background:transparent;border:none;border-radius:8px;color:#a1a1aa;cursor:pointer;display:flex;flex-shrink:0;height:36px;justify-content:center;padding:0;transition:all .15s ease;width:36px}.ai-chat-widget.dark .ai-chat-send-button{color:#71717a}.ai-chat-send-button.active{background:var(--primary-color,#07f);color:#fff}.ai-chat-send-button.active:hover:not(:disabled){opacity:.9}.ai-chat-send-button:active:not(:disabled){transform:scale(.95)}.ai-chat-send-button:disabled{cursor:not-allowed;opacity:.4}.ai-chat-tool-message{align-items:center;animation:toolPulse 2s ease-in-out infinite;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);background:linear-gradient(135deg,rgba(16,185,129,.15),rgba(16,185,129,.08));border:1px solid rgba(16,185,129,.2);border-radius:16px;display:inline-flex;gap:10px;padding:10px 16px}@keyframes toolPulse{0%,to{box-shadow:0 0 0 0 rgba(16,185,129,.2)}50%{box-shadow:0 0 0 8px rgba(16,185,129,0)}}.tool-finished{align-items:center;animation:toolComplete .5s var(--spring-bounce);background:linear-gradient(135deg,#10b981,#059669);border-radius:50%;color:#fff;display:inline-flex;height:28px;justify-content:center;position:relative;width:28px}@keyframes toolComplete{0%{transform:scale(0) rotate(-180deg)}to{transform:scale(1) rotate(0deg)}}.tool-indicator{align-items:center;background:linear-gradient(135deg,rgba(59,130,246,.2),rgba(59,130,246,.1));border-radius:50%;color:#3b82f6;display:inline-flex;height:24px;justify-content:center;position:relative;width:24px}.tool-indicator.started:after{animation:toolSpin .8s linear infinite;border:2px solid transparent;border-radius:50%;border-top-color:#3b82f6;content:\"\";inset:-2px;position:absolute}@keyframes toolSpin{to{transform:rotate(1turn)}}.ai-chat-welcome{align-items:center;animation:welcomeFadeIn var(--duration-slow) var(--spring-smooth);display:flex;flex-direction:column;justify-content:center;min-height:200px;padding:60px 32px 40px;text-align:center}@keyframes welcomeFadeIn{0%{opacity:0;transform:translateY(16px)}to{opacity:1;transform:translateY(0)}}.ai-chat-welcome-title{color:var(--primary-color);font-size:28px;font-weight:700;letter-spacing:-.03em;margin-bottom:12px}.ai-chat-welcome-text{color:var(--text-color);font-size:16px;line-height:1.6;max-width:280px;opacity:.6}.ai-chat-suggested-questions{bottom:76px;left:0;padding:0 16px 12px;position:absolute;right:0;z-index:5}.ai-chat-suggested-questions-list{display:flex;flex-direction:column;gap:6px}.ai-chat-suggested-question{align-items:center;background:#fff;border:1px solid #e5e7eb;border-radius:10px;color:#374151;cursor:pointer;display:flex;font-size:13px;font-weight:500;gap:10px;justify-content:space-between;padding:10px 14px;text-align:left;transition:all .15s ease;width:100%}.ai-chat-widget.dark .ai-chat-suggested-question{background:#18181b;border-color:#27272a;color:#e4e4e7}.ai-chat-suggested-question:hover{background:#f4f4f5;border-color:#d4d4d8}.ai-chat-widget.dark .ai-chat-suggested-question:hover{background:#27272a;border-color:#3f3f46}.ai-chat-suggested-question:active{transform:scale(.98)}.ai-chat-suggested-question-text{flex:1;line-height:1.4}.ai-chat-suggested-question-icon{color:var(--primary-color,#07f);flex-shrink:0;opacity:.7;transition:transform .15s ease,opacity .15s ease}.ai-chat-suggested-question:hover .ai-chat-suggested-question-icon{opacity:1;transform:translateX(3px)}.ai-chat-feedback-button{align-items:center;background:rgba(0,0,0,.04);border:none;border-radius:8px;cursor:pointer;display:flex;font-size:16px;gap:4px;padding:6px 10px;transition:all var(--duration-fast) var(--spring-bounce)}.ai-chat-feedback-button:hover:not(:disabled){background:rgba(0,0,0,.08);transform:scale(1.15)}.ai-chat-feedback-button:active:not(:disabled){transform:scale(.9)}.ai-chat-feedback-button.active{background:rgba(var(--primary-color-rgb,0,119,255),.15)}@media (max-width:480px){.ai-chat-window{animation:mobileSlideUp var(--duration-normal) var(--spring-smooth);border-radius:0!important;bottom:0!important;height:100%!important;left:0!important;position:fixed!important;right:0!important;top:0!important;width:100%!important}@keyframes mobileSlideUp{0%{transform:translateY(100%)}to{transform:translateY(0)}}.ai-chat-header{padding-top:max(16px,env(safe-area-inset-top))}.ai-chat-input-container{padding-bottom:max(20px,env(safe-area-inset-bottom))}}";
|
|
39728
|
+
var css_248z = ".ai-chat-widget{--radius-sm:4px;--radius-md:8px;--radius-lg:12px;--radius-xl:16px;--radius-2xl:18px;--radius-pill:9999px;--radius-window-top:22px;--radius-window-bottom:44px;--radius-window-gutter:16px;--radius-chat-bubble:14px;--radius-preset-badge:13px;--radius-history-item:14px;--radius-action-badge:14px;--radius-input:62px;--space-xs:4px;--space-sm:8px;--space-md:16px;--space-lg:24px;--space-xl:32px;--text-xs:12px;--text-sm:14px;--text-md:15px;--text-lg:18px;--text-xl:22px;--text-2xl:28px;--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--line-height-tight:1.3;--line-height-normal:1.4;--line-height-relaxed:1.6;--bg-primary:#fff;--bg-secondary:#f4f4f4;--bg-tertiary:#e5e7eb;--bg-hover:#e5e7eb;--text-primary:#3e3e3e;--text-secondary:#000;--text-muted:#71717a;--text-placeholder:#a1a1aa;--border-default:#d3d3d3;--border-subtle:#e5e7eb;--border-muted:#f4f4f5;--user-bg:#f4f3f0;--user-text:#000;--user-bg-hover:#e8e7e4;--agent-bg:transparent;--agent-text:#000;--input-bg:#f4f4f4;--input-border:#d3d3d3;--input-text:#000;--btn-primary-bg:#151515;--btn-primary-text:#f4f4f4;--btn-secondary-bg:transparent;--btn-secondary-text:#71717a;--spring-bounce:cubic-bezier(0.34,1.56,0.64,1);--spring-smooth:cubic-bezier(0.4,0,0.2,1);--spring-snappy:cubic-bezier(0.2,0,0,1);--duration-fast:0.15s;--duration-normal:0.25s;--duration-slow:0.35s;--shadow-sm:0 1px 2px rgba(0,0,0,.05);--shadow-md:0 2px 8px rgba(0,0,0,.1);--shadow-lg:0 4px 16px rgba(0,0,0,.12);--shadow-window:0px 0px 15px 9px rgba(0,0,0,.1);--shadow-button:0px 0px 15px 9px rgba(0,0,0,.03)}.ai-chat-widget.dark{--bg-primary:#282625;--bg-secondary:#4a4846;--bg-tertiary:#484848;--bg-hover:#484848;--text-primary:#fff;--text-secondary:#fff;--text-muted:#a1a1aa;--text-placeholder:#71717a;--border-default:#5d5b5b;--border-subtle:#5d5b5b;--border-muted:#5d5b5b;--user-bg:#484848;--user-text:#fff;--user-bg-hover:#5a5a5a;--agent-bg:transparent;--agent-text:#fff;--input-bg:#4a4846;--input-border:#5d5b5b;--input-text:#fff;--btn-primary-bg:#fff;--btn-primary-text:#312f2d;--btn-secondary-bg:transparent;--btn-secondary-text:#a1a1aa;--shadow-window:0px 0px 15px 9px rgba(0,0,0,.2);--shadow-button:0px 0px 15px 9px rgba(0,0,0,.03);--shadow-input:0px 0px 10px rgba(0,0,0,.15)}.ai-chat-widget{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif}.ai-chat-widget-container{font-size:var(--text-sm);line-height:1.5;position:fixed;z-index:9999}.ai-chat-widget-container.bottom-right{bottom:20px;right:20px}.ai-chat-widget-container.bottom-left{bottom:20px;left:20px}.ai-chat-widget-container.top-right{right:20px;top:20px}.ai-chat-widget-container.top-left{left:20px;top:20px}@keyframes windowOpen{0%{opacity:0;transform:scale(.9) translateY(20px)}to{opacity:1;transform:scale(1) translateY(0)}}@keyframes windowClose{0%{opacity:1;transform:scale(1) translateY(0)}to{opacity:0;transform:scale(.9) translateY(20px)}}@keyframes messageSlideIn{0%{opacity:0;transform:translateY(12px)}to{opacity:1;transform:translateY(0)}}@keyframes welcomeFadeIn{0%{opacity:0;transform:translateY(16px)}to{opacity:1;transform:translateY(0)}}@keyframes typingPulse{0%,60%,to{opacity:.4;transform:translateY(0) scale(1)}30%{opacity:1;transform:translateY(-4px) scale(1.1)}}@keyframes ai-chat-gear-spin{to{transform:rotate(1turn)}}@keyframes ai-chat-tool-active{0%,to{background:var(--bg-secondary);opacity:1}50%{background:var(--bg-tertiary);opacity:1}}@keyframes feedbackMorph{0%{opacity:.5;transform:scale(.8)}to{opacity:1;transform:scale(1)}}@keyframes checkmarkPop{0%{opacity:0;transform:scale(0) rotate(-45deg)}50%{transform:scale(1.3) rotate(0deg)}to{opacity:1;transform:scale(1) rotate(0deg)}}@keyframes ai-chat-history-exit{to{opacity:0;transform:translateY(-18px)}}@media (max-width:480px){.ai-chat-window{animation:mobileSlideUp var(--duration-normal) var(--spring-smooth);border-radius:0!important;bottom:0!important;height:100%!important;left:0!important;position:fixed!important;right:0!important;top:0!important;width:100%!important}@keyframes mobileSlideUp{0%{transform:translateY(100%)}to{transform:translateY(0)}}.ai-chat-header{padding-top:max(16px,env(safe-area-inset-top))}.ai-chat-input-container{padding-bottom:max(20px,env(safe-area-inset-bottom))}}.ai-chat-button{align-items:center;background:var(--button-color,var(--btn-primary-bg));border:1px solid var(--button-border-color,var(--button-color,var(--btn-primary-bg)));border-radius:50%;box-shadow:var(--shadow-button,0 0 15px 9px rgba(0,0,0,.03));color:var(--button-icon-color,var(--btn-primary-text));cursor:pointer;display:flex;height:var(--button-size,56px);justify-content:center;overflow:hidden;position:relative;transition:filter var(--duration-fast) ease,transform var(--duration-fast) ease;width:var(--button-size,56px);z-index:1}.ai-chat-button:hover{transform:scale(1.02)}.ai-chat-button:active{transform:scale(.98)}.ai-chat-button-svg{height:50%;min-height:24px;min-width:24px;transition:transform var(--duration-fast) ease;width:50%}.ai-chat-button.is-open .ai-chat-button-svg{transform:rotate(0deg)}.ai-chat-button-icon{font-size:1.5em;line-height:1}.ai-chat-window{animation:windowOpen var(--duration-slow,.35s) var(--spring-bounce,cubic-bezier(.34,1.56,.64,1));background:var(--bg-primary,#fff);border:1px solid var(--border-default,#d3d3d3);border-radius:var(--radius-window-top,22px) var(--radius-window-top,22px) var(--radius-window-bottom,44px) var(--radius-window-bottom,44px);box-shadow:var(--shadow-window,0 0 15px 5px rgba(0,0,0,.08));display:flex;flex-direction:column;overflow:hidden;position:absolute;transform-origin:bottom right;z-index:2}.ai-chat-widget.dark .ai-chat-window{background:var(--bg-primary,#282625);border-color:var(--border-default,#5d5b5b);border-width:.7px}.ai-chat-window.closing{animation:windowClose var(--duration-normal) var(--spring-smooth) forwards}.ai-chat-window.size-small{height:580px;width:380px}.ai-chat-window.size-medium{height:720px;width:440px}.ai-chat-window.size-large{height:820px;width:520px}.ai-chat-widget-container.bottom-right .ai-chat-window{bottom:calc(var(--button-size, 56px) + 8px);right:0}.ai-chat-widget-container.bottom-left .ai-chat-window{bottom:calc(var(--button-size, 56px) + 8px);left:0}.ai-chat-widget-container.top-right .ai-chat-window{right:0;top:calc(var(--button-size, 56px) + 8px)}.ai-chat-widget-container.top-left .ai-chat-window{left:0;top:calc(var(--button-size, 56px) + 8px)}.ai-chat-header{align-items:center;background:var(--bg-primary,#fff);border-bottom:1px solid var(--border-default,#d3d3d3);border-radius:var(--radius-window-top,22px) var(--radius-window-top,22px) 0 0;display:flex;justify-content:space-between;padding:18px var(--space-md,16px);position:relative;z-index:10}.ai-chat-widget.dark .ai-chat-header{background:var(--bg-primary,#282625);border-bottom-color:var(--border-default,#5d5b5b);border-bottom-width:.7px}.ai-chat-header.is-history{padding-left:var(--space-md)}.ai-chat-header.is-history .ai-chat-title{flex:1;min-width:0;overflow:hidden;padding-right:var(--space-lg);text-overflow:ellipsis;white-space:nowrap}.ai-chat-header-content{align-items:center;display:flex;flex:1;gap:var(--space-lg)}.ai-chat-header-actions{align-items:center;display:flex;gap:var(--space-sm)}.ai-chat-logo{border-radius:10px;height:36px;object-fit:cover;width:36px}.ai-chat-title{color:var(--text-primary,#3e3e3e);font-size:var(--text-xl,22px);font-weight:var(--font-weight-bold,700);letter-spacing:-.02em}.ai-chat-widget.dark .ai-chat-title{color:var(--text-primary,#fff)}.ai-chat-close-button{align-items:center;background:transparent;border:none;border-radius:var(--radius-md);color:var(--text-primary);cursor:pointer;display:flex;height:32px;justify-content:center;padding:0;transition:color var(--duration-fast) ease;width:32px}.ai-chat-close-button:hover{color:var(--text-muted)}.ai-chat-close-button:active{transform:scale(.95)}.ai-chat-header-button{align-items:center;background:transparent;border:none;border-radius:var(--radius-md);color:var(--text-muted);cursor:pointer;display:flex;height:32px;justify-content:center;padding:0;transition:all var(--duration-fast) ease;width:32px}.ai-chat-header-button:hover{background:var(--bg-secondary);color:var(--text-secondary)}.ai-chat-header-button svg{height:18px;width:18px}.ai-chat-messages{-webkit-overflow-scrolling:touch;-ms-overflow-style:none;align-items:stretch;background:var(--bg-primary,#fff);display:flex;flex:1;flex-direction:column;gap:var(--space-md,16px);justify-content:flex-start;overflow-x:hidden;overflow-y:auto;padding:var(--space-lg,24px) var(--space-md,16px) 100px;position:relative;scroll-behavior:smooth;scrollbar-width:none}.ai-chat-widget.dark .ai-chat-messages{background:var(--bg-primary,#18181b)}.ai-chat-messages::-webkit-scrollbar{display:none}.ai-chat-message{animation:messageSlideIn var(--duration-normal) var(--spring-bounce);display:flex;flex-direction:column;gap:6px}.ai-chat-message-content{word-wrap:break-word;font-size:var(--text-md);line-height:var(--line-height-relaxed);max-width:85%}.ai-chat-message.user{align-items:flex-end}.ai-chat-message.user .ai-chat-message-content{background:var(--user-bg,#f4f3f0);border:none;border-radius:var(--radius-chat-bubble,15px);box-shadow:none;color:var(--user-text,#000);padding:var(--space-sm,8px) var(--space-md,16px)}.ai-chat-widget.dark .ai-chat-message.user .ai-chat-message-content{background:var(--user-bg,#484848);color:var(--user-text,#fff)}.ai-chat-message.user .ai-chat-message-meta{justify-content:flex-end;padding-right:var(--space-xs)}.ai-chat-message.assistant{align-items:flex-start}.ai-chat-message.assistant .ai-chat-message-content{background:var(--agent-bg,transparent);border:none;color:var(--agent-text,#18181b);padding:0}.ai-chat-widget.dark .ai-chat-message.assistant .ai-chat-message-content{color:var(--agent-text,#fafafa)}.ai-chat-message.system{align-items:center}.ai-chat-message.system .ai-chat-message-content{background:hsla(48,96%,89%,.8);border-radius:var(--radius-md);color:#92400e;font-size:var(--text-xs);font-style:italic;max-width:90%;padding:var(--space-sm) var(--space-md);text-align:center}.ai-chat-widget.dark .ai-chat-message.system .ai-chat-message-content{background:rgba(120,53,15,.5);color:#fef3c7}.ai-chat-message.tool{align-items:flex-start}.ai-chat-message.tool .ai-chat-message-content{background:rgba(219,234,254,.8);border-radius:var(--radius-chat-bubble);border-bottom-left-radius:var(--radius-xs);color:#1e40af;font-family:Courier New,monospace;font-size:var(--text-sm);padding:var(--space-sm) var(--space-md)}.ai-chat-widget.dark .ai-chat-message.tool .ai-chat-message-content{background:rgba(30,58,138,.5);color:#dbeafe}.ai-chat-message-meta{align-items:center;color:var(--text-muted);display:flex;font-size:var(--text-xs);gap:var(--space-sm);padding-left:var(--space-xs)}.ai-chat-message-timestamp{font-size:var(--text-xs);line-height:1}.ai-chat-typing{align-items:center;animation:messageSlideIn var(--duration-normal) var(--spring-bounce);background:transparent;display:flex;gap:5px;padding:0}.ai-chat-typing-dot{animation:typingPulse 1.4s ease-in-out infinite;background:var(--text-muted);border-radius:50%;height:6px;width:6px}.ai-chat-typing-dot:nth-child(2){animation-delay:.15s}.ai-chat-typing-dot:nth-child(3){animation-delay:.3s}.ai-chat-welcome{align-items:stretch;animation:welcomeFadeIn var(--duration-slow) var(--spring-smooth);display:flex;flex-direction:column;justify-content:flex-start;padding:0;text-align:left}.ai-chat-welcome-text,.ai-chat-welcome-title{align-self:flex-start}.ai-chat-welcome-title{color:var(--text-primary);font-size:var(--text-2xl);font-weight:var(--font-weight-semibold);letter-spacing:-.02em;margin-bottom:var(--space-md)}.ai-chat-welcome-text{color:var(--text-secondary);font-size:var(--text-md);line-height:var(--line-height-relaxed);max-width:100%}.ai-chat-error{align-items:flex-start;align-self:center;background:var(--bg-secondary);border:none;border-radius:var(--radius-chat-bubble);color:var(--text-primary);display:flex;font-size:var(--text-md);font-weight:var(--font-weight-normal);gap:10px;line-height:1.5;margin:0 auto;max-width:90%;padding:10px var(--space-md)}.ai-chat-error:before{align-items:center;background:rgba(239,68,68,.15);border-radius:50%;color:#ef4444;content:\"⚠\";display:flex;flex-shrink:0;font-size:var(--text-xs);font-weight:700;height:18px;justify-content:center;margin-top:2px;width:18px}.ai-chat-widget.dark .ai-chat-error:before{background:rgba(239,68,68,.2);color:#fca5a5}.ai-chat-message.assistant .ai-chat-message-content p{margin:0 0 12px}.ai-chat-message.assistant .ai-chat-message-content p:last-child{margin-bottom:0}.ai-chat-message.assistant .ai-chat-message-content ol,.ai-chat-message.assistant .ai-chat-message-content ul{margin:8px 0 12px;padding-left:24px}.ai-chat-message.assistant .ai-chat-message-content li{line-height:1.5;margin:6px 0}.ai-chat-message.assistant .ai-chat-message-content strong{font-weight:var(--font-weight-semibold)}.ai-chat-message.assistant .ai-chat-message-content em{font-style:italic}.ai-chat-message.assistant .ai-chat-message-content code{background:rgba(0,0,0,.06);border-radius:var(--radius-sm);font-family:SF Mono,Consolas,Monaco,monospace;font-size:.9em;padding:2px 6px}.ai-chat-widget.dark .ai-chat-message.assistant .ai-chat-message-content code{background:hsla(0,0%,100%,.1)}.ai-chat-message.assistant .ai-chat-message-content pre{background:rgba(0,0,0,.06);border-radius:var(--radius-md);margin:8px 0 12px;overflow-x:auto;padding:var(--space-sm)}.ai-chat-widget.dark .ai-chat-message.assistant .ai-chat-message-content pre{background:hsla(0,0%,100%,.08)}.ai-chat-message.assistant .ai-chat-message-content pre code{background:transparent;border-radius:0;padding:0}.ai-chat-message.assistant .ai-chat-message-content blockquote{border-left:3px solid var(--btn-primary-bg);color:var(--text-muted);margin:8px 0 12px;padding:4px 0 4px 12px}.ai-chat-message.assistant .ai-chat-message-content a{color:var(--btn-primary-bg);text-decoration:underline}.ai-chat-message.assistant .ai-chat-message-content a:hover{opacity:.8}.ai-chat-message.assistant .ai-chat-message-content h1,.ai-chat-message.assistant .ai-chat-message-content h2,.ai-chat-message.assistant .ai-chat-message-content h3,.ai-chat-message.assistant .ai-chat-message-content h4,.ai-chat-message.assistant .ai-chat-message-content h5,.ai-chat-message.assistant .ai-chat-message-content h6{font-weight:var(--font-weight-semibold);line-height:var(--line-height-tight);margin:16px 0 8px}.ai-chat-message.assistant .ai-chat-message-content h1:first-child,.ai-chat-message.assistant .ai-chat-message-content h2:first-child,.ai-chat-message.assistant .ai-chat-message-content h3:first-child{margin-top:0}.ai-chat-message.assistant .ai-chat-message-content hr{border:none;border-top:1px solid var(--border-subtle);margin:12px 0}.ai-chat-input-container{background:linear-gradient(to bottom,transparent 0,var(--bg-primary,#fff) 50%,var(--bg-primary,#fff) 100%);bottom:0;left:0;padding-top:30px;position:absolute;right:0;z-index:10}.ai-chat-widget.dark .ai-chat-input-container{background:linear-gradient(to bottom,transparent 0,var(--bg-primary,#282625) 50%,var(--bg-primary,#282625) 100%)}.ai-chat-input-container.separate{padding:0 var(--radius-window-gutter,16px) var(--radius-window-gutter,16px);padding-top:30px}.ai-chat-input-wrapper{align-items:center;background:var(--input-bg,#f4f4f4);border:1px solid var(--input-border,#d3d3d3);border-radius:var(--radius-input,62px);display:flex;gap:0;height:52px;padding:6px 6px 6px 12px;position:relative;transition:all var(--duration-fast,.15s) ease;z-index:5}.ai-chat-widget.dark .ai-chat-input-wrapper{background:var(--input-bg,#4a4846);border-color:var(--input-border,#5d5b5b);border-width:.7px;box-shadow:var(--shadow-input,0 0 10px rgba(0,0,0,.15))}.ai-chat-input-wrapper:focus-within{border-color:var(--text-muted,#a1a1aa)}.ai-chat-input{background:transparent;border:none;color:var(--input-text,#000);flex:1;font-family:inherit;font-size:var(--text-md,15px);height:20px;line-height:var(--line-height-normal,1.4);max-height:20px;min-height:20px;outline:none;overflow:hidden;padding:0 var(--space-sm,8px);resize:none}.ai-chat-widget.dark .ai-chat-input{color:var(--input-text,#fff)}.ai-chat-input::placeholder{color:var(--text-placeholder,#a1a1aa)}.ai-chat-widget.dark .ai-chat-input::placeholder{color:var(--text-placeholder,#52525b)}.ai-chat-file-button{align-items:center;background:transparent;border:none;color:var(--text-placeholder);cursor:pointer;display:flex;flex-shrink:0;height:28px;justify-content:center;padding:0;transition:color var(--duration-fast) ease;width:28px}.ai-chat-file-button:hover{color:var(--text-secondary)}.ai-chat-file-button:disabled{cursor:not-allowed;opacity:.5}.ai-chat-send-button{align-items:center;background:var(--send-button-background,var(--primary-color,var(--button-color,var(--btn-primary-bg,#151515))));border:none;border-radius:50%;color:var(--button-icon-color,var(--btn-primary-text,#f4f4f4));cursor:pointer;display:flex;flex-shrink:0;height:40px;justify-content:center;padding:0;transition:all var(--duration-fast,.15s) ease;width:40px}.ai-chat-widget.dark .ai-chat-send-button{background:var(--send-button-background,var(--primary-color,var(--button-color,var(--btn-primary-bg,#fff))));color:var(--button-icon-color,var(--btn-primary-text,#312f2d))}.ai-chat-send-button.active{background:var(--send-button-background,var(--primary-color,var(--button-color,var(--btn-primary-bg,#151515))));color:var(--button-icon-color,var(--btn-primary-text,#f4f4f4))}.ai-chat-widget.dark .ai-chat-send-button.active{background:var(--send-button-background,var(--primary-color,var(--button-color,var(--btn-primary-bg,#fff))));color:var(--button-icon-color,var(--btn-primary-text,#312f2d))}.ai-chat-send-button:hover:not(:disabled){opacity:.8}.ai-chat-send-button:active:not(:disabled){transform:scale(.95)}.ai-chat-send-button:disabled{cursor:not-allowed;opacity:.3}.ai-chat-file-list{display:flex;flex-wrap:wrap;gap:var(--space-sm);padding:var(--space-sm) var(--space-sm)}.ai-chat-file-item{align-items:center;background:rgba(0,0,0,.05);border-radius:6px;display:flex;font-size:var(--text-xs);gap:var(--space-sm);padding:6px 10px}.ai-chat-file-extension{background:var(--btn-primary-bg);border-radius:3px;color:var(--btn-primary-text);display:inline-block;font-size:10px;font-weight:var(--font-weight-semibold);min-width:40px;padding:2px 6px;text-align:center;text-transform:uppercase}.ai-chat-file-info{display:flex;flex:1;flex-direction:column;gap:2px;min-width:0}.ai-chat-file-name{font-weight:var(--font-weight-medium);max-width:150px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ai-chat-file-size{color:var(--text-muted);font-size:10px;opacity:.7}.ai-chat-file-remove{align-items:center;background:none;border:none;color:inherit;cursor:pointer;display:flex;justify-content:center;opacity:.5;padding:var(--space-xs);transition:opacity var(--duration-fast) ease}.ai-chat-file-remove:hover{opacity:1}.ai-chat-suggested-questions{align-self:flex-end;margin:0;padding:16px 0 0;width:100%}.ai-chat-suggested-questions-list{align-items:center;display:flex;flex-wrap:wrap;gap:6px;justify-content:flex-end}.ai-chat-suggested-question{background:var(--primary-color,var(--button-color,var(--user-bg,#f4f3f0)));border:none;border-radius:var(--radius-preset-badge,13px);color:var(--button-icon-color,var(--user-text,#000));cursor:pointer;font-size:14px;font-weight:400;line-height:1.3;padding:8px 14px;transition:background .15s ease,opacity .15s ease;white-space:nowrap}.ai-chat-widget.dark .ai-chat-suggested-question{background:var(--primary-color,var(--button-color,var(--user-bg,#484848)));color:var(--button-icon-color,var(--user-text,#fff))}.ai-chat-suggested-question-text{white-space:nowrap}.ai-chat-suggested-question:hover{filter:brightness(.9)}.ai-chat-widget.dark .ai-chat-suggested-question:hover{filter:brightness(1.15)}.ai-chat-suggested-question:active{transform:scale(.98)}.ai-chat-suggested-question-icon{display:none}.ai-chat-feedback-buttons{align-items:center;display:flex;gap:var(--space-xs)}.ai-chat-feedback{align-items:center;display:inline-flex;gap:0;height:20px}.ai-chat-feedback-button{align-items:center;background:transparent!important;border:none;border-radius:var(--radius-sm);color:var(--text-placeholder);cursor:pointer;display:flex;font-size:var(--text-sm);height:20px;justify-content:center;padding:var(--space-xs);transition:all var(--duration-fast) var(--spring-bounce)}.ai-chat-feedback-button:hover:not(:disabled){background:none!important;color:var(--text-secondary)}.ai-chat-feedback-button:active:not(:disabled){transform:scale(.9)}.ai-chat-feedback-button:disabled{cursor:not-allowed;opacity:.4}.ai-chat-feedback-button.active{background:none!important;color:var(--text-primary)}.ai-chat-feedback-submitted{align-items:center;animation:feedbackMorph .3s var(--spring-bounce);display:flex;gap:6px}.ai-chat-feedback-checkmark{animation:checkmarkPop .3s var(--spring-bounce);color:#10b981;font-size:var(--text-md);font-weight:700}.ai-chat-feedback-text{color:#10b981;font-size:var(--text-sm);font-weight:var(--font-weight-medium)}.ai-chat-history-panel{background:var(--bg-primary,#fff);display:flex;flex:1;flex-direction:column;overflow:hidden}.ai-chat-widget.dark .ai-chat-history-panel{background:var(--bg-primary,#18181b)}.ai-chat-history-empty,.ai-chat-history-loading{align-items:center;color:var(--text-muted);display:flex;flex:1;font-size:var(--text-sm);justify-content:center;padding:var(--space-lg);text-align:center}.ai-chat-history-list{-ms-overflow-style:none;display:flex;flex:1;flex-direction:column;gap:var(--space-sm);overflow-y:auto;padding:var(--space-md) var(--space-md) 120px;scrollbar-width:none}.ai-chat-history-list::-webkit-scrollbar{display:none}.ai-chat-history-list.exiting{animation:ai-chat-history-exit .22s var(--spring-smooth) forwards}.ai-chat-history-item{align-items:stretch;background:var(--user-bg,#f4f4f5);border:none;border-radius:var(--radius-history-item,15px);cursor:pointer;display:flex;flex-direction:column;margin:0;padding:var(--space-sm,8px) var(--space-md,16px);text-align:left;transition:background var(--duration-fast,.15s) ease;width:100%}.ai-chat-widget.dark .ai-chat-history-item{background:var(--user-bg,#27272a)}.ai-chat-history-item:hover{background:var(--user-bg-hover,#e5e7eb)}.ai-chat-widget.dark .ai-chat-history-item:hover{background:var(--user-bg-hover,#3f3f46)}.ai-chat-history-item.active{background:var(--user-bg-hover,#e5e7eb)}.ai-chat-widget.dark .ai-chat-history-item.active{background:var(--user-bg-hover,#3f3f46)}.ai-chat-history-item-preview{color:var(--text-primary,#18181b);font-size:var(--text-sm,14px);font-weight:var(--font-weight-medium,500);line-height:var(--line-height-normal,1.4);margin-bottom:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ai-chat-widget.dark .ai-chat-history-item-preview{color:var(--text-primary,#fafafa)}.ai-chat-history-item.active .ai-chat-history-item-preview{font-weight:var(--font-weight-medium)}.ai-chat-history-item-meta{display:none}.ai-chat-tool-row{align-items:center;display:flex;gap:10px;margin:var(--space-sm) 0 6px}.ai-chat-tool-gear{align-items:center;color:var(--text-primary);display:inline-flex;height:26px;justify-content:center;width:26px}.ai-chat-tool-gear.spinning{animation:ai-chat-gear-spin .9s linear infinite}.ai-chat-tool-pills{display:flex;flex-wrap:wrap;gap:var(--space-sm)}.ai-chat-tool-pill{align-items:center;border-radius:var(--radius-pill);color:var(--button-icon-color,var(--btn-primary-text,var(--text-primary)));display:inline-flex;font-size:var(--text-sm);font-weight:var(--font-weight-medium);justify-content:center;line-height:1;padding:var(--space-sm) 14px}.ai-chat-tool-pill,.ai-chat-tool-pill.active{background:var(--primary-color,var(--button-color,var(--btn-primary-bg,var(--bg-secondary))))}.ai-chat-tool-pill.active{animation:ai-chat-tool-active 1.1s ease-in-out infinite;overflow:hidden;position:relative}.ai-chat-tool-pill.done{background:var(--primary-color,var(--button-color,var(--btn-primary-bg)));color:var(--button-icon-color,var(--btn-primary-text))}.ai-chat-tool-indicators{display:flex;gap:6px;margin-top:6px}.tool-indicator{align-items:center;background:linear-gradient(135deg,rgba(59,130,246,.2),rgba(59,130,246,.1));border-radius:50%;color:#3b82f6;display:inline-flex;height:24px;justify-content:center;position:relative;width:24px}.tool-indicator .icon{font-size:var(--text-xs);line-height:1;z-index:1}.tool-indicator.started:after{animation:ai-chat-gear-spin .8s linear infinite;border:2px solid transparent;border-radius:50%;border-top-color:#3b82f6;content:\"\";inset:-2px;position:absolute}.ai-chat-tool-message{align-items:center;background:hsla(0,0%,50%,.1);border:none;border-radius:var(--radius-pill);color:hsla(0,0%,50%,.8);display:inline-flex;font-size:12px;gap:5px;padding:4px 10px}.ai-chat-tool-message .ai-chat-tool-spinner{animation:ai-chat-tool-spin 1s linear infinite;flex-shrink:0;opacity:.6}.ai-chat-tool-message .ai-chat-tool-check{flex-shrink:0;opacity:.7}.ai-chat-tool-message .ai-chat-tool-error{color:#ef4444;flex-shrink:0;opacity:.7}.ai-chat-tool-message.error{background:rgba(239,68,68,.1);color:rgba(239,68,68,.9)}.tool-name{font-size:12px;font-weight:var(--font-weight-regular);line-height:1.2;white-space:nowrap}@keyframes ai-chat-tool-spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}@keyframes ai-chat-tool-check-appear{0%{opacity:0;transform:scale(.5)}to{opacity:.7;transform:scale(1)}}.ai-chat-sources{background:rgba(0,0,0,.02);border-radius:6px;font-size:var(--text-xs);margin-top:var(--space-sm);overflow:hidden}.ai-chat-sources-toggle{align-items:center;background:none;border:none;cursor:pointer;display:flex;gap:6px;padding:var(--space-sm) 10px;text-align:left;transition:background var(--duration-fast) ease;width:100%}.ai-chat-sources-toggle:hover{background:rgba(0,0,0,.03)}.ai-chat-sources-icon{color:var(--text-muted);font-size:10px;transition:transform var(--duration-fast) ease}.ai-chat-sources-title{color:var(--text-primary);flex:1;font-size:11px;font-weight:var(--font-weight-semibold);letter-spacing:.5px;text-transform:uppercase}.ai-chat-source-item{border-top:1px solid rgba(0,0,0,.05);color:var(--text-muted);display:flex;gap:var(--space-sm);padding:var(--space-sm) 10px}.ai-chat-source-item:last-child{border-bottom:none}.ai-chat-source-number{color:var(--btn-primary-bg);flex-shrink:0;font-weight:var(--font-weight-semibold)}.ai-chat-source-details{display:flex;flex:1;flex-direction:column;gap:var(--space-xs)}.ai-chat-source-score{color:var(--text-placeholder);font-size:11px}.ai-chat-source-content{color:var(--text-muted);font-size:11px;font-style:italic;line-height:var(--line-height-normal)}.ai-chat-source-metadata{display:flex;flex-wrap:wrap;gap:6px;margin-top:2px}.ai-chat-source-meta-item{background:rgba(0,0,0,.05);border-radius:3px;color:var(--text-muted);font-size:10px;padding:2px 6px}";
|
|
39620
39729
|
styleInject(css_248z);
|
|
39621
39730
|
|
|
39622
39731
|
// Icon components mapping
|
|
@@ -39624,19 +39733,76 @@
|
|
|
39624
39733
|
FiMessageCircle: () => (jsxRuntimeExports.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntimeExports.jsx("path", { d: "M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z" }) })),
|
|
39625
39734
|
FiChevronDown: () => (jsxRuntimeExports.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntimeExports.jsx("polyline", { points: "6 9 12 15 18 9" }) })),
|
|
39626
39735
|
};
|
|
39627
|
-
const ChatWidget = ({ widgetId, apiUrl = window.location.origin, position = 'bottom-right', primaryColor, onOpen, onClose, onMessage, onError, }) => {
|
|
39736
|
+
const ChatWidget = ({ widgetId, apiUrl = window.location.origin, previewMode = false, previewConfig, position = 'bottom-right', primaryColor, size, headerTitle, welcomeTitle, welcomeMessage, placeholder, theme, suggestedQuestions, customStyles, onOpen, onClose, onMessage, onError, }) => {
|
|
39628
39737
|
const [isOpen, setIsOpen] = reactExports.useState(false);
|
|
39629
39738
|
const [autoDetectedTheme, setAutoDetectedTheme] = reactExports.useState('light');
|
|
39630
39739
|
const widgetRef = reactExports.useRef(null);
|
|
39631
39740
|
const containerRef = reactExports.useRef(null);
|
|
39632
|
-
|
|
39633
|
-
|
|
39634
|
-
|
|
39635
|
-
|
|
39741
|
+
// Default config for preview mode
|
|
39742
|
+
const defaultPreviewConfig = {
|
|
39743
|
+
appearance: {
|
|
39744
|
+
primaryColor: primaryColor || '#0077FF',
|
|
39745
|
+
position: position || 'bottom-right',
|
|
39746
|
+
size: size || 'small',
|
|
39747
|
+
headerTitle: headerTitle || 'AI Assistant',
|
|
39748
|
+
welcomeTitle: welcomeTitle || 'Welcome!',
|
|
39749
|
+
welcomeMessage: welcomeMessage || 'Hi there! How can I help you today?',
|
|
39750
|
+
placeholder: placeholder || 'Ask me anything...',
|
|
39751
|
+
},
|
|
39752
|
+
settings: {
|
|
39753
|
+
autoOpen: false,
|
|
39754
|
+
persistConversation: true,
|
|
39755
|
+
showChatHistory: true,
|
|
39756
|
+
showTimestamps: true,
|
|
39757
|
+
showTypingIndicator: true,
|
|
39758
|
+
enableFileUpload: false,
|
|
39759
|
+
enableFeedback: true,
|
|
39760
|
+
showSources: false,
|
|
39761
|
+
sourceDisplayMode: 'none',
|
|
39762
|
+
},
|
|
39763
|
+
behavior: {
|
|
39764
|
+
agentic: false,
|
|
39765
|
+
},
|
|
39766
|
+
knowledgeBases: [],
|
|
39767
|
+
};
|
|
39768
|
+
// Merge preview config with defaults
|
|
39769
|
+
const mergedPreviewConfig = {
|
|
39770
|
+
...defaultPreviewConfig,
|
|
39771
|
+
...previewConfig,
|
|
39772
|
+
appearance: {
|
|
39773
|
+
...defaultPreviewConfig.appearance,
|
|
39774
|
+
...previewConfig?.appearance,
|
|
39775
|
+
},
|
|
39776
|
+
settings: {
|
|
39777
|
+
...defaultPreviewConfig.settings,
|
|
39778
|
+
...previewConfig?.settings,
|
|
39779
|
+
},
|
|
39780
|
+
behavior: {
|
|
39781
|
+
...defaultPreviewConfig.behavior,
|
|
39782
|
+
...previewConfig?.behavior,
|
|
39783
|
+
},
|
|
39784
|
+
};
|
|
39785
|
+
// Always call useChat hook (React rules), but use a dummy widgetId in preview mode
|
|
39786
|
+
// The hook will fail to load config, but we don't use its results in preview mode anyway
|
|
39787
|
+
const chatHook = useChat({
|
|
39788
|
+
widgetId: previewMode ? '__preview__' : (widgetId || '__preview__'),
|
|
39636
39789
|
apiUrl,
|
|
39637
|
-
onMessage,
|
|
39638
|
-
onError,
|
|
39790
|
+
onMessage: previewMode ? undefined : onMessage,
|
|
39791
|
+
onError: previewMode ? undefined : onError,
|
|
39639
39792
|
});
|
|
39793
|
+
// Extract values from hook or use preview defaults
|
|
39794
|
+
const messages = previewMode ? [] : chatHook.messages;
|
|
39795
|
+
const isLoading = previewMode ? false : chatHook.isLoading;
|
|
39796
|
+
const isTyping = previewMode ? false : chatHook.isTyping;
|
|
39797
|
+
const error = previewMode ? null : chatHook.error;
|
|
39798
|
+
const config = previewMode ? mergedPreviewConfig : chatHook.config;
|
|
39799
|
+
const sendMessage = previewMode ? (() => Promise.resolve()) : chatHook.sendMessage;
|
|
39800
|
+
const submitFeedback = previewMode ? (() => Promise.resolve()) : chatHook.submitFeedback;
|
|
39801
|
+
const conversations = previewMode ? [] : chatHook.conversations;
|
|
39802
|
+
const loadConversations = previewMode ? (() => { }) : chatHook.loadConversations;
|
|
39803
|
+
const switchConversation = previewMode ? (() => Promise.resolve()) : chatHook.switchConversation;
|
|
39804
|
+
const startNewConversation = previewMode ? (() => { }) : chatHook.startNewConversation;
|
|
39805
|
+
const conversationId = previewMode ? '' : chatHook.conversationId;
|
|
39640
39806
|
// Auto-detect theme from background
|
|
39641
39807
|
reactExports.useEffect(() => {
|
|
39642
39808
|
if (!containerRef.current)
|
|
@@ -39674,8 +39840,8 @@
|
|
|
39674
39840
|
}, [config, autoDetectedTheme]);
|
|
39675
39841
|
// Handle auto-open
|
|
39676
39842
|
reactExports.useEffect(() => {
|
|
39677
|
-
if (config?.
|
|
39678
|
-
const delay = config.
|
|
39843
|
+
if (config?.settings.autoOpen) {
|
|
39844
|
+
const delay = config.settings.autoOpenDelay || 0;
|
|
39679
39845
|
const timer = setTimeout(() => {
|
|
39680
39846
|
setIsOpen(true);
|
|
39681
39847
|
onOpen?.();
|
|
@@ -39697,31 +39863,33 @@
|
|
|
39697
39863
|
document.addEventListener('keydown', handleEscapeKey);
|
|
39698
39864
|
return () => document.removeEventListener('keydown', handleEscapeKey);
|
|
39699
39865
|
}, [isOpen, onClose]);
|
|
39700
|
-
// Determine theme -
|
|
39866
|
+
// Determine theme - use prop override if provided, otherwise auto-detect
|
|
39701
39867
|
const appearanceConfig = config?.appearance;
|
|
39702
|
-
const effectiveTheme = autoDetectedTheme;
|
|
39703
|
-
// Determine position (
|
|
39704
|
-
const effectivePosition = config?.appearance.position ||
|
|
39705
|
-
// Get accent color from
|
|
39706
|
-
const accentColor = primaryColor
|
|
39868
|
+
const effectiveTheme = theme ?? autoDetectedTheme;
|
|
39869
|
+
// Determine position (prop override takes priority for live preview)
|
|
39870
|
+
const effectivePosition = position || config?.appearance.position || 'bottom-right';
|
|
39871
|
+
// Get accent color from prop or config (empty string means no accent color / vanilla mode)
|
|
39872
|
+
const accentColor = primaryColor ?? appearanceConfig?.primaryColor ?? '';
|
|
39873
|
+
// Apply prop overrides for live preview (props take priority over config)
|
|
39874
|
+
size || appearanceConfig?.size || 'small';
|
|
39875
|
+
const effectiveHeaderTitle = headerTitle ?? appearanceConfig?.headerTitle ?? '';
|
|
39876
|
+
const effectiveWelcomeTitle = welcomeTitle ?? appearanceConfig?.welcomeTitle ?? '';
|
|
39877
|
+
const effectiveWelcomeMessage = welcomeMessage ?? appearanceConfig?.welcomeMessage ?? '';
|
|
39878
|
+
const effectivePlaceholder = placeholder ?? appearanceConfig?.placeholder ?? '';
|
|
39707
39879
|
// Generate styles using simplified theme system
|
|
39708
39880
|
const simpleAppearance = {
|
|
39709
|
-
accentColor
|
|
39710
|
-
size: appearanceConfig?.size || 'small',
|
|
39711
|
-
welcomeMessage: appearanceConfig?.welcomeMessage || '',
|
|
39712
|
-
placeholder: appearanceConfig?.placeholder || '',
|
|
39713
|
-
headerTitle: appearanceConfig?.headerTitle || '',
|
|
39714
|
-
};
|
|
39881
|
+
accentColor};
|
|
39715
39882
|
// Generate theme styles from accent color
|
|
39716
39883
|
const generatedStyles = generateThemeStyles(simpleAppearance, effectiveTheme);
|
|
39717
39884
|
// Also apply legacy styles for backward compatibility
|
|
39718
39885
|
const legacyStyles = appearanceConfig
|
|
39719
39886
|
? applyAppearanceStyles(appearanceConfig)
|
|
39720
39887
|
: {};
|
|
39721
|
-
// Merge styles (generated takes priority for new simplified system)
|
|
39722
|
-
const
|
|
39888
|
+
// Merge styles (generated takes priority for new simplified system, then custom overrides)
|
|
39889
|
+
const mergedStyles = {
|
|
39723
39890
|
...legacyStyles,
|
|
39724
39891
|
...generatedStyles,
|
|
39892
|
+
...customStyles,
|
|
39725
39893
|
};
|
|
39726
39894
|
// Debug logging for theme and styles
|
|
39727
39895
|
reactExports.useEffect(() => {
|
|
@@ -39746,16 +39914,19 @@
|
|
|
39746
39914
|
await submitFeedback(messageId, feedback);
|
|
39747
39915
|
};
|
|
39748
39916
|
// Don't render until config is loaded to avoid flash of unstyled content
|
|
39749
|
-
|
|
39917
|
+
// In preview mode, config is always available
|
|
39918
|
+
if (!config && !previewMode) {
|
|
39750
39919
|
console.log('[ChatWidget] Not rendering - config not loaded yet');
|
|
39751
39920
|
return null;
|
|
39752
39921
|
}
|
|
39753
39922
|
console.log('[ChatWidget] Rendering widget', { isOpen, hasConfig: !!config });
|
|
39754
39923
|
// Get button icon based on state
|
|
39755
39924
|
const IconComponent = isOpen ? iconComponents.FiChevronDown : iconComponents.FiMessageCircle;
|
|
39756
|
-
return (jsxRuntimeExports.jsx("div", { ref: containerRef, className: `ai-chat-widget ${effectiveTheme}`, style:
|
|
39925
|
+
return (jsxRuntimeExports.jsx("div", { ref: containerRef, className: `ai-chat-widget ${effectiveTheme}`, style: mergedStyles, children: jsxRuntimeExports.jsxs("div", { ref: widgetRef, className: `ai-chat-widget-container ${effectivePosition}`, children: [isOpen && (jsxRuntimeExports.jsx(ChatWindow, { messages: messages, isLoading: isLoading, isTyping: isTyping, error: error, config: config, onSendMessage: sendMessage, onClose: handleToggle, onFeedback: handleFeedback,
|
|
39757
39926
|
// Chat history props (only active when persistConversation is true)
|
|
39758
|
-
conversations: conversations, onLoadConversations: loadConversations, onSwitchConversation: switchConversation, onStartNewConversation: startNewConversation, currentConversationId: conversationId
|
|
39927
|
+
conversations: conversations, onLoadConversations: loadConversations, onSwitchConversation: switchConversation, onStartNewConversation: startNewConversation, currentConversationId: conversationId,
|
|
39928
|
+
// Override props for live preview
|
|
39929
|
+
headerTitleOverride: effectiveHeaderTitle, welcomeTitleOverride: effectiveWelcomeTitle, welcomeMessageOverride: effectiveWelcomeMessage, placeholderOverride: effectivePlaceholder, suggestedQuestionsOverride: suggestedQuestions })), jsxRuntimeExports.jsx("button", { className: `ai-chat-button ${isOpen ? 'is-open' : ''}`, onClick: handleToggle, "aria-label": isOpen ? "Minimize chat" : "Open chat", children: jsxRuntimeExports.jsx("div", { className: "ai-chat-button-svg", children: jsxRuntimeExports.jsx(IconComponent, {}) }) })] }) }));
|
|
39759
39930
|
};
|
|
39760
39931
|
|
|
39761
39932
|
/**
|