@chatwidgetai/chat-widget 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai-chat-widget.umd.js +1176 -400
- package/dist/ai-chat-widget.umd.js.map +1 -1
- package/dist/api/client.d.ts +2 -2
- package/dist/api/client.d.ts.map +1 -1
- package/dist/components/ChatWidget.d.ts +2 -1
- package/dist/components/ChatWidget.d.ts.map +1 -1
- package/dist/components/ChatWindow.d.ts +0 -1
- package/dist/components/ChatWindow.d.ts.map +1 -1
- package/dist/components/DataPolicyView.d.ts +14 -0
- package/dist/components/DataPolicyView.d.ts.map +1 -0
- package/dist/hooks/useChat/action-handler.d.ts +6 -0
- package/dist/hooks/useChat/action-handler.d.ts.map +1 -0
- package/dist/hooks/useChat/action-lifecycle.d.ts +19 -0
- package/dist/hooks/useChat/action-lifecycle.d.ts.map +1 -0
- package/dist/hooks/useChat/error-utils.d.ts +7 -0
- package/dist/hooks/useChat/error-utils.d.ts.map +1 -0
- package/dist/hooks/{useChat.d.ts → useChat/index.d.ts} +2 -2
- package/dist/hooks/useChat/index.d.ts.map +1 -0
- package/dist/hooks/useChat/message-hydration.d.ts +4 -0
- package/dist/hooks/useChat/message-hydration.d.ts.map +1 -0
- package/dist/hooks/useChat/stream-handlers.d.ts +27 -0
- package/dist/hooks/useChat/stream-handlers.d.ts.map +1 -0
- package/dist/hooks/useChat/stream-state.d.ts +8 -0
- package/dist/hooks/useChat/stream-state.d.ts.map +1 -0
- package/dist/hooks/useChat/types.d.ts +26 -0
- package/dist/hooks/useChat/types.d.ts.map +1 -0
- package/dist/index.esm.js +1176 -400
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +1176 -400
- package/dist/index.js.map +1 -1
- package/dist/types/index.d.ts +8 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/sse-parser.d.ts.map +1 -1
- package/package.json +7 -3
- package/dist/hooks/useChat.d.ts.map +0 -1
|
@@ -16696,11 +16696,14 @@
|
|
|
16696
16696
|
const reader = response.body.getReader();
|
|
16697
16697
|
const decoder = new TextDecoder();
|
|
16698
16698
|
let buffer = "";
|
|
16699
|
+
let eventCount = 0;
|
|
16699
16700
|
try {
|
|
16700
16701
|
while (true) {
|
|
16701
16702
|
const { done, value } = await reader.read();
|
|
16702
|
-
if (done)
|
|
16703
|
+
if (done) {
|
|
16704
|
+
console.log(`[SSE Parser] Stream ended normally after ${eventCount} events`);
|
|
16703
16705
|
break;
|
|
16706
|
+
}
|
|
16704
16707
|
buffer += decoder.decode(value, { stream: true });
|
|
16705
16708
|
const chunks = buffer.split("\n\n");
|
|
16706
16709
|
buffer = chunks.pop() || "";
|
|
@@ -16712,6 +16715,7 @@
|
|
|
16712
16715
|
const data = JSON.parse(line.slice(6));
|
|
16713
16716
|
if (validator) {
|
|
16714
16717
|
if (validator(data)) {
|
|
16718
|
+
eventCount++;
|
|
16715
16719
|
yield data;
|
|
16716
16720
|
}
|
|
16717
16721
|
else {
|
|
@@ -16719,6 +16723,7 @@
|
|
|
16719
16723
|
}
|
|
16720
16724
|
}
|
|
16721
16725
|
else {
|
|
16726
|
+
eventCount++;
|
|
16722
16727
|
yield data;
|
|
16723
16728
|
}
|
|
16724
16729
|
}
|
|
@@ -16731,6 +16736,10 @@
|
|
|
16731
16736
|
}
|
|
16732
16737
|
}
|
|
16733
16738
|
}
|
|
16739
|
+
catch (error) {
|
|
16740
|
+
console.error(`[SSE Parser] Stream error after ${eventCount} events:`, error);
|
|
16741
|
+
throw error;
|
|
16742
|
+
}
|
|
16734
16743
|
finally {
|
|
16735
16744
|
reader.releaseLock();
|
|
16736
16745
|
}
|
|
@@ -16864,7 +16873,7 @@
|
|
|
16864
16873
|
const result = await response.json();
|
|
16865
16874
|
return result.file;
|
|
16866
16875
|
}
|
|
16867
|
-
async *sendAgentMessageStream(conversationId, message, fileIds) {
|
|
16876
|
+
async *sendAgentMessageStream(conversationId, message, fileIds, signal) {
|
|
16868
16877
|
const headers = {
|
|
16869
16878
|
'Content-Type': 'application/json',
|
|
16870
16879
|
};
|
|
@@ -16880,6 +16889,7 @@
|
|
|
16880
16889
|
fileIds,
|
|
16881
16890
|
timeZone: this.getTimeZone(),
|
|
16882
16891
|
}),
|
|
16892
|
+
signal,
|
|
16883
16893
|
});
|
|
16884
16894
|
if (!response.ok) {
|
|
16885
16895
|
throw await buildApiError(response, 'Failed to send agent message');
|
|
@@ -16888,7 +16898,7 @@
|
|
|
16888
16898
|
return typeof data === 'object' && data !== null && 'type' in data;
|
|
16889
16899
|
});
|
|
16890
16900
|
}
|
|
16891
|
-
async *continueAgentMessageStream(conversationId, toolCallId, state) {
|
|
16901
|
+
async *continueAgentMessageStream(conversationId, toolCallId, state, signal) {
|
|
16892
16902
|
const headers = {
|
|
16893
16903
|
'Content-Type': 'application/json',
|
|
16894
16904
|
};
|
|
@@ -16904,6 +16914,7 @@
|
|
|
16904
16914
|
state,
|
|
16905
16915
|
timeZone: this.getTimeZone(),
|
|
16906
16916
|
}),
|
|
16917
|
+
signal,
|
|
16907
16918
|
});
|
|
16908
16919
|
if (!response.ok) {
|
|
16909
16920
|
throw await buildApiError(response, 'Failed to continue agent');
|
|
@@ -43804,18 +43815,14 @@
|
|
|
43804
43815
|
.map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
|
|
43805
43816
|
.join(' ');
|
|
43806
43817
|
};
|
|
43807
|
-
const GearIcon = ({ spinning = false }) => (jsxRuntimeExports.jsxs("svg", { className: `ai-chat-tool-gear ${spinning ? 'spinning' : ''}`, width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("path", { d: "M12 20a8 8 0 1 0 0-16 8 8 0 0 0 0 16Z" }), jsxRuntimeExports.jsx("path", { d: "M12 14a2 2 0 1 0 0-4 2 2 0 0 0 0 4Z" }), jsxRuntimeExports.jsx("path", { d: "M12 2v2" }), jsxRuntimeExports.jsx("path", { d: "M12 22v-2" }), jsxRuntimeExports.jsx("path", { d: "m17 20.66-1-1.73" }), jsxRuntimeExports.jsx("path", { d: "M11 10.27 7 3.34" }), jsxRuntimeExports.jsx("path", { d: "m20.66 17-1.73-1" }), jsxRuntimeExports.jsx("path", { d: "m3.34 7 1.73 1" }), jsxRuntimeExports.jsx("path", { d: "M14 12h8" }), jsxRuntimeExports.jsx("path", { d: "M2 12h2" }), jsxRuntimeExports.jsx("path", { d: "m20.66 7-1.73 1" }), jsxRuntimeExports.jsx("path", { d: "m3.34 17 1.73-1" }), jsxRuntimeExports.jsx("path", { d: "m17 3.34-1 1.73" }), jsxRuntimeExports.jsx("path", { d: "m11 13.73-4 6.93" })] }));
|
|
43808
|
-
const CheckIcon$2 = () => (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" }) }));
|
|
43809
|
-
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" }) }));
|
|
43810
43818
|
function ToolIndicator({ badges, className = '' }) {
|
|
43811
|
-
|
|
43812
|
-
return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-tool-row ${className}`, children: [jsxRuntimeExports.jsx(GearIcon, { spinning: isAnyLoading }), jsxRuntimeExports.jsx("div", { className: "ai-chat-tool-badges", children: badges.map((badge) => (jsxRuntimeExports.jsxs("div", { className: `ai-chat-tool-badge ${badge.status}`, children: [badge.status !== 'loading' && (badge.status === 'error' ? jsxRuntimeExports.jsx(ErrorIcon, {}) : jsxRuntimeExports.jsx(CheckIcon$2, {})), jsxRuntimeExports.jsx("span", { className: "tool-name", children: formatToolName(badge.name) })] }, badge.id))) })] }));
|
|
43819
|
+
return (jsxRuntimeExports.jsx("div", { className: `ai-chat-tool-row ${className}`, children: jsxRuntimeExports.jsx("div", { className: "ai-chat-tool-badges", children: badges.map((badge) => (jsxRuntimeExports.jsx("div", { className: `ai-chat-tool-badge ${badge.status}`, children: jsxRuntimeExports.jsx("span", { className: "tool-name", children: formatToolName(badge.name) }) }, badge.id))) }) }));
|
|
43813
43820
|
}
|
|
43814
43821
|
|
|
43815
43822
|
// SVG Icon components
|
|
43816
43823
|
const ThumbsUpIcon = () => (jsxRuntimeExports.jsx("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntimeExports.jsx("path", { d: "M14 9V5a3 3 0 0 0-3-3l-4 9v11h11.28a2 2 0 0 0 2-1.7l1.38-9a2 2 0 0 0-2-2.3zM7 22H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2h3" }) }));
|
|
43817
43824
|
const ThumbsDownIcon = () => (jsxRuntimeExports.jsx("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntimeExports.jsx("path", { d: "M10 15v4a3 3 0 0 0 3 3l4-9V2H5.72a2 2 0 0 0-2 1.7l-1.38 9a2 2 0 0 0 2 2.3zm7-13h2.67A2.31 2.31 0 0 1 22 4v7a2.31 2.31 0 0 1-2.33 2H17" }) }));
|
|
43818
|
-
const CheckIcon$
|
|
43825
|
+
const CheckIcon$2 = () => (jsxRuntimeExports.jsx("svg", { 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" }) }));
|
|
43819
43826
|
const FeedbackButtons = ({ messageId, currentFeedback, onFeedback, }) => {
|
|
43820
43827
|
const [isSubmitting, setIsSubmitting] = reactExports.useState(false);
|
|
43821
43828
|
const [submitted, setSubmitted] = reactExports.useState(false);
|
|
@@ -43836,10 +43843,10 @@
|
|
|
43836
43843
|
setIsSubmitting(false);
|
|
43837
43844
|
}
|
|
43838
43845
|
};
|
|
43839
|
-
return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-feedback ${submitted ? 'submitted' : ''}`, children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-feedback-buttons", children: [jsxRuntimeExports.jsx("button", { className: `ai-chat-feedback-button ${currentFeedback === 'positive' ? 'active' : ''}`, onClick: () => handleFeedback('positive'), disabled: isDisabled, "aria-label": "Helpful", title: "This was helpful", children: jsxRuntimeExports.jsx(ThumbsUpIcon, {}) }), jsxRuntimeExports.jsx("button", { className: `ai-chat-feedback-button ${currentFeedback === 'negative' ? 'active' : ''}`, onClick: () => handleFeedback('negative'), disabled: isDisabled, "aria-label": "Not helpful", title: "This was not helpful", children: jsxRuntimeExports.jsx(ThumbsDownIcon, {}) })] }), submitted && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-feedback-message", "aria-live": "polite", children: [jsxRuntimeExports.jsx("span", { className: "ai-chat-feedback-checkmark", children: jsxRuntimeExports.jsx(CheckIcon$
|
|
43846
|
+
return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-feedback ${submitted ? 'submitted' : ''}`, children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-feedback-buttons", children: [jsxRuntimeExports.jsx("button", { className: `ai-chat-feedback-button ${currentFeedback === 'positive' ? 'active' : ''}`, onClick: () => handleFeedback('positive'), disabled: isDisabled, "aria-label": "Helpful", title: "This was helpful", children: jsxRuntimeExports.jsx(ThumbsUpIcon, {}) }), jsxRuntimeExports.jsx("button", { className: `ai-chat-feedback-button ${currentFeedback === 'negative' ? 'active' : ''}`, onClick: () => handleFeedback('negative'), disabled: isDisabled, "aria-label": "Not helpful", title: "This was not helpful", children: jsxRuntimeExports.jsx(ThumbsDownIcon, {}) })] }), submitted && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-feedback-message", "aria-live": "polite", children: [jsxRuntimeExports.jsx("span", { className: "ai-chat-feedback-checkmark", children: jsxRuntimeExports.jsx(CheckIcon$2, {}) }), jsxRuntimeExports.jsx("span", { className: "ai-chat-feedback-text", children: "Thanks for feedback" })] }))] }));
|
|
43840
43847
|
};
|
|
43841
43848
|
|
|
43842
|
-
const Message = ({ message, showTimestamp = true, enableFeedback = true, onFeedback,
|
|
43849
|
+
const Message = ({ message, showTimestamp = true, enableFeedback = true, onFeedback, }) => {
|
|
43843
43850
|
const formatTime = (timestamp) => {
|
|
43844
43851
|
const date = typeof timestamp === 'string' ? new Date(timestamp) : timestamp;
|
|
43845
43852
|
return date.toLocaleTimeString('en-US', {
|
|
@@ -43859,15 +43866,15 @@
|
|
|
43859
43866
|
return null;
|
|
43860
43867
|
}
|
|
43861
43868
|
// AI message rendering
|
|
43869
|
+
// Note: Actions are rendered by ToolMessageGroup for tool messages, not here
|
|
43862
43870
|
if (isAssistant) {
|
|
43863
43871
|
const aiContent = message.message.content || '';
|
|
43864
43872
|
const hasContent = aiContent.trim().length > 0;
|
|
43865
43873
|
if (!hasContent)
|
|
43866
43874
|
return null;
|
|
43867
|
-
|
|
43868
|
-
|
|
43869
|
-
|
|
43870
|
-
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, { remarkPlugins: [remarkGfm], children: aiContent })] }), actionRenderer && message.action && actionRenderer(message, accentColor), 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 }))] }))] }));
|
|
43875
|
+
return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-message assistant ${isError ? 'error' : ''}`, children: [jsxRuntimeExports.jsx("div", { className: "ai-chat-message-content", children: jsxRuntimeExports.jsx(Markdown, { remarkPlugins: [remarkGfm], components: {
|
|
43876
|
+
table: ({ children, ...props }) => (jsxRuntimeExports.jsx("div", { className: "table-wrapper", children: jsxRuntimeExports.jsx("div", { className: "table-scroll", children: jsxRuntimeExports.jsx("table", { ...props, children: children }) }) })),
|
|
43877
|
+
}, 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 }))] }))] }));
|
|
43871
43878
|
}
|
|
43872
43879
|
// System message rendering
|
|
43873
43880
|
if (isSystem) {
|
|
@@ -43881,35 +43888,85 @@
|
|
|
43881
43888
|
return null;
|
|
43882
43889
|
};
|
|
43883
43890
|
|
|
43884
|
-
|
|
43891
|
+
// Centralized action state logic
|
|
43892
|
+
function isActionComplete(state) {
|
|
43893
|
+
if (!state)
|
|
43894
|
+
return false;
|
|
43895
|
+
const TERMINAL_STATUSES = [
|
|
43896
|
+
'completed', 'booked', 'scheduled', 'cancelled', 'failed', 'error',
|
|
43897
|
+
'displaying', 'clicked', 'contacted', 'submitted', 'sent'
|
|
43898
|
+
];
|
|
43899
|
+
const status = state.status;
|
|
43900
|
+
if (typeof status === 'string' && TERMINAL_STATUSES.includes(status)) {
|
|
43901
|
+
return true;
|
|
43902
|
+
}
|
|
43903
|
+
// For non-halting actions (query_contact_directory, etc.) with results/success
|
|
43904
|
+
if (!status && (state.success !== undefined || state.results !== undefined)) {
|
|
43905
|
+
return true;
|
|
43906
|
+
}
|
|
43907
|
+
return false;
|
|
43908
|
+
}
|
|
43909
|
+
function isActionLoading(message) {
|
|
43910
|
+
if (!message.action)
|
|
43911
|
+
return false;
|
|
43912
|
+
if (message.action.done)
|
|
43913
|
+
return false;
|
|
43914
|
+
if (message.isStreaming)
|
|
43915
|
+
return true;
|
|
43916
|
+
const state = message.action.state;
|
|
43917
|
+
return !isActionComplete(state);
|
|
43918
|
+
}
|
|
43919
|
+
const ToolMessageGroup = ({ messages, getActionRenderer, showToolIndicator = true, accentColor, variant }) => {
|
|
43885
43920
|
const actionMessages = messages.filter(message => message.action);
|
|
43921
|
+
// Debug logging
|
|
43922
|
+
console.log('[DEBUG ToolMessageGroup] ========================================');
|
|
43923
|
+
console.log('[DEBUG ToolMessageGroup] Total messages:', messages.length);
|
|
43924
|
+
console.log('[DEBUG ToolMessageGroup] Messages with action:', actionMessages.length);
|
|
43925
|
+
console.log('[DEBUG ToolMessageGroup] hasGetActionRenderer:', !!getActionRenderer);
|
|
43926
|
+
messages.forEach((msg, i) => {
|
|
43927
|
+
console.log(`[DEBUG ToolMessageGroup] Message ${i}:`, {
|
|
43928
|
+
id: msg.id,
|
|
43929
|
+
role: msg.message.role,
|
|
43930
|
+
hasAction: !!msg.action,
|
|
43931
|
+
actionImpl: msg.action?.implementation,
|
|
43932
|
+
toolExecuting: msg.toolExecuting,
|
|
43933
|
+
});
|
|
43934
|
+
});
|
|
43935
|
+
actionMessages.forEach((msg, i) => {
|
|
43936
|
+
const impl = msg.action?.implementation || '';
|
|
43937
|
+
const renderer = getActionRenderer?.(impl);
|
|
43938
|
+
console.log(`[DEBUG ToolMessageGroup] Action ${i}:`, {
|
|
43939
|
+
implementation: impl,
|
|
43940
|
+
hasRenderer: !!renderer,
|
|
43941
|
+
rendererType: renderer ? typeof renderer : 'undefined',
|
|
43942
|
+
state: msg.action?.state,
|
|
43943
|
+
});
|
|
43944
|
+
});
|
|
43886
43945
|
// If tool indicator is hidden AND there are no action cards to render, don't render anything
|
|
43887
|
-
// This prevents empty wrapper divs that cause layout jumping
|
|
43888
43946
|
if (!showToolIndicator && actionMessages.length === 0) {
|
|
43889
43947
|
return null;
|
|
43890
43948
|
}
|
|
43891
43949
|
const badges = messages.map((message) => {
|
|
43892
43950
|
const toolName = message.toolExecuting || message.message.name || 'Tool';
|
|
43893
43951
|
const hasError = message.isError || false;
|
|
43894
|
-
const
|
|
43895
|
-
const actionStatus = actionState?.status;
|
|
43896
|
-
const terminalStatuses = ['completed', 'booked', 'scheduled', 'failed', 'cancelled', 'displaying', 'clicked'];
|
|
43897
|
-
const isTerminalStatus = actionStatus && terminalStatuses.includes(actionStatus);
|
|
43898
|
-
const isDone = message.action ? (message.action.done ?? isTerminalStatus ?? false) : !message.isStreaming;
|
|
43899
|
-
const isLoading = !isDone;
|
|
43952
|
+
const loading = isActionLoading(message);
|
|
43900
43953
|
return {
|
|
43901
43954
|
id: message.id,
|
|
43902
43955
|
name: toolName,
|
|
43903
|
-
status:
|
|
43956
|
+
status: loading ? 'loading' : hasError ? 'error' : 'completed',
|
|
43904
43957
|
};
|
|
43905
43958
|
});
|
|
43906
43959
|
return (jsxRuntimeExports.jsxs("div", { className: "ai-chat-message tool", children: [showToolIndicator && jsxRuntimeExports.jsx(ToolIndicator, { badges: badges }), actionMessages.map((message) => {
|
|
43907
|
-
if (!message.action || !getActionRenderer)
|
|
43960
|
+
if (!message.action || !getActionRenderer) {
|
|
43961
|
+
console.log('[ToolMessageGroup] Skipping - no action or renderer:', { hasAction: !!message.action, hasGetRenderer: !!getActionRenderer });
|
|
43908
43962
|
return null;
|
|
43963
|
+
}
|
|
43909
43964
|
const renderer = getActionRenderer(message.action.implementation);
|
|
43910
|
-
if (!renderer)
|
|
43965
|
+
if (!renderer) {
|
|
43966
|
+
console.log('[ToolMessageGroup] No renderer for:', message.action.implementation);
|
|
43911
43967
|
return null;
|
|
43912
|
-
|
|
43968
|
+
}
|
|
43969
|
+
return (jsxRuntimeExports.jsx("div", { className: "ai-chat-tool-action", children: renderer(message, accentColor, variant) }, `action-${message.id}`));
|
|
43913
43970
|
})] }));
|
|
43914
43971
|
};
|
|
43915
43972
|
|
|
@@ -43971,12 +44028,16 @@
|
|
|
43971
44028
|
};
|
|
43972
44029
|
|
|
43973
44030
|
const MessageList = (props) => {
|
|
43974
|
-
const { messages, isTyping = false, showTypingIndicator = true, showTimestamps = true, showToolCalls = false, enableFeedback = true, welcomeTitle, welcomeMessage, suggestedQuestions, accentColor, onSuggestedQuestionClick, onActionClick, onFeedback, onScrollStateChange, getActionRenderer, } = props;
|
|
44031
|
+
const { messages, isTyping = false, showTypingIndicator = true, showTimestamps = true, showToolCalls = false, enableFeedback = true, welcomeTitle, welcomeMessage, suggestedQuestions, accentColor, onSuggestedQuestionClick, onActionClick, onFeedback, onScrollStateChange, getActionRenderer, variant, } = props;
|
|
43975
44032
|
const containerRef = reactExports.useRef(null);
|
|
43976
44033
|
const messagesEndRef = reactExports.useRef(null);
|
|
43977
44034
|
const [showScrollButton, setShowScrollButton] = reactExports.useState(false);
|
|
43978
44035
|
const prevMessageCountRef = reactExports.useRef(0);
|
|
43979
|
-
const hasActiveAction = reactExports.useMemo(() =>
|
|
44036
|
+
const hasActiveAction = reactExports.useMemo(() => {
|
|
44037
|
+
// Find the last tool message and check if its action is still active (not done)
|
|
44038
|
+
const lastToolMsg = [...messages].reverse().find(msg => msg.message.role === 'tool');
|
|
44039
|
+
return lastToolMsg?.action && lastToolMsg.action.done !== true;
|
|
44040
|
+
}, [messages]);
|
|
43980
44041
|
const checkScrollPosition = reactExports.useCallback(() => {
|
|
43981
44042
|
const c = containerRef.current;
|
|
43982
44043
|
if (!c)
|
|
@@ -44012,15 +44073,31 @@
|
|
|
44012
44073
|
checkScrollPosition();
|
|
44013
44074
|
}, [messages, isTyping, checkScrollPosition]);
|
|
44014
44075
|
const groupedMessages = reactExports.useMemo(() => {
|
|
44076
|
+
console.log('[DEBUG MessageList] ========================================');
|
|
44077
|
+
console.log('[DEBUG MessageList] Processing messages:', messages.length);
|
|
44078
|
+
messages.forEach((m, i) => {
|
|
44079
|
+
console.log(`[DEBUG MessageList] Message ${i}:`, {
|
|
44080
|
+
id: m.id,
|
|
44081
|
+
role: m.message.role,
|
|
44082
|
+
hasAction: !!m.action,
|
|
44083
|
+
actionImpl: m.action?.implementation,
|
|
44084
|
+
content: (m.message.content || '').substring(0, 50),
|
|
44085
|
+
});
|
|
44086
|
+
});
|
|
44015
44087
|
const result = [];
|
|
44016
44088
|
let toolGroup = [];
|
|
44017
|
-
const flush = () => {
|
|
44018
|
-
|
|
44019
|
-
|
|
44020
|
-
|
|
44089
|
+
const flush = () => {
|
|
44090
|
+
if (toolGroup.length) {
|
|
44091
|
+
console.log('[DEBUG MessageList] Flushing tool group with', toolGroup.length, 'messages');
|
|
44092
|
+
result.push({ type: 'tool-group', messages: [...toolGroup] });
|
|
44093
|
+
toolGroup = [];
|
|
44094
|
+
}
|
|
44095
|
+
};
|
|
44021
44096
|
for (const m of messages) {
|
|
44022
|
-
if (m.message.role === 'tool')
|
|
44097
|
+
if (m.message.role === 'tool') {
|
|
44098
|
+
console.log('[DEBUG MessageList] Adding to tool group:', m.id);
|
|
44023
44099
|
toolGroup.push(m);
|
|
44100
|
+
}
|
|
44024
44101
|
else if (m.message.role === 'user') {
|
|
44025
44102
|
flush();
|
|
44026
44103
|
result.push({ type: 'message', message: m });
|
|
@@ -44032,6 +44109,7 @@
|
|
|
44032
44109
|
flush();
|
|
44033
44110
|
result.push({ type: 'message', message: m });
|
|
44034
44111
|
}
|
|
44112
|
+
// Don't flush on empty assistant messages - let tools continue grouping
|
|
44035
44113
|
}
|
|
44036
44114
|
else {
|
|
44037
44115
|
flush();
|
|
@@ -44039,13 +44117,22 @@
|
|
|
44039
44117
|
}
|
|
44040
44118
|
}
|
|
44041
44119
|
flush();
|
|
44120
|
+
console.log('[DEBUG MessageList] Final grouped result:', result.length, 'items');
|
|
44121
|
+
result.forEach((item, i) => {
|
|
44122
|
+
if (item.type === 'tool-group') {
|
|
44123
|
+
console.log(`[DEBUG MessageList] Group ${i}: tool-group with ${item.messages.length} messages`);
|
|
44124
|
+
}
|
|
44125
|
+
else {
|
|
44126
|
+
console.log(`[DEBUG MessageList] Group ${i}: message (${item.message.message.role})`);
|
|
44127
|
+
}
|
|
44128
|
+
});
|
|
44042
44129
|
return result;
|
|
44043
44130
|
}, [messages]);
|
|
44044
44131
|
const hasSuggestions = messages.length === 0 && onSuggestedQuestionClick && suggestedQuestions?.length;
|
|
44045
44132
|
const showWelcome = welcomeTitle || welcomeMessage || hasSuggestions;
|
|
44046
44133
|
return (jsxRuntimeExports.jsxs("div", { ref: containerRef, className: "ai-chat-messages", role: "log", "aria-live": "polite", children: [showWelcome && (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 }), hasSuggestions && jsxRuntimeExports.jsx(SuggestedQuestions, { questions: suggestedQuestions, onQuestionClick: onSuggestedQuestionClick })] })), groupedMessages.map((item, i) => {
|
|
44047
44134
|
if (item.type === 'tool-group') {
|
|
44048
|
-
return jsxRuntimeExports.jsx(ToolMessageGroup, { messages: item.messages, getActionRenderer: getActionRenderer, showToolIndicator: showToolCalls, accentColor: accentColor }, `tg-${i}`);
|
|
44135
|
+
return jsxRuntimeExports.jsx(ToolMessageGroup, { messages: item.messages, getActionRenderer: getActionRenderer, showToolIndicator: showToolCalls, accentColor: accentColor, variant: variant }, `tg-${i}`);
|
|
44049
44136
|
}
|
|
44050
44137
|
const isLast = i === groupedMessages.length - 1;
|
|
44051
44138
|
const hasFollowUp = item.message.message.role === 'assistant' && item.message.suggestions?.length && isLast && !isTyping;
|
|
@@ -44064,7 +44151,7 @@
|
|
|
44064
44151
|
return (bytes / 1024).toFixed(1) + ' KB';
|
|
44065
44152
|
return (bytes / (1024 * 1024)).toFixed(1) + ' MB';
|
|
44066
44153
|
};
|
|
44067
|
-
const MessageInput = ({ onSend, placeholder = 'Type your message...', disabled = false, enableFileUpload = false, separateFromChat = true, }) => {
|
|
44154
|
+
const MessageInput = ({ onSend, placeholder = 'Type your message...', disabled = false, enableFileUpload = false, separateFromChat = true, showDataPolicy = true, onDataPolicyClick, }) => {
|
|
44068
44155
|
const [value, setValue] = reactExports.useState('');
|
|
44069
44156
|
const [selectedFiles, setSelectedFiles] = reactExports.useState([]);
|
|
44070
44157
|
const textareaRef = reactExports.useRef(null);
|
|
@@ -44099,10 +44186,10 @@
|
|
|
44099
44186
|
}
|
|
44100
44187
|
};
|
|
44101
44188
|
const canSend = value.trim() || selectedFiles.length > 0;
|
|
44102
|
-
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) => (jsxRuntimeExports.jsxs("div", { className: "ai-chat-file-item", children: [jsxRuntimeExports.jsx("span", { className: "ai-chat-file-extension", children: getFileExtension(file.name) }), 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", children: jsxRuntimeExports.jsx("path", { d: "M18 6L6 18M6 6l12 12" }) }) })] }, index))) })), 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(',') }), 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", 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: (e) => setValue(e.target.value), onKeyDown: handleKeyDown, placeholder: placeholder, disabled: disabled, rows: 2, wrap: "soft", "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", children: [jsxRuntimeExports.jsx("path", { d: "M12 19V5" }), jsxRuntimeExports.jsx("path", { d: "M5 12l7-7 7 7" })] }) })] })] }));
|
|
44189
|
+
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) => (jsxRuntimeExports.jsxs("div", { className: "ai-chat-file-item", children: [jsxRuntimeExports.jsx("span", { className: "ai-chat-file-extension", children: getFileExtension(file.name) }), 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", children: jsxRuntimeExports.jsx("path", { d: "M18 6L6 18M6 6l12 12" }) }) })] }, index))) })), 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(',') }), 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", 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: (e) => setValue(e.target.value), onKeyDown: handleKeyDown, placeholder: placeholder, disabled: disabled, rows: 2, wrap: "soft", "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", children: [jsxRuntimeExports.jsx("path", { d: "M12 19V5" }), jsxRuntimeExports.jsx("path", { d: "M5 12l7-7 7 7" })] }) })] }), showDataPolicy && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-data-policy", children: [jsxRuntimeExports.jsx("span", { children: "KI-generierte Antworten k\u00F6nnen unzutreffend sein." }), onDataPolicyClick && (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [' ', jsxRuntimeExports.jsx("button", { type: "button", className: "ai-chat-data-policy-link", onClick: onDataPolicyClick, children: "Datenschutzhinweis" })] }))] }))] }));
|
|
44103
44190
|
};
|
|
44104
44191
|
|
|
44105
|
-
function groupSlotsByDate(slots) {
|
|
44192
|
+
function groupSlotsByDate$1(slots) {
|
|
44106
44193
|
const grouped = new Map();
|
|
44107
44194
|
for (const slot of slots) {
|
|
44108
44195
|
if (!slot || typeof slot !== 'object' || !slot.startTime || typeof slot.startTime !== 'string') {
|
|
@@ -44116,7 +44203,7 @@
|
|
|
44116
44203
|
}
|
|
44117
44204
|
return grouped;
|
|
44118
44205
|
}
|
|
44119
|
-
function formatDate(dateStr) {
|
|
44206
|
+
function formatDate$1(dateStr) {
|
|
44120
44207
|
try {
|
|
44121
44208
|
const date = new Date(dateStr);
|
|
44122
44209
|
return new Intl.DateTimeFormat("en-US", {
|
|
@@ -44129,16 +44216,16 @@
|
|
|
44129
44216
|
return dateStr;
|
|
44130
44217
|
}
|
|
44131
44218
|
}
|
|
44132
|
-
function CalendarIcon() {
|
|
44219
|
+
function CalendarIcon$1() {
|
|
44133
44220
|
return (jsxRuntimeExports.jsx("svg", { className: "ai-chat-action-icon", viewBox: "0 0 20 20", fill: "currentColor", children: jsxRuntimeExports.jsx("path", { fillRule: "evenodd", d: "M6 2a1 1 0 00-1 1v1H4a2 2 0 00-2 2v10a2 2 0 002 2h12a2 2 0 002-2V6a2 2 0 00-2-2h-1V3a1 1 0 10-2 0v1H7V3a1 1 0 00-1-1zm0 5a1 1 0 000 2h8a1 1 0 100-2H6z", clipRule: "evenodd" }) }));
|
|
44134
44221
|
}
|
|
44135
|
-
function CheckIcon() {
|
|
44222
|
+
function CheckIcon$1() {
|
|
44136
44223
|
return (jsxRuntimeExports.jsx("svg", { className: "ai-chat-action-icon-success", viewBox: "0 0 20 20", fill: "currentColor", children: jsxRuntimeExports.jsx("path", { fillRule: "evenodd", d: "M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z", clipRule: "evenodd" }) }));
|
|
44137
44224
|
}
|
|
44138
|
-
function ExternalLinkIcon$
|
|
44225
|
+
function ExternalLinkIcon$2() {
|
|
44139
44226
|
return (jsxRuntimeExports.jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }), jsxRuntimeExports.jsx("polyline", { points: "15 3 21 3 21 9" }), jsxRuntimeExports.jsx("line", { x1: "10", y1: "14", x2: "21", y2: "3" })] }));
|
|
44140
44227
|
}
|
|
44141
|
-
function Skeleton({ width, height, borderRadius = '4px' }) {
|
|
44228
|
+
function Skeleton$1({ width, height, borderRadius = '4px' }) {
|
|
44142
44229
|
return (jsxRuntimeExports.jsx("div", { className: "ai-chat-action-skeleton-item", style: { width, height, borderRadius } }));
|
|
44143
44230
|
}
|
|
44144
44231
|
function GoogleCalendarCard({ action, onComplete, accentColor, className = '' }) {
|
|
@@ -44155,13 +44242,12 @@
|
|
|
44155
44242
|
: [];
|
|
44156
44243
|
const allowTopic = state.allowTopic !== false;
|
|
44157
44244
|
const isBooked = state.status === "booked";
|
|
44158
|
-
const slotsByDate = groupSlotsByDate(availableSlots);
|
|
44245
|
+
const slotsByDate = groupSlotsByDate$1(availableSlots);
|
|
44159
44246
|
const dates = Array.from(slotsByDate.keys()).sort();
|
|
44160
44247
|
const [selectedDate, setSelectedDate] = reactExports.useState(dates[0] ?? "");
|
|
44161
44248
|
const [selectedSlot, setSelectedSlot] = reactExports.useState(null);
|
|
44162
44249
|
const [topic, setTopic] = reactExports.useState("");
|
|
44163
44250
|
const [error, setError] = reactExports.useState(null);
|
|
44164
|
-
const [isSubmitting, setIsSubmitting] = reactExports.useState(false);
|
|
44165
44251
|
const slotsForSelectedDate = selectedDate ? slotsByDate.get(selectedDate) ?? [] : [];
|
|
44166
44252
|
const accentStyle = accentColor ? { '--action-accent': accentColor } : {};
|
|
44167
44253
|
const onConfirm = () => {
|
|
@@ -44174,8 +44260,245 @@
|
|
|
44174
44260
|
return;
|
|
44175
44261
|
}
|
|
44176
44262
|
setError(null);
|
|
44263
|
+
onComplete?.(action.toolCallId, {
|
|
44264
|
+
...action.state,
|
|
44265
|
+
selectedSlot: {
|
|
44266
|
+
startTime: selectedSlot.startTime,
|
|
44267
|
+
endTime: selectedSlot.endTime,
|
|
44268
|
+
},
|
|
44269
|
+
topic: allowTopic ? topic.trim() : null,
|
|
44270
|
+
});
|
|
44271
|
+
};
|
|
44272
|
+
// Booked state
|
|
44273
|
+
if (isBooked) {
|
|
44274
|
+
const bookedSlot = state.selectedSlot;
|
|
44275
|
+
const bookedTopic = state.topic;
|
|
44276
|
+
const eventLink = state.bookedEventLink;
|
|
44277
|
+
return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-action-card ai-chat-action-booked ${className}`, style: accentStyle, children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-header", children: [jsxRuntimeExports.jsx("div", { className: "ai-chat-action-success-icon-wrapper", children: jsxRuntimeExports.jsx(CheckIcon$1, {}) }), "Appointment Confirmed"] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-body", children: [bookedTopic && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-detail-box", children: [jsxRuntimeExports.jsx("span", { className: "ai-chat-action-label-small", children: "TOPIC" }), jsxRuntimeExports.jsx("span", { className: "ai-chat-action-value-large", children: bookedTopic })] })), bookedSlot && bookedSlot.startTime && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-detail-box", children: [jsxRuntimeExports.jsx("span", { className: "ai-chat-action-label-small", children: "TIME" }), jsxRuntimeExports.jsx("span", { className: "ai-chat-action-value-large", children: bookedSlot.displayTime || new Date(bookedSlot.startTime).toLocaleString() })] })), eventLink && (jsxRuntimeExports.jsxs("a", { href: eventLink, target: "_blank", rel: "noopener noreferrer", className: "ai-chat-action-link-button", children: ["View in Google Calendar", jsxRuntimeExports.jsx(ExternalLinkIcon$2, {})] }))] })] }));
|
|
44278
|
+
}
|
|
44279
|
+
// Skeleton loading state - show when waiting for backend after user confirms
|
|
44280
|
+
const isWaitingForBackend = !action.done && state.selectedSlot && !isBooked;
|
|
44281
|
+
if (isWaitingForBackend) {
|
|
44282
|
+
return (jsxRuntimeExports.jsx("div", { className: `ai-chat-action-card ai-chat-action-skeleton ${className}`, style: accentStyle, children: jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-skeleton-content", children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-skeleton-header", children: [jsxRuntimeExports.jsx(Skeleton$1, { width: "28px", height: "28px", borderRadius: "50%" }), jsxRuntimeExports.jsx(Skeleton$1, { width: "180px", height: "20px", borderRadius: "4px" })] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-skeleton-box", children: [jsxRuntimeExports.jsx(Skeleton$1, { width: "60px", height: "12px", borderRadius: "4px" }), jsxRuntimeExports.jsx(Skeleton$1, { width: "120px", height: "18px", borderRadius: "4px" })] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-skeleton-box", children: [jsxRuntimeExports.jsx(Skeleton$1, { width: "50px", height: "12px", borderRadius: "4px" }), jsxRuntimeExports.jsx(Skeleton$1, { width: "200px", height: "18px", borderRadius: "4px" })] }), jsxRuntimeExports.jsx(Skeleton$1, { width: "100%", height: "44px", borderRadius: "999px" })] }) }));
|
|
44283
|
+
}
|
|
44284
|
+
// Booking form
|
|
44285
|
+
return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-action-card ai-chat-google-calendar ${className}`, style: accentStyle, children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-header", children: [jsxRuntimeExports.jsx(CalendarIcon$1, {}), "Schedule an Appointment"] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-body", children: [allowTopic && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-field", children: [jsxRuntimeExports.jsx("label", { htmlFor: `topic-${action.toolCallId}`, className: "ai-chat-action-label", children: "Meeting Topic" }), jsxRuntimeExports.jsx("input", { id: `topic-${action.toolCallId}`, type: "text", className: "ai-chat-action-input", placeholder: "e.g., Product Demo", value: topic, onChange: (e) => setTopic(e.target.value) })] })), jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-field", children: [jsxRuntimeExports.jsx("label", { className: "ai-chat-action-label", children: "Select Date" }), jsxRuntimeExports.jsx("div", { className: "ai-chat-action-date-grid", children: dates.slice(0, 7).map((date) => (jsxRuntimeExports.jsx("button", { type: "button", className: `ai-chat-action-date-btn ${selectedDate === date ? "active" : ""}`, onClick: () => {
|
|
44286
|
+
setSelectedDate(date);
|
|
44287
|
+
setSelectedSlot(null);
|
|
44288
|
+
}, children: formatDate$1(date) }, date))) })] }), selectedDate && slotsForSelectedDate.length > 0 && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-field", children: [jsxRuntimeExports.jsx("label", { className: "ai-chat-action-label", children: "Select Time" }), jsxRuntimeExports.jsx("div", { className: "ai-chat-action-time-grid", children: slotsForSelectedDate.map((slot) => (jsxRuntimeExports.jsx("button", { type: "button", className: `ai-chat-action-time-btn ${selectedSlot?.startTime === slot.startTime ? "active" : ""}`, onClick: () => setSelectedSlot(slot), children: slot.displayTime || new Date(slot.startTime).toLocaleTimeString([], { hour: "numeric", minute: "2-digit" }) }, slot.startTime))) })] })), error && jsxRuntimeExports.jsx("div", { className: "ai-chat-action-error", children: error }), jsxRuntimeExports.jsx("button", { className: "ai-chat-action-button", type: "button", onClick: onConfirm, disabled: !selectedSlot, children: "Confirm Appointment" }), availableSlots.length === 0 && (jsxRuntimeExports.jsx("div", { className: "ai-chat-action-hint", children: "No available time slots found." }))] })] }));
|
|
44289
|
+
}
|
|
44290
|
+
|
|
44291
|
+
function groupSlotsByDate(slots) {
|
|
44292
|
+
const grouped = new Map();
|
|
44293
|
+
for (const slot of slots) {
|
|
44294
|
+
if (!slot || typeof slot !== 'object' || !slot.startTime || typeof slot.startTime !== 'string') {
|
|
44295
|
+
continue;
|
|
44296
|
+
}
|
|
44297
|
+
const date = slot.startTime.slice(0, 10);
|
|
44298
|
+
if (!grouped.has(date)) {
|
|
44299
|
+
grouped.set(date, []);
|
|
44300
|
+
}
|
|
44301
|
+
grouped.get(date).push(slot);
|
|
44302
|
+
}
|
|
44303
|
+
return grouped;
|
|
44304
|
+
}
|
|
44305
|
+
function formatDate(dateStr) {
|
|
44306
|
+
try {
|
|
44307
|
+
const date = new Date(dateStr);
|
|
44308
|
+
return new Intl.DateTimeFormat("en-US", {
|
|
44309
|
+
weekday: "short",
|
|
44310
|
+
month: "short",
|
|
44311
|
+
day: "numeric",
|
|
44312
|
+
}).format(date);
|
|
44313
|
+
}
|
|
44314
|
+
catch {
|
|
44315
|
+
return dateStr;
|
|
44316
|
+
}
|
|
44317
|
+
}
|
|
44318
|
+
function CalendarIcon() {
|
|
44319
|
+
return (jsxRuntimeExports.jsx("svg", { className: "ai-chat-action-icon", viewBox: "0 0 20 20", fill: "currentColor", children: jsxRuntimeExports.jsx("path", { fillRule: "evenodd", d: "M6 2a1 1 0 00-1 1v1H4a2 2 0 00-2 2v10a2 2 0 002 2h12a2 2 0 002-2V6a2 2 0 00-2-2h-1V3a1 1 0 10-2 0v1H7V3a1 1 0 00-1-1zm0 5a1 1 0 000 2h8a1 1 0 100-2H6z", clipRule: "evenodd" }) }));
|
|
44320
|
+
}
|
|
44321
|
+
function MailIcon() {
|
|
44322
|
+
return (jsxRuntimeExports.jsxs("svg", { className: "ai-chat-action-icon", viewBox: "0 0 20 20", fill: "currentColor", children: [jsxRuntimeExports.jsx("path", { d: "M2.003 5.884L10 9.882l7.997-3.998A2 2 0 0016 4H4a2 2 0 00-1.997 1.884z" }), jsxRuntimeExports.jsx("path", { d: "M18 8.118l-8 4-8-4V14a2 2 0 002 2h12a2 2 0 002-2V8.118z" })] }));
|
|
44323
|
+
}
|
|
44324
|
+
function CheckIcon() {
|
|
44325
|
+
return (jsxRuntimeExports.jsx("svg", { className: "ai-chat-action-icon-success", viewBox: "0 0 20 20", fill: "currentColor", children: jsxRuntimeExports.jsx("path", { fillRule: "evenodd", d: "M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z", clipRule: "evenodd" }) }));
|
|
44326
|
+
}
|
|
44327
|
+
function ErrorIcon() {
|
|
44328
|
+
return (jsxRuntimeExports.jsx("svg", { className: "ai-chat-action-icon-error", viewBox: "0 0 20 20", fill: "currentColor", children: jsxRuntimeExports.jsx("path", { fillRule: "evenodd", d: "M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z", clipRule: "evenodd" }) }));
|
|
44329
|
+
}
|
|
44330
|
+
function ExternalLinkIcon$1() {
|
|
44331
|
+
return (jsxRuntimeExports.jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }), jsxRuntimeExports.jsx("polyline", { points: "15 3 21 3 21 9" }), jsxRuntimeExports.jsx("line", { x1: "10", y1: "14", x2: "21", y2: "3" })] }));
|
|
44332
|
+
}
|
|
44333
|
+
function Skeleton({ width, height, borderRadius = '4px' }) {
|
|
44334
|
+
return (jsxRuntimeExports.jsx("div", { className: "ai-chat-action-skeleton-item", style: { width, height, borderRadius } }));
|
|
44335
|
+
}
|
|
44336
|
+
function PinInputGroup({ values, onChange, disabled }) {
|
|
44337
|
+
const inputRefs = reactExports.useRef([]);
|
|
44338
|
+
const handleChange = (index, value) => {
|
|
44339
|
+
// Only allow digits
|
|
44340
|
+
const digit = value.replace(/[^0-9]/g, '');
|
|
44341
|
+
const newValues = [...values];
|
|
44342
|
+
newValues[index] = digit.slice(-1);
|
|
44343
|
+
onChange(newValues);
|
|
44344
|
+
// Auto-focus next input
|
|
44345
|
+
if (digit && index < 5) {
|
|
44346
|
+
inputRefs.current[index + 1]?.focus();
|
|
44347
|
+
}
|
|
44348
|
+
};
|
|
44349
|
+
const handleKeyDown = (index, e) => {
|
|
44350
|
+
if (e.key === 'Backspace' && !values[index] && index > 0) {
|
|
44351
|
+
inputRefs.current[index - 1]?.focus();
|
|
44352
|
+
}
|
|
44353
|
+
};
|
|
44354
|
+
const handlePaste = (e) => {
|
|
44355
|
+
e.preventDefault();
|
|
44356
|
+
const pastedData = e.clipboardData.getData('text').replace(/[^0-9]/g, '').slice(0, 6);
|
|
44357
|
+
const newValues = pastedData.split('').concat(Array(6 - pastedData.length).fill(''));
|
|
44358
|
+
onChange(newValues);
|
|
44359
|
+
// Focus the next empty input or the last one
|
|
44360
|
+
const nextIndex = Math.min(pastedData.length, 5);
|
|
44361
|
+
inputRefs.current[nextIndex]?.focus();
|
|
44362
|
+
};
|
|
44363
|
+
return (jsxRuntimeExports.jsx("div", { className: "ai-chat-pin-input-group", children: values.map((value, index) => (jsxRuntimeExports.jsx("input", { ref: (el) => {
|
|
44364
|
+
inputRefs.current[index] = el;
|
|
44365
|
+
}, type: "text", inputMode: "numeric", maxLength: 1, className: "ai-chat-pin-input", value: value, onChange: (e) => handleChange(index, e.target.value), onKeyDown: (e) => handleKeyDown(index, e), onPaste: handlePaste, disabled: disabled, autoFocus: index === 0 }, index))) }));
|
|
44366
|
+
}
|
|
44367
|
+
function MicrosoftCalendarCard({ action, onComplete, accentColor, className = '' }) {
|
|
44368
|
+
const state = action.state;
|
|
44369
|
+
const phase = state.phase || "awaiting_email";
|
|
44370
|
+
const allowTopic = state.allowTopic !== false;
|
|
44371
|
+
const accentStyle = accentColor ? { '--action-accent': accentColor } : {};
|
|
44372
|
+
// Debug: Log state changes
|
|
44373
|
+
const prevStateRef = reactExports.useRef(null);
|
|
44374
|
+
reactExports.useEffect(() => {
|
|
44375
|
+
if (JSON.stringify(prevStateRef.current) !== JSON.stringify(state)) {
|
|
44376
|
+
console.log('[MicrosoftCalendarCard] State updated:', {
|
|
44377
|
+
phase: state.phase,
|
|
44378
|
+
hasError: !!state.errorMessage,
|
|
44379
|
+
error: state.errorMessage,
|
|
44380
|
+
slotsCount: state.availableSlots?.length || 0
|
|
44381
|
+
});
|
|
44382
|
+
prevStateRef.current = state;
|
|
44383
|
+
}
|
|
44384
|
+
}, [state]);
|
|
44385
|
+
// Email phase state
|
|
44386
|
+
const [email, setEmail] = reactExports.useState("");
|
|
44387
|
+
const [emailError, setEmailError] = reactExports.useState(null);
|
|
44388
|
+
// OTP phase state
|
|
44389
|
+
const [otpValues, setOtpValues] = reactExports.useState(Array(6).fill(''));
|
|
44390
|
+
const [otpError, setOtpError] = reactExports.useState(null);
|
|
44391
|
+
// Loading states
|
|
44392
|
+
const [isSubmitting, setIsSubmitting] = reactExports.useState(false);
|
|
44393
|
+
// Reset loading state when phase changes (backend has responded)
|
|
44394
|
+
// Use useEffect for reliable re-rendering
|
|
44395
|
+
reactExports.useEffect(() => {
|
|
44396
|
+
console.log('[MicrosoftCalendarCard] Phase changed to:', phase);
|
|
44397
|
+
setIsSubmitting(false);
|
|
44398
|
+
// Clear errors when transitioning to new phase
|
|
44399
|
+
if (phase === "awaiting_email") {
|
|
44400
|
+
setEmailError(null);
|
|
44401
|
+
setOtpError(null);
|
|
44402
|
+
setSelectionError(null);
|
|
44403
|
+
}
|
|
44404
|
+
else if (phase === "awaiting_otp") {
|
|
44405
|
+
setOtpError(state.errorMessage || null);
|
|
44406
|
+
setEmailError(null);
|
|
44407
|
+
setSelectionError(null);
|
|
44408
|
+
// Clear OTP input for fresh attempt
|
|
44409
|
+
setOtpValues(Array(6).fill(''));
|
|
44410
|
+
}
|
|
44411
|
+
else if (phase === "awaiting_options") {
|
|
44412
|
+
setEmailError(null);
|
|
44413
|
+
setOtpError(null);
|
|
44414
|
+
setSelectionError(null);
|
|
44415
|
+
}
|
|
44416
|
+
else if (phase === "awaiting_booking") {
|
|
44417
|
+
setSelectionError(state.errorMessage || null);
|
|
44418
|
+
setEmailError(null);
|
|
44419
|
+
setOtpError(null);
|
|
44420
|
+
}
|
|
44421
|
+
else if (phase === "booked" || phase === "cancelled" || phase === "error") {
|
|
44422
|
+
setEmailError(null);
|
|
44423
|
+
setOtpError(null);
|
|
44424
|
+
setSelectionError(null);
|
|
44425
|
+
setSelectedId(null); // Reset selection
|
|
44426
|
+
}
|
|
44427
|
+
}, [phase, state.errorMessage]);
|
|
44428
|
+
// Selection phase state
|
|
44429
|
+
const rawSlots = state.availableSlots;
|
|
44430
|
+
const availableSlots = Array.isArray(rawSlots)
|
|
44431
|
+
? rawSlots.filter((slot) => slot !== null &&
|
|
44432
|
+
slot !== undefined &&
|
|
44433
|
+
typeof slot === "object" &&
|
|
44434
|
+
"startTime" in slot &&
|
|
44435
|
+
"endTime" in slot &&
|
|
44436
|
+
typeof slot.startTime === "string" &&
|
|
44437
|
+
typeof slot.endTime === "string")
|
|
44438
|
+
: [];
|
|
44439
|
+
const slotsByDate = groupSlotsByDate(availableSlots);
|
|
44440
|
+
const dates = Array.from(slotsByDate.keys()).sort();
|
|
44441
|
+
const [selectedDate, setSelectedDate] = reactExports.useState(dates[0] ?? "");
|
|
44442
|
+
const [selectedSlot, setSelectedSlot] = reactExports.useState(null);
|
|
44443
|
+
const [topic, setTopic] = reactExports.useState("");
|
|
44444
|
+
const [selectionError, setSelectionError] = reactExports.useState(null);
|
|
44445
|
+
// Cancellation phase state
|
|
44446
|
+
const [selectedId, setSelectedId] = reactExports.useState(null);
|
|
44447
|
+
const slotsForSelectedDate = selectedDate ? slotsByDate.get(selectedDate) ?? [] : [];
|
|
44448
|
+
// Phase 1: Email Input
|
|
44449
|
+
const handleEmailSubmit = () => {
|
|
44450
|
+
const trimmedEmail = email.trim();
|
|
44451
|
+
if (!trimmedEmail) {
|
|
44452
|
+
setEmailError("Please enter your email address");
|
|
44453
|
+
return;
|
|
44454
|
+
}
|
|
44455
|
+
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(trimmedEmail)) {
|
|
44456
|
+
setEmailError("Please enter a valid email address");
|
|
44457
|
+
return;
|
|
44458
|
+
}
|
|
44459
|
+
setEmailError(null);
|
|
44460
|
+
setIsSubmitting(true);
|
|
44461
|
+
console.log('[MicrosoftCalendarCard] Submitting email:', trimmedEmail);
|
|
44462
|
+
setTimeout(() => {
|
|
44463
|
+
onComplete?.(action.toolCallId, {
|
|
44464
|
+
...action.state,
|
|
44465
|
+
email: trimmedEmail,
|
|
44466
|
+
});
|
|
44467
|
+
}, 50);
|
|
44468
|
+
};
|
|
44469
|
+
// Phase 2: OTP Verification
|
|
44470
|
+
const handleOtpSubmit = () => {
|
|
44471
|
+
const otpCode = otpValues.join('');
|
|
44472
|
+
if (otpCode.length !== 6) {
|
|
44473
|
+
setOtpError("Please enter the 6-digit code");
|
|
44474
|
+
return;
|
|
44475
|
+
}
|
|
44476
|
+
setOtpError(null);
|
|
44477
|
+
setIsSubmitting(true);
|
|
44478
|
+
console.log('[MicrosoftCalendarCard] Submitting OTP code');
|
|
44479
|
+
setTimeout(() => {
|
|
44480
|
+
onComplete?.(action.toolCallId, {
|
|
44481
|
+
...action.state,
|
|
44482
|
+
otpCode,
|
|
44483
|
+
});
|
|
44484
|
+
}, 50);
|
|
44485
|
+
};
|
|
44486
|
+
// Phase 3: Appointment Selection
|
|
44487
|
+
const handleAppointmentConfirm = () => {
|
|
44488
|
+
if (!selectedSlot) {
|
|
44489
|
+
setSelectionError("Please select a time slot");
|
|
44490
|
+
return;
|
|
44491
|
+
}
|
|
44492
|
+
if (allowTopic && !topic.trim()) {
|
|
44493
|
+
setSelectionError("Please enter a meeting topic");
|
|
44494
|
+
return;
|
|
44495
|
+
}
|
|
44496
|
+
setSelectionError(null);
|
|
44177
44497
|
setIsSubmitting(true);
|
|
44178
|
-
|
|
44498
|
+
console.log('[MicrosoftCalendarCard] Confirming appointment:', {
|
|
44499
|
+
slot: selectedSlot,
|
|
44500
|
+
topic: topic.trim()
|
|
44501
|
+
});
|
|
44179
44502
|
setTimeout(() => {
|
|
44180
44503
|
onComplete?.(action.toolCallId, {
|
|
44181
44504
|
...action.state,
|
|
@@ -44187,22 +44510,149 @@
|
|
|
44187
44510
|
});
|
|
44188
44511
|
}, 50);
|
|
44189
44512
|
};
|
|
44190
|
-
//
|
|
44191
|
-
|
|
44513
|
+
// Handle "Use different email" button
|
|
44514
|
+
const handleUseDifferentEmail = () => {
|
|
44515
|
+
setEmail("");
|
|
44516
|
+
setEmailError(null);
|
|
44517
|
+
setOtpValues(Array(6).fill(''));
|
|
44518
|
+
setOtpError(null);
|
|
44519
|
+
onComplete?.(action.toolCallId, {
|
|
44520
|
+
phase: "awaiting_email",
|
|
44521
|
+
email: null,
|
|
44522
|
+
otpVerified: false,
|
|
44523
|
+
otpAttempts: 0,
|
|
44524
|
+
availableSlots: [],
|
|
44525
|
+
selectedSlot: null,
|
|
44526
|
+
topic: null,
|
|
44527
|
+
bookedEventId: null,
|
|
44528
|
+
bookedEventLink: null,
|
|
44529
|
+
allowTopic,
|
|
44530
|
+
errorMessage: null,
|
|
44531
|
+
});
|
|
44532
|
+
};
|
|
44533
|
+
// Phase 5: Booked Confirmation
|
|
44534
|
+
if (phase === "booked") {
|
|
44192
44535
|
const bookedSlot = state.selectedSlot;
|
|
44193
44536
|
const bookedTopic = state.topic;
|
|
44194
44537
|
const eventLink = state.bookedEventLink;
|
|
44195
|
-
|
|
44196
|
-
|
|
44197
|
-
|
|
44538
|
+
const bookedEmail = state.email;
|
|
44539
|
+
return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-action-card ai-chat-action-booked ${className}`, style: accentStyle, children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-header", children: [jsxRuntimeExports.jsx("div", { className: "ai-chat-action-success-icon-wrapper", children: jsxRuntimeExports.jsx(CheckIcon, {}) }), "Appointment Confirmed"] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-body", children: [bookedTopic && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-detail-box", children: [jsxRuntimeExports.jsx("span", { className: "ai-chat-action-label-small", children: "TOPIC" }), jsxRuntimeExports.jsx("span", { className: "ai-chat-action-value-large", children: bookedTopic })] })), bookedSlot && bookedSlot.startTime && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-detail-box", children: [jsxRuntimeExports.jsx("span", { className: "ai-chat-action-label-small", children: "TIME" }), jsxRuntimeExports.jsx("span", { className: "ai-chat-action-value-large", children: bookedSlot.displayTime || new Date(bookedSlot.startTime).toLocaleString() })] })), bookedEmail && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-hint", children: ["A calendar invitation has been sent to ", bookedEmail] })), eventLink && (jsxRuntimeExports.jsxs("a", { href: eventLink, target: "_blank", rel: "noopener noreferrer", className: "ai-chat-action-link-button", children: ["View in Outlook Calendar", jsxRuntimeExports.jsx(ExternalLinkIcon$1, {})] }))] })] }));
|
|
44540
|
+
}
|
|
44541
|
+
// Phase 6: Cancelled Confirmation
|
|
44542
|
+
if (phase === "cancelled") {
|
|
44543
|
+
const cancelledSubject = state.cancelledEventSubject;
|
|
44544
|
+
const userEmail = state.email;
|
|
44545
|
+
return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-action-card ai-chat-action-booked ${className}`, style: accentStyle, children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-header", children: [jsxRuntimeExports.jsx("div", { className: "ai-chat-action-success-icon-wrapper", children: jsxRuntimeExports.jsx(CheckIcon, {}) }), "Appointment Cancelled"] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-body", children: [cancelledSubject && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-detail-box", children: [jsxRuntimeExports.jsx("span", { className: "ai-chat-action-label-small", children: "CANCELLED" }), jsxRuntimeExports.jsx("span", { className: "ai-chat-action-value-large", children: cancelledSubject })] })), userEmail && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-hint", children: ["A cancellation notice has been sent to ", userEmail] }))] })] }));
|
|
44546
|
+
}
|
|
44547
|
+
// Error State
|
|
44548
|
+
if (phase === "error") {
|
|
44549
|
+
return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-action-card ai-chat-action-error ${className}`, style: accentStyle, children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-header", children: [jsxRuntimeExports.jsx(ErrorIcon, {}), "Error"] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-body", children: [jsxRuntimeExports.jsx("div", { className: "ai-chat-action-error-message", children: state.errorMessage || "An error occurred. Please try again." }), jsxRuntimeExports.jsx("button", { className: "ai-chat-action-button-secondary", type: "button", onClick: () => {
|
|
44550
|
+
setEmail("");
|
|
44551
|
+
setEmailError(null);
|
|
44552
|
+
setOtpValues(Array(6).fill(''));
|
|
44553
|
+
setOtpError(null);
|
|
44554
|
+
onComplete?.(action.toolCallId, {
|
|
44555
|
+
phase: "awaiting_email",
|
|
44556
|
+
email: null,
|
|
44557
|
+
otpVerified: false,
|
|
44558
|
+
otpAttempts: 0,
|
|
44559
|
+
availableSlots: [],
|
|
44560
|
+
selectedSlot: null,
|
|
44561
|
+
topic: null,
|
|
44562
|
+
bookedEventId: null,
|
|
44563
|
+
bookedEventLink: null,
|
|
44564
|
+
allowTopic,
|
|
44565
|
+
errorMessage: null,
|
|
44566
|
+
});
|
|
44567
|
+
}, children: "Start Over" })] })] }));
|
|
44568
|
+
}
|
|
44569
|
+
// Loading State
|
|
44198
44570
|
if (isSubmitting) {
|
|
44199
|
-
return (jsxRuntimeExports.jsx("div", { className: `ai-chat-action-card ai-chat-action-skeleton ${className}`, style: accentStyle, children: jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-skeleton-content", children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-skeleton-header", children: [jsxRuntimeExports.jsx(Skeleton, { width: "28px", height: "28px", borderRadius: "50%" }), jsxRuntimeExports.jsx(Skeleton, { width: "180px", height: "20px", borderRadius: "4px" })] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-skeleton-box", children: [jsxRuntimeExports.jsx(Skeleton, { width: "60px", height: "12px", borderRadius: "4px" }), jsxRuntimeExports.jsx(Skeleton, { width: "120px", height: "18px", borderRadius: "4px" })] }), jsxRuntimeExports.
|
|
44200
|
-
}
|
|
44201
|
-
//
|
|
44202
|
-
|
|
44203
|
-
|
|
44204
|
-
|
|
44205
|
-
|
|
44571
|
+
return (jsxRuntimeExports.jsx("div", { className: `ai-chat-action-card ai-chat-action-skeleton ${className}`, style: accentStyle, children: jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-skeleton-content", children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-skeleton-header", children: [jsxRuntimeExports.jsx(Skeleton, { width: "28px", height: "28px", borderRadius: "50%" }), jsxRuntimeExports.jsx(Skeleton, { width: "180px", height: "20px", borderRadius: "4px" })] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-skeleton-box", children: [jsxRuntimeExports.jsx(Skeleton, { width: "60px", height: "12px", borderRadius: "4px" }), jsxRuntimeExports.jsx(Skeleton, { width: "120px", height: "18px", borderRadius: "4px" })] }), jsxRuntimeExports.jsx(Skeleton, { width: "100%", height: "44px", borderRadius: "999px" })] }) }));
|
|
44572
|
+
}
|
|
44573
|
+
// Phase 1: Email Input
|
|
44574
|
+
if (phase === "awaiting_email") {
|
|
44575
|
+
const displayError = state.errorMessage || emailError;
|
|
44576
|
+
return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-action-card ${className}`, style: accentStyle, children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-header", children: [jsxRuntimeExports.jsx(CalendarIcon, {}), "Schedule an Appointment"] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-body", children: [jsxRuntimeExports.jsx("div", { className: "ai-chat-action-hint", children: "We'll send a verification code to your email" }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-field", children: [jsxRuntimeExports.jsx("label", { htmlFor: `email-${action.toolCallId}`, className: "ai-chat-action-label", children: "Email Address" }), jsxRuntimeExports.jsx("input", { id: `email-${action.toolCallId}`, type: "email", className: "ai-chat-action-input", placeholder: "your@email.com", value: email, onChange: (e) => {
|
|
44577
|
+
setEmail(e.target.value);
|
|
44578
|
+
setEmailError(null);
|
|
44579
|
+
}, onKeyPress: (e) => {
|
|
44580
|
+
if (e.key === 'Enter') {
|
|
44581
|
+
handleEmailSubmit();
|
|
44582
|
+
}
|
|
44583
|
+
}, autoFocus: true })] }), displayError && (jsxRuntimeExports.jsx("div", { className: "ai-chat-action-error", children: displayError })), jsxRuntimeExports.jsx("button", { className: "ai-chat-action-button", type: "button", onClick: handleEmailSubmit, children: "Continue" })] })] }));
|
|
44584
|
+
}
|
|
44585
|
+
// Phase 2: OTP Input
|
|
44586
|
+
if (phase === "awaiting_otp") {
|
|
44587
|
+
const displayError = state.errorMessage || otpError;
|
|
44588
|
+
const userEmail = state.email;
|
|
44589
|
+
return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-action-card ${className}`, style: accentStyle, children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-header", children: [jsxRuntimeExports.jsx(MailIcon, {}), "Verify Your Email"] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-body", children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-hint", children: ["We sent a 6-digit code to ", jsxRuntimeExports.jsx("strong", { children: userEmail })] }), jsxRuntimeExports.jsx(PinInputGroup, { values: otpValues, onChange: (newValues) => {
|
|
44590
|
+
setOtpValues(newValues);
|
|
44591
|
+
setOtpError(null);
|
|
44592
|
+
// Auto-submit when all 6 digits are entered
|
|
44593
|
+
if (newValues.every(v => v.length === 1)) {
|
|
44594
|
+
console.log('[MicrosoftCalendarCard] Auto-submitting OTP (all 6 digits entered)');
|
|
44595
|
+
setIsSubmitting(true);
|
|
44596
|
+
const code = newValues.join('');
|
|
44597
|
+
setTimeout(() => {
|
|
44598
|
+
onComplete?.(action.toolCallId, {
|
|
44599
|
+
...action.state,
|
|
44600
|
+
otpCode: code,
|
|
44601
|
+
});
|
|
44602
|
+
}, 100);
|
|
44603
|
+
}
|
|
44604
|
+
}, disabled: isSubmitting }), displayError && (jsxRuntimeExports.jsx("div", { className: "ai-chat-action-error", children: displayError })), jsxRuntimeExports.jsx("button", { className: "ai-chat-action-button", type: "button", onClick: handleOtpSubmit, disabled: otpValues.join('').length !== 6, children: "Verify Code" }), jsxRuntimeExports.jsx("button", { className: "ai-chat-action-button-secondary", type: "button", onClick: handleUseDifferentEmail, children: "Use different email" })] })] }));
|
|
44605
|
+
}
|
|
44606
|
+
// Phase 3: Options Menu (with inline cancel buttons and confirmation)
|
|
44607
|
+
if (phase === "awaiting_options") {
|
|
44608
|
+
const userAppointments = state.userAppointments || [];
|
|
44609
|
+
const maxAppointments = state.maxAppointmentsPerUser || 3;
|
|
44610
|
+
const appointmentCount = userAppointments.length;
|
|
44611
|
+
const canBook = appointmentCount < maxAppointments;
|
|
44612
|
+
const hasAppointments = appointmentCount > 0;
|
|
44613
|
+
const displayError = state.errorMessage || selectionError;
|
|
44614
|
+
// If confirming cancellation, show confirmation dialog
|
|
44615
|
+
if (selectedId) {
|
|
44616
|
+
const appointmentToCancel = userAppointments.find(appt => appt.id === selectedId);
|
|
44617
|
+
if (!appointmentToCancel) {
|
|
44618
|
+
setSelectedId(null); // Reset if appointment not found
|
|
44619
|
+
}
|
|
44620
|
+
else {
|
|
44621
|
+
return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-action-card ${className}`, style: accentStyle, children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-header", children: [jsxRuntimeExports.jsx(CalendarIcon, {}), "Confirm Cancellation"] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-body", children: [jsxRuntimeExports.jsx("div", { className: "ai-chat-action-hint", children: "Are you sure you want to cancel this appointment?" }), jsxRuntimeExports.jsx("div", { className: "ai-chat-action-appointment-item", style: { marginBottom: '16px' }, children: jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-appointment-info", children: [jsxRuntimeExports.jsx("div", { className: "ai-chat-action-appointment-subject", children: appointmentToCancel.subject }), jsxRuntimeExports.jsx("div", { className: "ai-chat-action-appointment-time", children: appointmentToCancel.displayTime })] }) }), displayError && (jsxRuntimeExports.jsx("div", { className: "ai-chat-action-error", children: displayError })), jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-button-group", children: [jsxRuntimeExports.jsx("button", { className: "ai-chat-action-button", type: "button", onClick: () => {
|
|
44622
|
+
setIsSubmitting(true);
|
|
44623
|
+
onComplete?.(action.toolCallId, {
|
|
44624
|
+
...action.state,
|
|
44625
|
+
selectedOption: "cancel",
|
|
44626
|
+
selectedAppointmentId: selectedId,
|
|
44627
|
+
});
|
|
44628
|
+
}, disabled: isSubmitting, children: isSubmitting ? 'Cancelling...' : 'Confirm Cancellation' }), jsxRuntimeExports.jsx("button", { className: "ai-chat-action-button-secondary", type: "button", onClick: () => {
|
|
44629
|
+
setSelectedId(null);
|
|
44630
|
+
setSelectionError(null);
|
|
44631
|
+
}, disabled: isSubmitting, children: "Go Back" })] })] })] }));
|
|
44632
|
+
}
|
|
44633
|
+
}
|
|
44634
|
+
// Normal view with inline cancel buttons
|
|
44635
|
+
return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-action-card ${className}`, style: accentStyle, children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-header", children: [jsxRuntimeExports.jsx(CalendarIcon, {}), "Manage Your Appointments"] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-body", children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-hint", children: ["You have ", appointmentCount, " active appointment", appointmentCount !== 1 ? 's' : '', canBook && ` (${maxAppointments - appointmentCount} slot${maxAppointments - appointmentCount !== 1 ? 's' : ''} remaining)`] }), hasAppointments && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-appointment-list", children: [jsxRuntimeExports.jsx("div", { className: "ai-chat-action-label", children: "Your Upcoming Appointments" }), userAppointments.map((appt) => (jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-appointment-item", children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-appointment-info", children: [jsxRuntimeExports.jsx("div", { className: "ai-chat-action-appointment-subject", children: appt.subject }), jsxRuntimeExports.jsx("div", { className: "ai-chat-action-appointment-time", children: appt.displayTime })] }), jsxRuntimeExports.jsx("button", { className: "ai-chat-action-button-secondary", type: "button", onClick: () => {
|
|
44636
|
+
setSelectedId(appt.id);
|
|
44637
|
+
setSelectionError(null);
|
|
44638
|
+
}, children: "Cancel" })] }, appt.id)))] })), displayError && (jsxRuntimeExports.jsx("div", { className: "ai-chat-action-error", children: displayError })), canBook && (jsxRuntimeExports.jsx("button", { className: "ai-chat-action-button", type: "button", onClick: () => {
|
|
44639
|
+
setIsSubmitting(true);
|
|
44640
|
+
onComplete?.(action.toolCallId, {
|
|
44641
|
+
...action.state,
|
|
44642
|
+
selectedOption: "book",
|
|
44643
|
+
});
|
|
44644
|
+
}, disabled: isSubmitting, children: isSubmitting ? 'Loading...' : 'Book New Appointment' })), !canBook && !hasAppointments && (jsxRuntimeExports.jsx("div", { className: "ai-chat-action-hint", children: "No appointments found." }))] })] }));
|
|
44645
|
+
}
|
|
44646
|
+
// Phase 4: Appointment Selection (Booking)
|
|
44647
|
+
if (phase === "awaiting_booking") {
|
|
44648
|
+
const displayError = state.errorMessage || selectionError;
|
|
44649
|
+
return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-action-card ${className}`, style: accentStyle, children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-header", children: [jsxRuntimeExports.jsx(CalendarIcon, {}), "Select Appointment Time"] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-body", children: [allowTopic && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-field", children: [jsxRuntimeExports.jsx("label", { htmlFor: `topic-${action.toolCallId}`, className: "ai-chat-action-label", children: "Meeting Topic" }), jsxRuntimeExports.jsx("input", { id: `topic-${action.toolCallId}`, type: "text", className: "ai-chat-action-input", placeholder: "e.g., Product Demo", value: topic, onChange: (e) => setTopic(e.target.value) })] })), jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-field", children: [jsxRuntimeExports.jsx("label", { className: "ai-chat-action-label", children: "Select Date" }), jsxRuntimeExports.jsx("div", { className: "ai-chat-action-date-grid", children: dates.slice(0, 7).map((date) => (jsxRuntimeExports.jsx("button", { type: "button", className: `ai-chat-action-date-btn ${selectedDate === date ? "active" : ""}`, onClick: () => {
|
|
44650
|
+
setSelectedDate(date);
|
|
44651
|
+
setSelectedSlot(null);
|
|
44652
|
+
}, children: formatDate(date) }, date))) })] }), selectedDate && slotsForSelectedDate.length > 0 && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-field", children: [jsxRuntimeExports.jsx("label", { className: "ai-chat-action-label", children: "Select Time" }), jsxRuntimeExports.jsx("div", { className: "ai-chat-action-time-grid", children: slotsForSelectedDate.map((slot) => (jsxRuntimeExports.jsx("button", { type: "button", className: `ai-chat-action-time-btn ${selectedSlot?.startTime === slot.startTime ? "active" : ""}`, onClick: () => setSelectedSlot(slot), children: slot.displayTime || new Date(slot.startTime).toLocaleTimeString([], { hour: "numeric", minute: "2-digit" }) }, slot.startTime))) })] })), displayError && (jsxRuntimeExports.jsx("div", { className: "ai-chat-action-error", children: displayError })), jsxRuntimeExports.jsx("button", { className: "ai-chat-action-button", type: "button", onClick: handleAppointmentConfirm, disabled: !selectedSlot, children: "Confirm Appointment" }), availableSlots.length === 0 && (jsxRuntimeExports.jsx("div", { className: "ai-chat-action-hint", children: "No available time slots found." }))] })] }));
|
|
44653
|
+
}
|
|
44654
|
+
// Fallback
|
|
44655
|
+
return null;
|
|
44206
44656
|
}
|
|
44207
44657
|
|
|
44208
44658
|
function truncate(text, maxLength) {
|
|
@@ -44213,17 +44663,30 @@
|
|
|
44213
44663
|
function ExternalLinkIcon() {
|
|
44214
44664
|
return (jsxRuntimeExports.jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }), jsxRuntimeExports.jsx("polyline", { points: "15 3 21 3 21 9" }), jsxRuntimeExports.jsx("line", { x1: "10", y1: "14", x2: "21", y2: "3" })] }));
|
|
44215
44665
|
}
|
|
44666
|
+
function SingleLinkPreview({ link, onLinkClick, accentColor }) {
|
|
44667
|
+
const domain = (() => {
|
|
44668
|
+
if (!link.url)
|
|
44669
|
+
return '';
|
|
44670
|
+
try {
|
|
44671
|
+
return new URL(link.url).hostname.replace('www.', '');
|
|
44672
|
+
}
|
|
44673
|
+
catch {
|
|
44674
|
+
return link.url;
|
|
44675
|
+
}
|
|
44676
|
+
})();
|
|
44677
|
+
const style = accentColor ? { '--action-accent': accentColor } : undefined;
|
|
44678
|
+
return (jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-card ai-chat-link-preview", onClick: onLinkClick, style: style, role: "link", tabIndex: 0, onKeyDown: (e) => e.key === 'Enter' && onLinkClick(), children: [link.image && (jsxRuntimeExports.jsx("div", { className: "ai-chat-link-preview__image", children: jsxRuntimeExports.jsx("img", { src: link.image, alt: link.title, onError: (e) => {
|
|
44679
|
+
e.currentTarget.parentElement.style.display = 'none';
|
|
44680
|
+
} }) })), jsxRuntimeExports.jsxs("div", { className: "ai-chat-link-preview__content", children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-link-preview__site", children: [link.favicon && (jsxRuntimeExports.jsx("img", { src: link.favicon, alt: "", className: "ai-chat-link-preview__favicon", onError: (e) => {
|
|
44681
|
+
e.currentTarget.style.display = 'none';
|
|
44682
|
+
} })), jsxRuntimeExports.jsx("span", { className: "ai-chat-link-preview__domain", children: link.siteName || domain })] }), jsxRuntimeExports.jsx("h4", { className: "ai-chat-link-preview__title", children: link.title }), link.description && (jsxRuntimeExports.jsx("p", { className: "ai-chat-link-preview__description", children: truncate(link.description, 120) }))] }), jsxRuntimeExports.jsx("div", { className: "ai-chat-link-preview__arrow", children: jsxRuntimeExports.jsx(ExternalLinkIcon, {}) })] }));
|
|
44683
|
+
}
|
|
44216
44684
|
function LinkPreviewCard({ action, onComplete, accentColor }) {
|
|
44217
44685
|
const rawState = action.state;
|
|
44218
44686
|
const hasCompletedRef = reactExports.useRef(false);
|
|
44219
44687
|
// Provide safe defaults if state is missing
|
|
44220
44688
|
const state = {
|
|
44221
|
-
|
|
44222
|
-
title: rawState?.title || 'Link',
|
|
44223
|
-
description: rawState?.description,
|
|
44224
|
-
image: rawState?.image,
|
|
44225
|
-
siteName: rawState?.siteName,
|
|
44226
|
-
favicon: rawState?.favicon,
|
|
44689
|
+
links: rawState?.links || [],
|
|
44227
44690
|
context: rawState?.context,
|
|
44228
44691
|
status: rawState?.status || 'displaying',
|
|
44229
44692
|
error: rawState?.error,
|
|
@@ -44231,34 +44694,29 @@
|
|
|
44231
44694
|
const isError = state.status === 'error';
|
|
44232
44695
|
// Auto-complete on mount so AI can continue generating text response
|
|
44233
44696
|
reactExports.useEffect(() => {
|
|
44234
|
-
if (!action.done && !hasCompletedRef.current && onComplete && state.
|
|
44697
|
+
if (!action.done && !hasCompletedRef.current && onComplete && state.links.length > 0) {
|
|
44235
44698
|
hasCompletedRef.current = true;
|
|
44236
44699
|
// Signal completion immediately - the card is displayed, AI can continue
|
|
44237
44700
|
onComplete(action.toolCallId, { ...state, status: 'displaying' });
|
|
44238
44701
|
}
|
|
44239
44702
|
}, [action.done, action.toolCallId, onComplete, state]);
|
|
44240
|
-
const
|
|
44241
|
-
if (
|
|
44242
|
-
window.open(
|
|
44703
|
+
const handleLinkClick = (url) => {
|
|
44704
|
+
if (url) {
|
|
44705
|
+
window.open(url, '_blank', 'noopener,noreferrer');
|
|
44243
44706
|
}
|
|
44244
44707
|
onComplete?.(action.toolCallId, { ...state, status: 'clicked' });
|
|
44245
44708
|
};
|
|
44246
|
-
|
|
44247
|
-
|
|
44248
|
-
|
|
44249
|
-
|
|
44250
|
-
|
|
44251
|
-
|
|
44252
|
-
|
|
44253
|
-
|
|
44254
|
-
|
|
44255
|
-
|
|
44256
|
-
|
|
44257
|
-
return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-link-preview ${isError ? 'ai-chat-link-preview--error' : ''}`, onClick: handleClick, style: style, role: "link", tabIndex: 0, onKeyDown: (e) => e.key === 'Enter' && handleClick(), children: [state.image && !isError && (jsxRuntimeExports.jsx("div", { className: "ai-chat-link-preview__image", children: jsxRuntimeExports.jsx("img", { src: state.image, alt: state.title, onError: (e) => {
|
|
44258
|
-
e.currentTarget.parentElement.style.display = 'none';
|
|
44259
|
-
} }) })), jsxRuntimeExports.jsxs("div", { className: "ai-chat-link-preview__content", children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-link-preview__site", children: [state.favicon && (jsxRuntimeExports.jsx("img", { src: state.favicon, alt: "", className: "ai-chat-link-preview__favicon", onError: (e) => {
|
|
44260
|
-
e.currentTarget.style.display = 'none';
|
|
44261
|
-
} })), jsxRuntimeExports.jsx("span", { className: "ai-chat-link-preview__domain", children: state.siteName || domain })] }), jsxRuntimeExports.jsx("h4", { className: "ai-chat-link-preview__title", children: state.title }), state.description && (jsxRuntimeExports.jsx("p", { className: "ai-chat-link-preview__description", children: truncate(state.description, 120) })), state.context && (jsxRuntimeExports.jsx("p", { className: "ai-chat-link-preview__context", children: state.context })), isError && state.error && (jsxRuntimeExports.jsx("p", { className: "ai-chat-link-preview__error-text", children: state.error }))] }), jsxRuntimeExports.jsx("div", { className: "ai-chat-link-preview__arrow", children: jsxRuntimeExports.jsx(ExternalLinkIcon, {}) })] }));
|
|
44709
|
+
if (isError) {
|
|
44710
|
+
return (jsxRuntimeExports.jsx("div", { className: "ai-chat-action-card ai-chat-link-preview ai-chat-link-preview--error", children: jsxRuntimeExports.jsx("div", { className: "ai-chat-link-preview__content", children: jsxRuntimeExports.jsx("p", { className: "ai-chat-link-preview__error-text", children: state.error || 'Failed to load preview' }) }) }));
|
|
44711
|
+
}
|
|
44712
|
+
if (state.links.length === 0) {
|
|
44713
|
+
return null;
|
|
44714
|
+
}
|
|
44715
|
+
return (jsxRuntimeExports.jsxs("div", { className: "ai-chat-link-preview-container", children: [state.context && (jsxRuntimeExports.jsx("p", { className: "ai-chat-link-preview__context", style: { marginBottom: '8px', fontSize: '0.9em', color: 'var(--ai-chat-fg-muted)' }, children: state.context })), jsxRuntimeExports.jsx("div", { className: "ai-chat-link-preview-grid", style: {
|
|
44716
|
+
display: 'grid',
|
|
44717
|
+
gridTemplateColumns: state.links.length === 1 ? '1fr' : state.links.length === 2 ? 'repeat(2, 1fr)' : 'repeat(3, 1fr)',
|
|
44718
|
+
gap: '12px',
|
|
44719
|
+
}, children: state.links.map((link, index) => (jsxRuntimeExports.jsx(SingleLinkPreview, { link: link, onLinkClick: () => handleLinkClick(link.url), accentColor: accentColor }, index))) })] }));
|
|
44262
44720
|
}
|
|
44263
44721
|
|
|
44264
44722
|
function PlayIcon() {
|
|
@@ -44324,7 +44782,7 @@
|
|
|
44324
44782
|
return src;
|
|
44325
44783
|
}
|
|
44326
44784
|
};
|
|
44327
|
-
return (jsxRuntimeExports.jsxs("div", { className: "ai-chat-
|
|
44785
|
+
return (jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-card ai-chat-video-player", style: style, children: [jsxRuntimeExports.jsx("div", { className: "ai-chat-video-player__container", children: isError ? (jsxRuntimeExports.jsx("div", { className: "ai-chat-video-player__error", children: jsxRuntimeExports.jsx("span", { children: state.error || 'Could not load video' }) })) : !isPlaying && state.thumbnailUrl ? (jsxRuntimeExports.jsxs("div", { className: "ai-chat-video-player__thumbnail", onClick: handlePlay, children: [jsxRuntimeExports.jsx("img", { src: state.thumbnailUrl, alt: state.title || 'Video thumbnail' }), jsxRuntimeExports.jsx("button", { className: "ai-chat-video-player__play-btn", "aria-label": "Play video", children: jsxRuntimeExports.jsx(PlayIcon, {}) }), jsxRuntimeExports.jsx("div", { className: "ai-chat-video-player__provider-badge", children: getProviderLabel(state.provider) })] })) : !isPlaying ? (jsxRuntimeExports.jsxs("div", { className: "ai-chat-video-player__placeholder", onClick: handlePlay, children: [jsxRuntimeExports.jsx("button", { className: "ai-chat-video-player__play-btn", "aria-label": "Play video", children: jsxRuntimeExports.jsx(PlayIcon, {}) }), jsxRuntimeExports.jsx("span", { className: "ai-chat-video-player__click-text", children: "Click to play" }), jsxRuntimeExports.jsx("div", { className: "ai-chat-video-player__provider-badge", children: getProviderLabel(state.provider) })] })) : state.provider === 'direct' ? (jsxRuntimeExports.jsx("video", { src: state.embedUrl, controls: true, autoPlay: true, className: "ai-chat-video-player__video" })) : (jsxRuntimeExports.jsx("iframe", { src: getEmbedSrc(), className: "ai-chat-video-player__iframe", allow: "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share", allowFullScreen: true, title: state.title || 'Video player' })) }), state.context && (jsxRuntimeExports.jsx("div", { className: "ai-chat-video-player__context", children: state.context }))] }));
|
|
44328
44786
|
}
|
|
44329
44787
|
|
|
44330
44788
|
function MapPinIcon() {
|
|
@@ -44385,7 +44843,9 @@
|
|
|
44385
44843
|
}
|
|
44386
44844
|
};
|
|
44387
44845
|
const style = accentColor ? { '--action-accent': accentColor } : undefined;
|
|
44388
|
-
|
|
44846
|
+
// Use smaller map height in compact mode
|
|
44847
|
+
const effectiveMapHeight = compact ? Math.min(mapHeight, 140) : mapHeight;
|
|
44848
|
+
return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-action-card ai-chat-location-card ${compact ? 'ai-chat-location-card--compact' : ''}`, style: style, children: [showMap && settings.showMap !== false && (jsxRuntimeExports.jsx("div", { className: "ai-chat-location-card__map", style: { height: effectiveMapHeight }, children: jsxRuntimeExports.jsx("iframe", { src: getMapEmbedUrl(), allowFullScreen: true, loading: "lazy", referrerPolicy: "no-referrer-when-downgrade", title: `Map of ${location.name}` }) })), jsxRuntimeExports.jsxs("div", { className: "ai-chat-location-card__content", children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-location-card__header", children: [jsxRuntimeExports.jsx("h4", { className: "ai-chat-location-card__name", children: location.name }), location.type && (jsxRuntimeExports.jsx("span", { className: "ai-chat-location-card__type", children: location.type })), openStatus !== null && (jsxRuntimeExports.jsx("span", { className: `ai-chat-location-card__status ai-chat-location-card__status--${openStatus ? 'open' : 'closed'}`, children: openStatus ? 'Open' : 'Closed' }))] }), jsxRuntimeExports.jsxs("p", { className: "ai-chat-location-card__address", children: [jsxRuntimeExports.jsx(MapPinIcon, {}), location.address] }), location.description && (jsxRuntimeExports.jsx("p", { className: "ai-chat-location-card__description", children: location.description })), settings.showHours !== false && location.hours && location.hours.length > 0 && (jsxRuntimeExports.jsx(HoursDisplay, { hours: location.hours, compact: compact })), settings.showPhone !== false && location.phone && (jsxRuntimeExports.jsxs("button", { type: "button", className: "ai-chat-location-card__phone", onClick: handleCall, children: [jsxRuntimeExports.jsx(PhoneIcon, {}), location.phone] })), jsxRuntimeExports.jsxs("div", { className: "ai-chat-location-card__actions", children: [settings.showDirectionsButton !== false && (jsxRuntimeExports.jsxs("button", { type: "button", className: "ai-chat-location-card__button", style: accentColor ? { backgroundColor: accentColor } : undefined, onClick: onDirections, children: [jsxRuntimeExports.jsx(NavigationIcon, {}), compact ? 'Directions' : 'Get Directions'] })), !compact && location.website && (jsxRuntimeExports.jsxs("a", { href: location.website, target: "_blank", rel: "noopener noreferrer", className: "ai-chat-location-card__link", children: [jsxRuntimeExports.jsx(GlobeIcon, {}), "Website"] }))] })] })] }));
|
|
44389
44849
|
}
|
|
44390
44850
|
function LocationCard({ action, onComplete, accentColor, maxColumns = 3 }) {
|
|
44391
44851
|
const rawState = action.state;
|
|
@@ -44419,9 +44879,197 @@
|
|
|
44419
44879
|
if (isSingleLocation) {
|
|
44420
44880
|
return (jsxRuntimeExports.jsx(LocationItem, { location: locations[0], settings: settings, accentColor: accentColor, onDirections: () => handleDirections(locations[0]), showMap: true }));
|
|
44421
44881
|
}
|
|
44422
|
-
return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-location-card-list ai-chat-location-card-list--${layout}`, children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-location-card-list__header", children: [jsxRuntimeExports.jsx(MapPinIcon, {}), jsxRuntimeExports.jsxs("span", { children: [locations.length, " Locations"] })] }), layout === 'stack' && (jsxRuntimeExports.jsx("div", { className:
|
|
44882
|
+
return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-location-card-list ai-chat-location-card-list--${layout}`, children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-location-card-list__header", children: [jsxRuntimeExports.jsx(MapPinIcon, {}), jsxRuntimeExports.jsxs("span", { children: [locations.length, " Locations"] })] }), layout === 'stack' && (jsxRuntimeExports.jsx("div", { className: `ai-chat-location-card-list__stack ai-chat-location-card-list__stack--cols-${stackColumns}`, children: locations.map((location) => (jsxRuntimeExports.jsx(LocationItem, { location: location, settings: settings, accentColor: accentColor, onDirections: () => handleDirections(location), showMap: settings.showMap !== false, compact: locations.length > 2 }, location.id))) })), layout === 'grid' && (jsxRuntimeExports.jsx("div", { className: "ai-chat-location-card-list__grid", children: locations.map((location) => (jsxRuntimeExports.jsx(LocationItem, { location: location, settings: settings, accentColor: accentColor, onDirections: () => handleDirections(location), showMap: false, compact: true }, location.id))) })), layout === 'carousel' && (jsxRuntimeExports.jsx("div", { className: "ai-chat-location-card-list__carousel", children: locations.map((location) => (jsxRuntimeExports.jsx(LocationItem, { location: location, settings: settings, accentColor: accentColor, onDirections: () => handleDirections(location), showMap: true, compact: false }, location.id))) }))] }));
|
|
44883
|
+
}
|
|
44884
|
+
|
|
44885
|
+
function UsersIcon() {
|
|
44886
|
+
return (jsxRuntimeExports.jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("path", { d: "M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" }), jsxRuntimeExports.jsx("circle", { cx: "9", cy: "7", r: "4" }), jsxRuntimeExports.jsx("path", { d: "M22 21v-2a4 4 0 0 0-3-3.87" }), jsxRuntimeExports.jsx("path", { d: "M16 3.13a4 4 0 0 1 0 7.75" })] }));
|
|
44887
|
+
}
|
|
44888
|
+
const AVATAR_COLORS = [
|
|
44889
|
+
{ bg: '#E8F5E9', text: '#2E7D32' }, // Green
|
|
44890
|
+
{ bg: '#E3F2FD', text: '#1565C0' }, // Blue
|
|
44891
|
+
{ bg: '#FFF3E0', text: '#E65100' }, // Orange
|
|
44892
|
+
{ bg: '#F3E5F5', text: '#7B1FA2' }, // Purple
|
|
44893
|
+
{ bg: '#FFEBEE', text: '#C62828' }, // Red
|
|
44894
|
+
{ bg: '#E0F7FA', text: '#00838F' }, // Cyan
|
|
44895
|
+
{ bg: '#FFF8E1', text: '#F9A825' }, // Amber
|
|
44896
|
+
{ bg: '#FCE4EC', text: '#AD1457' }, // Pink
|
|
44897
|
+
];
|
|
44898
|
+
function getInitials(name) {
|
|
44899
|
+
const parts = name.trim().split(/\s+/);
|
|
44900
|
+
if (parts.length === 1) {
|
|
44901
|
+
return parts[0].substring(0, 2).toUpperCase();
|
|
44902
|
+
}
|
|
44903
|
+
return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
|
|
44904
|
+
}
|
|
44905
|
+
function getColorFromName(name) {
|
|
44906
|
+
let hash = 0;
|
|
44907
|
+
for (let i = 0; i < name.length; i++) {
|
|
44908
|
+
hash = name.charCodeAt(i) + ((hash << 5) - hash);
|
|
44909
|
+
}
|
|
44910
|
+
return AVATAR_COLORS[Math.abs(hash) % AVATAR_COLORS.length];
|
|
44911
|
+
}
|
|
44912
|
+
function ContactItem({ contact, settings, accentColor, onEmail, onPhone, compact = false, layout = 'vertical', }) {
|
|
44913
|
+
const style = accentColor ? { '--action-accent': accentColor } : undefined;
|
|
44914
|
+
const layoutClass = layout === 'horizontal'
|
|
44915
|
+
? 'ai-chat-contact-card--horizontal'
|
|
44916
|
+
: 'ai-chat-contact-card--vertical';
|
|
44917
|
+
return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-action-card ai-chat-contact-card ${layoutClass} ${compact ? 'ai-chat-contact-card--compact' : ''}`, style: style, children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-contact-card__image-section", children: [contact.profilePictureUrl ? (jsxRuntimeExports.jsx("img", { src: contact.profilePictureUrl, alt: contact.name, className: "ai-chat-contact-card__image", onError: (e) => {
|
|
44918
|
+
e.currentTarget.style.display = 'none';
|
|
44919
|
+
const placeholder = e.currentTarget.parentElement?.querySelector('.ai-chat-contact-card__initials');
|
|
44920
|
+
if (placeholder) {
|
|
44921
|
+
placeholder.style.display = 'flex';
|
|
44922
|
+
}
|
|
44923
|
+
} })) : null, (() => {
|
|
44924
|
+
const colors = getColorFromName(contact.name);
|
|
44925
|
+
return (jsxRuntimeExports.jsx("div", { className: "ai-chat-contact-card__initials", style: {
|
|
44926
|
+
display: contact.profilePictureUrl ? 'none' : 'flex',
|
|
44927
|
+
backgroundColor: colors.bg,
|
|
44928
|
+
color: colors.text,
|
|
44929
|
+
}, children: getInitials(contact.name) }));
|
|
44930
|
+
})()] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-contact-card__info", children: [jsxRuntimeExports.jsx("h4", { className: "ai-chat-contact-card__name", children: contact.name }), settings.showRole !== false && contact.role && (jsxRuntimeExports.jsx("p", { className: "ai-chat-contact-card__role", children: contact.role })), jsxRuntimeExports.jsxs("div", { className: "ai-chat-contact-card__details", children: [settings.showEmail !== false && contact.email && (jsxRuntimeExports.jsx("a", { href: `mailto:${contact.email}`, className: "ai-chat-contact-card__detail", onClick: onEmail, children: contact.email })), settings.showPhone !== false && contact.phone && (jsxRuntimeExports.jsx("a", { href: `tel:${contact.phone}`, className: "ai-chat-contact-card__detail", onClick: onPhone, children: contact.phone }))] }), settings.showResponsibilities !== false && contact.responsibilities && contact.responsibilities.length > 0 && !compact && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-contact-card__responsibilities", children: [contact.responsibilities.slice(0, 3).map((resp, idx) => (jsxRuntimeExports.jsx("span", { className: "ai-chat-contact-card__responsibility-tag", children: resp }, idx))), contact.responsibilities.length > 3 && (jsxRuntimeExports.jsxs("span", { className: "ai-chat-contact-card__responsibility-more", children: ["+", contact.responsibilities.length - 3, " more"] }))] }))] })] }));
|
|
44931
|
+
}
|
|
44932
|
+
function ContactCard({ action, onComplete, accentColor, maxColumns = 3 }) {
|
|
44933
|
+
const rawState = action.state;
|
|
44934
|
+
const hasCompletedRef = reactExports.useRef(false);
|
|
44935
|
+
const state = {
|
|
44936
|
+
contacts: rawState?.contacts || [],
|
|
44937
|
+
settings: rawState?.settings || {},
|
|
44938
|
+
query: rawState?.query,
|
|
44939
|
+
status: rawState?.status || 'displaying',
|
|
44940
|
+
};
|
|
44941
|
+
const { contacts, settings } = state;
|
|
44942
|
+
const isSingleContact = contacts.length === 1;
|
|
44943
|
+
const stackColumns = Math.min(Math.max(contacts.length, 1), maxColumns);
|
|
44944
|
+
reactExports.useEffect(() => {
|
|
44945
|
+
if (!action.done && !hasCompletedRef.current && onComplete) {
|
|
44946
|
+
hasCompletedRef.current = true;
|
|
44947
|
+
onComplete(action.toolCallId, { ...state, status: 'displaying' });
|
|
44948
|
+
}
|
|
44949
|
+
}, [action.done, action.toolCallId, onComplete, state]);
|
|
44950
|
+
const handleContact = () => {
|
|
44951
|
+
onComplete?.(action.toolCallId, { ...state, status: 'contacted' });
|
|
44952
|
+
};
|
|
44953
|
+
if (contacts.length === 0) {
|
|
44954
|
+
return (jsxRuntimeExports.jsxs("div", { className: "ai-chat-contact-card ai-chat-contact-card--empty", children: [jsxRuntimeExports.jsx("div", { className: "ai-chat-contact-card__empty-icon", children: jsxRuntimeExports.jsx(UsersIcon, {}) }), jsxRuntimeExports.jsxs("p", { className: "ai-chat-contact-card__empty-text", children: ["No contacts found", state.query ? ` for "${state.query}"` : ''] })] }));
|
|
44955
|
+
}
|
|
44956
|
+
if (isSingleContact) {
|
|
44957
|
+
return (jsxRuntimeExports.jsx(ContactItem, { contact: contacts[0], settings: settings, accentColor: accentColor, onEmail: handleContact, onPhone: handleContact, layout: settings.layout || 'horizontal' }));
|
|
44958
|
+
}
|
|
44959
|
+
const isWidget = maxColumns === 1;
|
|
44960
|
+
const stackClassName = isWidget
|
|
44961
|
+
? 'ai-chat-contact-card-list__stack ai-chat-contact-card-list__stack--widget'
|
|
44962
|
+
: 'ai-chat-contact-card-list__stack';
|
|
44963
|
+
return (jsxRuntimeExports.jsxs("div", { className: "ai-chat-contact-card-list", style: { containerType: 'inline-size' }, children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-contact-card-list__header", children: [jsxRuntimeExports.jsx(UsersIcon, {}), jsxRuntimeExports.jsxs("span", { children: [contacts.length, " Contacts"] })] }), jsxRuntimeExports.jsx("div", { className: stackClassName, style: isWidget ? undefined : {
|
|
44423
44964
|
gridTemplateColumns: `repeat(${stackColumns}, minmax(0, 1fr))`,
|
|
44424
|
-
}, children:
|
|
44965
|
+
}, children: contacts.map((contact) => (jsxRuntimeExports.jsx(ContactItem, { contact: contact, settings: settings, accentColor: accentColor, onEmail: handleContact, onPhone: handleContact, compact: true, layout: settings.layout || 'vertical' }, contact.id))) })] }));
|
|
44966
|
+
}
|
|
44967
|
+
|
|
44968
|
+
function FormCard({ action, onComplete, accentColor }) {
|
|
44969
|
+
const state = action.state;
|
|
44970
|
+
const [currentStep, setCurrentStep] = reactExports.useState(0);
|
|
44971
|
+
const [answers, setAnswers] = reactExports.useState({});
|
|
44972
|
+
const [isSubmitting, setIsSubmitting] = reactExports.useState(false);
|
|
44973
|
+
const questions = state.questions || [];
|
|
44974
|
+
const currentQuestion = questions[currentStep];
|
|
44975
|
+
const totalQuestions = questions.length;
|
|
44976
|
+
const handleAnswerChange = (questionId, value) => {
|
|
44977
|
+
setAnswers((prev) => ({ ...prev, [questionId]: value }));
|
|
44978
|
+
};
|
|
44979
|
+
const handleNext = () => {
|
|
44980
|
+
if (currentStep < totalQuestions - 1) {
|
|
44981
|
+
setCurrentStep((prev) => prev + 1);
|
|
44982
|
+
}
|
|
44983
|
+
};
|
|
44984
|
+
const handlePrev = () => {
|
|
44985
|
+
if (currentStep > 0) {
|
|
44986
|
+
setCurrentStep((prev) => prev - 1);
|
|
44987
|
+
}
|
|
44988
|
+
};
|
|
44989
|
+
const handleSubmit = () => {
|
|
44990
|
+
if (!onComplete)
|
|
44991
|
+
return;
|
|
44992
|
+
setIsSubmitting(true);
|
|
44993
|
+
const formattedAnswers = Object.entries(answers).map(([questionId, value]) => ({
|
|
44994
|
+
questionId,
|
|
44995
|
+
value,
|
|
44996
|
+
}));
|
|
44997
|
+
onComplete(action.toolCallId, {
|
|
44998
|
+
...state,
|
|
44999
|
+
status: 'submitted',
|
|
45000
|
+
answers: formattedAnswers,
|
|
45001
|
+
});
|
|
45002
|
+
};
|
|
45003
|
+
const handleSkip = () => {
|
|
45004
|
+
if (!onComplete || !state.settings.allowSkip)
|
|
45005
|
+
return;
|
|
45006
|
+
onComplete(action.toolCallId, {
|
|
45007
|
+
...state,
|
|
45008
|
+
status: 'skipped',
|
|
45009
|
+
});
|
|
45010
|
+
};
|
|
45011
|
+
const isCurrentAnswered = () => {
|
|
45012
|
+
if (!currentQuestion)
|
|
45013
|
+
return false;
|
|
45014
|
+
const answer = answers[currentQuestion.id];
|
|
45015
|
+
if (!answer)
|
|
45016
|
+
return !currentQuestion.required;
|
|
45017
|
+
if (Array.isArray(answer))
|
|
45018
|
+
return answer.length > 0 || !currentQuestion.required;
|
|
45019
|
+
return answer.trim() !== '' || !currentQuestion.required;
|
|
45020
|
+
};
|
|
45021
|
+
const canSubmit = () => {
|
|
45022
|
+
return questions.every((q) => {
|
|
45023
|
+
const answer = answers[q.id];
|
|
45024
|
+
if (!q.required)
|
|
45025
|
+
return true;
|
|
45026
|
+
if (!answer)
|
|
45027
|
+
return false;
|
|
45028
|
+
if (Array.isArray(answer))
|
|
45029
|
+
return answer.length > 0;
|
|
45030
|
+
return answer.trim() !== '';
|
|
45031
|
+
});
|
|
45032
|
+
};
|
|
45033
|
+
// Error state
|
|
45034
|
+
if (state.status === 'error') {
|
|
45035
|
+
return (jsxRuntimeExports.jsxs("div", { className: "ai-chat-form-card ai-chat-form-card--error", children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-form-card__header", children: [jsxRuntimeExports.jsx("span", { className: "ai-chat-form-card__icon", children: "\u26A0\uFE0F" }), jsxRuntimeExports.jsx("span", { className: "ai-chat-form-card__title", children: "Form Error" })] }), jsxRuntimeExports.jsx("p", { className: "ai-chat-form-card__error", children: state.error || 'Could not load form' })] }));
|
|
45036
|
+
}
|
|
45037
|
+
// Submitted state
|
|
45038
|
+
if (state.status === 'submitted' || action.done) {
|
|
45039
|
+
return (jsxRuntimeExports.jsxs("div", { className: "ai-chat-form-card ai-chat-form-card--submitted", children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-form-card__header", children: [jsxRuntimeExports.jsx("span", { className: "ai-chat-form-card__icon", children: "\u2713" }), jsxRuntimeExports.jsx("span", { className: "ai-chat-form-card__title", children: state.title })] }), jsxRuntimeExports.jsx("p", { className: "ai-chat-form-card__success", children: state.settings.successMessage || 'Thank you for your response!' })] }));
|
|
45040
|
+
}
|
|
45041
|
+
// Skipped state
|
|
45042
|
+
if (state.status === 'skipped') {
|
|
45043
|
+
return (jsxRuntimeExports.jsxs("div", { className: "ai-chat-form-card ai-chat-form-card--skipped", children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-form-card__header", children: [jsxRuntimeExports.jsx("span", { className: "ai-chat-form-card__icon", children: "\u21B7" }), jsxRuntimeExports.jsx("span", { className: "ai-chat-form-card__title", children: state.title })] }), jsxRuntimeExports.jsx("p", { className: "ai-chat-form-card__skipped-text", children: "Form skipped" })] }));
|
|
45044
|
+
}
|
|
45045
|
+
// No questions
|
|
45046
|
+
if (totalQuestions === 0) {
|
|
45047
|
+
return (jsxRuntimeExports.jsxs("div", { className: "ai-chat-form-card ai-chat-form-card--empty", children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-form-card__header", children: [jsxRuntimeExports.jsx("span", { className: "ai-chat-form-card__icon", children: "\uD83D\uDCCB" }), jsxRuntimeExports.jsx("span", { className: "ai-chat-form-card__title", children: state.title })] }), jsxRuntimeExports.jsx("p", { className: "ai-chat-form-card__empty-text", children: "This form has no questions." })] }));
|
|
45048
|
+
}
|
|
45049
|
+
return (jsxRuntimeExports.jsxs("div", { className: "ai-chat-form-card", children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-form-card__header", children: [jsxRuntimeExports.jsx("span", { className: "ai-chat-form-card__icon", children: "\uD83D\uDCCB" }), jsxRuntimeExports.jsx("span", { className: "ai-chat-form-card__title", children: state.title })] }), state.description && (jsxRuntimeExports.jsx("p", { className: "ai-chat-form-card__description", children: state.description })), state.context && (jsxRuntimeExports.jsx("p", { className: "ai-chat-form-card__context", children: state.context })), state.settings.showProgress && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-form-card__progress", children: [jsxRuntimeExports.jsx("div", { className: "ai-chat-form-card__progress-bar", style: {
|
|
45050
|
+
width: `${((currentStep + 1) / totalQuestions) * 100}%`,
|
|
45051
|
+
backgroundColor: accentColor || 'var(--ai-chat-accent-color, #3b82f6)',
|
|
45052
|
+
} }), jsxRuntimeExports.jsxs("span", { className: "ai-chat-form-card__progress-text", children: [currentStep + 1, " of ", totalQuestions] })] })), jsxRuntimeExports.jsxs("div", { className: "ai-chat-form-card__question", children: [jsxRuntimeExports.jsxs("p", { className: "ai-chat-form-card__question-text", children: [currentQuestion.text, currentQuestion.required && jsxRuntimeExports.jsx("span", { className: "ai-chat-form-card__required", children: "*" })] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-form-card__answer", children: [currentQuestion.type === 'text' && (jsxRuntimeExports.jsx("textarea", { className: "ai-chat-form-card__textarea", placeholder: currentQuestion.placeholder || 'Type your answer...', value: answers[currentQuestion.id] || '', onChange: (e) => handleAnswerChange(currentQuestion.id, e.target.value), rows: 3 })), currentQuestion.type === 'single_choice' && currentQuestion.options && (jsxRuntimeExports.jsx("div", { className: "ai-chat-form-card__options", children: currentQuestion.options.map((option) => (jsxRuntimeExports.jsxs("label", { className: "ai-chat-form-card__option", children: [jsxRuntimeExports.jsx("input", { type: "radio", name: currentQuestion.id, value: option.value, checked: answers[currentQuestion.id] === option.value, onChange: () => handleAnswerChange(currentQuestion.id, option.value) }), jsxRuntimeExports.jsx("span", { className: "ai-chat-form-card__option-text", children: option.text })] }, option.id))) })), currentQuestion.type === 'multiple_choice' && currentQuestion.options && (jsxRuntimeExports.jsx("div", { className: "ai-chat-form-card__options", children: currentQuestion.options.map((option) => {
|
|
45053
|
+
const currentAnswers = answers[currentQuestion.id] || [];
|
|
45054
|
+
const isChecked = currentAnswers.includes(option.value);
|
|
45055
|
+
return (jsxRuntimeExports.jsxs("label", { className: "ai-chat-form-card__option", children: [jsxRuntimeExports.jsx("input", { type: "checkbox", value: option.value, checked: isChecked, onChange: () => {
|
|
45056
|
+
const newAnswers = isChecked
|
|
45057
|
+
? currentAnswers.filter((v) => v !== option.value)
|
|
45058
|
+
: [...currentAnswers, option.value];
|
|
45059
|
+
handleAnswerChange(currentQuestion.id, newAnswers);
|
|
45060
|
+
} }), jsxRuntimeExports.jsx("span", { className: "ai-chat-form-card__option-text", children: option.text })] }, option.id));
|
|
45061
|
+
}) })), currentQuestion.type === 'rating' && (jsxRuntimeExports.jsx("div", { className: "ai-chat-form-card__rating", children: Array.from({ length: (currentQuestion.maxRating || 5) - (currentQuestion.minRating || 1) + 1 }, (_, i) => (currentQuestion.minRating || 1) + i).map((rating) => (jsxRuntimeExports.jsx("button", { type: "button", className: `ai-chat-form-card__rating-btn ${answers[currentQuestion.id] === String(rating) ? 'ai-chat-form-card__rating-btn--selected' : ''}`, onClick: () => handleAnswerChange(currentQuestion.id, String(rating)), style: {
|
|
45062
|
+
borderColor: answers[currentQuestion.id] === String(rating)
|
|
45063
|
+
? (accentColor || 'var(--ai-chat-accent-color, #3b82f6)')
|
|
45064
|
+
: undefined,
|
|
45065
|
+
backgroundColor: answers[currentQuestion.id] === String(rating)
|
|
45066
|
+
? (accentColor || 'var(--ai-chat-accent-color, #3b82f6)')
|
|
45067
|
+
: undefined,
|
|
45068
|
+
}, children: rating }, rating))) }))] })] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-form-card__actions", children: [currentStep > 0 && (jsxRuntimeExports.jsx("button", { type: "button", className: "ai-chat-form-card__btn ai-chat-form-card__btn--secondary", onClick: handlePrev, children: "Back" })), state.settings.allowSkip && currentStep === 0 && (jsxRuntimeExports.jsx("button", { type: "button", className: "ai-chat-form-card__btn ai-chat-form-card__btn--ghost", onClick: handleSkip, children: "Skip" })), jsxRuntimeExports.jsx("div", { className: "ai-chat-form-card__actions-spacer" }), currentStep < totalQuestions - 1 ? (jsxRuntimeExports.jsx("button", { type: "button", className: "ai-chat-form-card__btn ai-chat-form-card__btn--primary", onClick: handleNext, disabled: !isCurrentAnswered(), style: {
|
|
45069
|
+
backgroundColor: accentColor || 'var(--ai-chat-accent-color, #3b82f6)',
|
|
45070
|
+
}, children: "Next" })) : (jsxRuntimeExports.jsx("button", { type: "button", className: "ai-chat-form-card__btn ai-chat-form-card__btn--primary", onClick: handleSubmit, disabled: !canSubmit() || isSubmitting, style: {
|
|
45071
|
+
backgroundColor: accentColor || 'var(--ai-chat-accent-color, #3b82f6)',
|
|
45072
|
+
}, children: isSubmitting ? 'Submitting...' : (state.settings.submitButtonText || 'Submit') }))] })] }));
|
|
44425
45073
|
}
|
|
44426
45074
|
|
|
44427
45075
|
const pendingResolvers = new Map();
|
|
@@ -44434,12 +45082,6 @@
|
|
|
44434
45082
|
function getActionRenderer(implementation) {
|
|
44435
45083
|
return actionRenderers[implementation];
|
|
44436
45084
|
}
|
|
44437
|
-
function getActionPrompt(implementation) {
|
|
44438
|
-
if (implementation === "google-calendar-appointment") {
|
|
44439
|
-
return "Select a date to continue.";
|
|
44440
|
-
}
|
|
44441
|
-
return "Action input required.";
|
|
44442
|
-
}
|
|
44443
45085
|
function waitForActionState(toolCallId) {
|
|
44444
45086
|
return new Promise((resolve) => {
|
|
44445
45087
|
pendingResolvers.set(toolCallId, resolve);
|
|
@@ -44480,7 +45122,7 @@
|
|
|
44480
45122
|
// Register the handler
|
|
44481
45123
|
registerGoogleCalendarHandler();
|
|
44482
45124
|
// Register the renderer
|
|
44483
|
-
actionRenderers["google-calendar-appointment"] = (message) => {
|
|
45125
|
+
actionRenderers["google-calendar-appointment"] = (message, accentColor) => {
|
|
44484
45126
|
const action = message.action;
|
|
44485
45127
|
if (!action)
|
|
44486
45128
|
return null;
|
|
@@ -44494,22 +45136,54 @@
|
|
|
44494
45136
|
input: action.input,
|
|
44495
45137
|
state: action.state,
|
|
44496
45138
|
done: action.done ?? false,
|
|
44497
|
-
}, onComplete: handleComplete }));
|
|
45139
|
+
}, onComplete: handleComplete, accentColor: accentColor }));
|
|
45140
|
+
};
|
|
45141
|
+
}
|
|
45142
|
+
|
|
45143
|
+
function registerMicrosoftCalendarHandler() {
|
|
45144
|
+
frontendActionHandlers["microsoft-calendar-appointment"] = async (_input, _state, context) => {
|
|
45145
|
+
return waitForActionState(context.toolCallId);
|
|
44498
45146
|
};
|
|
44499
45147
|
}
|
|
44500
45148
|
|
|
44501
45149
|
/**
|
|
44502
|
-
* Register
|
|
45150
|
+
* Register microsoft-calendar-appointment action handler and renderer.
|
|
44503
45151
|
* Called by initializeActionHandlers to prevent tree-shaking.
|
|
44504
45152
|
*/
|
|
44505
|
-
function
|
|
44506
|
-
//
|
|
44507
|
-
|
|
44508
|
-
|
|
44509
|
-
|
|
44510
|
-
|
|
44511
|
-
|
|
44512
|
-
|
|
45153
|
+
function registerMicrosoftCalendarAction() {
|
|
45154
|
+
// Register the handler
|
|
45155
|
+
registerMicrosoftCalendarHandler();
|
|
45156
|
+
// Register the renderer
|
|
45157
|
+
actionRenderers["microsoft-calendar-appointment"] = (message, accentColor) => {
|
|
45158
|
+
const action = message.action;
|
|
45159
|
+
if (!action)
|
|
45160
|
+
return null;
|
|
45161
|
+
const handleComplete = (toolCallId, newState) => {
|
|
45162
|
+
resolveActionState(toolCallId, newState);
|
|
45163
|
+
};
|
|
45164
|
+
return (jsxRuntimeExports.jsx(MicrosoftCalendarCard, { action: {
|
|
45165
|
+
implementation: action.implementation,
|
|
45166
|
+
toolCallId: action.toolCallId,
|
|
45167
|
+
actionId: action.actionId,
|
|
45168
|
+
input: action.input,
|
|
45169
|
+
state: action.state,
|
|
45170
|
+
done: action.done ?? false,
|
|
45171
|
+
}, onComplete: handleComplete, accentColor: accentColor }));
|
|
45172
|
+
};
|
|
45173
|
+
}
|
|
45174
|
+
|
|
45175
|
+
/**
|
|
45176
|
+
* Register link-preview action handler and renderer.
|
|
45177
|
+
* Called by initializeActionHandlers to prevent tree-shaking.
|
|
45178
|
+
*/
|
|
45179
|
+
function registerLinkPreviewAction() {
|
|
45180
|
+
// Handler - auto-completes immediately since no user input is needed
|
|
45181
|
+
frontendActionHandlers["link-preview"] = async (_input, state, _context) => {
|
|
45182
|
+
return { ...state, status: "displaying" };
|
|
45183
|
+
};
|
|
45184
|
+
// Renderer - displays the link preview card
|
|
45185
|
+
actionRenderers["link-preview"] = (message, accentColor) => {
|
|
45186
|
+
const action = message.action;
|
|
44513
45187
|
if (!action)
|
|
44514
45188
|
return null;
|
|
44515
45189
|
const handleComplete = (toolCallId, newState) => {
|
|
@@ -44526,7 +45200,7 @@
|
|
|
44526
45200
|
input: action.input,
|
|
44527
45201
|
state: action.state,
|
|
44528
45202
|
done: isDone,
|
|
44529
|
-
}, onComplete: handleComplete }));
|
|
45203
|
+
}, onComplete: handleComplete, accentColor: accentColor }));
|
|
44530
45204
|
};
|
|
44531
45205
|
}
|
|
44532
45206
|
|
|
@@ -44540,7 +45214,7 @@
|
|
|
44540
45214
|
return { ...state, status: "displaying" };
|
|
44541
45215
|
};
|
|
44542
45216
|
// Renderer - displays the embedded video player card
|
|
44543
|
-
actionRenderers["video-player"] = (message) => {
|
|
45217
|
+
actionRenderers["video-player"] = (message, accentColor) => {
|
|
44544
45218
|
const action = message.action;
|
|
44545
45219
|
if (!action)
|
|
44546
45220
|
return null;
|
|
@@ -44558,7 +45232,7 @@
|
|
|
44558
45232
|
input: action.input,
|
|
44559
45233
|
state: action.state,
|
|
44560
45234
|
done: isDone,
|
|
44561
|
-
}, onComplete: handleComplete }));
|
|
45235
|
+
}, onComplete: handleComplete, accentColor: accentColor }));
|
|
44562
45236
|
};
|
|
44563
45237
|
}
|
|
44564
45238
|
|
|
@@ -44572,7 +45246,7 @@
|
|
|
44572
45246
|
return { ...state, status: "displaying" };
|
|
44573
45247
|
};
|
|
44574
45248
|
// Renderer - displays the location card
|
|
44575
|
-
actionRenderers["location-card"] = (message, accentColor) => {
|
|
45249
|
+
actionRenderers["location-card"] = (message, accentColor, variant) => {
|
|
44576
45250
|
const action = message.action;
|
|
44577
45251
|
if (!action)
|
|
44578
45252
|
return null;
|
|
@@ -44590,7 +45264,92 @@
|
|
|
44590
45264
|
input: action.input,
|
|
44591
45265
|
state: action.state,
|
|
44592
45266
|
done: isDone,
|
|
44593
|
-
}, onComplete: handleComplete, accentColor: accentColor, maxColumns: 1 }));
|
|
45267
|
+
}, onComplete: handleComplete, accentColor: accentColor, maxColumns: variant === 'fullpage' ? 3 : 1 }));
|
|
45268
|
+
};
|
|
45269
|
+
}
|
|
45270
|
+
|
|
45271
|
+
function registerContactCardAction() {
|
|
45272
|
+
// Handler - auto-completes immediately since no user input is needed
|
|
45273
|
+
frontendActionHandlers['contact-card'] = async (_input, state, _context) => {
|
|
45274
|
+
return { ...state, status: 'displaying' };
|
|
45275
|
+
};
|
|
45276
|
+
// Renderer - displays the contact card
|
|
45277
|
+
actionRenderers['contact-card'] = (message, accentColor, variant) => {
|
|
45278
|
+
const action = message.action;
|
|
45279
|
+
if (!action)
|
|
45280
|
+
return null;
|
|
45281
|
+
const handleComplete = (toolCallId, newState) => {
|
|
45282
|
+
resolveActionState(toolCallId, newState);
|
|
45283
|
+
};
|
|
45284
|
+
// Check if action state indicates it's already complete
|
|
45285
|
+
const state = action.state;
|
|
45286
|
+
const status = state?.status;
|
|
45287
|
+
const isDone = action.done || status === 'displaying' || status === 'contacted';
|
|
45288
|
+
return (jsxRuntimeExports.jsx(ContactCard, { action: {
|
|
45289
|
+
implementation: action.implementation,
|
|
45290
|
+
toolCallId: action.toolCallId,
|
|
45291
|
+
actionId: action.actionId,
|
|
45292
|
+
input: action.input,
|
|
45293
|
+
state: action.state,
|
|
45294
|
+
done: isDone,
|
|
45295
|
+
}, onComplete: handleComplete, accentColor: accentColor, maxColumns: variant === 'fullpage' ? 3 : 1 }));
|
|
45296
|
+
};
|
|
45297
|
+
}
|
|
45298
|
+
|
|
45299
|
+
function registerQueryContactDirectoryAction() {
|
|
45300
|
+
// Handler - auto-completes immediately since no user input is needed
|
|
45301
|
+
frontendActionHandlers['query-contact-directory'] = async (_input, state, _context) => {
|
|
45302
|
+
return { ...state, status: 'displaying' };
|
|
45303
|
+
};
|
|
45304
|
+
// Renderer - displays the contact card with search results
|
|
45305
|
+
actionRenderers['query-contact-directory'] = (message, accentColor, variant) => {
|
|
45306
|
+
const action = message.action;
|
|
45307
|
+
if (!action)
|
|
45308
|
+
return null;
|
|
45309
|
+
// Handle completion - triggers agent to continue with text response
|
|
45310
|
+
const handleComplete = (toolCallId, newState) => {
|
|
45311
|
+
resolveActionState(toolCallId, newState);
|
|
45312
|
+
};
|
|
45313
|
+
// Check if action state indicates it's already complete
|
|
45314
|
+
const state = action.state;
|
|
45315
|
+
const status = state?.status;
|
|
45316
|
+
const isDone = action.done || status === 'displaying' || status === 'contacted';
|
|
45317
|
+
return (jsxRuntimeExports.jsx(ContactCard, { action: {
|
|
45318
|
+
implementation: action.implementation,
|
|
45319
|
+
toolCallId: action.toolCallId,
|
|
45320
|
+
actionId: action.actionId,
|
|
45321
|
+
input: action.input,
|
|
45322
|
+
state: action.state,
|
|
45323
|
+
done: isDone,
|
|
45324
|
+
}, onComplete: handleComplete, accentColor: accentColor, maxColumns: variant === 'fullpage' ? 3 : 1 }));
|
|
45325
|
+
};
|
|
45326
|
+
}
|
|
45327
|
+
|
|
45328
|
+
function registerDisplayFormAction() {
|
|
45329
|
+
// Handler - handles form submission and state updates
|
|
45330
|
+
frontendActionHandlers['display-form'] = async (_input, _state, context) => {
|
|
45331
|
+
return waitForActionState(context.toolCallId);
|
|
45332
|
+
};
|
|
45333
|
+
// Renderer - displays the form card
|
|
45334
|
+
actionRenderers['display-form'] = (message, accentColor, variant) => {
|
|
45335
|
+
const action = message.action;
|
|
45336
|
+
if (!action)
|
|
45337
|
+
return null;
|
|
45338
|
+
const handleComplete = (toolCallId, newState) => {
|
|
45339
|
+
resolveActionState(toolCallId, newState);
|
|
45340
|
+
};
|
|
45341
|
+
// Check if action state indicates it's already complete
|
|
45342
|
+
const state = action.state;
|
|
45343
|
+
const status = state?.status;
|
|
45344
|
+
const isDone = action.done || status === 'completed' || status === 'submitted';
|
|
45345
|
+
return (jsxRuntimeExports.jsx(FormCard, { action: {
|
|
45346
|
+
implementation: action.implementation,
|
|
45347
|
+
toolCallId: action.toolCallId,
|
|
45348
|
+
actionId: action.actionId,
|
|
45349
|
+
input: action.input,
|
|
45350
|
+
state: action.state,
|
|
45351
|
+
done: isDone,
|
|
45352
|
+
}, onComplete: handleComplete, accentColor: accentColor }));
|
|
44594
45353
|
};
|
|
44595
45354
|
}
|
|
44596
45355
|
|
|
@@ -44607,9 +45366,13 @@
|
|
|
44607
45366
|
initialized = true;
|
|
44608
45367
|
// Explicitly call each registration function to prevent tree-shaking
|
|
44609
45368
|
registerGoogleCalendarAction();
|
|
45369
|
+
registerMicrosoftCalendarAction();
|
|
44610
45370
|
registerLinkPreviewAction();
|
|
44611
45371
|
registerVideoPlayerAction();
|
|
44612
45372
|
registerLocationCardAction();
|
|
45373
|
+
registerQueryContactDirectoryAction();
|
|
45374
|
+
registerContactCardAction();
|
|
45375
|
+
registerDisplayFormAction();
|
|
44613
45376
|
}
|
|
44614
45377
|
|
|
44615
45378
|
/**
|
|
@@ -44829,12 +45592,6 @@
|
|
|
44829
45592
|
}
|
|
44830
45593
|
}
|
|
44831
45594
|
|
|
44832
|
-
/**
|
|
44833
|
-
* useChat Hook
|
|
44834
|
-
* Main state management for chat functionality
|
|
44835
|
-
*/
|
|
44836
|
-
// Initialize action handlers immediately to prevent tree-shaking
|
|
44837
|
-
initializeActionHandlers();
|
|
44838
45595
|
function hydrateToolNames(messages) {
|
|
44839
45596
|
const toolCallNameById = new Map();
|
|
44840
45597
|
for (const entry of messages) {
|
|
@@ -44878,118 +45635,77 @@
|
|
|
44878
45635
|
};
|
|
44879
45636
|
});
|
|
44880
45637
|
}
|
|
44881
|
-
function
|
|
44882
|
-
return messages
|
|
44883
|
-
if (entry.message.role !== "assistant" || !entry.action) {
|
|
44884
|
-
return entry;
|
|
44885
|
-
}
|
|
44886
|
-
const content = typeof entry.message.content === "string" ? entry.message.content : "";
|
|
44887
|
-
if (content.trim().length > 0) {
|
|
44888
|
-
return entry;
|
|
44889
|
-
}
|
|
44890
|
-
return {
|
|
44891
|
-
...entry,
|
|
44892
|
-
message: { ...entry.message, content: getActionPrompt(entry.action.implementation) },
|
|
44893
|
-
};
|
|
44894
|
-
});
|
|
45638
|
+
function hydrateMessages(messages) {
|
|
45639
|
+
return hydrateToolNames(messages);
|
|
44895
45640
|
}
|
|
44896
|
-
|
|
44897
|
-
|
|
44898
|
-
|
|
44899
|
-
|
|
44900
|
-
|
|
44901
|
-
|
|
44902
|
-
|
|
44903
|
-
|
|
45641
|
+
|
|
45642
|
+
function deriveErrorInfo(error) {
|
|
45643
|
+
if (error instanceof ApiError) {
|
|
45644
|
+
const retryAfterSeconds = typeof error.retryAfterMs === 'number'
|
|
45645
|
+
? Math.max(1, Math.ceil(error.retryAfterMs / 1000))
|
|
45646
|
+
: undefined;
|
|
45647
|
+
const lowerMessage = (error.message || '').toLowerCase();
|
|
45648
|
+
let message;
|
|
45649
|
+
switch (error.status) {
|
|
45650
|
+
case 429: {
|
|
45651
|
+
const isPerUser = lowerMessage.includes('user');
|
|
45652
|
+
const base = isPerUser
|
|
45653
|
+
? 'You have reached the per-user rate limit.'
|
|
45654
|
+
: 'This widget has received too many requests.';
|
|
45655
|
+
if (retryAfterSeconds) {
|
|
45656
|
+
message = `${base} Please wait ${retryAfterSeconds} second${retryAfterSeconds === 1 ? '' : 's'} before trying again.`;
|
|
45657
|
+
}
|
|
45658
|
+
else {
|
|
45659
|
+
message = `${base} Please wait a moment and try again.`;
|
|
45660
|
+
}
|
|
45661
|
+
break;
|
|
45662
|
+
}
|
|
45663
|
+
case 401:
|
|
45664
|
+
message = 'Authentication failed. Please refresh the page or verify your API key.';
|
|
45665
|
+
break;
|
|
45666
|
+
case 403:
|
|
45667
|
+
message = 'Access to this widget is restricted. Please contact the site owner if you believe this is an error.';
|
|
45668
|
+
break;
|
|
45669
|
+
case 404:
|
|
45670
|
+
if (lowerMessage.includes('not active')) {
|
|
45671
|
+
message = 'This widget is currently inactive. Please contact the site owner.';
|
|
45672
|
+
}
|
|
45673
|
+
else {
|
|
45674
|
+
message = 'We could not find this widget. It may have been removed.';
|
|
45675
|
+
}
|
|
45676
|
+
break;
|
|
45677
|
+
default:
|
|
45678
|
+
if (error.status >= 500) {
|
|
45679
|
+
message = 'The server encountered an error. Please try again shortly.';
|
|
45680
|
+
}
|
|
45681
|
+
else if (error.status > 0) {
|
|
45682
|
+
message = error.message || 'Something went wrong. Please try again.';
|
|
45683
|
+
}
|
|
45684
|
+
else {
|
|
45685
|
+
message = error.message || 'Unable to connect to the server. Please check your internet connection.';
|
|
45686
|
+
}
|
|
44904
45687
|
}
|
|
44905
|
-
|
|
44906
|
-
|
|
44907
|
-
|
|
44908
|
-
|
|
45688
|
+
return { message, retryAfterSeconds, status: error.status };
|
|
45689
|
+
}
|
|
45690
|
+
if (error instanceof Error) {
|
|
45691
|
+
const lower = error.message.toLowerCase();
|
|
45692
|
+
if (lower.includes('network')) {
|
|
45693
|
+
return { message: 'Unable to connect to the server. Please check your internet connection.' };
|
|
44909
45694
|
}
|
|
44910
|
-
|
|
44911
|
-
|
|
44912
|
-
const status = state.status;
|
|
44913
|
-
if (status === "displaying" || status === "clicked") {
|
|
44914
|
-
return {
|
|
44915
|
-
...entry,
|
|
44916
|
-
action: { ...entry.action, done: true },
|
|
44917
|
-
};
|
|
44918
|
-
}
|
|
45695
|
+
if (lower.includes('timeout')) {
|
|
45696
|
+
return { message: 'The request timed out. Please try again.' };
|
|
44919
45697
|
}
|
|
44920
|
-
|
|
44921
|
-
|
|
44922
|
-
const status = state.status;
|
|
44923
|
-
if (status === "booked" || status === "cancelled" || status === "error") {
|
|
44924
|
-
return {
|
|
44925
|
-
...entry,
|
|
44926
|
-
action: { ...entry.action, done: true },
|
|
44927
|
-
};
|
|
44928
|
-
}
|
|
45698
|
+
if (lower.includes('unauthorized') || lower.includes('401')) {
|
|
45699
|
+
return { message: 'Authentication failed. Please refresh the page or verify your API key.' };
|
|
44929
45700
|
}
|
|
44930
|
-
|
|
44931
|
-
|
|
44932
|
-
}
|
|
44933
|
-
function hydrateMessages(messages) {
|
|
44934
|
-
return hydrateActionDoneStatus(hydrateActionContent(hydrateToolNames(messages)));
|
|
44935
|
-
}
|
|
44936
|
-
function setupActionResumeCallbacks(messages, client, conversationId, setState, onMessageUpdate) {
|
|
44937
|
-
// Find all incomplete actions and register resume callbacks
|
|
44938
|
-
for (const message of messages) {
|
|
44939
|
-
if (message.action && !message.action.done) {
|
|
44940
|
-
const toolCallId = message.action.toolCallId;
|
|
44941
|
-
const toolName = message.message.name || message.toolExecuting || "tool";
|
|
44942
|
-
registerActionResumeCallback(toolCallId, async (newState) => {
|
|
44943
|
-
// When user interacts with the action after reload, continue the stream
|
|
44944
|
-
try {
|
|
44945
|
-
// Update the action message with the new state
|
|
44946
|
-
setState(prev => ({
|
|
44947
|
-
...prev,
|
|
44948
|
-
messages: prev.messages.map(m => m.action?.toolCallId === toolCallId
|
|
44949
|
-
? {
|
|
44950
|
-
...m,
|
|
44951
|
-
action: m.action ? { ...m.action, state: newState } : undefined,
|
|
44952
|
-
}
|
|
44953
|
-
: m),
|
|
44954
|
-
isTyping: true,
|
|
44955
|
-
}));
|
|
44956
|
-
const streamState = createStreamState();
|
|
44957
|
-
// Continue the agent stream with the new state
|
|
44958
|
-
for await (const event of client.continueAgentMessageStream(conversationId, toolCallId, newState)) {
|
|
44959
|
-
if (event.type === "done") {
|
|
44960
|
-
finalizeToolMessage(streamState, setState, toolCallId, toolName);
|
|
44961
|
-
streamState.sources = event.sources;
|
|
44962
|
-
streamState.toolCallToActionId = event.tool_call_to_action_id;
|
|
44963
|
-
finalizeStreamMessages(setState, streamState.newMessageIds, event.sources, event.tool_call_to_action_id, event.suggestions);
|
|
44964
|
-
continue;
|
|
44965
|
-
}
|
|
44966
|
-
if (event.type === "error") {
|
|
44967
|
-
const errorMessage = {
|
|
44968
|
-
id: generateMessageId(),
|
|
44969
|
-
message: {
|
|
44970
|
-
role: "assistant",
|
|
44971
|
-
content: "Sorry, an error occurred. Please try again later.",
|
|
44972
|
-
},
|
|
44973
|
-
timestamp: new Date().toISOString(),
|
|
44974
|
-
sources: [],
|
|
44975
|
-
isError: true,
|
|
44976
|
-
};
|
|
44977
|
-
upsertMessage(setState, errorMessage, false);
|
|
44978
|
-
setState(prev => ({ ...prev, isTyping: false }));
|
|
44979
|
-
return;
|
|
44980
|
-
}
|
|
44981
|
-
handleStreamEvent(event, streamState, onMessageUpdate, setState);
|
|
44982
|
-
}
|
|
44983
|
-
setState(prev => ({ ...prev, isTyping: false }));
|
|
44984
|
-
}
|
|
44985
|
-
catch (error) {
|
|
44986
|
-
console.error("[Action Resume] Failed to continue stream:", error);
|
|
44987
|
-
setState(prev => ({ ...prev, isTyping: false }));
|
|
44988
|
-
}
|
|
44989
|
-
});
|
|
45701
|
+
if (lower.includes('internal server error') || lower.includes('500')) {
|
|
45702
|
+
return { message: 'The server encountered an error. Please try again shortly.' };
|
|
44990
45703
|
}
|
|
45704
|
+
return { message: error.message || 'Something went wrong. Please try again.' };
|
|
44991
45705
|
}
|
|
45706
|
+
return { message: 'Something went wrong. Please try again.' };
|
|
44992
45707
|
}
|
|
45708
|
+
|
|
44993
45709
|
function createStreamState() {
|
|
44994
45710
|
return {
|
|
44995
45711
|
currentContent: "",
|
|
@@ -44998,6 +45714,7 @@
|
|
|
44998
45714
|
newMessageIds: new Set(),
|
|
44999
45715
|
sources: [],
|
|
45000
45716
|
toolCallToActionId: {},
|
|
45717
|
+
requestId: generateMessageId(),
|
|
45001
45718
|
};
|
|
45002
45719
|
}
|
|
45003
45720
|
function upsertMessage(setState, message, isTyping) {
|
|
@@ -45033,15 +45750,40 @@
|
|
|
45033
45750
|
return msg;
|
|
45034
45751
|
}
|
|
45035
45752
|
// Attach suggestions only to the last assistant message
|
|
45036
|
-
|
|
45037
|
-
|
|
45038
|
-
|
|
45039
|
-
return { ...msg, sources, toolCallToActionId };
|
|
45753
|
+
const withSuggestions = index === lastAssistantIndex && suggestions && suggestions.length > 0
|
|
45754
|
+
? { suggestions }
|
|
45755
|
+
: {};
|
|
45756
|
+
return { ...msg, sources, toolCallToActionId, ...withSuggestions };
|
|
45040
45757
|
}),
|
|
45041
45758
|
isTyping: false,
|
|
45042
45759
|
};
|
|
45043
45760
|
});
|
|
45044
45761
|
}
|
|
45762
|
+
function finalizeToolMessage(streamState, setState, toolCallId, toolName) {
|
|
45763
|
+
setState(prev => {
|
|
45764
|
+
const messages = prev.messages.map((entry) => {
|
|
45765
|
+
const matchesToolCall = entry.message.role === "tool" && entry.message.tool_call_id === toolCallId;
|
|
45766
|
+
if (!matchesToolCall) {
|
|
45767
|
+
return entry;
|
|
45768
|
+
}
|
|
45769
|
+
const existingName = entry.message.name || toolName;
|
|
45770
|
+
return {
|
|
45771
|
+
...entry,
|
|
45772
|
+
message: {
|
|
45773
|
+
role: "tool",
|
|
45774
|
+
content: typeof entry.message.content === "string" ? entry.message.content : "",
|
|
45775
|
+
tool_call_id: toolCallId,
|
|
45776
|
+
name: existingName,
|
|
45777
|
+
},
|
|
45778
|
+
isStreaming: false,
|
|
45779
|
+
toolExecuting: existingName,
|
|
45780
|
+
};
|
|
45781
|
+
});
|
|
45782
|
+
return { ...prev, messages, isTyping: false, isLoading: false };
|
|
45783
|
+
});
|
|
45784
|
+
streamState.activeToolCallCount = Math.max(0, streamState.activeToolCallCount - 1);
|
|
45785
|
+
}
|
|
45786
|
+
|
|
45045
45787
|
function handleContentEvent(event, streamState, onMessageUpdate, setState) {
|
|
45046
45788
|
streamState.currentContent += event.content;
|
|
45047
45789
|
const assistantMessage = {
|
|
@@ -45088,8 +45830,6 @@
|
|
|
45088
45830
|
}
|
|
45089
45831
|
function handleToolEndEvent(event, streamState, _onMessageUpdate, setState) {
|
|
45090
45832
|
streamState.activeToolCallCount = Math.max(0, streamState.activeToolCallCount - 1);
|
|
45091
|
-
// Update state and mark action as done in a single setState call
|
|
45092
|
-
// Keep isTyping: true because the agent may continue generating content after tool completion
|
|
45093
45833
|
setState(prev => {
|
|
45094
45834
|
const messages = prev.messages.map((msg) => {
|
|
45095
45835
|
const matchesToolCall = msg.message.role === "tool" && msg.message.tool_call_id === event.tool_call_id;
|
|
@@ -45097,7 +45837,26 @@
|
|
|
45097
45837
|
return msg;
|
|
45098
45838
|
}
|
|
45099
45839
|
const existingName = msg.message.name || event.tool_name;
|
|
45100
|
-
|
|
45840
|
+
let action = msg.action;
|
|
45841
|
+
if (event.action_id && event.implementation) {
|
|
45842
|
+
action = {
|
|
45843
|
+
implementation: event.implementation,
|
|
45844
|
+
toolCallId: event.tool_call_id,
|
|
45845
|
+
actionId: event.action_id,
|
|
45846
|
+
input: (event.input || {}),
|
|
45847
|
+
state: (event.state || {}),
|
|
45848
|
+
done: event.done,
|
|
45849
|
+
};
|
|
45850
|
+
}
|
|
45851
|
+
else if (action) {
|
|
45852
|
+
action = {
|
|
45853
|
+
...action,
|
|
45854
|
+
input: event.input ? event.input : action.input,
|
|
45855
|
+
state: event.state ? event.state : action.state,
|
|
45856
|
+
done: event.done,
|
|
45857
|
+
};
|
|
45858
|
+
}
|
|
45859
|
+
const updatedMsg = {
|
|
45101
45860
|
...msg,
|
|
45102
45861
|
message: {
|
|
45103
45862
|
role: "tool",
|
|
@@ -45107,14 +45866,10 @@
|
|
|
45107
45866
|
},
|
|
45108
45867
|
isStreaming: false,
|
|
45109
45868
|
toolExecuting: existingName,
|
|
45110
|
-
action
|
|
45111
|
-
...msg.action,
|
|
45112
|
-
state: event.state || msg.action.state,
|
|
45113
|
-
done: true, // Mark action as completed
|
|
45114
|
-
} : undefined,
|
|
45869
|
+
action,
|
|
45115
45870
|
};
|
|
45871
|
+
return updatedMsg;
|
|
45116
45872
|
});
|
|
45117
|
-
// Keep typing indicator visible - it will be hidden by done/finalizeStreamMessages
|
|
45118
45873
|
return { ...prev, messages, isTyping: true, isLoading: false };
|
|
45119
45874
|
});
|
|
45120
45875
|
}
|
|
@@ -45146,34 +45901,6 @@
|
|
|
45146
45901
|
return { ...prev, messages, isTyping: true, isLoading: false };
|
|
45147
45902
|
});
|
|
45148
45903
|
}
|
|
45149
|
-
function finalizeToolMessage(streamState, setState, toolCallId, toolName) {
|
|
45150
|
-
setState(prev => {
|
|
45151
|
-
const messages = prev.messages.map((entry) => {
|
|
45152
|
-
const matchesToolCall = entry.message.role === "tool" && entry.message.tool_call_id === toolCallId;
|
|
45153
|
-
if (!matchesToolCall) {
|
|
45154
|
-
return entry;
|
|
45155
|
-
}
|
|
45156
|
-
const existingName = entry.message.name || toolName;
|
|
45157
|
-
return {
|
|
45158
|
-
...entry,
|
|
45159
|
-
message: {
|
|
45160
|
-
role: "tool",
|
|
45161
|
-
content: typeof entry.message.content === "string" ? entry.message.content : "",
|
|
45162
|
-
tool_call_id: toolCallId,
|
|
45163
|
-
name: existingName,
|
|
45164
|
-
},
|
|
45165
|
-
isStreaming: false,
|
|
45166
|
-
toolExecuting: existingName,
|
|
45167
|
-
action: entry.action ? {
|
|
45168
|
-
...entry.action,
|
|
45169
|
-
done: true, // Mark action as completed
|
|
45170
|
-
} : undefined,
|
|
45171
|
-
};
|
|
45172
|
-
});
|
|
45173
|
-
return { ...prev, messages, isTyping: false, isLoading: false };
|
|
45174
|
-
});
|
|
45175
|
-
streamState.activeToolCallCount = Math.max(0, streamState.activeToolCallCount - 1);
|
|
45176
|
-
}
|
|
45177
45904
|
function handleDoneEvent(event, streamState, _onMessageUpdate, setState) {
|
|
45178
45905
|
streamState.sources = event.sources;
|
|
45179
45906
|
streamState.toolCallToActionId = event.tool_call_to_action_id;
|
|
@@ -45232,6 +45959,7 @@
|
|
|
45232
45959
|
console.warn('[Chat] Unknown event type:', event.type);
|
|
45233
45960
|
}
|
|
45234
45961
|
}
|
|
45962
|
+
|
|
45235
45963
|
async function handleActionLoop(client, initialEvent, streamState, onMessageUpdate, setState, widgetId, conversationId, getMessages) {
|
|
45236
45964
|
let pendingEvent = initialEvent;
|
|
45237
45965
|
while (pendingEvent) {
|
|
@@ -45258,7 +45986,7 @@
|
|
|
45258
45986
|
actionId: pendingEvent.action_id,
|
|
45259
45987
|
input: pendingEvent.input,
|
|
45260
45988
|
state: pendingEvent.state,
|
|
45261
|
-
done: false,
|
|
45989
|
+
done: pendingEvent.done ?? false,
|
|
45262
45990
|
},
|
|
45263
45991
|
};
|
|
45264
45992
|
if (streamState.activeToolCallCount === 0) {
|
|
@@ -45272,7 +46000,7 @@
|
|
|
45272
46000
|
id: generateMessageId(),
|
|
45273
46001
|
message: {
|
|
45274
46002
|
role: "assistant",
|
|
45275
|
-
content: "Sorry, an error occurred.
|
|
46003
|
+
content: "Sorry, an error occurred.",
|
|
45276
46004
|
},
|
|
45277
46005
|
timestamp: new Date().toISOString(),
|
|
45278
46006
|
sources: [],
|
|
@@ -45296,7 +46024,7 @@
|
|
|
45296
46024
|
console.error("[Widget] Frontend action failed:", error);
|
|
45297
46025
|
const errorMessageEntry = {
|
|
45298
46026
|
id: generateMessageId(),
|
|
45299
|
-
message: { role: "assistant", content: "Sorry, an error occurred.
|
|
46027
|
+
message: { role: "assistant", content: "Sorry, an error occurred." },
|
|
45300
46028
|
timestamp: new Date().toISOString(),
|
|
45301
46029
|
sources: [],
|
|
45302
46030
|
isError: true,
|
|
@@ -45308,12 +46036,7 @@
|
|
|
45308
46036
|
pendingEvent = null;
|
|
45309
46037
|
const updatedToolMessage = {
|
|
45310
46038
|
...toolMessage,
|
|
45311
|
-
action: toolMessage.action
|
|
45312
|
-
? {
|
|
45313
|
-
...toolMessage.action,
|
|
45314
|
-
state: nextState,
|
|
45315
|
-
}
|
|
45316
|
-
: undefined,
|
|
46039
|
+
action: toolMessage.action ? { ...toolMessage.action, state: nextState } : toolMessage.action,
|
|
45317
46040
|
};
|
|
45318
46041
|
upsertMessage(setState, updatedToolMessage, true);
|
|
45319
46042
|
let streamEnded = false;
|
|
@@ -45323,22 +46046,20 @@
|
|
|
45323
46046
|
break;
|
|
45324
46047
|
}
|
|
45325
46048
|
if (event.type === "done") {
|
|
45326
|
-
//
|
|
45327
|
-
// updated by tool_end event or by the user's frontend action.
|
|
46049
|
+
// Finalize tool message and stream messages
|
|
45328
46050
|
finalizeToolMessage(streamState, setState, resumeToolCallId, toolName);
|
|
45329
|
-
// Handle the done event but skip the tool finalization part since we already did it
|
|
45330
46051
|
streamState.sources = event.sources;
|
|
45331
46052
|
streamState.toolCallToActionId = event.tool_call_to_action_id;
|
|
45332
46053
|
finalizeStreamMessages(setState, streamState.newMessageIds, event.sources, event.tool_call_to_action_id, event.suggestions);
|
|
45333
46054
|
streamEnded = true;
|
|
45334
|
-
continue;
|
|
46055
|
+
continue;
|
|
45335
46056
|
}
|
|
45336
46057
|
if (event.type === "error") {
|
|
45337
46058
|
const errorMessage = {
|
|
45338
46059
|
id: generateMessageId(),
|
|
45339
46060
|
message: {
|
|
45340
46061
|
role: "assistant",
|
|
45341
|
-
content: "Sorry, an error occurred.
|
|
46062
|
+
content: "Sorry, an error occurred.",
|
|
45342
46063
|
},
|
|
45343
46064
|
timestamp: new Date().toISOString(),
|
|
45344
46065
|
sources: [],
|
|
@@ -45349,73 +46070,79 @@
|
|
|
45349
46070
|
}
|
|
45350
46071
|
handleStreamEvent(event, streamState, onMessageUpdate, setState);
|
|
45351
46072
|
}
|
|
45352
|
-
// If stream ended without a done event
|
|
46073
|
+
// If stream ended without a done event, finalize the tool message
|
|
45353
46074
|
if (!streamEnded && !pendingEvent) {
|
|
45354
46075
|
finalizeToolMessage(streamState, setState, resumeToolCallId, toolName);
|
|
45355
46076
|
}
|
|
45356
46077
|
}
|
|
45357
46078
|
}
|
|
45358
|
-
function
|
|
45359
|
-
|
|
45360
|
-
|
|
45361
|
-
|
|
45362
|
-
|
|
45363
|
-
|
|
45364
|
-
|
|
45365
|
-
|
|
45366
|
-
|
|
45367
|
-
|
|
45368
|
-
|
|
45369
|
-
|
|
45370
|
-
|
|
45371
|
-
|
|
45372
|
-
|
|
45373
|
-
|
|
45374
|
-
|
|
45375
|
-
|
|
45376
|
-
|
|
45377
|
-
|
|
45378
|
-
|
|
45379
|
-
|
|
45380
|
-
|
|
45381
|
-
|
|
45382
|
-
|
|
45383
|
-
|
|
45384
|
-
|
|
45385
|
-
|
|
45386
|
-
|
|
45387
|
-
|
|
45388
|
-
|
|
45389
|
-
|
|
45390
|
-
|
|
45391
|
-
|
|
45392
|
-
|
|
45393
|
-
|
|
46079
|
+
function setupActionResumeCallbacks(messages, client, conversationId, setState, onMessageUpdate, createStreamState, registerCallback) {
|
|
46080
|
+
// Find all incomplete actions and register resume callbacks
|
|
46081
|
+
for (const message of messages) {
|
|
46082
|
+
if (message.action && !message.action.done) {
|
|
46083
|
+
const toolCallId = message.action.toolCallId;
|
|
46084
|
+
const toolName = message.message.name || message.toolExecuting || "tool";
|
|
46085
|
+
registerCallback(toolCallId, async (newState) => {
|
|
46086
|
+
// When user interacts with the action after reload, continue the stream
|
|
46087
|
+
try {
|
|
46088
|
+
// Update the action message with the new state and check completion
|
|
46089
|
+
setState(prev => ({
|
|
46090
|
+
...prev,
|
|
46091
|
+
messages: prev.messages.map(m => {
|
|
46092
|
+
if (m.action?.toolCallId !== toolCallId) {
|
|
46093
|
+
return m;
|
|
46094
|
+
}
|
|
46095
|
+
if (!m.action) {
|
|
46096
|
+
return m;
|
|
46097
|
+
}
|
|
46098
|
+
return { ...m, action: { ...m.action, state: newState } };
|
|
46099
|
+
}),
|
|
46100
|
+
isTyping: true,
|
|
46101
|
+
}));
|
|
46102
|
+
const streamState = createStreamState();
|
|
46103
|
+
// Continue the agent stream with the new state
|
|
46104
|
+
for await (const event of client.continueAgentMessageStream(conversationId, toolCallId, newState)) {
|
|
46105
|
+
if (event.type === "done") {
|
|
46106
|
+
finalizeToolMessage(streamState, setState, toolCallId, toolName);
|
|
46107
|
+
streamState.sources = event.sources;
|
|
46108
|
+
streamState.toolCallToActionId = event.tool_call_to_action_id;
|
|
46109
|
+
finalizeStreamMessages(setState, streamState.newMessageIds, event.sources, event.tool_call_to_action_id, event.suggestions);
|
|
46110
|
+
continue;
|
|
46111
|
+
}
|
|
46112
|
+
if (event.type === "error") {
|
|
46113
|
+
const errorMessage = {
|
|
46114
|
+
id: generateMessageId(),
|
|
46115
|
+
message: {
|
|
46116
|
+
role: "assistant",
|
|
46117
|
+
content: "Sorry, an error occurred. Please try again later.",
|
|
46118
|
+
},
|
|
46119
|
+
timestamp: new Date().toISOString(),
|
|
46120
|
+
sources: [],
|
|
46121
|
+
isError: true,
|
|
46122
|
+
};
|
|
46123
|
+
upsertMessage(setState, errorMessage, false);
|
|
46124
|
+
setState(prev => ({ ...prev, isTyping: false }));
|
|
46125
|
+
return;
|
|
46126
|
+
}
|
|
46127
|
+
handleStreamEvent(event, streamState, onMessageUpdate, setState);
|
|
46128
|
+
}
|
|
46129
|
+
setState(prev => ({ ...prev, isTyping: false }));
|
|
45394
46130
|
}
|
|
45395
|
-
|
|
45396
|
-
|
|
46131
|
+
catch (error) {
|
|
46132
|
+
console.error("[Action Resume] Failed to continue stream:", error);
|
|
46133
|
+
setState(prev => ({ ...prev, isTyping: false }));
|
|
45397
46134
|
}
|
|
46135
|
+
});
|
|
45398
46136
|
}
|
|
45399
|
-
return { message, retryAfterSeconds, status: error.status };
|
|
45400
|
-
}
|
|
45401
|
-
if (error instanceof Error) {
|
|
45402
|
-
const lower = error.message.toLowerCase();
|
|
45403
|
-
if (lower.includes('network')) {
|
|
45404
|
-
return { message: 'Unable to connect to the server. Please check your internet connection.' };
|
|
45405
|
-
}
|
|
45406
|
-
if (lower.includes('timeout')) {
|
|
45407
|
-
return { message: 'The request timed out. Please try again.' };
|
|
45408
|
-
}
|
|
45409
|
-
if (lower.includes('unauthorized') || lower.includes('401')) {
|
|
45410
|
-
return { message: 'Authentication failed. Please refresh the page or verify your API key.' };
|
|
45411
|
-
}
|
|
45412
|
-
if (lower.includes('internal server error') || lower.includes('500')) {
|
|
45413
|
-
return { message: 'The server encountered an error. Please try again shortly.' };
|
|
45414
|
-
}
|
|
45415
|
-
return { message: error.message || 'Something went wrong. Please try again.' };
|
|
45416
46137
|
}
|
|
45417
|
-
return { message: 'Something went wrong. Please try again.' };
|
|
45418
46138
|
}
|
|
46139
|
+
|
|
46140
|
+
/**
|
|
46141
|
+
* useChat Hook
|
|
46142
|
+
* Main state management for chat functionality
|
|
46143
|
+
*/
|
|
46144
|
+
// Initialize action handlers immediately to prevent tree-shaking
|
|
46145
|
+
initializeActionHandlers();
|
|
45419
46146
|
function useChat(options) {
|
|
45420
46147
|
const { widgetId, apiUrl, currentRoute, onMessage, onError, skipInitialization = false, } = options;
|
|
45421
46148
|
const [state, setState] = reactExports.useState({
|
|
@@ -45424,27 +46151,24 @@
|
|
|
45424
46151
|
isLoading: false,
|
|
45425
46152
|
isTyping: false,
|
|
45426
46153
|
error: null,
|
|
45427
|
-
conversationId: '',
|
|
46154
|
+
conversationId: '',
|
|
45428
46155
|
config: null,
|
|
45429
46156
|
});
|
|
45430
46157
|
const stateRef = reactExports.useRef(state);
|
|
45431
46158
|
reactExports.useEffect(() => {
|
|
45432
46159
|
stateRef.current = state;
|
|
45433
46160
|
}, [state]);
|
|
45434
|
-
// Chat history state
|
|
45435
46161
|
const [conversations, setConversations] = reactExports.useState([]);
|
|
45436
|
-
// Stream cancellation and rate limiting
|
|
45437
46162
|
const abortControllerRef = reactExports.useRef(null);
|
|
46163
|
+
const currentRequestIdRef = reactExports.useRef(null);
|
|
45438
46164
|
const lastNewChatTimeRef = reactExports.useRef(0);
|
|
45439
|
-
const NEW_CHAT_COOLDOWN_MS = 5000;
|
|
46165
|
+
const NEW_CHAT_COOLDOWN_MS = 5000;
|
|
45440
46166
|
const apiClient = reactExports.useRef(new WidgetApiClient({ widgetId, apiUrl, currentRoute }));
|
|
45441
|
-
// Update API client when currentRoute changes
|
|
45442
46167
|
reactExports.useEffect(() => {
|
|
45443
46168
|
apiClient.current = new WidgetApiClient({ widgetId, apiUrl, currentRoute });
|
|
45444
46169
|
}, [widgetId, apiUrl, currentRoute]);
|
|
45445
46170
|
// Load configuration on mount and hydrate with existing conversation if available
|
|
45446
46171
|
reactExports.useEffect(() => {
|
|
45447
|
-
// Skip initialization in preview mode
|
|
45448
46172
|
if (skipInitialization) {
|
|
45449
46173
|
return;
|
|
45450
46174
|
}
|
|
@@ -45481,7 +46205,7 @@
|
|
|
45481
46205
|
}));
|
|
45482
46206
|
// Setup resume callbacks for incomplete actions
|
|
45483
46207
|
if (conversationId) {
|
|
45484
|
-
setupActionResumeCallbacks(hydratedMessages, apiClient.current, conversationId, setState, onMessage ?? (() => { }));
|
|
46208
|
+
setupActionResumeCallbacks(hydratedMessages, apiClient.current, conversationId, setState, onMessage ?? (() => { }), createStreamState, registerActionResumeCallback);
|
|
45485
46209
|
}
|
|
45486
46210
|
}
|
|
45487
46211
|
catch (error) {
|
|
@@ -45498,7 +46222,6 @@
|
|
|
45498
46222
|
initialize();
|
|
45499
46223
|
return () => {
|
|
45500
46224
|
isMounted = false;
|
|
45501
|
-
// Cleanup resume callbacks
|
|
45502
46225
|
state.messages.forEach(message => {
|
|
45503
46226
|
if (message.action?.toolCallId) {
|
|
45504
46227
|
unregisterActionResumeCallback(message.action.toolCallId);
|
|
@@ -45521,19 +46244,15 @@
|
|
|
45521
46244
|
const hasFiles = !!files && files.length > 0;
|
|
45522
46245
|
if (!trimmedContent && !hasFiles)
|
|
45523
46246
|
return;
|
|
45524
|
-
// Block parallel streams - don't allow sending while already streaming
|
|
45525
46247
|
if (stateRef.current.isTyping) {
|
|
45526
46248
|
console.warn('[Widget] Cannot send message while streaming is in progress');
|
|
45527
46249
|
return;
|
|
45528
46250
|
}
|
|
45529
|
-
// Cancel any existing stream before starting new one
|
|
45530
46251
|
if (abortControllerRef.current) {
|
|
45531
46252
|
abortControllerRef.current.abort();
|
|
45532
46253
|
abortControllerRef.current = null;
|
|
45533
46254
|
}
|
|
45534
|
-
// Create new abort controller for this stream
|
|
45535
46255
|
abortControllerRef.current = new AbortController();
|
|
45536
|
-
// Strip [EXECUTE_ACTION:...] prefix from displayed message (but keep for API)
|
|
45537
46256
|
const displayContent = trimmedContent.replace(/^\[EXECUTE_ACTION:[^\]]+\]\s*/, '');
|
|
45538
46257
|
const userMessage = {
|
|
45539
46258
|
id: generateMessageId(),
|
|
@@ -45544,12 +46263,11 @@
|
|
|
45544
46263
|
timestamp: new Date().toISOString(),
|
|
45545
46264
|
sources: [],
|
|
45546
46265
|
};
|
|
45547
|
-
// Add user message immediately
|
|
45548
46266
|
setState(prev => ({
|
|
45549
46267
|
...prev,
|
|
45550
46268
|
messages: [...prev.messages, userMessage],
|
|
45551
|
-
isLoading: false,
|
|
45552
|
-
isTyping: true,
|
|
46269
|
+
isLoading: false,
|
|
46270
|
+
isTyping: true,
|
|
45553
46271
|
error: null,
|
|
45554
46272
|
}));
|
|
45555
46273
|
onMessage?.(userMessage);
|
|
@@ -45589,26 +46307,27 @@
|
|
|
45589
46307
|
}
|
|
45590
46308
|
catch (uploadError) {
|
|
45591
46309
|
console.error('Failed to upload file:', uploadError);
|
|
45592
|
-
// Continue with other files
|
|
45593
46310
|
}
|
|
45594
46311
|
}
|
|
45595
46312
|
}
|
|
45596
|
-
// Stream the response
|
|
45597
46313
|
let lastStreamedMessage = null;
|
|
45598
46314
|
const streamState = createStreamState();
|
|
45599
|
-
|
|
46315
|
+
currentRequestIdRef.current = streamState.requestId;
|
|
45600
46316
|
const currentAbortController = abortControllerRef.current;
|
|
45601
46317
|
const streamConversationId = conversationId;
|
|
45602
|
-
const
|
|
46318
|
+
const streamRequestId = streamState.requestId;
|
|
46319
|
+
const stream = apiClient.current.sendAgentMessageStream(conversationId, trimmedContent, fileIds, currentAbortController?.signal);
|
|
45603
46320
|
for await (const event of stream) {
|
|
45604
|
-
|
|
45605
|
-
|
|
45606
|
-
|
|
46321
|
+
if (currentAbortController?.signal.aborted ||
|
|
46322
|
+
stateRef.current.conversationId !== streamConversationId ||
|
|
46323
|
+
currentRequestIdRef.current !== streamRequestId) {
|
|
46324
|
+
console.log('[Widget] Stream aborted, conversation changed, or superseded by new request');
|
|
45607
46325
|
break;
|
|
45608
46326
|
}
|
|
45609
46327
|
if (event.type === "action_request") {
|
|
45610
|
-
|
|
45611
|
-
|
|
46328
|
+
if (currentAbortController?.signal.aborted ||
|
|
46329
|
+
stateRef.current.conversationId !== streamConversationId ||
|
|
46330
|
+
currentRequestIdRef.current !== streamRequestId) {
|
|
45612
46331
|
break;
|
|
45613
46332
|
}
|
|
45614
46333
|
await handleActionLoop(apiClient.current, event, streamState, (message) => {
|
|
@@ -45620,30 +46339,26 @@
|
|
|
45620
46339
|
lastStreamedMessage = message;
|
|
45621
46340
|
}, setState);
|
|
45622
46341
|
}
|
|
45623
|
-
|
|
45624
|
-
|
|
45625
|
-
|
|
46342
|
+
if (currentAbortController?.signal.aborted ||
|
|
46343
|
+
stateRef.current.conversationId !== streamConversationId ||
|
|
46344
|
+
currentRequestIdRef.current !== streamRequestId) {
|
|
46345
|
+
console.log('[Widget] Stream was aborted or superseded, skipping finalization');
|
|
45626
46346
|
return;
|
|
45627
46347
|
}
|
|
45628
|
-
// Stream completed - finalize state
|
|
45629
46348
|
setState(prev => ({
|
|
45630
46349
|
...prev,
|
|
45631
46350
|
isLoading: false,
|
|
45632
46351
|
isTyping: false,
|
|
45633
46352
|
}));
|
|
45634
|
-
// Notify about final message
|
|
45635
46353
|
if (lastStreamedMessage) {
|
|
45636
46354
|
onMessage?.(lastStreamedMessage);
|
|
45637
46355
|
}
|
|
45638
|
-
// Generate follow-up suggestions asynchronously
|
|
45639
46356
|
const enableFollowUps = state.config?.settings.enableFollowUpSuggestions !== false;
|
|
45640
46357
|
const actionIds = state.config?.actions || [];
|
|
45641
46358
|
if (enableFollowUps) {
|
|
45642
|
-
// Don't await - let it run in background
|
|
45643
46359
|
apiClient.current.generateFollowUps(stateRef.current.messages, actionIds)
|
|
45644
46360
|
.then(suggestions => {
|
|
45645
46361
|
if (suggestions.length > 0) {
|
|
45646
|
-
// Attach suggestions to the last assistant message
|
|
45647
46362
|
setState(prev => {
|
|
45648
46363
|
const messages = [...prev.messages];
|
|
45649
46364
|
for (let i = messages.length - 1; i >= 0; i--) {
|
|
@@ -45672,7 +46387,7 @@
|
|
|
45672
46387
|
},
|
|
45673
46388
|
timestamp: new Date().toISOString(),
|
|
45674
46389
|
sources: [],
|
|
45675
|
-
isError: !fallbackMessage,
|
|
46390
|
+
isError: !fallbackMessage,
|
|
45676
46391
|
};
|
|
45677
46392
|
setState(prev => ({
|
|
45678
46393
|
...prev,
|
|
@@ -45684,9 +46399,6 @@
|
|
|
45684
46399
|
onError?.(err);
|
|
45685
46400
|
}
|
|
45686
46401
|
}, [state.conversationId, state.config, state.messages, onMessage, onError]);
|
|
45687
|
-
/**
|
|
45688
|
-
* Clear all messages
|
|
45689
|
-
*/
|
|
45690
46402
|
const clearMessages = reactExports.useCallback(() => {
|
|
45691
46403
|
setState(prev => ({
|
|
45692
46404
|
...prev,
|
|
@@ -45699,9 +46411,6 @@
|
|
|
45699
46411
|
clearConversation(widgetId);
|
|
45700
46412
|
}
|
|
45701
46413
|
}, [widgetId, state.config?.settings.persistConversation]);
|
|
45702
|
-
/**
|
|
45703
|
-
* Submit feedback for a message
|
|
45704
|
-
*/
|
|
45705
46414
|
const submitFeedback = reactExports.useCallback(async (messageId, feedback) => {
|
|
45706
46415
|
try {
|
|
45707
46416
|
const message = state.messages.find(msg => msg.id === messageId);
|
|
@@ -45711,7 +46420,6 @@
|
|
|
45711
46420
|
: undefined;
|
|
45712
46421
|
console.log('Submitting feedback:', { conversationId: state.conversationId, messageId, feedback });
|
|
45713
46422
|
await apiClient.current.submitFeedback(state.conversationId, messageId, feedback, meta);
|
|
45714
|
-
// Update message with feedback
|
|
45715
46423
|
setState(prev => ({
|
|
45716
46424
|
...prev,
|
|
45717
46425
|
messages: prev.messages.map(msg => msg.id === messageId
|
|
@@ -45726,9 +46434,6 @@
|
|
|
45726
46434
|
onError?.(err);
|
|
45727
46435
|
}
|
|
45728
46436
|
}, [state.conversationId, onError]);
|
|
45729
|
-
/**
|
|
45730
|
-
* Load conversation history list from localStorage
|
|
45731
|
-
*/
|
|
45732
46437
|
const loadConversations = reactExports.useCallback(() => {
|
|
45733
46438
|
const persistConversation = state.config?.settings.persistConversation ?? true;
|
|
45734
46439
|
if (!persistConversation || !isStorageAvailable()) {
|
|
@@ -45745,13 +46450,11 @@
|
|
|
45745
46450
|
})));
|
|
45746
46451
|
}, [widgetId, state.config?.settings.persistConversation]);
|
|
45747
46452
|
const switchConversation = reactExports.useCallback(async (conversationId) => {
|
|
45748
|
-
// Cancel any active stream before switching conversations
|
|
45749
46453
|
if (abortControllerRef.current) {
|
|
45750
46454
|
abortControllerRef.current.abort();
|
|
45751
46455
|
abortControllerRef.current = null;
|
|
45752
46456
|
}
|
|
45753
46457
|
const persistConversation = state.config?.settings.persistConversation ?? true;
|
|
45754
|
-
// First try to load from localStorage
|
|
45755
46458
|
if (persistConversation && isStorageAvailable()) {
|
|
45756
46459
|
const stored = loadConversationById(widgetId, conversationId);
|
|
45757
46460
|
if (stored) {
|
|
@@ -45770,7 +46473,6 @@
|
|
|
45770
46473
|
try {
|
|
45771
46474
|
const conversation = await apiClient.current.getOrCreateConversation(conversationId);
|
|
45772
46475
|
const hydratedMessages = hydrateMessages(conversation.messages);
|
|
45773
|
-
// Clear old resume callbacks
|
|
45774
46476
|
state.messages.forEach(message => {
|
|
45775
46477
|
if (message.action?.toolCallId) {
|
|
45776
46478
|
unregisterActionResumeCallback(message.action.toolCallId);
|
|
@@ -45782,9 +46484,7 @@
|
|
|
45782
46484
|
messages: hydratedMessages,
|
|
45783
46485
|
isLoading: false,
|
|
45784
46486
|
}));
|
|
45785
|
-
|
|
45786
|
-
setupActionResumeCallbacks(hydratedMessages, apiClient.current, conversation.id, setState, onMessage ?? (() => { }));
|
|
45787
|
-
// Save to local storage
|
|
46487
|
+
setupActionResumeCallbacks(hydratedMessages, apiClient.current, conversation.id, setState, onMessage ?? (() => { }), createStreamState, registerActionResumeCallback);
|
|
45788
46488
|
if (persistConversation && isStorageAvailable()) {
|
|
45789
46489
|
saveConversation(widgetId, conversation.id, hydratedMessages);
|
|
45790
46490
|
}
|
|
@@ -45795,19 +46495,16 @@
|
|
|
45795
46495
|
}
|
|
45796
46496
|
}, [widgetId, state.config?.settings.persistConversation]);
|
|
45797
46497
|
const startNewConversation = reactExports.useCallback(() => {
|
|
45798
|
-
// Rate limiting - prevent spamming new chats
|
|
45799
46498
|
const now = Date.now();
|
|
45800
46499
|
if (now - lastNewChatTimeRef.current < NEW_CHAT_COOLDOWN_MS) {
|
|
45801
46500
|
console.warn('[Widget] New chat rate limited - please wait');
|
|
45802
46501
|
return;
|
|
45803
46502
|
}
|
|
45804
46503
|
lastNewChatTimeRef.current = now;
|
|
45805
|
-
// Cancel any active stream before starting new conversation
|
|
45806
46504
|
if (abortControllerRef.current) {
|
|
45807
46505
|
abortControllerRef.current.abort();
|
|
45808
46506
|
abortControllerRef.current = null;
|
|
45809
46507
|
}
|
|
45810
|
-
// Reset typing state if stream was active
|
|
45811
46508
|
setState(prev => ({
|
|
45812
46509
|
...prev,
|
|
45813
46510
|
messages: [],
|
|
@@ -45826,11 +46523,8 @@
|
|
|
45826
46523
|
if (!persistConversation || !isStorageAvailable()) {
|
|
45827
46524
|
return;
|
|
45828
46525
|
}
|
|
45829
|
-
// Delete from storage
|
|
45830
46526
|
deleteConversation(widgetId, conversationId);
|
|
45831
|
-
// Update local state
|
|
45832
46527
|
setConversations(prev => prev.filter(c => c.id !== conversationId));
|
|
45833
|
-
// If we deleted the current conversation, clear it
|
|
45834
46528
|
if (state.conversationId === conversationId) {
|
|
45835
46529
|
setState(prev => ({
|
|
45836
46530
|
...prev,
|
|
@@ -45850,7 +46544,6 @@
|
|
|
45850
46544
|
sendMessage,
|
|
45851
46545
|
clearMessages,
|
|
45852
46546
|
submitFeedback,
|
|
45853
|
-
// Chat history features
|
|
45854
46547
|
conversations,
|
|
45855
46548
|
loadConversations,
|
|
45856
46549
|
switchConversation,
|
|
@@ -45859,11 +46552,20 @@
|
|
|
45859
46552
|
};
|
|
45860
46553
|
}
|
|
45861
46554
|
|
|
46555
|
+
const ShieldIcon = () => (jsxRuntimeExports.jsxs("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("path", { d: "M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" }), jsxRuntimeExports.jsx("path", { d: "M9 12l2 2 4-4" })] }));
|
|
46556
|
+
const DataPolicyView = ({ config, widgetName, }) => {
|
|
46557
|
+
const headerTitle = widgetName || config?.appearance?.headerTitle || 'AI Assistant';
|
|
46558
|
+
const hasFileUpload = config?.settings?.enableFileUpload ?? false;
|
|
46559
|
+
const persistsConversation = config?.settings?.persistConversation ?? true;
|
|
46560
|
+
return (jsxRuntimeExports.jsx("div", { className: "ai-chat-data-policy-view", children: jsxRuntimeExports.jsxs("div", { className: "ai-chat-data-policy-content", children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-data-policy-intro", children: [jsxRuntimeExports.jsx("div", { className: "ai-chat-data-policy-icon", children: jsxRuntimeExports.jsx(ShieldIcon, {}) }), jsxRuntimeExports.jsxs("p", { children: ["Dieser Datenschutzhinweis informiert dich gem\u00E4\u00DF Art. 13 DSGVO dar\u00FCber, wie ", jsxRuntimeExports.jsx("strong", { children: headerTitle }), " Daten verarbeitet, wenn du diesen Chat nutzt. Bitte beachte, dass der konkrete Umfang der Verarbeitung vom Betreiber dieser Website/Anwendung (dem Verantwortlichen) sowie von den jeweils aktivierten Funktionen abh\u00E4ngt."] })] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-data-policy-section", children: [jsxRuntimeExports.jsx("h3", { children: "Verantwortlicher / Kontakt" }), jsxRuntimeExports.jsx("p", { children: "Verantwortlicher im Sinne von Art. 4 Nr. 7 DSGVO ist der Betreiber dieser Website/Anwendung. Die Kontaktdaten (und ggf. die Kontaktdaten eines Datenschutzbeauftragten) findest du in der Datenschutzerkl\u00E4rung bzw. im Impressum der Website, in die dieses Chat-Widget eingebunden ist." })] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-data-policy-section", children: [jsxRuntimeExports.jsx("h3", { children: "Verarbeitete Daten (Kategorien)" }), jsxRuntimeExports.jsxs("ul", { children: [jsxRuntimeExports.jsxs("li", { children: [jsxRuntimeExports.jsx("strong", { children: "Chat-Inhalte:" }), " Nachrichten (Text) sowie ggf. Kontextinformationen, die du im Chat angibst. Diese Inhalte werden verarbeitet, um Antworten zu generieren und die Unterhaltung bereitzustellen."] }), hasFileUpload && (jsxRuntimeExports.jsxs("li", { children: [jsxRuntimeExports.jsx("strong", { children: "Hochgeladene Dateien:" }), " Dateien, die du an den Chat \u00FCbermittelst, werden zur Bearbeitung des Anliegens verarbeitet. Die Verarbeitung kann das Extrahieren von Text/Informationen umfassen."] })), jsxRuntimeExports.jsxs("li", { children: [jsxRuntimeExports.jsx("strong", { children: "Technische Nutzungsdaten:" }), " z.B. Zeitstempel, Sitzungs-/Request-Informationen sowie technische Metadaten, die f\u00FCr den Betrieb, die Sicherheit (Missbrauchspr\u00E4vention) und Fehleranalyse erforderlich sind."] })] })] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-data-policy-section", children: [jsxRuntimeExports.jsx("h3", { children: "Zwecke und Rechtsgrundlagen" }), jsxRuntimeExports.jsxs("ul", { children: [jsxRuntimeExports.jsxs("li", { children: [jsxRuntimeExports.jsx("strong", { children: "Bereitstellung des Chats und Beantwortung von Anfragen" }), " (Art. 6 Abs. 1 lit. b DSGVO, soweit Vertrags-/vorvertragliche Ma\u00DFnahmen; andernfalls Art. 6 Abs. 1 lit. f DSGVO \u2013 berechtigtes Interesse an effizienter Kommunikation und Support)."] }), jsxRuntimeExports.jsxs("li", { children: [jsxRuntimeExports.jsx("strong", { children: "Qualit\u00E4tssicherung, Betrieb und Sicherheit" }), " (Art. 6 Abs. 1 lit. f DSGVO), z.B. zur Stabilit\u00E4t, Missbrauchserkennung und Fehlerbehebung."] }), jsxRuntimeExports.jsxs("li", { children: [jsxRuntimeExports.jsx("strong", { children: "Einwilligungsbasierte Verarbeitung" }), " kann erfolgen, sofern der Betreiber dies vorsieht (Art. 6 Abs. 1 lit. a DSGVO)."] })] })] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-data-policy-section", children: [jsxRuntimeExports.jsx("h3", { children: "Empf\u00E4nger und Auftragsverarbeiter" }), jsxRuntimeExports.jsxs("ul", { children: [jsxRuntimeExports.jsxs("li", { children: [jsxRuntimeExports.jsx("strong", { children: "Hosting/IT-Dienstleister:" }), " Der Betreiber kann Dienstleister f\u00FCr Hosting, Logging, Monitoring und Infrastruktur einsetzen."] }), jsxRuntimeExports.jsxs("li", { children: [jsxRuntimeExports.jsx("strong", { children: "KI-Dienstleister:" }), " Zur Generierung von Antworten k\u00F6nnen Chat-Inhalte an KI-Modelle bzw. Anbieter von KI-Infrastruktur \u00FCbertragen werden. Soweit erforderlich, erfolgt dies auf Grundlage eines Auftragsverarbeitungsvertrags (Art. 28 DSGVO)."] }), jsxRuntimeExports.jsxs("li", { children: [jsxRuntimeExports.jsx("strong", { children: "Drittlandtransfer:" }), " Falls Empf\u00E4nger au\u00DFerhalb der EU/des EWR sitzen, kann ein Transfer in Drittl\u00E4nder stattfinden. In diesem Fall werden geeignete Garantien (z.B. EU-Standardvertragsklauseln) eingesetzt, soweit erforderlich."] })] })] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-data-policy-section", children: [jsxRuntimeExports.jsx("h3", { children: "Speicherdauer" }), jsxRuntimeExports.jsxs("ul", { children: [persistsConversation ? (jsxRuntimeExports.jsxs("li", { children: [jsxRuntimeExports.jsx("strong", { children: "Chatverlauf:" }), " Der Chatverlauf kann gespeichert werden, um die Unterhaltung \u00FCber mehrere Sitzungen hinweg fortzusetzen."] })) : (jsxRuntimeExports.jsxs("li", { children: [jsxRuntimeExports.jsx("strong", { children: "Chatverlauf:" }), " Der Chatverlauf wird nicht dauerhaft gespeichert und wird beim Schlie\u00DFen des Chats beendet."] })), hasFileUpload && (jsxRuntimeExports.jsxs("li", { children: [jsxRuntimeExports.jsx("strong", { children: "Dateien:" }), " Hochgeladene Dateien werden nur so lange verarbeitet, wie dies f\u00FCr die Bearbeitung erforderlich ist, und anschlie\u00DFend gel\u00F6scht, sofern keine l\u00E4ngere Speicherung gesetzlich erforderlich ist."] })), jsxRuntimeExports.jsxs("li", { children: [jsxRuntimeExports.jsx("strong", { children: "Technische Protokolle:" }), " Technische Logdaten k\u00F6nnen f\u00FCr einen begrenzten Zeitraum gespeichert werden, um den sicheren Betrieb zu gew\u00E4hrleisten."] })] })] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-data-policy-section", children: [jsxRuntimeExports.jsx("h3", { children: "Deine Rechte (Betroffenenrechte)" }), jsxRuntimeExports.jsxs("ul", { children: [jsxRuntimeExports.jsxs("li", { children: [jsxRuntimeExports.jsx("strong", { children: "Auskunft" }), " (Art. 15 DSGVO)"] }), jsxRuntimeExports.jsxs("li", { children: [jsxRuntimeExports.jsx("strong", { children: "Berichtigung" }), " (Art. 16 DSGVO)"] }), jsxRuntimeExports.jsxs("li", { children: [jsxRuntimeExports.jsx("strong", { children: "L\u00F6schung" }), " (Art. 17 DSGVO) und ", jsxRuntimeExports.jsx("strong", { children: "Einschr\u00E4nkung der Verarbeitung" }), " (Art. 18 DSGVO)"] }), jsxRuntimeExports.jsxs("li", { children: [jsxRuntimeExports.jsx("strong", { children: "Daten\u00FCbertragbarkeit" }), " (Art. 20 DSGVO), soweit anwendbar"] }), jsxRuntimeExports.jsxs("li", { children: [jsxRuntimeExports.jsx("strong", { children: "Widerspruch" }), " gegen Verarbeitungen auf Grundlage berechtigter Interessen (Art. 21 DSGVO)"] }), jsxRuntimeExports.jsxs("li", { children: [jsxRuntimeExports.jsx("strong", { children: "Beschwerderecht" }), " bei einer Datenschutzaufsichtsbeh\u00F6rde (Art. 77 DSGVO)"] })] }), jsxRuntimeExports.jsx("p", { children: "Hinweis: Ohne eindeutige Identifikationsmerkmale kann der Betreiber einzelne Chatverl\u00E4ufe ggf. nicht einer Person zuordnen. F\u00FCr Anfragen wende dich bitte an den Betreiber dieser Website/Anwendung." })] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-data-policy-section", children: [jsxRuntimeExports.jsx("h3", { children: "Wichtiger Hinweis" }), jsxRuntimeExports.jsx("p", { className: "ai-chat-data-policy-warning", children: "Bitte gib keine besonderen Kategorien personenbezogener Daten (z.B. Gesundheitsdaten), Passw\u00F6rter, Kreditkarten-/Bankdaten oder vertrauliche Gesch\u00E4ftsgeheimnisse in den Chat ein. KI-generierte Antworten k\u00F6nnen unzutreffend sein und sollten vor einer Nutzung eigenverantwortlich gepr\u00FCft werden." })] })] }) }));
|
|
46561
|
+
};
|
|
46562
|
+
|
|
45862
46563
|
const MenuIcon = () => (jsxRuntimeExports.jsxs("svg", { width: "22", height: "22", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("line", { x1: "4", y1: "10", x2: "20", y2: "10" }), jsxRuntimeExports.jsx("line", { x1: "10", y1: "14", x2: "20", y2: "14" })] }));
|
|
45863
46564
|
const PlusIcon = () => (jsxRuntimeExports.jsxs("svg", { width: "22", height: "22", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("line", { x1: "12", y1: "5", x2: "12", y2: "19" }), jsxRuntimeExports.jsx("line", { x1: "5", y1: "12", x2: "19", y2: "12" })] }));
|
|
45864
46565
|
const TrashIcon = () => (jsxRuntimeExports.jsxs("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: "M3 6h18" }), jsxRuntimeExports.jsx("path", { d: "M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6" }), jsxRuntimeExports.jsx("path", { d: "M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2" })] }));
|
|
45865
46566
|
const CloseIcon = () => (jsxRuntimeExports.jsxs("svg", { width: "22", height: "22", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }), jsxRuntimeExports.jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })] }));
|
|
45866
|
-
const
|
|
46567
|
+
const BackIcon = () => (jsxRuntimeExports.jsxs("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: "M19 12H5" }), jsxRuntimeExports.jsx("path", { d: "M12 19l-7-7 7-7" })] }));
|
|
46568
|
+
const ChatWindow = ({ messages, isLoading, isTyping, config, onSendMessage, onClose: _onClose, onFeedback, onActionClick,
|
|
45867
46569
|
// Chat history props (only active when persistConversation is true)
|
|
45868
46570
|
conversations = [], onLoadConversations, onSwitchConversation, onStartNewConversation, onDeleteConversation, currentConversationId,
|
|
45869
46571
|
// Override props for live preview
|
|
@@ -45880,6 +46582,8 @@
|
|
|
45880
46582
|
const inputPlaceholder = placeholderOverride ?? appearance?.placeholder ?? 'Ask me anything...';
|
|
45881
46583
|
// Track if history panel is open
|
|
45882
46584
|
const [showHistory, setShowHistory] = reactExports.useState(false);
|
|
46585
|
+
// Track if data policy view is open
|
|
46586
|
+
const [showDataPolicy, setShowDataPolicy] = reactExports.useState(false);
|
|
45883
46587
|
// Scroll button state (managed by MessageList)
|
|
45884
46588
|
const [showScrollButton, setShowScrollButton] = reactExports.useState(false);
|
|
45885
46589
|
const [scrollToBottom, setScrollToBottom] = reactExports.useState(null);
|
|
@@ -45889,6 +46593,13 @@
|
|
|
45889
46593
|
}, []);
|
|
45890
46594
|
// History exit animation when starting a new chat from overview
|
|
45891
46595
|
const [isHistoryExiting, setIsHistoryExiting] = reactExports.useState(false);
|
|
46596
|
+
// Handle data policy click
|
|
46597
|
+
const handleDataPolicyClick = reactExports.useCallback(() => {
|
|
46598
|
+
setShowDataPolicy(true);
|
|
46599
|
+
}, []);
|
|
46600
|
+
const handleDataPolicyBack = reactExports.useCallback(() => {
|
|
46601
|
+
setShowDataPolicy(false);
|
|
46602
|
+
}, []);
|
|
45892
46603
|
// Load conversations when history panel opens
|
|
45893
46604
|
const handleOpenHistory = () => {
|
|
45894
46605
|
setShowHistory(true);
|
|
@@ -45936,10 +46647,22 @@
|
|
|
45936
46647
|
// The backend will detect and trigger the action based on the message
|
|
45937
46648
|
onSendMessage(question);
|
|
45938
46649
|
};
|
|
45939
|
-
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 })] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-header-actions", children: [canShowHistory && (jsxRuntimeExports.jsx("button", { className: "ai-chat-header-button", onClick: handleOpenHistory, "aria-label": "Chat overview", children: jsxRuntimeExports.jsx(MenuIcon, {}) })), jsxRuntimeExports.jsx("button", { className: "ai-chat-close-button header-close-button", onClick: _onClose, "aria-label": "Close chat", children: jsxRuntimeExports.jsx(CloseIcon, {}) })] })] })) }),
|
|
46650
|
+
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' : ''} ${showDataPolicy ? 'is-data-policy' : ''}`, children: showDataPolicy ? (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("button", { className: "ai-chat-header-button", onClick: handleDataPolicyBack, "aria-label": "Back to chat", children: jsxRuntimeExports.jsx(BackIcon, {}) }), jsxRuntimeExports.jsx("div", { className: "ai-chat-title", children: "Datenschutzhinweis" })] })) : 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 })] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-header-actions", children: [canShowHistory && (jsxRuntimeExports.jsx("button", { className: "ai-chat-header-button", onClick: handleOpenHistory, "aria-label": "Chat overview", children: jsxRuntimeExports.jsx(MenuIcon, {}) })), jsxRuntimeExports.jsx("button", { className: "ai-chat-close-button header-close-button", onClick: _onClose, "aria-label": "Close chat", children: jsxRuntimeExports.jsx(CloseIcon, {}) })] })] })) }), showDataPolicy ? (jsxRuntimeExports.jsx(DataPolicyView, { config: config, onBack: handleDataPolicyBack, widgetName: headerTitle })) : showHistory ? (
|
|
46651
|
+
/* History Panel */
|
|
46652
|
+
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.jsx("div", { className: `ai-chat-history-item ${conv.id === currentConversationId ? 'active' : ''}`, onClick: () => handleSelectConversation(conv.id), children: jsxRuntimeExports.jsxs("div", { className: "ai-chat-history-item-content", children: [jsxRuntimeExports.jsx("div", { className: "ai-chat-history-item-preview", children: conv.preview }), onDeleteConversation && (jsxRuntimeExports.jsx("button", { className: "ai-chat-history-item-delete", onClick: (e) => {
|
|
45940
46653
|
e.stopPropagation();
|
|
45941
46654
|
onDeleteConversation(conv.id);
|
|
45942
|
-
}, "aria-label": "Delete conversation", children: jsxRuntimeExports.jsx(TrashIcon, {}) }))] }) }, conv.id))) })), jsxRuntimeExports.jsx(MessageInput, { onSend: (text) => handleSendFromOverview(text), placeholder: inputPlaceholder, disabled: isLoading, enableFileUpload: settings?.enableFileUpload })] })) : (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
46655
|
+
}, "aria-label": "Delete conversation", children: jsxRuntimeExports.jsx(TrashIcon, {}) }))] }) }, conv.id))) })), jsxRuntimeExports.jsx(MessageInput, { onSend: (text) => handleSendFromOverview(text), placeholder: inputPlaceholder, disabled: isLoading, enableFileUpload: settings?.enableFileUpload, showDataPolicy: settings?.showDataPolicy ?? true, onDataPolicyClick: handleDataPolicyClick })] })) : (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [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." })), (() => {
|
|
46656
|
+
console.log('[DEBUG ChatWindow] Rendering MessageList with', messages.length, 'messages');
|
|
46657
|
+
messages.forEach((m, i) => {
|
|
46658
|
+
console.log(`[DEBUG ChatWindow] msg ${i}:`, { role: m.message.role, hasAction: !!m.action, impl: m.action?.implementation });
|
|
46659
|
+
});
|
|
46660
|
+
console.log('[DEBUG ChatWindow] getActionRenderer available:', !!getActionRenderer);
|
|
46661
|
+
if (getActionRenderer) {
|
|
46662
|
+
console.log('[DEBUG ChatWindow] Testing renderer for query-contact-directory:', !!getActionRenderer('query-contact-directory'));
|
|
46663
|
+
}
|
|
46664
|
+
return null;
|
|
46665
|
+
})(), jsxRuntimeExports.jsx(MessageList, { messages: messages, isTyping: isTyping, showTypingIndicator: settings?.showTypingIndicator, showTimestamps: settings?.showTimestamps, showToolCalls: settings?.showToolCalls, enableFeedback: settings?.enableFeedback, welcomeTitle: welcomeTitle || 'Welcome Message', welcomeMessage: welcomeMessage, suggestedQuestions: suggestedQuestionsOverride ?? settings?.suggestedQuestions, accentColor: appearance?.primaryColor, onSuggestedQuestionClick: handleQuestionClick, onActionClick: onActionClick, onFeedback: onFeedback, onScrollStateChange: handleScrollStateChange, getActionRenderer: getActionRenderer }), jsxRuntimeExports.jsx(ScrollButton, { onClick: () => scrollToBottom?.(), visible: showScrollButton }), jsxRuntimeExports.jsx(MessageInput, { onSend: onSendMessage, placeholder: isLimitReached ? 'Message limit reached' : (isTyping ? 'Waiting for response...' : inputPlaceholder), disabled: isLoading || isTyping || isLimitReached, enableFileUpload: settings?.enableFileUpload, showDataPolicy: settings?.showDataPolicy ?? true, onDataPolicyClick: handleDataPolicyClick })] }))] }));
|
|
45943
46666
|
};
|
|
45944
46667
|
|
|
45945
46668
|
/**
|
|
@@ -46345,7 +47068,7 @@
|
|
|
46345
47068
|
if ( ref === void 0 ) ref = {};
|
|
46346
47069
|
var insertAt = ref.insertAt;
|
|
46347
47070
|
|
|
46348
|
-
if (typeof document === 'undefined') { return; }
|
|
47071
|
+
if (!css || typeof document === 'undefined') { return; }
|
|
46349
47072
|
|
|
46350
47073
|
var head = document.head || document.getElementsByTagName('head')[0];
|
|
46351
47074
|
var style = document.createElement('style');
|
|
@@ -46368,7 +47091,10 @@
|
|
|
46368
47091
|
}
|
|
46369
47092
|
}
|
|
46370
47093
|
|
|
46371
|
-
var css_248z = ".ai-chat-message{animation:ai-chat-message-appear .2s var(--chat-ease-bounce);max-width:85%}.ai-chat-message-content{border-radius:var(--chat-radius-bubble,14px);font-size:var(--chat-text-md,15px);line-height:var(--chat-line-relaxed,1.6);padding:var(--chat-space-sm,8px) var(--chat-space-md,16px)}.ai-chat-message.user .ai-chat-message-content{background:var(--chat-user-bg,#f4f3f0);border-bottom-right-radius:var(--chat-radius-sm,4px);color:var(--chat-user-text,#000)}.ai-chat-message.assistant .ai-chat-message-content{background:var(--chat-assistant-bg,transparent);color:var(--chat-assistant-text,#000)}.ai-chat-message-timestamp{color:var(--chat-text-muted,#71717a);font-size:var(--chat-text-xs,12px);margin-top:var(--chat-space-xs,4px);padding:0 var(--chat-space-xs,4px)}.ai-chat-message.streaming .ai-chat-message-content:after{animation:ai-chat-cursor-blink .8s infinite;content:\"▋\";margin-left:2px;opacity:.7}@keyframes ai-chat-message-appear{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}@keyframes ai-chat-cursor-blink{0%,50%{opacity:1}51%,to{opacity:0}}.ai-chat-message.fullpage .ai-chat-message-content{font-size:var(--chat-text-lg,18px);padding:var(--chat-space-md,16px) var(--chat-space-lg,24px)}.ai-chat-typing{gap:var(--chat-space-xs,4px);padding:var(--chat-space-sm,8px) var(--chat-space-md,16px)}.ai-chat-typing-dot{background:var(--chat-text-muted,#71717a)}.ai-chat-tool-gear{color:var(--text-primary,#3e3e3e)}.ai-chat-tool-gear.spinning{animation:ai-chat-spin 1.5s linear infinite}.ai-chat-tool-badge{border-radius:8px}.ai-chat-tool-badge.loading{background:#e5e7eb;border:1px solid #d1d5db;color:#1f2937}.ai-chat-tool-badge.error{background:rgba(239,68,68,.1);color:#ef4444}.ai-chat-tool-check{color:#22c55e;flex-shrink:0}.ai-chat-tool-error{color:#ef4444;flex-shrink:0}.ai-chat-tool-badge .tool-name{max-width:150px;overflow:hidden;text-overflow:ellipsis}.ai-chat-widget.dark .ai-chat-tool-gear,.ai-chat-widget[data-theme=dark] .ai-chat-tool-gear,.dark .ai-chat-tool-gear,[data-theme=dark] .ai-chat-tool-gear{color:#fff}.ai-chat-widget.dark .ai-chat-tool-badge,.ai-chat-widget[data-theme=dark] .ai-chat-tool-badge,.dark .ai-chat-tool-badge,[data-theme=dark] .ai-chat-tool-badge{background:hsla(0,0%,100%,.12);border:1px solid hsla(0,0%,100%,.2);color:hsla(0,0%,100%,.9)}.ai-chat-widget.dark .ai-chat-tool-badge.error,.ai-chat-widget[data-theme=dark] .ai-chat-tool-badge.error,.dark .ai-chat-tool-badge.error,[data-theme=dark] .ai-chat-tool-badge.error{background:rgba(239,68,68,.2);color:#f87171}.chakra-ui-dark .ai-chat-tool-gear,html.dark .ai-chat-tool-gear{color:#fff}.chakra-ui-dark .ai-chat-tool-badge,html.dark .ai-chat-tool-badge{background:hsla(0,0%,100%,.12);border:1px solid hsla(0,0%,100%,.2);color:hsla(0,0%,100%,.9)}.chakra-ui-dark .ai-chat-tool-badge.error,html.dark .ai-chat-tool-badge.error{background:rgba(239,68,68,.2);color:#f87171}@keyframes ai-chat-skeleton-pulse{0%,to{opacity:.4}50%{opacity:.7}}.ai-chat-action-skeleton-item{animation:ai-chat-skeleton-pulse 1.5s ease-in-out infinite;background:var(--bg-secondary,#e5e7eb)}.ai-chat-widget.dark .ai-chat-action-skeleton-item,.chakra-ui-dark .ai-chat-action-skeleton-item,.dark .ai-chat-action-skeleton-item,[data-theme=dark] .ai-chat-action-skeleton-item{background:hsla(0,0%,100%,.1)}.ai-chat-action-skeleton-content{display:flex;flex-direction:column;gap:16px}.ai-chat-action-skeleton-header{align-items:center;display:flex;gap:10px}.ai-chat-action-skeleton-box{background:rgba(0,0,0,.08);border-radius:10px;display:flex;flex-direction:column;gap:8px;padding:14px}.ai-chat-widget.dark .ai-chat-action-skeleton-box,.chakra-ui-dark .ai-chat-action-skeleton-box,.dark .ai-chat-action-skeleton-box,[data-theme=dark] .ai-chat-action-skeleton-box{background:rgba(0,0,0,.25)}.ai-chat-action-card{--action-accent:var(--primary-color,#3b82f6);background:var(--bg-secondary,#f4f4f4);border:none;border-radius:var(--radius-lg,12px);box-sizing:border-box;margin-top:var(--space-sm,8px);max-width:100%;padding:var(--space-md,16px);transition:all var(--duration-normal,.25s) ease;width:100%}.ai-chat-widget.dark .ai-chat-action-card,.chakra-ui-dark .ai-chat-action-card,.dark .ai-chat-action-card,[data-theme=dark] .ai-chat-action-card{background:var(--bg-secondary,#3a3a3a)}.ai-chat-action-booked{background:var(--bg-secondary,#f4f4f4);border:none}.ai-chat-widget.dark .ai-chat-action-booked,.chakra-ui-dark .ai-chat-action-booked,.dark .ai-chat-action-booked,[data-theme=dark] .ai-chat-action-booked{background:var(--bg-secondary,#3a3a3a)}.ai-chat-action-header{align-items:center;color:var(--text-primary,#3e3e3e);display:flex;font-size:var(--text-md,15px);font-weight:var(--font-weight-semibold,600);gap:var(--space-sm,8px);margin-bottom:var(--space-md,16px)}.ai-chat-widget.dark .ai-chat-action-header,.chakra-ui-dark .ai-chat-action-header,.dark .ai-chat-action-header,[data-theme=dark] .ai-chat-action-header{color:var(--text-primary,#fff)}.ai-chat-action-icon{color:var(--action-accent,var(--primary-color,#3b82f6));flex-shrink:0;height:20px;width:20px}.ai-chat-action-success-icon-wrapper{align-items:center;background:var(--action-accent,var(--primary-color,#22c55e));border-radius:50%;color:#fff;display:flex;flex-shrink:0;height:24px;justify-content:center;width:24px}.ai-chat-action-icon-success{color:currentColor;height:14px;width:14px}.ai-chat-action-detail-box{background:var(--bg-primary,#fff);border:1px solid var(--border-subtle,rgba(0,0,0,.08));border-radius:var(--radius-md,8px);display:flex;flex-direction:column;gap:4px;padding:12px 16px}.ai-chat-widget.dark .ai-chat-action-detail-box,.chakra-ui-dark .ai-chat-action-detail-box,.dark .ai-chat-action-detail-box,[data-theme=dark] .ai-chat-action-detail-box{background:rgba(0,0,0,.2);border-color:hsla(0,0%,100%,.05)}.ai-chat-action-label-small{color:var(--text-muted,#71717a);font-size:11px;font-weight:600;letter-spacing:.5px;text-transform:uppercase}.ai-chat-action-value-large{color:var(--text-primary,#3e3e3e);font-size:15px;font-weight:500}.ai-chat-widget.dark .ai-chat-action-value-large,.chakra-ui-dark .ai-chat-action-value-large,.dark .ai-chat-action-value-large,[data-theme=dark] .ai-chat-action-value-large{color:#fff}.ai-chat-action-link-button{align-items:center;background:var(--action-accent,var(--primary-color,#3b82f6));border:none;border-radius:9999px;box-sizing:border-box;color:#fff;display:flex;font-size:14px;font-weight:600;gap:6px;justify-content:center;margin-top:8px;padding:12px;text-decoration:none;transition:all .2s ease;width:100%}.ai-chat-action-link-button:hover{opacity:.9;transform:translateY(-1px)}.ai-chat-action-body{display:flex;flex-direction:column;gap:var(--space-md,16px)}.ai-chat-action-field{display:flex;flex-direction:column;gap:var(--space-xs,6px)}.ai-chat-action-label{color:var(--text-secondary,#6b7280);font-size:var(--text-sm,13px);font-weight:var(--font-weight-medium,500)}.ai-chat-widget.dark .ai-chat-action-label,.chakra-ui-dark .ai-chat-action-label,.dark .ai-chat-action-label,[data-theme=dark] .ai-chat-action-label{color:var(--text-secondary,#a1a1aa)}.ai-chat-action-input{background:var(--bg-primary,#fff);border:1px solid var(--border-default,#e5e7eb);border-radius:var(--radius-md,8px);color:var(--text-primary,#3e3e3e);font-size:var(--text-sm,13px);outline:none;padding:10px 12px;transition:border-color .2s ease,box-shadow .2s ease}.ai-chat-action-input:focus{border-color:var(--action-accent,var(--primary-color,#3b82f6));box-shadow:0 0 0 3px rgba(59,130,246,.1)}.ai-chat-action-input::placeholder{color:var(--text-muted,#9ca3af)}.ai-chat-widget.dark .ai-chat-action-input,.chakra-ui-dark .ai-chat-action-input,.dark .ai-chat-action-input,[data-theme=dark] .ai-chat-action-input{background:rgba(0,0,0,.2);border-color:hsla(0,0%,100%,.1);color:#fff}.ai-chat-widget.dark .ai-chat-action-input:focus,.chakra-ui-dark .ai-chat-action-input:focus,.dark .ai-chat-action-input:focus,[data-theme=dark] .ai-chat-action-input:focus{border-color:var(--action-accent,var(--primary-color,#3b82f6));box-shadow:0 0 0 3px rgba(59,130,246,.2)}.ai-chat-action-date-grid{display:grid;gap:var(--space-xs,6px);grid-template-columns:repeat(auto-fill,minmax(90px,1fr))}.ai-chat-action-date-btn{background:var(--bg-primary,#fff);border:1px solid var(--border-default,#e5e7eb);border-radius:var(--radius-md,8px);color:var(--text-primary,#3e3e3e);cursor:pointer;font-size:var(--text-xs,12px);font-weight:var(--font-weight-medium,500);padding:8px 10px;text-align:center;transition:all .15s ease}.ai-chat-action-date-btn:hover{background:rgba(59,130,246,.05);border-color:var(--action-accent,var(--primary-color,#3b82f6))}.ai-chat-action-date-btn.active{background:var(--action-accent,var(--primary-color,#3b82f6));border-color:var(--action-accent,var(--primary-color,#3b82f6));color:#fff}.ai-chat-widget.dark .ai-chat-action-date-btn,.chakra-ui-dark .ai-chat-action-date-btn,.dark .ai-chat-action-date-btn,[data-theme=dark] .ai-chat-action-date-btn{background:rgba(0,0,0,.2);border-color:hsla(0,0%,100%,.1);color:#fff}.ai-chat-widget.dark .ai-chat-action-date-btn:hover,.chakra-ui-dark .ai-chat-action-date-btn:hover,.dark .ai-chat-action-date-btn:hover,[data-theme=dark] .ai-chat-action-date-btn:hover{background:rgba(59,130,246,.15);border-color:var(--action-accent,var(--primary-color,#3b82f6))}.ai-chat-widget.dark .ai-chat-action-date-btn.active,.chakra-ui-dark .ai-chat-action-date-btn.active,.dark .ai-chat-action-date-btn.active,[data-theme=dark] .ai-chat-action-date-btn.active{background:var(--action-accent,var(--primary-color,#3b82f6));border-color:var(--action-accent,var(--primary-color,#3b82f6));color:#fff}.ai-chat-action-time-grid{display:grid;gap:var(--space-xs,6px);grid-template-columns:repeat(auto-fill,minmax(100px,1fr))}.ai-chat-action-time-btn{background:var(--bg-primary,#fff);border:1px solid var(--border-default,#e5e7eb);border-radius:var(--radius-md,8px);color:var(--text-primary,#3e3e3e);cursor:pointer;font-size:var(--text-xs,12px);font-weight:var(--font-weight-medium,500);padding:8px 10px;text-align:center;transition:all .15s ease}.ai-chat-action-time-btn:hover{background:rgba(59,130,246,.05);border-color:var(--action-accent,var(--primary-color,#3b82f6))}.ai-chat-action-time-btn.active{background:var(--action-accent,var(--primary-color,#3b82f6));border-color:var(--action-accent,var(--primary-color,#3b82f6));color:#fff}.ai-chat-widget.dark .ai-chat-action-time-btn,.chakra-ui-dark .ai-chat-action-time-btn,.dark .ai-chat-action-time-btn,[data-theme=dark] .ai-chat-action-time-btn{background:rgba(0,0,0,.2);border-color:hsla(0,0%,100%,.1);color:#fff}.ai-chat-widget.dark .ai-chat-action-time-btn:hover,.chakra-ui-dark .ai-chat-action-time-btn:hover,.dark .ai-chat-action-time-btn:hover,[data-theme=dark] .ai-chat-action-time-btn:hover{background:rgba(59,130,246,.15);border-color:var(--action-accent,var(--primary-color,#3b82f6))}.ai-chat-widget.dark .ai-chat-action-time-btn.active,.chakra-ui-dark .ai-chat-action-time-btn.active,.dark .ai-chat-action-time-btn.active,[data-theme=dark] .ai-chat-action-time-btn.active{background:var(--action-accent,var(--primary-color,#3b82f6));border-color:var(--action-accent,var(--primary-color,#3b82f6));color:#fff}.ai-chat-action-button{background:var(--action-accent,var(--primary-color,#3b82f6));border:none;border-radius:9999px;color:#fff;cursor:pointer;font-size:var(--text-sm,13px);font-weight:var(--font-weight-semibold,600);padding:12px 16px;transition:all .2s ease;width:100%}.ai-chat-action-button:hover:not(:disabled){opacity:.9;transform:translateY(-1px)}.ai-chat-action-button:disabled{cursor:not-allowed;opacity:.5}.ai-chat-action-error{background:rgba(239,68,68,.1);border-radius:var(--radius-md,8px);color:#dc2626;font-size:var(--text-sm,13px);padding:10px 12px}.ai-chat-widget.dark .ai-chat-action-error,.chakra-ui-dark .ai-chat-action-error,.dark .ai-chat-action-error,[data-theme=dark] .ai-chat-action-error{background:rgba(239,68,68,.2);color:#fca5a5}.ai-chat-action-hint{color:var(--text-muted,#9ca3af);font-size:var(--text-sm,13px);padding:var(--space-sm,8px);text-align:center}.ai-chat-link-preview{--action-accent:var(--primary-color,#3b82f6);background:var(--bg-secondary,#f4f4f4);border:1px solid var(--border-subtle,rgba(0,0,0,.08));border-radius:var(--radius-lg,12px);cursor:pointer;display:flex;flex-direction:column;margin-top:var(--space-sm,8px);overflow:hidden;position:relative;transition:border-color .2s,box-shadow .2s,transform .2s}.ai-chat-link-preview:hover{border-color:var(--action-accent);box-shadow:0 2px 8px rgba(0,0,0,.1);transform:translateY(-1px)}.ai-chat-link-preview:focus{border-color:var(--action-accent);box-shadow:0 0 0 2px rgba(59,130,246,.2);outline:none}.ai-chat-widget.dark .ai-chat-link-preview,.chakra-ui-dark .ai-chat-link-preview,.dark .ai-chat-link-preview,[data-theme=dark] .ai-chat-link-preview{background:var(--bg-secondary,#3a3a3a);border-color:hsla(0,0%,100%,.08)}.ai-chat-widget.dark .ai-chat-link-preview:hover,.chakra-ui-dark .ai-chat-link-preview:hover,.dark .ai-chat-link-preview:hover,[data-theme=dark] .ai-chat-link-preview:hover{border-color:var(--action-accent);box-shadow:0 2px 12px rgba(0,0,0,.3)}.ai-chat-link-preview__image{aspect-ratio:1.91/1;background:var(--bg-muted,#e5e7eb);overflow:hidden;width:100%}.ai-chat-widget.dark .ai-chat-link-preview__image,.chakra-ui-dark .ai-chat-link-preview__image,.dark .ai-chat-link-preview__image,[data-theme=dark] .ai-chat-link-preview__image{background:hsla(0,0%,100%,.05)}.ai-chat-link-preview__image img{height:100%;object-fit:cover;width:100%}.ai-chat-link-preview__content{flex:1;padding:12px}.ai-chat-link-preview__site{align-items:center;display:flex;gap:6px;margin-bottom:6px}.ai-chat-link-preview__favicon{border-radius:2px;flex-shrink:0;height:16px;width:16px}.ai-chat-link-preview__domain{color:var(--text-muted,#71717a);font-size:12px;letter-spacing:.5px;overflow:hidden;text-overflow:ellipsis;text-transform:uppercase;white-space:nowrap}.ai-chat-link-preview__title{-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical;color:var(--text-primary,#3e3e3e);display:-webkit-box;font-size:15px;font-weight:600;line-height:1.3;margin:0 0 4px;overflow:hidden}.ai-chat-widget.dark .ai-chat-link-preview__title,.chakra-ui-dark .ai-chat-link-preview__title,.dark .ai-chat-link-preview__title,[data-theme=dark] .ai-chat-link-preview__title{color:#fff}.ai-chat-link-preview__description{-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical;color:var(--text-muted,#71717a);display:-webkit-box;font-size:13px;line-height:1.4;margin:0;overflow:hidden}.ai-chat-link-preview__context{border-top:1px solid var(--border-subtle,rgba(0,0,0,.08));color:var(--text-muted,#71717a);font-size:12px;font-style:italic;margin:8px 0 0;padding-top:8px}.ai-chat-widget.dark .ai-chat-link-preview__context,.chakra-ui-dark .ai-chat-link-preview__context,.dark .ai-chat-link-preview__context,[data-theme=dark] .ai-chat-link-preview__context{border-color:hsla(0,0%,100%,.08)}.ai-chat-link-preview__arrow{align-items:center;background:var(--bg-primary,#fff);border-radius:50%;box-shadow:0 1px 3px rgba(0,0,0,.1);color:var(--text-muted,#71717a);display:flex;height:28px;justify-content:center;opacity:0;position:absolute;right:12px;top:12px;transition:opacity .2s,background .2s;width:28px}.ai-chat-link-preview:hover .ai-chat-link-preview__arrow{opacity:1}.ai-chat-widget.dark .ai-chat-link-preview__arrow,.chakra-ui-dark .ai-chat-link-preview__arrow,.dark .ai-chat-link-preview__arrow,[data-theme=dark] .ai-chat-link-preview__arrow{background:hsla(0,0%,100%,.1);color:#fff}.ai-chat-link-preview--error{border-color:rgba(239,68,68,.3)}.ai-chat-link-preview--error:hover{border-color:rgba(239,68,68,.5)}.ai-chat-link-preview__error-text{color:#dc2626;font-size:12px;margin:4px 0 0}.ai-chat-widget.dark .ai-chat-link-preview__error-text,.chakra-ui-dark .ai-chat-link-preview__error-text,.dark .ai-chat-link-preview__error-text,[data-theme=dark] .ai-chat-link-preview__error-text{color:#fca5a5}.ai-chat-video-player{--action-accent:var(--primary-color,#3b82f6);background:var(--bg-secondary,#f4f4f4);border-radius:var(--radius-lg,12px);display:flex;flex-direction:column;margin-top:var(--space-sm,8px);overflow:hidden}.ai-chat-widget.dark .ai-chat-video-player,.chakra-ui-dark .ai-chat-video-player,.dark .ai-chat-video-player,[data-theme=dark] .ai-chat-video-player{background:var(--bg-secondary,#3a3a3a)}.ai-chat-video-player__header{align-items:center;color:var(--action-accent,var(--primary-color,#3b82f6));display:flex;gap:8px;padding:12px 12px 8px}.ai-chat-video-player__title{color:var(--text-primary,#3e3e3e);font-size:14px;font-weight:600}.ai-chat-widget.dark .ai-chat-video-player__title,.chakra-ui-dark .ai-chat-video-player__title,.dark .ai-chat-video-player__title,[data-theme=dark] .ai-chat-video-player__title{color:#fff}.ai-chat-video-player__container{aspect-ratio:16/9;background:#000;position:relative;width:100%}.ai-chat-video-player__thumbnail{cursor:pointer;height:100%;position:relative;width:100%}.ai-chat-video-player__thumbnail img{height:100%;object-fit:cover;width:100%}.ai-chat-video-player__placeholder{align-items:center;background:linear-gradient(135deg,#1a1a2e,#16213e);cursor:pointer;display:flex;flex-direction:column;gap:8px;height:100%;justify-content:center;position:relative;width:100%}.ai-chat-video-player__click-text{color:hsla(0,0%,100%,.7);font-size:13px}.ai-chat-video-player__play-btn{align-items:center;background:rgba(0,0,0,.7);border:none;border-radius:50%;color:#fff;cursor:pointer;display:flex;height:64px;justify-content:center;left:50%;position:absolute;top:50%;transform:translate(-50%,-50%);transition:background .2s,transform .2s;width:64px}.ai-chat-video-player__placeholder .ai-chat-video-player__play-btn{left:auto;position:relative;top:auto;transform:none}.ai-chat-video-player__play-btn:hover{background:rgba(0,0,0,.9);transform:translate(-50%,-50%) scale(1.05)}.ai-chat-video-player__placeholder .ai-chat-video-player__play-btn:hover{transform:scale(1.05)}.ai-chat-video-player__provider-badge{background:rgba(0,0,0,.8);border-radius:4px;bottom:8px;color:#fff;font-size:11px;font-weight:600;letter-spacing:.5px;padding:4px 8px;position:absolute;right:8px;text-transform:uppercase}.ai-chat-video-player__iframe,.ai-chat-video-player__video{border:none;height:100%;left:0;position:absolute;top:0;width:100%}.ai-chat-video-player__error{align-items:center;background:rgba(239,68,68,.1);color:#dc2626;display:flex;font-size:13px;height:100%;justify-content:center;padding:16px;text-align:center;width:100%}.ai-chat-widget.dark .ai-chat-video-player__error,.chakra-ui-dark .ai-chat-video-player__error,.dark .ai-chat-video-player__error,[data-theme=dark] .ai-chat-video-player__error{background:rgba(239,68,68,.2);color:#fca5a5}.ai-chat-video-player__context{border-top:1px solid var(--border-subtle,rgba(0,0,0,.08));color:var(--text-muted,#71717a);font-size:12px;font-style:italic;padding:10px 12px}.ai-chat-widget.dark .ai-chat-video-player__context,.chakra-ui-dark .ai-chat-video-player__context,.dark .ai-chat-video-player__context,[data-theme=dark] .ai-chat-video-player__context{border-color:hsla(0,0%,100%,.08)}.ai-chat-location-card{background:var(--bg-secondary,#fff);border:1px solid var(--border-subtle,rgba(0,0,0,.08));border-radius:12px;overflow:hidden}.ai-chat-widget.dark .ai-chat-location-card,.chakra-ui-dark .ai-chat-location-card,.dark .ai-chat-location-card,[data-theme=dark] .ai-chat-location-card{background:hsla(0,0%,100%,.05);border-color:hsla(0,0%,100%,.1)}.ai-chat-location-card--compact{border-radius:10px}.ai-chat-location-card--error{color:var(--text-muted,#71717a);padding:16px;text-align:center}.ai-chat-location-card__map{background:var(--bg-muted,#f4f4f5);position:relative;width:100%}.ai-chat-widget.dark .ai-chat-location-card__map,.chakra-ui-dark .ai-chat-location-card__map,.dark .ai-chat-location-card__map,[data-theme=dark] .ai-chat-location-card__map{background:rgba(0,0,0,.2)}.ai-chat-location-card__map iframe{border:none;display:block;height:100%;width:100%}.ai-chat-location-card__content{padding:14px}.ai-chat-location-card--compact .ai-chat-location-card__content{padding:12px}.ai-chat-location-card__header{align-items:center;display:flex;flex-wrap:wrap;gap:8px;margin-bottom:8px}.ai-chat-location-card__name{color:var(--text-primary,#18181b);flex:1;font-size:16px;font-weight:600;margin:0;min-width:0}.ai-chat-widget.dark .ai-chat-location-card__name,.chakra-ui-dark .ai-chat-location-card__name,.dark .ai-chat-location-card__name,[data-theme=dark] .ai-chat-location-card__name{color:#fff}.ai-chat-location-card--compact .ai-chat-location-card__name{font-size:14px}.ai-chat-location-card__type{background:var(--bg-muted,#f4f4f5);border-radius:10px;color:var(--text-muted,#71717a);font-size:11px;font-weight:500;letter-spacing:.5px;padding:2px 8px;text-transform:uppercase}.ai-chat-widget.dark .ai-chat-location-card__type,.chakra-ui-dark .ai-chat-location-card__type,.dark .ai-chat-location-card__type,[data-theme=dark] .ai-chat-location-card__type{background:hsla(0,0%,100%,.1);color:hsla(0,0%,100%,.7)}.ai-chat-location-card__status{border-radius:12px;font-size:12px;font-weight:500;padding:2px 8px}.ai-chat-location-card__status--open{background:#dcfce7;color:#16a34a}.ai-chat-location-card__status--closed{background:#fef2f2;color:#dc2626}.ai-chat-widget.dark .ai-chat-location-card__status--open,.chakra-ui-dark .ai-chat-location-card__status--open,.dark .ai-chat-location-card__status--open,[data-theme=dark] .ai-chat-location-card__status--open{background:rgba(34,197,94,.2);color:#4ade80}.ai-chat-widget.dark .ai-chat-location-card__status--closed,.chakra-ui-dark .ai-chat-location-card__status--closed,.dark .ai-chat-location-card__status--closed,[data-theme=dark] .ai-chat-location-card__status--closed{background:rgba(239,68,68,.2);color:#fca5a5}.ai-chat-location-card__address{align-items:flex-start;color:var(--text-muted,#71717a);display:flex;font-size:13px;gap:6px;line-height:1.4;margin:0 0 8px}.ai-chat-location-card__address svg{flex-shrink:0;margin-top:2px}.ai-chat-location-card__description{color:var(--text-muted,#71717a);font-size:13px;line-height:1.4;margin:0 0 8px}.ai-chat-location-card__hours{align-items:flex-start;color:var(--text-muted,#71717a);display:flex;font-size:13px;gap:6px;margin-bottom:8px}.ai-chat-location-card__hours svg{flex-shrink:0;margin-top:2px}.ai-chat-location-card__hours-list{flex:1}.ai-chat-location-card__hours-toggle{align-items:center;background:none;border:none;color:inherit;cursor:pointer;display:flex;font:inherit;gap:4px;padding:0}.ai-chat-location-card__hours-toggle:hover{text-decoration:underline}.ai-chat-location-card__hours-full{list-style:none;margin:8px 0 0;padding:0}.ai-chat-location-card__hours-full li{display:flex;font-size:12px;justify-content:space-between;padding:4px 0}.ai-chat-location-card__hours-today{color:var(--text-primary,#18181b);font-weight:600}.ai-chat-widget.dark .ai-chat-location-card__hours-today,.chakra-ui-dark .ai-chat-location-card__hours-today,.dark .ai-chat-location-card__hours-today,[data-theme=dark] .ai-chat-location-card__hours-today{color:#fff}.ai-chat-location-card__phone{align-items:center;background:none;border:none;color:var(--action-accent,#3b82f6);cursor:pointer;display:flex;font-size:13px;gap:6px;margin-bottom:12px;padding:0}.ai-chat-location-card__phone:hover{text-decoration:underline}.ai-chat-location-card__actions{display:flex;gap:8px;justify-content:flex-start;width:100%}.ai-chat-location-card__button{align-items:center;background:var(--action-accent,#3b82f6);border:none;border-radius:20px;color:#fff;cursor:pointer;display:flex;flex:1;font-size:13px;font-weight:500;gap:6px;justify-content:center;padding:10px 16px;transition:opacity .2s}.ai-chat-location-card__button:hover{opacity:.9}.ai-chat-location-card--compact .ai-chat-location-card__button{font-size:12px;padding:8px 12px}.ai-chat-location-card__link{align-items:center;background:var(--bg-secondary,#fff);border:1px solid var(--border-subtle,rgba(0,0,0,.08));border-radius:20px;color:var(--text-primary,#18181b);display:flex;font-size:13px;gap:6px;padding:10px 16px;text-decoration:none;transition:border-color .2s}.ai-chat-widget.dark .ai-chat-location-card__link,.chakra-ui-dark .ai-chat-location-card__link,.dark .ai-chat-location-card__link,[data-theme=dark] .ai-chat-location-card__link{background:hsla(0,0%,100%,.05);border-color:hsla(0,0%,100%,.1);color:#fff}.ai-chat-location-card__link:hover{border-color:var(--action-accent,#3b82f6)}.ai-chat-location-card-list{display:flex;flex-direction:column;gap:8px}.ai-chat-location-card-list__header{align-items:center;color:var(--text-muted,#71717a);display:flex;font-size:13px;font-weight:500;gap:6px;margin-bottom:4px;padding:0 4px}.ai-chat-location-card-list__stack{display:grid;gap:12px;grid-template-columns:repeat(3,minmax(0,1fr))}@media (max-width:1200px){.ai-chat-location-card-list__stack{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (max-width:768px){.ai-chat-location-card-list__stack{grid-template-columns:1fr}}@media (max-width:520px){.ai-chat-location-card-list__stack{grid-template-columns:1fr!important}}@media (min-width:521px) and (max-width:900px){.ai-chat-location-card-list__stack{grid-template-columns:repeat(2,minmax(0,1fr))!important}}.ai-chat-location-card-list__grid{display:grid;gap:8px;grid-template-columns:repeat(2,1fr)}@media (max-width:400px){.ai-chat-location-card-list__grid{grid-template-columns:1fr}}.ai-chat-location-card-list__carousel{-webkit-overflow-scrolling:touch;-ms-overflow-style:none;display:flex;gap:8px;overflow-x:auto;padding-bottom:4px;scroll-snap-type:x mandatory;scrollbar-width:none}.ai-chat-location-card-list__carousel::-webkit-scrollbar{display:none}.ai-chat-location-card-list__carousel>.ai-chat-location-card{flex:0 0 280px;scroll-snap-align:start}.ai-chat-widget,.chat-ui{--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:8px;--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,.chat-ui.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,.chat-ui{-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 ai-chat-window-open{0%{opacity:0;transform:scale(.9) translateY(20px)}to{opacity:1;transform:scale(1) translateY(0)}}@keyframes ai-chat-window-close{0%{opacity:1;transform:scale(1) translateY(0)}to{opacity:0;transform:scale(.9) translateY(20px)}}@keyframes ai-chat-message-slide-in{0%{opacity:0;transform:translateY(12px)}to{opacity:1;transform:translateY(0)}}@keyframes ai-chat-welcome-fade-in{0%{opacity:0;transform:translateY(16px)}to{opacity:1;transform:translateY(0)}}@keyframes ai-chat-typing-pulse{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 ai-chat-feedback-morph{0%{opacity:.5;transform:scale(.8)}to{opacity:1;transform:scale(1)}}@keyframes ai-chat-checkmark-pop{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)}}@keyframes ai-chat-tool-gradient{0%{background-position:200% 0}to{background-position:-200% 0}}@media (max-width:480px){.ai-chat-widget-container.is-open{height:100vh!important;inset:0!important;width:100vw!important}.ai-chat-widget-container.is-open .ai-chat-window{animation:none!important;border-radius:0!important;height:100%!important;inset:0!important;max-height:100%!important;max-width:100%!important;position:absolute!important;width:100%!important}.ai-chat-widget-container.is-open .ai-chat-button{display:none!important;visibility:hidden!important}.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-window{animation:ai-chat-window-open var(--duration-slow,.35s) var(--spring-bounce);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:ai-chat-window-close var(--duration-normal) var(--spring-smooth) forwards}.ai-chat-window.size-small{height:500px;width:380px}.ai-chat-window.size-medium,.ai-chat-window.size-small{max-height:calc(100vh - 100px);max-width:calc(100vw - 40px)}.ai-chat-window.size-medium{height:600px;width:420px}.ai-chat-window.size-large{height:700px;max-height:calc(100vh - 100px);max-width:calc(100vw - 40px);width:480px}.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,.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:color var(--duration-fast) ease;width:32px}.ai-chat-close-button:hover,.ai-chat-header-button:hover{color:var(--text-primary)}.ai-chat-close-button:active,.ai-chat-header-button:active{transform:scale(.95)}.ai-chat-close-button svg,.ai-chat-header-button svg{height:22px;width:22px}.ai-chat-button{align-items:center;background:var(--button-color,var(--btn-primary-bg));border:1px solid var(--border-default,#d3d3d3);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:opacity var(--duration-fast) ease;width:var(--button-size,56px);z-index:1}.ai-chat-button:hover{opacity:.9}.ai-chat-button:active{opacity:.8}.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-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:flex-end;background:var(--input-bg,#f4f4f4);border:1px solid var(--input-border,#d3d3d3);border-radius:var(--radius-input,62px);box-sizing:border-box;display:flex;gap:0;height:52px;overflow:hidden;padding:6px 6px 6px 16px;position:relative;transition:all var(--duration-fast,.15s) ease;z-index:5}.ai-chat-input-wrapper.multiline{border-radius:14px!important;min-height:64px;padding:10px 10px 10px 14px}.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{word-wrap:break-word!important;background:transparent!important;border:none!important;border-radius:0!important;box-shadow:none!important;box-sizing:border-box!important;color:var(--input-text,#000)!important;flex:1!important;font-family:inherit!important;font-size:var(--text-md,15px)!important;height:40px!important;line-height:20px!important;margin:0!important;max-height:40px!important;min-height:40px!important;min-width:0!important;outline:none!important;overflow-wrap:anywhere!important;overflow-x:hidden!important;overflow-y:auto!important;padding:10px var(--space-sm,8px)!important;resize:none!important;white-space:pre-wrap!important;width:0!important;word-break:break-word!important}.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;align-self: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;align-self: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;min-height:40px;min-width:40px;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-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:ai-chat-message-slide-in .2s var(--spring-bounce);display:flex;flex-direction:column;max-width:90%}.ai-chat-message.user{align-items:flex-end;align-self:flex-end}.ai-chat-message.assistant{align-items:flex-start;align-self:flex-start;max-width:100%}.ai-chat-message.tool{align-self:flex-start;margin:0 -16px;max-width:100%;padding:0;width:calc(100% + 32px)}.ai-chat-message-content{word-wrap:break-word;border-radius:18px;font-size:var(--text-md,15px);line-height:var(--line-height-relaxed,1.6);overflow-wrap:break-word;padding:8px 14px}.ai-chat-message.user .ai-chat-message-content{background:var(--user-bg,#f4f3f0);border-radius:18px;color:var(--user-text,#000)}.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.assistant .ai-chat-message-content{background:var(--agent-bg,transparent);color:var(--agent-text,#000);padding:0}.ai-chat-widget.dark .ai-chat-message.assistant .ai-chat-message-content{color:var(--agent-text,#fff)}.ai-chat-message-timestamp{color:var(--text-muted,#71717a);font-size:var(--text-xs,12px);margin-top:var(--space-xs,4px);padding:0 var(--space-xs,4px)}.ai-chat-welcome{animation:ai-chat-welcome-fade-in .3s var(--spring-smooth);display:flex;flex-direction:column;gap:var(--space-md,16px);padding:var(--space-lg,24px) 0}.ai-chat-welcome-title{color:var(--text-primary,#3e3e3e);font-size:var(--text-2xl,28px);font-weight:var(--font-weight-bold,700);line-height:var(--line-height-tight,1.3)}.ai-chat-widget.dark .ai-chat-welcome-title{color:var(--text-primary,#fff)}.ai-chat-welcome-text{color:var(--text-secondary,#000);font-size:var(--text-md,15px);line-height:var(--line-height-relaxed,1.6);max-width:100%}.ai-chat-widget.dark .ai-chat-welcome-text{color:var(--text-secondary,#fff)}.ai-chat-typing{align-items:center;display:flex;gap:var(--space-xs,4px);padding:var(--space-sm,8px) var(--space-md,16px)}.ai-chat-typing-dot{animation:ai-chat-typing-bounce 1.4s ease-in-out infinite both;background:var(--text-muted,#71717a);border-radius:50%;height:8px;width:8px}.ai-chat-typing-dot:first-child{animation-delay:-.32s}.ai-chat-typing-dot:nth-child(2){animation-delay:-.16s}.ai-chat-typing-dot:nth-child(3){animation-delay:0s}@keyframes ai-chat-typing-bounce{0%,80%,to{opacity:.4;transform:scale(.6)}40%{opacity:1;transform:scale(1)}}.ai-chat-scroll-button{align-items:center;background:var(--bg-secondary,#f4f4f5);border:1px solid var(--border-subtle,rgba(0,0,0,.1));border-radius:50%;bottom:80px;box-shadow:0 2px 8px rgba(0,0,0,.1);color:var(--text-secondary,#71717a);cursor:pointer;display:flex;height:36px;justify-content:center;left:50%;opacity:0;pointer-events:none;position:absolute;transform:translateX(-50%);transition:background .15s ease,box-shadow .15s ease,opacity .15s ease,visibility .15s ease;visibility:hidden;width:36px;z-index:15}.ai-chat-scroll-button.visible{opacity:1;pointer-events:auto;visibility:visible}.ai-chat-scroll-button:hover{background:var(--bg-tertiary,#e4e4e7);box-shadow:0 4px 12px rgba(0,0,0,.15)}.ai-chat-scroll-button:active{background:var(--bg-tertiary,#d4d4d8)}.ai-chat-widget.dark .ai-chat-scroll-button{background:var(--bg-secondary,#3f3f46);border-color:var(--border-subtle,hsla(0,0%,100%,.1));box-shadow:0 2px 8px rgba(0,0,0,.3);color:var(--text-secondary,#a1a1aa)}.ai-chat-widget.dark .ai-chat-scroll-button:hover{background:var(--bg-tertiary,#52525b);box-shadow:0 4px 12px rgba(0,0,0,.4)}.ai-chat-error{background:var(--bg-secondary);border-radius:var(--radius-chat-bubble);color:var(--text-primary);font-size:var(--text-md);margin:0 auto;padding:10px var(--space-md)}.ai-chat-message.assistant .ai-chat-message-content p{margin:0 0 var(--space-sm) 0}.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:var(--space-sm) 0;padding-left:var(--space-lg)}.ai-chat-message.assistant .ai-chat-message-content li{margin-bottom:var(--space-xs)}.ai-chat-message.assistant .ai-chat-message-content code{background:rgba(0,0,0,.05);border-radius:var(--radius-sm);font-family:SF Mono,Monaco,Cascadia Code,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,.05);border-radius:var(--radius-md);margin:var(--space-sm) 0;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%,.05)}.ai-chat-message.assistant .ai-chat-message-content pre code{background:transparent;padding:0}.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 strong{font-weight:var(--font-weight-semibold)}.ai-chat-message.assistant .ai-chat-message-content blockquote{border-left:3px solid var(--border-default);color:var(--text-muted);margin:var(--space-sm) 0;padding-left:var(--space-md)}.ai-chat-message.assistant .ai-chat-message-content hr{border:none;border-top:1px solid var(--border-subtle,rgba(0,0,0,.1));margin:var(--space-lg,24px) 0}.ai-chat-widget.dark .ai-chat-message.assistant .ai-chat-message-content hr{border-top-color:var(--border-subtle,hsla(0,0%,100%,.1))}.ai-chat-message.assistant .ai-chat-message-content table{border-collapse:collapse;font-size:var(--text-sm);margin:var(--space-sm) 0;width:100%}.ai-chat-message.assistant .ai-chat-message-content td,.ai-chat-message.assistant .ai-chat-message-content th{border:1px solid var(--border-subtle);padding:var(--space-sm);text-align:left}.ai-chat-message.assistant .ai-chat-message-content th{font-weight:var(--font-weight-semibold);white-space:nowrap}.ai-chat-message.assistant .ai-chat-message-content tbody tr:nth-child(2n){background:rgba(0,0,0,.02)}.ai-chat-widget.dark .ai-chat-message.assistant .ai-chat-message-content tbody tr:nth-child(2n){background:hsla(0,0%,100%,.03)}.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{align-items:center;background:transparent;border:1px solid var(--border-default,#d4d4d8);border-radius:var(--radius-preset-badge,18px);color:var(--text-primary,#18181b);cursor:pointer;display:inline-flex;font-size:14px;font-weight:400;gap:6px;justify-content:center;line-height:1.3;max-width:100%;overflow:hidden;padding:8px 14px;text-overflow:ellipsis;transition:background .15s ease,border-color .15s ease,transform .1s ease;white-space:nowrap}.ai-chat-widget.dark .ai-chat-suggested-question{background:transparent;border-color:var(--border-subtle,#52525b);color:var(--text-primary,#fafafa)}.ai-chat-suggested-question-text{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ai-chat-suggested-question:hover{background:var(--bg-hover,#f4f4f5);border-color:var(--border-default,#d4d4d8)}.ai-chat-widget.dark .ai-chat-suggested-question:hover{background:var(--bg-hover,#3f3f46);border-color:var(--border-subtle,#52525b)}.ai-chat-suggested-question:active{transform:scale(.98)}.ai-chat-suggested-question.action-type{border:none}.ai-chat-suggested-question.action-type,.ai-chat-widget.dark .ai-chat-suggested-question.action-type{background:var(--primary-color,var(--button-color,#ef4444));color:var(--button-icon-color,#fff)}.ai-chat-suggested-question.action-type:hover{background:var(--primary-color,var(--button-color,#ef4444));opacity:.9}.ai-chat-suggested-question-icon{align-items:center;display:flex;flex-shrink:0;justify-content:center}.ai-chat-suggested-question:not(.action-type) .ai-chat-suggested-question-icon{display:none}.ai-chat-follow-up-suggestions{box-sizing:border-box;margin:0;padding:8px 16px 0;width:100%}.ai-chat-follow-up-list{align-items:flex-end;display:flex;flex-direction:column;gap:6px}.ai-chat-follow-up-item{align-items:center;border:none;border-radius:var(--radius-preset-badge,18px);cursor:pointer;display:inline-flex;font-size:14px;font-weight:400;gap:6px;justify-content:center;line-height:1.3;max-width:100%;overflow:hidden;padding:8px 14px;text-overflow:ellipsis;transition:opacity .15s ease,transform .1s ease;white-space:nowrap}.ai-chat-follow-up-item,.ai-chat-widget.dark .ai-chat-follow-up-item{background:var(--primary-color,var(--button-color,#07f));color:var(--button-icon-color,#fff)}.ai-chat-follow-up-item:hover{opacity:.9}.ai-chat-follow-up-item:active{transform:scale(.98)}.ai-chat-follow-up-item.question-type{background:transparent;border:1px solid var(--border-default,#d4d4d8);color:var(--text-primary,#18181b)}.ai-chat-widget.dark .ai-chat-follow-up-item.question-type,.dark .ai-chat-follow-up-item.question-type,[data-theme=dark] .ai-chat-follow-up-item.question-type{background:transparent;border:1px solid var(--border-subtle,#52525b);color:var(--text-primary,#fafafa)}@media (prefers-color-scheme:dark){.ai-chat-follow-up-item.question-type{background:transparent;border:1px solid var(--border-subtle,#52525b);color:var(--text-primary,#fafafa)}}.ai-chat-follow-up-item.question-type:hover{background:var(--bg-hover,#f4f4f5);opacity:1}.ai-chat-widget.dark .ai-chat-follow-up-item.question-type:hover,.dark .ai-chat-follow-up-item.question-type:hover,[data-theme=dark] .ai-chat-follow-up-item.question-type:hover{background:var(--bg-hover,#3f3f46);opacity:1}@media (prefers-color-scheme:dark){.ai-chat-follow-up-item.question-type:hover{background:var(--bg-hover,#3f3f46);opacity:1}}.ai-chat-follow-up-item.action-type{background:var(--primary-color,var(--button-color,#07f));border:none;color:var(--button-icon-color,#fff)}.ai-chat-follow-up-icon{align-items:center;display:flex;flex-shrink:0;justify-content:center}.ai-chat-follow-up-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.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:ai-chat-feedback-morph .3s var(--spring-bounce);gap:var(--space-xs)}.ai-chat-feedback-message{align-items:center;display:flex;gap:4px;margin-left:var(--space-xxs)}.ai-chat-feedback-checkmark{animation:ai-chat-checkmark-pop .3s var(--spring-bounce);color:#10b981;font-size:var(--text-md);font-weight:700}.ai-chat-feedback-text{color:#10b981;font-size:var(--text-xs);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-xs) 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:center;background:var(--user-bg,#f4f4f5);border-radius:var(--radius-history-item,15px);display:flex;flex:0 0 auto;flex-direction:row;height:var(--history-item-height,36px);margin:0;overflow:hidden;transition:background var(--duration-fast,.15s) ease;width:100%}.ai-chat-history-item-content{align-items:center;background:transparent;border:none;cursor:pointer;display:flex;flex:1;flex-direction:row;height:100%;min-width:0;padding:0 var(--space-xs,4px) 0 var(--space-md,16px);text-align:left}.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);flex:1;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-history-item-delete{align-items:center;background:transparent;border:none;border-radius:var(--radius-sm,6px);color:var(--text-muted,#71717a);cursor:pointer;display:flex;flex-shrink:0;height:24px;justify-content:center;margin-left:auto;margin-right:var(--space-xs,4px);opacity:0;transition:opacity var(--duration-fast,.15s) ease,background var(--duration-fast,.15s) ease,color var(--duration-fast,.15s) ease;width:24px}.ai-chat-history-item-delete svg{height:14px;width:14px}.ai-chat-history-item:hover .ai-chat-history-item-delete{opacity:1}.ai-chat-history-item-delete:hover{background:rgba(239,68,68,.1);color:#ef4444}.ai-chat-widget.dark .ai-chat-history-item-delete:hover{background:rgba(239,68,68,.2);color:#f87171}.ai-chat-tool-row{align-items:center;display:flex;gap:10px;margin:2px 0;padding:0 16px}.ai-chat-tool-gear{color:#1f2937;flex-shrink:0;height:20px;width:20px}.ai-chat-tool-gear.spinning{animation:ai-chat-gear-spin 1.5s linear infinite}.ai-chat-tool-badges{align-items:center;display:flex;flex-wrap:wrap;gap:8px}.ai-chat-tool-badge{align-items:center;background:#e5e7eb;border:1px solid #d1d5db;border-radius:var(--radius-action-badge,8px);color:#1f2937;display:inline-flex;font-size:12px;font-weight:500;gap:4px;line-height:1.2;padding:5px 12px;transition:all .2s ease;white-space:nowrap}.ai-chat-tool-badge.loading{animation:ai-chat-tool-gradient 2s linear infinite;background:linear-gradient(90deg,var(--tool-loading-bg-1,#e0e0e0) 0,var(--tool-loading-bg-2,#f0f0f0) 25%,var(--tool-loading-bg-3,#fff) 50%,var(--tool-loading-bg-2,#f0f0f0) 75%,var(--tool-loading-bg-1,#e0e0e0) 100%);background-size:200% 100%;color:var(--tool-loading-text,#1a1a1a);position:relative}.ai-chat-widget:not(.dark) .ai-chat-tool-badge.loading{--tool-loading-bg-1:#2a2a2a;--tool-loading-bg-2:#3a3a3a;--tool-loading-bg-3:#4a4a4a;--tool-loading-text:#fff}.ai-chat-tool-badge.completed{background:#e5e7eb;border:1px solid #d1d5db;color:#1f2937}.ai-chat-widget.dark .ai-chat-tool-badge,.ai-chat-widget[data-theme=dark] .ai-chat-tool-badge,.chakra-ui-dark .ai-chat-tool-badge,.dark .ai-chat-tool-badge,[data-theme=dark] .ai-chat-tool-badge,html.dark .ai-chat-tool-badge{background:hsla(0,0%,100%,.12);border:1px solid hsla(0,0%,100%,.2);color:hsla(0,0%,100%,.9)}.ai-chat-widget.dark .ai-chat-tool-gear,.ai-chat-widget[data-theme=dark] .ai-chat-tool-gear,.chakra-ui-dark .ai-chat-tool-gear,.dark .ai-chat-tool-gear,[data-theme=dark] .ai-chat-tool-gear,html.dark .ai-chat-tool-gear{color:#fff}.ai-chat-tool-badge.error{background:var(--tool-error-bg,rgba(239,68,68,.15));color:var(--tool-error-text,#ef4444)}.ai-chat-tool-badge .ai-chat-tool-check{color:#fff;flex-shrink:0}.ai-chat-tool-badge .ai-chat-tool-error{color:#ef4444;flex-shrink:0}.tool-name{font-weight:500;line-height:1.2;white-space:nowrap}.ai-chat-tool-action{box-sizing:border-box;padding:0 16px;width:100%}";
|
|
47094
|
+
var css_248z$1 = ".ai-chat-message{animation:ai-chat-message-appear .2s var(--chat-ease-bounce);max-width:85%}.ai-chat-message-content{border-radius:var(--chat-radius-bubble,14px);font-size:var(--chat-text-md,15px);line-height:var(--chat-line-relaxed,1.6);padding:var(--chat-space-sm,8px) var(--chat-space-md,16px)}.ai-chat-message.user .ai-chat-message-content{background:var(--chat-user-bg,#f4f3f0);border-bottom-right-radius:var(--chat-radius-sm,4px);color:var(--chat-user-text,#000)}.ai-chat-message.assistant .ai-chat-message-content{background:var(--chat-assistant-bg,transparent);color:var(--chat-assistant-text,#000)}.ai-chat-message-timestamp{color:var(--chat-text-muted,#71717a);font-size:var(--chat-text-xs,12px);margin-top:var(--chat-space-xs,4px);padding:0 var(--chat-space-xs,4px)}.ai-chat-message.streaming .ai-chat-message-content:after{animation:ai-chat-cursor-blink .8s infinite;content:\"▋\";margin-left:2px;opacity:.7}@keyframes ai-chat-message-appear{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}@keyframes ai-chat-cursor-blink{0%,50%{opacity:1}51%,to{opacity:0}}.ai-chat-message.fullpage .ai-chat-message-content{font-size:var(--chat-text-lg,18px);padding:var(--chat-space-md,16px) var(--chat-space-lg,24px)}.ai-chat-typing{gap:var(--chat-space-xs,4px);padding:var(--chat-space-sm,8px) var(--chat-space-md,16px)}.ai-chat-typing-dot{background:var(--chat-text-muted,#71717a)}.ai-chat-tool-row{padding:0 16px}.ai-chat-tool-gear{color:var(--text-primary,#3e3e3e)}.ai-chat-tool-badge{border-radius:8px}.ai-chat-tool-badge.loading{background:#e5e7eb;border:1px solid #d1d5db;color:#1f2937}.ai-chat-tool-badge.error{background:rgba(239,68,68,.1);color:#ef4444}.ai-chat-tool-check{color:#22c55e;flex-shrink:0}.ai-chat-tool-error{color:#ef4444;flex-shrink:0}.ai-chat-tool-badge .tool-name{max-width:150px;overflow:hidden;text-overflow:ellipsis}.ai-chat-widget.dark .ai-chat-tool-gear,.ai-chat-widget[data-theme=dark] .ai-chat-tool-gear,.dark .ai-chat-tool-gear,[data-theme=dark] .ai-chat-tool-gear{color:#fff}.ai-chat-widget.dark .ai-chat-tool-badge,.ai-chat-widget[data-theme=dark] .ai-chat-tool-badge,.dark .ai-chat-tool-badge,[data-theme=dark] .ai-chat-tool-badge{background:hsla(0,0%,100%,.12);border:1px solid hsla(0,0%,100%,.2);color:hsla(0,0%,100%,.9)}.ai-chat-widget.dark .ai-chat-tool-badge.error,.ai-chat-widget[data-theme=dark] .ai-chat-tool-badge.error,.dark .ai-chat-tool-badge.error,[data-theme=dark] .ai-chat-tool-badge.error{background:rgba(239,68,68,.2);color:#f87171}.chakra-ui-dark .ai-chat-tool-gear,html.dark .ai-chat-tool-gear{color:#fff}.chakra-ui-dark .ai-chat-tool-badge,html.dark .ai-chat-tool-badge{background:hsla(0,0%,100%,.12);border:1px solid hsla(0,0%,100%,.2);color:hsla(0,0%,100%,.9)}.chakra-ui-dark .ai-chat-tool-badge.error,html.dark .ai-chat-tool-badge.error{background:rgba(239,68,68,.2);color:#f87171}.ai-chat-pin-input-group{align-items:center;display:flex;flex-wrap:nowrap;gap:8px;justify-content:center;margin:4px 0 8px}.ai-chat-pin-input{align-items:center;appearance:none;background:var(--bg-primary,#fff);border:1px solid var(--border-default,#e5e7eb);border-radius:var(--radius-md,8px);box-sizing:border-box;color:var(--text-primary,#3e3e3e);display:inline-flex;flex:0 0 42px;font-family:inherit;font-size:18px;font-weight:600;height:46px;justify-content:center;line-height:1;max-width:42px;min-width:42px;outline:none;padding:0;text-align:center;transition:border-color .2s ease,box-shadow .2s ease;width:42px}.ai-chat-pin-input:focus{border-color:var(--action-accent,var(--primary-color,#3b82f6));box-shadow:0 0 0 3px rgba(59,130,246,.1)}.ai-chat-pin-input:disabled{cursor:not-allowed;opacity:.6}.ai-chat-widget.dark .ai-chat-pin-input,.chakra-ui-dark .ai-chat-pin-input,.dark .ai-chat-pin-input,[data-theme=dark] .ai-chat-pin-input{background:rgba(0,0,0,.2);border-color:hsla(0,0%,100%,.1);color:#fff}.ai-chat-widget.dark .ai-chat-pin-input:focus,.chakra-ui-dark .ai-chat-pin-input:focus,.dark .ai-chat-pin-input:focus,[data-theme=dark] .ai-chat-pin-input:focus{border-color:var(--action-accent,var(--primary-color,#3b82f6));box-shadow:0 0 0 3px rgba(59,130,246,.2)}.ai-chat-action-button-secondary{background:var(--bg-primary,#fff);border:1px solid var(--border-default,#e5e7eb);border-radius:9999px;color:var(--text-secondary,#6b7280);cursor:pointer;font-size:var(--text-sm,13px);font-weight:var(--font-weight-medium,500);padding:10px 16px;transition:all .2s ease;width:100%}.ai-chat-action-button-secondary:hover:not(:disabled){background:rgba(59,130,246,.05);border-color:var(--action-accent,var(--primary-color,#3b82f6));color:var(--action-accent,var(--primary-color,#3b82f6))}.ai-chat-action-button-secondary:disabled{cursor:not-allowed;opacity:.5}.ai-chat-widget.dark .ai-chat-action-button-secondary,.chakra-ui-dark .ai-chat-action-button-secondary,.dark .ai-chat-action-button-secondary,[data-theme=dark] .ai-chat-action-button-secondary{background:rgba(0,0,0,.2);border-color:hsla(0,0%,100%,.1);color:#e5e7eb}.ai-chat-widget.dark .ai-chat-action-button-secondary:hover:not(:disabled),.chakra-ui-dark .ai-chat-action-button-secondary:hover:not(:disabled),.dark .ai-chat-action-button-secondary:hover:not(:disabled),[data-theme=dark] .ai-chat-action-button-secondary:hover:not(:disabled){background:rgba(59,130,246,.2);border-color:var(--action-accent,var(--primary-color,#3b82f6));color:#fff}.ai-chat-action-appointment-list,.ai-chat-action-button-group{display:flex;flex-direction:column;gap:8px}.ai-chat-action-appointment-item{align-items:center;background:var(--bg-primary,#fff);border:1px solid var(--border-subtle,rgba(0,0,0,.08));border-radius:var(--radius-md,8px);display:flex;gap:12px;justify-content:space-between;padding:10px 12px}.ai-chat-widget.dark .ai-chat-action-appointment-item,.chakra-ui-dark .ai-chat-action-appointment-item,.dark .ai-chat-action-appointment-item,[data-theme=dark] .ai-chat-action-appointment-item{background:rgba(0,0,0,.2);border-color:hsla(0,0%,100%,.08)}.ai-chat-action-appointment-info{display:flex;flex-direction:column;gap:2px;min-width:0}.ai-chat-action-appointment-subject{color:var(--text-primary,#3e3e3e);font-size:14px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ai-chat-widget.dark .ai-chat-action-appointment-subject,.chakra-ui-dark .ai-chat-action-appointment-subject,.dark .ai-chat-action-appointment-subject,[data-theme=dark] .ai-chat-action-appointment-subject{color:#fff}.ai-chat-action-appointment-time{color:var(--text-muted,#71717a);font-size:12px}.ai-chat-action-appointment-item .ai-chat-action-button-secondary{font-size:12px;padding:6px 12px;width:auto}.ai-chat-action-error-message{background:rgba(239,68,68,.1);border-radius:var(--radius-md,8px);color:#dc2626;font-size:var(--text-sm,13px);padding:12px}.ai-chat-widget.dark .ai-chat-action-error-message,.chakra-ui-dark .ai-chat-action-error-message,.dark .ai-chat-action-error-message,[data-theme=dark] .ai-chat-action-error-message{background:rgba(239,68,68,.2);color:#fca5a5}.ai-chat-widget,.chat-ui{--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:8px;--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,.chat-ui.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,.chat-ui{-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:var(--widget-z-index,2147483647)}.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-widget-container.container-mode{position:absolute}@keyframes ai-chat-window-open{0%{opacity:0;transform:scale(.9) translateY(20px)}to{opacity:1;transform:scale(1) translateY(0)}}@keyframes ai-chat-window-close{0%{opacity:1;transform:scale(1) translateY(0)}to{opacity:0;transform:scale(.9) translateY(20px)}}@keyframes ai-chat-message-slide-in{0%{opacity:0;transform:translateY(12px)}to{opacity:1;transform:translateY(0)}}@keyframes ai-chat-welcome-fade-in{0%{opacity:0;transform:translateY(16px)}to{opacity:1;transform:translateY(0)}}@keyframes ai-chat-typing-pulse{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 ai-chat-feedback-morph{0%{opacity:.5;transform:scale(.8)}to{opacity:1;transform:scale(1)}}@keyframes ai-chat-checkmark-pop{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)}}@keyframes ai-chat-tool-gradient{0%{background-position:200% 0}to{background-position:-200% 0}}.ai-chat-window{animation:ai-chat-window-open var(--duration-slow,.35s) var(--spring-bounce);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:ai-chat-window-close var(--duration-normal) var(--spring-smooth) forwards}.ai-chat-window.size-small{height:500px;width:380px}.ai-chat-window.size-medium,.ai-chat-window.size-small{max-height:calc(100vh - 100px);max-width:calc(100vw - 40px)}.ai-chat-window.size-medium{height:600px;width:420px}.ai-chat-window.size-large{height:700px;max-height:calc(100vh - 100px);max-width:calc(100vw - 40px);width:480px}.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:12px 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,.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:color var(--duration-fast) ease;width:32px}.ai-chat-close-button:hover,.ai-chat-header-button:hover{color:var(--text-primary)}.ai-chat-close-button:active,.ai-chat-header-button:active{transform:scale(.95)}.ai-chat-close-button svg,.ai-chat-header-button svg{height:22px;width:22px}.ai-chat-button{align-items:center;background:var(--button-color,var(--btn-primary-bg));border:1px solid var(--border-default,#d3d3d3);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:opacity var(--duration-fast) ease;width:var(--button-size,56px);z-index:1}.ai-chat-button:hover{opacity:.9}.ai-chat-button:active{opacity:.8}.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-welcome-bubble{animation:ai-chat-bubble-fade-in .3s ease-out;background:var(--button-color,var(--btn-primary-bg,#07f));border:none;border-radius:12px;box-shadow:0 4px 12px rgba(0,0,0,.15);color:var(--button-icon-color,var(--btn-primary-text,#fff));cursor:pointer;font-size:14px;font-weight:500;line-height:1.4;padding:12px 16px;position:absolute;width:200px;z-index:0}.ai-chat-widget-container.bottom-right .ai-chat-welcome-bubble{bottom:68px;right:0;text-align:right}.ai-chat-widget-container.bottom-left .ai-chat-welcome-bubble{bottom:68px;left:0;right:auto;text-align:left}.ai-chat-widget-container.top-right .ai-chat-welcome-bubble{right:0;text-align:right;top:68px}.ai-chat-widget-container.top-left .ai-chat-welcome-bubble{left:0;right:auto;text-align:left;top:68px}.ai-chat-welcome-bubble:hover{filter:brightness(1.1)}@keyframes ai-chat-bubble-fade-in{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}.ai-chat-widget-container.top-left .ai-chat-welcome-bubble,.ai-chat-widget-container.top-right .ai-chat-welcome-bubble{animation-name:ai-chat-bubble-fade-in-down}@keyframes ai-chat-bubble-fade-in-down{0%{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:translateY(0)}}.ai-chat-input-container{background:var(--bg-primary,#fff);bottom:0;left:0;padding:8px 0 16px;position:absolute;right:0;z-index:10}.ai-chat-widget.dark .ai-chat-input-container{background:var(--bg-primary,#282625)}.ai-chat-input-container.separate{padding:0 var(--radius-window-gutter,16px) var(--radius-window-gutter,16px)}.ai-chat-input-wrapper{align-items:flex-end;background:var(--input-bg,#f4f4f4);border:1px solid var(--input-border,#d3d3d3);border-radius:var(--radius-input,62px);box-sizing:border-box;display:flex;gap:0;height:52px;overflow:hidden;padding:6px 6px 6px 16px;position:relative;transition:all var(--duration-fast,.15s) ease;z-index:5}.ai-chat-input-wrapper.multiline{border-radius:14px!important;min-height:64px;padding:10px 10px 10px 14px}.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{word-wrap:break-word!important;background:transparent!important;border:none!important;border-radius:0!important;box-shadow:none!important;box-sizing:border-box!important;color:var(--input-text,#000)!important;flex:1!important;font-family:inherit!important;font-size:var(--text-md,15px)!important;height:40px!important;line-height:20px!important;margin:0!important;max-height:40px!important;min-height:40px!important;min-width:0!important;outline:none!important;overflow-wrap:anywhere!important;overflow-x:hidden!important;overflow-y:auto!important;padding:10px var(--space-sm,8px)!important;resize:none!important;white-space:pre-wrap!important;width:0!important;word-break:break-word!important}.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;align-self: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;align-self: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;min-height:40px;min-width:40px;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-data-policy{bottom:2px;color:var(--text-muted,#71717a);font-size:9px;left:0;line-height:1.4;opacity:.5;pointer-events:auto;position:absolute;right:0;text-align:center}.ai-chat-widget.dark .ai-chat-data-policy{color:var(--text-muted,#a1a1aa)}.ai-chat-data-policy-link{background:none;border:none;color:var(--text-muted,#71717a);cursor:pointer;font-family:inherit;font-size:inherit;margin:0;padding:0;text-decoration:underline;text-underline-offset:2px;transition:color .15s ease}.ai-chat-data-policy-link:hover{color:var(--text-secondary,#52525b)}.ai-chat-widget.dark .ai-chat-data-policy-link{color:var(--text-muted,#a1a1aa)}.ai-chat-widget.dark .ai-chat-data-policy-link:hover{color:var(--text-secondary,#d4d4d8)}.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:0 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:ai-chat-message-slide-in .2s var(--spring-bounce);display:flex;flex-direction:column;max-width:90%}.ai-chat-message.user{align-items:flex-end;align-self:flex-end}.ai-chat-message.assistant{align-items:flex-start;align-self:flex-start;max-width:100%;width:100%}.ai-chat-message.tool{align-self:stretch;max-width:none;padding:0}.ai-chat-message-content{word-wrap:break-word;border-radius:18px;font-size:var(--text-md,15px);line-height:var(--line-height-relaxed,1.6);overflow-wrap:break-word;padding:8px 14px}.ai-chat-message.user .ai-chat-message-content{background:var(--user-bg,#f4f3f0);border-radius:18px;color:var(--user-text,#000)}.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.assistant .ai-chat-message-content{background:var(--agent-bg,transparent);box-sizing:border-box;color:var(--agent-text,#000);padding:0;width:100%}.ai-chat-widget.dark .ai-chat-message.assistant .ai-chat-message-content{color:var(--agent-text,#fff)}.ai-chat-message-timestamp{color:var(--text-muted,#71717a);font-size:var(--text-xs,12px);margin-top:var(--space-xs,4px);padding:0 var(--space-xs,4px)}.ai-chat-welcome{animation:ai-chat-welcome-fade-in .3s var(--spring-smooth);display:flex;flex-direction:column;gap:var(--space-md,16px);padding:var(--space-lg,24px) 0}.ai-chat-welcome-title{color:var(--text-primary,#3e3e3e);font-size:var(--text-2xl,28px);font-weight:var(--font-weight-bold,700);line-height:var(--line-height-tight,1.3)}.ai-chat-widget.dark .ai-chat-welcome-title{color:var(--text-primary,#fff)}.ai-chat-welcome-text{color:var(--text-secondary,#000);font-size:var(--text-md,15px);line-height:var(--line-height-relaxed,1.6);max-width:100%}.ai-chat-widget.dark .ai-chat-welcome-text{color:var(--text-secondary,#fff)}.ai-chat-typing{align-items:center;display:flex;gap:var(--space-xs,4px);padding:var(--space-sm,8px) var(--space-md,16px)}.ai-chat-typing-dot{animation:ai-chat-typing-bounce 1.4s ease-in-out infinite both;background:var(--text-muted,#71717a);border-radius:50%;height:8px;width:8px}.ai-chat-typing-dot:first-child{animation-delay:-.32s}.ai-chat-typing-dot:nth-child(2){animation-delay:-.16s}.ai-chat-typing-dot:nth-child(3){animation-delay:0s}@keyframes ai-chat-typing-bounce{0%,80%,to{opacity:.4;transform:scale(.6)}40%{opacity:1;transform:scale(1)}}.ai-chat-scroll-button{align-items:center;background:var(--bg-secondary,#f4f4f5);border:1px solid var(--border-subtle,rgba(0,0,0,.1));border-radius:50%;bottom:80px;box-shadow:0 2px 8px rgba(0,0,0,.1);color:var(--text-secondary,#71717a);cursor:pointer;display:flex;height:36px;justify-content:center;left:50%;opacity:0;pointer-events:none;position:absolute;transform:translateX(-50%);transition:background .15s ease,box-shadow .15s ease,opacity .15s ease,visibility .15s ease;visibility:hidden;width:36px;z-index:15}.ai-chat-scroll-button.visible{opacity:1;pointer-events:auto;visibility:visible}.ai-chat-scroll-button:hover{background:var(--bg-tertiary,#e4e4e7);box-shadow:0 4px 12px rgba(0,0,0,.15)}.ai-chat-scroll-button:active{background:var(--bg-tertiary,#d4d4d8)}.ai-chat-widget.dark .ai-chat-scroll-button{background:var(--bg-secondary,#3f3f46);border-color:var(--border-subtle,hsla(0,0%,100%,.1));box-shadow:0 2px 8px rgba(0,0,0,.3);color:var(--text-secondary,#a1a1aa)}.ai-chat-widget.dark .ai-chat-scroll-button:hover{background:var(--bg-tertiary,#52525b);box-shadow:0 4px 12px rgba(0,0,0,.4)}.ai-chat-error{background:var(--bg-secondary);border-radius:var(--radius-chat-bubble);color:var(--text-primary);font-size:var(--text-md);margin:0 auto;padding:10px var(--space-md)}.ai-chat-message.assistant .ai-chat-message-content p{margin:0 0 var(--space-sm) 0}.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:var(--space-sm) 0;padding-left:var(--space-lg)}.ai-chat-message.assistant .ai-chat-message-content li{margin-bottom:var(--space-xs)}.ai-chat-message.assistant .ai-chat-message-content code{background:rgba(0,0,0,.05);border-radius:var(--radius-sm);font-family:SF Mono,Monaco,Cascadia Code,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,.05);border-radius:var(--radius-md);margin:var(--space-sm) 0;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%,.05)}.ai-chat-message.assistant .ai-chat-message-content pre code{background:transparent;padding:0}.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 strong{font-weight:var(--font-weight-semibold)}.ai-chat-message.assistant .ai-chat-message-content blockquote{border-left:3px solid var(--border-default);color:var(--text-muted);margin:var(--space-sm) 0;padding-left:var(--space-md)}.ai-chat-message.assistant .ai-chat-message-content hr{border:none;border-top:1px solid var(--border-subtle,rgba(0,0,0,.1));margin:var(--space-lg,24px) 0}.ai-chat-widget.dark .ai-chat-message.assistant .ai-chat-message-content hr{border-top-color:var(--border-subtle,hsla(0,0%,100%,.1))}.ai-chat-message.assistant .ai-chat-message-content .table-wrapper{border:1px solid var(--border-subtle,rgba(0,0,0,.1));border-radius:var(--radius-md,8px);box-sizing:border-box;display:block;margin:var(--space-sm) var(--space-sm);max-width:100%;overflow:hidden;width:auto}.ai-chat-message.assistant .ai-chat-message-content .table-scroll{max-width:100%;overflow-x:auto;overflow-y:hidden;width:100%}.ai-chat-widget.dark .ai-chat-message.assistant .ai-chat-message-content .table-wrapper{border-color:var(--border-subtle,hsla(0,0%,100%,.1))}.ai-chat-message.assistant .ai-chat-message-content table{border-collapse:collapse;font-size:var(--text-sm);min-width:100%;width:max-content}.ai-chat-message.assistant .ai-chat-message-content td,.ai-chat-message.assistant .ai-chat-message-content th{border-bottom:1px solid var(--border-subtle,rgba(0,0,0,.1));border-right:1px solid var(--border-subtle,rgba(0,0,0,.1));padding:var(--space-sm);text-align:left}.ai-chat-widget.dark .ai-chat-message.assistant .ai-chat-message-content td,.ai-chat-widget.dark .ai-chat-message.assistant .ai-chat-message-content th{border-color:var(--border-subtle,hsla(0,0%,100%,.1))}.ai-chat-message.assistant .ai-chat-message-content td:last-child,.ai-chat-message.assistant .ai-chat-message-content th:last-child{border-right:none}.ai-chat-message.assistant .ai-chat-message-content tr:last-child td{border-bottom:none}.ai-chat-message.assistant .ai-chat-message-content th{background:rgba(0,0,0,.03);font-weight:var(--font-weight-semibold);white-space:nowrap}.ai-chat-widget.dark .ai-chat-message.assistant .ai-chat-message-content th{background:hsla(0,0%,100%,.05)}.ai-chat-message.assistant .ai-chat-message-content tbody tr:nth-child(2n){background:rgba(0,0,0,.02)}.ai-chat-widget.dark .ai-chat-message.assistant .ai-chat-message-content tbody tr:nth-child(2n){background:hsla(0,0%,100%,.03)}.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{align-items:center;background:transparent;border:1px solid var(--border-default,#d4d4d8);border-radius:var(--radius-preset-badge,18px);color:var(--text-primary,#18181b);cursor:pointer;display:inline-flex;font-size:14px;font-weight:400;gap:6px;justify-content:center;line-height:1.3;max-width:100%;overflow:hidden;padding:8px 14px;text-overflow:ellipsis;transition:background .15s ease,border-color .15s ease,transform .1s ease;white-space:nowrap}.ai-chat-widget.dark .ai-chat-suggested-question{background:transparent;border-color:var(--border-subtle,#52525b);color:var(--text-primary,#fafafa)}.ai-chat-suggested-question-text{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ai-chat-suggested-question:hover{background:var(--bg-hover,#f4f4f5);border-color:var(--border-default,#d4d4d8)}.ai-chat-widget.dark .ai-chat-suggested-question:hover{background:var(--bg-hover,#3f3f46);border-color:var(--border-subtle,#52525b)}.ai-chat-suggested-question:active{transform:scale(.98)}.ai-chat-suggested-question.action-type{border:none}.ai-chat-suggested-question.action-type,.ai-chat-widget.dark .ai-chat-suggested-question.action-type{background:var(--primary-color,var(--button-color,#ef4444));color:var(--button-icon-color,#fff)}.ai-chat-suggested-question.action-type:hover{background:var(--primary-color,var(--button-color,#ef4444));opacity:.9}.ai-chat-suggested-question-icon{align-items:center;display:flex;flex-shrink:0;justify-content:center}.ai-chat-suggested-question:not(.action-type) .ai-chat-suggested-question-icon{display:none}.ai-chat-follow-up-suggestions{box-sizing:border-box;margin:0;padding:8px 16px 0;width:100%}.ai-chat-follow-up-list{align-items:flex-end;display:flex;flex-direction:column;gap:6px}.ai-chat-follow-up-item{align-items:center;border:none;border-radius:var(--radius-preset-badge,18px);cursor:pointer;display:inline-flex;font-size:14px;font-weight:400;gap:6px;justify-content:center;line-height:1.3;max-width:100%;overflow:hidden;padding:8px 14px;text-overflow:ellipsis;transition:opacity .15s ease,transform .1s ease;white-space:nowrap}.ai-chat-follow-up-item,.ai-chat-widget.dark .ai-chat-follow-up-item{background:var(--primary-color,var(--button-color,#07f));color:var(--button-icon-color,#fff)}.ai-chat-follow-up-item:hover{opacity:.9}.ai-chat-follow-up-item:active{transform:scale(.98)}.ai-chat-follow-up-item.question-type{background:transparent;border:1px solid var(--border-default,#d4d4d8);color:var(--text-primary,#18181b)}.ai-chat-widget.dark .ai-chat-follow-up-item.question-type,.dark .ai-chat-follow-up-item.question-type,[data-color-mode=dark] .ai-chat-follow-up-item.question-type,[data-theme=dark] .ai-chat-follow-up-item.question-type{background:transparent;border:1px solid var(--border-subtle,#52525b);color:var(--text-primary,#fafafa)}@media (prefers-color-scheme:dark){.ai-chat-follow-up-item.question-type{background:transparent;border:1px solid var(--border-subtle,#52525b);color:var(--text-primary,#fafafa)}}.ai-chat-follow-up-item.question-type:hover{background:var(--bg-hover,#f4f4f5);opacity:1}.ai-chat-widget.dark .ai-chat-follow-up-item.question-type:hover,.dark .ai-chat-follow-up-item.question-type:hover,[data-color-mode=dark] .ai-chat-follow-up-item.question-type:hover,[data-theme=dark] .ai-chat-follow-up-item.question-type:hover{background:var(--bg-hover,#3f3f46);opacity:1}@media (prefers-color-scheme:dark){.ai-chat-follow-up-item.question-type:hover{background:var(--bg-hover,#3f3f46);opacity:1}}.ai-chat-follow-up-item.action-type{background:var(--primary-color,var(--button-color,#07f));border:none;color:var(--button-icon-color,#fff)}.ai-chat-follow-up-icon{align-items:center;display:flex;flex-shrink:0;justify-content:center}.ai-chat-follow-up-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.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:ai-chat-feedback-morph .3s var(--spring-bounce);gap:var(--space-xs)}.ai-chat-feedback-message{align-items:center;display:flex;gap:4px;margin-left:var(--space-xxs)}.ai-chat-feedback-checkmark{animation:ai-chat-checkmark-pop .3s var(--spring-bounce);color:#10b981;font-size:var(--text-md);font-weight:700}.ai-chat-feedback-text{color:#10b981;font-size:var(--text-xs);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-xs) 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:center;background:var(--user-bg,#f4f4f5);border-radius:var(--radius-history-item,15px);display:flex;flex:0 0 auto;flex-direction:row;height:var(--history-item-height,36px);margin:0;overflow:hidden;transition:background var(--duration-fast,.15s) ease;width:100%}.ai-chat-history-item-content{align-items:center;background:transparent;border:none;cursor:pointer;display:flex;flex:1;flex-direction:row;height:100%;min-width:0;padding:0 var(--space-xs,4px) 0 var(--space-md,16px);text-align:left}.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);flex:1;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-history-item-delete{align-items:center;background:transparent;border:none;border-radius:var(--radius-sm,6px);color:var(--text-muted,#71717a);cursor:pointer;display:flex;flex-shrink:0;height:24px;justify-content:center;margin-left:auto;margin-right:var(--space-xs,4px);opacity:0;transition:opacity var(--duration-fast,.15s) ease,background var(--duration-fast,.15s) ease,color var(--duration-fast,.15s) ease;width:24px}.ai-chat-history-item-delete svg{height:14px;width:14px}.ai-chat-history-item:hover .ai-chat-history-item-delete{opacity:1}.ai-chat-history-item-delete:hover{background:rgba(239,68,68,.1);color:#ef4444}.ai-chat-widget.dark .ai-chat-history-item-delete:hover{background:rgba(239,68,68,.2);color:#f87171}.ai-chat-tool-row{align-items:center;display:flex;gap:10px;margin:2px 0;padding:0}.ai-chat-tool-gear{color:#1f2937;flex-shrink:0;height:20px;width:20px}.ai-chat-tool-gear.spinning{animation:ai-chat-gear-spin 1.5s linear infinite}.ai-chat-tool-badges{align-items:center;display:flex;flex-wrap:wrap;gap:8px}.ai-chat-tool-badge{align-items:center;background:#e5e7eb;border:1px solid #d1d5db;border-radius:var(--radius-action-badge,8px);color:#1f2937;display:inline-flex;font-size:12px;font-weight:500;gap:4px;line-height:1.2;padding:5px 12px;transition:all .2s ease;white-space:nowrap}.ai-chat-tool-badge.loading{animation:ai-chat-tool-gradient 2s linear infinite;background:linear-gradient(90deg,var(--tool-loading-bg-1,#e0e0e0) 0,var(--tool-loading-bg-2,#f0f0f0) 25%,var(--tool-loading-bg-3,#fff) 50%,var(--tool-loading-bg-2,#f0f0f0) 75%,var(--tool-loading-bg-1,#e0e0e0) 100%);background-size:200% 100%;color:var(--tool-loading-text,#1a1a1a);position:relative}.ai-chat-widget:not(.dark) .ai-chat-tool-badge.loading{--tool-loading-bg-1:#2a2a2a;--tool-loading-bg-2:#3a3a3a;--tool-loading-bg-3:#4a4a4a;--tool-loading-text:#fff}.ai-chat-tool-badge.completed{background:#e5e7eb;border:1px solid #d1d5db;color:#1f2937}.ai-chat-widget.dark .ai-chat-tool-badge,.ai-chat-widget[data-theme=dark] .ai-chat-tool-badge,.chakra-ui-dark .ai-chat-tool-badge,.dark .ai-chat-tool-badge,[data-theme=dark] .ai-chat-tool-badge,html.dark .ai-chat-tool-badge{background:hsla(0,0%,100%,.12);border:1px solid hsla(0,0%,100%,.2);color:hsla(0,0%,100%,.9)}.ai-chat-widget.dark .ai-chat-tool-gear,.ai-chat-widget[data-theme=dark] .ai-chat-tool-gear,.chakra-ui-dark .ai-chat-tool-gear,.dark .ai-chat-tool-gear,[data-theme=dark] .ai-chat-tool-gear,html.dark .ai-chat-tool-gear{color:#fff}.ai-chat-tool-badge.error{background:var(--tool-error-bg,rgba(239,68,68,.15));color:var(--tool-error-text,#ef4444)}.ai-chat-tool-badge .ai-chat-tool-check{color:#fff;flex-shrink:0}.ai-chat-tool-badge .ai-chat-tool-error{color:#ef4444;flex-shrink:0}.tool-name{font-weight:500;line-height:1.2;white-space:nowrap}.ai-chat-tool-action{box-sizing:border-box;padding:0;width:100%}@keyframes ai-chat-skeleton-pulse{0%,to{opacity:.4}50%{opacity:.7}}.ai-chat-action-skeleton-item{animation:ai-chat-skeleton-pulse 1.5s ease-in-out infinite;background:var(--bg-secondary,#e5e7eb)}.ai-chat-widget.dark .ai-chat-action-skeleton-item,.chakra-ui-dark .ai-chat-action-skeleton-item,.dark .ai-chat-action-skeleton-item,[data-theme=dark] .ai-chat-action-skeleton-item{background:hsla(0,0%,100%,.1)}.ai-chat-action-skeleton-content{display:flex;flex-direction:column;gap:16px}.ai-chat-action-skeleton-header{align-items:center;display:flex;gap:10px}.ai-chat-action-skeleton-box{background:rgba(0,0,0,.08);border-radius:10px;display:flex;flex-direction:column;gap:8px;padding:14px}.ai-chat-widget.dark .ai-chat-action-skeleton-box,.chakra-ui-dark .ai-chat-action-skeleton-box,.dark .ai-chat-action-skeleton-box,[data-theme=dark] .ai-chat-action-skeleton-box{background:rgba(0,0,0,.25)}.ai-chat-action-card{--action-accent:var(--primary-color,#3b82f6);background:var(--bg-secondary,#f9fafb);border:1px solid var(--border-subtle,rgba(0,0,0,.06));border-radius:12px;box-sizing:border-box;margin-top:4px;padding:16px;transition:all .2s ease;width:100%}.ai-chat-widget.dark .ai-chat-action-card,.chakra-ui-dark .ai-chat-action-card,.dark .ai-chat-action-card,[data-theme=dark] .ai-chat-action-card{background:hsla(0,0%,100%,.05);border-color:hsla(0,0%,100%,.1)}.ai-chat-action-booked{background:var(--bg-secondary,#f9fafb);border:1px solid var(--border-subtle,rgba(0,0,0,.06))}.ai-chat-widget.dark .ai-chat-action-booked,.chakra-ui-dark .ai-chat-action-booked,.dark .ai-chat-action-booked,[data-theme=dark] .ai-chat-action-booked{background:var(--bg-secondary,#3a3a3a)}.ai-chat-action-header{align-items:center;color:var(--text-primary,#3e3e3e);display:flex;font-size:var(--text-md,15px);font-weight:var(--font-weight-semibold,600);gap:var(--space-sm,8px);margin-bottom:var(--space-md,16px)}.ai-chat-widget.dark .ai-chat-action-header,.chakra-ui-dark .ai-chat-action-header,.dark .ai-chat-action-header,[data-theme=dark] .ai-chat-action-header{color:var(--text-primary,#fff)}.ai-chat-action-icon{color:var(--action-accent,var(--primary-color,#3b82f6));flex-shrink:0;height:20px;width:20px}.ai-chat-action-success-icon-wrapper{align-items:center;background:var(--action-accent,var(--primary-color,#22c55e));border-radius:50%;color:#fff;display:flex;flex-shrink:0;height:24px;justify-content:center;width:24px}.ai-chat-action-icon-success{color:currentColor;height:14px;width:14px}.ai-chat-action-detail-box{background:var(--bg-primary,#fff);border:1px solid var(--border-subtle,rgba(0,0,0,.08));border-radius:var(--radius-md,8px);display:flex;flex-direction:column;gap:4px;padding:12px 16px}.ai-chat-widget.dark .ai-chat-action-detail-box,.chakra-ui-dark .ai-chat-action-detail-box,.dark .ai-chat-action-detail-box,[data-theme=dark] .ai-chat-action-detail-box{background:rgba(0,0,0,.2);border-color:hsla(0,0%,100%,.05)}.ai-chat-action-label-small{color:var(--text-muted,#71717a);font-size:11px;font-weight:600;letter-spacing:.5px;text-transform:uppercase}.ai-chat-action-value-large{color:var(--text-primary,#3e3e3e);font-size:15px;font-weight:500}.ai-chat-widget.dark .ai-chat-action-value-large,.chakra-ui-dark .ai-chat-action-value-large,.dark .ai-chat-action-value-large,[data-theme=dark] .ai-chat-action-value-large{color:#fff}.ai-chat-action-body{display:flex;flex-direction:column;gap:var(--space-md,16px)}.ai-chat-action-field{display:flex;flex-direction:column;gap:var(--space-xs,6px)}.ai-chat-action-label{color:var(--text-secondary,#6b7280);font-size:var(--text-sm,13px);font-weight:var(--font-weight-medium,500)}.ai-chat-widget.dark .ai-chat-action-label,.chakra-ui-dark .ai-chat-action-label,.dark .ai-chat-action-label,[data-theme=dark] .ai-chat-action-label{color:var(--text-secondary,#a1a1aa)}.ai-chat-action-input{background:var(--bg-primary,#fff);border:1px solid var(--border-default,#e5e7eb);border-radius:var(--radius-md,8px);color:var(--text-primary,#3e3e3e);font-size:var(--text-sm,13px);outline:none;padding:10px 12px;transition:border-color .2s ease,box-shadow .2s ease}.ai-chat-action-input:focus{border-color:var(--action-accent,var(--primary-color,#3b82f6));box-shadow:0 0 0 3px rgba(59,130,246,.1)}.ai-chat-action-input::placeholder{color:var(--text-muted,#9ca3af)}.ai-chat-widget.dark .ai-chat-action-input,.chakra-ui-dark .ai-chat-action-input,.dark .ai-chat-action-input,[data-theme=dark] .ai-chat-action-input{background:rgba(0,0,0,.2);border-color:hsla(0,0%,100%,.1);color:#fff}.ai-chat-widget.dark .ai-chat-action-input:focus,.chakra-ui-dark .ai-chat-action-input:focus,.dark .ai-chat-action-input:focus,[data-theme=dark] .ai-chat-action-input:focus{border-color:var(--action-accent,var(--primary-color,#3b82f6));box-shadow:0 0 0 3px rgba(59,130,246,.2)}.ai-chat-action-button{background:var(--action-accent,var(--primary-color,#3b82f6));border:none;border-radius:9999px;color:#fff;cursor:pointer;font-size:var(--text-sm,13px);font-weight:var(--font-weight-semibold,600);padding:12px 16px;transition:all .2s ease;width:100%}.ai-chat-action-button:hover:not(:disabled){opacity:.9;transform:translateY(-1px)}.ai-chat-action-button:disabled{cursor:not-allowed;opacity:.5}.ai-chat-action-link-button{align-items:center;background:var(--action-accent,var(--primary-color,#3b82f6));border:none;border-radius:9999px;box-sizing:border-box;color:#fff;display:flex;font-size:14px;font-weight:600;gap:6px;justify-content:center;margin-top:8px;padding:12px;text-decoration:none;transition:all .2s ease;width:100%}.ai-chat-action-link-button:hover{opacity:.9;transform:translateY(-1px)}.ai-chat-action-error{background:rgba(239,68,68,.1);border-radius:var(--radius-md,8px);color:#dc2626;font-size:var(--text-sm,13px);padding:10px 12px}.ai-chat-widget.dark .ai-chat-action-error,.chakra-ui-dark .ai-chat-action-error,.dark .ai-chat-action-error,[data-theme=dark] .ai-chat-action-error{background:rgba(239,68,68,.2);color:#fca5a5}.ai-chat-action-hint{color:var(--text-muted,#9ca3af);font-size:var(--text-sm,13px);padding:var(--space-sm,8px);text-align:center}.ai-chat-action-date-grid{display:grid;gap:var(--space-xs,6px);grid-template-columns:repeat(auto-fill,minmax(90px,1fr))}.ai-chat-action-date-btn{background:var(--bg-primary,#fff);border:1px solid var(--border-default,#e5e7eb);border-radius:var(--radius-md,8px);color:var(--text-primary,#3e3e3e);cursor:pointer;font-size:var(--text-xs,12px);font-weight:var(--font-weight-medium,500);padding:8px 10px;text-align:center;transition:all .15s ease}.ai-chat-action-date-btn:hover{background:rgba(59,130,246,.05);border-color:var(--action-accent,var(--primary-color,#3b82f6))}.ai-chat-action-date-btn.active{background:var(--action-accent,var(--primary-color,#3b82f6));border-color:var(--action-accent,var(--primary-color,#3b82f6));color:#fff}.ai-chat-widget.dark .ai-chat-action-date-btn,.chakra-ui-dark .ai-chat-action-date-btn,.dark .ai-chat-action-date-btn,[data-theme=dark] .ai-chat-action-date-btn{background:rgba(0,0,0,.2);border-color:hsla(0,0%,100%,.1);color:#fff}.ai-chat-widget.dark .ai-chat-action-date-btn:hover,.chakra-ui-dark .ai-chat-action-date-btn:hover,.dark .ai-chat-action-date-btn:hover,[data-theme=dark] .ai-chat-action-date-btn:hover{background:rgba(59,130,246,.15);border-color:var(--action-accent,var(--primary-color,#3b82f6))}.ai-chat-widget.dark .ai-chat-action-date-btn.active,.chakra-ui-dark .ai-chat-action-date-btn.active,.dark .ai-chat-action-date-btn.active,[data-theme=dark] .ai-chat-action-date-btn.active{background:var(--action-accent,var(--primary-color,#3b82f6));border-color:var(--action-accent,var(--primary-color,#3b82f6));color:#fff}.ai-chat-action-time-grid{display:grid;gap:var(--space-xs,6px);grid-template-columns:repeat(auto-fill,minmax(100px,1fr))}.ai-chat-action-time-btn{background:var(--bg-primary,#fff);border:1px solid var(--border-default,#e5e7eb);border-radius:var(--radius-md,8px);color:var(--text-primary,#3e3e3e);cursor:pointer;font-size:var(--text-xs,12px);font-weight:var(--font-weight-medium,500);padding:8px 10px;text-align:center;transition:all .15s ease}.ai-chat-action-time-btn:hover{background:rgba(59,130,246,.05);border-color:var(--action-accent,var(--primary-color,#3b82f6))}.ai-chat-action-time-btn.active{background:var(--action-accent,var(--primary-color,#3b82f6));border-color:var(--action-accent,var(--primary-color,#3b82f6));color:#fff}.ai-chat-widget.dark .ai-chat-action-time-btn,.chakra-ui-dark .ai-chat-action-time-btn,.dark .ai-chat-action-time-btn,[data-theme=dark] .ai-chat-action-time-btn{background:rgba(0,0,0,.2);border-color:hsla(0,0%,100%,.1);color:#fff}.ai-chat-widget.dark .ai-chat-action-time-btn:hover,.chakra-ui-dark .ai-chat-action-time-btn:hover,.dark .ai-chat-action-time-btn:hover,[data-theme=dark] .ai-chat-action-time-btn:hover{background:rgba(59,130,246,.15);border-color:var(--action-accent,var(--primary-color,#3b82f6))}.ai-chat-widget.dark .ai-chat-action-time-btn.active,.chakra-ui-dark .ai-chat-action-time-btn.active,.dark .ai-chat-action-time-btn.active,[data-theme=dark] .ai-chat-action-time-btn.active{background:var(--action-accent,var(--primary-color,#3b82f6));border-color:var(--action-accent,var(--primary-color,#3b82f6));color:#fff}.ai-chat-link-preview{--action-accent:var(--primary-color,#3b82f6);background:var(--bg-secondary,#f4f4f4);border:1px solid var(--border-subtle,rgba(0,0,0,.08));border-radius:var(--radius-lg,12px);cursor:pointer;display:flex;flex-direction:column;margin-top:4px;overflow:hidden;padding:0!important;position:relative;transition:border-color .2s,box-shadow .2s,transform .2s}.ai-chat-link-preview:hover{border-color:var(--action-accent);box-shadow:0 2px 8px rgba(0,0,0,.1);transform:translateY(-1px)}.ai-chat-link-preview:focus{border-color:var(--action-accent);box-shadow:0 0 0 2px rgba(59,130,246,.2);outline:none}.ai-chat-widget.dark .ai-chat-link-preview,.chakra-ui-dark .ai-chat-link-preview,.dark .ai-chat-link-preview,[data-theme=dark] .ai-chat-link-preview{background:var(--bg-secondary,#3a3a3a);border-color:hsla(0,0%,100%,.08)}.ai-chat-widget.dark .ai-chat-link-preview:hover,.chakra-ui-dark .ai-chat-link-preview:hover,.dark .ai-chat-link-preview:hover,[data-theme=dark] .ai-chat-link-preview:hover{border-color:var(--action-accent);box-shadow:0 2px 12px rgba(0,0,0,.3)}.ai-chat-link-preview__image{aspect-ratio:1.91/1;background:var(--bg-muted,#e5e7eb);overflow:hidden;width:100%}.ai-chat-widget.dark .ai-chat-link-preview__image,.chakra-ui-dark .ai-chat-link-preview__image,.dark .ai-chat-link-preview__image,[data-theme=dark] .ai-chat-link-preview__image{background:hsla(0,0%,100%,.05)}.ai-chat-link-preview__image img{height:100%;object-fit:cover;width:100%}.ai-chat-link-preview__content{flex:1;padding:8px 10px}.ai-chat-link-preview__site{align-items:center;display:flex;gap:6px;margin-bottom:6px}.ai-chat-link-preview__favicon{border-radius:2px;flex-shrink:0;height:16px;width:16px}.ai-chat-link-preview__domain{color:var(--text-muted,#71717a);font-size:12px;letter-spacing:.5px;overflow:hidden;text-overflow:ellipsis;text-transform:uppercase;white-space:nowrap}.ai-chat-link-preview__title{-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical;color:var(--text-primary,#3e3e3e);display:-webkit-box;font-size:15px;font-weight:600;line-height:1.3;margin:0 0 4px;overflow:hidden}.ai-chat-widget.dark .ai-chat-link-preview__title,.chakra-ui-dark .ai-chat-link-preview__title,.dark .ai-chat-link-preview__title,[data-theme=dark] .ai-chat-link-preview__title{color:#fff}.ai-chat-link-preview__description{-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical;color:var(--text-muted,#71717a);display:-webkit-box;font-size:13px;line-height:1.4;margin:0;overflow:hidden}.ai-chat-link-preview__context{border-top:1px solid var(--border-subtle,rgba(0,0,0,.08));color:var(--text-muted,#71717a);font-size:12px;font-style:italic;margin:8px 0 0;padding-top:8px}.ai-chat-widget.dark .ai-chat-link-preview__context,.chakra-ui-dark .ai-chat-link-preview__context,.dark .ai-chat-link-preview__context,[data-theme=dark] .ai-chat-link-preview__context{border-color:hsla(0,0%,100%,.08)}.ai-chat-link-preview__arrow{align-items:center;background:var(--bg-primary,#fff);border-radius:50%;box-shadow:0 1px 3px rgba(0,0,0,.1);color:var(--text-muted,#71717a);display:flex;height:28px;justify-content:center;opacity:0;position:absolute;right:12px;top:12px;transition:opacity .2s,background .2s;width:28px}.ai-chat-link-preview:hover .ai-chat-link-preview__arrow{opacity:1}.ai-chat-widget.dark .ai-chat-link-preview__arrow,.chakra-ui-dark .ai-chat-link-preview__arrow,.dark .ai-chat-link-preview__arrow,[data-theme=dark] .ai-chat-link-preview__arrow{background:hsla(0,0%,100%,.1);color:#fff}.ai-chat-link-preview--error{border-color:rgba(239,68,68,.3)}.ai-chat-link-preview--error:hover{border-color:rgba(239,68,68,.5)}.ai-chat-link-preview__error-text{color:#dc2626;font-size:12px;margin:4px 0 0}.ai-chat-widget.dark .ai-chat-link-preview__error-text,.chakra-ui-dark .ai-chat-link-preview__error-text,.dark .ai-chat-link-preview__error-text,[data-theme=dark] .ai-chat-link-preview__error-text{color:#fca5a5}.ai-chat-video-player{--action-accent:var(--primary-color,#3b82f6);background:var(--bg-secondary,#f4f4f4);border-radius:var(--radius-lg,12px);display:flex;flex-direction:column;gap:0;margin-top:4px;overflow:hidden;padding:0!important}.ai-chat-widget.dark .ai-chat-video-player,.chakra-ui-dark .ai-chat-video-player,.dark .ai-chat-video-player,[data-theme=dark] .ai-chat-video-player{background:var(--bg-secondary,#3a3a3a)}.ai-chat-video-player__header{align-items:center;color:var(--action-accent,var(--primary-color,#3b82f6));display:flex;gap:8px}.ai-chat-video-player__title{color:var(--text-primary,#3e3e3e);font-size:14px;font-weight:600}.ai-chat-widget.dark .ai-chat-video-player__title,.chakra-ui-dark .ai-chat-video-player__title,.dark .ai-chat-video-player__title,[data-theme=dark] .ai-chat-video-player__title{color:#fff}.ai-chat-video-player__container{aspect-ratio:16/9;background:#000;border-radius:8px;overflow:hidden;position:relative;width:100%}.ai-chat-video-player__thumbnail{cursor:pointer;height:100%;position:relative;width:100%}.ai-chat-video-player__thumbnail img{height:100%;object-fit:cover;width:100%}.ai-chat-video-player__placeholder{align-items:center;background:linear-gradient(135deg,#1a1a2e,#16213e);cursor:pointer;display:flex;flex-direction:column;gap:8px;height:100%;justify-content:center;position:relative;width:100%}.ai-chat-video-player__click-text{color:hsla(0,0%,100%,.7);font-size:13px}.ai-chat-video-player__play-btn{align-items:center;background:rgba(0,0,0,.7);border:none;border-radius:50%;color:#fff;cursor:pointer;display:flex;height:64px;justify-content:center;left:50%;position:absolute;top:50%;transform:translate(-50%,-50%);transition:background .2s,transform .2s;width:64px}.ai-chat-video-player__placeholder .ai-chat-video-player__play-btn{left:auto;position:relative;top:auto;transform:none}.ai-chat-video-player__play-btn:hover{background:rgba(0,0,0,.9);transform:translate(-50%,-50%) scale(1.05)}.ai-chat-video-player__placeholder .ai-chat-video-player__play-btn:hover{transform:scale(1.05)}.ai-chat-video-player__provider-badge{background:rgba(0,0,0,.8);border-radius:4px;bottom:8px;color:#fff;font-size:11px;font-weight:600;letter-spacing:.5px;padding:4px 8px;position:absolute;right:8px;text-transform:uppercase}.ai-chat-video-player__iframe,.ai-chat-video-player__video{border:none;height:100%;left:0;position:absolute;top:0;width:100%}.ai-chat-video-player__error{align-items:center;background:rgba(239,68,68,.1);color:#dc2626;display:flex;font-size:13px;height:100%;justify-content:center;padding:16px;text-align:center;width:100%}.ai-chat-widget.dark .ai-chat-video-player__error,.chakra-ui-dark .ai-chat-video-player__error,.dark .ai-chat-video-player__error,[data-theme=dark] .ai-chat-video-player__error{background:rgba(239,68,68,.2);color:#fca5a5}.ai-chat-video-player__context{border-top:1px solid var(--border-subtle,rgba(0,0,0,.08));color:var(--text-muted,#71717a);font-size:12px;font-style:italic;margin-top:4px;padding-top:8px}.ai-chat-widget.dark .ai-chat-video-player__context,.chakra-ui-dark .ai-chat-video-player__context,.dark .ai-chat-video-player__context,[data-theme=dark] .ai-chat-video-player__context{border-color:hsla(0,0%,100%,.08)}.ai-chat-location-card{background:var(--bg-secondary,#fff);border:1px solid var(--border-subtle,rgba(0,0,0,.08));border-radius:12px;overflow:hidden;padding:0}.ai-chat-widget.dark .ai-chat-location-card,.chakra-ui-dark .ai-chat-location-card,.dark .ai-chat-location-card,[data-theme=dark] .ai-chat-location-card{background:hsla(0,0%,100%,.05);border-color:hsla(0,0%,100%,.1)}.ai-chat-location-card--compact{border-radius:10px}.ai-chat-location-card--error{color:var(--text-muted,#71717a);padding:16px;text-align:center}.ai-chat-location-card__map{background:var(--bg-muted,#f4f4f5);position:relative;width:100%}.ai-chat-widget.dark .ai-chat-location-card__map,.chakra-ui-dark .ai-chat-location-card__map,.dark .ai-chat-location-card__map,[data-theme=dark] .ai-chat-location-card__map{background:rgba(0,0,0,.2)}.ai-chat-location-card__map iframe{border:none;display:block;height:100%;width:100%}.ai-chat-location-card__content{padding:12px}.ai-chat-location-card--compact .ai-chat-location-card__content{padding:10px}.ai-chat-location-card__header{align-items:center;display:flex;flex-wrap:wrap;gap:8px;margin-bottom:8px}.ai-chat-location-card__name{color:var(--text-primary,#18181b);flex:1;font-size:16px;font-weight:600;margin:0;min-width:0}.ai-chat-widget.dark .ai-chat-location-card__name,.chakra-ui-dark .ai-chat-location-card__name,.dark .ai-chat-location-card__name,[data-theme=dark] .ai-chat-location-card__name{color:#fff}.ai-chat-location-card--compact .ai-chat-location-card__name{font-size:14px}.ai-chat-location-card__type{background:var(--bg-muted,#f4f4f5);border-radius:10px;color:var(--text-muted,#71717a);font-size:11px;font-weight:500;letter-spacing:.5px;padding:2px 8px;text-transform:uppercase}.ai-chat-widget.dark .ai-chat-location-card__type,.chakra-ui-dark .ai-chat-location-card__type,.dark .ai-chat-location-card__type,[data-theme=dark] .ai-chat-location-card__type{background:hsla(0,0%,100%,.1);color:hsla(0,0%,100%,.7)}.ai-chat-location-card__status{border-radius:12px;font-size:12px;font-weight:500;padding:2px 8px}.ai-chat-location-card__status--open{background:#dcfce7;color:#16a34a}.ai-chat-location-card__status--closed{background:#fef2f2;color:#dc2626}.ai-chat-widget.dark .ai-chat-location-card__status--open,.chakra-ui-dark .ai-chat-location-card__status--open,.dark .ai-chat-location-card__status--open,[data-theme=dark] .ai-chat-location-card__status--open{background:rgba(34,197,94,.2);color:#4ade80}.ai-chat-widget.dark .ai-chat-location-card__status--closed,.chakra-ui-dark .ai-chat-location-card__status--closed,.dark .ai-chat-location-card__status--closed,[data-theme=dark] .ai-chat-location-card__status--closed{background:rgba(239,68,68,.2);color:#fca5a5}.ai-chat-location-card__address{align-items:flex-start;color:var(--text-muted,#71717a);display:flex;font-size:13px;gap:6px;line-height:1.4;margin:0 0 8px}.ai-chat-location-card__address svg{flex-shrink:0;margin-top:2px}.ai-chat-location-card__description{color:var(--text-muted,#71717a);font-size:13px;line-height:1.4;margin:0 0 8px}.ai-chat-location-card__hours{align-items:flex-start;color:var(--text-muted,#71717a);display:flex;font-size:13px;gap:6px;margin-bottom:8px}.ai-chat-location-card__hours svg{flex-shrink:0;margin-top:2px}.ai-chat-location-card__hours-list{flex:1}.ai-chat-location-card__hours-toggle{align-items:center;background:none;border:none;color:inherit;cursor:pointer;display:flex;font:inherit;gap:4px;padding:0}.ai-chat-location-card__hours-toggle:hover{text-decoration:underline}.ai-chat-location-card__hours-full{list-style:none;margin:8px 0 0;padding:0}.ai-chat-location-card__hours-full li{display:flex;font-size:12px;justify-content:space-between;padding:4px 0}.ai-chat-location-card__hours-today{color:var(--text-primary,#18181b);font-weight:600}.ai-chat-widget.dark .ai-chat-location-card__hours-today,.chakra-ui-dark .ai-chat-location-card__hours-today,.dark .ai-chat-location-card__hours-today,[data-theme=dark] .ai-chat-location-card__hours-today{color:#fff}.ai-chat-location-card__phone{align-items:center;background:none;border:none;color:var(--action-accent,#3b82f6);cursor:pointer;display:flex;font-size:13px;gap:6px;margin-bottom:12px;padding:0}.ai-chat-location-card__phone:hover{text-decoration:underline}.ai-chat-location-card__actions{display:flex;gap:8px;justify-content:flex-start;width:100%}.ai-chat-location-card__button{align-items:center;background:var(--action-accent,#3b82f6);border:none;border-radius:20px;color:#fff;cursor:pointer;display:flex;flex:1;font-size:13px;font-weight:500;gap:6px;justify-content:center;padding:10px 16px;transition:opacity .2s}.ai-chat-location-card__button:hover{opacity:.9}.ai-chat-location-card--compact .ai-chat-location-card__button{font-size:12px;padding:8px 12px}.ai-chat-location-card__link{align-items:center;background:var(--bg-secondary,#fff);border:1px solid var(--border-subtle,rgba(0,0,0,.08));border-radius:20px;color:var(--text-primary,#18181b);display:flex;font-size:13px;gap:6px;padding:10px 16px;text-decoration:none;transition:border-color .2s}.ai-chat-widget.dark .ai-chat-location-card__link,.chakra-ui-dark .ai-chat-location-card__link,.dark .ai-chat-location-card__link,[data-theme=dark] .ai-chat-location-card__link{background:hsla(0,0%,100%,.05);border-color:hsla(0,0%,100%,.1);color:#fff}.ai-chat-location-card__link:hover{border-color:var(--action-accent,#3b82f6)}.ai-chat-location-card-list{display:flex;flex-direction:column;gap:8px}.ai-chat-location-card-list__header{align-items:center;color:var(--text-muted,#71717a);display:flex;font-size:13px;font-weight:500;gap:6px;margin-bottom:4px;padding:0 4px}.ai-chat-location-card-list__stack{display:grid;gap:12px;grid-template-columns:1fr}.ai-chat-location-card-list__stack--cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.ai-chat-location-card-list__stack--cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}@media (max-width:1000px){.ai-chat-location-card-list__stack--cols-3{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (max-width:640px){.ai-chat-location-card-list__stack--cols-2,.ai-chat-location-card-list__stack--cols-3{grid-template-columns:1fr}}.ai-chat-location-card-list__grid{display:grid;gap:8px;grid-template-columns:repeat(2,1fr)}@media (max-width:400px){.ai-chat-location-card-list__grid{grid-template-columns:1fr}}.ai-chat-location-card-list__carousel{-webkit-overflow-scrolling:touch;-ms-overflow-style:none;display:flex;gap:8px;overflow-x:auto;padding-bottom:4px;scroll-snap-type:x mandatory;scrollbar-width:none}.ai-chat-location-card-list__carousel::-webkit-scrollbar{display:none}.ai-chat-location-card-list__carousel>.ai-chat-location-card{flex:0 0 280px;scroll-snap-align:start}.ai-chat-contact-card{background:#fff;border:1px solid rgba(0,0,0,.08);border-radius:16px;overflow:hidden;padding:0;position:relative}.ai-chat-widget.dark .ai-chat-contact-card,.ai-chat-widget[data-theme=dark] .ai-chat-contact-card,.chakra-ui-dark .ai-chat-contact-card,.dark .ai-chat-contact-card,[data-theme=dark] .ai-chat-contact-card,html.dark .ai-chat-contact-card{background:#4a4a4a;border-color:hsla(0,0%,100%,.08)}.ai-chat-contact-card-list{gap:12px;width:100%}.ai-chat-contact-card--compact{border-radius:12px}.ai-chat-contact-card--empty{align-items:center;background:var(--bg-secondary,#f4f4f5);display:flex;flex-direction:column;gap:8px;justify-content:center;padding:24px 16px;text-align:center}.ai-chat-widget.dark .ai-chat-contact-card--empty,.chakra-ui-dark .ai-chat-contact-card--empty,.dark .ai-chat-contact-card--empty,[data-theme=dark] .ai-chat-contact-card--empty{background:#3a3a3a}.ai-chat-contact-card__empty-icon{color:var(--text-muted,#71717a);opacity:.6}.ai-chat-contact-card__empty-text{color:var(--text-muted,#71717a);font-size:14px;margin:0}.ai-chat-contact-card--vertical{display:flex;flex-direction:column}.ai-chat-contact-card--vertical .ai-chat-contact-card__image-section{aspect-ratio:3/2;overflow:hidden;width:100%}.ai-chat-contact-card--vertical .ai-chat-contact-card__image{height:100%;object-fit:cover;width:100%}.ai-chat-contact-card--vertical .ai-chat-contact-card__image-placeholder{align-items:center;background:linear-gradient(135deg,#5a5a5a,#3a3a3a);color:hsla(0,0%,100%,.5);display:flex;height:100%;justify-content:center;width:100%}.ai-chat-contact-card--vertical .ai-chat-contact-card__image-placeholder svg{height:48px;width:48px}.ai-chat-contact-card--vertical .ai-chat-contact-card__info{padding:16px;text-align:center}.ai-chat-contact-card--horizontal{display:flex;flex-direction:row}.ai-chat-contact-card--horizontal .ai-chat-contact-card__image-section{height:160px;min-width:140px;overflow:hidden;width:140px}.ai-chat-contact-card--horizontal.ai-chat-contact-card--compact .ai-chat-contact-card__image-section{height:120px;min-width:100px;width:100px}.ai-chat-contact-card--horizontal .ai-chat-contact-card__image{height:100%;object-fit:cover;width:100%}.ai-chat-contact-card--horizontal .ai-chat-contact-card__image-placeholder{align-items:center;background:linear-gradient(135deg,#5a5a5a,#3a3a3a);color:hsla(0,0%,100%,.5);display:flex;height:100%;justify-content:center;width:100%}.ai-chat-contact-card--horizontal .ai-chat-contact-card__image-placeholder svg{height:36px;width:36px}.ai-chat-contact-card--horizontal .ai-chat-contact-card__info{display:flex;flex:1;flex-direction:column;justify-content:center;padding:16px}.ai-chat-contact-card__name{color:var(--action-accent,#ef4444);font-size:18px;font-weight:600;line-height:1.3;margin:0}.ai-chat-contact-card--compact .ai-chat-contact-card__name{font-size:15px}.ai-chat-contact-card__role{color:rgba(0,0,0,.7);font-size:14px;font-weight:400;margin:2px 0 0}.ai-chat-widget.dark .ai-chat-contact-card__role,.ai-chat-widget[data-theme=dark] .ai-chat-contact-card__role,.chakra-ui-dark .ai-chat-contact-card__role,.dark .ai-chat-contact-card__role,[data-theme=dark] .ai-chat-contact-card__role,html.dark .ai-chat-contact-card__role{color:hsla(0,0%,100%,.9)}.ai-chat-contact-card--compact .ai-chat-contact-card__role{font-size:13px}.ai-chat-contact-card__details{display:flex;flex-direction:column;gap:2px;margin-top:12px}.ai-chat-contact-card__detail{color:rgba(0,0,0,.6);display:block;font-size:14px;line-height:1.5;margin:0;text-decoration:none}.ai-chat-contact-card__detail:hover{color:#000;text-decoration:underline}.ai-chat-widget.dark .ai-chat-contact-card__detail,.ai-chat-widget[data-theme=dark] .ai-chat-contact-card__detail,.chakra-ui-dark .ai-chat-contact-card__detail,.dark .ai-chat-contact-card__detail,[data-theme=dark] .ai-chat-contact-card__detail,html.dark .ai-chat-contact-card__detail{color:hsla(0,0%,100%,.7)}.ai-chat-widget.dark .ai-chat-contact-card__detail:hover,.ai-chat-widget[data-theme=dark] .ai-chat-contact-card__detail:hover,.chakra-ui-dark .ai-chat-contact-card__detail:hover,.dark .ai-chat-contact-card__detail:hover,[data-theme=dark] .ai-chat-contact-card__detail:hover,html.dark .ai-chat-contact-card__detail:hover{color:#fff}.ai-chat-contact-card--compact .ai-chat-contact-card__detail{font-size:13px}.ai-chat-contact-card__responsibilities{display:flex;flex-wrap:wrap;gap:4px;margin-top:8px}.ai-chat-contact-card__responsibility-tag{background:rgba(0,0,0,.08);border-radius:10px;color:rgba(0,0,0,.8);font-size:11px;font-weight:500;padding:3px 10px}.ai-chat-widget.dark .ai-chat-contact-card__responsibility-tag,.ai-chat-widget[data-theme=dark] .ai-chat-contact-card__responsibility-tag,.chakra-ui-dark .ai-chat-contact-card__responsibility-tag,.dark .ai-chat-contact-card__responsibility-tag,[data-theme=dark] .ai-chat-contact-card__responsibility-tag,html.dark .ai-chat-contact-card__responsibility-tag{background:hsla(0,0%,100%,.15);color:hsla(0,0%,100%,.9)}.ai-chat-contact-card__responsibility-more{color:rgba(0,0,0,.5);font-size:11px;padding:3px 4px}.ai-chat-widget.dark .ai-chat-contact-card__responsibility-more,.ai-chat-widget[data-theme=dark] .ai-chat-contact-card__responsibility-more,.chakra-ui-dark .ai-chat-contact-card__responsibility-more,.dark .ai-chat-contact-card__responsibility-more,[data-theme=dark] .ai-chat-contact-card__responsibility-more,html.dark .ai-chat-contact-card__responsibility-more{color:hsla(0,0%,100%,.5)}.ai-chat-contact-card__actions{display:flex;gap:8px;padding:0 12px 12px}.ai-chat-contact-card--compact .ai-chat-contact-card__actions{gap:6px;padding:0 10px 10px}.ai-chat-contact-card__button{align-items:center;border:none;border-radius:9999px;cursor:pointer;display:flex;font-size:14px;font-weight:600;gap:8px;justify-content:center;padding:12px 20px;transition:all .15s ease;white-space:nowrap}.ai-chat-contact-card--compact .ai-chat-contact-card__button{font-size:13px;padding:10px 16px}.ai-chat-contact-card__button:hover{box-shadow:0 4px 12px rgba(0,0,0,.15);transform:translateY(-1px)}.ai-chat-contact-card__button:active{transform:translateY(0)}.ai-chat-contact-card__button--primary{background:var(--action-accent,#3b82f6);color:#fff;flex:1}.ai-chat-contact-card__button--primary:hover{background:color-mix(in srgb,var(--action-accent,#3b82f6) 90%,#000)}.ai-chat-contact-card__button--secondary{background:var(--bg-muted,#f4f4f5);border:1px solid var(--border-subtle,rgba(0,0,0,.08));color:var(--text-primary,#18181b);flex:1}.ai-chat-contact-card__button--secondary:hover{background:var(--bg-hover,#e4e4e7)}.ai-chat-widget.dark .ai-chat-contact-card__button--secondary,.chakra-ui-dark .ai-chat-contact-card__button--secondary,.dark .ai-chat-contact-card__button--secondary,[data-theme=dark] .ai-chat-contact-card__button--secondary{background:hsla(0,0%,100%,.1);border-color:hsla(0,0%,100%,.15);color:#fff}.ai-chat-widget.dark .ai-chat-contact-card__button--secondary:hover,.chakra-ui-dark .ai-chat-contact-card__button--secondary:hover,.dark .ai-chat-contact-card__button--secondary:hover,[data-theme=dark] .ai-chat-contact-card__button--secondary:hover{background:hsla(0,0%,100%,.15)}.ai-chat-contact-card-list{display:flex;flex-direction:column;gap:8px}.ai-chat-contact-card-list__header{align-items:center;color:var(--text-muted,#71717a);display:flex;font-size:13px;font-weight:500;gap:6px;margin-bottom:2px;margin-top:8px;padding:0 4px}.ai-chat-contact-card-list__stack{display:grid;gap:12px;grid-template-columns:repeat(3,minmax(0,1fr))}@media (max-width:900px){.ai-chat-contact-card-list__stack{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (max-width:600px){.ai-chat-contact-card-list__stack{grid-template-columns:1fr}}.ai-chat-contact-card-list__stack--widget{grid-template-columns:1fr}@container (min-width: 380px){.ai-chat-contact-card-list__stack--widget{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (max-width:520px){.ai-chat-contact-card-list__stack{grid-template-columns:1fr!important}.ai-chat-contact-card--horizontal{flex-direction:column}.ai-chat-contact-card--horizontal .ai-chat-contact-card__image-section{aspect-ratio:3/2;height:auto;min-width:100%;width:100%}}.ai-chat-contact-card__initials{align-items:center;display:flex;font-size:48px;font-weight:600;height:100%;justify-content:center;letter-spacing:.05em;text-transform:uppercase;width:100%}.ai-chat-contact-card--compact .ai-chat-contact-card__initials{font-size:32px}.ai-chat-contact-card--horizontal .ai-chat-contact-card__initials{font-size:28px}.ai-chat-contact-card--horizontal.ai-chat-contact-card--compact .ai-chat-contact-card__initials{font-size:22px}.ai-chat-form-card{--action-accent:var(--primary-color,#3b82f6);background:var(--bg-secondary,#f9fafb);border:1px solid var(--border-subtle,rgba(0,0,0,.06));border-radius:12px;box-sizing:border-box;margin:6px 0;overflow:hidden;padding:16px;width:100%}.ai-chat-widget.dark .ai-chat-form-card,.chakra-ui-dark .ai-chat-form-card,.dark .ai-chat-form-card,[data-theme=dark] .ai-chat-form-card{background:hsla(0,0%,100%,.05);border-color:hsla(0,0%,100%,.1)}.ai-chat-form-card--empty,.ai-chat-form-card--error,.ai-chat-form-card--skipped,.ai-chat-form-card--submitted{padding:12px 16px}.ai-chat-form-card__header{align-items:center;display:flex;gap:8px;margin-bottom:12px}.ai-chat-form-card__icon{font-size:18px}.ai-chat-form-card__title{color:var(--text-primary,#3e3e3e);font-size:15px;font-weight:600}.ai-chat-widget.dark .ai-chat-form-card__title,.chakra-ui-dark .ai-chat-form-card__title,.dark .ai-chat-form-card__title,[data-theme=dark] .ai-chat-form-card__title{color:#fff}.ai-chat-form-card__description{color:var(--text-muted,#71717a);font-size:13px;line-height:1.4;margin:0 0 12px}.ai-chat-form-card__context{color:var(--text-muted,#71717a);font-size:12px;font-style:italic;margin:0 0 12px}.ai-chat-form-card__error{color:#dc2626;font-size:13px;margin:0}.ai-chat-widget.dark .ai-chat-form-card__error,.chakra-ui-dark .ai-chat-form-card__error,.dark .ai-chat-form-card__error,[data-theme=dark] .ai-chat-form-card__error{color:#fca5a5}.ai-chat-form-card__success{color:#16a34a;font-size:13px;margin:0}.ai-chat-widget.dark .ai-chat-form-card__success,.chakra-ui-dark .ai-chat-form-card__success,.dark .ai-chat-form-card__success,[data-theme=dark] .ai-chat-form-card__success{color:#4ade80}.ai-chat-form-card__empty-text,.ai-chat-form-card__skipped-text{color:var(--text-muted,#71717a);font-size:13px;margin:0}.ai-chat-form-card__progress{align-items:center;display:flex;gap:12px;margin-bottom:16px}.ai-chat-form-card__progress-bar{background:var(--action-accent,var(--primary-color,#3b82f6));border-radius:2px;flex:1;height:4px;transition:width .3s ease}.ai-chat-form-card__progress-text{color:var(--text-muted,#71717a);font-size:12px;white-space:nowrap}.ai-chat-form-card__question{margin-bottom:16px}.ai-chat-form-card__question-text{color:var(--text-primary,#3e3e3e);font-size:14px;font-weight:500;line-height:1.4;margin:0 0 12px}.ai-chat-widget.dark .ai-chat-form-card__question-text,.chakra-ui-dark .ai-chat-form-card__question-text,.dark .ai-chat-form-card__question-text,[data-theme=dark] .ai-chat-form-card__question-text{color:#fff}.ai-chat-form-card__required{color:#dc2626;margin-left:2px}.ai-chat-form-card__answer{margin-top:8px}.ai-chat-form-card__textarea{background:var(--bg-primary,#fff);border:1px solid var(--border-default,#e5e7eb);border-radius:var(--radius-md,8px);box-sizing:border-box;color:var(--text-primary,#3e3e3e);font-family:inherit;font-size:14px;min-height:80px;outline:none;padding:10px 12px;resize:vertical;transition:border-color .2s ease,box-shadow .2s ease;width:100%}.ai-chat-form-card__textarea:focus{border-color:var(--action-accent,var(--primary-color,#3b82f6));box-shadow:0 0 0 3px rgba(59,130,246,.1)}.ai-chat-form-card__textarea::placeholder{color:var(--text-muted,#9ca3af)}.ai-chat-widget.dark .ai-chat-form-card__textarea,.chakra-ui-dark .ai-chat-form-card__textarea,.dark .ai-chat-form-card__textarea,[data-theme=dark] .ai-chat-form-card__textarea{background:rgba(0,0,0,.2);border-color:hsla(0,0%,100%,.1);color:#fff}.ai-chat-widget.dark .ai-chat-form-card__textarea:focus,.chakra-ui-dark .ai-chat-form-card__textarea:focus,.dark .ai-chat-form-card__textarea:focus,[data-theme=dark] .ai-chat-form-card__textarea:focus{border-color:var(--action-accent,var(--primary-color,#3b82f6));box-shadow:0 0 0 3px rgba(59,130,246,.2)}.ai-chat-form-card__options{display:flex;flex-direction:column;gap:8px}.ai-chat-form-card__option{align-items:center;background:var(--bg-primary,#fff);border:1px solid var(--border-default,#e5e7eb);border-radius:var(--radius-md,8px);cursor:pointer;display:flex;gap:10px;padding:10px 12px;transition:border-color .15s,background .15s}.ai-chat-form-card__option:hover{background:rgba(59,130,246,.05);border-color:var(--action-accent,var(--primary-color,#3b82f6))}.ai-chat-widget.dark .ai-chat-form-card__option,.chakra-ui-dark .ai-chat-form-card__option,.dark .ai-chat-form-card__option,[data-theme=dark] .ai-chat-form-card__option{background:rgba(0,0,0,.2);border-color:hsla(0,0%,100%,.1)}.ai-chat-widget.dark .ai-chat-form-card__option:hover,.chakra-ui-dark .ai-chat-form-card__option:hover,.dark .ai-chat-form-card__option:hover,[data-theme=dark] .ai-chat-form-card__option:hover{background:rgba(59,130,246,.15);border-color:var(--action-accent,var(--primary-color,#3b82f6))}.ai-chat-form-card__option input{accent-color:var(--action-accent,var(--primary-color,#3b82f6));margin:0}.ai-chat-form-card__option-text{color:var(--text-primary,#3e3e3e);font-size:14px}.ai-chat-widget.dark .ai-chat-form-card__option-text,.chakra-ui-dark .ai-chat-form-card__option-text,.dark .ai-chat-form-card__option-text,[data-theme=dark] .ai-chat-form-card__option-text{color:#fff}.ai-chat-form-card__rating{display:flex;flex-wrap:wrap;gap:8px}.ai-chat-form-card__rating-btn{align-items:center;background:var(--bg-primary,#fff);border:1px solid var(--border-default,#e5e7eb);border-radius:var(--radius-md,8px);color:var(--text-primary,#3e3e3e);cursor:pointer;display:flex;font-size:14px;font-weight:500;height:40px;justify-content:center;transition:all .15s ease;width:40px}.ai-chat-form-card__rating-btn--selected,.ai-chat-form-card__rating-btn:hover{border-color:var(--action-accent,var(--primary-color,#3b82f6))}.ai-chat-form-card__rating-btn--selected{background:var(--action-accent,var(--primary-color,#3b82f6));color:#fff}.ai-chat-widget.dark .ai-chat-form-card__rating-btn,.chakra-ui-dark .ai-chat-form-card__rating-btn,.dark .ai-chat-form-card__rating-btn,[data-theme=dark] .ai-chat-form-card__rating-btn{background:rgba(0,0,0,.2);border-color:hsla(0,0%,100%,.1);color:#fff}.ai-chat-widget.dark .ai-chat-form-card__rating-btn:hover,.chakra-ui-dark .ai-chat-form-card__rating-btn:hover,.dark .ai-chat-form-card__rating-btn:hover,[data-theme=dark] .ai-chat-form-card__rating-btn:hover{border-color:var(--action-accent,var(--primary-color,#3b82f6))}.ai-chat-widget.dark .ai-chat-form-card__rating-btn--selected,.chakra-ui-dark .ai-chat-form-card__rating-btn--selected,.dark .ai-chat-form-card__rating-btn--selected,[data-theme=dark] .ai-chat-form-card__rating-btn--selected{background:var(--action-accent,var(--primary-color,#3b82f6));border-color:var(--action-accent,var(--primary-color,#3b82f6));color:#fff}.ai-chat-form-card__actions{align-items:center;border-top:1px solid var(--border-subtle,rgba(0,0,0,.08));display:flex;gap:8px;margin-top:16px;padding-top:16px}.ai-chat-widget.dark .ai-chat-form-card__actions,.chakra-ui-dark .ai-chat-form-card__actions,.dark .ai-chat-form-card__actions,[data-theme=dark] .ai-chat-form-card__actions{border-color:hsla(0,0%,100%,.08)}.ai-chat-form-card__actions-spacer{flex:1}.ai-chat-form-card__btn{border:none;border-radius:9999px;cursor:pointer;font-family:inherit;font-size:13px;font-weight:500;padding:8px 16px;transition:all .2s ease}.ai-chat-form-card__btn:disabled{cursor:not-allowed;opacity:.5}.ai-chat-form-card__btn--primary{background:var(--action-accent,var(--primary-color,#3b82f6));color:#fff}.ai-chat-form-card__btn--primary:hover:not(:disabled){opacity:.9;transform:translateY(-1px)}.ai-chat-form-card__btn--secondary{background:var(--bg-primary,#fff);border:1px solid var(--border-default,#e5e7eb);color:var(--text-primary,#3e3e3e)}.ai-chat-form-card__btn--secondary:hover:not(:disabled){border-color:var(--action-accent,var(--primary-color,#3b82f6))}.ai-chat-widget.dark .ai-chat-form-card__btn--secondary,.chakra-ui-dark .ai-chat-form-card__btn--secondary,.dark .ai-chat-form-card__btn--secondary,[data-theme=dark] .ai-chat-form-card__btn--secondary{background:hsla(0,0%,100%,.05);border-color:hsla(0,0%,100%,.1);color:#fff}.ai-chat-form-card__btn--ghost{background:transparent;color:var(--text-muted,#71717a)}.ai-chat-form-card__btn--ghost:hover:not(:disabled){background:rgba(0,0,0,.05);color:var(--text-primary,#3e3e3e)}.ai-chat-widget.dark .ai-chat-form-card__btn--ghost:hover:not(:disabled),.chakra-ui-dark .ai-chat-form-card__btn--ghost:hover:not(:disabled),.dark .ai-chat-form-card__btn--ghost:hover:not(:disabled),[data-theme=dark] .ai-chat-form-card__btn--ghost:hover:not(:disabled){background:hsla(0,0%,100%,.05);color:#fff}.chat-fullpage{--fp-max-width:800px;--fp-padding-x:16px;--fp-padding-top-mobile:64px;--fp-padding-top-desktop:16px;--fp-padding-bottom:200px;--fp-input-bottom:0}.chat-fullpage .ai-chat-messages{background:transparent;height:100%;margin:0 auto;max-width:var(--fp-max-width);padding:var(--fp-padding-top-desktop) var(--fp-padding-x) var(--fp-padding-bottom)}@media (max-width:768px){.chat-fullpage .ai-chat-messages{padding-top:var(--fp-padding-top-mobile)}}.chat-fullpage .ai-chat-message{animation:none}.chat-fullpage .ai-chat-message.user{max-width:85%}.chat-fullpage .ai-chat-message.user .ai-chat-message-content{background:var(--bg-muted,#f4f4f5);border-radius:24px;color:#000;padding:8px 16px}.chat-fullpage.dark .ai-chat-message.user .ai-chat-message-content{background:var(--bg-muted,#27272a);color:#fff}.chat-fullpage .ai-chat-message.assistant{width:100%}.chat-fullpage .ai-chat-message.assistant .ai-chat-message-content{color:#000;padding:8px 16px}.chat-fullpage.dark .ai-chat-message.assistant .ai-chat-message-content{color:#fff}.chat-fullpage .ai-chat-message.tool{margin:0;padding:0;width:100%}.chat-fullpage .ai-chat-welcome{align-items:center;display:flex;flex-direction:column;gap:24px;justify-content:center;min-height:60vh;padding:24px;text-align:center}.chat-fullpage .ai-chat-welcome-title{font-size:32px;font-weight:600}.chat-fullpage .ai-chat-welcome-text{color:var(--text-muted,#71717a);font-size:18px;max-width:400px}.chat-fullpage .ai-chat-input-container{background:transparent;bottom:0;left:0;padding:16px 16px calc(16px + env(safe-area-inset-bottom));position:fixed;right:0;z-index:20}.chat-fullpage .ai-chat-input-container:after{background:var(--bg-primary,#fff);bottom:0;content:\"\";height:calc(40% + 16px);left:0;pointer-events:none;position:absolute;right:0;z-index:-1}.chat-fullpage.dark .ai-chat-input-container:after{background:var(--bg-primary,#18181b)}@media (min-width:769px){.chat-fullpage .ai-chat-input-container{background:transparent;bottom:var(--fp-input-bottom);left:50%;max-width:var(--fp-max-width);padding:0;position:absolute;right:auto;transform:translateX(-50%);width:100%}}.chat-fullpage .ai-chat-input-wrapper{background:var(--bg-muted,#f4f4f5);border:1px solid var(--border-muted,#e4e4e7);border-radius:24px;box-shadow:0 1px 8px rgba(0,0,0,.06);margin:0 auto;max-width:var(--fp-max-width)}.chat-fullpage.dark .ai-chat-input-wrapper{background:var(--bg-muted,#27272a);border-color:var(--border-muted,#3f3f46);box-shadow:0 1px 12px rgba(0,0,0,.25)}.chat-fullpage .ai-chat-scroll-button{bottom:100px}@media (min-width:769px){.chat-fullpage .ai-chat-scroll-button{bottom:90px}}.chat-fullpage .ai-chat-suggested-questions{display:flex;flex-wrap:wrap;gap:8px;justify-content:center;max-width:600px}.chat-fullpage .ai-chat-suggested-question{border-radius:9999px;font-size:14px;padding:8px 16px}.chat-fullpage .ai-chat-follow-up-suggestions{margin-top:12px}.chat-fullpage .ai-chat-follow-up-item.question-type{background:transparent;border:1px solid var(--border-default,#d4d4d8);color:#000}.chat-fullpage .ai-chat-follow-up-item.question-type:hover{background:var(--bg-hover,#f4f4f5)}.chat-fullpage.dark .ai-chat-follow-up-item.question-type{background:transparent;border:1px solid var(--border-subtle,#52525b);color:#fff}.chat-fullpage.dark .ai-chat-follow-up-item.question-type:hover{background:var(--bg-hover,#3f3f46)}.chat-fullpage .ai-chat-typing{padding:8px 16px}@media (max-width:480px){body.ai-chat-widget-open{height:100%!important;overflow:hidden!important;position:fixed!important;touch-action:none!important;width:100%!important}.ai-chat-widget-container.is-open{height:100vh!important;height:100dvh!important;width:100vw!important;z-index:var(--widget-z-index,2147483647)!important}.ai-chat-widget-container.is-open,.ai-chat-widget-container.is-open .ai-chat-window{bottom:0!important;left:0!important;position:fixed!important;right:0!important;top:0!important}.ai-chat-widget-container.is-open .ai-chat-window{animation:none!important;border:none!important;border-radius:0!important;box-shadow:none!important;height:100%!important;max-height:100%!important;max-width:100%!important;outline:none!important;transform:none!important;width:100%!important}.ai-chat-widget-container.is-open .ai-chat-button{display:none!important;pointer-events:none!important;visibility:hidden!important}.ai-chat-widget-container.is-open .ai-chat-header{border-radius:0!important;flex-shrink:0;padding-left:max(16px,env(safe-area-inset-left));padding-right:max(16px,env(safe-area-inset-right));padding-top:max(12px,env(safe-area-inset-top));position:relative;z-index:100}.ai-chat-widget-container.is-open .ai-chat-messages{-webkit-overflow-scrolling:touch;flex:1;overflow-x:hidden;overflow-y:auto;overscroll-behavior:contain;padding-bottom:120px;padding-left:max(16px,env(safe-area-inset-left));padding-right:max(16px,env(safe-area-inset-right));touch-action:pan-y}.ai-chat-widget-container.is-open .ai-chat-input-container{background:var(--bg-primary,#fff);bottom:0!important;left:0!important;padding:8px max(12px,env(safe-area-inset-right)) max(16px,calc(env(safe-area-inset-bottom) + 8px)) max(12px,env(safe-area-inset-left));position:fixed!important;right:0!important;z-index:100}.ai-chat-widget.dark .ai-chat-widget-container.is-open .ai-chat-input-container{background:var(--bg-primary,#282625)}.ai-chat-widget-container.is-open .ai-chat-input-container:after{display:none}.ai-chat-widget-container.is-open .ai-chat-input-wrapper{margin:0;max-width:100%}.ai-chat-widget-container.is-open .ai-chat-scroll-button{bottom:calc(80px + env(safe-area-inset-bottom))}.ai-chat-widget-container.is-open .ai-chat-welcome{padding:16px 0}.ai-chat-widget-container.is-open .ai-chat-welcome-title{font-size:24px}.ai-chat-widget-container.is-open .ai-chat-suggested-questions{align-items:stretch;flex-direction:column}.ai-chat-widget-container.is-open .ai-chat-suggested-question{text-align:center;width:100%}}@media (min-width:481px) and (max-width:768px){.ai-chat-widget-container.is-open .ai-chat-window{border-radius:22px 22px 44px 44px;max-height:calc(100vh - 100px);max-width:calc(100vw - 32px)}}";
|
|
47095
|
+
styleInject(css_248z$1);
|
|
47096
|
+
|
|
47097
|
+
var css_248z = ".ai-chat-data-policy-view{display:flex;flex:1;flex-direction:column;min-height:0;overflow:hidden}.ai-chat-data-policy-content{-webkit-overflow-scrolling:touch;flex:1;overflow-y:auto;padding:20px 16px 40px}.ai-chat-data-policy-intro{align-items:center;background:var(--bg-subtle,rgba(0,0,0,.02));border-radius:12px;display:flex;flex-direction:column;margin-bottom:20px;padding:16px;text-align:center}.ai-chat-widget.dark .ai-chat-data-policy-intro{background:var(--bg-subtle,hsla(0,0%,100%,.04))}.ai-chat-data-policy-icon{align-items:center;background:var(--primary-color,#07f);border-radius:12px;color:#fff;display:flex;height:48px;justify-content:center;margin-bottom:12px;width:48px}.ai-chat-data-policy-intro p{color:var(--text-secondary,#52525b);font-size:13px;line-height:1.5;margin:0}.ai-chat-widget.dark .ai-chat-data-policy-intro p{color:var(--text-secondary,#a1a1aa)}.ai-chat-data-policy-intro strong{color:var(--text-primary,#18181b)}.ai-chat-widget.dark .ai-chat-data-policy-intro strong{color:var(--text-primary,#fafafa)}.ai-chat-data-policy-section{margin-bottom:20px}.ai-chat-data-policy-section h3{color:var(--text-primary,#18181b);font-size:13px;font-weight:600;letter-spacing:.02em;margin:0 0 8px;text-transform:uppercase}.ai-chat-widget.dark .ai-chat-data-policy-section h3{color:var(--text-primary,#fafafa)}.ai-chat-data-policy-section ul{list-style:none;margin:0;padding:0}.ai-chat-data-policy-section li{color:var(--text-secondary,#52525b);font-size:12px;line-height:1.5;padding:8px 0 8px 16px;position:relative}.ai-chat-widget.dark .ai-chat-data-policy-section li{color:var(--text-secondary,#a1a1aa)}.ai-chat-data-policy-section li:before{background:var(--text-muted,#a1a1aa);border-radius:50%;content:\"\";height:4px;left:0;position:absolute;top:14px;width:4px}.ai-chat-data-policy-section li strong{color:var(--text-primary,#18181b)}.ai-chat-widget.dark .ai-chat-data-policy-section li strong{color:var(--text-primary,#fafafa)}.ai-chat-data-policy-section p{color:var(--text-secondary,#52525b);font-size:12px;line-height:1.5;margin:0}.ai-chat-widget.dark .ai-chat-data-policy-section p{color:var(--text-secondary,#a1a1aa)}.ai-chat-data-policy-warning{background:rgba(234,179,8,.1);border:1px solid rgba(234,179,8,.3);border-radius:8px;color:#92400e!important;padding:12px}.ai-chat-widget.dark .ai-chat-data-policy-warning{background:rgba(234,179,8,.15);border-color:rgba(234,179,8,.25);color:#fbbf24!important}";
|
|
46372
47098
|
styleInject(css_248z);
|
|
46373
47099
|
|
|
46374
47100
|
// Icon components mapping
|
|
@@ -46376,9 +47102,10 @@
|
|
|
46376
47102
|
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" }) })),
|
|
46377
47103
|
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" }) })),
|
|
46378
47104
|
};
|
|
46379
|
-
const ChatWidget = ({ widgetId, apiUrl = window.location.origin, previewMode = false, previewConfig, position = 'bottom-right', primaryColor, size, headerTitle, welcomeTitle, welcomeMessage, placeholder, theme, suggestedQuestions, customStyles, currentRoute, defaultOpen = false, zIndex, onOpen, onClose, onMessage, onError, mode = 'bubble', }) => {
|
|
47105
|
+
const ChatWidget = ({ widgetId, apiUrl = window.location.origin, previewMode = false, previewConfig, position = 'bottom-right', primaryColor, size, headerTitle, welcomeTitle, welcomeMessage, placeholder, welcomeBubbleText, theme, suggestedQuestions, customStyles, currentRoute, defaultOpen = false, zIndex, containerMode = false, onOpen, onClose, onMessage, onError, mode = 'bubble', }) => {
|
|
46380
47106
|
const [isOpen, setIsOpen] = reactExports.useState(defaultOpen);
|
|
46381
47107
|
const [autoDetectedTheme, setAutoDetectedTheme] = reactExports.useState('light');
|
|
47108
|
+
const [showWelcomeBubble, setShowWelcomeBubble] = reactExports.useState(false);
|
|
46382
47109
|
const widgetRef = reactExports.useRef(null);
|
|
46383
47110
|
const containerRef = reactExports.useRef(null);
|
|
46384
47111
|
// Determine mode
|
|
@@ -46400,6 +47127,7 @@
|
|
|
46400
47127
|
showChatHistory: true,
|
|
46401
47128
|
showTimestamps: true,
|
|
46402
47129
|
showTypingIndicator: true,
|
|
47130
|
+
showToolCalls: false,
|
|
46403
47131
|
enableFileUpload: false,
|
|
46404
47132
|
enableFeedback: true,
|
|
46405
47133
|
},
|
|
@@ -46438,7 +47166,6 @@
|
|
|
46438
47166
|
const messages = previewMode ? [] : chatHook.messages;
|
|
46439
47167
|
const isLoading = previewMode ? false : chatHook.isLoading;
|
|
46440
47168
|
const isTyping = previewMode ? false : chatHook.isTyping;
|
|
46441
|
-
const error = previewMode ? null : chatHook.error;
|
|
46442
47169
|
const config = previewMode ? mergedPreviewConfig : chatHook.config;
|
|
46443
47170
|
const sendMessage = previewMode ? (() => Promise.resolve()) : chatHook.sendMessage;
|
|
46444
47171
|
const submitFeedback = previewMode ? (() => Promise.resolve()) : chatHook.submitFeedback;
|
|
@@ -46473,8 +47200,13 @@
|
|
|
46473
47200
|
mediaQuery.removeEventListener('change', handleMediaChange);
|
|
46474
47201
|
};
|
|
46475
47202
|
}, [config]);
|
|
46476
|
-
//
|
|
47203
|
+
// Check if device is mobile
|
|
47204
|
+
const isMobile = typeof window !== 'undefined' && window.innerWidth <= 480;
|
|
47205
|
+
// Handle auto-open (only for bubble mode, disabled on mobile)
|
|
46477
47206
|
reactExports.useEffect(() => {
|
|
47207
|
+
// Never auto-open on mobile devices
|
|
47208
|
+
if (isMobile)
|
|
47209
|
+
return undefined;
|
|
46478
47210
|
if (!isEmbedded && config?.settings.autoOpen) {
|
|
46479
47211
|
const delay = config.settings.autoOpenDelay || 0;
|
|
46480
47212
|
const timer = setTimeout(() => {
|
|
@@ -46484,7 +47216,7 @@
|
|
|
46484
47216
|
return () => clearTimeout(timer);
|
|
46485
47217
|
}
|
|
46486
47218
|
return undefined;
|
|
46487
|
-
}, [config, onOpen, isEmbedded]);
|
|
47219
|
+
}, [config, onOpen, isEmbedded, isMobile]);
|
|
46488
47220
|
// Handle close on Escape key (only for bubble mode)
|
|
46489
47221
|
reactExports.useEffect(() => {
|
|
46490
47222
|
if (!isOpen || isEmbedded)
|
|
@@ -46498,6 +47230,37 @@
|
|
|
46498
47230
|
document.addEventListener('keydown', handleEscapeKey);
|
|
46499
47231
|
return () => document.removeEventListener('keydown', handleEscapeKey);
|
|
46500
47232
|
}, [isOpen, onClose, isEmbedded]);
|
|
47233
|
+
// Handle body scroll lock on mobile when widget is open
|
|
47234
|
+
reactExports.useEffect(() => {
|
|
47235
|
+
if (!isOpen || isEmbedded)
|
|
47236
|
+
return;
|
|
47237
|
+
// Only apply scroll lock on mobile
|
|
47238
|
+
const checkMobile = window.innerWidth <= 480;
|
|
47239
|
+
if (!checkMobile)
|
|
47240
|
+
return;
|
|
47241
|
+
// Add class to body to lock scrolling
|
|
47242
|
+
document.body.classList.add('ai-chat-widget-open');
|
|
47243
|
+
return () => {
|
|
47244
|
+
document.body.classList.remove('ai-chat-widget-open');
|
|
47245
|
+
};
|
|
47246
|
+
}, [isOpen, isEmbedded]);
|
|
47247
|
+
// Handle welcome bubble visibility per session
|
|
47248
|
+
// Shows on each new session if welcomeBubbleText is configured
|
|
47249
|
+
reactExports.useEffect(() => {
|
|
47250
|
+
if (isEmbedded || previewMode)
|
|
47251
|
+
return;
|
|
47252
|
+
const bubbleText = welcomeBubbleText ?? config?.appearance?.welcomeBubbleText;
|
|
47253
|
+
if (!bubbleText) {
|
|
47254
|
+
setShowWelcomeBubble(false);
|
|
47255
|
+
return;
|
|
47256
|
+
}
|
|
47257
|
+
// Check if bubble was already dismissed this session
|
|
47258
|
+
const storageKey = `ai-chat-bubble-dismissed-${widgetId || 'default'}`;
|
|
47259
|
+
const wasDismissed = sessionStorage.getItem(storageKey) === 'true';
|
|
47260
|
+
if (!wasDismissed && !isOpen) {
|
|
47261
|
+
setShowWelcomeBubble(true);
|
|
47262
|
+
}
|
|
47263
|
+
}, [widgetId, welcomeBubbleText, config, isOpen, isEmbedded, previewMode]);
|
|
46501
47264
|
// Determine theme - use prop override if provided, otherwise auto-detect
|
|
46502
47265
|
const appearanceConfig = config?.appearance;
|
|
46503
47266
|
const effectiveTheme = theme ?? autoDetectedTheme;
|
|
@@ -46511,6 +47274,7 @@
|
|
|
46511
47274
|
const effectiveWelcomeTitle = welcomeTitle ?? appearanceConfig?.welcomeTitle ?? '';
|
|
46512
47275
|
const effectiveWelcomeMessage = welcomeMessage ?? appearanceConfig?.welcomeMessage ?? '';
|
|
46513
47276
|
const effectivePlaceholder = placeholder ?? appearanceConfig?.placeholder ?? '';
|
|
47277
|
+
const effectiveWelcomeBubbleText = welcomeBubbleText ?? appearanceConfig?.welcomeBubbleText ?? '';
|
|
46514
47278
|
// Generate styles using simplified theme system
|
|
46515
47279
|
const simpleAppearance = {
|
|
46516
47280
|
accentColor};
|
|
@@ -46532,6 +47296,18 @@
|
|
|
46532
47296
|
return;
|
|
46533
47297
|
const newState = !isOpen;
|
|
46534
47298
|
setIsOpen(newState);
|
|
47299
|
+
// Dismiss welcome bubble when chat is opened
|
|
47300
|
+
if (newState && showWelcomeBubble) {
|
|
47301
|
+
setShowWelcomeBubble(false);
|
|
47302
|
+
// Store in sessionStorage so it doesn't show again this session
|
|
47303
|
+
const storageKey = `ai-chat-bubble-dismissed-${widgetId || 'default'}`;
|
|
47304
|
+
try {
|
|
47305
|
+
sessionStorage.setItem(storageKey, 'true');
|
|
47306
|
+
}
|
|
47307
|
+
catch {
|
|
47308
|
+
// Ignore storage errors
|
|
47309
|
+
}
|
|
47310
|
+
}
|
|
46535
47311
|
if (newState) {
|
|
46536
47312
|
onOpen?.();
|
|
46537
47313
|
}
|
|
@@ -46562,13 +47338,13 @@
|
|
|
46562
47338
|
const IconComponent = isOpen ? iconComponents.FiChevronDown : iconComponents.FiMessageCircle;
|
|
46563
47339
|
// Embedded mode renders directly without wrapper positioning
|
|
46564
47340
|
if (isEmbedded) {
|
|
46565
|
-
return (jsxRuntimeExports.jsx("div", { ref: containerRef, className: `ai-chat-widget ai-chat-widget-embedded ${effectiveTheme}`, style: { ...mergedStyles, width: '100%', height: '100%' }, children: jsxRuntimeExports.jsx(ChatWindow, { messages: messages, isLoading: isLoading, isTyping: isTyping,
|
|
47341
|
+
return (jsxRuntimeExports.jsx("div", { ref: containerRef, className: `ai-chat-widget ai-chat-widget-embedded ${effectiveTheme}`, style: { ...mergedStyles, width: '100%', height: '100%' }, children: jsxRuntimeExports.jsx(ChatWindow, { messages: messages, isLoading: isLoading, isTyping: isTyping, config: config, onSendMessage: sendMessage, onClose: () => { }, onFeedback: handleFeedback, onActionClick: handleActionClick, conversations: conversations, onLoadConversations: loadConversations, onSwitchConversation: switchConversation, onStartNewConversation: startNewConversation, onDeleteConversation: deleteConversation, currentConversationId: conversationId, headerTitleOverride: effectiveHeaderTitle, welcomeTitleOverride: effectiveWelcomeTitle, welcomeMessageOverride: effectiveWelcomeMessage, placeholderOverride: effectivePlaceholder, suggestedQuestionsOverride: suggestedQuestions }) }));
|
|
46566
47342
|
}
|
|
46567
|
-
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} ${isOpen ? 'is-open' : ''}`, children: [isOpen && (jsxRuntimeExports.jsx(ChatWindow, { messages: messages, isLoading: isLoading, isTyping: isTyping,
|
|
47343
|
+
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} ${isOpen ? 'is-open' : ''} ${containerMode ? 'container-mode' : ''}`, children: [isOpen && (jsxRuntimeExports.jsx(ChatWindow, { messages: messages, isLoading: isLoading, isTyping: isTyping, config: config, onSendMessage: sendMessage, onClose: handleToggle, onFeedback: handleFeedback, onActionClick: handleActionClick,
|
|
46568
47344
|
// Chat history props (only active when persistConversation is true)
|
|
46569
47345
|
conversations: conversations, onLoadConversations: loadConversations, onSwitchConversation: switchConversation, onStartNewConversation: startNewConversation, onDeleteConversation: deleteConversation, currentConversationId: conversationId,
|
|
46570
47346
|
// Override props for live preview
|
|
46571
|
-
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, {}) }) })] }) }));
|
|
47347
|
+
headerTitleOverride: effectiveHeaderTitle, welcomeTitleOverride: effectiveWelcomeTitle, welcomeMessageOverride: effectiveWelcomeMessage, placeholderOverride: effectivePlaceholder, suggestedQuestionsOverride: suggestedQuestions })), !isOpen && effectiveWelcomeBubbleText && (previewMode || showWelcomeBubble) && (jsxRuntimeExports.jsx("div", { className: "ai-chat-welcome-bubble", onClick: handleToggle, children: jsxRuntimeExports.jsx("span", { children: effectiveWelcomeBubbleText }) })), 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, {}) }) })] }) }));
|
|
46572
47348
|
};
|
|
46573
47349
|
|
|
46574
47350
|
/**
|