@chatwidgetai/chat-widget 0.1.7 → 0.1.9
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 +648 -248
- 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 +11 -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 +11 -0
- package/dist/hooks/useChat.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.js +649 -249
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +648 -248
- 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/dist/utils/storage.d.ts +31 -3
- package/dist/utils/storage.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
|
*/
|
|
@@ -17599,8 +17717,10 @@
|
|
|
17599
17717
|
/**
|
|
17600
17718
|
* Local Storage Utilities
|
|
17601
17719
|
* Handles conversation persistence in browser localStorage
|
|
17720
|
+
* Supports multiple conversations per widget with history
|
|
17602
17721
|
*/
|
|
17603
17722
|
const STORAGE_PREFIX = 'ai-chat-widget';
|
|
17723
|
+
const MAX_STORED_CONVERSATIONS = 20;
|
|
17604
17724
|
/**
|
|
17605
17725
|
* Generate a storage key for a widget
|
|
17606
17726
|
*/
|
|
@@ -17608,33 +17728,113 @@
|
|
|
17608
17728
|
return `${STORAGE_PREFIX}:${widgetId}`;
|
|
17609
17729
|
}
|
|
17610
17730
|
/**
|
|
17611
|
-
*
|
|
17731
|
+
* Get widget storage data
|
|
17612
17732
|
*/
|
|
17613
|
-
function
|
|
17733
|
+
function getWidgetStorage(widgetId) {
|
|
17734
|
+
try {
|
|
17735
|
+
const key = getStorageKey(widgetId);
|
|
17736
|
+
const data = localStorage.getItem(key);
|
|
17737
|
+
if (!data) {
|
|
17738
|
+
return { activeConversationId: null, conversations: {}, history: [] };
|
|
17739
|
+
}
|
|
17740
|
+
const parsed = JSON.parse(data);
|
|
17741
|
+
// Handle legacy format (single conversation)
|
|
17742
|
+
if (parsed.conversationId && parsed.messages) {
|
|
17743
|
+
const legacy = parsed;
|
|
17744
|
+
return {
|
|
17745
|
+
activeConversationId: legacy.conversationId,
|
|
17746
|
+
conversations: { [legacy.conversationId]: legacy },
|
|
17747
|
+
history: [{
|
|
17748
|
+
id: legacy.conversationId,
|
|
17749
|
+
preview: getConversationPreview(legacy.messages),
|
|
17750
|
+
lastUpdated: legacy.lastUpdated,
|
|
17751
|
+
messageCount: legacy.messages.length,
|
|
17752
|
+
}],
|
|
17753
|
+
};
|
|
17754
|
+
}
|
|
17755
|
+
return parsed;
|
|
17756
|
+
}
|
|
17757
|
+
catch (error) {
|
|
17758
|
+
console.error('Failed to get widget storage:', error);
|
|
17759
|
+
return { activeConversationId: null, conversations: {}, history: [] };
|
|
17760
|
+
}
|
|
17761
|
+
}
|
|
17762
|
+
/**
|
|
17763
|
+
* Save widget storage data
|
|
17764
|
+
*/
|
|
17765
|
+
function setWidgetStorage(widgetId, storage) {
|
|
17614
17766
|
try {
|
|
17615
17767
|
const key = getStorageKey(widgetId);
|
|
17616
|
-
|
|
17768
|
+
localStorage.setItem(key, JSON.stringify(storage));
|
|
17769
|
+
}
|
|
17770
|
+
catch (error) {
|
|
17771
|
+
console.error('Failed to save widget storage:', error);
|
|
17772
|
+
}
|
|
17773
|
+
}
|
|
17774
|
+
/**
|
|
17775
|
+
* Get preview text from messages
|
|
17776
|
+
*/
|
|
17777
|
+
function getConversationPreview(messages) {
|
|
17778
|
+
const firstUserMessage = messages.find(m => m.message.type === 'human');
|
|
17779
|
+
if (firstUserMessage) {
|
|
17780
|
+
return firstUserMessage.message.content.slice(0, 100);
|
|
17781
|
+
}
|
|
17782
|
+
return 'New conversation';
|
|
17783
|
+
}
|
|
17784
|
+
/**
|
|
17785
|
+
* Save conversation to localStorage (updates both conversation and history)
|
|
17786
|
+
*/
|
|
17787
|
+
function saveConversation(widgetId, conversationId, messages) {
|
|
17788
|
+
try {
|
|
17789
|
+
const storage = getWidgetStorage(widgetId);
|
|
17790
|
+
const now = new Date().toISOString();
|
|
17791
|
+
// Update conversation data
|
|
17792
|
+
storage.conversations[conversationId] = {
|
|
17617
17793
|
conversationId,
|
|
17618
17794
|
messages,
|
|
17619
|
-
lastUpdated:
|
|
17795
|
+
lastUpdated: now,
|
|
17796
|
+
};
|
|
17797
|
+
// Update active conversation
|
|
17798
|
+
storage.activeConversationId = conversationId;
|
|
17799
|
+
// Update history entry
|
|
17800
|
+
const existingIndex = storage.history.findIndex(h => h.id === conversationId);
|
|
17801
|
+
const historyEntry = {
|
|
17802
|
+
id: conversationId,
|
|
17803
|
+
preview: getConversationPreview(messages),
|
|
17804
|
+
lastUpdated: now,
|
|
17805
|
+
messageCount: messages.length,
|
|
17620
17806
|
};
|
|
17621
|
-
|
|
17807
|
+
if (existingIndex >= 0) {
|
|
17808
|
+
storage.history[existingIndex] = historyEntry;
|
|
17809
|
+
}
|
|
17810
|
+
else {
|
|
17811
|
+
storage.history.unshift(historyEntry);
|
|
17812
|
+
}
|
|
17813
|
+
// Sort by lastUpdated (most recent first)
|
|
17814
|
+
storage.history.sort((a, b) => new Date(b.lastUpdated).getTime() - new Date(a.lastUpdated).getTime());
|
|
17815
|
+
// Limit stored conversations
|
|
17816
|
+
if (storage.history.length > MAX_STORED_CONVERSATIONS) {
|
|
17817
|
+
const toRemove = storage.history.slice(MAX_STORED_CONVERSATIONS);
|
|
17818
|
+
storage.history = storage.history.slice(0, MAX_STORED_CONVERSATIONS);
|
|
17819
|
+
toRemove.forEach(entry => {
|
|
17820
|
+
delete storage.conversations[entry.id];
|
|
17821
|
+
});
|
|
17822
|
+
}
|
|
17823
|
+
setWidgetStorage(widgetId, storage);
|
|
17622
17824
|
}
|
|
17623
17825
|
catch (error) {
|
|
17624
17826
|
console.error('Failed to save conversation:', error);
|
|
17625
17827
|
}
|
|
17626
17828
|
}
|
|
17627
17829
|
/**
|
|
17628
|
-
* Load conversation from localStorage
|
|
17830
|
+
* Load active conversation from localStorage (legacy compatibility)
|
|
17629
17831
|
*/
|
|
17630
17832
|
function loadConversation(widgetId) {
|
|
17631
17833
|
try {
|
|
17632
|
-
const
|
|
17633
|
-
|
|
17634
|
-
if (!data)
|
|
17834
|
+
const storage = getWidgetStorage(widgetId);
|
|
17835
|
+
if (!storage.activeConversationId)
|
|
17635
17836
|
return null;
|
|
17636
|
-
|
|
17637
|
-
return parsed;
|
|
17837
|
+
return storage.conversations[storage.activeConversationId] || null;
|
|
17638
17838
|
}
|
|
17639
17839
|
catch (error) {
|
|
17640
17840
|
console.error('Failed to load conversation:', error);
|
|
@@ -17642,12 +17842,52 @@
|
|
|
17642
17842
|
}
|
|
17643
17843
|
}
|
|
17644
17844
|
/**
|
|
17645
|
-
*
|
|
17845
|
+
* Load a specific conversation by ID
|
|
17846
|
+
*/
|
|
17847
|
+
function loadConversationById(widgetId, conversationId) {
|
|
17848
|
+
try {
|
|
17849
|
+
const storage = getWidgetStorage(widgetId);
|
|
17850
|
+
return storage.conversations[conversationId] || null;
|
|
17851
|
+
}
|
|
17852
|
+
catch (error) {
|
|
17853
|
+
console.error('Failed to load conversation by ID:', error);
|
|
17854
|
+
return null;
|
|
17855
|
+
}
|
|
17856
|
+
}
|
|
17857
|
+
/**
|
|
17858
|
+
* Get conversation history list
|
|
17859
|
+
*/
|
|
17860
|
+
function getConversationHistory(widgetId) {
|
|
17861
|
+
try {
|
|
17862
|
+
const storage = getWidgetStorage(widgetId);
|
|
17863
|
+
return storage.history;
|
|
17864
|
+
}
|
|
17865
|
+
catch (error) {
|
|
17866
|
+
console.error('Failed to get conversation history:', error);
|
|
17867
|
+
return [];
|
|
17868
|
+
}
|
|
17869
|
+
}
|
|
17870
|
+
/**
|
|
17871
|
+
* Set active conversation
|
|
17872
|
+
*/
|
|
17873
|
+
function setActiveConversation(widgetId, conversationId) {
|
|
17874
|
+
try {
|
|
17875
|
+
const storage = getWidgetStorage(widgetId);
|
|
17876
|
+
storage.activeConversationId = conversationId;
|
|
17877
|
+
setWidgetStorage(widgetId, storage);
|
|
17878
|
+
}
|
|
17879
|
+
catch (error) {
|
|
17880
|
+
console.error('Failed to set active conversation:', error);
|
|
17881
|
+
}
|
|
17882
|
+
}
|
|
17883
|
+
/**
|
|
17884
|
+
* Clear current conversation (start fresh, but keep history)
|
|
17646
17885
|
*/
|
|
17647
17886
|
function clearConversation(widgetId) {
|
|
17648
17887
|
try {
|
|
17649
|
-
const
|
|
17650
|
-
|
|
17888
|
+
const storage = getWidgetStorage(widgetId);
|
|
17889
|
+
storage.activeConversationId = null;
|
|
17890
|
+
setWidgetStorage(widgetId, storage);
|
|
17651
17891
|
}
|
|
17652
17892
|
catch (error) {
|
|
17653
17893
|
console.error('Failed to clear conversation:', error);
|
|
@@ -17744,6 +17984,8 @@
|
|
|
17744
17984
|
conversationId: '', // Will be set after loading conversation
|
|
17745
17985
|
config: null,
|
|
17746
17986
|
});
|
|
17987
|
+
// Chat history state
|
|
17988
|
+
const [conversations, setConversations] = reactExports.useState([]);
|
|
17747
17989
|
const apiClient = reactExports.useRef(new WidgetApiClient({ widgetId, apiUrl }));
|
|
17748
17990
|
// Load configuration on mount and hydrate with existing conversation if available
|
|
17749
17991
|
reactExports.useEffect(() => {
|
|
@@ -17756,7 +17998,7 @@
|
|
|
17756
17998
|
console.log('[useChat] Config fetched successfully:', {
|
|
17757
17999
|
hasAppearance: !!config.appearance,
|
|
17758
18000
|
});
|
|
17759
|
-
const persistConversation = config.
|
|
18001
|
+
const persistConversation = config.settings.persistConversation ?? true;
|
|
17760
18002
|
let conversationId = '';
|
|
17761
18003
|
let messages = [];
|
|
17762
18004
|
if (persistConversation && isStorageAvailable()) {
|
|
@@ -17804,14 +18046,14 @@
|
|
|
17804
18046
|
}, [widgetId, apiUrl, onError]);
|
|
17805
18047
|
// Save conversation when messages change
|
|
17806
18048
|
reactExports.useEffect(() => {
|
|
17807
|
-
const persistConversation = state.config?.
|
|
18049
|
+
const persistConversation = state.config?.settings.persistConversation ?? true;
|
|
17808
18050
|
if (persistConversation &&
|
|
17809
18051
|
isStorageAvailable() &&
|
|
17810
18052
|
state.messages.length > 0 &&
|
|
17811
18053
|
state.conversationId) {
|
|
17812
18054
|
saveConversation(widgetId, state.conversationId, state.messages);
|
|
17813
18055
|
}
|
|
17814
|
-
}, [widgetId, state.messages, state.conversationId, state.config?.
|
|
18056
|
+
}, [widgetId, state.messages, state.conversationId, state.config?.settings.persistConversation]);
|
|
17815
18057
|
/**
|
|
17816
18058
|
* Send a message
|
|
17817
18059
|
*/
|
|
@@ -17833,8 +18075,8 @@
|
|
|
17833
18075
|
setState(prev => ({
|
|
17834
18076
|
...prev,
|
|
17835
18077
|
messages: [...prev.messages, userMessage],
|
|
17836
|
-
isLoading:
|
|
17837
|
-
isTyping: true,
|
|
18078
|
+
isLoading: false, // Don't show loading, will show typing when stream starts
|
|
18079
|
+
isTyping: true, // Show typing indicator immediately
|
|
17838
18080
|
error: null,
|
|
17839
18081
|
}));
|
|
17840
18082
|
onMessage?.(userMessage);
|
|
@@ -17880,71 +18122,56 @@
|
|
|
17880
18122
|
}
|
|
17881
18123
|
// Determine if widget has actions (use agent endpoint)
|
|
17882
18124
|
const useAgent = state.config?.behavior.agentic || (state.config?.actions && state.config.actions.length > 0);
|
|
17883
|
-
|
|
17884
|
-
|
|
17885
|
-
|
|
17886
|
-
|
|
17887
|
-
|
|
17888
|
-
|
|
17889
|
-
|
|
17890
|
-
|
|
17891
|
-
|
|
17892
|
-
|
|
17893
|
-
|
|
17894
|
-
|
|
17895
|
-
|
|
17896
|
-
|
|
17897
|
-
|
|
17898
|
-
|
|
17899
|
-
|
|
17900
|
-
|
|
17901
|
-
|
|
17902
|
-
|
|
17903
|
-
|
|
17904
|
-
|
|
17905
|
-
|
|
17906
|
-
|
|
17907
|
-
|
|
17908
|
-
|
|
17909
|
-
|
|
17910
|
-
|
|
17911
|
-
|
|
17912
|
-
|
|
17913
|
-
|
|
17914
|
-
|
|
17915
|
-
|
|
17916
|
-
|
|
17917
|
-
|
|
17918
|
-
|
|
17919
|
-
|
|
17920
|
-
|
|
17921
|
-
|
|
17922
|
-
|
|
17923
|
-
isLoading: false,
|
|
17924
|
-
isTyping: false,
|
|
17925
|
-
error: errorContent,
|
|
17926
|
-
}));
|
|
17927
|
-
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
|
+
});
|
|
17928
18165
|
}
|
|
17929
|
-
|
|
17930
|
-
|
|
17931
|
-
|
|
17932
|
-
|
|
17933
|
-
|
|
17934
|
-
|
|
17935
|
-
|
|
17936
|
-
|
|
17937
|
-
|
|
17938
|
-
timestamp: response.timestamp || new Date().toISOString(),
|
|
17939
|
-
sources: response.sources || [],
|
|
17940
|
-
};
|
|
17941
|
-
setState(prev => ({
|
|
17942
|
-
...prev,
|
|
17943
|
-
messages: [...prev.messages, assistantMessage],
|
|
17944
|
-
isLoading: false,
|
|
17945
|
-
isTyping: false,
|
|
17946
|
-
}));
|
|
17947
|
-
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);
|
|
17948
18175
|
}
|
|
17949
18176
|
}
|
|
17950
18177
|
catch (error) {
|
|
@@ -18002,11 +18229,11 @@
|
|
|
18002
18229
|
conversationId: '',
|
|
18003
18230
|
error: null,
|
|
18004
18231
|
}));
|
|
18005
|
-
const persistConversation = state.config?.
|
|
18232
|
+
const persistConversation = state.config?.settings.persistConversation ?? true;
|
|
18006
18233
|
if (persistConversation && isStorageAvailable()) {
|
|
18007
18234
|
clearConversation(widgetId);
|
|
18008
18235
|
}
|
|
18009
|
-
}, [widgetId, state.config?.
|
|
18236
|
+
}, [widgetId, state.config?.settings.persistConversation]);
|
|
18010
18237
|
/**
|
|
18011
18238
|
* Submit feedback for a message
|
|
18012
18239
|
*/
|
|
@@ -18029,6 +18256,78 @@
|
|
|
18029
18256
|
onError?.(err);
|
|
18030
18257
|
}
|
|
18031
18258
|
}, [state.conversationId, onError]);
|
|
18259
|
+
/**
|
|
18260
|
+
* Load conversation history list from localStorage
|
|
18261
|
+
*/
|
|
18262
|
+
const loadConversations = reactExports.useCallback(() => {
|
|
18263
|
+
const persistConversation = state.config?.settings.persistConversation ?? true;
|
|
18264
|
+
if (!persistConversation || !isStorageAvailable()) {
|
|
18265
|
+
setConversations([]);
|
|
18266
|
+
return;
|
|
18267
|
+
}
|
|
18268
|
+
const history = getConversationHistory(widgetId);
|
|
18269
|
+
setConversations(history.map(entry => ({
|
|
18270
|
+
id: entry.id,
|
|
18271
|
+
preview: entry.preview,
|
|
18272
|
+
lastMessageAt: entry.lastUpdated,
|
|
18273
|
+
messageCount: entry.messageCount,
|
|
18274
|
+
startedAt: entry.lastUpdated,
|
|
18275
|
+
})));
|
|
18276
|
+
}, [widgetId, state.config?.settings.persistConversation]);
|
|
18277
|
+
/**
|
|
18278
|
+
* Switch to a different conversation (from localStorage first, then fetch from server if needed)
|
|
18279
|
+
*/
|
|
18280
|
+
const switchConversation = reactExports.useCallback(async (conversationId) => {
|
|
18281
|
+
const persistConversation = state.config?.settings.persistConversation ?? true;
|
|
18282
|
+
// First try to load from localStorage
|
|
18283
|
+
if (persistConversation && isStorageAvailable()) {
|
|
18284
|
+
const stored = loadConversationById(widgetId, conversationId);
|
|
18285
|
+
if (stored) {
|
|
18286
|
+
setState(prev => ({
|
|
18287
|
+
...prev,
|
|
18288
|
+
conversationId: stored.conversationId,
|
|
18289
|
+
messages: stored.messages,
|
|
18290
|
+
}));
|
|
18291
|
+
setActiveConversation(widgetId, conversationId);
|
|
18292
|
+
return;
|
|
18293
|
+
}
|
|
18294
|
+
}
|
|
18295
|
+
// If not in localStorage, fetch from server
|
|
18296
|
+
setState(prev => ({ ...prev, isLoading: true, error: null }));
|
|
18297
|
+
try {
|
|
18298
|
+
const conversation = await apiClient.current.getOrCreateConversation(conversationId);
|
|
18299
|
+
setState(prev => ({
|
|
18300
|
+
...prev,
|
|
18301
|
+
conversationId: conversation.id,
|
|
18302
|
+
messages: conversation.messages,
|
|
18303
|
+
isLoading: false,
|
|
18304
|
+
}));
|
|
18305
|
+
// Save to local storage
|
|
18306
|
+
if (persistConversation && isStorageAvailable()) {
|
|
18307
|
+
saveConversation(widgetId, conversation.id, conversation.messages);
|
|
18308
|
+
}
|
|
18309
|
+
}
|
|
18310
|
+
catch (error) {
|
|
18311
|
+
const errorInfo = deriveErrorInfo(error);
|
|
18312
|
+
setState(prev => ({ ...prev, isLoading: false, error: errorInfo.message }));
|
|
18313
|
+
}
|
|
18314
|
+
}, [widgetId, state.config?.settings.persistConversation]);
|
|
18315
|
+
/**
|
|
18316
|
+
* Start a new conversation (keeps history)
|
|
18317
|
+
*/
|
|
18318
|
+
const startNewConversation = reactExports.useCallback(() => {
|
|
18319
|
+
setState(prev => ({
|
|
18320
|
+
...prev,
|
|
18321
|
+
messages: [],
|
|
18322
|
+
conversationId: '',
|
|
18323
|
+
error: null,
|
|
18324
|
+
}));
|
|
18325
|
+
// Clear active conversation but keep history
|
|
18326
|
+
const persistConversation = state.config?.settings.persistConversation ?? true;
|
|
18327
|
+
if (persistConversation && isStorageAvailable()) {
|
|
18328
|
+
clearConversation(widgetId);
|
|
18329
|
+
}
|
|
18330
|
+
}, [widgetId, state.config?.settings.persistConversation]);
|
|
18032
18331
|
return {
|
|
18033
18332
|
messages: state.messages,
|
|
18034
18333
|
isLoading: state.isLoading,
|
|
@@ -18039,6 +18338,11 @@
|
|
|
18039
18338
|
sendMessage,
|
|
18040
18339
|
clearMessages,
|
|
18041
18340
|
submitFeedback,
|
|
18341
|
+
// Chat history features
|
|
18342
|
+
conversations,
|
|
18343
|
+
loadConversations,
|
|
18344
|
+
switchConversation,
|
|
18345
|
+
startNewConversation,
|
|
18042
18346
|
};
|
|
18043
18347
|
}
|
|
18044
18348
|
|
|
@@ -38727,7 +39031,7 @@
|
|
|
38727
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}`))) }))] }));
|
|
38728
39032
|
};
|
|
38729
39033
|
|
|
38730
|
-
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, }) => {
|
|
38731
39035
|
const formatTime = (timestamp) => {
|
|
38732
39036
|
const date = typeof timestamp === 'string' ? new Date(timestamp) : timestamp;
|
|
38733
39037
|
return date.toLocaleTimeString('en-US', {
|
|
@@ -38736,72 +39040,84 @@
|
|
|
38736
39040
|
hour12: true,
|
|
38737
39041
|
});
|
|
38738
39042
|
};
|
|
38739
|
-
// Map message type to CSS class
|
|
38740
|
-
const messageClass = message.message.type === 'human' ? 'user' :
|
|
38741
|
-
message.message.type === 'ai' ? 'assistant' :
|
|
38742
|
-
message.message.type === 'system' ? 'system' : 'tool';
|
|
38743
|
-
const isAssistant = message.message.type === 'ai';
|
|
38744
|
-
const isSystem = message.message.type === 'system';
|
|
38745
|
-
const isTool = message.message.type === 'tool';
|
|
38746
|
-
const isHuman = message.message.type === 'human';
|
|
38747
|
-
const userMessage = isHuman ? message.message.content.split('--- File Content ---')[0] : '';
|
|
38748
|
-
const aiContent = isAssistant ? (message.message.content || '') : '';
|
|
38749
|
-
const aiHasContent = isAssistant ? aiContent.trim().length > 0 : false;
|
|
38750
|
-
const renderAssistant = () => {
|
|
38751
|
-
// Only render assistant bubble if there's textual content
|
|
38752
|
-
return jsxRuntimeExports.jsx(Markdown, { children: aiContent });
|
|
38753
|
-
};
|
|
38754
39043
|
const formatToolName = (name) => {
|
|
38755
|
-
|
|
38756
|
-
|
|
38757
|
-
// Convert snake_case to Title Case
|
|
38758
|
-
formatted = formatted
|
|
39044
|
+
return name
|
|
39045
|
+
.replace(/^(action_|tool_)/, '')
|
|
38759
39046
|
.split('_')
|
|
38760
39047
|
.map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
|
|
38761
39048
|
.join(' ');
|
|
38762
|
-
return formatted;
|
|
38763
39049
|
};
|
|
38764
|
-
const
|
|
38765
|
-
|
|
38766
|
-
|
|
38767
|
-
|
|
38768
|
-
|
|
38769
|
-
|
|
38770
|
-
|
|
38771
|
-
|
|
38772
|
-
|
|
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) }) }))] }));
|
|
38773
39077
|
}
|
|
38774
|
-
|
|
38775
|
-
|
|
38776
|
-
|
|
38777
|
-
|
|
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;
|
|
38778
39084
|
};
|
|
38779
39085
|
|
|
38780
39086
|
const TypingIndicator = () => {
|
|
38781
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" })] }) }));
|
|
38782
39088
|
};
|
|
38783
39089
|
|
|
38784
|
-
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);
|
|
38785
39104
|
const messagesEndRef = reactExports.useRef(null);
|
|
38786
|
-
// Auto-scroll to bottom
|
|
39105
|
+
// Auto-scroll to bottom only on initial mount/load
|
|
38787
39106
|
reactExports.useEffect(() => {
|
|
38788
|
-
|
|
38789
|
-
|
|
38790
|
-
|
|
38791
|
-
|
|
38792
|
-
|
|
38793
|
-
|
|
38794
|
-
|
|
38795
|
-
|
|
38796
|
-
|
|
38797
|
-
|
|
38798
|
-
|
|
38799
|
-
}
|
|
38800
|
-
}
|
|
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' });
|
|
38801
39118
|
}
|
|
38802
|
-
|
|
38803
|
-
},
|
|
38804
|
-
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 })] }));
|
|
38805
39121
|
};
|
|
38806
39122
|
|
|
38807
39123
|
// Allowed file types
|
|
@@ -38889,58 +39205,98 @@
|
|
|
38889
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) => {
|
|
38890
39206
|
const ext = getFileExtension(file.name);
|
|
38891
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));
|
|
38892
|
-
}) })), 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: "
|
|
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" })] }) })] })] }));
|
|
38893
39209
|
};
|
|
38894
39210
|
|
|
38895
|
-
const
|
|
38896
|
-
const
|
|
38897
|
-
|
|
38898
|
-
|
|
38899
|
-
|
|
38900
|
-
|
|
38901
|
-
|
|
38902
|
-
if (validQuestions.length === 0) {
|
|
38903
|
-
return null;
|
|
38904
|
-
}
|
|
38905
|
-
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))) }) }));
|
|
38906
|
-
};
|
|
38907
|
-
|
|
38908
|
-
const MinimizeIcon = () => (jsxRuntimeExports.jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntimeExports.jsx("path", { d: "M5 12h14" }) }));
|
|
38909
|
-
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,
|
|
39214
|
+
// Chat history props (only active when persistConversation is true)
|
|
39215
|
+
conversations = [], onLoadConversations, onSwitchConversation, onStartNewConversation, currentConversationId,
|
|
39216
|
+
// Override props for live preview
|
|
39217
|
+
headerTitleOverride, welcomeTitleOverride, welcomeMessageOverride, placeholderOverride, suggestedQuestionsOverride, }) => {
|
|
38910
39218
|
console.log('[ChatWindow] Rendering ChatWindow component');
|
|
38911
39219
|
const appearance = config?.appearance;
|
|
38912
|
-
const
|
|
38913
|
-
//
|
|
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)
|
|
38914
39224
|
const size = appearance?.size || 'medium';
|
|
38915
|
-
const headerTitle = appearance?.headerTitle
|
|
38916
|
-
const
|
|
38917
|
-
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...';
|
|
38918
39229
|
console.log('[ChatWindow] Appearance values:', {
|
|
38919
39230
|
size,
|
|
38920
39231
|
headerTitle,
|
|
39232
|
+
welcomeTitle,
|
|
38921
39233
|
welcomeMessage,
|
|
38922
39234
|
inputPlaceholder,
|
|
38923
39235
|
});
|
|
38924
|
-
// Track if
|
|
38925
|
-
const [
|
|
38926
|
-
//
|
|
38927
|
-
reactExports.
|
|
38928
|
-
|
|
38929
|
-
|
|
38930
|
-
|
|
39236
|
+
// Track if history panel is open
|
|
39237
|
+
const [showHistory, setShowHistory] = reactExports.useState(false);
|
|
39238
|
+
// History exit animation when starting a new chat from overview
|
|
39239
|
+
const [isHistoryExiting, setIsHistoryExiting] = reactExports.useState(false);
|
|
39240
|
+
// Load conversations when history panel opens
|
|
39241
|
+
const handleOpenHistory = () => {
|
|
39242
|
+
setShowHistory(true);
|
|
39243
|
+
if (onLoadConversations) {
|
|
39244
|
+
onLoadConversations();
|
|
39245
|
+
}
|
|
39246
|
+
};
|
|
39247
|
+
// Handle conversation selection
|
|
39248
|
+
const handleSelectConversation = async (conversationId) => {
|
|
39249
|
+
if (onSwitchConversation) {
|
|
39250
|
+
await onSwitchConversation(conversationId);
|
|
39251
|
+
setShowHistory(false);
|
|
38931
39252
|
}
|
|
38932
|
-
}
|
|
39253
|
+
};
|
|
39254
|
+
const handleNewConversation = () => {
|
|
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
|
|
39266
|
+
setShowHistory(false);
|
|
39267
|
+
onSendMessage(trimmed);
|
|
39268
|
+
return;
|
|
39269
|
+
}
|
|
39270
|
+
setIsHistoryExiting(true);
|
|
39271
|
+
window.setTimeout(() => {
|
|
39272
|
+
onStartNewConversation();
|
|
39273
|
+
setShowHistory(false);
|
|
39274
|
+
setIsHistoryExiting(false);
|
|
39275
|
+
onSendMessage(trimmed);
|
|
39276
|
+
}, 240);
|
|
39277
|
+
};
|
|
38933
39278
|
// Check if message limit is reached
|
|
38934
|
-
const maxMessages =
|
|
39279
|
+
const maxMessages = settings?.maxMessagesPerSession;
|
|
38935
39280
|
const userMessageCount = messages.filter(m => m.message.type === 'human').length;
|
|
38936
39281
|
const isLimitReached = maxMessages ? userMessageCount >= maxMessages : false;
|
|
38937
|
-
// Handle suggested question click
|
|
38938
39282
|
const handleQuestionClick = (question) => {
|
|
38939
|
-
setShowSuggestedQuestions(false);
|
|
38940
39283
|
onSendMessage(question);
|
|
38941
39284
|
};
|
|
38942
|
-
|
|
38943
|
-
|
|
39285
|
+
// Format date for conversation list
|
|
39286
|
+
const formatDate = (dateString) => {
|
|
39287
|
+
const date = new Date(dateString);
|
|
39288
|
+
const now = new Date();
|
|
39289
|
+
const diffMs = now.getTime() - date.getTime();
|
|
39290
|
+
const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));
|
|
39291
|
+
if (diffDays === 0)
|
|
39292
|
+
return 'Today';
|
|
39293
|
+
if (diffDays === 1)
|
|
39294
|
+
return 'Yesterday';
|
|
39295
|
+
if (diffDays < 7)
|
|
39296
|
+
return `${diffDays} days ago`;
|
|
39297
|
+
return date.toLocaleDateString();
|
|
39298
|
+
};
|
|
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 })] }))] }));
|
|
38944
39300
|
};
|
|
38945
39301
|
|
|
38946
39302
|
/**
|
|
@@ -39123,22 +39479,18 @@
|
|
|
39123
39479
|
* Generate all CSS custom properties for the widget
|
|
39124
39480
|
*/
|
|
39125
39481
|
function generateThemeStyles(appearance, theme) {
|
|
39126
|
-
const
|
|
39127
|
-
? generateDarkPalette(appearance.accentColor)
|
|
39128
|
-
: generateLightPalette(appearance.accentColor);
|
|
39482
|
+
const hasAccentColor = appearance.accentColor && appearance.accentColor.trim() !== '';
|
|
39129
39483
|
// Liquid glass design - frosted glass with transparency
|
|
39130
39484
|
const isLight = theme === 'light';
|
|
39131
|
-
|
|
39485
|
+
// Base styles that don't depend on accent color
|
|
39486
|
+
const styles = {
|
|
39132
39487
|
// ========================================================================
|
|
39133
|
-
// BUTTON (FAB) -
|
|
39488
|
+
// BUTTON (FAB) - Base styles
|
|
39134
39489
|
// ========================================================================
|
|
39135
|
-
'--button-color': palette.accent,
|
|
39136
39490
|
'--button-opacity': '1',
|
|
39137
39491
|
'--button-size': '56px',
|
|
39138
|
-
'--button-icon-color': palette.userBubbleText,
|
|
39139
39492
|
'--button-border-radius': '50%',
|
|
39140
39493
|
'--button-border-width': '0px',
|
|
39141
|
-
'--button-border-color': palette.accent,
|
|
39142
39494
|
'--button-border-opacity': '1',
|
|
39143
39495
|
'--button-backdrop-blur': '20px',
|
|
39144
39496
|
'--button-shadow': `0 4px 24px rgba(0, 0, 0, 0.15), 0 2px 8px rgba(0, 0, 0, 0.1)`,
|
|
@@ -39161,7 +39513,6 @@
|
|
|
39161
39513
|
// ========================================================================
|
|
39162
39514
|
'--header-background': 'transparent',
|
|
39163
39515
|
'--header-opacity': '1',
|
|
39164
|
-
'--header-text-color': palette.accent,
|
|
39165
39516
|
'--header-border-bottom-width': '0px',
|
|
39166
39517
|
'--header-border-bottom-color': 'transparent',
|
|
39167
39518
|
'--header-border-bottom-opacity': '0',
|
|
@@ -39171,17 +39522,13 @@
|
|
|
39171
39522
|
// ========================================================================
|
|
39172
39523
|
'--chat-background': 'transparent',
|
|
39173
39524
|
'--chat-opacity': '1',
|
|
39174
|
-
'--welcome-color': palette.text,
|
|
39175
|
-
'--message-text-color': palette.text,
|
|
39176
39525
|
// ========================================================================
|
|
39177
39526
|
// MESSAGE BUBBLES - Glass style
|
|
39178
39527
|
// ========================================================================
|
|
39179
|
-
'--bubble-user-color': palette.userBubble,
|
|
39180
39528
|
'--bubble-user-opacity': '1',
|
|
39181
|
-
'--user-message-text': palette.userBubbleText,
|
|
39182
39529
|
'--bubble-assistant-color': isLight ? 'rgba(255, 255, 255, 0.8)' : 'rgba(255, 255, 255, 0.1)',
|
|
39183
39530
|
'--bubble-assistant-opacity': '1',
|
|
39184
|
-
'--assistant-message-text': isLight ?
|
|
39531
|
+
'--assistant-message-text': isLight ? '#000000' : '#f0f0f0',
|
|
39185
39532
|
'--bubble-border-radius': '20px',
|
|
39186
39533
|
'--bubble-border-width': isLight ? '1px' : '1px',
|
|
39187
39534
|
'--bubble-border-color': isLight ? 'rgba(0, 0, 0, 0.05)' : 'rgba(255, 255, 255, 0.08)',
|
|
@@ -39203,38 +39550,48 @@
|
|
|
39203
39550
|
'--input-border-color': isLight ? 'rgba(0, 0, 0, 0.08)' : 'rgba(255, 255, 255, 0.1)',
|
|
39204
39551
|
'--input-border-opacity': '1',
|
|
39205
39552
|
'--input-shadow': `inset 0 1px 3px rgba(0, 0, 0, 0.04), 0 2px 8px rgba(0, 0, 0, 0.04)`,
|
|
39206
|
-
'--send-button-background': palette.accent,
|
|
39207
39553
|
'--send-button-opacity': '1',
|
|
39208
39554
|
'--send-button-border-radius': '50%',
|
|
39209
39555
|
'--send-button-border-width': '0px',
|
|
39210
|
-
'--send-button-border-color': palette.accent,
|
|
39211
39556
|
'--send-button-border-opacity': '1',
|
|
39212
39557
|
// ========================================================================
|
|
39213
39558
|
// HOVER STATES
|
|
39214
39559
|
// ========================================================================
|
|
39215
39560
|
'--hover-button-scale': '1.08',
|
|
39216
39561
|
'--hover-button-opacity': '1',
|
|
39217
|
-
'--hover-input-border-color': palette.accent,
|
|
39218
39562
|
'--hover-send-button-opacity': '1',
|
|
39219
39563
|
'--hover-close-button-opacity': '1',
|
|
39220
39564
|
// ========================================================================
|
|
39221
|
-
// ACTIVE STATES
|
|
39222
|
-
// ========================================================================
|
|
39223
|
-
'--active-input-border-color': palette.accent,
|
|
39224
|
-
'--active-input-shadow': `0 0 0 4px ${withAlpha(palette.accent, 0.15)}`,
|
|
39225
|
-
// ========================================================================
|
|
39226
|
-
// GENERAL
|
|
39227
|
-
// ========================================================================
|
|
39228
|
-
'--primary-color': palette.accent,
|
|
39229
|
-
'--background-color': palette.background,
|
|
39230
|
-
'--text-color': palette.text,
|
|
39231
|
-
'--border-color': palette.border,
|
|
39232
|
-
// ========================================================================
|
|
39233
39565
|
// GLASS EFFECTS
|
|
39234
39566
|
// ========================================================================
|
|
39235
39567
|
'--glass-blur': '20px',
|
|
39236
39568
|
'--glass-saturation': '180%',
|
|
39237
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;
|
|
39238
39595
|
}
|
|
39239
39596
|
|
|
39240
39597
|
/**
|
|
@@ -39345,7 +39702,7 @@
|
|
|
39345
39702
|
if ( ref === void 0 ) ref = {};
|
|
39346
39703
|
var insertAt = ref.insertAt;
|
|
39347
39704
|
|
|
39348
|
-
if (
|
|
39705
|
+
if (typeof document === 'undefined') { return; }
|
|
39349
39706
|
|
|
39350
39707
|
var head = document.head || document.getElementsByTagName('head')[0];
|
|
39351
39708
|
var style = document.createElement('style');
|
|
@@ -39368,10 +39725,7 @@
|
|
|
39368
39725
|
}
|
|
39369
39726
|
}
|
|
39370
39727
|
|
|
39371
|
-
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)}}";
|
|
39372
|
-
styleInject(css_248z$1);
|
|
39373
|
-
|
|
39374
|
-
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}";
|
|
39375
39729
|
styleInject(css_248z);
|
|
39376
39730
|
|
|
39377
39731
|
// Icon components mapping
|
|
@@ -39379,17 +39733,76 @@
|
|
|
39379
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" }) })),
|
|
39380
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" }) })),
|
|
39381
39735
|
};
|
|
39382
|
-
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, }) => {
|
|
39383
39737
|
const [isOpen, setIsOpen] = reactExports.useState(false);
|
|
39384
39738
|
const [autoDetectedTheme, setAutoDetectedTheme] = reactExports.useState('light');
|
|
39385
39739
|
const widgetRef = reactExports.useRef(null);
|
|
39386
39740
|
const containerRef = reactExports.useRef(null);
|
|
39387
|
-
|
|
39388
|
-
|
|
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__'),
|
|
39389
39789
|
apiUrl,
|
|
39390
|
-
onMessage,
|
|
39391
|
-
onError,
|
|
39790
|
+
onMessage: previewMode ? undefined : onMessage,
|
|
39791
|
+
onError: previewMode ? undefined : onError,
|
|
39392
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;
|
|
39393
39806
|
// Auto-detect theme from background
|
|
39394
39807
|
reactExports.useEffect(() => {
|
|
39395
39808
|
if (!containerRef.current)
|
|
@@ -39427,8 +39840,8 @@
|
|
|
39427
39840
|
}, [config, autoDetectedTheme]);
|
|
39428
39841
|
// Handle auto-open
|
|
39429
39842
|
reactExports.useEffect(() => {
|
|
39430
|
-
if (config?.
|
|
39431
|
-
const delay = config.
|
|
39843
|
+
if (config?.settings.autoOpen) {
|
|
39844
|
+
const delay = config.settings.autoOpenDelay || 0;
|
|
39432
39845
|
const timer = setTimeout(() => {
|
|
39433
39846
|
setIsOpen(true);
|
|
39434
39847
|
onOpen?.();
|
|
@@ -39437,26 +39850,6 @@
|
|
|
39437
39850
|
}
|
|
39438
39851
|
return undefined;
|
|
39439
39852
|
}, [config, onOpen]);
|
|
39440
|
-
// Handle close on outside click - always enabled for better UX
|
|
39441
|
-
reactExports.useEffect(() => {
|
|
39442
|
-
if (!isOpen)
|
|
39443
|
-
return;
|
|
39444
|
-
const handleClickOutside = (event) => {
|
|
39445
|
-
// Check if click is outside the widget container
|
|
39446
|
-
if (widgetRef.current && !widgetRef.current.contains(event.target)) {
|
|
39447
|
-
setIsOpen(false);
|
|
39448
|
-
onClose?.();
|
|
39449
|
-
}
|
|
39450
|
-
};
|
|
39451
|
-
// Small delay to prevent immediate close on open
|
|
39452
|
-
const timer = setTimeout(() => {
|
|
39453
|
-
document.addEventListener('mousedown', handleClickOutside);
|
|
39454
|
-
}, 150);
|
|
39455
|
-
return () => {
|
|
39456
|
-
clearTimeout(timer);
|
|
39457
|
-
document.removeEventListener('mousedown', handleClickOutside);
|
|
39458
|
-
};
|
|
39459
|
-
}, [isOpen, onClose]);
|
|
39460
39853
|
// Handle close on Escape key
|
|
39461
39854
|
reactExports.useEffect(() => {
|
|
39462
39855
|
if (!isOpen)
|
|
@@ -39470,31 +39863,33 @@
|
|
|
39470
39863
|
document.addEventListener('keydown', handleEscapeKey);
|
|
39471
39864
|
return () => document.removeEventListener('keydown', handleEscapeKey);
|
|
39472
39865
|
}, [isOpen, onClose]);
|
|
39473
|
-
// Determine theme -
|
|
39866
|
+
// Determine theme - use prop override if provided, otherwise auto-detect
|
|
39474
39867
|
const appearanceConfig = config?.appearance;
|
|
39475
|
-
const effectiveTheme = autoDetectedTheme;
|
|
39476
|
-
// Determine position (
|
|
39477
|
-
const effectivePosition = config?.appearance.position ||
|
|
39478
|
-
// Get accent color from
|
|
39479
|
-
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 ?? '';
|
|
39480
39879
|
// Generate styles using simplified theme system
|
|
39481
39880
|
const simpleAppearance = {
|
|
39482
|
-
accentColor
|
|
39483
|
-
size: appearanceConfig?.size || 'small',
|
|
39484
|
-
welcomeMessage: appearanceConfig?.welcomeMessage || '',
|
|
39485
|
-
placeholder: appearanceConfig?.placeholder || '',
|
|
39486
|
-
headerTitle: appearanceConfig?.headerTitle || '',
|
|
39487
|
-
};
|
|
39881
|
+
accentColor};
|
|
39488
39882
|
// Generate theme styles from accent color
|
|
39489
39883
|
const generatedStyles = generateThemeStyles(simpleAppearance, effectiveTheme);
|
|
39490
39884
|
// Also apply legacy styles for backward compatibility
|
|
39491
39885
|
const legacyStyles = appearanceConfig
|
|
39492
39886
|
? applyAppearanceStyles(appearanceConfig)
|
|
39493
39887
|
: {};
|
|
39494
|
-
// Merge styles (generated takes priority for new simplified system)
|
|
39495
|
-
const
|
|
39888
|
+
// Merge styles (generated takes priority for new simplified system, then custom overrides)
|
|
39889
|
+
const mergedStyles = {
|
|
39496
39890
|
...legacyStyles,
|
|
39497
39891
|
...generatedStyles,
|
|
39892
|
+
...customStyles,
|
|
39498
39893
|
};
|
|
39499
39894
|
// Debug logging for theme and styles
|
|
39500
39895
|
reactExports.useEffect(() => {
|
|
@@ -39519,14 +39914,19 @@
|
|
|
39519
39914
|
await submitFeedback(messageId, feedback);
|
|
39520
39915
|
};
|
|
39521
39916
|
// Don't render until config is loaded to avoid flash of unstyled content
|
|
39522
|
-
|
|
39917
|
+
// In preview mode, config is always available
|
|
39918
|
+
if (!config && !previewMode) {
|
|
39523
39919
|
console.log('[ChatWidget] Not rendering - config not loaded yet');
|
|
39524
39920
|
return null;
|
|
39525
39921
|
}
|
|
39526
39922
|
console.log('[ChatWidget] Rendering widget', { isOpen, hasConfig: !!config });
|
|
39527
39923
|
// Get button icon based on state
|
|
39528
39924
|
const IconComponent = isOpen ? iconComponents.FiChevronDown : iconComponents.FiMessageCircle;
|
|
39529
|
-
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,
|
|
39926
|
+
// Chat history props (only active when persistConversation is true)
|
|
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, {}) }) })] }) }));
|
|
39530
39930
|
};
|
|
39531
39931
|
|
|
39532
39932
|
/**
|