@chatwidgetai/chat-widget 0.2.3 → 0.2.5

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.
Files changed (34) hide show
  1. package/dist/actions/google-calendar-appointment/component.d.ts +6 -0
  2. package/dist/actions/google-calendar-appointment/component.d.ts.map +1 -0
  3. package/dist/actions/google-calendar-appointment/handler.d.ts +2 -0
  4. package/dist/actions/google-calendar-appointment/handler.d.ts.map +1 -0
  5. package/dist/actions/google-calendar-appointment/index.d.ts +3 -0
  6. package/dist/actions/google-calendar-appointment/index.d.ts.map +1 -0
  7. package/dist/actions/index.d.ts +3 -0
  8. package/dist/actions/index.d.ts.map +1 -0
  9. package/dist/actions/registry.d.ts +24 -0
  10. package/dist/actions/registry.d.ts.map +1 -0
  11. package/dist/ai-chat-widget.umd.js +803 -307
  12. package/dist/ai-chat-widget.umd.js.map +1 -1
  13. package/dist/api/client.d.ts +8 -27
  14. package/dist/api/client.d.ts.map +1 -1
  15. package/dist/components/ChatWidget.d.ts.map +1 -1
  16. package/dist/components/ChatWindow.d.ts.map +1 -1
  17. package/dist/components/Message.d.ts.map +1 -1
  18. package/dist/components/MessageList.d.ts.map +1 -1
  19. package/dist/components/ToolMessageGroup.d.ts.map +1 -1
  20. package/dist/hooks/useChat.d.ts.map +1 -1
  21. package/dist/index.d.ts +1 -1
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.esm.js +803 -307
  24. package/dist/index.esm.js.map +1 -1
  25. package/dist/index.js +803 -307
  26. package/dist/index.js.map +1 -1
  27. package/dist/types/index.d.ts +86 -40
  28. package/dist/types/index.d.ts.map +1 -1
  29. package/dist/umd.d.ts +2 -1
  30. package/dist/umd.d.ts.map +1 -1
  31. package/dist/utils/sse-parser.d.ts +2 -0
  32. package/dist/utils/sse-parser.d.ts.map +1 -0
  33. package/dist/utils/storage.d.ts.map +1 -1
  34. package/package.json +1 -1
@@ -17341,13 +17341,53 @@
17341
17341
 
17342
17342
  var jsxRuntimeExports = requireJsxRuntime();
17343
17343
 
17344
- /**
17345
- * API Client for Widget Communication
17346
- * Handles all HTTP requests to the widget API
17347
- *
17348
- * Note: No API key required - widget ID acts as the access token.
17349
- * The widget ID should be kept confidential by the site owner.
17350
- */
17344
+ async function* parseSSEStream(response, validator) {
17345
+ if (!response.body) {
17346
+ throw new Error("Response body is null");
17347
+ }
17348
+ const reader = response.body.getReader();
17349
+ const decoder = new TextDecoder();
17350
+ let buffer = "";
17351
+ try {
17352
+ while (true) {
17353
+ const { done, value } = await reader.read();
17354
+ if (done)
17355
+ break;
17356
+ buffer += decoder.decode(value, { stream: true });
17357
+ const chunks = buffer.split("\n\n");
17358
+ buffer = chunks.pop() || "";
17359
+ for (const chunk of chunks) {
17360
+ const lines = chunk.split("\n");
17361
+ for (const line of lines) {
17362
+ if (line.startsWith("data: ")) {
17363
+ try {
17364
+ const data = JSON.parse(line.slice(6));
17365
+ if (validator) {
17366
+ if (validator(data)) {
17367
+ yield data;
17368
+ }
17369
+ else {
17370
+ console.warn("[SSE Parser] Data failed validation:", data);
17371
+ }
17372
+ }
17373
+ else {
17374
+ yield data;
17375
+ }
17376
+ }
17377
+ catch (e) {
17378
+ console.error("[SSE Parser] Failed to parse SSE data:", line, e);
17379
+ throw e;
17380
+ }
17381
+ }
17382
+ }
17383
+ }
17384
+ }
17385
+ }
17386
+ finally {
17387
+ reader.releaseLock();
17388
+ }
17389
+ }
17390
+
17351
17391
  class ApiError extends Error {
17352
17392
  constructor(message, status, options) {
17353
17393
  super(message);
@@ -17476,12 +17516,8 @@
17476
17516
  const result = await response.json();
17477
17517
  return result.file;
17478
17518
  }
17479
- /**
17480
- * Send a chat message (standard RAG, no actions)
17481
- * Returns ConversationMessage[] array
17482
- */
17483
- async sendMessage(conversationId, message, fileIds) {
17484
- const response = await fetch(`${this.config.apiUrl}/api/widget/${this.config.widgetId}/chat`, {
17519
+ async *sendAgentMessageStream(conversationId, message, fileIds) {
17520
+ const response = await fetch(`${this.config.apiUrl}/api/widget/${this.config.widgetId}/agent`, {
17485
17521
  method: 'POST',
17486
17522
  headers: {
17487
17523
  'Content-Type': 'application/json',
@@ -17494,167 +17530,36 @@
17494
17530
  }),
17495
17531
  });
17496
17532
  if (!response.ok) {
17497
- throw await buildApiError(response, 'Failed to send message');
17498
- }
17499
- return response.json();
17500
- }
17501
- /**
17502
- * Send a message to agent (with actions support)
17503
- */
17504
- async sendAgentMessage(conversationId, message, fileIds) {
17505
- try {
17506
- const response = await fetch(`${this.config.apiUrl}/api/widget/${this.config.widgetId}/agent`, {
17507
- method: 'POST',
17508
- headers: {
17509
- 'Content-Type': 'application/json',
17510
- },
17511
- body: JSON.stringify({
17512
- conversationId: conversationId,
17513
- message,
17514
- fileIds,
17515
- timeZone: this.getTimeZone(),
17516
- }),
17517
- });
17518
- if (!response.ok) {
17519
- throw await buildApiError(response, `Agent request failed with status ${response.status}`);
17520
- }
17521
- const data = await response.json();
17522
- // Check if response indicates an error
17523
- if (data.type === 'error') {
17524
- throw new Error(data.message || 'Agent encountered an error');
17525
- }
17526
- return data;
17527
- }
17528
- catch (error) {
17529
- // Enhance error messages
17530
- if (error instanceof TypeError && error.message.includes('fetch')) {
17531
- throw new ApiError('Network error: Unable to reach the server', 0);
17532
- }
17533
- throw error;
17533
+ throw await buildApiError(response, 'Failed to send agent message');
17534
17534
  }
17535
- }
17536
- /**
17537
- * Stream chat message responses
17538
- */
17539
- async *sendMessageStream(conversationId, message, fileIds) {
17540
- const response = await fetch(`${this.config.apiUrl}/api/widget/${this.config.widgetId}/chat`, {
17541
- method: 'POST',
17542
- headers: {
17543
- 'Content-Type': 'application/json',
17544
- },
17545
- body: JSON.stringify({
17546
- conversationId: conversationId,
17547
- message,
17548
- fileIds,
17549
- timeZone: this.getTimeZone(),
17550
- }),
17535
+ yield* parseSSEStream(response, (data) => {
17536
+ return typeof data === 'object' && data !== null && 'type' in data;
17551
17537
  });
17552
- if (!response.ok) {
17553
- throw await buildApiError(response, 'Failed to send message');
17554
- }
17555
- if (!response.body) {
17556
- throw new Error('Response body is null');
17557
- }
17558
- const reader = response.body.getReader();
17559
- const decoder = new TextDecoder();
17560
- let buffer = '';
17561
- try {
17562
- while (true) {
17563
- const { done, value } = await reader.read();
17564
- if (done)
17565
- break;
17566
- buffer += decoder.decode(value, { stream: true });
17567
- const lines = buffer.split('\n');
17568
- buffer = lines.pop() || '';
17569
- for (const line of lines) {
17570
- if (line.startsWith('data: ')) {
17571
- try {
17572
- const data = JSON.parse(line.slice(6));
17573
- // Handle error events
17574
- if (data.type === 'error') {
17575
- throw new Error(data.error || 'Stream error');
17576
- }
17577
- // Yield ConversationMessage objects
17578
- if (data.id) {
17579
- yield data;
17580
- }
17581
- }
17582
- catch (e) {
17583
- console.error('[Widget API Client] Failed to parse SSE data:', line, e);
17584
- throw e;
17585
- }
17586
- }
17587
- }
17588
- }
17589
- }
17590
- finally {
17591
- reader.releaseLock();
17592
- }
17593
17538
  }
17594
- /**
17595
- * Stream agent message responses with tool execution
17596
- * Handles streaming events from backend and yields ConversationMessage updates
17597
- */
17598
- async *sendAgentMessageStream(conversationId, message, fileIds) {
17599
- const response = await fetch(`${this.config.apiUrl}/api/widget/${this.config.widgetId}/agent`, {
17539
+ async *continueAgentMessageStream(conversationId, toolCallId, state) {
17540
+ const response = await fetch(`${this.config.apiUrl}/api/widget/${this.config.widgetId}/agent/continue`, {
17600
17541
  method: 'POST',
17601
17542
  headers: {
17602
17543
  'Content-Type': 'application/json',
17603
17544
  },
17604
17545
  body: JSON.stringify({
17605
17546
  conversationId: conversationId,
17606
- message,
17607
- fileIds,
17547
+ toolCallId,
17548
+ state,
17608
17549
  timeZone: this.getTimeZone(),
17609
17550
  }),
17610
17551
  });
17611
17552
  if (!response.ok) {
17612
- throw await buildApiError(response, 'Failed to send agent message');
17613
- }
17614
- if (!response.body) {
17615
- throw new Error('Response body is null');
17616
- }
17617
- const reader = response.body.getReader();
17618
- const decoder = new TextDecoder();
17619
- let buffer = '';
17620
- try {
17621
- while (true) {
17622
- const { done, value } = await reader.read();
17623
- if (done)
17624
- break;
17625
- buffer += decoder.decode(value, { stream: true });
17626
- const lines = buffer.split('\n');
17627
- buffer = lines.pop() || '';
17628
- for (const line of lines) {
17629
- if (line.startsWith('data: ')) {
17630
- try {
17631
- const data = JSON.parse(line.slice(6));
17632
- // Handle error events
17633
- if (data.type === 'error') {
17634
- throw new Error(data.error || 'Stream error');
17635
- }
17636
- // Yield ConversationMessage objects that come from the backend
17637
- // The backend yields full ConversationMessage objects during streaming
17638
- if (data.id) {
17639
- yield data;
17640
- }
17641
- }
17642
- catch (e) {
17643
- console.error('[Widget API Client] Failed to parse SSE data:', line, e);
17644
- throw e;
17645
- }
17646
- }
17647
- }
17648
- }
17649
- }
17650
- finally {
17651
- reader.releaseLock();
17553
+ throw await buildApiError(response, 'Failed to continue agent');
17652
17554
  }
17555
+ yield* parseSSEStream(response, (data) => {
17556
+ return typeof data === 'object' && data !== null && 'type' in data;
17557
+ });
17653
17558
  }
17654
17559
  /**
17655
17560
  * Submit feedback for a message
17656
17561
  */
17657
- async submitFeedback(sessionId, messageId, feedback) {
17562
+ async submitFeedback(sessionId, messageId, feedback, meta) {
17658
17563
  const response = await fetch(`${this.config.apiUrl}/api/widget/${this.config.widgetId}/feedback`, {
17659
17564
  method: 'POST',
17660
17565
  headers: {
@@ -17664,6 +17569,9 @@
17664
17569
  conversationId: sessionId,
17665
17570
  messageId: messageId,
17666
17571
  feedback,
17572
+ messageRole: meta?.role,
17573
+ messageContent: meta?.content,
17574
+ messageTimestamp: meta?.timestamp,
17667
17575
  }),
17668
17576
  });
17669
17577
  if (!response.ok) {
@@ -17714,6 +17622,173 @@
17714
17622
  return `msg_${timestamp}_${randomStr}`;
17715
17623
  }
17716
17624
 
17625
+ const pendingResolvers = new Map();
17626
+ const resumeCallbacks = new Map();
17627
+ const frontendActionHandlers = {};
17628
+ const actionRenderers = {};
17629
+ function getFrontendActionHandler(implementation) {
17630
+ return frontendActionHandlers[implementation];
17631
+ }
17632
+ function getActionRenderer(implementation) {
17633
+ return actionRenderers[implementation];
17634
+ }
17635
+ function getActionPrompt(implementation) {
17636
+ if (implementation === "google-calendar-appointment") {
17637
+ return "Select a date to continue.";
17638
+ }
17639
+ return "Action input required.";
17640
+ }
17641
+ function waitForActionState(toolCallId) {
17642
+ return new Promise((resolve) => {
17643
+ pendingResolvers.set(toolCallId, resolve);
17644
+ });
17645
+ }
17646
+ function resolveActionState(toolCallId, state) {
17647
+ const resolver = pendingResolvers.get(toolCallId);
17648
+ if (resolver) {
17649
+ pendingResolvers.delete(toolCallId);
17650
+ resolver(state);
17651
+ return;
17652
+ }
17653
+ // If no active resolver, check for a resume callback (for page reload scenario)
17654
+ const resumeCallback = resumeCallbacks.get(toolCallId);
17655
+ if (resumeCallback) {
17656
+ resumeCallback(state).catch((error) => {
17657
+ console.error("[Action] Failed to resume action:", error);
17658
+ });
17659
+ }
17660
+ }
17661
+ function registerActionResumeCallback(toolCallId, callback) {
17662
+ resumeCallbacks.set(toolCallId, callback);
17663
+ }
17664
+ function unregisterActionResumeCallback(toolCallId) {
17665
+ resumeCallbacks.delete(toolCallId);
17666
+ }
17667
+
17668
+ function groupSlotsByDate(slots) {
17669
+ const grouped = new Map();
17670
+ for (const slot of slots) {
17671
+ if (!slot || typeof slot !== 'object' || !slot.startTime || typeof slot.startTime !== 'string') {
17672
+ continue;
17673
+ }
17674
+ const date = slot.startTime.slice(0, 10);
17675
+ if (!grouped.has(date)) {
17676
+ grouped.set(date, []);
17677
+ }
17678
+ grouped.get(date).push(slot);
17679
+ }
17680
+ return grouped;
17681
+ }
17682
+ function formatDate(dateStr) {
17683
+ try {
17684
+ const date = new Date(dateStr);
17685
+ return new Intl.DateTimeFormat("en-US", {
17686
+ weekday: "short",
17687
+ month: "short",
17688
+ day: "numeric",
17689
+ }).format(date);
17690
+ }
17691
+ catch {
17692
+ return dateStr;
17693
+ }
17694
+ }
17695
+ function GoogleCalendarAppointmentCard({ message }) {
17696
+ const action = message.action;
17697
+ if (!action || action.implementation !== "google-calendar-appointment") {
17698
+ return null;
17699
+ }
17700
+ const rawSlots = action.state.availableSlots;
17701
+ const availableSlots = Array.isArray(rawSlots)
17702
+ ? rawSlots.filter((slot) => slot !== null &&
17703
+ slot !== undefined &&
17704
+ typeof slot === "object" &&
17705
+ "startTime" in slot &&
17706
+ "endTime" in slot &&
17707
+ typeof slot.startTime === "string" &&
17708
+ typeof slot.endTime === "string")
17709
+ : [];
17710
+ const allowTopic = action.state.allowTopic !== false;
17711
+ const isBooked = action.state.status === "booked";
17712
+ const slotsByDate = groupSlotsByDate(availableSlots);
17713
+ const dates = Array.from(slotsByDate.keys()).sort();
17714
+ const [selectedDate, setSelectedDate] = reactExports.useState(dates[0] ?? "");
17715
+ const [selectedSlot, setSelectedSlot] = reactExports.useState(null);
17716
+ const [topic, setTopic] = reactExports.useState("");
17717
+ const [error, setError] = reactExports.useState(null);
17718
+ const slotsForSelectedDate = selectedDate ? slotsByDate.get(selectedDate) ?? [] : [];
17719
+ const onConfirm = () => {
17720
+ if (!selectedSlot) {
17721
+ setError("Please select a time slot.");
17722
+ return;
17723
+ }
17724
+ if (allowTopic && !topic.trim()) {
17725
+ setError("Please enter a topic for the meeting.");
17726
+ return;
17727
+ }
17728
+ setError(null);
17729
+ resolveActionState(action.toolCallId, {
17730
+ ...action.state,
17731
+ selectedSlot: {
17732
+ startTime: selectedSlot.startTime,
17733
+ endTime: selectedSlot.endTime,
17734
+ },
17735
+ topic: allowTopic ? topic.trim() : null,
17736
+ });
17737
+ };
17738
+ if (isBooked) {
17739
+ const rawBookedSlot = action.state.selectedSlot;
17740
+ const bookedSlot = rawBookedSlot &&
17741
+ typeof rawBookedSlot === "object" &&
17742
+ "startTime" in rawBookedSlot &&
17743
+ "endTime" in rawBookedSlot
17744
+ ? rawBookedSlot
17745
+ : null;
17746
+ const bookedTopic = typeof action.state.topic === "string" ? action.state.topic : null;
17747
+ const eventLink = typeof action.state.bookedEventLink === "string" ? action.state.bookedEventLink : null;
17748
+ return (jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-card ai-chat-action-booked", children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-header", children: [jsxRuntimeExports.jsx("svg", { className: "ai-chat-action-icon-success", viewBox: "0 0 20 20", fill: "currentColor", children: jsxRuntimeExports.jsx("path", { fillRule: "evenodd", d: "M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z", clipRule: "evenodd" }) }), "Appointment Confirmed"] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-body", children: [bookedTopic && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-detail", children: [jsxRuntimeExports.jsx("span", { className: "ai-chat-action-label", children: "Topic:" }), jsxRuntimeExports.jsx("span", { className: "ai-chat-action-value", children: bookedTopic })] })), bookedSlot && bookedSlot.startTime && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-detail", children: [jsxRuntimeExports.jsx("span", { className: "ai-chat-action-label", children: "Time:" }), jsxRuntimeExports.jsx("span", { className: "ai-chat-action-value", children: bookedSlot.displayTime || new Date(bookedSlot.startTime).toLocaleString() })] })), eventLink && (jsxRuntimeExports.jsx("a", { href: eventLink, target: "_blank", rel: "noopener noreferrer", className: "ai-chat-action-link", children: "View in Google Calendar \u2192" }))] })] }));
17749
+ }
17750
+ return (jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-card", children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-header", children: [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" }) }), "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: () => {
17751
+ setSelectedDate(date);
17752
+ setSelectedSlot(null);
17753
+ }, 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))) })] })), 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." }))] })] }));
17754
+ }
17755
+
17756
+ frontendActionHandlers["google-calendar-appointment"] = async (_input, _state, context) => {
17757
+ return waitForActionState(context.toolCallId);
17758
+ };
17759
+
17760
+ function styleInject(css, ref) {
17761
+ if ( ref === void 0 ) ref = {};
17762
+ var insertAt = ref.insertAt;
17763
+
17764
+ if (!css || typeof document === 'undefined') { return; }
17765
+
17766
+ var head = document.head || document.getElementsByTagName('head')[0];
17767
+ var style = document.createElement('style');
17768
+ style.type = 'text/css';
17769
+
17770
+ if (insertAt === 'top') {
17771
+ if (head.firstChild) {
17772
+ head.insertBefore(style, head.firstChild);
17773
+ } else {
17774
+ head.appendChild(style);
17775
+ }
17776
+ } else {
17777
+ head.appendChild(style);
17778
+ }
17779
+
17780
+ if (style.styleSheet) {
17781
+ style.styleSheet.cssText = css;
17782
+ } else {
17783
+ style.appendChild(document.createTextNode(css));
17784
+ }
17785
+ }
17786
+
17787
+ var css_248z$1 = ".ai-chat-action-card{background:linear-gradient(135deg,#fff,#f9fafb);border:1px solid #e5e7eb;border-radius:12px;box-shadow:0 2px 8px rgba(0,0,0,.06);margin-top:12px;padding:20px;transition:all .2s ease}.ai-chat-action-card:hover{box-shadow:0 4px 12px rgba(0,0,0,.1)}.ai-chat-action-booked{background:linear-gradient(135deg,#ecfdf5,#d1fae5);border-color:#10b981}.ai-chat-action-header{align-items:center;color:#111827;display:flex;font-size:16px;font-weight:600;gap:8px;margin-bottom:16px}.ai-chat-action-icon{color:#6366f1;height:20px;width:20px}.ai-chat-action-icon-success{color:#10b981;height:24px;width:24px}.ai-chat-action-body{display:flex;flex-direction:column;gap:16px}.ai-chat-action-field{display:flex;flex-direction:column;gap:8px}.ai-chat-action-label{color:#374151;font-size:13px;font-weight:500}.ai-chat-action-input{background:#fff;border:1px solid #d1d5db;border-radius:8px;font-size:14px;padding:10px 12px;transition:all .2s ease}.ai-chat-action-input:focus{border-color:#6366f1;box-shadow:0 0 0 3px rgba(99,102,241,.1);outline:none}.ai-chat-action-date-grid{display:grid;gap:8px;grid-template-columns:repeat(auto-fill,minmax(110px,1fr))}.ai-chat-action-date-btn{background:#fff;border:1px solid #d1d5db;border-radius:8px;color:#374151;cursor:pointer;font-size:13px;font-weight:500;padding:10px 8px;transition:all .2s ease}.ai-chat-action-date-btn:hover{background:#f3f4f6;border-color:#9ca3af}.ai-chat-action-date-btn.active{background:#6366f1;border-color:#6366f1;color:#fff}.ai-chat-action-time-grid{display:grid;gap:8px;grid-template-columns:repeat(auto-fill,minmax(100px,1fr))}.ai-chat-action-time-btn{background:#fff;border:1px solid #d1d5db;border-radius:8px;color:#374151;cursor:pointer;font-size:13px;font-weight:500;padding:10px 8px;transition:all .2s ease}.ai-chat-action-time-btn:hover{background:#f3f4f6;border-color:#9ca3af}.ai-chat-action-time-btn.active{background:#6366f1;border-color:#6366f1;color:#fff}.ai-chat-action-button{background:linear-gradient(135deg,#6366f1,#4f46e5);border:none;border-radius:8px;box-shadow:0 2px 4px rgba(99,102,241,.2);color:#fff;cursor:pointer;font-size:14px;font-weight:600;padding:12px 20px;transition:all .2s ease}.ai-chat-action-button:hover:not(:disabled){background:linear-gradient(135deg,#4f46e5,#4338ca);box-shadow:0 4px 8px rgba(99,102,241,.3);transform:translateY(-1px)}.ai-chat-action-button:disabled{cursor:not-allowed;opacity:.5;transform:none}.ai-chat-action-error{background:#fef2f2;border:1px solid #fecaca;border-radius:8px;color:#dc2626;font-size:13px;font-weight:500;padding:10px 12px}.ai-chat-action-hint{color:#6b7280;font-size:12px;font-style:italic}.ai-chat-action-detail{background:#fff;border:1px solid #e5e7eb;border-radius:8px;display:flex;flex-direction:column;gap:4px;padding:12px}.ai-chat-action-detail .ai-chat-action-label{color:#6b7280;font-size:12px;letter-spacing:.5px;text-transform:uppercase}.ai-chat-action-detail .ai-chat-action-value{color:#111827;font-size:14px;font-weight:600}.ai-chat-action-link{align-items:center;background:#fff;border:1px solid #10b981;border-radius:8px;color:#10b981;display:inline-flex;font-size:14px;font-weight:600;gap:4px;padding:10px 16px;text-decoration:none;transition:all .2s ease}.ai-chat-action-link:hover{background:#10b981;color:#fff;transform:translateX(2px)}";
17788
+ styleInject(css_248z$1);
17789
+
17790
+ actionRenderers["google-calendar-appointment"] = (message) => (jsxRuntimeExports.jsx(GoogleCalendarAppointmentCard, { message: message }));
17791
+
17717
17792
  /**
17718
17793
  * Local Storage Utilities
17719
17794
  * Handles conversation persistence in browser localStorage
@@ -17775,9 +17850,12 @@
17775
17850
  * Get preview text from messages
17776
17851
  */
17777
17852
  function getConversationPreview(messages) {
17778
- const firstUserMessage = messages.find(m => m.message.type === 'human');
17853
+ const firstUserMessage = messages.find(m => m.message.role === "user");
17779
17854
  if (firstUserMessage) {
17780
- return firstUserMessage.message.content.slice(0, 100);
17855
+ const content = typeof firstUserMessage.message.content === "string"
17856
+ ? firstUserMessage.message.content
17857
+ : "";
17858
+ return content.slice(0, 100);
17781
17859
  }
17782
17860
  return 'New conversation';
17783
17861
  }
@@ -17932,6 +18010,473 @@
17932
18010
  * useChat Hook
17933
18011
  * Main state management for chat functionality
17934
18012
  */
18013
+ function hydrateToolNames(messages) {
18014
+ const toolCallNameById = new Map();
18015
+ for (const entry of messages) {
18016
+ if (entry.message.role !== "assistant") {
18017
+ continue;
18018
+ }
18019
+ const toolCalls = entry.message.tool_calls;
18020
+ if (!Array.isArray(toolCalls)) {
18021
+ continue;
18022
+ }
18023
+ for (const call of toolCalls) {
18024
+ const callId = call?.id;
18025
+ const callName = call?.function?.name;
18026
+ if (callId && callName) {
18027
+ toolCallNameById.set(callId, callName);
18028
+ }
18029
+ }
18030
+ }
18031
+ if (toolCallNameById.size === 0) {
18032
+ return messages;
18033
+ }
18034
+ return messages.map((entry) => {
18035
+ if (entry.message.role !== "tool") {
18036
+ return entry;
18037
+ }
18038
+ const toolCallId = entry.message.tool_call_id;
18039
+ const resolvedName = toolCallNameById.get(toolCallId);
18040
+ if (!resolvedName) {
18041
+ return entry;
18042
+ }
18043
+ const currentName = entry.message.name;
18044
+ const nextName = currentName && currentName.trim().length > 0 ? currentName : resolvedName;
18045
+ const nextToolExecuting = entry.toolExecuting || resolvedName;
18046
+ if (nextName === currentName && nextToolExecuting === entry.toolExecuting) {
18047
+ return entry;
18048
+ }
18049
+ return {
18050
+ ...entry,
18051
+ message: { ...entry.message, name: nextName },
18052
+ toolExecuting: nextToolExecuting,
18053
+ };
18054
+ });
18055
+ }
18056
+ function hydrateActionContent(messages) {
18057
+ return messages.map((entry) => {
18058
+ if (entry.message.role !== "assistant" || !entry.action) {
18059
+ return entry;
18060
+ }
18061
+ const content = typeof entry.message.content === "string" ? entry.message.content : "";
18062
+ if (content.trim().length > 0) {
18063
+ return entry;
18064
+ }
18065
+ return {
18066
+ ...entry,
18067
+ message: { ...entry.message, content: getActionPrompt(entry.action.implementation) },
18068
+ };
18069
+ });
18070
+ }
18071
+ function hydrateMessages(messages) {
18072
+ return hydrateActionContent(hydrateToolNames(messages));
18073
+ }
18074
+ function setupActionResumeCallbacks(messages, client, conversationId, setState, onMessageUpdate) {
18075
+ // Find all incomplete actions and register resume callbacks
18076
+ for (const message of messages) {
18077
+ if (message.action && !message.action.done) {
18078
+ const toolCallId = message.action.toolCallId;
18079
+ const toolName = message.message.name || message.toolExecuting || "tool";
18080
+ registerActionResumeCallback(toolCallId, async (newState) => {
18081
+ // When user interacts with the action after reload, continue the stream
18082
+ try {
18083
+ // Update the action message with the new state
18084
+ setState(prev => ({
18085
+ ...prev,
18086
+ messages: prev.messages.map(m => m.action?.toolCallId === toolCallId
18087
+ ? {
18088
+ ...m,
18089
+ action: m.action ? { ...m.action, state: newState } : undefined,
18090
+ }
18091
+ : m),
18092
+ isTyping: true,
18093
+ }));
18094
+ const streamState = createStreamState();
18095
+ // Continue the agent stream with the new state
18096
+ for await (const event of client.continueAgentMessageStream(conversationId, toolCallId, newState)) {
18097
+ if (event.type === "done") {
18098
+ finalizeToolMessage(streamState, setState, toolCallId, toolName);
18099
+ streamState.sources = event.sources;
18100
+ streamState.toolCallToActionId = event.tool_call_to_action_id;
18101
+ finalizeStreamMessages(setState, streamState.newMessageIds, event.sources, event.tool_call_to_action_id);
18102
+ continue;
18103
+ }
18104
+ if (event.type === "error") {
18105
+ const errorMessage = {
18106
+ id: generateMessageId(),
18107
+ message: {
18108
+ role: "assistant",
18109
+ content: `Error: ${event.error}`,
18110
+ },
18111
+ timestamp: new Date().toISOString(),
18112
+ sources: [],
18113
+ isError: true,
18114
+ };
18115
+ upsertMessage(setState, errorMessage, false);
18116
+ setState(prev => ({ ...prev, isTyping: false }));
18117
+ return;
18118
+ }
18119
+ handleStreamEvent(event, streamState, onMessageUpdate, setState);
18120
+ }
18121
+ setState(prev => ({ ...prev, isTyping: false }));
18122
+ }
18123
+ catch (error) {
18124
+ console.error("[Action Resume] Failed to continue stream:", error);
18125
+ setState(prev => ({ ...prev, isTyping: false, error: error instanceof Error ? error.message : "Failed to resume action" }));
18126
+ throw error;
18127
+ }
18128
+ });
18129
+ }
18130
+ }
18131
+ }
18132
+ function createStreamState() {
18133
+ return {
18134
+ currentContent: "",
18135
+ currentMessageId: generateMessageId(),
18136
+ activeToolCallCount: 0,
18137
+ newMessageIds: new Set(),
18138
+ sources: [],
18139
+ toolCallToActionId: {},
18140
+ };
18141
+ }
18142
+ function upsertMessage(setState, message, isTyping) {
18143
+ setState(prev => {
18144
+ const existingIndex = prev.messages.findIndex(m => m.id === message.id);
18145
+ if (existingIndex >= 0) {
18146
+ const newMessages = [...prev.messages];
18147
+ newMessages[existingIndex] = message;
18148
+ return { ...prev, messages: newMessages, isTyping, isLoading: false };
18149
+ }
18150
+ return {
18151
+ ...prev,
18152
+ messages: [...prev.messages, message],
18153
+ isTyping,
18154
+ isLoading: false,
18155
+ };
18156
+ });
18157
+ }
18158
+ function finalizeStreamMessages(setState, messageIds, sources, toolCallToActionId) {
18159
+ setState(prev => ({
18160
+ ...prev,
18161
+ messages: prev.messages.map(msg => (messageIds.has(msg.id)
18162
+ ? { ...msg, sources, toolCallToActionId }
18163
+ : msg)),
18164
+ isTyping: false,
18165
+ }));
18166
+ }
18167
+ function handleContentEvent(event, streamState, onMessageUpdate, setState) {
18168
+ streamState.currentContent += event.content;
18169
+ const assistantMessage = {
18170
+ id: streamState.currentMessageId,
18171
+ message: { role: "assistant", content: streamState.currentContent },
18172
+ timestamp: new Date().toISOString(),
18173
+ sources: streamState.sources,
18174
+ isStreaming: true,
18175
+ };
18176
+ streamState.newMessageIds.add(assistantMessage.id);
18177
+ onMessageUpdate(assistantMessage);
18178
+ const hasContent = assistantMessage.message.content?.trim().length || 0 > 0;
18179
+ const isToolExecuting = streamState.activeToolCallCount > 0;
18180
+ const isTyping = (!hasContent && assistantMessage.isStreaming) || isToolExecuting;
18181
+ upsertMessage(setState, assistantMessage, isTyping);
18182
+ }
18183
+ function handleToolStartEvent(event, streamState, onMessageUpdate, setState) {
18184
+ if (streamState.currentContent.trim()) {
18185
+ const finalAssistant = {
18186
+ id: streamState.currentMessageId,
18187
+ message: { role: "assistant", content: streamState.currentContent },
18188
+ timestamp: new Date().toISOString(),
18189
+ sources: streamState.sources,
18190
+ isStreaming: false,
18191
+ };
18192
+ streamState.newMessageIds.add(finalAssistant.id);
18193
+ onMessageUpdate(finalAssistant);
18194
+ upsertMessage(setState, finalAssistant, true);
18195
+ streamState.currentContent = "";
18196
+ streamState.currentMessageId = generateMessageId();
18197
+ }
18198
+ const toolMessageId = event.tool_call_id;
18199
+ streamState.activeToolCallCount += 1;
18200
+ streamState.newMessageIds.add(toolMessageId);
18201
+ const toolMessage = {
18202
+ id: toolMessageId,
18203
+ sources: [],
18204
+ message: { role: "tool", content: "", tool_call_id: event.tool_call_id, name: event.tool_name },
18205
+ timestamp: new Date().toISOString(),
18206
+ isStreaming: true,
18207
+ toolExecuting: event.tool_name,
18208
+ };
18209
+ upsertMessage(setState, toolMessage, true);
18210
+ }
18211
+ function handleToolEndEvent(event, streamState, _onMessageUpdate, setState) {
18212
+ // Update state and mark action as done in a single setState call
18213
+ setState(prev => {
18214
+ const messages = prev.messages.map((msg) => {
18215
+ const matchesToolCall = msg.message.role === "tool" && msg.message.tool_call_id === event.tool_call_id;
18216
+ if (!matchesToolCall) {
18217
+ return msg;
18218
+ }
18219
+ const existingName = msg.message.name || event.tool_name;
18220
+ return {
18221
+ ...msg,
18222
+ message: {
18223
+ role: "tool",
18224
+ content: event.state ? JSON.stringify(event.state) : (typeof msg.message.content === "string" ? msg.message.content : ""),
18225
+ tool_call_id: event.tool_call_id,
18226
+ name: existingName,
18227
+ },
18228
+ isStreaming: false,
18229
+ toolExecuting: existingName,
18230
+ action: msg.action ? {
18231
+ ...msg.action,
18232
+ state: event.state || msg.action.state,
18233
+ done: true, // Mark action as completed
18234
+ } : undefined,
18235
+ };
18236
+ });
18237
+ return { ...prev, messages, isTyping: false, isLoading: false };
18238
+ });
18239
+ streamState.activeToolCallCount = Math.max(0, streamState.activeToolCallCount - 1);
18240
+ }
18241
+ function handleToolErrorEvent(event, streamState, _onMessageUpdate, setState) {
18242
+ setState(prev => {
18243
+ const messages = prev.messages.map((entry) => {
18244
+ const matchesToolCall = entry.message.role === "tool" && entry.message.tool_call_id === event.tool_call_id;
18245
+ if (!matchesToolCall) {
18246
+ return entry;
18247
+ }
18248
+ const name = entry.message.name || "tool";
18249
+ const toolMessage = {
18250
+ ...entry,
18251
+ message: {
18252
+ role: "tool",
18253
+ content: event.error || "Tool execution failed",
18254
+ tool_call_id: event.tool_call_id,
18255
+ name,
18256
+ },
18257
+ timestamp: new Date().toISOString(),
18258
+ isStreaming: false,
18259
+ isError: true,
18260
+ toolExecuting: name,
18261
+ };
18262
+ return toolMessage;
18263
+ });
18264
+ return { ...prev, messages, isTyping: false, isLoading: false };
18265
+ });
18266
+ streamState.activeToolCallCount = Math.max(0, streamState.activeToolCallCount - 1);
18267
+ }
18268
+ function finalizeToolMessage(streamState, setState, toolCallId, toolName) {
18269
+ setState(prev => {
18270
+ const messages = prev.messages.map((entry) => {
18271
+ const matchesToolCall = entry.message.role === "tool" && entry.message.tool_call_id === toolCallId;
18272
+ if (!matchesToolCall) {
18273
+ return entry;
18274
+ }
18275
+ const existingName = entry.message.name || toolName;
18276
+ return {
18277
+ ...entry,
18278
+ message: {
18279
+ role: "tool",
18280
+ content: typeof entry.message.content === "string" ? entry.message.content : "",
18281
+ tool_call_id: toolCallId,
18282
+ name: existingName,
18283
+ },
18284
+ isStreaming: false,
18285
+ toolExecuting: existingName,
18286
+ action: entry.action ? {
18287
+ ...entry.action,
18288
+ done: true, // Mark action as completed
18289
+ } : undefined,
18290
+ };
18291
+ });
18292
+ return { ...prev, messages, isTyping: false, isLoading: false };
18293
+ });
18294
+ streamState.activeToolCallCount = Math.max(0, streamState.activeToolCallCount - 1);
18295
+ }
18296
+ function handleDoneEvent(event, streamState, _onMessageUpdate, setState) {
18297
+ streamState.sources = event.sources;
18298
+ streamState.toolCallToActionId = event.tool_call_to_action_id;
18299
+ finalizeStreamMessages(setState, streamState.newMessageIds, event.sources, event.tool_call_to_action_id);
18300
+ }
18301
+ function handleHaltEvent(event, _streamState, onMessageUpdate, setState) {
18302
+ const toolNames = event.tool_calls.map(call => call.name).join(", ");
18303
+ const notice = toolNames
18304
+ ? `Awaiting external tool results: ${toolNames}.`
18305
+ : "Awaiting external tool results.";
18306
+ const haltMessage = {
18307
+ id: generateMessageId(),
18308
+ message: { role: "assistant", content: notice },
18309
+ timestamp: new Date().toISOString(),
18310
+ sources: [],
18311
+ isError: true,
18312
+ };
18313
+ onMessageUpdate(haltMessage);
18314
+ upsertMessage(setState, haltMessage, false);
18315
+ setState(prev => ({ ...prev, error: "Awaiting external tool handling." }));
18316
+ }
18317
+ function handleErrorEvent(event, _streamState, onMessageUpdate, setState) {
18318
+ const errorMessage = {
18319
+ id: generateMessageId(),
18320
+ message: { role: "assistant", content: `⚠️ ${event.error}` },
18321
+ timestamp: new Date().toISOString(),
18322
+ sources: [],
18323
+ isError: true,
18324
+ };
18325
+ onMessageUpdate(errorMessage);
18326
+ upsertMessage(setState, errorMessage, false);
18327
+ setState(prev => ({ ...prev, error: event.error }));
18328
+ }
18329
+ const eventHandlers = {
18330
+ content: handleContentEvent,
18331
+ tool_start: handleToolStartEvent,
18332
+ tool_end: handleToolEndEvent,
18333
+ tool_error: handleToolErrorEvent,
18334
+ done: handleDoneEvent,
18335
+ halt: handleHaltEvent,
18336
+ error: handleErrorEvent,
18337
+ action_request: () => { },
18338
+ };
18339
+ function handleStreamEvent(event, streamState, onMessageUpdate, setState) {
18340
+ if (event.type === "tool_start" || event.type === "tool_end" || event.type === "tool_error" || event.type === "action_request" || event.type === "done" || event.type === "halt") {
18341
+ console.log("[Widget] stream event:", {
18342
+ type: event.type,
18343
+ toolCallId: "tool_call_id" in event ? event.tool_call_id : undefined,
18344
+ toolName: "tool_name" in event ? event.tool_name : undefined,
18345
+ });
18346
+ }
18347
+ const handler = eventHandlers[event.type];
18348
+ if (handler) {
18349
+ handler(event, streamState, onMessageUpdate, setState);
18350
+ }
18351
+ else {
18352
+ console.warn('[Chat] Unknown event type:', event.type);
18353
+ }
18354
+ }
18355
+ async function handleActionLoop(client, initialEvent, streamState, onMessageUpdate, setState, widgetId, conversationId, getMessages) {
18356
+ let pendingEvent = initialEvent;
18357
+ while (pendingEvent) {
18358
+ streamState.toolCallToActionId = pendingEvent.tool_call_to_action_id;
18359
+ const resumeToolCallId = pendingEvent.tool_call_id;
18360
+ const existingToolMessage = getMessages().find((entry) => entry.message.role === "tool" && entry.message.tool_call_id === resumeToolCallId);
18361
+ const toolMessageId = existingToolMessage?.id ?? resumeToolCallId;
18362
+ const toolName = existingToolMessage?.message.name ?? "tool";
18363
+ const toolMessage = {
18364
+ id: toolMessageId,
18365
+ sources: [],
18366
+ message: {
18367
+ role: "tool",
18368
+ content: "",
18369
+ tool_call_id: resumeToolCallId,
18370
+ name: toolName,
18371
+ },
18372
+ timestamp: new Date().toISOString(),
18373
+ isStreaming: true,
18374
+ toolExecuting: toolName,
18375
+ action: {
18376
+ implementation: pendingEvent.implementation,
18377
+ toolCallId: pendingEvent.tool_call_id,
18378
+ actionId: pendingEvent.action_id,
18379
+ input: pendingEvent.input,
18380
+ state: pendingEvent.state,
18381
+ done: false, // Action not yet completed
18382
+ },
18383
+ };
18384
+ if (streamState.activeToolCallCount === 0) {
18385
+ streamState.activeToolCallCount = 1;
18386
+ }
18387
+ onMessageUpdate(toolMessage);
18388
+ upsertMessage(setState, toolMessage, true);
18389
+ const handler = getFrontendActionHandler(pendingEvent.implementation);
18390
+ if (!handler) {
18391
+ const errorMessage = {
18392
+ id: generateMessageId(),
18393
+ message: {
18394
+ role: "assistant",
18395
+ content: `⚠️ No frontend handler for action '${pendingEvent.implementation}'.`,
18396
+ },
18397
+ timestamp: new Date().toISOString(),
18398
+ sources: [],
18399
+ isError: true,
18400
+ };
18401
+ onMessageUpdate(errorMessage);
18402
+ upsertMessage(setState, errorMessage, false);
18403
+ setState(prev => ({ ...prev, error: `Missing frontend handler: ${pendingEvent?.implementation}` }));
18404
+ return;
18405
+ }
18406
+ let nextState;
18407
+ try {
18408
+ nextState = await handler(pendingEvent.input, pendingEvent.state, {
18409
+ widgetId,
18410
+ conversationId,
18411
+ toolCallId: pendingEvent.tool_call_id,
18412
+ actionId: pendingEvent.action_id,
18413
+ implementation: pendingEvent.implementation,
18414
+ });
18415
+ }
18416
+ catch (error) {
18417
+ const errorMessage = error instanceof Error ? error.message : "Frontend action failed.";
18418
+ const errorMessageEntry = {
18419
+ id: generateMessageId(),
18420
+ message: { role: "assistant", content: `⚠️ ${errorMessage}` },
18421
+ timestamp: new Date().toISOString(),
18422
+ sources: [],
18423
+ isError: true,
18424
+ };
18425
+ onMessageUpdate(errorMessageEntry);
18426
+ upsertMessage(setState, errorMessageEntry, false);
18427
+ setState(prev => ({ ...prev, error: errorMessage }));
18428
+ return;
18429
+ }
18430
+ pendingEvent = null;
18431
+ const updatedToolMessage = {
18432
+ ...toolMessage,
18433
+ action: toolMessage.action
18434
+ ? {
18435
+ ...toolMessage.action,
18436
+ state: nextState,
18437
+ }
18438
+ : undefined,
18439
+ };
18440
+ upsertMessage(setState, updatedToolMessage, true);
18441
+ let streamEnded = false;
18442
+ for await (const event of client.continueAgentMessageStream(conversationId, resumeToolCallId, nextState)) {
18443
+ if (event.type === "action_request") {
18444
+ pendingEvent = event;
18445
+ break;
18446
+ }
18447
+ if (event.type === "done") {
18448
+ // Don't extract and update state from done event - the state was already
18449
+ // updated by tool_end event or by the user's frontend action.
18450
+ finalizeToolMessage(streamState, setState, resumeToolCallId, toolName);
18451
+ // Handle the done event but skip the tool finalization part since we already did it
18452
+ streamState.sources = event.sources;
18453
+ streamState.toolCallToActionId = event.tool_call_to_action_id;
18454
+ finalizeStreamMessages(setState, streamState.newMessageIds, event.sources, event.tool_call_to_action_id);
18455
+ streamEnded = true;
18456
+ continue; // Skip handleStreamEvent for done events to avoid state conflicts
18457
+ }
18458
+ if (event.type === "error") {
18459
+ const errorMessage = {
18460
+ id: generateMessageId(),
18461
+ message: {
18462
+ role: "assistant",
18463
+ content: `Error occurred during action execution: ${event.error}`,
18464
+ },
18465
+ timestamp: new Date().toISOString(),
18466
+ sources: [],
18467
+ isError: true,
18468
+ };
18469
+ upsertMessage(setState, errorMessage, false);
18470
+ return;
18471
+ }
18472
+ handleStreamEvent(event, streamState, onMessageUpdate, setState);
18473
+ }
18474
+ // If stream ended without a done event (e.g., only tool_end was sent), finalize the tool message
18475
+ if (!streamEnded && !pendingEvent) {
18476
+ finalizeToolMessage(streamState, setState, resumeToolCallId, toolName);
18477
+ }
18478
+ }
18479
+ }
17935
18480
  function deriveErrorInfo(error) {
17936
18481
  if (error instanceof ApiError) {
17937
18482
  const retryAfterSeconds = typeof error.retryAfterMs === 'number'
@@ -18004,6 +18549,10 @@
18004
18549
  conversationId: '', // Will be set after loading conversation
18005
18550
  config: null,
18006
18551
  });
18552
+ const stateRef = reactExports.useRef(state);
18553
+ reactExports.useEffect(() => {
18554
+ stateRef.current = state;
18555
+ }, [state]);
18007
18556
  // Chat history state
18008
18557
  const [conversations, setConversations] = reactExports.useState([]);
18009
18558
  const apiClient = reactExports.useRef(new WidgetApiClient({ widgetId, apiUrl }));
@@ -18011,18 +18560,12 @@
18011
18560
  reactExports.useEffect(() => {
18012
18561
  // Skip initialization in preview mode
18013
18562
  if (skipInitialization) {
18014
- console.log('[useChat] Skipping initialization (preview mode)');
18015
18563
  return;
18016
18564
  }
18017
18565
  let isMounted = true;
18018
- console.log('[useChat] Effect running, mounting component');
18019
18566
  const initialize = async () => {
18020
18567
  try {
18021
- console.log('[useChat] Fetching config...');
18022
18568
  const config = await apiClient.current.getConfig();
18023
- console.log('[useChat] Config fetched successfully:', {
18024
- hasAppearance: !!config.appearance,
18025
- });
18026
18569
  const persistConversation = config.settings.persistConversation ?? true;
18027
18570
  let conversationId = '';
18028
18571
  let messages = [];
@@ -18033,7 +18576,7 @@
18033
18576
  try {
18034
18577
  const conversation = await apiClient.current.getOrCreateConversation(storedId);
18035
18578
  conversationId = conversation.id;
18036
- messages = conversation.messages;
18579
+ messages = hydrateMessages(conversation.messages);
18037
18580
  }
18038
18581
  catch (conversationError) {
18039
18582
  console.warn('Failed to load existing conversation:', conversationError);
@@ -18041,16 +18584,19 @@
18041
18584
  }
18042
18585
  }
18043
18586
  if (!isMounted) {
18044
- console.log('[useChat] Component unmounted, skipping state update');
18045
18587
  return;
18046
18588
  }
18047
- console.log('[useChat] Setting config in state');
18589
+ const hydratedMessages = hydrateMessages(messages);
18048
18590
  setState(prev => ({
18049
18591
  ...prev,
18050
18592
  config,
18051
18593
  conversationId,
18052
- messages,
18594
+ messages: hydratedMessages,
18053
18595
  }));
18596
+ // Setup resume callbacks for incomplete actions
18597
+ if (conversationId) {
18598
+ setupActionResumeCallbacks(hydratedMessages, apiClient.current, conversationId, setState, onMessage ?? (() => { }));
18599
+ }
18054
18600
  }
18055
18601
  catch (error) {
18056
18602
  console.error('[useChat] Error fetching config:', error);
@@ -18065,8 +18611,13 @@
18065
18611
  };
18066
18612
  initialize();
18067
18613
  return () => {
18068
- console.log('[useChat] Effect cleanup, unmounting component');
18069
18614
  isMounted = false;
18615
+ // Cleanup resume callbacks
18616
+ state.messages.forEach(message => {
18617
+ if (message.action?.toolCallId) {
18618
+ unregisterActionResumeCallback(message.action.toolCallId);
18619
+ }
18620
+ });
18070
18621
  };
18071
18622
  }, [widgetId, apiUrl, onError]);
18072
18623
  // Save conversation when messages change
@@ -18079,9 +18630,6 @@
18079
18630
  saveConversation(widgetId, state.conversationId, state.messages);
18080
18631
  }
18081
18632
  }, [widgetId, state.messages, state.conversationId, state.config?.settings.persistConversation]);
18082
- /**
18083
- * Send a message
18084
- */
18085
18633
  const sendMessage = reactExports.useCallback(async (content, files) => {
18086
18634
  const trimmedContent = content.trim();
18087
18635
  const hasFiles = !!files && files.length > 0;
@@ -18090,7 +18638,7 @@
18090
18638
  const userMessage = {
18091
18639
  id: generateMessageId(),
18092
18640
  message: {
18093
- type: 'human',
18641
+ role: "user",
18094
18642
  content: trimmedContent,
18095
18643
  },
18096
18644
  timestamp: new Date().toISOString(),
@@ -18111,7 +18659,7 @@
18111
18659
  const conversation = await apiClient.current.getOrCreateConversation();
18112
18660
  conversationId = conversation.id;
18113
18661
  setState(prev => {
18114
- const serverMessages = conversation.messages ?? [];
18662
+ const serverMessages = hydrateMessages(conversation.messages ?? []);
18115
18663
  if (serverMessages.length === 0) {
18116
18664
  return {
18117
18665
  ...prev,
@@ -18145,48 +18693,20 @@
18145
18693
  }
18146
18694
  }
18147
18695
  }
18148
- // Determine if widget has actions (use agent endpoint)
18149
- const useAgent = state.config?.behavior.agentic || (state.config?.actions && state.config.actions.length > 0);
18150
18696
  // Stream the response
18151
18697
  let lastStreamedMessage = null;
18152
- const stream = useAgent
18153
- ? apiClient.current.sendAgentMessageStream(conversationId, trimmedContent, fileIds)
18154
- : apiClient.current.sendMessageStream(conversationId, trimmedContent, fileIds);
18155
- for await (const message of stream) {
18156
- lastStreamedMessage = message;
18157
- // Update state with streamed message
18158
- setState(prev => {
18159
- const existingIndex = prev.messages.findIndex(m => m.id === message.id);
18160
- if (existingIndex >= 0) {
18161
- // Update existing streaming message
18162
- const newMessages = [...prev.messages];
18163
- newMessages[existingIndex] = message;
18164
- // Show typing indicator if:
18165
- // 1. Message is streaming AND has no content (waiting for first token or after tool call)
18166
- // 2. Message is a tool execution (shows loading spinner on the tool)
18167
- const isAIMessage = message.message.type === 'ai';
18168
- const hasContent = isAIMessage && message.message.content.trim().length > 0;
18169
- const isToolExecuting = message.toolExecuting !== undefined;
18170
- return {
18171
- ...prev,
18172
- messages: newMessages,
18173
- isTyping: (message.isStreaming && !hasContent && isAIMessage) || isToolExecuting,
18174
- isLoading: false,
18175
- };
18176
- }
18177
- else {
18178
- // Add new streaming message
18179
- const isAIMessage = message.message.type === 'ai';
18180
- const hasContent = isAIMessage && message.message.content.trim().length > 0;
18181
- const isToolExecuting = message.toolExecuting !== undefined;
18182
- return {
18183
- ...prev,
18184
- messages: [...prev.messages, message],
18185
- isTyping: (message.isStreaming && !hasContent && isAIMessage) || isToolExecuting,
18186
- isLoading: false,
18187
- };
18188
- }
18189
- });
18698
+ const streamState = createStreamState();
18699
+ const stream = apiClient.current.sendAgentMessageStream(conversationId, trimmedContent, fileIds);
18700
+ for await (const event of stream) {
18701
+ if (event.type === "action_request") {
18702
+ await handleActionLoop(apiClient.current, event, streamState, (message) => {
18703
+ lastStreamedMessage = message;
18704
+ }, setState, widgetId, conversationId, () => stateRef.current.messages);
18705
+ break;
18706
+ }
18707
+ handleStreamEvent(event, streamState, (message) => {
18708
+ lastStreamedMessage = message;
18709
+ }, setState);
18190
18710
  }
18191
18711
  // Stream completed - finalize state
18192
18712
  setState(prev => ({
@@ -18207,7 +18727,7 @@
18207
18727
  const fallbackAssistantMessage = {
18208
18728
  id: generateMessageId(),
18209
18729
  message: {
18210
- type: 'ai',
18730
+ role: "assistant",
18211
18731
  content: fallbackMessage,
18212
18732
  },
18213
18733
  timestamp: new Date().toISOString(),
@@ -18226,7 +18746,7 @@
18226
18746
  const errorAssistantMessage = {
18227
18747
  id: generateMessageId(),
18228
18748
  message: {
18229
- type: 'ai',
18749
+ role: "assistant",
18230
18750
  content: `⚠️ ${errorInfo.message}`,
18231
18751
  },
18232
18752
  timestamp: new Date().toISOString(),
@@ -18264,8 +18784,13 @@
18264
18784
  */
18265
18785
  const submitFeedback = reactExports.useCallback(async (messageId, feedback) => {
18266
18786
  try {
18787
+ const message = state.messages.find(msg => msg.id === messageId);
18788
+ const messageContent = typeof message?.message.content === "string" ? message.message.content : undefined;
18789
+ const meta = message
18790
+ ? { role: message.message.role, content: messageContent, timestamp: message.timestamp }
18791
+ : undefined;
18267
18792
  console.log('Submitting feedback:', { conversationId: state.conversationId, messageId, feedback });
18268
- await apiClient.current.submitFeedback(state.conversationId, messageId, feedback);
18793
+ await apiClient.current.submitFeedback(state.conversationId, messageId, feedback, meta);
18269
18794
  // Update message with feedback
18270
18795
  setState(prev => ({
18271
18796
  ...prev,
@@ -18299,9 +18824,6 @@
18299
18824
  startedAt: entry.lastUpdated,
18300
18825
  })));
18301
18826
  }, [widgetId, state.config?.settings.persistConversation]);
18302
- /**
18303
- * Switch to a different conversation (from localStorage first, then fetch from server if needed)
18304
- */
18305
18827
  const switchConversation = reactExports.useCallback(async (conversationId) => {
18306
18828
  const persistConversation = state.config?.settings.persistConversation ?? true;
18307
18829
  // First try to load from localStorage
@@ -18311,25 +18833,33 @@
18311
18833
  setState(prev => ({
18312
18834
  ...prev,
18313
18835
  conversationId: stored.conversationId,
18314
- messages: stored.messages,
18836
+ messages: hydrateMessages(stored.messages),
18315
18837
  }));
18316
18838
  setActiveConversation(widgetId, conversationId);
18317
18839
  return;
18318
18840
  }
18319
18841
  }
18320
- // If not in localStorage, fetch from server
18321
18842
  setState(prev => ({ ...prev, isLoading: true, error: null }));
18322
18843
  try {
18323
18844
  const conversation = await apiClient.current.getOrCreateConversation(conversationId);
18845
+ const hydratedMessages = hydrateMessages(conversation.messages);
18846
+ // Clear old resume callbacks
18847
+ state.messages.forEach(message => {
18848
+ if (message.action?.toolCallId) {
18849
+ unregisterActionResumeCallback(message.action.toolCallId);
18850
+ }
18851
+ });
18324
18852
  setState(prev => ({
18325
18853
  ...prev,
18326
18854
  conversationId: conversation.id,
18327
- messages: conversation.messages,
18855
+ messages: hydratedMessages,
18328
18856
  isLoading: false,
18329
18857
  }));
18858
+ // Setup new resume callbacks
18859
+ setupActionResumeCallbacks(hydratedMessages, apiClient.current, conversation.id, setState, onMessage ?? (() => { }));
18330
18860
  // Save to local storage
18331
18861
  if (persistConversation && isStorageAvailable()) {
18332
- saveConversation(widgetId, conversation.id, conversation.messages);
18862
+ saveConversation(widgetId, conversation.id, hydratedMessages);
18333
18863
  }
18334
18864
  }
18335
18865
  catch (error) {
@@ -18337,9 +18867,6 @@
18337
18867
  setState(prev => ({ ...prev, isLoading: false, error: errorInfo.message }));
18338
18868
  }
18339
18869
  }, [widgetId, state.config?.settings.persistConversation]);
18340
- /**
18341
- * Start a new conversation (keeps history)
18342
- */
18343
18870
  const startNewConversation = reactExports.useCallback(() => {
18344
18871
  setState(prev => ({
18345
18872
  ...prev,
@@ -18347,15 +18874,11 @@
18347
18874
  conversationId: '',
18348
18875
  error: null,
18349
18876
  }));
18350
- // Clear active conversation but keep history
18351
18877
  const persistConversation = state.config?.settings.persistConversation ?? true;
18352
18878
  if (persistConversation && isStorageAvailable()) {
18353
18879
  clearConversation(widgetId);
18354
18880
  }
18355
18881
  }, [widgetId, state.config?.settings.persistConversation]);
18356
- /**
18357
- * Delete a conversation from history
18358
- */
18359
18882
  const deleteConversation$1 = reactExports.useCallback((conversationId) => {
18360
18883
  const persistConversation = state.config?.settings.persistConversation ?? true;
18361
18884
  if (!persistConversation || !isStorageAvailable()) {
@@ -45205,12 +45728,12 @@
45205
45728
  hour12: true,
45206
45729
  });
45207
45730
  };
45208
- const msgType = message.message.type;
45731
+ const role = message.message.role;
45209
45732
  const isError = message.isError || false;
45210
- const isTool = msgType === 'tool';
45211
- const isAssistant = msgType === 'ai';
45212
- const isSystem = msgType === 'system';
45213
- const isHuman = msgType === 'human';
45733
+ const isTool = role === "tool";
45734
+ const isAssistant = role === "assistant";
45735
+ const isSystem = role === "system";
45736
+ const isHuman = role === "user";
45214
45737
  // Tool messages are now handled by ToolMessageGroup in MessageList
45215
45738
  if (isTool) {
45216
45739
  return null;
@@ -45221,7 +45744,10 @@
45221
45744
  const hasContent = aiContent.trim().length > 0;
45222
45745
  if (!hasContent)
45223
45746
  return null;
45224
- 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 })] }), showTimestamp && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-message-meta", children: [jsxRuntimeExports.jsx("span", { className: "ai-chat-message-timestamp", children: formatTime(message.timestamp) }), enableFeedback && onFeedback && (jsxRuntimeExports.jsx(FeedbackButtons, { messageId: message.id, currentFeedback: message.feedback, onFeedback: onFeedback }))] })), showSources && message.sources?.length > 0 && (jsxRuntimeExports.jsx(Sources, { sources: message.sources, displayMode: sourceDisplayMode }))] }));
45747
+ const actionRenderer = message.action
45748
+ ? getActionRenderer(message.action.implementation)
45749
+ : undefined;
45750
+ 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), showTimestamp && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-message-meta", children: [jsxRuntimeExports.jsx("span", { className: "ai-chat-message-timestamp", children: formatTime(message.timestamp) }), enableFeedback && onFeedback && (jsxRuntimeExports.jsx(FeedbackButtons, { messageId: message.id, currentFeedback: message.feedback, onFeedback: onFeedback }))] })), showSources && message.sources?.length > 0 && (jsxRuntimeExports.jsx(Sources, { sources: message.sources, displayMode: sourceDisplayMode }))] }));
45225
45751
  }
45226
45752
  // System message rendering
45227
45753
  if (isSystem) {
@@ -45229,7 +45755,7 @@
45229
45755
  }
45230
45756
  // Human message rendering
45231
45757
  if (isHuman) {
45232
- const userContent = message.message.content.split('--- File Content ---')[0];
45758
+ const userContent = (message.message.content || '').split('--- File Content ---')[0];
45233
45759
  return (jsxRuntimeExports.jsxs("div", { className: "ai-chat-message user", children: [jsxRuntimeExports.jsx("div", { className: "ai-chat-message-content", children: userContent }), showTimestamp && (jsxRuntimeExports.jsx("div", { className: "ai-chat-message-meta", children: jsxRuntimeExports.jsx("span", { className: "ai-chat-message-timestamp", children: formatTime(message.timestamp) }) }))] }));
45234
45760
  }
45235
45761
  return null;
@@ -45246,13 +45772,31 @@
45246
45772
  const CheckIcon = () => (jsxRuntimeExports.jsx("svg", { className: "ai-chat-tool-check", width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntimeExports.jsx("polyline", { points: "20 6 9 17 4 12" }) }));
45247
45773
  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" }) }));
45248
45774
  const ToolMessageGroup = ({ messages }) => {
45249
- const isAnyLoading = messages.some(m => m.isStreaming);
45250
- return (jsxRuntimeExports.jsx("div", { className: "ai-chat-message tool", children: jsxRuntimeExports.jsxs("div", { className: "ai-chat-tool-row", children: [jsxRuntimeExports.jsx(GearIcon, { spinning: isAnyLoading }), jsxRuntimeExports.jsx("div", { className: "ai-chat-tool-badges", children: messages.map((message) => {
45251
- const toolName = message.toolExecuting || message.message.name || 'Tool';
45252
- const hasError = message.isError || false;
45253
- const isLoading = message.isStreaming;
45254
- return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-tool-badge ${isLoading ? 'loading' : hasError ? 'error' : 'completed'}`, children: [!isLoading && (hasError ? jsxRuntimeExports.jsx(ErrorIcon, {}) : jsxRuntimeExports.jsx(CheckIcon, {})), jsxRuntimeExports.jsx("span", { className: "tool-name", children: formatToolName(toolName) })] }, message.id));
45255
- }) })] }) }));
45775
+ // Check if any message is loading (for actions, check done flag; otherwise check isStreaming)
45776
+ const isAnyLoading = messages.some(m => {
45777
+ if (m.action) {
45778
+ return !(m.action.done ?? false);
45779
+ }
45780
+ return m.isStreaming;
45781
+ });
45782
+ const actionMessages = messages.filter(message => message.action);
45783
+ return (jsxRuntimeExports.jsxs("div", { className: "ai-chat-message tool", children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-tool-row", children: [jsxRuntimeExports.jsx(GearIcon, { spinning: isAnyLoading }), jsxRuntimeExports.jsx("div", { className: "ai-chat-tool-badges", children: messages.map((message) => {
45784
+ const toolName = message.toolExecuting || message.message.name || 'Tool';
45785
+ const hasError = message.isError || false;
45786
+ // For actions, check if done flag is set; otherwise fall back to isStreaming
45787
+ const isDone = message.action ? (message.action.done ?? false) : !message.isStreaming;
45788
+ const isLoading = !isDone;
45789
+ return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-tool-badge ${isLoading ? 'loading' : hasError ? 'error' : 'completed'}`, children: [!isLoading && (hasError ? jsxRuntimeExports.jsx(ErrorIcon, {}) : jsxRuntimeExports.jsx(CheckIcon, {})), jsxRuntimeExports.jsx("span", { className: "tool-name", children: formatToolName(toolName) })] }, message.id));
45790
+ }) })] }), actionMessages.map((message) => {
45791
+ if (!message.action) {
45792
+ return null;
45793
+ }
45794
+ const renderer = getActionRenderer(message.action.implementation);
45795
+ if (!renderer) {
45796
+ return null;
45797
+ }
45798
+ return (jsxRuntimeExports.jsx("div", { className: "ai-chat-tool-action", children: renderer(message) }, `action-${message.id}`));
45799
+ })] }));
45256
45800
  };
45257
45801
 
45258
45802
  const TypingIndicator = () => {
@@ -45277,6 +45821,14 @@
45277
45821
  const MessageList = ({ messages, isTyping = false, showTypingIndicator = true, showTimestamps = true, enableFeedback = true, showSources = true, sourceDisplayMode = 'with-score', welcomeTitle, welcomeMessage, suggestedQuestions, onSuggestedQuestionClick, onFeedback, }) => {
45278
45822
  const containerRef = reactExports.useRef(null);
45279
45823
  const messagesEndRef = reactExports.useRef(null);
45824
+ // Check if there's an active action awaiting user input
45825
+ const hasActiveAction = reactExports.useMemo(() => {
45826
+ return messages.some(msg => msg.action &&
45827
+ msg.action.state &&
45828
+ msg.action.state.status !== 'completed' &&
45829
+ msg.action.state.status !== 'booked' &&
45830
+ msg.action.state.status !== 'failed');
45831
+ }, [messages]);
45280
45832
  // Auto-scroll to bottom only on initial mount/load
45281
45833
  reactExports.useEffect(() => {
45282
45834
  const container = containerRef.current;
@@ -45305,16 +45857,16 @@
45305
45857
  }
45306
45858
  };
45307
45859
  for (const message of messages) {
45308
- if (message.message.type === 'tool') {
45860
+ if (message.message.role === "tool") {
45309
45861
  // Add to current tool group
45310
45862
  currentToolGroup.push(message);
45311
45863
  }
45312
- else if (message.message.type === 'human') {
45864
+ else if (message.message.role === "user") {
45313
45865
  // Human message breaks tool grouping
45314
45866
  flushToolGroup();
45315
45867
  result.push({ type: 'message', message });
45316
45868
  }
45317
- else if (message.message.type === 'ai') {
45869
+ else if (message.message.role === "assistant") {
45318
45870
  // Skip empty AI messages
45319
45871
  const content = (message.message.content || '').trim();
45320
45872
  if (!content) {
@@ -45340,7 +45892,7 @@
45340
45892
  return (jsxRuntimeExports.jsx(ToolMessageGroup, { messages: item.messages }, `tool-group-${index}`));
45341
45893
  }
45342
45894
  return (jsxRuntimeExports.jsx(Message, { message: item.message, showTimestamp: showTimestamps, enableFeedback: enableFeedback, showSources: showSources, sourceDisplayMode: sourceDisplayMode, onFeedback: onFeedback }, item.message.id));
45343
- }), isTyping && showTypingIndicator && jsxRuntimeExports.jsx(TypingIndicator, {}), jsxRuntimeExports.jsx("div", { ref: messagesEndRef })] }));
45895
+ }), isTyping && showTypingIndicator && !hasActiveAction && jsxRuntimeExports.jsx(TypingIndicator, {}), jsxRuntimeExports.jsx("div", { ref: messagesEndRef })] }));
45344
45896
  };
45345
45897
 
45346
45898
  // Allowed file types
@@ -45430,7 +45982,6 @@
45430
45982
  conversations = [], onLoadConversations, onSwitchConversation, onStartNewConversation, onDeleteConversation, currentConversationId,
45431
45983
  // Override props for live preview
45432
45984
  headerTitleOverride, welcomeTitleOverride, welcomeMessageOverride, placeholderOverride, suggestedQuestionsOverride, }) => {
45433
- console.log('[ChatWindow] Rendering ChatWindow component');
45434
45985
  const appearance = config?.appearance;
45435
45986
  const settings = config?.settings;
45436
45987
  // Check if chat history should be shown (requires both persistConversation AND showChatHistory)
@@ -45441,13 +45992,6 @@
45441
45992
  const welcomeTitle = welcomeTitleOverride ?? appearance?.welcomeTitle ?? '';
45442
45993
  const welcomeMessage = welcomeMessageOverride ?? appearance?.welcomeMessage ?? '';
45443
45994
  const inputPlaceholder = placeholderOverride ?? appearance?.placeholder ?? 'Ask me anything...';
45444
- console.log('[ChatWindow] Appearance values:', {
45445
- size,
45446
- headerTitle,
45447
- welcomeTitle,
45448
- welcomeMessage,
45449
- inputPlaceholder,
45450
- });
45451
45995
  // Track if history panel is open
45452
45996
  const [showHistory, setShowHistory] = reactExports.useState(false);
45453
45997
  // History exit animation when starting a new chat from overview
@@ -45492,7 +46036,7 @@
45492
46036
  };
45493
46037
  // Check if message limit is reached
45494
46038
  const maxMessages = settings?.maxMessagesPerSession;
45495
- const userMessageCount = messages.filter(m => m.message.type === 'human').length;
46039
+ const userMessageCount = messages.filter(m => m.message.role === "user").length;
45496
46040
  const isLimitReached = maxMessages ? userMessageCount >= maxMessages : false;
45497
46041
  const handleQuestionClick = (question) => {
45498
46042
  onSendMessage(question);
@@ -45902,34 +46446,7 @@
45902
46446
  return observer;
45903
46447
  }
45904
46448
 
45905
- function styleInject(css, ref) {
45906
- if ( ref === void 0 ) ref = {};
45907
- var insertAt = ref.insertAt;
45908
-
45909
- if (typeof document === 'undefined') { return; }
45910
-
45911
- var head = document.head || document.getElementsByTagName('head')[0];
45912
- var style = document.createElement('style');
45913
- style.type = 'text/css';
45914
-
45915
- if (insertAt === 'top') {
45916
- if (head.firstChild) {
45917
- head.insertBefore(style, head.firstChild);
45918
- } else {
45919
- head.appendChild(style);
45920
- }
45921
- } else {
45922
- head.appendChild(style);
45923
- }
45924
-
45925
- if (style.styleSheet) {
45926
- style.styleSheet.cssText = css;
45927
- } else {
45928
- style.appendChild(document.createTextNode(css));
45929
- }
45930
- }
45931
-
45932
- var css_248z = ".ai-chat-widget{--radius-sm:4px;--radius-md:8px;--radius-lg:12px;--radius-xl:16px;--radius-2xl:18px;--radius-pill:9999px;--radius-window-top:22px;--radius-window-bottom:44px;--radius-window-gutter:16px;--radius-chat-bubble:14px;--radius-preset-badge:13px;--radius-history-item:14px;--radius-action-badge: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{--bg-primary:#282625;--bg-secondary:#4a4846;--bg-tertiary:#484848;--bg-hover:#484848;--text-primary:#fff;--text-secondary:#fff;--text-muted:#a1a1aa;--text-placeholder:#71717a;--border-default:#5d5b5b;--border-subtle:#5d5b5b;--border-muted:#5d5b5b;--user-bg:#484848;--user-text:#fff;--user-bg-hover:#5a5a5a;--agent-bg:transparent;--agent-text:#fff;--input-bg:#4a4846;--input-border:#5d5b5b;--input-text:#fff;--btn-primary-bg:#fff;--btn-primary-text:#312f2d;--btn-secondary-bg:transparent;--btn-secondary-text:#a1a1aa;--shadow-window:0px 0px 15px 9px rgba(0,0,0,.2);--shadow-button:0px 0px 15px 9px rgba(0,0,0,.03);--shadow-input:0px 0px 10px rgba(0,0,0,.15)}.ai-chat-widget{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif}.ai-chat-widget-container{font-size:var(--text-sm);line-height:1.5;position:fixed;z-index:var(--widget-z-index,9999)}.ai-chat-widget-container.bottom-right{bottom:20px;right:20px}.ai-chat-widget-container.bottom-left{bottom:20px;left:20px}.ai-chat-widget-container.top-right{right:20px;top:20px}.ai-chat-widget-container.top-left{left:20px;top:20px}@keyframes windowOpen{0%{opacity:0;transform:scale(.9) translateY(20px)}to{opacity:1;transform:scale(1) translateY(0)}}@keyframes windowClose{0%{opacity:1;transform:scale(1) translateY(0)}to{opacity:0;transform:scale(.9) translateY(20px)}}@keyframes messageSlideIn{0%{opacity:0;transform:translateY(12px)}to{opacity:1;transform:translateY(0)}}@keyframes welcomeFadeIn{0%{opacity:0;transform:translateY(16px)}to{opacity:1;transform:translateY(0)}}@keyframes typingPulse{0%,60%,to{opacity:.4;transform:translateY(0) scale(1)}30%{opacity:1;transform:translateY(-4px) scale(1.1)}}@keyframes ai-chat-tool-active{0%,to{background:var(--bg-secondary);opacity:1}50%{background:var(--bg-tertiary);opacity:1}}@keyframes feedbackMorph{0%{opacity:.5;transform:scale(.8)}to{opacity:1;transform:scale(1)}}@keyframes checkmarkPop{0%{opacity:0;transform:scale(0) rotate(-45deg)}50%{transform:scale(1.3) rotate(0deg)}to{opacity:1;transform:scale(1) rotate(0deg)}}@keyframes ai-chat-history-exit{to{opacity:0;transform:translateY(-18px)}}@media (max-width:480px){.ai-chat-window{animation:mobileSlideUp var(--duration-normal) var(--spring-smooth);border-radius:0!important;bottom:0!important;height:100%!important;left:0!important;position:fixed!important;right:0!important;top:0!important;width:100%!important}@keyframes mobileSlideUp{0%{transform:translateY(100%)}to{transform:translateY(0)}}.ai-chat-header{padding-top:max(16px,env(safe-area-inset-top))}.ai-chat-input-container{padding-bottom:max(20px,env(safe-area-inset-bottom))}}.ai-chat-button{align-items:center;background:var(--button-color,var(--btn-primary-bg));border:1px solid var(--button-border-color,var(--button-color,var(--btn-primary-bg)));border-radius:50%;box-shadow:var(--shadow-button,0 0 15px 9px rgba(0,0,0,.03));color:var(--button-icon-color,var(--btn-primary-text));cursor:pointer;display:flex;height:var(--button-size,56px);justify-content:center;overflow:hidden;position:relative;transition:filter var(--duration-fast) ease,transform var(--duration-fast) ease;width:var(--button-size,56px);z-index:1}.ai-chat-button:hover{transform:scale(1.02)}.ai-chat-button:active{transform:scale(.98)}.ai-chat-button-svg{height:50%;min-height:24px;min-width:24px;transition:transform var(--duration-fast) ease;width:50%}.ai-chat-button.is-open .ai-chat-button-svg{transform:rotate(0deg)}.ai-chat-button-icon{font-size:1.5em;line-height:1}.ai-chat-window{animation:windowOpen var(--duration-slow,.35s) var(--spring-bounce,cubic-bezier(.34,1.56,.64,1));background:var(--bg-primary,#fff);border:1px solid var(--border-default,#d3d3d3);border-radius:var(--radius-window-top,22px) var(--radius-window-top,22px) var(--radius-window-bottom,44px) var(--radius-window-bottom,44px);box-shadow:var(--shadow-window,0 0 15px 5px rgba(0,0,0,.08));display:flex;flex-direction:column;overflow:hidden;position:absolute;transform-origin:bottom right;z-index:2}.ai-chat-widget.dark .ai-chat-window{background:var(--bg-primary,#282625);border-color:var(--border-default,#5d5b5b);border-width:.7px}.ai-chat-window.closing{animation:windowClose var(--duration-normal) var(--spring-smooth) forwards}.ai-chat-window.size-small{height:var(--window-height,580px);width:var(--window-width,380px)}.ai-chat-window.size-medium{height:var(--window-height,720px);width:var(--window-width,440px)}.ai-chat-window.size-large{height:var(--window-height,820px);width:var(--window-width,520px)}.ai-chat-widget-container.bottom-right .ai-chat-window{bottom:calc(var(--button-size, 56px) + 8px);right:0}.ai-chat-widget-container.bottom-left .ai-chat-window{bottom:calc(var(--button-size, 56px) + 8px);left:0}.ai-chat-widget-container.top-right .ai-chat-window{right:0;top:calc(var(--button-size, 56px) + 8px)}.ai-chat-widget-container.top-left .ai-chat-window{left:0;top:calc(var(--button-size, 56px) + 8px)}.ai-chat-header{align-items:center;background:var(--bg-primary,#fff);border-bottom:1px solid var(--border-default,#d3d3d3);border-radius:var(--radius-window-top,22px) var(--radius-window-top,22px) 0 0;display:flex;justify-content:space-between;padding:18px var(--space-md,16px);position:relative;z-index:10}.ai-chat-widget.dark .ai-chat-header{background:var(--bg-primary,#282625);border-bottom-color:var(--border-default,#5d5b5b);border-bottom-width:.7px}.ai-chat-header.is-history{padding-left:var(--space-md)}.ai-chat-header.is-history .ai-chat-title{flex:1;min-width:0;overflow:hidden;padding-right:var(--space-lg);text-overflow:ellipsis;white-space:nowrap}.ai-chat-header-content{align-items:center;display:flex;flex:1;gap:var(--space-lg)}.ai-chat-header-actions{align-items:center;display:flex;gap:var(--space-sm)}.ai-chat-logo{border-radius:10px;height:36px;object-fit:cover;width:36px}.ai-chat-title{color:var(--text-primary,#3e3e3e);font-size:var(--text-xl,22px);font-weight:var(--font-weight-bold,700);letter-spacing:-.02em}.ai-chat-widget.dark .ai-chat-title{color:var(--text-primary,#fff)}.ai-chat-close-button{align-items:center;background:transparent;border:none;border-radius:var(--radius-md);color:var(--text-primary);cursor:pointer;display:flex;height:32px;justify-content:center;padding:0;transition:color var(--duration-fast) ease;width:32px}.ai-chat-close-button:hover{color:var(--text-muted)}.ai-chat-close-button:active{transform:scale(.95)}.ai-chat-header-button{align-items:center;background:transparent;border:none;border-radius:var(--radius-md);color:var(--text-muted);cursor:pointer;display:flex;height:32px;justify-content:center;padding:0;transition:all var(--duration-fast) ease;width:32px}.ai-chat-header-button:hover{background:var(--bg-secondary);color:var(--text-secondary)}.ai-chat-header-button svg{height:18px;width:18px}.ai-chat-messages{-webkit-overflow-scrolling:touch;-ms-overflow-style:none;align-items:stretch;background:var(--bg-primary,#fff);display:flex;flex:1;flex-direction:column;gap:var(--space-md,16px);justify-content:flex-start;overflow-x:hidden;overflow-y:auto;padding:var(--space-lg,24px) var(--space-md,16px) 100px;position:relative;scroll-behavior:smooth;scrollbar-width:none}.ai-chat-widget.dark .ai-chat-messages{background:var(--bg-primary,#18181b)}.ai-chat-messages::-webkit-scrollbar{display:none}.ai-chat-message{animation:messageSlideIn var(--duration-normal) var(--spring-bounce);display:flex;flex-direction:column;gap:6px}.ai-chat-message-content{word-wrap:break-word;font-size:var(--text-md);line-height:var(--line-height-relaxed);max-width:85%}.ai-chat-message.user{align-items:flex-end}.ai-chat-message.user .ai-chat-message-content{background:var(--user-bg,#f4f3f0);border:none;border-radius:var(--radius-chat-bubble,15px);box-shadow:none;color:var(--user-text,#000);padding:var(--space-sm,8px) var(--space-md,16px)}.ai-chat-widget.dark .ai-chat-message.user .ai-chat-message-content{background:var(--user-bg,#484848);color:var(--user-text,#fff)}.ai-chat-message.user .ai-chat-message-meta{justify-content:flex-end;padding-right:var(--space-xs)}.ai-chat-message.assistant{align-items:flex-start}.ai-chat-message.assistant .ai-chat-message-content{background:var(--agent-bg,transparent);border:none;color:var(--agent-text,#18181b);padding:0}.ai-chat-widget.dark .ai-chat-message.assistant .ai-chat-message-content{color:var(--agent-text,#fafafa)}.ai-chat-message.system{align-items:center}.ai-chat-message.system .ai-chat-message-content{background:hsla(48,96%,89%,.8);border-radius:var(--radius-md);color:#92400e;font-size:var(--text-xs);font-style:italic;max-width:90%;padding:var(--space-sm) var(--space-md);text-align:center}.ai-chat-widget.dark .ai-chat-message.system .ai-chat-message-content{background:rgba(120,53,15,.5);color:#fef3c7}.ai-chat-message.tool{align-items:flex-start}.ai-chat-message.tool .ai-chat-message-content{background:rgba(219,234,254,.8);border-radius:var(--radius-chat-bubble);border-bottom-left-radius:var(--radius-xs);color:#1e40af;font-family:Courier New,monospace;font-size:var(--text-sm);padding:var(--space-sm) var(--space-md)}.ai-chat-widget.dark .ai-chat-message.tool .ai-chat-message-content{background:rgba(30,58,138,.5);color:#dbeafe}.ai-chat-message-meta{align-items:center;color:var(--text-muted);display:flex;font-size:var(--text-xs);gap:var(--space-sm);padding-left:var(--space-xs)}.ai-chat-message-timestamp{font-size:var(--text-xs);line-height:1}.ai-chat-typing{align-items:center;animation:messageSlideIn var(--duration-normal) var(--spring-bounce);background:transparent;display:flex;gap:5px;padding:0}.ai-chat-typing-dot{animation:typingPulse 1.4s ease-in-out infinite;background:var(--text-muted);border-radius:50%;height:6px;width:6px}.ai-chat-typing-dot:nth-child(2){animation-delay:.15s}.ai-chat-typing-dot:nth-child(3){animation-delay:.3s}.ai-chat-welcome{align-items:stretch;animation:welcomeFadeIn var(--duration-slow) var(--spring-smooth);display:flex;flex-direction:column;justify-content:flex-start;padding:0;text-align:left}.ai-chat-welcome-text,.ai-chat-welcome-title{align-self:flex-start}.ai-chat-welcome-title{color:var(--text-primary);font-size:var(--text-2xl);font-weight:var(--font-weight-semibold);letter-spacing:-.02em;margin-bottom:var(--space-md)}.ai-chat-welcome-text{color:var(--text-secondary);font-size:var(--text-md);line-height:var(--line-height-relaxed);max-width:100%}.ai-chat-error{align-items:flex-start;align-self:center;background:var(--bg-secondary);border:none;border-radius:var(--radius-chat-bubble);color:var(--text-primary);display:flex;font-size:var(--text-md);font-weight:var(--font-weight-normal);gap:10px;line-height:1.5;margin:0 auto;max-width:90%;padding:10px var(--space-md)}.ai-chat-error:before{align-items:center;background:rgba(239,68,68,.15);border-radius:50%;color:#ef4444;content:\"⚠\";display:flex;flex-shrink:0;font-size:var(--text-xs);font-weight:700;height:18px;justify-content:center;margin-top:2px;width:18px}.ai-chat-widget.dark .ai-chat-error:before{background:rgba(239,68,68,.2);color:#fca5a5}.ai-chat-message.assistant .ai-chat-message-content p{margin:0 0 12px}.ai-chat-message.assistant .ai-chat-message-content p:last-child{margin-bottom:0}.ai-chat-message.assistant .ai-chat-message-content ol,.ai-chat-message.assistant .ai-chat-message-content ul{margin:8px 0 12px;padding-left:24px}.ai-chat-message.assistant .ai-chat-message-content li{line-height:1.5;margin:6px 0}.ai-chat-message.assistant .ai-chat-message-content strong{font-weight:var(--font-weight-semibold)}.ai-chat-message.assistant .ai-chat-message-content em{font-style:italic}.ai-chat-message.assistant .ai-chat-message-content code{background:rgba(0,0,0,.06);border-radius:var(--radius-sm);font-family:SF Mono,Consolas,Monaco,monospace;font-size:.9em;padding:2px 6px}.ai-chat-widget.dark .ai-chat-message.assistant .ai-chat-message-content code{background:hsla(0,0%,100%,.1)}.ai-chat-message.assistant .ai-chat-message-content pre{background:rgba(0,0,0,.06);border-radius:var(--radius-md);margin:8px 0 12px;overflow-x:auto;padding:var(--space-sm)}.ai-chat-widget.dark .ai-chat-message.assistant .ai-chat-message-content pre{background:hsla(0,0%,100%,.08)}.ai-chat-message.assistant .ai-chat-message-content pre code{background:transparent;border-radius:0;padding:0}.ai-chat-message.assistant .ai-chat-message-content blockquote{border-left:3px solid var(--btn-primary-bg);color:var(--text-muted);margin:8px 0 12px;padding:4px 0 4px 12px}.ai-chat-message.assistant .ai-chat-message-content a{color:var(--btn-primary-bg);text-decoration:underline}.ai-chat-message.assistant .ai-chat-message-content a:hover{opacity:.8}.ai-chat-message.assistant .ai-chat-message-content h1,.ai-chat-message.assistant .ai-chat-message-content h2,.ai-chat-message.assistant .ai-chat-message-content h3,.ai-chat-message.assistant .ai-chat-message-content h4,.ai-chat-message.assistant .ai-chat-message-content h5,.ai-chat-message.assistant .ai-chat-message-content h6{font-weight:var(--font-weight-semibold);line-height:var(--line-height-tight);margin:16px 0 8px}.ai-chat-message.assistant .ai-chat-message-content h1:first-child,.ai-chat-message.assistant .ai-chat-message-content h2:first-child,.ai-chat-message.assistant .ai-chat-message-content h3:first-child{margin-top:0}.ai-chat-message.assistant .ai-chat-message-content hr{border:none;border-top:1px solid var(--border-subtle);margin:12px 0}.ai-chat-input-container{background:linear-gradient(to bottom,transparent 0,var(--bg-primary,#fff) 50%,var(--bg-primary,#fff) 100%);bottom:0;left:0;padding-top:30px;position:absolute;right:0;z-index:10}.ai-chat-widget.dark .ai-chat-input-container{background:linear-gradient(to bottom,transparent 0,var(--bg-primary,#282625) 50%,var(--bg-primary,#282625) 100%)}.ai-chat-input-container.separate{padding:0 var(--radius-window-gutter,16px) var(--radius-window-gutter,16px);padding-top:30px}.ai-chat-input-wrapper{align-items:flex-start;background:var(--input-bg,#f4f4f4);border:1px solid var(--input-border,#d3d3d3);border-radius:var(--radius-input,62px);display:flex;gap:0;height:52px;padding:6px 6px 6px 12px;position:relative;transition:all var(--duration-fast,.15s) ease;z-index:5}.ai-chat-widget.dark .ai-chat-input-wrapper{background:var(--input-bg,#4a4846);border-color:var(--input-border,#5d5b5b);border-width:.7px;box-shadow:var(--shadow-input,0 0 10px rgba(0,0,0,.15))}.ai-chat-input-wrapper:focus-within{border-color:var(--text-muted,#a1a1aa)}.ai-chat-input{word-wrap:break-word;background:transparent;border:none;box-sizing:border-box;color:var(--input-text,#000);flex:1;font-family:inherit;font-size:var(--text-md,15px);height:40px;line-height:20px;max-height:40px;min-height:40px;min-width:0;outline:none;overflow-wrap:anywhere;overflow-x:hidden;overflow-y:auto;padding:10px var(--space-sm,8px);resize:none;white-space:pre-wrap;width:0;word-break:break-word}.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;padding:0;transition:all var(--duration-fast,.15s) ease;width:40px}.ai-chat-widget.dark .ai-chat-send-button{background:var(--send-button-background,var(--primary-color,var(--button-color,var(--btn-primary-bg,#fff))));color:var(--button-icon-color,var(--btn-primary-text,#312f2d))}.ai-chat-send-button.active{background:var(--send-button-background,var(--primary-color,var(--button-color,var(--btn-primary-bg,#151515))));color:var(--button-icon-color,var(--btn-primary-text,#f4f4f4))}.ai-chat-widget.dark .ai-chat-send-button.active{background:var(--send-button-background,var(--primary-color,var(--button-color,var(--btn-primary-bg,#fff))));color:var(--button-icon-color,var(--btn-primary-text,#312f2d))}.ai-chat-send-button:hover:not(:disabled){opacity:.8}.ai-chat-send-button:active:not(:disabled){transform:scale(.95)}.ai-chat-send-button:disabled{cursor:not-allowed;opacity:.3}.ai-chat-file-list{display:flex;flex-wrap:wrap;gap:var(--space-sm);padding:var(--space-sm) var(--space-sm)}.ai-chat-file-item{align-items:center;background:rgba(0,0,0,.05);border-radius:6px;display:flex;font-size:var(--text-xs);gap:var(--space-sm);padding:6px 10px}.ai-chat-file-extension{background:var(--btn-primary-bg);border-radius:3px;color:var(--btn-primary-text);display:inline-block;font-size:10px;font-weight:var(--font-weight-semibold);min-width:40px;padding:2px 6px;text-align:center;text-transform:uppercase}.ai-chat-file-info{display:flex;flex:1;flex-direction:column;gap:2px;min-width:0}.ai-chat-file-name{font-weight:var(--font-weight-medium);max-width:150px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ai-chat-file-size{color:var(--text-muted);font-size:10px;opacity:.7}.ai-chat-file-remove{align-items:center;background:none;border:none;color:inherit;cursor:pointer;display:flex;justify-content:center;opacity:.5;padding:var(--space-xs);transition:opacity var(--duration-fast) ease}.ai-chat-file-remove:hover{opacity:1}.ai-chat-suggested-questions{align-self:flex-end;margin:0;padding:16px 0 0;width:100%}.ai-chat-suggested-questions-list{align-items:center;display:flex;flex-wrap:wrap;gap:6px;justify-content:flex-end}.ai-chat-suggested-question{background:var(--primary-color,var(--button-color,var(--user-bg,#f4f3f0)));border:none;border-radius:var(--radius-preset-badge,13px);color:var(--button-icon-color,var(--user-text,#000));cursor:pointer;font-size:14px;font-weight:400;line-height:1.3;max-width:100%;overflow:hidden;padding:8px 14px;text-overflow:ellipsis;transition:background .15s ease,opacity .15s ease;white-space:nowrap}.ai-chat-widget.dark .ai-chat-suggested-question{background:var(--primary-color,var(--button-color,var(--user-bg,#484848)));color:var(--button-icon-color,var(--user-text,#fff))}.ai-chat-suggested-question-text{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ai-chat-suggested-question:hover{filter:brightness(.9)}.ai-chat-widget.dark .ai-chat-suggested-question:hover{filter:brightness(1.15)}.ai-chat-suggested-question:active{transform:scale(.98)}.ai-chat-suggested-question-icon{display:none}.ai-chat-feedback-buttons{align-items:center;display:flex;gap:var(--space-xs)}.ai-chat-feedback{align-items:center;display:inline-flex;gap:0;height:20px}.ai-chat-feedback-button{align-items:center;background:transparent!important;border:none;border-radius:var(--radius-sm);color:var(--text-placeholder);cursor:pointer;display:flex;font-size:var(--text-sm);height:20px;justify-content:center;padding:var(--space-xs);transition:all var(--duration-fast) var(--spring-bounce)}.ai-chat-feedback-button:hover:not(:disabled){background:none!important;color:var(--text-secondary)}.ai-chat-feedback-button:active:not(:disabled){transform:scale(.9)}.ai-chat-feedback-button:disabled{cursor:not-allowed;opacity:.4}.ai-chat-feedback-button.active{background:none!important;color:var(--text-primary)}.ai-chat-feedback-submitted{align-items:center;animation:feedbackMorph .3s var(--spring-bounce);display:flex;gap:6px}.ai-chat-feedback-checkmark{animation:checkmarkPop .3s var(--spring-bounce);color:#10b981;font-size:var(--text-md);font-weight:700}.ai-chat-feedback-text{color:#10b981;font-size:var(--text-sm);font-weight:var(--font-weight-medium)}.ai-chat-history-panel{background:var(--bg-primary,#fff);display:flex;flex:1;flex-direction:column;overflow:hidden}.ai-chat-widget.dark .ai-chat-history-panel{background:var(--bg-primary,#18181b)}.ai-chat-history-empty,.ai-chat-history-loading{align-items:center;color:var(--text-muted);display:flex;flex:1;font-size:var(--text-sm);justify-content:center;padding:var(--space-lg);text-align:center}.ai-chat-history-list{-ms-overflow-style:none;display:flex;flex:1;flex-direction:column;gap:var(--space-sm);overflow-y:auto;padding:var(--space-md) var(--space-md) 120px;scrollbar-width:none}.ai-chat-history-list::-webkit-scrollbar{display:none}.ai-chat-history-list.exiting{animation:ai-chat-history-exit .22s var(--spring-smooth) forwards}.ai-chat-history-item{align-items:center;background:var(--user-bg,#f4f4f5);border-radius:var(--radius-history-item,15px);display:flex;flex-direction:row;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:36px;min-width:0;padding:0 3px 0 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;color:var(--text-muted,#71717a);cursor:pointer;display:flex;flex-shrink:0;height:32px;justify-content:center;margin-right:4px;opacity:0;transition:opacity var(--duration-fast,.15s) ease,color var(--duration-fast,.15s) ease;width:32px}.ai-chat-history-item:hover .ai-chat-history-item-delete{opacity:1}.ai-chat-history-item-delete:hover{color:var(--text-primary,#18181b)}.ai-chat-widget.dark .ai-chat-history-item-delete:hover{color:var(--text-primary,#fafafa)}.ai-chat-tool-row{align-items:center;display:flex;gap:10px;margin:2px 0}.ai-chat-tool-gear{color:var(--text-primary);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;border-radius:var(--radius-action-badge,3px);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:var(--tool-completed-bg,hsla(0,0%,100%,.12));color:var(--tool-completed-text,hsla(0,0%,100%,.9))}.ai-chat-widget:not(.dark) .ai-chat-tool-badge.completed{--tool-completed-bg:rgba(0,0,0,.08);--tool-completed-text:rgba(0,0,0,.8)}.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:#22c55e;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}@keyframes ai-chat-gear-spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}@keyframes ai-chat-tool-gradient{0%{background-position:200% 0}to{background-position:-200% 0}}@keyframes ai-chat-tool-check-appear{0%{opacity:0;transform:scale(.5)}to{opacity:.7;transform:scale(1)}}.ai-chat-sources{background:rgba(0,0,0,.02);border-radius:6px;font-size:var(--text-xs);margin-top:var(--space-sm);overflow:hidden}.ai-chat-sources-toggle{align-items:center;background:none;border:none;cursor:pointer;display:flex;gap:6px;padding:var(--space-sm) 10px;text-align:left;transition:background var(--duration-fast) ease;width:100%}.ai-chat-sources-toggle:hover{background:rgba(0,0,0,.03)}.ai-chat-sources-icon{color:var(--text-muted);font-size:10px;transition:transform var(--duration-fast) ease}.ai-chat-sources-title{color:var(--text-primary);flex:1;font-size:11px;font-weight:var(--font-weight-semibold);letter-spacing:.5px;text-transform:uppercase}.ai-chat-source-item{border-top:1px solid rgba(0,0,0,.05);color:var(--text-muted);display:flex;gap:var(--space-sm);padding:var(--space-sm) 10px}.ai-chat-source-item:last-child{border-bottom:none}.ai-chat-source-number{color:var(--btn-primary-bg);flex-shrink:0;font-weight:var(--font-weight-semibold)}.ai-chat-source-details{display:flex;flex:1;flex-direction:column;gap:var(--space-xs)}.ai-chat-source-score{color:var(--text-placeholder);font-size:11px}.ai-chat-source-content{color:var(--text-muted);font-size:11px;font-style:italic;line-height:var(--line-height-normal)}.ai-chat-source-metadata{display:flex;flex-wrap:wrap;gap:6px;margin-top:2px}.ai-chat-source-meta-item{background:rgba(0,0,0,.05);border-radius:3px;color:var(--text-muted);font-size:10px;padding:2px 6px}";
46449
+ var css_248z = ".ai-chat-widget{--radius-sm:4px;--radius-md:8px;--radius-lg:12px;--radius-xl:16px;--radius-2xl:18px;--radius-pill:9999px;--radius-window-top:22px;--radius-window-bottom:44px;--radius-window-gutter:16px;--radius-chat-bubble:14px;--radius-preset-badge:13px;--radius-history-item:14px;--radius-action-badge: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{--bg-primary:#282625;--bg-secondary:#4a4846;--bg-tertiary:#484848;--bg-hover:#484848;--text-primary:#fff;--text-secondary:#fff;--text-muted:#a1a1aa;--text-placeholder:#71717a;--border-default:#5d5b5b;--border-subtle:#5d5b5b;--border-muted:#5d5b5b;--user-bg:#484848;--user-text:#fff;--user-bg-hover:#5a5a5a;--agent-bg:transparent;--agent-text:#fff;--input-bg:#4a4846;--input-border:#5d5b5b;--input-text:#fff;--btn-primary-bg:#fff;--btn-primary-text:#312f2d;--btn-secondary-bg:transparent;--btn-secondary-text:#a1a1aa;--shadow-window:0px 0px 15px 9px rgba(0,0,0,.2);--shadow-button:0px 0px 15px 9px rgba(0,0,0,.03);--shadow-input:0px 0px 10px rgba(0,0,0,.15)}.ai-chat-widget{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif}.ai-chat-widget-container{font-size:var(--text-sm);line-height:1.5;position:fixed;z-index:var(--widget-z-index,9999)}.ai-chat-widget-container.bottom-right{bottom:20px;right:20px}.ai-chat-widget-container.bottom-left{bottom:20px;left:20px}.ai-chat-widget-container.top-right{right:20px;top:20px}.ai-chat-widget-container.top-left{left:20px;top:20px}@keyframes windowOpen{0%{opacity:0;transform:scale(.9) translateY(20px)}to{opacity:1;transform:scale(1) translateY(0)}}@keyframes windowClose{0%{opacity:1;transform:scale(1) translateY(0)}to{opacity:0;transform:scale(.9) translateY(20px)}}@keyframes messageSlideIn{0%{opacity:0;transform:translateY(12px)}to{opacity:1;transform:translateY(0)}}@keyframes welcomeFadeIn{0%{opacity:0;transform:translateY(16px)}to{opacity:1;transform:translateY(0)}}@keyframes typingPulse{0%,60%,to{opacity:.4;transform:translateY(0) scale(1)}30%{opacity:1;transform:translateY(-4px) scale(1.1)}}@keyframes ai-chat-tool-active{0%,to{background:var(--bg-secondary);opacity:1}50%{background:var(--bg-tertiary);opacity:1}}@keyframes feedbackMorph{0%{opacity:.5;transform:scale(.8)}to{opacity:1;transform:scale(1)}}@keyframes checkmarkPop{0%{opacity:0;transform:scale(0) rotate(-45deg)}50%{transform:scale(1.3) rotate(0deg)}to{opacity:1;transform:scale(1) rotate(0deg)}}@keyframes ai-chat-history-exit{to{opacity:0;transform:translateY(-18px)}}@media (max-width:480px){.ai-chat-window{animation:mobileSlideUp var(--duration-normal) var(--spring-smooth);border-radius:0!important;bottom:0!important;height:100%!important;left:0!important;position:fixed!important;right:0!important;top:0!important;width:100%!important}@keyframes mobileSlideUp{0%{transform:translateY(100%)}to{transform:translateY(0)}}.ai-chat-header{padding-top:max(16px,env(safe-area-inset-top))}.ai-chat-input-container{padding-bottom:max(20px,env(safe-area-inset-bottom))}}.ai-chat-button{align-items:center;background:var(--button-color,var(--btn-primary-bg));border:1px solid var(--button-border-color,var(--button-color,var(--btn-primary-bg)));border-radius:50%;box-shadow:var(--shadow-button,0 0 15px 9px rgba(0,0,0,.03));color:var(--button-icon-color,var(--btn-primary-text));cursor:pointer;display:flex;height:var(--button-size,56px);justify-content:center;overflow:hidden;position:relative;transition:filter var(--duration-fast) ease,transform var(--duration-fast) ease;width:var(--button-size,56px);z-index:1}.ai-chat-button:hover{transform:scale(1.02)}.ai-chat-button:active{transform:scale(.98)}.ai-chat-button-svg{height:50%;min-height:24px;min-width:24px;transition:transform var(--duration-fast) ease;width:50%}.ai-chat-button.is-open .ai-chat-button-svg{transform:rotate(0deg)}.ai-chat-button-icon{font-size:1.5em;line-height:1}.ai-chat-window{animation:windowOpen var(--duration-slow,.35s) var(--spring-bounce,cubic-bezier(.34,1.56,.64,1));background:var(--bg-primary,#fff);border:1px solid var(--border-default,#d3d3d3);border-radius:var(--radius-window-top,22px) var(--radius-window-top,22px) var(--radius-window-bottom,44px) var(--radius-window-bottom,44px);box-shadow:var(--shadow-window,0 0 15px 5px rgba(0,0,0,.08));display:flex;flex-direction:column;overflow:hidden;position:absolute;transform-origin:bottom right;z-index:2}.ai-chat-widget.dark .ai-chat-window{background:var(--bg-primary,#282625);border-color:var(--border-default,#5d5b5b);border-width:.7px}.ai-chat-window.closing{animation:windowClose var(--duration-normal) var(--spring-smooth) forwards}.ai-chat-window.size-small{height:var(--window-height,580px);width:var(--window-width,380px)}.ai-chat-window.size-medium{height:var(--window-height,720px);width:var(--window-width,440px)}.ai-chat-window.size-large{height:var(--window-height,820px);width:var(--window-width,520px)}.ai-chat-widget-container.bottom-right .ai-chat-window{bottom:calc(var(--button-size, 56px) + 8px);right:0}.ai-chat-widget-container.bottom-left .ai-chat-window{bottom:calc(var(--button-size, 56px) + 8px);left:0}.ai-chat-widget-container.top-right .ai-chat-window{right:0;top:calc(var(--button-size, 56px) + 8px)}.ai-chat-widget-container.top-left .ai-chat-window{left:0;top:calc(var(--button-size, 56px) + 8px)}.ai-chat-header{align-items:center;background:var(--bg-primary,#fff);border-bottom:1px solid var(--border-default,#d3d3d3);border-radius:var(--radius-window-top,22px) var(--radius-window-top,22px) 0 0;display:flex;justify-content:space-between;padding:18px var(--space-md,16px);position:relative;z-index:10}.ai-chat-widget.dark .ai-chat-header{background:var(--bg-primary,#282625);border-bottom-color:var(--border-default,#5d5b5b);border-bottom-width:.7px}.ai-chat-header.is-history{padding-left:var(--space-md)}.ai-chat-header.is-history .ai-chat-title{flex:1;min-width:0;overflow:hidden;padding-right:var(--space-lg);text-overflow:ellipsis;white-space:nowrap}.ai-chat-header-content{align-items:center;display:flex;flex:1;gap:var(--space-lg)}.ai-chat-header-actions{align-items:center;display:flex;gap:var(--space-sm)}.ai-chat-logo{border-radius:10px;height:36px;object-fit:cover;width:36px}.ai-chat-title{color:var(--text-primary,#3e3e3e);font-size:var(--text-xl,22px);font-weight:var(--font-weight-bold,700);letter-spacing:-.02em}.ai-chat-widget.dark .ai-chat-title{color:var(--text-primary,#fff)}.ai-chat-close-button{align-items:center;background:transparent;border:none;border-radius:var(--radius-md);color:var(--text-primary);cursor:pointer;display:flex;height:32px;justify-content:center;padding:0;transition:color var(--duration-fast) ease;width:32px}.ai-chat-close-button:hover{color:var(--text-muted)}.ai-chat-close-button:active{transform:scale(.95)}.ai-chat-header-button{align-items:center;background:transparent;border:none;border-radius:var(--radius-md);color:var(--text-muted);cursor:pointer;display:flex;height:32px;justify-content:center;padding:0;transition:all var(--duration-fast) ease;width:32px}.ai-chat-header-button:hover{background:var(--bg-secondary);color:var(--text-secondary)}.ai-chat-header-button svg{height:18px;width:18px}.ai-chat-messages{-webkit-overflow-scrolling:touch;-ms-overflow-style:none;align-items:stretch;background:var(--bg-primary,#fff);display:flex;flex:1;flex-direction:column;gap:var(--space-md,16px);justify-content:flex-start;overflow-x:hidden;overflow-y:auto;padding:var(--space-lg,24px) var(--space-md,16px) 100px;position:relative;scroll-behavior:smooth;scrollbar-width:none}.ai-chat-widget.dark .ai-chat-messages{background:var(--bg-primary,#18181b)}.ai-chat-messages::-webkit-scrollbar{display:none}.ai-chat-message{animation:messageSlideIn var(--duration-normal) var(--spring-bounce);display:flex;flex-direction:column;gap:6px}.ai-chat-message-content{word-wrap:break-word;font-size:var(--text-md);line-height:var(--line-height-relaxed);max-width:85%}.ai-chat-message.user{align-items:flex-end}.ai-chat-message.user .ai-chat-message-content{background:var(--user-bg,#f4f3f0);border:none;border-radius:var(--radius-chat-bubble,15px);box-shadow:none;color:var(--user-text,#000);padding:var(--space-sm,8px) var(--space-md,16px)}.ai-chat-widget.dark .ai-chat-message.user .ai-chat-message-content{background:var(--user-bg,#484848);color:var(--user-text,#fff)}.ai-chat-message.user .ai-chat-message-meta{justify-content:flex-end;padding-right:var(--space-xs)}.ai-chat-message.assistant{align-items:flex-start}.ai-chat-message.assistant .ai-chat-message-content{background:var(--agent-bg,transparent);border:none;color:var(--agent-text,#18181b);padding:0}.ai-chat-widget.dark .ai-chat-message.assistant .ai-chat-message-content{color:var(--agent-text,#fafafa)}.ai-chat-message.system{align-items:center}.ai-chat-message.system .ai-chat-message-content{background:hsla(48,96%,89%,.8);border-radius:var(--radius-md);color:#92400e;font-size:var(--text-xs);font-style:italic;max-width:90%;padding:var(--space-sm) var(--space-md);text-align:center}.ai-chat-widget.dark .ai-chat-message.system .ai-chat-message-content{background:rgba(120,53,15,.5);color:#fef3c7}.ai-chat-message.tool{align-items:flex-start}.ai-chat-message.tool .ai-chat-message-content{background:rgba(219,234,254,.8);border-radius:var(--radius-chat-bubble);border-bottom-left-radius:var(--radius-xs);color:#1e40af;font-family:Courier New,monospace;font-size:var(--text-sm);padding:var(--space-sm) var(--space-md)}.ai-chat-widget.dark .ai-chat-message.tool .ai-chat-message-content{background:rgba(30,58,138,.5);color:#dbeafe}.ai-chat-message-meta{align-items:center;color:var(--text-muted);display:flex;font-size:var(--text-xs);gap:var(--space-sm);padding-left:var(--space-xs)}.ai-chat-message-timestamp{font-size:var(--text-xs);line-height:1}.ai-chat-typing{align-items:center;animation:messageSlideIn var(--duration-normal) var(--spring-bounce);background:transparent;display:flex;gap:5px;padding:0}.ai-chat-typing-dot{animation:typingPulse 1.4s ease-in-out infinite;background:var(--text-muted);border-radius:50%;height:6px;width:6px}.ai-chat-typing-dot:nth-child(2){animation-delay:.15s}.ai-chat-typing-dot:nth-child(3){animation-delay:.3s}.ai-chat-welcome{align-items:stretch;animation:welcomeFadeIn var(--duration-slow) var(--spring-smooth);display:flex;flex-direction:column;justify-content:flex-start;padding:0;text-align:left}.ai-chat-welcome-text,.ai-chat-welcome-title{align-self:flex-start}.ai-chat-welcome-title{color:var(--text-primary);font-size:var(--text-2xl);font-weight:var(--font-weight-semibold);letter-spacing:-.02em;margin-bottom:var(--space-md)}.ai-chat-welcome-text{color:var(--text-secondary);font-size:var(--text-md);line-height:var(--line-height-relaxed);max-width:100%}.ai-chat-error{align-items:flex-start;align-self:center;background:var(--bg-secondary);border:none;border-radius:var(--radius-chat-bubble);color:var(--text-primary);display:flex;font-size:var(--text-md);font-weight:var(--font-weight-normal);gap:10px;line-height:1.5;margin:0 auto;max-width:90%;padding:10px var(--space-md)}.ai-chat-error:before{align-items:center;background:rgba(239,68,68,.15);border-radius:50%;color:#ef4444;content:\"⚠\";display:flex;flex-shrink:0;font-size:var(--text-xs);font-weight:700;height:18px;justify-content:center;margin-top:2px;width:18px}.ai-chat-widget.dark .ai-chat-error:before{background:rgba(239,68,68,.2);color:#fca5a5}.ai-chat-message.assistant .ai-chat-message-content p{margin:0 0 12px}.ai-chat-message.assistant .ai-chat-message-content p:last-child{margin-bottom:0}.ai-chat-message.assistant .ai-chat-message-content ol,.ai-chat-message.assistant .ai-chat-message-content ul{margin:8px 0 12px;padding-left:24px}.ai-chat-message.assistant .ai-chat-message-content li{line-height:1.5;margin:6px 0}.ai-chat-message.assistant .ai-chat-message-content strong{font-weight:var(--font-weight-semibold)}.ai-chat-message.assistant .ai-chat-message-content em{font-style:italic}.ai-chat-message.assistant .ai-chat-message-content code{background:rgba(0,0,0,.06);border-radius:var(--radius-sm);font-family:SF Mono,Consolas,Monaco,monospace;font-size:.9em;padding:2px 6px}.ai-chat-widget.dark .ai-chat-message.assistant .ai-chat-message-content code{background:hsla(0,0%,100%,.1)}.ai-chat-message.assistant .ai-chat-message-content pre{background:rgba(0,0,0,.06);border-radius:var(--radius-md);margin:8px 0 12px;overflow-x:auto;padding:var(--space-sm)}.ai-chat-widget.dark .ai-chat-message.assistant .ai-chat-message-content pre{background:hsla(0,0%,100%,.08)}.ai-chat-message.assistant .ai-chat-message-content pre code{background:transparent;border-radius:0;padding:0}.ai-chat-message.assistant .ai-chat-message-content blockquote{border-left:3px solid var(--btn-primary-bg);color:var(--text-muted);margin:8px 0 12px;padding:4px 0 4px 12px}.ai-chat-message.assistant .ai-chat-message-content a{color:var(--btn-primary-bg);text-decoration:underline}.ai-chat-message.assistant .ai-chat-message-content a:hover{opacity:.8}.ai-chat-message.assistant .ai-chat-message-content h1,.ai-chat-message.assistant .ai-chat-message-content h2,.ai-chat-message.assistant .ai-chat-message-content h3,.ai-chat-message.assistant .ai-chat-message-content h4,.ai-chat-message.assistant .ai-chat-message-content h5,.ai-chat-message.assistant .ai-chat-message-content h6{font-weight:var(--font-weight-semibold);line-height:var(--line-height-tight);margin:16px 0 8px}.ai-chat-message.assistant .ai-chat-message-content h1:first-child,.ai-chat-message.assistant .ai-chat-message-content h2:first-child,.ai-chat-message.assistant .ai-chat-message-content h3:first-child{margin-top:0}.ai-chat-message.assistant .ai-chat-message-content hr{border:none;border-top:1px solid var(--border-subtle);margin:12px 0}.ai-chat-input-container{background:linear-gradient(to bottom,transparent 0,var(--bg-primary,#fff) 50%,var(--bg-primary,#fff) 100%);bottom:0;left:0;padding-top:30px;position:absolute;right:0;z-index:10}.ai-chat-widget.dark .ai-chat-input-container{background:linear-gradient(to bottom,transparent 0,var(--bg-primary,#282625) 50%,var(--bg-primary,#282625) 100%)}.ai-chat-input-container.separate{padding:0 var(--radius-window-gutter,16px) var(--radius-window-gutter,16px);padding-top:30px}.ai-chat-input-wrapper{align-items:flex-start;background:var(--input-bg,#f4f4f4);border:1px solid var(--input-border,#d3d3d3);border-radius:var(--radius-input,62px);display:flex;gap:0;height:52px;padding:6px 6px 6px 12px;position:relative;transition:all var(--duration-fast,.15s) ease;z-index:5}.ai-chat-widget.dark .ai-chat-input-wrapper{background:var(--input-bg,#4a4846);border-color:var(--input-border,#5d5b5b);border-width:.7px;box-shadow:var(--shadow-input,0 0 10px rgba(0,0,0,.15))}.ai-chat-input-wrapper:focus-within{border-color:var(--text-muted,#a1a1aa)}.ai-chat-input{word-wrap:break-word;background:transparent;border:none;box-sizing:border-box;color:var(--input-text,#000);flex:1;font-family:inherit;font-size:var(--text-md,15px);height:40px;line-height:20px;max-height:40px;min-height:40px;min-width:0;outline:none;overflow-wrap:anywhere;overflow-x:hidden;overflow-y:auto;padding:10px var(--space-sm,8px);resize:none;white-space:pre-wrap;width:0;word-break:break-word}.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;padding:0;transition:all var(--duration-fast,.15s) ease;width:40px}.ai-chat-widget.dark .ai-chat-send-button{background:var(--send-button-background,var(--primary-color,var(--button-color,var(--btn-primary-bg,#fff))));color:var(--button-icon-color,var(--btn-primary-text,#312f2d))}.ai-chat-send-button.active{background:var(--send-button-background,var(--primary-color,var(--button-color,var(--btn-primary-bg,#151515))));color:var(--button-icon-color,var(--btn-primary-text,#f4f4f4))}.ai-chat-widget.dark .ai-chat-send-button.active{background:var(--send-button-background,var(--primary-color,var(--button-color,var(--btn-primary-bg,#fff))));color:var(--button-icon-color,var(--btn-primary-text,#312f2d))}.ai-chat-send-button:hover:not(:disabled){opacity:.8}.ai-chat-send-button:active:not(:disabled){transform:scale(.95)}.ai-chat-send-button:disabled{cursor:not-allowed;opacity:.3}.ai-chat-file-list{display:flex;flex-wrap:wrap;gap:var(--space-sm);padding:var(--space-sm) var(--space-sm)}.ai-chat-file-item{align-items:center;background:rgba(0,0,0,.05);border-radius:6px;display:flex;font-size:var(--text-xs);gap:var(--space-sm);padding:6px 10px}.ai-chat-file-extension{background:var(--btn-primary-bg);border-radius:3px;color:var(--btn-primary-text);display:inline-block;font-size:10px;font-weight:var(--font-weight-semibold);min-width:40px;padding:2px 6px;text-align:center;text-transform:uppercase}.ai-chat-file-info{display:flex;flex:1;flex-direction:column;gap:2px;min-width:0}.ai-chat-file-name{font-weight:var(--font-weight-medium);max-width:150px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ai-chat-file-size{color:var(--text-muted);font-size:10px;opacity:.7}.ai-chat-file-remove{align-items:center;background:none;border:none;color:inherit;cursor:pointer;display:flex;justify-content:center;opacity:.5;padding:var(--space-xs);transition:opacity var(--duration-fast) ease}.ai-chat-file-remove:hover{opacity:1}.ai-chat-suggested-questions{align-self:flex-end;margin:0;padding:16px 0 0;width:100%}.ai-chat-suggested-questions-list{align-items:center;display:flex;flex-wrap:wrap;gap:6px;justify-content:flex-end}.ai-chat-suggested-question{background:var(--primary-color,var(--button-color,var(--user-bg,#f4f3f0)));border:none;border-radius:var(--radius-preset-badge,13px);color:var(--button-icon-color,var(--user-text,#000));cursor:pointer;font-size:14px;font-weight:400;line-height:1.3;max-width:100%;overflow:hidden;padding:8px 14px;text-overflow:ellipsis;transition:background .15s ease,opacity .15s ease;white-space:nowrap}.ai-chat-widget.dark .ai-chat-suggested-question{background:var(--primary-color,var(--button-color,var(--user-bg,#484848)));color:var(--button-icon-color,var(--user-text,#fff))}.ai-chat-suggested-question-text{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ai-chat-suggested-question:hover{filter:brightness(.9)}.ai-chat-widget.dark .ai-chat-suggested-question:hover{filter:brightness(1.15)}.ai-chat-suggested-question:active{transform:scale(.98)}.ai-chat-suggested-question-icon{display:none}.ai-chat-feedback-buttons{align-items:center;display:flex;gap:var(--space-xs)}.ai-chat-feedback{align-items:center;display:inline-flex;gap:0;height:20px}.ai-chat-feedback-button{align-items:center;background:transparent!important;border:none;border-radius:var(--radius-sm);color:var(--text-placeholder);cursor:pointer;display:flex;font-size:var(--text-sm);height:20px;justify-content:center;padding:var(--space-xs);transition:all var(--duration-fast) var(--spring-bounce)}.ai-chat-feedback-button:hover:not(:disabled){background:none!important;color:var(--text-secondary)}.ai-chat-feedback-button:active:not(:disabled){transform:scale(.9)}.ai-chat-feedback-button:disabled{cursor:not-allowed;opacity:.4}.ai-chat-feedback-button.active{background:none!important;color:var(--text-primary)}.ai-chat-feedback-submitted{align-items:center;animation:feedbackMorph .3s var(--spring-bounce);display:flex;gap:6px}.ai-chat-feedback-checkmark{animation:checkmarkPop .3s var(--spring-bounce);color:#10b981;font-size:var(--text-md);font-weight:700}.ai-chat-feedback-text{color:#10b981;font-size:var(--text-sm);font-weight:var(--font-weight-medium)}.ai-chat-history-panel{background:var(--bg-primary,#fff);display:flex;flex:1;flex-direction:column;overflow:hidden}.ai-chat-widget.dark .ai-chat-history-panel{background:var(--bg-primary,#18181b)}.ai-chat-history-empty,.ai-chat-history-loading{align-items:center;color:var(--text-muted);display:flex;flex:1;font-size:var(--text-sm);justify-content:center;padding:var(--space-lg);text-align:center}.ai-chat-history-list{-ms-overflow-style:none;display:flex;flex:1;flex-direction:column;gap:var(--space-sm);overflow-y:auto;padding:var(--space-md) var(--space-md) 120px;scrollbar-width:none}.ai-chat-history-list::-webkit-scrollbar{display:none}.ai-chat-history-list.exiting{animation:ai-chat-history-exit .22s var(--spring-smooth) forwards}.ai-chat-history-item{align-items: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,44px);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 3px 0 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;color:var(--text-muted,#71717a);cursor:pointer;display:flex;flex-shrink:0;height:32px;justify-content:center;margin-right:4px;opacity:0;transition:opacity var(--duration-fast,.15s) ease,color var(--duration-fast,.15s) ease;width:32px}.ai-chat-history-item:hover .ai-chat-history-item-delete{opacity:1}.ai-chat-history-item-delete:hover{color:var(--text-primary,#18181b)}.ai-chat-widget.dark .ai-chat-history-item-delete:hover{color:var(--text-primary,#fafafa)}.ai-chat-tool-row{align-items:center;display:flex;gap:10px;margin:2px 0}.ai-chat-tool-gear{color:var(--text-primary);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;border-radius:var(--radius-action-badge,3px);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:var(--tool-completed-bg,hsla(0,0%,100%,.12));color:var(--tool-completed-text,hsla(0,0%,100%,.9))}.ai-chat-widget:not(.dark) .ai-chat-tool-badge.completed{--tool-completed-bg:rgba(0,0,0,.08);--tool-completed-text:rgba(0,0,0,.8)}.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:#22c55e;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}@keyframes ai-chat-gear-spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}@keyframes ai-chat-tool-gradient{0%{background-position:200% 0}to{background-position:-200% 0}}@keyframes ai-chat-tool-check-appear{0%{opacity:0;transform:scale(.5)}to{opacity:.7;transform:scale(1)}}.ai-chat-sources{background:rgba(0,0,0,.02);border-radius:6px;font-size:var(--text-xs);margin-top:var(--space-sm);overflow:hidden}.ai-chat-sources-toggle{align-items:center;background:none;border:none;cursor:pointer;display:flex;gap:6px;padding:var(--space-sm) 10px;text-align:left;transition:background var(--duration-fast) ease;width:100%}.ai-chat-sources-toggle:hover{background:rgba(0,0,0,.03)}.ai-chat-sources-icon{color:var(--text-muted);font-size:10px;transition:transform var(--duration-fast) ease}.ai-chat-sources-title{color:var(--text-primary);flex:1;font-size:11px;font-weight:var(--font-weight-semibold);letter-spacing:.5px;text-transform:uppercase}.ai-chat-source-item{border-top:1px solid rgba(0,0,0,.05);color:var(--text-muted);display:flex;gap:var(--space-sm);padding:var(--space-sm) 10px}.ai-chat-source-item:last-child{border-bottom:none}.ai-chat-source-number{color:var(--btn-primary-bg);flex-shrink:0;font-weight:var(--font-weight-semibold)}.ai-chat-source-details{display:flex;flex:1;flex-direction:column;gap:var(--space-xs)}.ai-chat-source-score{color:var(--text-placeholder);font-size:11px}.ai-chat-source-content{color:var(--text-muted);font-size:11px;font-style:italic;line-height:var(--line-height-normal)}.ai-chat-source-metadata{display:flex;flex-wrap:wrap;gap:6px;margin-top:2px}.ai-chat-source-meta-item{background:rgba(0,0,0,.05);border-radius:3px;color:var(--text-muted);font-size:10px;padding:2px 6px}";
45933
46450
  styleInject(css_248z);
45934
46451
 
45935
46452
  // Icon components mapping
@@ -46033,16 +46550,6 @@
46033
46550
  mediaQuery.removeEventListener('change', handleMediaChange);
46034
46551
  };
46035
46552
  }, [config]);
46036
- // Debug logging
46037
- reactExports.useEffect(() => {
46038
- console.log('[ChatWidget] Config loaded:', config ? 'YES' : 'NO');
46039
- if (config) {
46040
- console.log('[ChatWidget] Config details:', {
46041
- accentColor: config.appearance?.primaryColor,
46042
- autoDetectedTheme,
46043
- });
46044
- }
46045
- }, [config, autoDetectedTheme]);
46046
46553
  // Handle auto-open
46047
46554
  reactExports.useEffect(() => {
46048
46555
  if (config?.settings.autoOpen) {
@@ -46097,17 +46604,8 @@
46097
46604
  ...customStyles,
46098
46605
  ...(zIndex !== undefined ? { '--widget-z-index': String(zIndex) } : {}),
46099
46606
  };
46100
- // Debug logging for theme and styles
46101
- reactExports.useEffect(() => {
46102
- console.log('[ChatWidget] Theme info:', {
46103
- effectiveTheme,
46104
- autoDetectedTheme,
46105
- accentColor,
46106
- });
46107
- }, [effectiveTheme, autoDetectedTheme, accentColor]);
46108
46607
  const handleToggle = () => {
46109
46608
  const newState = !isOpen;
46110
- console.log('[ChatWidget] handleToggle called, setting isOpen to:', newState);
46111
46609
  setIsOpen(newState);
46112
46610
  if (newState) {
46113
46611
  onOpen?.();
@@ -46122,10 +46620,8 @@
46122
46620
  // Don't render until config is loaded to avoid flash of unstyled content
46123
46621
  // In preview mode, config is always available
46124
46622
  if (!config && !previewMode) {
46125
- console.log('[ChatWidget] Not rendering - config not loaded yet');
46126
46623
  return null;
46127
46624
  }
46128
- console.log('[ChatWidget] Rendering widget', { isOpen, hasConfig: !!config });
46129
46625
  // Get button icon based on state
46130
46626
  const IconComponent = isOpen ? iconComponents.FiChevronDown : iconComponents.FiMessageCircle;
46131
46627
  return (jsxRuntimeExports.jsx("div", { ref: containerRef, className: `ai-chat-widget ${effectiveTheme}`, style: mergedStyles, children: jsxRuntimeExports.jsxs("div", { ref: widgetRef, className: `ai-chat-widget-container ${effectivePosition}`, children: [isOpen && (jsxRuntimeExports.jsx(ChatWindow, { messages: messages, isLoading: isLoading, isTyping: isTyping, error: error, config: config, onSendMessage: sendMessage, onClose: handleToggle, onFeedback: handleFeedback,