@kite-copilot/chat-panel 0.2.54 → 0.2.56

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -6,6 +6,7 @@ An AI-powered chat panel SDK for embedding intelligent chat assistants. This pac
6
6
 
7
7
  - **Side Panel UX**: Slides in from the right edge, pushes page content (no overlay)
8
8
  - **Zero-Config**: Drop-in integration - no layout changes required from host apps
9
+ - **Automatic URL Tracking**: Captures the exact browser URL (including path and query params) for context
9
10
  - **AI-Powered Chat**: Connects to your AI backend agent for intelligent responses
10
11
  - **CSV Bulk Operations**: Upload CSV files for bulk data processing
11
12
  - **Interactive Guides**: Built-in guided tours with animated cursor
@@ -76,11 +77,11 @@ if (chat.isOpen()) {
76
77
  console.log('Panel is open');
77
78
  }
78
79
 
79
- // Update context as user navigates
80
- chat.setCurrentPage('settings');
81
-
82
80
  // Clean up when done
83
81
  chat.unmount();
82
+
83
+ // Note: The chat panel automatically captures the browser URL (window.location.href)
84
+ // so you don't need to manually track or pass the current page.
84
85
  ```
85
86
 
86
87
  ### Vue.js
@@ -124,11 +125,7 @@ export function useKiteChat(config: KiteChatConfig) {
124
125
  isOpen.value = !isOpen.value;
125
126
  };
126
127
 
127
- const setCurrentPage = (page: string) => {
128
- chat.value?.setCurrentPage(page);
129
- };
130
-
131
- return { isOpen, open, close, toggle, setCurrentPage };
128
+ return { isOpen, open, close, toggle };
132
129
  }
133
130
  ```
134
131
 
@@ -142,7 +139,7 @@ import { useRouter } from 'vue-router';
142
139
 
143
140
  const router = useRouter();
144
141
 
145
- const { open, close, toggle, setCurrentPage } = useKiteChat({
142
+ const { open, close, toggle } = useKiteChat({
146
143
  userId: 'user-123',
147
144
  agentUrl: 'https://your-api.example.com',
148
145
  onNavigate: (page, subtab) => {
@@ -150,10 +147,8 @@ const { open, close, toggle, setCurrentPage } = useKiteChat({
150
147
  },
151
148
  });
152
149
 
153
- // Update context when route changes
154
- router.afterEach((to) => {
155
- setCurrentPage(to.name as string);
156
- });
150
+ // Note: The chat panel automatically captures window.location.href,
151
+ // so you don't need to manually track route changes.
157
152
  </script>
158
153
 
159
154
  <template>
@@ -320,7 +315,7 @@ Creates a new chat instance with explicit lifecycle control.
320
315
  | `userId` | `string` | Yes | Unique identifier for the current user |
321
316
  | `orgId` | `string` | No | Organization ID for multi-tenant data isolation |
322
317
  | `agentUrl` | `string` | No | Backend agent API URL |
323
- | `currentPage` | `string` | No | Current page context |
318
+ | ~~`currentPage`~~ | `string` | No | **Deprecated** - URL is now captured automatically |
324
319
  | `userName` | `string` | No | User's display name (for control center) |
325
320
  | `userEmail` | `string` | No | User's email address (for control center) |
326
321
  | `theme` | `'light' \| 'dark' \| 'system'` | No | Theme preference |
@@ -340,7 +335,7 @@ Creates a new chat instance with explicit lifecycle control.
340
335
  | `close()` | Close the side panel |
341
336
  | `toggle()` | Toggle the panel open/closed |
342
337
  | `isOpen()` | Check if the panel is currently open |
343
- | `setCurrentPage(page)` | Update the current page context |
338
+ | ~~`setCurrentPage(page)`~~ | **Deprecated** - URL is now captured automatically |
344
339
  | `updateConfig(config)` | Update configuration options |
345
340
  | `isMounted()` | Check if the widget is currently mounted |
346
341
 
@@ -357,7 +352,7 @@ import { ChatPanelWithToggle } from '@kite-copilot/chat-panel';
357
352
  | Prop | Type | Default | Description |
358
353
  |------|------|---------|-------------|
359
354
  | `agentUrl` | `string` | `localhost:5002` | Backend agent URL |
360
- | `currentPage` | `string` | - | Current page for context |
355
+ | ~~`currentPage`~~ | `string` | - | **Deprecated** - URL is now captured automatically |
361
356
  | `userId` | `string` | - | Unique user identifier |
362
357
  | `orgId` | `string` | - | Organization ID for multi-tenant data isolation |
363
358
  | `userName` | `string` | - | User's display name (for control center) |
@@ -457,7 +452,7 @@ Main chat endpoint for streaming responses.
457
452
  "user_id": "user-123",
458
453
  "org_id": "org-456",
459
454
  "message": "user message",
460
- "current_page": "dashboard",
455
+ "current_page": "https://example.com/dashboard/123?tab=settings",
461
456
  "user_name": "John Doe",
462
457
  "user_email": "john@example.com"
463
458
  }
@@ -473,7 +468,7 @@ Main chat endpoint for streaming responses.
473
468
 
474
469
  CSV file upload endpoint for bulk operations.
475
470
 
476
- **Request:** FormData with `file`, `message`, `session_id`, `user_id`, `org_id`, `current_page`
471
+ **Request:** FormData with `file`, `message`, `session_id`, `user_id`, `org_id`, `current_page` (full browser URL)
477
472
 
478
473
  ### `/chat/bulk/confirm` (POST)
479
474
 
package/dist/auto.cjs CHANGED
@@ -1691,9 +1691,8 @@ function ChatPanel({
1691
1691
  const [input, setInput] = React6.useState("");
1692
1692
  const [corner, setCorner] = React6.useState(initialCorner);
1693
1693
  const [isDragging, setIsDragging] = React6.useState(false);
1694
- const dragControls = (0, import_framer_motion2.useAnimationControls)();
1694
+ const dragControls = (0, import_framer_motion2.useDragControls)();
1695
1695
  const handleDragEnd = React6.useCallback((_event, info) => {
1696
- dragControls.set({ x: 0, y: 0 });
1697
1696
  setIsDragging(false);
1698
1697
  const viewportWidth = window.innerWidth;
1699
1698
  const pointerX = info.point.x;
@@ -1702,7 +1701,7 @@ function ChatPanel({
1702
1701
  setCorner(newCorner);
1703
1702
  onCornerChange?.(newCorner);
1704
1703
  }
1705
- }, [corner, onCornerChange, dragControls]);
1704
+ }, [corner, onCornerChange]);
1706
1705
  const [sessionId, setSessionId] = React6.useState(() => crypto.randomUUID());
1707
1706
  const [sessionUser, setSessionUser] = React6.useState(null);
1708
1707
  const orgConfigState = useOrgConfig({ agentUrl, orgId: orgId || "" });
@@ -1775,6 +1774,18 @@ function ChatPanel({
1775
1774
  }
1776
1775
  );
1777
1776
  }
1777
+ if (supabaseRef.current && sessionId) {
1778
+ console.log("[KiteChat] resetSession - marking session as ended:", sessionId);
1779
+ supabaseRef.current.from("sessions").update({ session_status: "ended" }).eq("session_id", sessionId).then(
1780
+ () => console.log("[KiteChat] resetSession - session marked as ended successfully:", sessionId),
1781
+ (err) => console.error("[KiteChat] resetSession - failed to mark session as ended:", sessionId, err)
1782
+ );
1783
+ } else {
1784
+ console.log("[KiteChat] resetSession - skipped marking session as ended:", {
1785
+ hasSupabase: !!supabaseRef.current,
1786
+ sessionId
1787
+ });
1788
+ }
1778
1789
  setSessionUser(null);
1779
1790
  setSessionId(crypto.randomUUID());
1780
1791
  setIsEscalated(false);
@@ -1837,19 +1848,112 @@ function ChatPanel({
1837
1848
  };
1838
1849
  }, [isEscalated, sessionId, effectiveSupabaseUrl, effectiveSupabaseAnonKey]);
1839
1850
  React6.useEffect(() => {
1840
- if (!isOpen && isEscalated && supabaseRef.current && sessionId) {
1841
- console.log("[KiteChat] Panel closed during live chat, marking disconnected");
1851
+ if (!sessionId || !supabaseRef.current || isEscalated) {
1852
+ console.log("[KiteChat] Session status subscription skip - sessionId:", sessionId, "supabase:", !!supabaseRef.current, "isEscalated:", isEscalated);
1853
+ return;
1854
+ }
1855
+ const channelName = `session-status:${sessionId}`;
1856
+ console.log("[KiteChat] Subscribing to session status changes:", channelName);
1857
+ const statusChannel = supabaseRef.current.channel(channelName).on(
1858
+ "postgres_changes",
1859
+ {
1860
+ event: "UPDATE",
1861
+ schema: "public",
1862
+ table: "sessions",
1863
+ filter: `session_id=eq.${sessionId}`
1864
+ },
1865
+ (payload) => {
1866
+ console.log("[KiteChat] Session status changed:", payload);
1867
+ if (payload.new.session_status === "escalated") {
1868
+ console.log("[KiteChat] Manual escalation detected - agent took over from control center");
1869
+ setIsEscalated(true);
1870
+ setPhase("idle");
1871
+ const escalationMessageId = Date.now() + 2;
1872
+ const escalationMessage = {
1873
+ id: escalationMessageId,
1874
+ role: "assistant",
1875
+ kind: "text",
1876
+ content: "A support agent has joined the conversation and will assist you shortly."
1877
+ };
1878
+ setMessages((prev) => [...prev, escalationMessage]);
1879
+ }
1880
+ }
1881
+ ).subscribe((status) => {
1882
+ if (status === "SUBSCRIBED") {
1883
+ console.log("[KiteChat] Successfully subscribed to session status changes");
1884
+ } else if (status === "CHANNEL_ERROR") {
1885
+ console.error("[KiteChat] Failed to subscribe to session status changes");
1886
+ }
1887
+ });
1888
+ return () => {
1889
+ console.log("[KiteChat] Unsubscribing from session status changes");
1890
+ statusChannel.unsubscribe();
1891
+ };
1892
+ }, [sessionId, isEscalated, effectiveSupabaseUrl, effectiveSupabaseAnonKey]);
1893
+ React6.useEffect(() => {
1894
+ if (!isEscalated || !supabaseRef.current || !sessionId) {
1895
+ return;
1896
+ }
1897
+ if (!isOpen) {
1898
+ console.log("[KiteChat] Panel minimized during live chat, marking inactive");
1842
1899
  supabaseRef.current.from("escalations").update({
1843
- customer_status: "disconnected",
1900
+ customer_status: "inactive",
1901
+ customer_last_seen: (/* @__PURE__ */ new Date()).toISOString()
1902
+ }).eq("session_id", sessionId).then(
1903
+ () => console.log("[KiteChat] Successfully marked inactive on panel minimize"),
1904
+ (err) => {
1905
+ console.error("[KiteChat] Failed to mark inactive on panel minimize:", err);
1906
+ }
1907
+ );
1908
+ } else {
1909
+ console.log("[KiteChat] Panel reopened during live chat, marking active");
1910
+ supabaseRef.current.from("escalations").update({
1911
+ customer_status: "active",
1844
1912
  customer_last_seen: (/* @__PURE__ */ new Date()).toISOString()
1845
1913
  }).eq("session_id", sessionId).then(
1846
- () => console.log("[KiteChat] Successfully marked disconnected on panel close"),
1914
+ () => console.log("[KiteChat] Successfully marked active on panel reopen"),
1847
1915
  (err) => {
1848
- console.error("[KiteChat] Failed to mark disconnected on panel close:", err);
1916
+ console.error("[KiteChat] Failed to mark active on panel reopen:", err);
1849
1917
  }
1850
1918
  );
1851
1919
  }
1852
1920
  }, [isOpen, isEscalated, sessionId]);
1921
+ React6.useEffect(() => {
1922
+ if (!sessionId || !effectiveSupabaseUrl || !effectiveSupabaseAnonKey) {
1923
+ console.log("[KiteChat] Session end handler skipped - missing:", {
1924
+ sessionId: !!sessionId,
1925
+ supabaseUrl: !!effectiveSupabaseUrl,
1926
+ supabaseKey: !!effectiveSupabaseAnonKey
1927
+ });
1928
+ return;
1929
+ }
1930
+ const currentSessionId = sessionId;
1931
+ const sbUrl = effectiveSupabaseUrl;
1932
+ const sbKey = effectiveSupabaseAnonKey;
1933
+ console.log("[KiteChat] Registering session end handler for session:", currentSessionId);
1934
+ const markSessionEnded = () => {
1935
+ console.log("[KiteChat] Marking session as ended:", currentSessionId);
1936
+ const sessionsUrl = `${sbUrl}/rest/v1/sessions?session_id=eq.${currentSessionId}`;
1937
+ fetch(sessionsUrl, {
1938
+ method: "PATCH",
1939
+ headers: {
1940
+ "Content-Type": "application/json",
1941
+ "apikey": sbKey,
1942
+ "Authorization": `Bearer ${sbKey}`,
1943
+ "Prefer": "return=minimal"
1944
+ },
1945
+ body: JSON.stringify({ session_status: "ended" }),
1946
+ keepalive: true
1947
+ }).catch(() => {
1948
+ });
1949
+ };
1950
+ window.addEventListener("beforeunload", markSessionEnded);
1951
+ return () => {
1952
+ console.log("[KiteChat] Component unmounting - marking session as ended:", currentSessionId);
1953
+ window.removeEventListener("beforeunload", markSessionEnded);
1954
+ markSessionEnded();
1955
+ };
1956
+ }, [sessionId, effectiveSupabaseUrl, effectiveSupabaseAnonKey]);
1853
1957
  const heartbeatIntervalRef = React6.useRef(null);
1854
1958
  const updateCustomerStatus = React6.useCallback(async (status) => {
1855
1959
  if (!supabaseRef.current || !sessionId) return;
@@ -1880,8 +1984,21 @@ function ChatPanel({
1880
1984
  (err) => console.error("[KiteChat] Failed to update customer status:", err)
1881
1985
  );
1882
1986
  };
1987
+ const markInactive = () => {
1988
+ supabase.from("escalations").update({
1989
+ customer_status: "inactive",
1990
+ customer_last_seen: (/* @__PURE__ */ new Date()).toISOString()
1991
+ }).eq("session_id", currentSessionId).then(
1992
+ () => console.log("[KiteChat] Marked inactive on tab hidden"),
1993
+ (err) => console.error("[KiteChat] Failed to mark inactive:", err)
1994
+ );
1995
+ };
1883
1996
  const markDisconnectedWithKeepalive = () => {
1884
- if (!sbUrl || !sbKey) return;
1997
+ console.log("[KiteChat] markDisconnectedWithKeepalive called for escalated session:", currentSessionId);
1998
+ if (!sbUrl || !sbKey) {
1999
+ console.log("[KiteChat] markDisconnectedWithKeepalive skipped - missing credentials");
2000
+ return;
2001
+ }
1885
2002
  const url = `${sbUrl}/rest/v1/escalations?session_id=eq.${currentSessionId}`;
1886
2003
  fetch(url, {
1887
2004
  method: "PATCH",
@@ -1898,6 +2015,20 @@ function ChatPanel({
1898
2015
  keepalive: true
1899
2016
  }).catch(() => {
1900
2017
  });
2018
+ console.log("[KiteChat] markDisconnectedWithKeepalive - also marking session as ended:", currentSessionId);
2019
+ const sessionsUrl = `${sbUrl}/rest/v1/sessions?session_id=eq.${currentSessionId}`;
2020
+ fetch(sessionsUrl, {
2021
+ method: "PATCH",
2022
+ headers: {
2023
+ "Content-Type": "application/json",
2024
+ "apikey": sbKey,
2025
+ "Authorization": `Bearer ${sbKey}`,
2026
+ "Prefer": "return=minimal"
2027
+ },
2028
+ body: JSON.stringify({ session_status: "ended" }),
2029
+ keepalive: true
2030
+ }).catch(() => {
2031
+ });
1901
2032
  };
1902
2033
  console.log("[KiteChat] Starting presence heartbeat for live chat");
1903
2034
  markActive();
@@ -1910,6 +2041,8 @@ function ChatPanel({
1910
2041
  const handleVisibilityChange = () => {
1911
2042
  if (document.visibilityState === "visible") {
1912
2043
  markActive();
2044
+ } else {
2045
+ markInactive();
1913
2046
  }
1914
2047
  };
1915
2048
  window.addEventListener("beforeunload", handleBeforeUnload);
@@ -2672,7 +2805,7 @@ ${imageMarkdown}` : imageMarkdown;
2672
2805
  body: JSON.stringify({
2673
2806
  session_id: sessionId,
2674
2807
  message: userText,
2675
- current_page: currentPage || "dashboard",
2808
+ current_page: typeof window !== "undefined" ? window.location.href : currentPage || "dashboard",
2676
2809
  user_id: userId,
2677
2810
  org_id: orgId,
2678
2811
  user_name: userName,
@@ -2869,6 +3002,7 @@ ${imageMarkdown}` : imageMarkdown;
2869
3002
  setPhase("idle");
2870
3003
  streamCompleted = true;
2871
3004
  } else if (eventType === "escalation") {
3005
+ console.log("[KiteChat] SSE escalation event received (AI-triggered)");
2872
3006
  setIsEscalated(true);
2873
3007
  setPhase("idle");
2874
3008
  const escalationMessageId = Date.now() + 2;
@@ -2941,7 +3075,7 @@ ${userText}`
2941
3075
  formData.append("file", file);
2942
3076
  formData.append("message", userText);
2943
3077
  formData.append("session_id", sessionId);
2944
- formData.append("current_page", currentPage || "dashboard");
3078
+ formData.append("current_page", typeof window !== "undefined" ? window.location.href : currentPage || "dashboard");
2945
3079
  if (orgId) formData.append("org_id", orgId);
2946
3080
  const controller = new AbortController();
2947
3081
  const timeoutId = setTimeout(() => controller.abort(), 12e4);
@@ -3715,9 +3849,10 @@ ${userText}`
3715
3849
  import_framer_motion2.motion.section,
3716
3850
  {
3717
3851
  drag: true,
3852
+ dragControls,
3853
+ dragListener: false,
3718
3854
  dragMomentum: false,
3719
3855
  dragElastic: 0,
3720
- animate: dragControls,
3721
3856
  onDragStart: () => setIsDragging(true),
3722
3857
  onDragEnd: handleDragEnd,
3723
3858
  className: `fixed bottom-4 z-40 flex flex-col bg-white border border-gray-200 rounded-2xl overflow-hidden shadow-2xl ${isDragging ? "cursor-grabbing" : ""} ${corner === "bottom-left" ? "left-4" : "right-4"} ${isOpen ? "opacity-100 scale-100" : "opacity-0 scale-95 pointer-events-none"}`,
@@ -3726,53 +3861,60 @@ ${userText}`
3726
3861
  height: `${PANEL_HEIGHT}px`
3727
3862
  },
3728
3863
  children: [
3729
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center justify-between px-4 py-3 border-b border-gray-100 bg-gradient-to-r from-gray-50 to-white shrink-0 cursor-grab active:cursor-grabbing", children: [
3730
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center gap-2.5", children: [
3731
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react4.Sparkles, { className: "h-3.5 w-3.5 text-black", fill: "currentColor" }),
3732
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h3", { className: "text-sm font-semibold text-gray-800", children: "Copilot" })
3733
- ] }),
3734
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center gap-1", children: [
3735
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
3736
- Button,
3737
- {
3738
- variant: "ghost",
3739
- size: "sm",
3740
- className: "h-7 w-7 p-0 text-gray-400 hover:text-gray-600 hover:bg-gray-100 rounded-full",
3741
- onClick: () => {
3742
- setMessages([]);
3743
- resetSession();
3744
- setCurrentFolderId(void 0);
3745
- setActiveGuide(void 0);
3746
- activeGuideRef.current = void 0;
3747
- setGuideComplete(false);
3748
- },
3749
- children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react4.SquarePen, { className: "h-3 w-3" })
3750
- }
3751
- ),
3752
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
3753
- Button,
3754
- {
3755
- variant: "ghost",
3756
- size: "sm",
3757
- className: "h-7 w-7 p-0 text-gray-400 hover:text-gray-600 hover:bg-gray-100 rounded-full",
3758
- onClick: () => {
3759
- if (isEscalated) {
3760
- resetSession();
3761
- setMessages([]);
3762
- setPanelView("landing");
3763
- setCurrentFolderId(void 0);
3764
- setActiveGuide(void 0);
3765
- activeGuideRef.current = void 0;
3766
- setGuideComplete(false);
3864
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
3865
+ "div",
3866
+ {
3867
+ className: "flex items-center justify-between px-4 py-3 border-b border-gray-100 bg-gradient-to-r from-gray-50 to-white shrink-0 cursor-grab active:cursor-grabbing",
3868
+ onPointerDown: (e) => dragControls.start(e),
3869
+ children: [
3870
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center gap-2.5", children: [
3871
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react4.Sparkles, { className: "h-3.5 w-3.5 text-black", fill: "currentColor" }),
3872
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h3", { className: "text-sm font-semibold text-gray-800", children: "Copilot" })
3873
+ ] }),
3874
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center gap-1", children: [
3875
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
3876
+ Button,
3877
+ {
3878
+ variant: "ghost",
3879
+ size: "sm",
3880
+ className: "h-7 w-7 p-0 text-gray-400 hover:text-gray-600 hover:bg-gray-100 rounded-full",
3881
+ onClick: () => {
3882
+ setMessages([]);
3883
+ resetSession();
3884
+ setCurrentFolderId(void 0);
3885
+ setActiveGuide(void 0);
3886
+ activeGuideRef.current = void 0;
3887
+ setGuideComplete(false);
3888
+ },
3889
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react4.SquarePen, { className: "h-3 w-3" })
3767
3890
  }
3768
- onClose?.();
3769
- },
3770
- children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react4.Minus, { className: "h-3.5 w-3.5" })
3771
- }
3772
- )
3773
- ] })
3774
- ] }),
3775
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex-1 flex flex-col min-h-0 overflow-hidden relative", children: [
3891
+ ),
3892
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
3893
+ Button,
3894
+ {
3895
+ variant: "ghost",
3896
+ size: "sm",
3897
+ className: "h-7 w-7 p-0 text-gray-400 hover:text-gray-600 hover:bg-gray-100 rounded-full",
3898
+ onClick: () => {
3899
+ if (isEscalated) {
3900
+ resetSession();
3901
+ setMessages([]);
3902
+ setPanelView("landing");
3903
+ setCurrentFolderId(void 0);
3904
+ setActiveGuide(void 0);
3905
+ activeGuideRef.current = void 0;
3906
+ setGuideComplete(false);
3907
+ }
3908
+ onClose?.();
3909
+ },
3910
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react4.Minus, { className: "h-3.5 w-3.5" })
3911
+ }
3912
+ )
3913
+ ] })
3914
+ ]
3915
+ }
3916
+ ),
3917
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex-1 flex flex-col min-h-0 overflow-hidden relative select-text", children: [
3776
3918
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
3777
3919
  "div",
3778
3920
  {
@@ -3892,8 +4034,8 @@ ${userText}`
3892
4034
  }
3893
4035
  const agentImageUrls = message.imageUrls || extractedImageUrls;
3894
4036
  const agentTextContent = contentStr.replace(/!\[image\]\([^)]+\)\n*/g, "").trim();
3895
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: `flex flex-col items-start gap-2 ${isRoleChange ? "mt-3" : ""}`, children: [
3896
- isRoleChange && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-[10px] text-gray-500 mb-1 ml-1", children: "Agent" }),
4037
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: `flex flex-col items-start ${isRoleChange ? "mt-2" : ""}`, children: [
4038
+ isRoleChange && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-[10px] text-gray-500 mb-0.5 ml-1", children: "Agent" }),
3897
4039
  agentImageUrls.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "flex flex-wrap gap-1 justify-start max-w-[300px]", children: agentImageUrls.map((url, imgIndex) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
3898
4040
  "button",
3899
4041
  {
package/dist/auto.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { K as KiteChatConfig, a as KiteChatInstance } from './createKiteChat-Cl1sNjam.cjs';
1
+ import { K as KiteChatConfig, a as KiteChatInstance } from './createKiteChat-DiJ2Otkm.cjs';
2
2
  import 'react/jsx-runtime';
3
3
 
4
4
  /**
package/dist/auto.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { K as KiteChatConfig, a as KiteChatInstance } from './createKiteChat-Cl1sNjam.js';
1
+ import { K as KiteChatConfig, a as KiteChatInstance } from './createKiteChat-DiJ2Otkm.js';
2
2
  import 'react/jsx-runtime';
3
3
 
4
4
  /**
package/dist/auto.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createKiteChat
3
- } from "./chunk-TK7U64UR.js";
3
+ } from "./chunk-YTH7EUFD.js";
4
4
 
5
5
  // src/auto.ts
6
6
  function mountKiteChat(config) {